blob: f8fa43bb2c86cadfdeda86daaadd9a534bc34d36 [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
Xiaojun Sang5f88ef22017-03-08 15:13:18 +0800191#define TASHA_TX_UNMUTE_DELAY_MS 40
Banajit Goswamide8271c2017-01-18 00:28:59 -0800192
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);
Banajit Goswamide8271c2017-01-18 00:28:59 -08005905 break;
5906 case SND_SOC_DAPM_POST_PMU:
5907 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00);
5908
5909 if (decimator == 0) {
5910 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
5911 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3);
5912 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
5913 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
5914 }
5915 /* schedule work queue to Remove Mute */
5916 schedule_delayed_work(&tasha->tx_mute_dwork[decimator].dwork,
5917 msecs_to_jiffies(tx_unmute_delay));
5918 if (tasha->tx_hpf_work[decimator].hpf_cut_off_freq !=
5919 CF_MIN_3DB_150HZ)
5920 schedule_delayed_work(
5921 &tasha->tx_hpf_work[decimator].dwork,
5922 msecs_to_jiffies(300));
5923 /* apply gain after decimator is enabled */
5924 snd_soc_write(codec, tx_gain_ctl_reg,
5925 snd_soc_read(codec, tx_gain_ctl_reg));
5926 break;
5927 case SND_SOC_DAPM_PRE_PMD:
5928 hpf_cut_off_freq =
5929 tasha->tx_hpf_work[decimator].hpf_cut_off_freq;
5930 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
Banajit Goswamide8271c2017-01-18 00:28:59 -08005931 if (cancel_delayed_work_sync(
5932 &tasha->tx_hpf_work[decimator].dwork)) {
5933 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
5934 tasha_codec_vote_max_bw(codec, true);
5935 snd_soc_update_bits(codec, dec_cfg_reg,
5936 TX_HPF_CUT_OFF_FREQ_MASK,
5937 hpf_cut_off_freq << 5);
5938 tasha_codec_vote_max_bw(codec, false);
5939 }
5940 }
5941 cancel_delayed_work_sync(
5942 &tasha->tx_mute_dwork[decimator].dwork);
5943 break;
5944 case SND_SOC_DAPM_POST_PMD:
5945 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
5946 break;
5947 };
5948out:
5949 kfree(wname);
5950 return ret;
5951}
5952
5953static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec,
5954 unsigned int dmic, struct wcd9xxx_pdata *pdata)
5955{
5956 u8 tx_stream_fs;
5957 u8 adc_mux_index = 0, adc_mux_sel = 0;
5958 bool dec_found = false;
5959 u16 adc_mux_ctl_reg, tx_fs_reg;
5960 u32 dmic_fs;
5961
5962 while (dec_found == 0 && adc_mux_index < WCD9335_MAX_VALID_ADC_MUX) {
5963 if (adc_mux_index < 4) {
5964 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
5965 (adc_mux_index * 2);
5966 adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
5967 0x78) >> 3) - 1;
5968 } else if (adc_mux_index < 9) {
5969 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
5970 ((adc_mux_index - 4) * 1);
5971 adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
5972 0x38) >> 3) - 1;
5973 } else if (adc_mux_index == 9) {
5974 ++adc_mux_index;
5975 continue;
5976 }
5977 if (adc_mux_sel == dmic)
5978 dec_found = true;
5979 else
5980 ++adc_mux_index;
5981 }
5982
5983 if (dec_found == true && adc_mux_index <= 8) {
5984 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index);
5985 tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F;
5986 dmic_fs = tx_stream_fs <= 4 ? WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ :
5987 WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
5988
5989 /*
5990 * Check for ECPP path selection and DEC1 not connected to
5991 * any other audio path to apply ECPP DMIC sample rate
5992 */
5993 if ((adc_mux_index == 1) &&
5994 ((snd_soc_read(codec, WCD9335_CPE_SS_US_EC_MUX_CFG)
5995 & 0x0F) == 0x0A) &&
5996 ((snd_soc_read(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0)
5997 & 0x0C) == 0x00)) {
5998 dmic_fs = pdata->ecpp_dmic_sample_rate;
5999 }
6000 } else {
6001 dmic_fs = pdata->dmic_sample_rate;
6002 }
6003
6004 return dmic_fs;
6005}
6006
6007static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec,
6008 u32 mclk_rate, u32 dmic_clk_rate)
6009{
6010 u32 div_factor;
6011 u8 dmic_ctl_val;
6012
6013 dev_dbg(codec->dev,
6014 "%s: mclk_rate = %d, dmic_sample_rate = %d\n",
6015 __func__, mclk_rate, dmic_clk_rate);
6016
6017 /* Default value to return in case of error */
6018 if (mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
6019 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
6020 else
6021 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
6022
6023 if (dmic_clk_rate == 0) {
6024 dev_err(codec->dev,
6025 "%s: dmic_sample_rate cannot be 0\n",
6026 __func__);
6027 goto done;
6028 }
6029
6030 div_factor = mclk_rate / dmic_clk_rate;
6031 switch (div_factor) {
6032 case 2:
6033 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
6034 break;
6035 case 3:
6036 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
6037 break;
6038 case 4:
6039 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4;
6040 break;
6041 case 6:
6042 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6;
6043 break;
6044 case 8:
6045 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8;
6046 break;
6047 case 16:
6048 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16;
6049 break;
6050 default:
6051 dev_err(codec->dev,
6052 "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n",
6053 __func__, div_factor, mclk_rate, dmic_clk_rate);
6054 break;
6055 }
6056
6057done:
6058 return dmic_ctl_val;
6059}
6060
6061static int tasha_codec_enable_adc(struct snd_soc_dapm_widget *w,
6062 struct snd_kcontrol *kcontrol, int event)
6063{
6064 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6065
6066 dev_dbg(codec->dev, "%s: event:%d\n", __func__, event);
6067
6068 switch (event) {
6069 case SND_SOC_DAPM_PRE_PMU:
6070 tasha_codec_set_tx_hold(codec, w->reg, true);
6071 break;
6072 default:
6073 break;
6074 }
6075
6076 return 0;
6077}
6078
6079static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w,
6080 struct snd_kcontrol *kcontrol, int event)
6081{
6082 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6083 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6084 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
6085 u8 dmic_clk_en = 0x01;
6086 u16 dmic_clk_reg;
6087 s32 *dmic_clk_cnt;
6088 u8 dmic_rate_val, dmic_rate_shift = 1;
6089 unsigned int dmic;
6090 u32 dmic_sample_rate;
6091 int ret;
6092 char *wname;
6093
6094 wname = strpbrk(w->name, "012345");
6095 if (!wname) {
6096 dev_err(codec->dev, "%s: widget not found\n", __func__);
6097 return -EINVAL;
6098 }
6099
6100 ret = kstrtouint(wname, 10, &dmic);
6101 if (ret < 0) {
6102 dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n",
6103 __func__);
6104 return -EINVAL;
6105 }
6106
6107 switch (dmic) {
6108 case 0:
6109 case 1:
6110 dmic_clk_cnt = &(tasha->dmic_0_1_clk_cnt);
6111 dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL;
6112 break;
6113 case 2:
6114 case 3:
6115 dmic_clk_cnt = &(tasha->dmic_2_3_clk_cnt);
6116 dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL;
6117 break;
6118 case 4:
6119 case 5:
6120 dmic_clk_cnt = &(tasha->dmic_4_5_clk_cnt);
6121 dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL;
6122 break;
6123 default:
6124 dev_err(codec->dev, "%s: Invalid DMIC Selection\n",
6125 __func__);
6126 return -EINVAL;
6127 };
6128 dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
6129 __func__, event, dmic, *dmic_clk_cnt);
6130
6131 switch (event) {
6132 case SND_SOC_DAPM_PRE_PMU:
6133 dmic_sample_rate = tasha_get_dmic_sample_rate(codec, dmic,
6134 pdata);
6135 dmic_rate_val =
6136 tasha_get_dmic_clk_val(codec,
6137 pdata->mclk_rate,
6138 dmic_sample_rate);
6139
6140 (*dmic_clk_cnt)++;
6141 if (*dmic_clk_cnt == 1) {
6142 snd_soc_update_bits(codec, dmic_clk_reg,
6143 0x07 << dmic_rate_shift,
6144 dmic_rate_val << dmic_rate_shift);
6145 snd_soc_update_bits(codec, dmic_clk_reg,
6146 dmic_clk_en, dmic_clk_en);
6147 }
6148
6149 break;
6150 case SND_SOC_DAPM_POST_PMD:
6151 dmic_rate_val =
6152 tasha_get_dmic_clk_val(codec,
6153 pdata->mclk_rate,
6154 pdata->mad_dmic_sample_rate);
6155 (*dmic_clk_cnt)--;
6156 if (*dmic_clk_cnt == 0) {
6157 snd_soc_update_bits(codec, dmic_clk_reg,
6158 dmic_clk_en, 0);
6159 snd_soc_update_bits(codec, dmic_clk_reg,
6160 0x07 << dmic_rate_shift,
6161 dmic_rate_val << dmic_rate_shift);
6162 }
6163 break;
6164 };
6165
6166 return 0;
6167}
6168
6169static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6170 int event)
6171{
6172 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6173 int micb_num;
6174
6175 dev_dbg(codec->dev, "%s: wname: %s, event: %d\n",
6176 __func__, w->name, event);
6177
6178 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1")))
6179 micb_num = MIC_BIAS_1;
6180 else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2")))
6181 micb_num = MIC_BIAS_2;
6182 else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))
6183 micb_num = MIC_BIAS_3;
6184 else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4")))
6185 micb_num = MIC_BIAS_4;
6186 else
6187 return -EINVAL;
6188
6189 switch (event) {
6190 case SND_SOC_DAPM_PRE_PMU:
6191 /*
6192 * MIC BIAS can also be requested by MBHC,
6193 * so use ref count to handle micbias pullup
6194 * and enable requests
6195 */
6196 tasha_micbias_control(codec, micb_num, MICB_ENABLE, true);
6197 break;
6198 case SND_SOC_DAPM_POST_PMU:
6199 /* wait for cnp time */
6200 usleep_range(1000, 1100);
6201 break;
6202 case SND_SOC_DAPM_POST_PMD:
6203 tasha_micbias_control(codec, micb_num, MICB_DISABLE, true);
6204 break;
6205 };
6206
6207 return 0;
6208}
6209
6210static int tasha_codec_ldo_h_control(struct snd_soc_dapm_widget *w,
6211 int event)
6212{
6213 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6214 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6215
6216 if (SND_SOC_DAPM_EVENT_ON(event)) {
6217 tasha->ldo_h_users++;
6218
6219 if (tasha->ldo_h_users == 1)
6220 snd_soc_update_bits(codec, WCD9335_LDOH_MODE,
6221 0x80, 0x80);
6222 }
6223
6224 if (SND_SOC_DAPM_EVENT_OFF(event)) {
6225 tasha->ldo_h_users--;
6226
6227 if (tasha->ldo_h_users < 0)
6228 tasha->ldo_h_users = 0;
6229
6230 if (tasha->ldo_h_users == 0)
6231 snd_soc_update_bits(codec, WCD9335_LDOH_MODE,
6232 0x80, 0x00);
6233 }
6234
6235 return 0;
6236}
6237
6238static int tasha_codec_force_enable_ldo_h(struct snd_soc_dapm_widget *w,
6239 struct snd_kcontrol *kcontrol,
6240 int event)
6241{
6242 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6243 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6244
6245 switch (event) {
6246 case SND_SOC_DAPM_PRE_PMU:
6247 wcd_resmgr_enable_master_bias(tasha->resmgr);
6248 tasha_codec_ldo_h_control(w, event);
6249 break;
6250 case SND_SOC_DAPM_POST_PMD:
6251 tasha_codec_ldo_h_control(w, event);
6252 wcd_resmgr_disable_master_bias(tasha->resmgr);
6253 break;
6254 }
6255
6256 return 0;
6257}
6258
6259static int tasha_codec_force_enable_micbias(struct snd_soc_dapm_widget *w,
6260 struct snd_kcontrol *kcontrol,
6261 int event)
6262{
6263 int ret = 0;
6264 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6265 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6266
6267 switch (event) {
6268 case SND_SOC_DAPM_PRE_PMU:
6269 wcd_resmgr_enable_master_bias(tasha->resmgr);
6270 tasha_cdc_mclk_enable(codec, true, true);
6271 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU);
6272 /* Wait for 1ms for better cnp */
6273 usleep_range(1000, 1100);
6274 tasha_cdc_mclk_enable(codec, false, true);
6275 break;
6276 case SND_SOC_DAPM_POST_PMD:
6277 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD);
6278 wcd_resmgr_disable_master_bias(tasha->resmgr);
6279 break;
6280 }
6281
6282 return ret;
6283}
6284
6285static int tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6286 struct snd_kcontrol *kcontrol, int event)
6287{
6288 return __tasha_codec_enable_micbias(w, event);
6289}
6290
6291static int tasha_codec_enable_standalone_ldo_h(struct snd_soc_codec *codec,
6292 bool enable)
6293{
6294 int rc;
6295
6296 if (enable)
6297 rc = snd_soc_dapm_force_enable_pin(
6298 snd_soc_codec_get_dapm(codec),
6299 DAPM_LDO_H_STANDALONE);
6300 else
6301 rc = snd_soc_dapm_disable_pin(
6302 snd_soc_codec_get_dapm(codec),
6303 DAPM_LDO_H_STANDALONE);
6304
6305 if (!rc)
6306 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
6307 else
6308 dev_err(codec->dev, "%s: ldo_h force %s pin failed\n",
6309 __func__, (enable ? "enable" : "disable"));
6310
6311 return rc;
6312}
6313
6314/*
6315 * tasha_codec_enable_standalone_micbias - enable micbias standalone
6316 * @codec: pointer to codec instance
6317 * @micb_num: number of micbias to be enabled
6318 * @enable: true to enable micbias or false to disable
6319 *
6320 * This function is used to enable micbias (1, 2, 3 or 4) during
6321 * standalone independent of whether TX use-case is running or not
6322 *
6323 * Return: error code in case of failure or 0 for success
6324 */
6325int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec,
6326 int micb_num,
6327 bool enable)
6328{
6329 const char * const micb_names[] = {
6330 DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE,
6331 DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE
6332 };
6333 int micb_index = micb_num - 1;
6334 int rc;
6335
6336 if (!codec) {
6337 pr_err("%s: Codec memory is NULL\n", __func__);
6338 return -EINVAL;
6339 }
6340
6341 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
6342 dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
6343 __func__, micb_index);
6344 return -EINVAL;
6345 }
6346
6347 if (enable)
6348 rc = snd_soc_dapm_force_enable_pin(
6349 snd_soc_codec_get_dapm(codec),
6350 micb_names[micb_index]);
6351 else
6352 rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec),
6353 micb_names[micb_index]);
6354
6355 if (!rc)
6356 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
6357 else
6358 dev_err(codec->dev, "%s: micbias%d force %s pin failed\n",
6359 __func__, micb_num, (enable ? "enable" : "disable"));
6360
6361 return rc;
6362}
6363EXPORT_SYMBOL(tasha_codec_enable_standalone_micbias);
6364
6365static const char *const tasha_anc_func_text[] = {"OFF", "ON"};
6366static const struct soc_enum tasha_anc_func_enum =
6367 SOC_ENUM_SINGLE_EXT(2, tasha_anc_func_text);
6368
6369static const char *const tasha_clkmode_text[] = {"EXTERNAL", "INTERNAL"};
6370static SOC_ENUM_SINGLE_EXT_DECL(tasha_clkmode_enum, tasha_clkmode_text);
6371
6372/* Cutoff frequency for high pass filter */
6373static const char * const cf_text[] = {
6374 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
6375};
6376
6377static const char * const rx_cf_text[] = {
6378 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
6379 "CF_NEG_3DB_0P48HZ"
6380};
6381
6382static const struct soc_enum cf_dec0_enum =
6383 SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text);
6384
6385static const struct soc_enum cf_dec1_enum =
6386 SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text);
6387
6388static const struct soc_enum cf_dec2_enum =
6389 SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text);
6390
6391static const struct soc_enum cf_dec3_enum =
6392 SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text);
6393
6394static const struct soc_enum cf_dec4_enum =
6395 SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text);
6396
6397static const struct soc_enum cf_dec5_enum =
6398 SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text);
6399
6400static const struct soc_enum cf_dec6_enum =
6401 SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text);
6402
6403static const struct soc_enum cf_dec7_enum =
6404 SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text);
6405
6406static const struct soc_enum cf_dec8_enum =
6407 SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text);
6408
6409static const struct soc_enum cf_int0_1_enum =
6410 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
6411
6412static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
6413 rx_cf_text);
6414
6415static const struct soc_enum cf_int1_1_enum =
6416 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
6417
6418static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
6419 rx_cf_text);
6420
6421static const struct soc_enum cf_int2_1_enum =
6422 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
6423
6424static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
6425 rx_cf_text);
6426
6427static const struct soc_enum cf_int3_1_enum =
6428 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
6429
6430static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
6431 rx_cf_text);
6432
6433static const struct soc_enum cf_int4_1_enum =
6434 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
6435
6436static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
6437 rx_cf_text);
6438
6439static const struct soc_enum cf_int5_1_enum =
6440 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
6441
6442static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
6443 rx_cf_text);
6444
6445static const struct soc_enum cf_int6_1_enum =
6446 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
6447
6448static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
6449 rx_cf_text);
6450
6451static const struct soc_enum cf_int7_1_enum =
6452 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
6453
6454static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
6455 rx_cf_text);
6456
6457static const struct soc_enum cf_int8_1_enum =
6458 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
6459
6460static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
6461 rx_cf_text);
6462
6463static const struct snd_soc_dapm_route audio_i2s_map[] = {
6464 {"SLIM RX0 MUX", NULL, "RX_I2S_CTL"},
6465 {"SLIM RX1 MUX", NULL, "RX_I2S_CTL"},
6466 {"SLIM RX2 MUX", NULL, "RX_I2S_CTL"},
6467 {"SLIM RX3 MUX", NULL, "RX_I2S_CTL"},
6468
6469 {"SLIM TX6 MUX", NULL, "TX_I2S_CTL"},
6470 {"SLIM TX7 MUX", NULL, "TX_I2S_CTL"},
6471 {"SLIM TX8 MUX", NULL, "TX_I2S_CTL"},
6472 {"SLIM TX11 MUX", NULL, "TX_I2S_CTL"},
6473};
6474
6475static const struct snd_soc_dapm_route audio_map[] = {
6476
6477 /* MAD */
6478 {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"},
6479 {"MAD_SEL MUX", "MSM", "MADINPUT"},
6480 {"MADONOFF", "Switch", "MAD_SEL MUX"},
6481 {"MAD_BROADCAST", "Switch", "MAD_SEL MUX"},
6482 {"TX13 INP MUX", "CPE_TX_PP", "MADONOFF"},
6483
6484 /* CPE HW MAD bypass */
6485 {"CPE IN Mixer", "MAD_BYPASS", "SLIM TX1 MUX"},
6486
6487 {"AIF4_MAD Mixer", "SLIM TX1", "CPE IN Mixer"},
6488 {"AIF4_MAD Mixer", "SLIM TX12", "MADONOFF"},
6489 {"AIF4_MAD Mixer", "SLIM TX13", "TX13 INP MUX"},
6490 {"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
6491 {"AIF4 MAD", NULL, "AIF4"},
6492
6493 {"EC BUF MUX INP", "DEC1", "ADC MUX1"},
6494 {"AIF5 CPE", NULL, "EC BUF MUX INP"},
6495
6496 /* SLIMBUS Connections */
6497 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
6498 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
6499 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
6500
6501 /* VI Feedback */
6502 {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"},
6503 {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"},
6504 {"AIF4 VI", NULL, "AIF4_VI Mixer"},
6505
6506 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
6507 {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6508 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6509 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6510 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6511 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6512 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6513 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6514 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6515 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6516 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6517 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6518 {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6519 {"AIF1_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6520 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
6521 {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6522 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6523 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6524 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6525 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6526 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6527 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6528 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6529 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6530 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6531 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6532 {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6533 {"AIF2_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6534 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
6535 {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6536 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6537 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6538 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6539 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6540 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6541 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6542 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6543 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6544 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6545 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6546 {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6547 {"AIF3_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6548
6549 {"SLIM TX0 MUX", "DEC0", "ADC MUX0"},
6550 {"SLIM TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
6551 {"SLIM TX0 MUX", "DEC0_192", "ADC US MUX0"},
6552
6553 {"SLIM TX1 MUX", "DEC1", "ADC MUX1"},
6554 {"SLIM TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"},
6555 {"SLIM TX1 MUX", "DEC1_192", "ADC US MUX1"},
6556
6557 {"SLIM TX2 MUX", "DEC2", "ADC MUX2"},
6558 {"SLIM TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"},
6559 {"SLIM TX2 MUX", "DEC2_192", "ADC US MUX2"},
6560
6561 {"SLIM TX3 MUX", "DEC3", "ADC MUX3"},
6562 {"SLIM TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"},
6563 {"SLIM TX3 MUX", "DEC3_192", "ADC US MUX3"},
6564
6565 {"SLIM TX4 MUX", "DEC4", "ADC MUX4"},
6566 {"SLIM TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"},
6567 {"SLIM TX4 MUX", "DEC4_192", "ADC US MUX4"},
6568
6569 {"SLIM TX5 MUX", "DEC5", "ADC MUX5"},
6570 {"SLIM TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6571 {"SLIM TX5 MUX", "DEC5_192", "ADC US MUX5"},
6572
6573 {"SLIM TX6 MUX", "DEC6", "ADC MUX6"},
6574 {"SLIM TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"},
6575 {"SLIM TX6 MUX", "DEC6_192", "ADC US MUX6"},
6576
6577 {"SLIM TX7 MUX", "DEC7", "ADC MUX7"},
6578 {"SLIM TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"},
6579 {"SLIM TX7 MUX", "DEC7_192", "ADC US MUX7"},
6580
6581 {"SLIM TX8 MUX", "DEC8", "ADC MUX8"},
6582 {"SLIM TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"},
6583 {"SLIM TX8 MUX", "DEC8_192", "ADC US MUX8"},
6584
6585 {"SLIM TX9 MUX", "DEC7", "ADC MUX7"},
6586 {"SLIM TX9 MUX", "DEC7_192", "ADC US MUX7"},
6587 {"SLIM TX10 MUX", "DEC6", "ADC MUX6"},
6588 {"SLIM TX10 MUX", "DEC6_192", "ADC US MUX6"},
6589
6590 {"SLIM TX11 MUX", "DEC_0_5", "SLIM TX11 INP1 MUX"},
6591 {"SLIM TX11 MUX", "DEC_9_12", "SLIM TX11 INP1 MUX"},
6592 {"SLIM TX11 INP1 MUX", "DEC0", "ADC MUX0"},
6593 {"SLIM TX11 INP1 MUX", "DEC1", "ADC MUX1"},
6594 {"SLIM TX11 INP1 MUX", "DEC2", "ADC MUX2"},
6595 {"SLIM TX11 INP1 MUX", "DEC3", "ADC MUX3"},
6596 {"SLIM TX11 INP1 MUX", "DEC4", "ADC MUX4"},
6597 {"SLIM TX11 INP1 MUX", "DEC5", "ADC MUX5"},
6598 {"SLIM TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6599
6600 {"TX13 INP MUX", "MAD_BRDCST", "MAD_BROADCAST"},
6601 {"TX13 INP MUX", "CDC_DEC_5", "SLIM TX13 MUX"},
6602 {"SLIM TX13 MUX", "DEC5", "ADC MUX5"},
6603
6604 {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6605 {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6606 {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6607 {"RX MIX TX0 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6608 {"RX MIX TX0 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6609 {"RX MIX TX0 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6610 {"RX MIX TX0 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6611 {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6612 {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6613 {"RX MIX TX0 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6614 {"RX MIX TX0 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6615 {"RX MIX TX0 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6616 {"RX MIX TX0 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6617
6618 {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6619 {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6620 {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6621 {"RX MIX TX1 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6622 {"RX MIX TX1 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6623 {"RX MIX TX1 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6624 {"RX MIX TX1 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6625 {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6626 {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6627 {"RX MIX TX1 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6628 {"RX MIX TX1 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6629 {"RX MIX TX1 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6630 {"RX MIX TX1 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6631
6632 {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6633 {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6634 {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6635 {"RX MIX TX2 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6636 {"RX MIX TX2 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6637 {"RX MIX TX2 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6638 {"RX MIX TX2 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6639 {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6640 {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6641 {"RX MIX TX2 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6642 {"RX MIX TX2 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6643 {"RX MIX TX2 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6644 {"RX MIX TX2 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6645
6646 {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6647 {"RX MIX TX3 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6648 {"RX MIX TX3 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6649 {"RX MIX TX3 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6650 {"RX MIX TX3 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6651 {"RX MIX TX3 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6652 {"RX MIX TX3 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6653 {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6654 {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6655 {"RX MIX TX3 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6656 {"RX MIX TX3 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6657 {"RX MIX TX3 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6658 {"RX MIX TX3 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6659
6660 {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6661 {"RX MIX TX4 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6662 {"RX MIX TX4 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6663 {"RX MIX TX4 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6664 {"RX MIX TX4 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6665 {"RX MIX TX4 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6666 {"RX MIX TX4 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6667 {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6668 {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6669 {"RX MIX TX4 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6670 {"RX MIX TX4 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6671 {"RX MIX TX4 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6672 {"RX MIX TX4 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6673
6674 {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6675 {"RX MIX TX5 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6676 {"RX MIX TX5 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6677 {"RX MIX TX5 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6678 {"RX MIX TX5 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6679 {"RX MIX TX5 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6680 {"RX MIX TX5 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6681 {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6682 {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6683 {"RX MIX TX5 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6684 {"RX MIX TX5 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6685 {"RX MIX TX5 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6686 {"RX MIX TX5 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6687
6688 {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6689 {"RX MIX TX6 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6690 {"RX MIX TX6 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6691 {"RX MIX TX6 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6692 {"RX MIX TX6 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6693 {"RX MIX TX6 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6694 {"RX MIX TX6 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6695 {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6696 {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6697 {"RX MIX TX6 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6698 {"RX MIX TX6 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6699 {"RX MIX TX6 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6700 {"RX MIX TX6 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6701
6702 {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6703 {"RX MIX TX7 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6704 {"RX MIX TX7 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6705 {"RX MIX TX7 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6706 {"RX MIX TX7 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6707 {"RX MIX TX7 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6708 {"RX MIX TX7 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6709 {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6710 {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6711 {"RX MIX TX7 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6712 {"RX MIX TX7 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6713 {"RX MIX TX7 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6714 {"RX MIX TX7 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6715
6716 {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6717 {"RX MIX TX8 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6718 {"RX MIX TX8 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6719 {"RX MIX TX8 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6720 {"RX MIX TX8 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6721 {"RX MIX TX8 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6722 {"RX MIX TX8 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6723 {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6724 {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6725 {"RX MIX TX8 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6726 {"RX MIX TX8 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6727 {"RX MIX TX8 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6728 {"RX MIX TX8 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6729
6730 {"ADC US MUX0", "US_Switch", "ADC MUX0"},
6731 {"ADC US MUX1", "US_Switch", "ADC MUX1"},
6732 {"ADC US MUX2", "US_Switch", "ADC MUX2"},
6733 {"ADC US MUX3", "US_Switch", "ADC MUX3"},
6734 {"ADC US MUX4", "US_Switch", "ADC MUX4"},
6735 {"ADC US MUX5", "US_Switch", "ADC MUX5"},
6736 {"ADC US MUX6", "US_Switch", "ADC MUX6"},
6737 {"ADC US MUX7", "US_Switch", "ADC MUX7"},
6738 {"ADC US MUX8", "US_Switch", "ADC MUX8"},
6739 {"ADC MUX0", "DMIC", "DMIC MUX0"},
6740 {"ADC MUX0", "AMIC", "AMIC MUX0"},
6741 {"ADC MUX1", "DMIC", "DMIC MUX1"},
6742 {"ADC MUX1", "AMIC", "AMIC MUX1"},
6743 {"ADC MUX2", "DMIC", "DMIC MUX2"},
6744 {"ADC MUX2", "AMIC", "AMIC MUX2"},
6745 {"ADC MUX3", "DMIC", "DMIC MUX3"},
6746 {"ADC MUX3", "AMIC", "AMIC MUX3"},
6747 {"ADC MUX4", "DMIC", "DMIC MUX4"},
6748 {"ADC MUX4", "AMIC", "AMIC MUX4"},
6749 {"ADC MUX5", "DMIC", "DMIC MUX5"},
6750 {"ADC MUX5", "AMIC", "AMIC MUX5"},
6751 {"ADC MUX6", "DMIC", "DMIC MUX6"},
6752 {"ADC MUX6", "AMIC", "AMIC MUX6"},
6753 {"ADC MUX7", "DMIC", "DMIC MUX7"},
6754 {"ADC MUX7", "AMIC", "AMIC MUX7"},
6755 {"ADC MUX8", "DMIC", "DMIC MUX8"},
6756 {"ADC MUX8", "AMIC", "AMIC MUX8"},
6757 {"ADC MUX10", "DMIC", "DMIC MUX10"},
6758 {"ADC MUX10", "AMIC", "AMIC MUX10"},
6759 {"ADC MUX11", "DMIC", "DMIC MUX11"},
6760 {"ADC MUX11", "AMIC", "AMIC MUX11"},
6761 {"ADC MUX12", "DMIC", "DMIC MUX12"},
6762 {"ADC MUX12", "AMIC", "AMIC MUX12"},
6763 {"ADC MUX13", "DMIC", "DMIC MUX13"},
6764 {"ADC MUX13", "AMIC", "AMIC MUX13"},
6765
6766 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"},
6767 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"},
6768 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX12"},
6769 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX13"},
6770 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"},
6771 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"},
6772 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX12"},
6773 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX13"},
6774 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"},
6775 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"},
6776 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX12"},
6777 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX13"},
6778 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"},
6779 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"},
6780 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX12"},
6781 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX13"},
6782 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"},
6783 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"},
6784 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX12"},
6785 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX13"},
6786 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"},
6787 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"},
6788 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX12"},
6789 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX13"},
6790 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"},
6791 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"},
6792 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX12"},
6793 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX13"},
6794 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"},
6795 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"},
6796 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX12"},
6797 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX13"},
6798 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"},
6799 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"},
6800 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX12"},
6801 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX13"},
6802
6803 {"DMIC MUX0", "DMIC0", "DMIC0"},
6804 {"DMIC MUX0", "DMIC1", "DMIC1"},
6805 {"DMIC MUX0", "DMIC2", "DMIC2"},
6806 {"DMIC MUX0", "DMIC3", "DMIC3"},
6807 {"DMIC MUX0", "DMIC4", "DMIC4"},
6808 {"DMIC MUX0", "DMIC5", "DMIC5"},
6809 {"AMIC MUX0", "ADC1", "ADC1"},
6810 {"AMIC MUX0", "ADC2", "ADC2"},
6811 {"AMIC MUX0", "ADC3", "ADC3"},
6812 {"AMIC MUX0", "ADC4", "ADC4"},
6813 {"AMIC MUX0", "ADC5", "ADC5"},
6814 {"AMIC MUX0", "ADC6", "ADC6"},
6815
6816 {"DMIC MUX1", "DMIC0", "DMIC0"},
6817 {"DMIC MUX1", "DMIC1", "DMIC1"},
6818 {"DMIC MUX1", "DMIC2", "DMIC2"},
6819 {"DMIC MUX1", "DMIC3", "DMIC3"},
6820 {"DMIC MUX1", "DMIC4", "DMIC4"},
6821 {"DMIC MUX1", "DMIC5", "DMIC5"},
6822 {"AMIC MUX1", "ADC1", "ADC1"},
6823 {"AMIC MUX1", "ADC2", "ADC2"},
6824 {"AMIC MUX1", "ADC3", "ADC3"},
6825 {"AMIC MUX1", "ADC4", "ADC4"},
6826 {"AMIC MUX1", "ADC5", "ADC5"},
6827 {"AMIC MUX1", "ADC6", "ADC6"},
6828
6829 {"DMIC MUX2", "DMIC0", "DMIC0"},
6830 {"DMIC MUX2", "DMIC1", "DMIC1"},
6831 {"DMIC MUX2", "DMIC2", "DMIC2"},
6832 {"DMIC MUX2", "DMIC3", "DMIC3"},
6833 {"DMIC MUX2", "DMIC4", "DMIC4"},
6834 {"DMIC MUX2", "DMIC5", "DMIC5"},
6835 {"AMIC MUX2", "ADC1", "ADC1"},
6836 {"AMIC MUX2", "ADC2", "ADC2"},
6837 {"AMIC MUX2", "ADC3", "ADC3"},
6838 {"AMIC MUX2", "ADC4", "ADC4"},
6839 {"AMIC MUX2", "ADC5", "ADC5"},
6840 {"AMIC MUX2", "ADC6", "ADC6"},
6841
6842 {"DMIC MUX3", "DMIC0", "DMIC0"},
6843 {"DMIC MUX3", "DMIC1", "DMIC1"},
6844 {"DMIC MUX3", "DMIC2", "DMIC2"},
6845 {"DMIC MUX3", "DMIC3", "DMIC3"},
6846 {"DMIC MUX3", "DMIC4", "DMIC4"},
6847 {"DMIC MUX3", "DMIC5", "DMIC5"},
6848 {"AMIC MUX3", "ADC1", "ADC1"},
6849 {"AMIC MUX3", "ADC2", "ADC2"},
6850 {"AMIC MUX3", "ADC3", "ADC3"},
6851 {"AMIC MUX3", "ADC4", "ADC4"},
6852 {"AMIC MUX3", "ADC5", "ADC5"},
6853 {"AMIC MUX3", "ADC6", "ADC6"},
6854
6855 {"DMIC MUX4", "DMIC0", "DMIC0"},
6856 {"DMIC MUX4", "DMIC1", "DMIC1"},
6857 {"DMIC MUX4", "DMIC2", "DMIC2"},
6858 {"DMIC MUX4", "DMIC3", "DMIC3"},
6859 {"DMIC MUX4", "DMIC4", "DMIC4"},
6860 {"DMIC MUX4", "DMIC5", "DMIC5"},
6861 {"AMIC MUX4", "ADC1", "ADC1"},
6862 {"AMIC MUX4", "ADC2", "ADC2"},
6863 {"AMIC MUX4", "ADC3", "ADC3"},
6864 {"AMIC MUX4", "ADC4", "ADC4"},
6865 {"AMIC MUX4", "ADC5", "ADC5"},
6866 {"AMIC MUX4", "ADC6", "ADC6"},
6867
6868 {"DMIC MUX5", "DMIC0", "DMIC0"},
6869 {"DMIC MUX5", "DMIC1", "DMIC1"},
6870 {"DMIC MUX5", "DMIC2", "DMIC2"},
6871 {"DMIC MUX5", "DMIC3", "DMIC3"},
6872 {"DMIC MUX5", "DMIC4", "DMIC4"},
6873 {"DMIC MUX5", "DMIC5", "DMIC5"},
6874 {"AMIC MUX5", "ADC1", "ADC1"},
6875 {"AMIC MUX5", "ADC2", "ADC2"},
6876 {"AMIC MUX5", "ADC3", "ADC3"},
6877 {"AMIC MUX5", "ADC4", "ADC4"},
6878 {"AMIC MUX5", "ADC5", "ADC5"},
6879 {"AMIC MUX5", "ADC6", "ADC6"},
6880
6881 {"DMIC MUX6", "DMIC0", "DMIC0"},
6882 {"DMIC MUX6", "DMIC1", "DMIC1"},
6883 {"DMIC MUX6", "DMIC2", "DMIC2"},
6884 {"DMIC MUX6", "DMIC3", "DMIC3"},
6885 {"DMIC MUX6", "DMIC4", "DMIC4"},
6886 {"DMIC MUX6", "DMIC5", "DMIC5"},
6887 {"AMIC MUX6", "ADC1", "ADC1"},
6888 {"AMIC MUX6", "ADC2", "ADC2"},
6889 {"AMIC MUX6", "ADC3", "ADC3"},
6890 {"AMIC MUX6", "ADC4", "ADC4"},
6891 {"AMIC MUX6", "ADC5", "ADC5"},
6892 {"AMIC MUX6", "ADC6", "ADC6"},
6893
6894 {"DMIC MUX7", "DMIC0", "DMIC0"},
6895 {"DMIC MUX7", "DMIC1", "DMIC1"},
6896 {"DMIC MUX7", "DMIC2", "DMIC2"},
6897 {"DMIC MUX7", "DMIC3", "DMIC3"},
6898 {"DMIC MUX7", "DMIC4", "DMIC4"},
6899 {"DMIC MUX7", "DMIC5", "DMIC5"},
6900 {"AMIC MUX7", "ADC1", "ADC1"},
6901 {"AMIC MUX7", "ADC2", "ADC2"},
6902 {"AMIC MUX7", "ADC3", "ADC3"},
6903 {"AMIC MUX7", "ADC4", "ADC4"},
6904 {"AMIC MUX7", "ADC5", "ADC5"},
6905 {"AMIC MUX7", "ADC6", "ADC6"},
6906
6907 {"DMIC MUX8", "DMIC0", "DMIC0"},
6908 {"DMIC MUX8", "DMIC1", "DMIC1"},
6909 {"DMIC MUX8", "DMIC2", "DMIC2"},
6910 {"DMIC MUX8", "DMIC3", "DMIC3"},
6911 {"DMIC MUX8", "DMIC4", "DMIC4"},
6912 {"DMIC MUX8", "DMIC5", "DMIC5"},
6913 {"AMIC MUX8", "ADC1", "ADC1"},
6914 {"AMIC MUX8", "ADC2", "ADC2"},
6915 {"AMIC MUX8", "ADC3", "ADC3"},
6916 {"AMIC MUX8", "ADC4", "ADC4"},
6917 {"AMIC MUX8", "ADC5", "ADC5"},
6918 {"AMIC MUX8", "ADC6", "ADC6"},
6919
6920 {"DMIC MUX10", "DMIC0", "DMIC0"},
6921 {"DMIC MUX10", "DMIC1", "DMIC1"},
6922 {"DMIC MUX10", "DMIC2", "DMIC2"},
6923 {"DMIC MUX10", "DMIC3", "DMIC3"},
6924 {"DMIC MUX10", "DMIC4", "DMIC4"},
6925 {"DMIC MUX10", "DMIC5", "DMIC5"},
6926 {"AMIC MUX10", "ADC1", "ADC1"},
6927 {"AMIC MUX10", "ADC2", "ADC2"},
6928 {"AMIC MUX10", "ADC3", "ADC3"},
6929 {"AMIC MUX10", "ADC4", "ADC4"},
6930 {"AMIC MUX10", "ADC5", "ADC5"},
6931 {"AMIC MUX10", "ADC6", "ADC6"},
6932
6933 {"DMIC MUX11", "DMIC0", "DMIC0"},
6934 {"DMIC MUX11", "DMIC1", "DMIC1"},
6935 {"DMIC MUX11", "DMIC2", "DMIC2"},
6936 {"DMIC MUX11", "DMIC3", "DMIC3"},
6937 {"DMIC MUX11", "DMIC4", "DMIC4"},
6938 {"DMIC MUX11", "DMIC5", "DMIC5"},
6939 {"AMIC MUX11", "ADC1", "ADC1"},
6940 {"AMIC MUX11", "ADC2", "ADC2"},
6941 {"AMIC MUX11", "ADC3", "ADC3"},
6942 {"AMIC MUX11", "ADC4", "ADC4"},
6943 {"AMIC MUX11", "ADC5", "ADC5"},
6944 {"AMIC MUX11", "ADC6", "ADC6"},
6945
6946 {"DMIC MUX12", "DMIC0", "DMIC0"},
6947 {"DMIC MUX12", "DMIC1", "DMIC1"},
6948 {"DMIC MUX12", "DMIC2", "DMIC2"},
6949 {"DMIC MUX12", "DMIC3", "DMIC3"},
6950 {"DMIC MUX12", "DMIC4", "DMIC4"},
6951 {"DMIC MUX12", "DMIC5", "DMIC5"},
6952 {"AMIC MUX12", "ADC1", "ADC1"},
6953 {"AMIC MUX12", "ADC2", "ADC2"},
6954 {"AMIC MUX12", "ADC3", "ADC3"},
6955 {"AMIC MUX12", "ADC4", "ADC4"},
6956 {"AMIC MUX12", "ADC5", "ADC5"},
6957 {"AMIC MUX12", "ADC6", "ADC6"},
6958
6959 {"DMIC MUX13", "DMIC0", "DMIC0"},
6960 {"DMIC MUX13", "DMIC1", "DMIC1"},
6961 {"DMIC MUX13", "DMIC2", "DMIC2"},
6962 {"DMIC MUX13", "DMIC3", "DMIC3"},
6963 {"DMIC MUX13", "DMIC4", "DMIC4"},
6964 {"DMIC MUX13", "DMIC5", "DMIC5"},
6965 {"AMIC MUX13", "ADC1", "ADC1"},
6966 {"AMIC MUX13", "ADC2", "ADC2"},
6967 {"AMIC MUX13", "ADC3", "ADC3"},
6968 {"AMIC MUX13", "ADC4", "ADC4"},
6969 {"AMIC MUX13", "ADC5", "ADC5"},
6970 {"AMIC MUX13", "ADC6", "ADC6"},
6971 /* ADC Connections */
6972 {"ADC1", NULL, "AMIC1"},
6973 {"ADC2", NULL, "AMIC2"},
6974 {"ADC3", NULL, "AMIC3"},
6975 {"ADC4", NULL, "AMIC4"},
6976 {"ADC5", NULL, "AMIC5"},
6977 {"ADC6", NULL, "AMIC6"},
6978
6979 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
6980 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
6981 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
6982 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
6983 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
6984 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
6985 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
6986 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
6987 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
6988 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP0"},
6989 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP1"},
6990 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP2"},
6991 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP0"},
6992 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP1"},
6993 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP2"},
6994 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP0"},
6995 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP1"},
6996 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP2"},
6997 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP0"},
6998 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP1"},
6999 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP2"},
7000 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"},
7001 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"},
7002 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"},
7003 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"},
7004 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"},
7005 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"},
7006
7007 {"RX INT0 SEC MIX", NULL, "RX INT0_1 MIX1"},
7008 {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
7009 {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
7010 {"RX INT0 INTERP", NULL, "RX INT0 MIX2"},
7011 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"},
7012 {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"},
7013 {"RX INT0 DAC", NULL, "RX_BIAS"},
7014 {"EAR PA", NULL, "RX INT0 DAC"},
7015 {"EAR", NULL, "EAR PA"},
7016
7017 {"SPL SRC0 MUX", "SRC_IN_HPHL", "RX INT1_1 MIX1"},
7018 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 MIX1"},
7019 {"RX INT1 SPLINE MIX", "HPHL Switch", "SPL SRC0 MUX"},
7020 {"RX INT1_1 NATIVE MUX", "ON", "RX INT1_1 MIX1"},
7021 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 NATIVE MUX"},
7022 {"RX INT1_1 NATIVE MUX", NULL, "RX INT1 NATIVE SUPPLY"},
7023 {"RX INT1 SEC MIX", NULL, "RX INT1 SPLINE MIX"},
7024 {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
7025 {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
7026 {"RX INT1 INTERP", NULL, "RX INT1 MIX2"},
7027 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"},
7028 {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"},
7029 {"RX INT1 DAC", NULL, "RX_BIAS"},
7030 {"HPHL PA", NULL, "RX INT1 DAC"},
7031 {"HPHL", NULL, "HPHL PA"},
7032
7033 {"SPL SRC1 MUX", "SRC_IN_HPHR", "RX INT2_1 MIX1"},
7034 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 MIX1"},
7035 {"RX INT2 SPLINE MIX", "HPHR Switch", "SPL SRC1 MUX"},
7036 {"RX INT2_1 NATIVE MUX", "ON", "RX INT2_1 MIX1"},
7037 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 NATIVE MUX"},
7038 {"RX INT2_1 NATIVE MUX", NULL, "RX INT2 NATIVE SUPPLY"},
7039 {"RX INT2 SEC MIX", NULL, "RX INT2 SPLINE MIX"},
7040 {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
7041 {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
7042 {"RX INT2 INTERP", NULL, "RX INT2 MIX2"},
7043 {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"},
7044 {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"},
7045 {"RX INT2 DAC", NULL, "RX_BIAS"},
7046 {"HPHR PA", NULL, "RX INT2 DAC"},
7047 {"HPHR", NULL, "HPHR PA"},
7048
7049 {"SPL SRC0 MUX", "SRC_IN_LO1", "RX INT3_1 MIX1"},
7050 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 MIX1"},
7051 {"RX INT3 SPLINE MIX", "LO1 Switch", "SPL SRC0 MUX"},
7052 {"RX INT3_1 NATIVE MUX", "ON", "RX INT3_1 MIX1"},
7053 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 NATIVE MUX"},
7054 {"RX INT3_1 NATIVE MUX", NULL, "RX INT3 NATIVE SUPPLY"},
7055 {"RX INT3 SEC MIX", NULL, "RX INT3 SPLINE MIX"},
7056 {"RX INT3 MIX2", NULL, "RX INT3 SEC MIX"},
7057 {"RX INT3 MIX2", NULL, "RX INT3 MIX2 INP"},
7058 {"RX INT3 INTERP", NULL, "RX INT3 MIX2"},
7059 {"RX INT3 DAC", NULL, "RX INT3 INTERP"},
7060 {"RX INT3 DAC", NULL, "RX_BIAS"},
7061 {"LINEOUT1 PA", NULL, "RX INT3 DAC"},
7062 {"LINEOUT1", NULL, "LINEOUT1 PA"},
7063
7064 {"SPL SRC1 MUX", "SRC_IN_LO2", "RX INT4_1 MIX1"},
7065 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 MIX1"},
7066 {"RX INT4 SPLINE MIX", "LO2 Switch", "SPL SRC1 MUX"},
7067 {"RX INT4_1 NATIVE MUX", "ON", "RX INT4_1 MIX1"},
7068 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 NATIVE MUX"},
7069 {"RX INT4_1 NATIVE MUX", NULL, "RX INT4 NATIVE SUPPLY"},
7070 {"RX INT4 SEC MIX", NULL, "RX INT4 SPLINE MIX"},
7071 {"RX INT4 MIX2", NULL, "RX INT4 SEC MIX"},
7072 {"RX INT4 MIX2", NULL, "RX INT4 MIX2 INP"},
7073 {"RX INT4 INTERP", NULL, "RX INT4 MIX2"},
7074 {"RX INT4 DAC", NULL, "RX INT4 INTERP"},
7075 {"RX INT4 DAC", NULL, "RX_BIAS"},
7076 {"LINEOUT2 PA", NULL, "RX INT4 DAC"},
7077 {"LINEOUT2", NULL, "LINEOUT2 PA"},
7078
7079 {"SPL SRC2 MUX", "SRC_IN_LO3", "RX INT5_1 MIX1"},
7080 {"RX INT5 SPLINE MIX", NULL, "RX INT5_1 MIX1"},
7081 {"RX INT5 SPLINE MIX", "LO3 Switch", "SPL SRC2 MUX"},
7082 {"RX INT5 SEC MIX", NULL, "RX INT5 SPLINE MIX"},
7083 {"RX INT5 MIX2", NULL, "RX INT5 SEC MIX"},
7084 {"RX INT5 INTERP", NULL, "RX INT5 MIX2"},
7085
7086 {"RX INT5 VBAT", "LO3 VBAT Enable", "RX INT5 INTERP"},
7087 {"RX INT5 DAC", NULL, "RX INT5 VBAT"},
7088
7089 {"RX INT5 DAC", NULL, "RX INT5 INTERP"},
7090 {"RX INT5 DAC", NULL, "RX_BIAS"},
7091 {"LINEOUT3 PA", NULL, "RX INT5 DAC"},
7092 {"LINEOUT3", NULL, "LINEOUT3 PA"},
7093
7094 {"SPL SRC3 MUX", "SRC_IN_LO4", "RX INT6_1 MIX1"},
7095 {"RX INT6 SPLINE MIX", NULL, "RX INT6_1 MIX1"},
7096 {"RX INT6 SPLINE MIX", "LO4 Switch", "SPL SRC3 MUX"},
7097 {"RX INT6 SEC MIX", NULL, "RX INT6 SPLINE MIX"},
7098 {"RX INT6 MIX2", NULL, "RX INT6 SEC MIX"},
7099 {"RX INT6 INTERP", NULL, "RX INT6 MIX2"},
7100
7101 {"RX INT6 VBAT", "LO4 VBAT Enable", "RX INT6 INTERP"},
7102 {"RX INT6 DAC", NULL, "RX INT6 VBAT"},
7103
7104 {"RX INT6 DAC", NULL, "RX INT6 INTERP"},
7105 {"RX INT6 DAC", NULL, "RX_BIAS"},
7106 {"LINEOUT4 PA", NULL, "RX INT6 DAC"},
7107 {"LINEOUT4", NULL, "LINEOUT4 PA"},
7108
7109 {"SPL SRC2 MUX", "SRC_IN_SPKRL", "RX INT7_1 MIX1"},
7110 {"RX INT7 SPLINE MIX", NULL, "RX INT7_1 MIX1"},
7111 {"RX INT7 SPLINE MIX", "SPKRL Switch", "SPL SRC2 MUX"},
7112 {"RX INT7 SEC MIX", NULL, "RX INT7 SPLINE MIX"},
7113 {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"},
7114 {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"},
7115
7116 {"RX INT7 INTERP", NULL, "RX INT7 MIX2"},
7117
7118 {"RX INT7 VBAT", "SPKRL VBAT Enable", "RX INT7 INTERP"},
7119 {"RX INT7 CHAIN", NULL, "RX INT7 VBAT"},
7120
7121 {"RX INT7 CHAIN", NULL, "RX INT7 INTERP"},
7122 {"RX INT7 CHAIN", NULL, "RX_BIAS"},
7123 {"SPK1 OUT", NULL, "RX INT7 CHAIN"},
7124
7125 {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"},
7126 {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"},
7127 {"SPK1 OUT", NULL, "ANC SPK1 PA"},
7128
7129 {"SPL SRC3 MUX", "SRC_IN_SPKRR", "RX INT8_1 MIX1"},
7130 {"RX INT8 SPLINE MIX", NULL, "RX INT8_1 MIX1"},
7131 {"RX INT8 SPLINE MIX", "SPKRR Switch", "SPL SRC3 MUX"},
7132 {"RX INT8 SEC MIX", NULL, "RX INT8 SPLINE MIX"},
7133 {"RX INT8 INTERP", NULL, "RX INT8 SEC MIX"},
7134
7135 {"RX INT8 VBAT", "SPKRR VBAT Enable", "RX INT8 INTERP"},
7136 {"RX INT8 CHAIN", NULL, "RX INT8 VBAT"},
7137
7138 {"RX INT8 CHAIN", NULL, "RX INT8 INTERP"},
7139 {"RX INT8 CHAIN", NULL, "RX_BIAS"},
7140 {"SPK2 OUT", NULL, "RX INT8 CHAIN"},
7141
7142 {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"},
7143 {"ANC0 FB MUX", "ANC_IN_HPHL", "RX INT1 MIX2"},
7144 {"ANC0 FB MUX", "ANC_IN_LO1", "RX INT3 MIX2"},
7145 {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"},
7146 {"ANC1 FB MUX", "ANC_IN_HPHR", "RX INT2 MIX2"},
7147 {"ANC1 FB MUX", "ANC_IN_LO2", "RX INT4 MIX2"},
7148
7149 {"ANC HPHL Enable", "Switch", "ADC MUX10"},
7150 {"ANC HPHL Enable", "Switch", "ADC MUX11"},
7151 {"RX INT1 MIX2", NULL, "ANC HPHL Enable"},
7152
7153 {"ANC HPHR Enable", "Switch", "ADC MUX12"},
7154 {"ANC HPHR Enable", "Switch", "ADC MUX13"},
7155 {"RX INT2 MIX2", NULL, "ANC HPHR Enable"},
7156
7157 {"ANC EAR Enable", "Switch", "ADC MUX10"},
7158 {"ANC EAR Enable", "Switch", "ADC MUX11"},
7159 {"RX INT0 MIX2", NULL, "ANC EAR Enable"},
7160
7161 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"},
7162 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"},
7163 {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"},
7164
7165 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX10"},
7166 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX11"},
7167 {"RX INT3 MIX2", NULL, "ANC LINEOUT1 Enable"},
7168
7169 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX12"},
7170 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX13"},
7171 {"RX INT4 MIX2", NULL, "ANC LINEOUT2 Enable"},
7172
7173 {"ANC EAR PA", NULL, "RX INT0 DAC"},
7174 {"ANC EAR", NULL, "ANC EAR PA"},
7175 {"ANC HPHL PA", NULL, "RX INT1 DAC"},
7176 {"ANC HPHL", NULL, "ANC HPHL PA"},
7177 {"ANC HPHR PA", NULL, "RX INT2 DAC"},
7178 {"ANC HPHR", NULL, "ANC HPHR PA"},
7179 {"ANC LINEOUT1 PA", NULL, "RX INT3 DAC"},
7180 {"ANC LINEOUT1", NULL, "ANC LINEOUT1 PA"},
7181 {"ANC LINEOUT2 PA", NULL, "RX INT4 DAC"},
7182 {"ANC LINEOUT2", NULL, "ANC LINEOUT2 PA"},
7183
7184 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
7185 {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
7186 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
7187 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
7188 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
7189 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
7190 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
7191 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
7192 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
7193 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
7194 {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"},
7195 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
7196 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
7197 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
7198 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
7199 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
7200 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
7201 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
7202 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
7203 {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"},
7204 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
7205 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
7206 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
7207 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
7208 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
7209 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
7210 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
7211 /* SLIM_MUX("AIF4_PB", "AIF4 PB"),*/
7212 {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
7213 {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
7214 {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
7215 {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
7216 {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
7217 {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
7218 {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
7219 {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
7220
7221 /* SLIM_MUX("AIF_MIX1_PB", "AIF MIX1 PB"),*/
7222 {"SLIM RX0 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7223 {"SLIM RX1 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7224 {"SLIM RX2 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7225 {"SLIM RX3 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7226 {"SLIM RX4 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7227 {"SLIM RX5 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7228 {"SLIM RX6 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7229 {"SLIM RX7 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7230
7231 {"SLIM RX0", NULL, "SLIM RX0 MUX"},
7232 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
7233 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
7234 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
7235 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
7236 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
7237 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
7238 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
7239
7240 {"RX INT0_1 MIX1 INP0", "RX0", "SLIM RX0"},
7241 {"RX INT0_1 MIX1 INP0", "RX1", "SLIM RX1"},
7242 {"RX INT0_1 MIX1 INP0", "RX2", "SLIM RX2"},
7243 {"RX INT0_1 MIX1 INP0", "RX3", "SLIM RX3"},
7244 {"RX INT0_1 MIX1 INP0", "RX4", "SLIM RX4"},
7245 {"RX INT0_1 MIX1 INP0", "RX5", "SLIM RX5"},
7246 {"RX INT0_1 MIX1 INP0", "RX6", "SLIM RX6"},
7247 {"RX INT0_1 MIX1 INP0", "RX7", "SLIM RX7"},
7248 {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
7249 {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
7250 {"RX INT0_1 MIX1 INP1", "RX0", "SLIM RX0"},
7251 {"RX INT0_1 MIX1 INP1", "RX1", "SLIM RX1"},
7252 {"RX INT0_1 MIX1 INP1", "RX2", "SLIM RX2"},
7253 {"RX INT0_1 MIX1 INP1", "RX3", "SLIM RX3"},
7254 {"RX INT0_1 MIX1 INP1", "RX4", "SLIM RX4"},
7255 {"RX INT0_1 MIX1 INP1", "RX5", "SLIM RX5"},
7256 {"RX INT0_1 MIX1 INP1", "RX6", "SLIM RX6"},
7257 {"RX INT0_1 MIX1 INP1", "RX7", "SLIM RX7"},
7258 {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
7259 {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
7260 {"RX INT0_1 MIX1 INP2", "RX0", "SLIM RX0"},
7261 {"RX INT0_1 MIX1 INP2", "RX1", "SLIM RX1"},
7262 {"RX INT0_1 MIX1 INP2", "RX2", "SLIM RX2"},
7263 {"RX INT0_1 MIX1 INP2", "RX3", "SLIM RX3"},
7264 {"RX INT0_1 MIX1 INP2", "RX4", "SLIM RX4"},
7265 {"RX INT0_1 MIX1 INP2", "RX5", "SLIM RX5"},
7266 {"RX INT0_1 MIX1 INP2", "RX6", "SLIM RX6"},
7267 {"RX INT0_1 MIX1 INP2", "RX7", "SLIM RX7"},
7268 {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
7269 {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
7270
7271 /* MIXing path INT0 */
7272 {"RX INT0_2 MUX", "RX0", "SLIM RX0"},
7273 {"RX INT0_2 MUX", "RX1", "SLIM RX1"},
7274 {"RX INT0_2 MUX", "RX2", "SLIM RX2"},
7275 {"RX INT0_2 MUX", "RX3", "SLIM RX3"},
7276 {"RX INT0_2 MUX", "RX4", "SLIM RX4"},
7277 {"RX INT0_2 MUX", "RX5", "SLIM RX5"},
7278 {"RX INT0_2 MUX", "RX6", "SLIM RX6"},
7279 {"RX INT0_2 MUX", "RX7", "SLIM RX7"},
7280 {"RX INT0 SEC MIX", NULL, "RX INT0_2 MUX"},
7281
7282 /* MIXing path INT1 */
7283 {"RX INT1_2 MUX", "RX0", "SLIM RX0"},
7284 {"RX INT1_2 MUX", "RX1", "SLIM RX1"},
7285 {"RX INT1_2 MUX", "RX2", "SLIM RX2"},
7286 {"RX INT1_2 MUX", "RX3", "SLIM RX3"},
7287 {"RX INT1_2 MUX", "RX4", "SLIM RX4"},
7288 {"RX INT1_2 MUX", "RX5", "SLIM RX5"},
7289 {"RX INT1_2 MUX", "RX6", "SLIM RX6"},
7290 {"RX INT1_2 MUX", "RX7", "SLIM RX7"},
7291 {"RX INT1 SEC MIX", NULL, "RX INT1_2 MUX"},
7292
7293 /* MIXing path INT2 */
7294 {"RX INT2_2 MUX", "RX0", "SLIM RX0"},
7295 {"RX INT2_2 MUX", "RX1", "SLIM RX1"},
7296 {"RX INT2_2 MUX", "RX2", "SLIM RX2"},
7297 {"RX INT2_2 MUX", "RX3", "SLIM RX3"},
7298 {"RX INT2_2 MUX", "RX4", "SLIM RX4"},
7299 {"RX INT2_2 MUX", "RX5", "SLIM RX5"},
7300 {"RX INT2_2 MUX", "RX6", "SLIM RX6"},
7301 {"RX INT2_2 MUX", "RX7", "SLIM RX7"},
7302 {"RX INT2 SEC MIX", NULL, "RX INT2_2 MUX"},
7303
7304 /* MIXing path INT3 */
7305 {"RX INT3_2 MUX", "RX0", "SLIM RX0"},
7306 {"RX INT3_2 MUX", "RX1", "SLIM RX1"},
7307 {"RX INT3_2 MUX", "RX2", "SLIM RX2"},
7308 {"RX INT3_2 MUX", "RX3", "SLIM RX3"},
7309 {"RX INT3_2 MUX", "RX4", "SLIM RX4"},
7310 {"RX INT3_2 MUX", "RX5", "SLIM RX5"},
7311 {"RX INT3_2 MUX", "RX6", "SLIM RX6"},
7312 {"RX INT3_2 MUX", "RX7", "SLIM RX7"},
7313 {"RX INT3 SEC MIX", NULL, "RX INT3_2 MUX"},
7314
7315 /* MIXing path INT4 */
7316 {"RX INT4_2 MUX", "RX0", "SLIM RX0"},
7317 {"RX INT4_2 MUX", "RX1", "SLIM RX1"},
7318 {"RX INT4_2 MUX", "RX2", "SLIM RX2"},
7319 {"RX INT4_2 MUX", "RX3", "SLIM RX3"},
7320 {"RX INT4_2 MUX", "RX4", "SLIM RX4"},
7321 {"RX INT4_2 MUX", "RX5", "SLIM RX5"},
7322 {"RX INT4_2 MUX", "RX6", "SLIM RX6"},
7323 {"RX INT4_2 MUX", "RX7", "SLIM RX7"},
7324 {"RX INT4 SEC MIX", NULL, "RX INT4_2 MUX"},
7325
7326 /* MIXing path INT5 */
7327 {"RX INT5_2 MUX", "RX0", "SLIM RX0"},
7328 {"RX INT5_2 MUX", "RX1", "SLIM RX1"},
7329 {"RX INT5_2 MUX", "RX2", "SLIM RX2"},
7330 {"RX INT5_2 MUX", "RX3", "SLIM RX3"},
7331 {"RX INT5_2 MUX", "RX4", "SLIM RX4"},
7332 {"RX INT5_2 MUX", "RX5", "SLIM RX5"},
7333 {"RX INT5_2 MUX", "RX6", "SLIM RX6"},
7334 {"RX INT5_2 MUX", "RX7", "SLIM RX7"},
7335 {"RX INT5 SEC MIX", NULL, "RX INT5_2 MUX"},
7336
7337 /* MIXing path INT6 */
7338 {"RX INT6_2 MUX", "RX0", "SLIM RX0"},
7339 {"RX INT6_2 MUX", "RX1", "SLIM RX1"},
7340 {"RX INT6_2 MUX", "RX2", "SLIM RX2"},
7341 {"RX INT6_2 MUX", "RX3", "SLIM RX3"},
7342 {"RX INT6_2 MUX", "RX4", "SLIM RX4"},
7343 {"RX INT6_2 MUX", "RX5", "SLIM RX5"},
7344 {"RX INT6_2 MUX", "RX6", "SLIM RX6"},
7345 {"RX INT6_2 MUX", "RX7", "SLIM RX7"},
7346 {"RX INT6 SEC MIX", NULL, "RX INT6_2 MUX"},
7347
7348 /* MIXing path INT7 */
7349 {"RX INT7_2 MUX", "RX0", "SLIM RX0"},
7350 {"RX INT7_2 MUX", "RX1", "SLIM RX1"},
7351 {"RX INT7_2 MUX", "RX2", "SLIM RX2"},
7352 {"RX INT7_2 MUX", "RX3", "SLIM RX3"},
7353 {"RX INT7_2 MUX", "RX4", "SLIM RX4"},
7354 {"RX INT7_2 MUX", "RX5", "SLIM RX5"},
7355 {"RX INT7_2 MUX", "RX6", "SLIM RX6"},
7356 {"RX INT7_2 MUX", "RX7", "SLIM RX7"},
7357 {"RX INT7 SEC MIX", NULL, "RX INT7_2 MUX"},
7358
7359 /* MIXing path INT8 */
7360 {"RX INT8_2 MUX", "RX0", "SLIM RX0"},
7361 {"RX INT8_2 MUX", "RX1", "SLIM RX1"},
7362 {"RX INT8_2 MUX", "RX2", "SLIM RX2"},
7363 {"RX INT8_2 MUX", "RX3", "SLIM RX3"},
7364 {"RX INT8_2 MUX", "RX4", "SLIM RX4"},
7365 {"RX INT8_2 MUX", "RX5", "SLIM RX5"},
7366 {"RX INT8_2 MUX", "RX6", "SLIM RX6"},
7367 {"RX INT8_2 MUX", "RX7", "SLIM RX7"},
7368 {"RX INT8 SEC MIX", NULL, "RX INT8_2 MUX"},
7369
7370 {"RX INT1_1 MIX1 INP0", "RX0", "SLIM RX0"},
7371 {"RX INT1_1 MIX1 INP0", "RX1", "SLIM RX1"},
7372 {"RX INT1_1 MIX1 INP0", "RX2", "SLIM RX2"},
7373 {"RX INT1_1 MIX1 INP0", "RX3", "SLIM RX3"},
7374 {"RX INT1_1 MIX1 INP0", "RX4", "SLIM RX4"},
7375 {"RX INT1_1 MIX1 INP0", "RX5", "SLIM RX5"},
7376 {"RX INT1_1 MIX1 INP0", "RX6", "SLIM RX6"},
7377 {"RX INT1_1 MIX1 INP0", "RX7", "SLIM RX7"},
7378 {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
7379 {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
7380 {"RX INT1_1 MIX1 INP1", "RX0", "SLIM RX0"},
7381 {"RX INT1_1 MIX1 INP1", "RX1", "SLIM RX1"},
7382 {"RX INT1_1 MIX1 INP1", "RX2", "SLIM RX2"},
7383 {"RX INT1_1 MIX1 INP1", "RX3", "SLIM RX3"},
7384 {"RX INT1_1 MIX1 INP1", "RX4", "SLIM RX4"},
7385 {"RX INT1_1 MIX1 INP1", "RX5", "SLIM RX5"},
7386 {"RX INT1_1 MIX1 INP1", "RX6", "SLIM RX6"},
7387 {"RX INT1_1 MIX1 INP1", "RX7", "SLIM RX7"},
7388 {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
7389 {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
7390 {"RX INT1_1 MIX1 INP2", "RX0", "SLIM RX0"},
7391 {"RX INT1_1 MIX1 INP2", "RX1", "SLIM RX1"},
7392 {"RX INT1_1 MIX1 INP2", "RX2", "SLIM RX2"},
7393 {"RX INT1_1 MIX1 INP2", "RX3", "SLIM RX3"},
7394 {"RX INT1_1 MIX1 INP2", "RX4", "SLIM RX4"},
7395 {"RX INT1_1 MIX1 INP2", "RX5", "SLIM RX5"},
7396 {"RX INT1_1 MIX1 INP2", "RX6", "SLIM RX6"},
7397 {"RX INT1_1 MIX1 INP2", "RX7", "SLIM RX7"},
7398 {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
7399 {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
7400 {"RX INT2_1 MIX1 INP0", "RX0", "SLIM RX0"},
7401 {"RX INT2_1 MIX1 INP0", "RX1", "SLIM RX1"},
7402 {"RX INT2_1 MIX1 INP0", "RX2", "SLIM RX2"},
7403 {"RX INT2_1 MIX1 INP0", "RX3", "SLIM RX3"},
7404 {"RX INT2_1 MIX1 INP0", "RX4", "SLIM RX4"},
7405 {"RX INT2_1 MIX1 INP0", "RX5", "SLIM RX5"},
7406 {"RX INT2_1 MIX1 INP0", "RX6", "SLIM RX6"},
7407 {"RX INT2_1 MIX1 INP0", "RX7", "SLIM RX7"},
7408 {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
7409 {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
7410 {"RX INT2_1 MIX1 INP1", "RX0", "SLIM RX0"},
7411 {"RX INT2_1 MIX1 INP1", "RX1", "SLIM RX1"},
7412 {"RX INT2_1 MIX1 INP1", "RX2", "SLIM RX2"},
7413 {"RX INT2_1 MIX1 INP1", "RX3", "SLIM RX3"},
7414 {"RX INT2_1 MIX1 INP1", "RX4", "SLIM RX4"},
7415 {"RX INT2_1 MIX1 INP1", "RX5", "SLIM RX5"},
7416 {"RX INT2_1 MIX1 INP1", "RX6", "SLIM RX6"},
7417 {"RX INT2_1 MIX1 INP1", "RX7", "SLIM RX7"},
7418 {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
7419 {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
7420 {"RX INT2_1 MIX1 INP2", "RX0", "SLIM RX0"},
7421 {"RX INT2_1 MIX1 INP2", "RX1", "SLIM RX1"},
7422 {"RX INT2_1 MIX1 INP2", "RX2", "SLIM RX2"},
7423 {"RX INT2_1 MIX1 INP2", "RX3", "SLIM RX3"},
7424 {"RX INT2_1 MIX1 INP2", "RX4", "SLIM RX4"},
7425 {"RX INT2_1 MIX1 INP2", "RX5", "SLIM RX5"},
7426 {"RX INT2_1 MIX1 INP2", "RX6", "SLIM RX6"},
7427 {"RX INT2_1 MIX1 INP2", "RX7", "SLIM RX7"},
7428 {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
7429 {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
7430
7431 {"RX INT3_1 MIX1 INP0", "RX0", "SLIM RX0"},
7432 {"RX INT3_1 MIX1 INP0", "RX1", "SLIM RX1"},
7433 {"RX INT3_1 MIX1 INP0", "RX2", "SLIM RX2"},
7434 {"RX INT3_1 MIX1 INP0", "RX3", "SLIM RX3"},
7435 {"RX INT3_1 MIX1 INP0", "RX4", "SLIM RX4"},
7436 {"RX INT3_1 MIX1 INP0", "RX5", "SLIM RX5"},
7437 {"RX INT3_1 MIX1 INP0", "RX6", "SLIM RX6"},
7438 {"RX INT3_1 MIX1 INP0", "RX7", "SLIM RX7"},
7439 {"RX INT3_1 MIX1 INP0", "IIR0", "IIR0"},
7440 {"RX INT3_1 MIX1 INP0", "IIR1", "IIR1"},
7441 {"RX INT3_1 MIX1 INP1", "RX0", "SLIM RX0"},
7442 {"RX INT3_1 MIX1 INP1", "RX1", "SLIM RX1"},
7443 {"RX INT3_1 MIX1 INP1", "RX2", "SLIM RX2"},
7444 {"RX INT3_1 MIX1 INP1", "RX3", "SLIM RX3"},
7445 {"RX INT3_1 MIX1 INP1", "RX4", "SLIM RX4"},
7446 {"RX INT3_1 MIX1 INP1", "RX5", "SLIM RX5"},
7447 {"RX INT3_1 MIX1 INP1", "RX6", "SLIM RX6"},
7448 {"RX INT3_1 MIX1 INP1", "RX7", "SLIM RX7"},
7449 {"RX INT3_1 MIX1 INP1", "IIR0", "IIR0"},
7450 {"RX INT3_1 MIX1 INP1", "IIR1", "IIR1"},
7451 {"RX INT3_1 MIX1 INP2", "RX0", "SLIM RX0"},
7452 {"RX INT3_1 MIX1 INP2", "RX1", "SLIM RX1"},
7453 {"RX INT3_1 MIX1 INP2", "RX2", "SLIM RX2"},
7454 {"RX INT3_1 MIX1 INP2", "RX3", "SLIM RX3"},
7455 {"RX INT3_1 MIX1 INP2", "RX4", "SLIM RX4"},
7456 {"RX INT3_1 MIX1 INP2", "RX5", "SLIM RX5"},
7457 {"RX INT3_1 MIX1 INP2", "RX6", "SLIM RX6"},
7458 {"RX INT3_1 MIX1 INP2", "RX7", "SLIM RX7"},
7459 {"RX INT3_1 MIX1 INP2", "IIR0", "IIR0"},
7460 {"RX INT3_1 MIX1 INP2", "IIR1", "IIR1"},
7461
7462 {"RX INT4_1 MIX1 INP0", "RX0", "SLIM RX0"},
7463 {"RX INT4_1 MIX1 INP0", "RX1", "SLIM RX1"},
7464 {"RX INT4_1 MIX1 INP0", "RX2", "SLIM RX2"},
7465 {"RX INT4_1 MIX1 INP0", "RX3", "SLIM RX3"},
7466 {"RX INT4_1 MIX1 INP0", "RX4", "SLIM RX4"},
7467 {"RX INT4_1 MIX1 INP0", "RX5", "SLIM RX5"},
7468 {"RX INT4_1 MIX1 INP0", "RX6", "SLIM RX6"},
7469 {"RX INT4_1 MIX1 INP0", "RX7", "SLIM RX7"},
7470 {"RX INT4_1 MIX1 INP0", "IIR0", "IIR0"},
7471 {"RX INT4_1 MIX1 INP0", "IIR1", "IIR1"},
7472 {"RX INT4_1 MIX1 INP1", "RX0", "SLIM RX0"},
7473 {"RX INT4_1 MIX1 INP1", "RX1", "SLIM RX1"},
7474 {"RX INT4_1 MIX1 INP1", "RX2", "SLIM RX2"},
7475 {"RX INT4_1 MIX1 INP1", "RX3", "SLIM RX3"},
7476 {"RX INT4_1 MIX1 INP1", "RX4", "SLIM RX4"},
7477 {"RX INT4_1 MIX1 INP1", "RX5", "SLIM RX5"},
7478 {"RX INT4_1 MIX1 INP1", "RX6", "SLIM RX6"},
7479 {"RX INT4_1 MIX1 INP1", "RX7", "SLIM RX7"},
7480 {"RX INT4_1 MIX1 INP1", "IIR0", "IIR0"},
7481 {"RX INT4_1 MIX1 INP1", "IIR1", "IIR1"},
7482 {"RX INT4_1 MIX1 INP2", "RX0", "SLIM RX0"},
7483 {"RX INT4_1 MIX1 INP2", "RX1", "SLIM RX1"},
7484 {"RX INT4_1 MIX1 INP2", "RX2", "SLIM RX2"},
7485 {"RX INT4_1 MIX1 INP2", "RX3", "SLIM RX3"},
7486 {"RX INT4_1 MIX1 INP2", "RX4", "SLIM RX4"},
7487 {"RX INT4_1 MIX1 INP2", "RX5", "SLIM RX5"},
7488 {"RX INT4_1 MIX1 INP2", "RX6", "SLIM RX6"},
7489 {"RX INT4_1 MIX1 INP2", "RX7", "SLIM RX7"},
7490 {"RX INT4_1 MIX1 INP2", "IIR0", "IIR0"},
7491 {"RX INT4_1 MIX1 INP2", "IIR1", "IIR1"},
7492
7493 {"RX INT5_1 MIX1 INP0", "RX0", "SLIM RX0"},
7494 {"RX INT5_1 MIX1 INP0", "RX1", "SLIM RX1"},
7495 {"RX INT5_1 MIX1 INP0", "RX2", "SLIM RX2"},
7496 {"RX INT5_1 MIX1 INP0", "RX3", "SLIM RX3"},
7497 {"RX INT5_1 MIX1 INP0", "RX4", "SLIM RX4"},
7498 {"RX INT5_1 MIX1 INP0", "RX5", "SLIM RX5"},
7499 {"RX INT5_1 MIX1 INP0", "RX6", "SLIM RX6"},
7500 {"RX INT5_1 MIX1 INP0", "RX7", "SLIM RX7"},
7501 {"RX INT5_1 MIX1 INP0", "IIR0", "IIR0"},
7502 {"RX INT5_1 MIX1 INP0", "IIR1", "IIR1"},
7503 {"RX INT5_1 MIX1 INP1", "RX0", "SLIM RX0"},
7504 {"RX INT5_1 MIX1 INP1", "RX1", "SLIM RX1"},
7505 {"RX INT5_1 MIX1 INP1", "RX2", "SLIM RX2"},
7506 {"RX INT5_1 MIX1 INP1", "RX3", "SLIM RX3"},
7507 {"RX INT5_1 MIX1 INP1", "RX4", "SLIM RX4"},
7508 {"RX INT5_1 MIX1 INP1", "RX5", "SLIM RX5"},
7509 {"RX INT5_1 MIX1 INP1", "RX6", "SLIM RX6"},
7510 {"RX INT5_1 MIX1 INP1", "RX7", "SLIM RX7"},
7511 {"RX INT5_1 MIX1 INP1", "IIR0", "IIR0"},
7512 {"RX INT5_1 MIX1 INP1", "IIR1", "IIR1"},
7513 {"RX INT5_1 MIX1 INP2", "RX0", "SLIM RX0"},
7514 {"RX INT5_1 MIX1 INP2", "RX1", "SLIM RX1"},
7515 {"RX INT5_1 MIX1 INP2", "RX2", "SLIM RX2"},
7516 {"RX INT5_1 MIX1 INP2", "RX3", "SLIM RX3"},
7517 {"RX INT5_1 MIX1 INP2", "RX4", "SLIM RX4"},
7518 {"RX INT5_1 MIX1 INP2", "RX5", "SLIM RX5"},
7519 {"RX INT5_1 MIX1 INP2", "RX6", "SLIM RX6"},
7520 {"RX INT5_1 MIX1 INP2", "RX7", "SLIM RX7"},
7521 {"RX INT5_1 MIX1 INP2", "IIR0", "IIR0"},
7522 {"RX INT5_1 MIX1 INP2", "IIR1", "IIR1"},
7523
7524 {"RX INT6_1 MIX1 INP0", "RX0", "SLIM RX0"},
7525 {"RX INT6_1 MIX1 INP0", "RX1", "SLIM RX1"},
7526 {"RX INT6_1 MIX1 INP0", "RX2", "SLIM RX2"},
7527 {"RX INT6_1 MIX1 INP0", "RX3", "SLIM RX3"},
7528 {"RX INT6_1 MIX1 INP0", "RX4", "SLIM RX4"},
7529 {"RX INT6_1 MIX1 INP0", "RX5", "SLIM RX5"},
7530 {"RX INT6_1 MIX1 INP0", "RX6", "SLIM RX6"},
7531 {"RX INT6_1 MIX1 INP0", "RX7", "SLIM RX7"},
7532 {"RX INT6_1 MIX1 INP0", "IIR0", "IIR0"},
7533 {"RX INT6_1 MIX1 INP0", "IIR1", "IIR1"},
7534 {"RX INT6_1 MIX1 INP1", "RX0", "SLIM RX0"},
7535 {"RX INT6_1 MIX1 INP1", "RX1", "SLIM RX1"},
7536 {"RX INT6_1 MIX1 INP1", "RX2", "SLIM RX2"},
7537 {"RX INT6_1 MIX1 INP1", "RX3", "SLIM RX3"},
7538 {"RX INT6_1 MIX1 INP1", "RX4", "SLIM RX4"},
7539 {"RX INT6_1 MIX1 INP1", "RX5", "SLIM RX5"},
7540 {"RX INT6_1 MIX1 INP1", "RX6", "SLIM RX6"},
7541 {"RX INT6_1 MIX1 INP1", "RX7", "SLIM RX7"},
7542 {"RX INT6_1 MIX1 INP1", "IIR0", "IIR0"},
7543 {"RX INT6_1 MIX1 INP1", "IIR1", "IIR1"},
7544 {"RX INT6_1 MIX1 INP2", "RX0", "SLIM RX0"},
7545 {"RX INT6_1 MIX1 INP2", "RX1", "SLIM RX1"},
7546 {"RX INT6_1 MIX1 INP2", "RX2", "SLIM RX2"},
7547 {"RX INT6_1 MIX1 INP2", "RX3", "SLIM RX3"},
7548 {"RX INT6_1 MIX1 INP2", "RX4", "SLIM RX4"},
7549 {"RX INT6_1 MIX1 INP2", "RX5", "SLIM RX5"},
7550 {"RX INT6_1 MIX1 INP2", "RX6", "SLIM RX6"},
7551 {"RX INT6_1 MIX1 INP2", "RX7", "SLIM RX7"},
7552 {"RX INT6_1 MIX1 INP2", "IIR0", "IIR0"},
7553 {"RX INT6_1 MIX1 INP2", "IIR1", "IIR1"},
7554
7555 {"RX INT7_1 MIX1 INP0", "RX0", "SLIM RX0"},
7556 {"RX INT7_1 MIX1 INP0", "RX1", "SLIM RX1"},
7557 {"RX INT7_1 MIX1 INP0", "RX2", "SLIM RX2"},
7558 {"RX INT7_1 MIX1 INP0", "RX3", "SLIM RX3"},
7559 {"RX INT7_1 MIX1 INP0", "RX4", "SLIM RX4"},
7560 {"RX INT7_1 MIX1 INP0", "RX5", "SLIM RX5"},
7561 {"RX INT7_1 MIX1 INP0", "RX6", "SLIM RX6"},
7562 {"RX INT7_1 MIX1 INP0", "RX7", "SLIM RX7"},
7563 {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"},
7564 {"RX INT7_1 MIX1 INP0", "IIR1", "IIR1"},
7565 {"RX INT7_1 MIX1 INP1", "RX0", "SLIM RX0"},
7566 {"RX INT7_1 MIX1 INP1", "RX1", "SLIM RX1"},
7567 {"RX INT7_1 MIX1 INP1", "RX2", "SLIM RX2"},
7568 {"RX INT7_1 MIX1 INP1", "RX3", "SLIM RX3"},
7569 {"RX INT7_1 MIX1 INP1", "RX4", "SLIM RX4"},
7570 {"RX INT7_1 MIX1 INP1", "RX5", "SLIM RX5"},
7571 {"RX INT7_1 MIX1 INP1", "RX6", "SLIM RX6"},
7572 {"RX INT7_1 MIX1 INP1", "RX7", "SLIM RX7"},
7573 {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"},
7574 {"RX INT7_1 MIX1 INP1", "IIR1", "IIR1"},
7575 {"RX INT7_1 MIX1 INP2", "RX0", "SLIM RX0"},
7576 {"RX INT7_1 MIX1 INP2", "RX1", "SLIM RX1"},
7577 {"RX INT7_1 MIX1 INP2", "RX2", "SLIM RX2"},
7578 {"RX INT7_1 MIX1 INP2", "RX3", "SLIM RX3"},
7579 {"RX INT7_1 MIX1 INP2", "RX4", "SLIM RX4"},
7580 {"RX INT7_1 MIX1 INP2", "RX5", "SLIM RX5"},
7581 {"RX INT7_1 MIX1 INP2", "RX6", "SLIM RX6"},
7582 {"RX INT7_1 MIX1 INP2", "RX7", "SLIM RX7"},
7583 {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"},
7584 {"RX INT7_1 MIX1 INP2", "IIR1", "IIR1"},
7585
7586 {"RX INT8_1 MIX1 INP0", "RX0", "SLIM RX0"},
7587 {"RX INT8_1 MIX1 INP0", "RX1", "SLIM RX1"},
7588 {"RX INT8_1 MIX1 INP0", "RX2", "SLIM RX2"},
7589 {"RX INT8_1 MIX1 INP0", "RX3", "SLIM RX3"},
7590 {"RX INT8_1 MIX1 INP0", "RX4", "SLIM RX4"},
7591 {"RX INT8_1 MIX1 INP0", "RX5", "SLIM RX5"},
7592 {"RX INT8_1 MIX1 INP0", "RX6", "SLIM RX6"},
7593 {"RX INT8_1 MIX1 INP0", "RX7", "SLIM RX7"},
7594 {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"},
7595 {"RX INT8_1 MIX1 INP0", "IIR1", "IIR1"},
7596 {"RX INT8_1 MIX1 INP1", "RX0", "SLIM RX0"},
7597 {"RX INT8_1 MIX1 INP1", "RX1", "SLIM RX1"},
7598 {"RX INT8_1 MIX1 INP1", "RX2", "SLIM RX2"},
7599 {"RX INT8_1 MIX1 INP1", "RX3", "SLIM RX3"},
7600 {"RX INT8_1 MIX1 INP1", "RX4", "SLIM RX4"},
7601 {"RX INT8_1 MIX1 INP1", "RX5", "SLIM RX5"},
7602 {"RX INT8_1 MIX1 INP1", "RX6", "SLIM RX6"},
7603 {"RX INT8_1 MIX1 INP1", "RX7", "SLIM RX7"},
7604 {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"},
7605 {"RX INT8_1 MIX1 INP1", "IIR1", "IIR1"},
7606 {"RX INT8_1 MIX1 INP2", "RX0", "SLIM RX0"},
7607 {"RX INT8_1 MIX1 INP2", "RX1", "SLIM RX1"},
7608 {"RX INT8_1 MIX1 INP2", "RX2", "SLIM RX2"},
7609 {"RX INT8_1 MIX1 INP2", "RX3", "SLIM RX3"},
7610 {"RX INT8_1 MIX1 INP2", "RX4", "SLIM RX4"},
7611 {"RX INT8_1 MIX1 INP2", "RX5", "SLIM RX5"},
7612 {"RX INT8_1 MIX1 INP2", "RX6", "SLIM RX6"},
7613 {"RX INT8_1 MIX1 INP2", "RX7", "SLIM RX7"},
7614 {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"},
7615 {"RX INT8_1 MIX1 INP2", "IIR1", "IIR1"},
7616
7617 /* SRC0, SRC1 inputs to Sidetone RX Mixer
7618 * on RX0, RX1, RX2, RX3, RX4 and RX7 chains
7619 */
7620 {"IIR0", NULL, "IIR0 INP0 MUX"},
7621 {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"},
7622 {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"},
7623 {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"},
7624 {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"},
7625 {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"},
7626 {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"},
7627 {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"},
7628 {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"},
7629 {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"},
7630 {"IIR0 INP0 MUX", "RX0", "SLIM RX0"},
7631 {"IIR0 INP0 MUX", "RX1", "SLIM RX1"},
7632 {"IIR0 INP0 MUX", "RX2", "SLIM RX2"},
7633 {"IIR0 INP0 MUX", "RX3", "SLIM RX3"},
7634 {"IIR0 INP0 MUX", "RX4", "SLIM RX4"},
7635 {"IIR0 INP0 MUX", "RX5", "SLIM RX5"},
7636 {"IIR0 INP0 MUX", "RX6", "SLIM RX6"},
7637 {"IIR0 INP0 MUX", "RX7", "SLIM RX7"},
7638 {"IIR0", NULL, "IIR0 INP1 MUX"},
7639 {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"},
7640 {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"},
7641 {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"},
7642 {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"},
7643 {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"},
7644 {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"},
7645 {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"},
7646 {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"},
7647 {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"},
7648 {"IIR0 INP1 MUX", "RX0", "SLIM RX0"},
7649 {"IIR0 INP1 MUX", "RX1", "SLIM RX1"},
7650 {"IIR0 INP1 MUX", "RX2", "SLIM RX2"},
7651 {"IIR0 INP1 MUX", "RX3", "SLIM RX3"},
7652 {"IIR0 INP1 MUX", "RX4", "SLIM RX4"},
7653 {"IIR0 INP1 MUX", "RX5", "SLIM RX5"},
7654 {"IIR0 INP1 MUX", "RX6", "SLIM RX6"},
7655 {"IIR0 INP1 MUX", "RX7", "SLIM RX7"},
7656 {"IIR0", NULL, "IIR0 INP2 MUX"},
7657 {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"},
7658 {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"},
7659 {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"},
7660 {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"},
7661 {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"},
7662 {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"},
7663 {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"},
7664 {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"},
7665 {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"},
7666 {"IIR0 INP2 MUX", "RX0", "SLIM RX0"},
7667 {"IIR0 INP2 MUX", "RX1", "SLIM RX1"},
7668 {"IIR0 INP2 MUX", "RX2", "SLIM RX2"},
7669 {"IIR0 INP2 MUX", "RX3", "SLIM RX3"},
7670 {"IIR0 INP2 MUX", "RX4", "SLIM RX4"},
7671 {"IIR0 INP2 MUX", "RX5", "SLIM RX5"},
7672 {"IIR0 INP2 MUX", "RX6", "SLIM RX6"},
7673 {"IIR0 INP2 MUX", "RX7", "SLIM RX7"},
7674 {"IIR0", NULL, "IIR0 INP3 MUX"},
7675 {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"},
7676 {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"},
7677 {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"},
7678 {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"},
7679 {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"},
7680 {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"},
7681 {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"},
7682 {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"},
7683 {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"},
7684 {"IIR0 INP3 MUX", "RX0", "SLIM RX0"},
7685 {"IIR0 INP3 MUX", "RX1", "SLIM RX1"},
7686 {"IIR0 INP3 MUX", "RX2", "SLIM RX2"},
7687 {"IIR0 INP3 MUX", "RX3", "SLIM RX3"},
7688 {"IIR0 INP3 MUX", "RX4", "SLIM RX4"},
7689 {"IIR0 INP3 MUX", "RX5", "SLIM RX5"},
7690 {"IIR0 INP3 MUX", "RX6", "SLIM RX6"},
7691 {"IIR0 INP3 MUX", "RX7", "SLIM RX7"},
7692
7693 {"IIR1", NULL, "IIR1 INP0 MUX"},
7694 {"IIR1 INP0 MUX", "DEC0", "ADC MUX0"},
7695 {"IIR1 INP0 MUX", "DEC1", "ADC MUX1"},
7696 {"IIR1 INP0 MUX", "DEC2", "ADC MUX2"},
7697 {"IIR1 INP0 MUX", "DEC3", "ADC MUX3"},
7698 {"IIR1 INP0 MUX", "DEC4", "ADC MUX4"},
7699 {"IIR1 INP0 MUX", "DEC5", "ADC MUX5"},
7700 {"IIR1 INP0 MUX", "DEC6", "ADC MUX6"},
7701 {"IIR1 INP0 MUX", "DEC7", "ADC MUX7"},
7702 {"IIR1 INP0 MUX", "DEC8", "ADC MUX8"},
7703 {"IIR1 INP0 MUX", "RX0", "SLIM RX0"},
7704 {"IIR1 INP0 MUX", "RX1", "SLIM RX1"},
7705 {"IIR1 INP0 MUX", "RX2", "SLIM RX2"},
7706 {"IIR1 INP0 MUX", "RX3", "SLIM RX3"},
7707 {"IIR1 INP0 MUX", "RX4", "SLIM RX4"},
7708 {"IIR1 INP0 MUX", "RX5", "SLIM RX5"},
7709 {"IIR1 INP0 MUX", "RX6", "SLIM RX6"},
7710 {"IIR1 INP0 MUX", "RX7", "SLIM RX7"},
7711 {"IIR1", NULL, "IIR1 INP1 MUX"},
7712 {"IIR1 INP1 MUX", "DEC0", "ADC MUX0"},
7713 {"IIR1 INP1 MUX", "DEC1", "ADC MUX1"},
7714 {"IIR1 INP1 MUX", "DEC2", "ADC MUX2"},
7715 {"IIR1 INP1 MUX", "DEC3", "ADC MUX3"},
7716 {"IIR1 INP1 MUX", "DEC4", "ADC MUX4"},
7717 {"IIR1 INP1 MUX", "DEC5", "ADC MUX5"},
7718 {"IIR1 INP1 MUX", "DEC6", "ADC MUX6"},
7719 {"IIR1 INP1 MUX", "DEC7", "ADC MUX7"},
7720 {"IIR1 INP1 MUX", "DEC8", "ADC MUX8"},
7721 {"IIR1 INP1 MUX", "RX0", "SLIM RX0"},
7722 {"IIR1 INP1 MUX", "RX1", "SLIM RX1"},
7723 {"IIR1 INP1 MUX", "RX2", "SLIM RX2"},
7724 {"IIR1 INP1 MUX", "RX3", "SLIM RX3"},
7725 {"IIR1 INP1 MUX", "RX4", "SLIM RX4"},
7726 {"IIR1 INP1 MUX", "RX5", "SLIM RX5"},
7727 {"IIR1 INP1 MUX", "RX6", "SLIM RX6"},
7728 {"IIR1 INP1 MUX", "RX7", "SLIM RX7"},
7729 {"IIR1", NULL, "IIR1 INP2 MUX"},
7730 {"IIR1 INP2 MUX", "DEC0", "ADC MUX0"},
7731 {"IIR1 INP2 MUX", "DEC1", "ADC MUX1"},
7732 {"IIR1 INP2 MUX", "DEC2", "ADC MUX2"},
7733 {"IIR1 INP2 MUX", "DEC3", "ADC MUX3"},
7734 {"IIR1 INP2 MUX", "DEC4", "ADC MUX4"},
7735 {"IIR1 INP2 MUX", "DEC5", "ADC MUX5"},
7736 {"IIR1 INP2 MUX", "DEC6", "ADC MUX6"},
7737 {"IIR1 INP2 MUX", "DEC7", "ADC MUX7"},
7738 {"IIR1 INP2 MUX", "DEC8", "ADC MUX8"},
7739 {"IIR1 INP2 MUX", "RX0", "SLIM RX0"},
7740 {"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
7741 {"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
7742 {"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
7743 {"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
7744 {"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
7745 {"IIR1 INP2 MUX", "RX6", "SLIM RX6"},
7746 {"IIR1 INP2 MUX", "RX7", "SLIM RX7"},
7747 {"IIR1", NULL, "IIR1 INP3 MUX"},
7748 {"IIR1 INP3 MUX", "DEC0", "ADC MUX0"},
7749 {"IIR1 INP3 MUX", "DEC1", "ADC MUX1"},
7750 {"IIR1 INP3 MUX", "DEC2", "ADC MUX2"},
7751 {"IIR1 INP3 MUX", "DEC3", "ADC MUX3"},
7752 {"IIR1 INP3 MUX", "DEC4", "ADC MUX4"},
7753 {"IIR1 INP3 MUX", "DEC5", "ADC MUX5"},
7754 {"IIR1 INP3 MUX", "DEC6", "ADC MUX6"},
7755 {"IIR1 INP3 MUX", "DEC7", "ADC MUX7"},
7756 {"IIR1 INP3 MUX", "DEC8", "ADC MUX8"},
7757 {"IIR1 INP3 MUX", "RX0", "SLIM RX0"},
7758 {"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
7759 {"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
7760 {"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
7761 {"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
7762 {"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
7763 {"IIR1 INP3 MUX", "RX6", "SLIM RX6"},
7764 {"IIR1 INP3 MUX", "RX7", "SLIM RX7"},
7765
7766 {"SRC0", NULL, "IIR0"},
7767 {"SRC1", NULL, "IIR1"},
7768 {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
7769 {"RX INT0 MIX2 INP", "SRC1", "SRC1"},
7770 {"RX INT1 MIX2 INP", "SRC0", "SRC0"},
7771 {"RX INT1 MIX2 INP", "SRC1", "SRC1"},
7772 {"RX INT2 MIX2 INP", "SRC0", "SRC0"},
7773 {"RX INT2 MIX2 INP", "SRC1", "SRC1"},
7774 {"RX INT3 MIX2 INP", "SRC0", "SRC0"},
7775 {"RX INT3 MIX2 INP", "SRC1", "SRC1"},
7776 {"RX INT4 MIX2 INP", "SRC0", "SRC0"},
7777 {"RX INT4 MIX2 INP", "SRC1", "SRC1"},
7778 {"RX INT7 MIX2 INP", "SRC0", "SRC0"},
7779 {"RX INT7 MIX2 INP", "SRC1", "SRC1"},
7780};
7781
7782static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol,
7783 struct snd_ctl_elem_value *ucontrol)
7784{
7785 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7786 u16 amic_reg;
7787
7788 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7789 amic_reg = WCD9335_ANA_AMIC1;
7790 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7791 amic_reg = WCD9335_ANA_AMIC3;
7792 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7793 amic_reg = WCD9335_ANA_AMIC5;
7794
7795 ucontrol->value.integer.value[0] =
7796 (snd_soc_read(codec, amic_reg) & WCD9335_AMIC_PWR_LVL_MASK) >>
7797 WCD9335_AMIC_PWR_LVL_SHIFT;
7798
7799 return 0;
7800}
7801
7802static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol,
7803 struct snd_ctl_elem_value *ucontrol)
7804{
7805 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7806 u32 mode_val;
7807 u16 amic_reg;
7808
7809 mode_val = ucontrol->value.enumerated.item[0];
7810
7811 dev_dbg(codec->dev, "%s: mode: %d\n",
7812 __func__, mode_val);
7813
7814 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7815 amic_reg = WCD9335_ANA_AMIC1;
7816 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7817 amic_reg = WCD9335_ANA_AMIC3;
7818 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7819 amic_reg = WCD9335_ANA_AMIC5;
7820
7821 snd_soc_update_bits(codec, amic_reg, WCD9335_AMIC_PWR_LVL_MASK,
7822 mode_val << WCD9335_AMIC_PWR_LVL_SHIFT);
7823
7824 return 0;
7825}
7826
7827static int tasha_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
7828 struct snd_ctl_elem_value *ucontrol)
7829{
7830 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7831 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7832
7833 ucontrol->value.integer.value[0] = tasha->hph_mode;
7834 return 0;
7835}
7836
7837static int tasha_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
7838 struct snd_ctl_elem_value *ucontrol)
7839{
7840 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7841 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7842 u32 mode_val;
7843
7844 mode_val = ucontrol->value.enumerated.item[0];
7845
7846 dev_dbg(codec->dev, "%s: mode: %d\n",
7847 __func__, mode_val);
7848
7849 if (mode_val == 0) {
7850 dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H HiFi\n",
7851 __func__);
7852 mode_val = CLS_H_HIFI;
7853 }
7854 tasha->hph_mode = mode_val;
7855 return 0;
7856}
7857
7858static const char *const tasha_conn_mad_text[] = {
7859 "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6",
7860 "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4",
7861 "DMIC5", "NOTUSED3", "NOTUSED4"
7862};
7863
7864static const struct soc_enum tasha_conn_mad_enum =
7865 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_conn_mad_text),
7866 tasha_conn_mad_text);
7867
7868static int tasha_enable_ldo_h_get(struct snd_kcontrol *kcontrol,
7869 struct snd_ctl_elem_value *ucontrol)
7870{
7871 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7872 u8 val = 0;
7873
7874 if (codec)
7875 val = snd_soc_read(codec, WCD9335_LDOH_MODE) & 0x80;
7876
7877 ucontrol->value.integer.value[0] = !!val;
7878
7879 return 0;
7880}
7881
7882static int tasha_enable_ldo_h_put(struct snd_kcontrol *kcontrol,
7883 struct snd_ctl_elem_value *ucontrol)
7884{
7885 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7886 int value = ucontrol->value.integer.value[0];
7887 bool enable;
7888
7889 enable = !!value;
7890 if (codec)
7891 tasha_codec_enable_standalone_ldo_h(codec, enable);
7892
7893 return 0;
7894}
7895
7896static int tasha_mad_input_get(struct snd_kcontrol *kcontrol,
7897 struct snd_ctl_elem_value *ucontrol)
7898{
7899 u8 tasha_mad_input;
7900 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7901
7902 tasha_mad_input = snd_soc_read(codec,
7903 WCD9335_SOC_MAD_INP_SEL) & 0x0F;
7904 ucontrol->value.integer.value[0] = tasha_mad_input;
7905
7906 dev_dbg(codec->dev,
7907 "%s: tasha_mad_input = %s\n", __func__,
7908 tasha_conn_mad_text[tasha_mad_input]);
7909 return 0;
7910}
7911
7912static int tasha_mad_input_put(struct snd_kcontrol *kcontrol,
7913 struct snd_ctl_elem_value *ucontrol)
7914{
7915 u8 tasha_mad_input;
7916 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7917 struct snd_soc_card *card = codec->component.card;
7918 char mad_amic_input_widget[6];
7919 const char *mad_input_widget;
7920 const char *source_widget = NULL;
7921 u32 adc, i, mic_bias_found = 0;
7922 int ret = 0;
7923 char *mad_input;
7924
7925 tasha_mad_input = ucontrol->value.integer.value[0];
7926
Karthikeyan Mani63955b42016-12-14 11:46:35 -08007927 if (tasha_mad_input >= ARRAY_SIZE(tasha_conn_mad_text)) {
7928 dev_err(codec->dev,
7929 "%s: tasha_mad_input = %d out of bounds\n",
7930 __func__, tasha_mad_input);
7931 return -EINVAL;
7932 }
7933
Banajit Goswamide8271c2017-01-18 00:28:59 -08007934 if (!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED1") ||
7935 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED2") ||
7936 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED3") ||
7937 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED4")) {
7938 dev_err(codec->dev,
7939 "%s: Unsupported tasha_mad_input = %s\n",
7940 __func__, tasha_conn_mad_text[tasha_mad_input]);
7941 return -EINVAL;
7942 }
7943
7944 if (strnstr(tasha_conn_mad_text[tasha_mad_input],
7945 "ADC", sizeof("ADC"))) {
7946 mad_input = strpbrk(tasha_conn_mad_text[tasha_mad_input],
7947 "123456");
7948 if (!mad_input) {
7949 dev_err(codec->dev, "%s: Invalid MAD input %s\n",
7950 __func__,
7951 tasha_conn_mad_text[tasha_mad_input]);
7952 return -EINVAL;
7953 }
7954 ret = kstrtouint(mad_input, 10, &adc);
7955 if ((ret < 0) || (adc > 6)) {
7956 dev_err(codec->dev,
7957 "%s: Invalid ADC = %s\n", __func__,
7958 tasha_conn_mad_text[tasha_mad_input]);
7959 ret = -EINVAL;
7960 }
7961
7962 snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc);
7963
7964 mad_input_widget = mad_amic_input_widget;
7965 } else {
7966 /* DMIC type input widget*/
7967 mad_input_widget = tasha_conn_mad_text[tasha_mad_input];
7968 }
7969
7970 dev_dbg(codec->dev,
7971 "%s: tasha input widget = %s\n", __func__,
7972 mad_input_widget);
7973
7974 for (i = 0; i < card->num_of_dapm_routes; i++) {
7975 if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) {
7976 source_widget = card->of_dapm_routes[i].source;
7977 if (!source_widget) {
7978 dev_err(codec->dev,
7979 "%s: invalid source widget\n",
7980 __func__);
7981 return -EINVAL;
7982 }
7983
7984 if (strnstr(source_widget,
7985 "MIC BIAS1", sizeof("MIC BIAS1"))) {
7986 mic_bias_found = 1;
7987 break;
7988 } else if (strnstr(source_widget,
7989 "MIC BIAS2", sizeof("MIC BIAS2"))) {
7990 mic_bias_found = 2;
7991 break;
7992 } else if (strnstr(source_widget,
7993 "MIC BIAS3", sizeof("MIC BIAS3"))) {
7994 mic_bias_found = 3;
7995 break;
7996 } else if (strnstr(source_widget,
7997 "MIC BIAS4", sizeof("MIC BIAS4"))) {
7998 mic_bias_found = 4;
7999 break;
8000 }
8001 }
8002 }
8003
8004 if (!mic_bias_found) {
8005 dev_err(codec->dev,
8006 "%s: mic bias source not found for input = %s\n",
8007 __func__, mad_input_widget);
8008 return -EINVAL;
8009 }
8010
8011 dev_dbg(codec->dev,
8012 "%s: mic_bias found = %d\n", __func__,
8013 mic_bias_found);
8014
8015 snd_soc_update_bits(codec, WCD9335_SOC_MAD_INP_SEL,
8016 0x0F, tasha_mad_input);
8017 snd_soc_update_bits(codec, WCD9335_ANA_MAD_SETUP,
8018 0x07, mic_bias_found);
8019
8020 return 0;
8021}
8022
8023static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol,
8024 struct snd_ctl_elem_value *ucontrol)
8025{
8026 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8027 u16 ctl_reg;
8028 u8 reg_val, pinctl_position;
8029
8030 pinctl_position = ((struct soc_multi_mixer_control *)
8031 kcontrol->private_value)->shift;
8032 switch (pinctl_position >> 3) {
8033 case 0:
8034 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
8035 break;
8036 case 1:
8037 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
8038 break;
8039 case 2:
8040 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
8041 break;
8042 case 3:
8043 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
8044 break;
8045 default:
8046 dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
8047 __func__, pinctl_position);
8048 return -EINVAL;
8049 }
8050
8051 reg_val = snd_soc_read(codec, ctl_reg);
8052 reg_val = (reg_val >> (pinctl_position & 0x07)) & 0x1;
8053 ucontrol->value.integer.value[0] = reg_val;
8054
8055 return 0;
8056}
8057
8058static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol,
8059 struct snd_ctl_elem_value *ucontrol)
8060{
8061 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8062 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8063 u16 ctl_reg, cfg_reg;
8064 u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask;
8065
8066 /* 1- high or low; 0- high Z */
8067 pinctl_mode = ucontrol->value.integer.value[0];
8068 pinctl_position = ((struct soc_multi_mixer_control *)
8069 kcontrol->private_value)->shift;
8070
8071 switch (pinctl_position >> 3) {
8072 case 0:
8073 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
8074 break;
8075 case 1:
8076 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
8077 break;
8078 case 2:
8079 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
8080 break;
8081 case 3:
8082 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
8083 break;
8084 default:
8085 dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
8086 __func__, pinctl_position);
8087 return -EINVAL;
8088 }
8089
8090 ctl_val = pinctl_mode << (pinctl_position & 0x07);
8091 mask = 1 << (pinctl_position & 0x07);
8092 snd_soc_update_bits(codec, ctl_reg, mask, ctl_val);
8093
8094 cfg_reg = WCD9335_TLMM_BIST_MODE_PINCFG + pinctl_position;
8095 if (!pinctl_mode) {
8096 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
8097 cfg_val = 0x4;
8098 else
8099 cfg_val = 0xC;
8100 } else {
8101 cfg_val = 0;
8102 }
8103 snd_soc_update_bits(codec, cfg_reg, 0x07, cfg_val);
8104
8105 dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n",
8106 __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val);
8107
8108 return 0;
8109}
8110
8111static void wcd_vbat_adc_out_config_2_0(struct wcd_vbat *vbat,
8112 struct snd_soc_codec *codec)
8113{
8114 u8 val1, val2;
8115
8116 /*
8117 * Measure dcp1 by using "ALT" branch of band gap
8118 * voltage(Vbg) and use it in FAST mode
8119 */
8120 snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x82, 0x82);
8121 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10);
8122 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x01);
8123 snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x80);
8124 snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x00);
8125
8126 snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x20);
8127 /* Wait 100 usec after calibration select as Vbg */
8128 usleep_range(100, 110);
8129
8130 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40);
8131 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8132 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8133 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00);
8134
8135 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8136
8137 snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x40, 0x40);
8138 /* Wait 100 usec after selecting Vbg as 1.05V */
8139 usleep_range(100, 110);
8140
8141 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40);
8142 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8143 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8144 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00);
8145
8146 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8147
8148 dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
8149 __func__, vbat->dcp1, vbat->dcp2);
8150
8151 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8152 /* Wait 100 usec after selecting Vbg as 0.85V */
8153 usleep_range(100, 110);
8154
8155 snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x00);
8156 snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x20);
8157 snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x00);
8158
8159 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x00);
8160 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x00);
8161}
8162
8163static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat,
8164 struct snd_soc_codec *codec)
8165{
8166 u8 val1, val2;
8167
8168 /*
8169 * Measure dcp1 by applying band gap voltage(Vbg)
8170 * of 0.85V
8171 */
8172 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x20);
8173 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8174 snd_soc_write(codec, WCD9335_BIAS_VBG_FINE_ADJ, 0x05);
8175 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0);
8176 /* Wait 2 sec after enabling band gap bias */
8177 usleep_range(2000000, 2000100);
8178
8179 snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x82);
8180 snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x87);
8181 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10);
8182 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0D);
8183 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01);
8184
8185 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80);
8186 snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xDE);
8187 snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x3C);
8188 /* Wait 1 msec after calibration select as Vbg */
8189 usleep_range(1000, 1100);
8190
8191 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0);
8192 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8193 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8194 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8195
8196 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8197
8198 /*
8199 * Measure dcp2 by applying band gap voltage(Vbg)
8200 * of 1.05V
8201 */
8202 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8203 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0);
8204 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x68);
8205 /* Wait 2 msec after selecting Vbg as 1.05V */
8206 usleep_range(2000, 2100);
8207
8208 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8209 /* Wait 1 sec after enabling band gap bias */
8210 usleep_range(1000000, 1000100);
8211
8212 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0);
8213 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8214 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8215 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8216
8217 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8218
8219 dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
8220 __func__, vbat->dcp1, vbat->dcp2);
8221
8222 /* Reset the Vbat ADC configuration */
8223 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8224 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0);
8225
8226 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8227 /* Wait 2 msec after selecting Vbg as 0.85V */
8228 usleep_range(2000, 2100);
8229
8230 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0);
8231 /* Wait 1 sec after enabling band gap bias */
8232 usleep_range(1000000, 1000100);
8233
8234 snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x1C);
8235 snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xFE);
8236 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8237 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00);
8238
8239 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00);
8240 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x00);
8241 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0A);
8242}
8243
8244static void wcd_vbat_adc_out_config(struct wcd_vbat *vbat,
8245 struct snd_soc_codec *codec)
8246{
8247 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
8248
8249 if (!vbat->adc_config) {
8250 tasha_cdc_mclk_enable(codec, true, false);
8251
8252 if (TASHA_IS_2_0(wcd9xxx))
8253 wcd_vbat_adc_out_config_2_0(vbat, codec);
8254 else
8255 wcd_vbat_adc_out_config_1_x(vbat, codec);
8256
8257 tasha_cdc_mclk_enable(codec, false, false);
8258 vbat->adc_config = true;
8259 }
8260}
8261
8262static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec)
8263{
8264 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8265 struct firmware_cal *hwdep_cal = NULL;
8266 struct vbat_monitor_reg *vbat_reg_ptr = NULL;
8267 const void *data;
8268 size_t cal_size, vbat_size_remaining;
8269 int ret = 0, i;
8270 u32 vbat_writes_size = 0;
8271 u16 reg;
8272 u8 mask, val, old_val;
8273
8274 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_VBAT_CAL);
8275 if (hwdep_cal) {
8276 data = hwdep_cal->data;
8277 cal_size = hwdep_cal->size;
8278 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
8279 __func__);
8280 } else {
8281 dev_err(codec->dev, "%s: Vbat cal not received\n",
8282 __func__);
8283 ret = -EINVAL;
8284 goto done;
8285 }
8286
8287 if (cal_size < sizeof(*vbat_reg_ptr)) {
8288 dev_err(codec->dev,
8289 "%s: Incorrect size %zd for Vbat Cal, expected %zd\n",
8290 __func__, cal_size, sizeof(*vbat_reg_ptr));
8291 ret = -EINVAL;
8292 goto done;
8293 }
8294
8295 vbat_reg_ptr = (struct vbat_monitor_reg *) (data);
8296
8297 if (!vbat_reg_ptr) {
8298 dev_err(codec->dev,
8299 "%s: Invalid calibration data for Vbat\n",
8300 __func__);
8301 ret = -EINVAL;
8302 goto done;
8303 }
8304
8305 vbat_writes_size = vbat_reg_ptr->size;
8306 vbat_size_remaining = cal_size - sizeof(u32);
8307 dev_dbg(codec->dev, "%s: vbat_writes_sz: %d, vbat_sz_remaining: %zd\n",
8308 __func__, vbat_writes_size, vbat_size_remaining);
8309
8310 if ((vbat_writes_size * TASHA_PACKED_REG_SIZE)
8311 > vbat_size_remaining) {
8312 pr_err("%s: Incorrect Vbat calibration data\n", __func__);
8313 ret = -EINVAL;
8314 goto done;
8315 }
8316
8317 for (i = 0 ; i < vbat_writes_size; i++) {
8318 TASHA_CODEC_UNPACK_ENTRY(vbat_reg_ptr->writes[i],
8319 reg, mask, val);
8320 old_val = snd_soc_read(codec, reg);
8321 snd_soc_write(codec, reg, (old_val & ~mask) | (val & mask));
8322 }
8323
8324done:
8325 return ret;
8326}
8327
8328static int tasha_vbat_adc_data_get(struct snd_kcontrol *kcontrol,
8329 struct snd_ctl_elem_value *ucontrol)
8330{
8331 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8332 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8333
8334 wcd_vbat_adc_out_config(&tasha->vbat, codec);
8335
8336 ucontrol->value.integer.value[0] = tasha->vbat.dcp1;
8337 ucontrol->value.integer.value[1] = tasha->vbat.dcp2;
8338
8339 dev_dbg(codec->dev,
8340 "%s: Vbat ADC output values, Dcp1 : %lu, Dcp2: %lu\n",
8341 __func__, ucontrol->value.integer.value[0],
8342 ucontrol->value.integer.value[1]);
8343
8344 return 0;
8345}
8346
8347static const char * const tasha_vbat_gsm_mode_text[] = {
8348 "OFF", "ON"};
8349
8350static const struct soc_enum tasha_vbat_gsm_mode_enum =
8351 SOC_ENUM_SINGLE_EXT(2, tasha_vbat_gsm_mode_text);
8352
8353static int tasha_vbat_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
8354 struct snd_ctl_elem_value *ucontrol)
8355{
8356 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8357
8358 ucontrol->value.integer.value[0] =
8359 ((snd_soc_read(codec, WCD9335_CDC_VBAT_VBAT_CFG) & 0x04) ?
8360 1 : 0);
8361
8362 dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
8363 ucontrol->value.integer.value[0]);
8364
8365 return 0;
8366}
8367
8368static int tasha_vbat_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
8369 struct snd_ctl_elem_value *ucontrol)
8370{
8371 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8372
8373 dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
8374 ucontrol->value.integer.value[0]);
8375
8376 /* Set Vbat register configuration for GSM mode bit based on value */
8377 if (ucontrol->value.integer.value[0])
8378 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG,
8379 0x04, 0x04);
8380 else
8381 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG,
8382 0x04, 0x00);
8383
8384 return 0;
8385}
8386
8387static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w,
8388 struct snd_kcontrol *kcontrol,
8389 int event)
8390{
8391 int ret = 0;
8392 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
8393 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8394 u16 vbat_path_ctl, vbat_cfg, vbat_path_cfg;
8395
8396 vbat_path_ctl = WCD9335_CDC_VBAT_VBAT_PATH_CTL;
8397 vbat_cfg = WCD9335_CDC_VBAT_VBAT_CFG;
8398 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8399
8400 if (!strcmp(w->name, "RX INT8 VBAT"))
8401 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8402 else if (!strcmp(w->name, "RX INT7 VBAT"))
8403 vbat_path_cfg = WCD9335_CDC_RX7_RX_PATH_CFG1;
8404 else if (!strcmp(w->name, "RX INT6 VBAT"))
8405 vbat_path_cfg = WCD9335_CDC_RX6_RX_PATH_CFG1;
8406 else if (!strcmp(w->name, "RX INT5 VBAT"))
8407 vbat_path_cfg = WCD9335_CDC_RX5_RX_PATH_CFG1;
8408
8409 switch (event) {
8410 case SND_SOC_DAPM_PRE_PMU:
8411 ret = tasha_update_vbat_reg_config(codec);
8412 if (ret) {
8413 dev_dbg(codec->dev,
8414 "%s : VBAT isn't calibrated, So not enabling it\n",
8415 __func__);
8416 return 0;
8417 }
8418 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80);
8419 snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02);
8420 snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x10);
8421 snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x01);
8422 tasha->vbat.is_enabled = true;
8423 break;
8424 case SND_SOC_DAPM_POST_PMD:
8425 if (tasha->vbat.is_enabled) {
8426 snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x00);
8427 snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x00);
8428 snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00);
8429 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00);
8430 tasha->vbat.is_enabled = false;
8431 }
8432 break;
8433 };
8434
8435 return ret;
8436}
8437
8438static const char * const rx_hph_mode_mux_text[] = {
8439 "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI"
8440};
8441
8442static const struct soc_enum rx_hph_mode_mux_enum =
8443 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
8444 rx_hph_mode_mux_text);
8445
8446static const char * const amic_pwr_lvl_text[] = {
8447 "LOW_PWR", "DEFAULT", "HIGH_PERF"
8448};
8449
8450static const struct soc_enum amic_pwr_lvl_enum =
8451 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(amic_pwr_lvl_text),
8452 amic_pwr_lvl_text);
8453
8454static const struct snd_kcontrol_new tasha_snd_controls[] = {
8455 SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
8456 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8457 SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
8458 0, -84, 40, digital_gain),
8459 SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
8460 0, -84, 40, digital_gain),
8461 SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
8462 0, -84, 40, digital_gain),
8463 SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
8464 0, -84, 40, digital_gain),
8465 SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
8466 0, -84, 40, digital_gain),
8467 SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
8468 0, -84, 40, digital_gain),
8469 SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
8470 0, -84, 40, digital_gain),
8471 SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
8472 0, -84, 40, digital_gain),
8473
8474 SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
8475 WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
8476 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8477 SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
8478 WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
8479 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8480 SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
8481 WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
8482 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8483 SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
8484 WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
8485 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8486 SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
8487 WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
8488 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8489 SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
8490 WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
8491 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8492 SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
8493 WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
8494 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8495 SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
8496 WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
8497 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8498 SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
8499 WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
8500 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8501
8502 SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9335_CDC_TX0_TX_VOL_CTL, 0,
8503 -84, 40, digital_gain),
8504 SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9335_CDC_TX1_TX_VOL_CTL, 0,
8505 -84, 40, digital_gain),
8506 SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9335_CDC_TX2_TX_VOL_CTL, 0,
8507 -84, 40, digital_gain),
8508 SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9335_CDC_TX3_TX_VOL_CTL, 0,
8509 -84, 40, digital_gain),
8510 SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9335_CDC_TX4_TX_VOL_CTL, 0,
8511 -84, 40, digital_gain),
8512 SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9335_CDC_TX5_TX_VOL_CTL, 0,
8513 -84, 40, digital_gain),
8514 SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9335_CDC_TX6_TX_VOL_CTL, 0,
8515 -84, 40, digital_gain),
8516 SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9335_CDC_TX7_TX_VOL_CTL, 0,
8517 -84, 40, digital_gain),
8518 SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9335_CDC_TX8_TX_VOL_CTL, 0,
8519 -84, 40, digital_gain),
8520
8521 SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
8522 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84,
8523 40, digital_gain),
8524 SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
8525 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84,
8526 40, digital_gain),
8527 SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
8528 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84,
8529 40, digital_gain),
8530 SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
8531 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84,
8532 40, digital_gain),
8533 SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
8534 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84,
8535 40, digital_gain),
8536 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
8537 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84,
8538 40, digital_gain),
8539 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
8540 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84,
8541 40, digital_gain),
8542 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
8543 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84,
8544 40, digital_gain),
8545
8546 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tasha_get_anc_slot,
8547 tasha_put_anc_slot),
8548 SOC_ENUM_EXT("ANC Function", tasha_anc_func_enum, tasha_get_anc_func,
8549 tasha_put_anc_func),
8550
8551 SOC_ENUM_EXT("CLK MODE", tasha_clkmode_enum, tasha_get_clkmode,
8552 tasha_put_clkmode),
8553
8554 SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
8555 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
8556 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
8557 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
8558 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
8559 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
8560 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
8561 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
8562 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
8563
8564 SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
8565 SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
8566 SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
8567 SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
8568 SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
8569 SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
8570 SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
8571 SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
8572 SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
8573 SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
8574 SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
8575 SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
8576 SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
8577 SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
8578 SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
8579 SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
8580 SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
8581 SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
8582
8583 SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
8584 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8585 SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
8586 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8587 SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
8588 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8589 SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
8590 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8591 SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
8592 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8593 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
8594 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8595 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
8596 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8597 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
8598 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8599 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
8600 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8601 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
8602 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8603
8604 SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
8605 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8606 SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
8607 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8608 SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
8609 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8610 SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
8611 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8612 SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
8613 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8614 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
8615 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8616 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
8617 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8618 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
8619 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8620 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
8621 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8622 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
8623 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8624
8625 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
8626 tasha_get_compander, tasha_set_compander),
8627 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
8628 tasha_get_compander, tasha_set_compander),
8629 SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0,
8630 tasha_get_compander, tasha_set_compander),
8631 SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0,
8632 tasha_get_compander, tasha_set_compander),
8633 SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0,
8634 tasha_get_compander, tasha_set_compander),
8635 SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0,
8636 tasha_get_compander, tasha_set_compander),
8637 SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
8638 tasha_get_compander, tasha_set_compander),
8639 SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
8640 tasha_get_compander, tasha_set_compander),
8641
8642 SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
8643 tasha_rx_hph_mode_get, tasha_rx_hph_mode_put),
8644
8645 SOC_ENUM_EXT("MAD Input", tasha_conn_mad_enum,
8646 tasha_mad_input_get, tasha_mad_input_put),
8647 SOC_SINGLE_EXT("LDO_H Enable", SND_SOC_NOPM, 0, 1, 0,
8648 tasha_enable_ldo_h_get, tasha_enable_ldo_h_put),
8649
8650 SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0,
8651 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8652
8653 SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0,
8654 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8655
8656 SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 19, 1, 0,
8657 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8658
8659 SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 20, 1, 0,
8660 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8661
8662 SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 21, 1, 0,
8663 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8664
8665 SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 22, 1, 0,
8666 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8667 SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum,
8668 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8669 SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum,
8670 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8671 SOC_ENUM_EXT("AMIC_5_6 PWR MODE", amic_pwr_lvl_enum,
8672 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8673
8674 SOC_SINGLE_MULTI_EXT("Vbat ADC data", SND_SOC_NOPM, 0, 0xFFFF, 0, 2,
8675 tasha_vbat_adc_data_get, NULL),
8676
8677 SOC_ENUM_EXT("GSM mode Enable", tasha_vbat_gsm_mode_enum,
8678 tasha_vbat_gsm_mode_func_get,
8679 tasha_vbat_gsm_mode_func_put),
8680};
8681
8682static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol,
8683 struct snd_ctl_elem_value *ucontrol)
8684{
8685 struct snd_soc_dapm_widget_list *wlist =
8686 dapm_kcontrol_get_wlist(kcontrol);
8687 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
8688 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8689 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8690 unsigned int val;
8691 u16 mic_sel_reg;
8692 u8 mic_sel;
8693
8694 val = ucontrol->value.enumerated.item[0];
8695 if (val > e->items - 1)
8696 return -EINVAL;
8697
8698 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
8699 widget->name, val);
8700
8701 switch (e->reg) {
8702 case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1:
8703 mic_sel_reg = WCD9335_CDC_TX0_TX_PATH_CFG0;
8704 break;
8705 case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1:
8706 mic_sel_reg = WCD9335_CDC_TX1_TX_PATH_CFG0;
8707 break;
8708 case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1:
8709 mic_sel_reg = WCD9335_CDC_TX2_TX_PATH_CFG0;
8710 break;
8711 case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1:
8712 mic_sel_reg = WCD9335_CDC_TX3_TX_PATH_CFG0;
8713 break;
8714 case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
8715 mic_sel_reg = WCD9335_CDC_TX4_TX_PATH_CFG0;
8716 break;
8717 case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
8718 mic_sel_reg = WCD9335_CDC_TX5_TX_PATH_CFG0;
8719 break;
8720 case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
8721 mic_sel_reg = WCD9335_CDC_TX6_TX_PATH_CFG0;
8722 break;
8723 case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
8724 mic_sel_reg = WCD9335_CDC_TX7_TX_PATH_CFG0;
8725 break;
8726 case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0:
8727 mic_sel_reg = WCD9335_CDC_TX8_TX_PATH_CFG0;
8728 break;
8729 default:
8730 dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n",
8731 __func__, e->reg);
8732 return -EINVAL;
8733 }
8734
8735 /* ADC: 0, DMIC: 1 */
8736 mic_sel = val ? 0x0 : 0x1;
8737 snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7);
8738
8739 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8740}
8741
8742static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
8743 struct snd_ctl_elem_value *ucontrol)
8744{
8745 struct snd_soc_dapm_widget_list *wlist =
8746 dapm_kcontrol_get_wlist(kcontrol);
8747 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
8748 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8749 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8750 unsigned int val;
8751 unsigned short look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8752
8753 val = ucontrol->value.enumerated.item[0];
8754 if (val >= e->items)
8755 return -EINVAL;
8756
8757 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
8758 widget->name, val);
8759
8760 if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0)
8761 look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8762 else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0)
8763 look_ahead_dly_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
8764 else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0)
8765 look_ahead_dly_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
8766
8767 /* Set Look Ahead Delay */
8768 snd_soc_update_bits(codec, look_ahead_dly_reg,
8769 0x08, (val ? 0x08 : 0x00));
8770 /* Set DEM INP Select */
8771 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8772}
8773
8774static int tasha_ear_pa_gain_get(struct snd_kcontrol *kcontrol,
8775 struct snd_ctl_elem_value *ucontrol)
8776{
8777 u8 ear_pa_gain;
8778 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8779
8780 ear_pa_gain = snd_soc_read(codec, WCD9335_ANA_EAR);
8781
8782 ear_pa_gain = (ear_pa_gain & 0x70) >> 4;
8783
8784 ucontrol->value.integer.value[0] = ear_pa_gain;
8785
8786 dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__,
8787 ear_pa_gain);
8788
8789 return 0;
8790}
8791
8792static int tasha_ear_pa_gain_put(struct snd_kcontrol *kcontrol,
8793 struct snd_ctl_elem_value *ucontrol)
8794{
8795 u8 ear_pa_gain;
8796 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8797
8798 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8799 __func__, ucontrol->value.integer.value[0]);
8800
8801 ear_pa_gain = ucontrol->value.integer.value[0] << 4;
8802
8803 snd_soc_update_bits(codec, WCD9335_ANA_EAR, 0x70, ear_pa_gain);
8804 return 0;
8805}
8806
8807static int tasha_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
8808 struct snd_ctl_elem_value *ucontrol)
8809{
8810 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8811 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8812
8813 ucontrol->value.integer.value[0] = tasha->ear_spkr_gain;
8814
8815 dev_dbg(codec->dev, "%s: ear_spkr_gain = %ld\n", __func__,
8816 ucontrol->value.integer.value[0]);
8817
8818 return 0;
8819}
8820
8821static int tasha_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
8822 struct snd_ctl_elem_value *ucontrol)
8823{
8824 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8825 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8826
8827 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8828 __func__, ucontrol->value.integer.value[0]);
8829
8830 tasha->ear_spkr_gain = ucontrol->value.integer.value[0];
8831
8832 return 0;
8833}
8834
8835static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n,
8836 int event)
8837{
8838 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8839 int comp;
8840 u16 comp_ctl0_reg, rx_path_cfg0_reg;
8841
8842 /* EAR does not have compander */
8843 if (!interp_n)
8844 return 0;
8845
8846 comp = interp_n - 1;
8847 dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n",
8848 __func__, event, comp + 1, tasha->comp_enabled[comp]);
8849
8850 if (!tasha->comp_enabled[comp])
8851 return 0;
8852
8853 comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL0 + (comp * 8);
8854 rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG0 + (comp * 20);
8855
8856 if (SND_SOC_DAPM_EVENT_ON(event)) {
8857 /* Enable Compander Clock */
8858 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01);
8859 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
8860 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
8861 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02);
8862 }
8863
8864 if (SND_SOC_DAPM_EVENT_OFF(event)) {
8865 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
8866 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
8867 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
8868 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
8869 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
8870 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
8871 }
8872
8873 return 0;
8874}
8875
8876static int tasha_codec_config_mad(struct snd_soc_codec *codec)
8877{
8878 int ret = 0;
8879 int idx;
8880 const struct firmware *fw;
8881 struct firmware_cal *hwdep_cal = NULL;
8882 struct wcd_mad_audio_cal *mad_cal = NULL;
8883 const void *data;
8884 const char *filename = TASHA_MAD_AUDIO_FIRMWARE_PATH;
8885 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8886 size_t cal_size;
8887
8888 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_MAD_CAL);
8889 if (hwdep_cal) {
8890 data = hwdep_cal->data;
8891 cal_size = hwdep_cal->size;
8892 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
8893 __func__);
8894 } else {
8895 ret = request_firmware(&fw, filename, codec->dev);
8896 if (ret || !fw) {
8897 dev_err(codec->dev,
8898 "%s: MAD firmware acquire failed, err = %d\n",
8899 __func__, ret);
8900 return -ENODEV;
8901 }
8902 data = fw->data;
8903 cal_size = fw->size;
8904 dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
8905 __func__);
8906 }
8907
8908 if (cal_size < sizeof(*mad_cal)) {
8909 dev_err(codec->dev,
8910 "%s: Incorrect size %zd for MAD Cal, expected %zd\n",
8911 __func__, cal_size, sizeof(*mad_cal));
8912 ret = -ENOMEM;
8913 goto done;
8914 }
8915
8916 mad_cal = (struct wcd_mad_audio_cal *) (data);
8917 if (!mad_cal) {
8918 dev_err(codec->dev,
8919 "%s: Invalid calibration data\n",
8920 __func__);
8921 ret = -EINVAL;
8922 goto done;
8923 }
8924
8925 snd_soc_write(codec, WCD9335_SOC_MAD_MAIN_CTL_2,
8926 mad_cal->microphone_info.cycle_time);
8927 snd_soc_update_bits(codec, WCD9335_SOC_MAD_MAIN_CTL_1, 0xFF << 3,
8928 ((uint16_t)mad_cal->microphone_info.settle_time)
8929 << 3);
8930
8931 /* Audio */
8932 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_8,
8933 mad_cal->audio_info.rms_omit_samples);
8934 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_1,
8935 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
8936 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03 << 2,
8937 mad_cal->audio_info.detection_mechanism << 2);
8938 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_7,
8939 mad_cal->audio_info.rms_diff_threshold & 0x3F);
8940 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_5,
8941 mad_cal->audio_info.rms_threshold_lsb);
8942 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_6,
8943 mad_cal->audio_info.rms_threshold_msb);
8944
8945 for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients);
8946 idx++) {
8947 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR,
8948 0x3F, idx);
8949 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL,
8950 mad_cal->audio_info.iir_coefficients[idx]);
8951 dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x",
8952 __func__, idx,
8953 mad_cal->audio_info.iir_coefficients[idx]);
8954 }
8955
8956 /* Beacon */
8957 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_8,
8958 mad_cal->beacon_info.rms_omit_samples);
8959 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_1,
8960 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4);
8961 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_2, 0x03 << 2,
8962 mad_cal->beacon_info.detection_mechanism << 2);
8963 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_7,
8964 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
8965 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_5,
8966 mad_cal->beacon_info.rms_threshold_lsb);
8967 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_6,
8968 mad_cal->beacon_info.rms_threshold_msb);
8969
8970 for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients);
8971 idx++) {
8972 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR,
8973 0x3F, idx);
8974 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL,
8975 mad_cal->beacon_info.iir_coefficients[idx]);
8976 dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x",
8977 __func__, idx,
8978 mad_cal->beacon_info.iir_coefficients[idx]);
8979 }
8980
8981 /* Ultrasound */
8982 snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_1,
8983 0x07 << 4,
8984 mad_cal->ultrasound_info.rms_comp_time << 4);
8985 snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_2, 0x03 << 2,
8986 mad_cal->ultrasound_info.detection_mechanism << 2);
8987 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_7,
8988 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
8989 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_5,
8990 mad_cal->ultrasound_info.rms_threshold_lsb);
8991 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_6,
8992 mad_cal->ultrasound_info.rms_threshold_msb);
8993
8994done:
8995 if (!hwdep_cal)
8996 release_firmware(fw);
8997
8998 return ret;
8999}
9000
9001static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w,
9002 struct snd_kcontrol *kcontrol, int event)
9003{
9004 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
9005 int ret = 0;
9006
9007 dev_dbg(codec->dev,
9008 "%s: event = %d\n", __func__, event);
9009
9010 /* Return if CPE INPUT is DEC1 */
9011 if (snd_soc_read(codec, WCD9335_CPE_SS_SVA_CFG) & 0x01)
9012 return ret;
9013
9014 switch (event) {
9015 case SND_SOC_DAPM_PRE_PMU:
9016
9017 /* Turn on MAD clk */
9018 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9019 0x01, 0x01);
9020
9021 /* Undo reset for MAD */
9022 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9023 0x02, 0x00);
9024 ret = tasha_codec_config_mad(codec);
9025 if (ret)
9026 dev_err(codec->dev,
9027 "%s: Failed to config MAD, err = %d\n",
9028 __func__, ret);
9029 break;
9030 case SND_SOC_DAPM_POST_PMD:
9031 /* Reset the MAD block */
9032 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9033 0x02, 0x02);
9034 /* Turn off MAD clk */
9035 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9036 0x01, 0x00);
9037 break;
9038 }
9039
9040 return ret;
9041}
9042
9043static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w,
9044 struct snd_kcontrol *kcontrol, int event)
9045{
9046 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
9047
9048 dev_dbg(codec->dev,
9049 "%s: event = %d\n", __func__, event);
9050
9051 switch (event) {
9052 case SND_SOC_DAPM_PRE_PMU:
9053 /* Configure CPE input as DEC1 */
9054 snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
9055 0x01, 0x01);
9056
9057 /* Configure DEC1 Tx out with sample rate as 16K */
9058 snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
9059 0x0F, 0x01);
9060
9061 break;
9062 case SND_SOC_DAPM_POST_PMD:
9063 /* Reset DEC1 Tx out sample rate */
9064 snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
9065 0x0F, 0x04);
9066 snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
9067 0x01, 0x00);
9068
9069 break;
9070 }
9071
9072 return 0;
9073}
9074
9075
9076static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol,
9077 struct snd_ctl_elem_value *ucontrol)
9078{
9079 struct snd_soc_dapm_widget_list *wlist =
9080 dapm_kcontrol_get_wlist(kcontrol);
9081 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
9082 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
9083 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
9084
9085 if (test_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask))
9086 ucontrol->value.integer.value[0] = 1;
9087 else
9088 ucontrol->value.integer.value[0] = 0;
9089
9090 dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n",
9091 __func__, ucontrol->value.integer.value[0]);
9092 return 0;
9093}
9094
9095static int tasha_codec_aif4_mixer_switch_put(struct snd_kcontrol *kcontrol,
9096 struct snd_ctl_elem_value *ucontrol)
9097{
9098 struct snd_soc_dapm_widget_list *wlist =
9099 dapm_kcontrol_get_wlist(kcontrol);
9100 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
9101 struct snd_soc_dapm_update *update = NULL;
9102 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
9103 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
9104
9105 dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n",
9106 __func__, ucontrol->value.integer.value[0]);
9107
9108 if (ucontrol->value.integer.value[0]) {
9109 snd_soc_dapm_mixer_update_power(widget->dapm,
9110 kcontrol, 1, update);
9111 set_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9112 } else {
9113 snd_soc_dapm_mixer_update_power(widget->dapm,
9114 kcontrol, 0, update);
9115 clear_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9116 }
9117
9118 return 1;
9119}
9120
9121static const char * const tasha_ear_pa_gain_text[] = {
9122 "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB",
9123 "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB"
9124};
9125
9126static const char * const tasha_ear_spkr_pa_gain_text[] = {
9127 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", "G_4_DB",
9128 "G_5_DB", "G_6_DB"
9129};
9130
9131static const struct soc_enum tasha_ear_pa_gain_enum =
9132 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_pa_gain_text),
9133 tasha_ear_pa_gain_text);
9134
9135static const struct soc_enum tasha_ear_spkr_pa_gain_enum =
9136 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_spkr_pa_gain_text),
9137 tasha_ear_spkr_pa_gain_text);
9138
9139static const struct snd_kcontrol_new tasha_analog_gain_controls[] = {
9140 SOC_ENUM_EXT("EAR PA Gain", tasha_ear_pa_gain_enum,
9141 tasha_ear_pa_gain_get, tasha_ear_pa_gain_put),
9142
9143 SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum,
9144 tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put),
9145
9146 SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1,
9147 line_gain),
9148 SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
9149 line_gain),
9150 SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
9151 3, 16, 1, line_gain),
9152 SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
9153 3, 16, 1, line_gain),
9154 SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
9155 line_gain),
9156 SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
9157 line_gain),
9158
9159 SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
9160 analog_gain),
9161 SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0,
9162 analog_gain),
9163 SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0,
9164 analog_gain),
9165 SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0,
9166 analog_gain),
9167 SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0,
9168 analog_gain),
9169 SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0,
9170 analog_gain),
9171};
9172
9173static const char * const spl_src0_mux_text[] = {
9174 "ZERO", "SRC_IN_HPHL", "SRC_IN_LO1",
9175};
9176
9177static const char * const spl_src1_mux_text[] = {
9178 "ZERO", "SRC_IN_HPHR", "SRC_IN_LO2",
9179};
9180
9181static const char * const spl_src2_mux_text[] = {
9182 "ZERO", "SRC_IN_LO3", "SRC_IN_SPKRL",
9183};
9184
9185static const char * const spl_src3_mux_text[] = {
9186 "ZERO", "SRC_IN_LO4", "SRC_IN_SPKRR",
9187};
9188
9189static const char * const rx_int0_7_mix_mux_text[] = {
9190 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9191 "RX6", "RX7", "PROXIMITY"
9192};
9193
9194static const char * const rx_int_mix_mux_text[] = {
9195 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9196 "RX6", "RX7"
9197};
9198
9199static const char * const rx_prim_mix_text[] = {
9200 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
9201 "RX3", "RX4", "RX5", "RX6", "RX7"
9202};
9203
9204static const char * const rx_sidetone_mix_text[] = {
9205 "ZERO", "SRC0", "SRC1", "SRC_SUM"
9206};
9207
9208static const char * const sb_tx0_mux_text[] = {
9209 "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192"
9210};
9211
9212static const char * const sb_tx1_mux_text[] = {
9213 "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192"
9214};
9215
9216static const char * const sb_tx2_mux_text[] = {
9217 "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192"
9218};
9219
9220static const char * const sb_tx3_mux_text[] = {
9221 "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192"
9222};
9223
9224static const char * const sb_tx4_mux_text[] = {
9225 "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192"
9226};
9227
9228static const char * const sb_tx5_mux_text[] = {
9229 "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192"
9230};
9231
9232static const char * const sb_tx6_mux_text[] = {
9233 "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192"
9234};
9235
9236static const char * const sb_tx7_mux_text[] = {
9237 "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192"
9238};
9239
9240static const char * const sb_tx8_mux_text[] = {
9241 "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
9242};
9243
9244static const char * const sb_tx9_mux_text[] = {
9245 "ZERO", "DEC7", "DEC7_192"
9246};
9247
9248static const char * const sb_tx10_mux_text[] = {
9249 "ZERO", "DEC6", "DEC6_192"
9250};
9251
9252static const char * const sb_tx11_mux_text[] = {
9253 "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST"
9254};
9255
9256static const char * const sb_tx11_inp1_mux_text[] = {
9257 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4",
9258 "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12"
9259};
9260
9261static const char * const sb_tx13_mux_text[] = {
9262 "ZERO", "DEC5", "DEC5_192"
9263};
9264
9265static const char * const tx13_inp_mux_text[] = {
9266 "CDC_DEC_5", "MAD_BRDCST", "CPE_TX_PP"
9267};
9268
9269static const char * const iir_inp_mux_text[] = {
9270 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6",
9271 "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
9272};
9273
9274static const char * const rx_int_dem_inp_mux_text[] = {
9275 "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
9276};
9277
9278static const char * const rx_int0_interp_mux_text[] = {
9279 "ZERO", "RX INT0 MIX2",
9280};
9281
9282static const char * const rx_int1_interp_mux_text[] = {
9283 "ZERO", "RX INT1 MIX2",
9284};
9285
9286static const char * const rx_int2_interp_mux_text[] = {
9287 "ZERO", "RX INT2 MIX2",
9288};
9289
9290static const char * const rx_int3_interp_mux_text[] = {
9291 "ZERO", "RX INT3 MIX2",
9292};
9293
9294static const char * const rx_int4_interp_mux_text[] = {
9295 "ZERO", "RX INT4 MIX2",
9296};
9297
9298static const char * const rx_int5_interp_mux_text[] = {
9299 "ZERO", "RX INT5 MIX2",
9300};
9301
9302static const char * const rx_int6_interp_mux_text[] = {
9303 "ZERO", "RX INT6 MIX2",
9304};
9305
9306static const char * const rx_int7_interp_mux_text[] = {
9307 "ZERO", "RX INT7 MIX2",
9308};
9309
9310static const char * const rx_int8_interp_mux_text[] = {
9311 "ZERO", "RX INT8 SEC MIX"
9312};
9313
9314static const char * const mad_sel_text[] = {
9315 "SPE", "MSM"
9316};
9317
9318static const char * const adc_mux_text[] = {
9319 "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2"
9320};
9321
9322static const char * const dmic_mux_text[] = {
9323 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9324 "SMIC0", "SMIC1", "SMIC2", "SMIC3"
9325};
9326
9327static const char * const dmic_mux_alt_text[] = {
9328 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9329};
9330
9331static const char * const amic_mux_text[] = {
9332 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6"
9333};
9334
9335static const char * const rx_echo_mux_text[] = {
9336 "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2", "RX_MIX3", "RX_MIX4",
9337 "RX_MIX5", "RX_MIX6", "RX_MIX7", "RX_MIX8", "RX_MIX_VBAT5",
9338 "RX_MIX_VBAT6", "RX_MIX_VBAT7", "RX_MIX_VBAT8"
9339};
9340
9341static const char * const anc0_fb_mux_text[] = {
9342 "ZERO", "ANC_IN_HPHL", "ANC_IN_EAR", "ANC_IN_EAR_SPKR",
9343 "ANC_IN_LO1"
9344};
9345
9346static const char * const anc1_fb_mux_text[] = {
9347 "ZERO", "ANC_IN_HPHR", "ANC_IN_LO2"
9348};
9349
9350static const char * const native_mux_text[] = {
9351 "OFF", "ON",
9352};
9353
9354static const struct soc_enum spl_src0_mux_chain_enum =
9355 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 0, 3,
9356 spl_src0_mux_text);
9357
9358static const struct soc_enum spl_src1_mux_chain_enum =
9359 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 2, 3,
9360 spl_src1_mux_text);
9361
9362static const struct soc_enum spl_src2_mux_chain_enum =
9363 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 4, 3,
9364 spl_src2_mux_text);
9365
9366static const struct soc_enum spl_src3_mux_chain_enum =
9367 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 6, 3,
9368 spl_src3_mux_text);
9369
9370static const struct soc_enum rx_int0_2_mux_chain_enum =
9371 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10,
9372 rx_int0_7_mix_mux_text);
9373
9374static const struct soc_enum rx_int1_2_mux_chain_enum =
9375 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9,
9376 rx_int_mix_mux_text);
9377
9378static const struct soc_enum rx_int2_2_mux_chain_enum =
9379 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9,
9380 rx_int_mix_mux_text);
9381
9382static const struct soc_enum rx_int3_2_mux_chain_enum =
9383 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9,
9384 rx_int_mix_mux_text);
9385
9386static const struct soc_enum rx_int4_2_mux_chain_enum =
9387 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9,
9388 rx_int_mix_mux_text);
9389
9390static const struct soc_enum rx_int5_2_mux_chain_enum =
9391 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9,
9392 rx_int_mix_mux_text);
9393
9394static const struct soc_enum rx_int6_2_mux_chain_enum =
9395 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9,
9396 rx_int_mix_mux_text);
9397
9398static const struct soc_enum rx_int7_2_mux_chain_enum =
9399 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10,
9400 rx_int0_7_mix_mux_text);
9401
9402static const struct soc_enum rx_int8_2_mux_chain_enum =
9403 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9,
9404 rx_int_mix_mux_text);
9405
9406static const struct soc_enum int1_1_native_enum =
9407 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9408 native_mux_text);
9409
9410static const struct soc_enum int2_1_native_enum =
9411 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9412 native_mux_text);
9413
9414static const struct soc_enum int3_1_native_enum =
9415 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9416 native_mux_text);
9417
9418static const struct soc_enum int4_1_native_enum =
9419 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9420 native_mux_text);
9421
9422static const struct soc_enum rx_int0_1_mix_inp0_chain_enum =
9423 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13,
9424 rx_prim_mix_text);
9425
9426static const struct soc_enum rx_int0_1_mix_inp1_chain_enum =
9427 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13,
9428 rx_prim_mix_text);
9429
9430static const struct soc_enum rx_int0_1_mix_inp2_chain_enum =
9431 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13,
9432 rx_prim_mix_text);
9433
9434static const struct soc_enum rx_int1_1_mix_inp0_chain_enum =
9435 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13,
9436 rx_prim_mix_text);
9437
9438static const struct soc_enum rx_int1_1_mix_inp1_chain_enum =
9439 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13,
9440 rx_prim_mix_text);
9441
9442static const struct soc_enum rx_int1_1_mix_inp2_chain_enum =
9443 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13,
9444 rx_prim_mix_text);
9445
9446static const struct soc_enum rx_int2_1_mix_inp0_chain_enum =
9447 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13,
9448 rx_prim_mix_text);
9449
9450static const struct soc_enum rx_int2_1_mix_inp1_chain_enum =
9451 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13,
9452 rx_prim_mix_text);
9453
9454static const struct soc_enum rx_int2_1_mix_inp2_chain_enum =
9455 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13,
9456 rx_prim_mix_text);
9457
9458static const struct soc_enum rx_int3_1_mix_inp0_chain_enum =
9459 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13,
9460 rx_prim_mix_text);
9461
9462static const struct soc_enum rx_int3_1_mix_inp1_chain_enum =
9463 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13,
9464 rx_prim_mix_text);
9465
9466static const struct soc_enum rx_int3_1_mix_inp2_chain_enum =
9467 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13,
9468 rx_prim_mix_text);
9469
9470static const struct soc_enum rx_int4_1_mix_inp0_chain_enum =
9471 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13,
9472 rx_prim_mix_text);
9473
9474static const struct soc_enum rx_int4_1_mix_inp1_chain_enum =
9475 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13,
9476 rx_prim_mix_text);
9477
9478static const struct soc_enum rx_int4_1_mix_inp2_chain_enum =
9479 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13,
9480 rx_prim_mix_text);
9481
9482static const struct soc_enum rx_int5_1_mix_inp0_chain_enum =
9483 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13,
9484 rx_prim_mix_text);
9485
9486static const struct soc_enum rx_int5_1_mix_inp1_chain_enum =
9487 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13,
9488 rx_prim_mix_text);
9489
9490static const struct soc_enum rx_int5_1_mix_inp2_chain_enum =
9491 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13,
9492 rx_prim_mix_text);
9493
9494static const struct soc_enum rx_int6_1_mix_inp0_chain_enum =
9495 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13,
9496 rx_prim_mix_text);
9497
9498static const struct soc_enum rx_int6_1_mix_inp1_chain_enum =
9499 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13,
9500 rx_prim_mix_text);
9501
9502static const struct soc_enum rx_int6_1_mix_inp2_chain_enum =
9503 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13,
9504 rx_prim_mix_text);
9505
9506static const struct soc_enum rx_int7_1_mix_inp0_chain_enum =
9507 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13,
9508 rx_prim_mix_text);
9509
9510static const struct soc_enum rx_int7_1_mix_inp1_chain_enum =
9511 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13,
9512 rx_prim_mix_text);
9513
9514static const struct soc_enum rx_int7_1_mix_inp2_chain_enum =
9515 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13,
9516 rx_prim_mix_text);
9517
9518static const struct soc_enum rx_int8_1_mix_inp0_chain_enum =
9519 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13,
9520 rx_prim_mix_text);
9521
9522static const struct soc_enum rx_int8_1_mix_inp1_chain_enum =
9523 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13,
9524 rx_prim_mix_text);
9525
9526static const struct soc_enum rx_int8_1_mix_inp2_chain_enum =
9527 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13,
9528 rx_prim_mix_text);
9529
9530static const struct soc_enum rx_int0_sidetone_mix_chain_enum =
9531 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, 4,
9532 rx_sidetone_mix_text);
9533
9534static const struct soc_enum rx_int1_sidetone_mix_chain_enum =
9535 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 4,
9536 rx_sidetone_mix_text);
9537
9538static const struct soc_enum rx_int2_sidetone_mix_chain_enum =
9539 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, 4,
9540 rx_sidetone_mix_text);
9541
9542static const struct soc_enum rx_int3_sidetone_mix_chain_enum =
9543 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, 4,
9544 rx_sidetone_mix_text);
9545
9546static const struct soc_enum rx_int4_sidetone_mix_chain_enum =
9547 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0, 4,
9548 rx_sidetone_mix_text);
9549
9550static const struct soc_enum rx_int7_sidetone_mix_chain_enum =
9551 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, 4,
9552 rx_sidetone_mix_text);
9553
9554static const struct soc_enum tx_adc_mux0_chain_enum =
9555 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4,
9556 adc_mux_text);
9557
9558static const struct soc_enum tx_adc_mux1_chain_enum =
9559 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4,
9560 adc_mux_text);
9561
9562static const struct soc_enum tx_adc_mux2_chain_enum =
9563 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4,
9564 adc_mux_text);
9565
9566static const struct soc_enum tx_adc_mux3_chain_enum =
9567 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4,
9568 adc_mux_text);
9569
9570static const struct soc_enum tx_adc_mux4_chain_enum =
9571 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4,
9572 adc_mux_text);
9573
9574static const struct soc_enum tx_adc_mux5_chain_enum =
9575 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4,
9576 adc_mux_text);
9577
9578static const struct soc_enum tx_adc_mux6_chain_enum =
9579 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4,
9580 adc_mux_text);
9581
9582static const struct soc_enum tx_adc_mux7_chain_enum =
9583 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4,
9584 adc_mux_text);
9585
9586static const struct soc_enum tx_adc_mux8_chain_enum =
9587 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4,
9588 adc_mux_text);
9589
9590static const struct soc_enum tx_adc_mux10_chain_enum =
9591 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 6, 4,
9592 adc_mux_text);
9593
9594static const struct soc_enum tx_adc_mux11_chain_enum =
9595 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 6, 4,
9596 adc_mux_text);
9597
9598static const struct soc_enum tx_adc_mux12_chain_enum =
9599 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 6, 4,
9600 adc_mux_text);
9601
9602static const struct soc_enum tx_adc_mux13_chain_enum =
9603 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 6, 4,
9604 adc_mux_text);
9605
9606static const struct soc_enum tx_dmic_mux0_enum =
9607 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11,
9608 dmic_mux_text);
9609
9610static const struct soc_enum tx_dmic_mux1_enum =
9611 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11,
9612 dmic_mux_text);
9613
9614static const struct soc_enum tx_dmic_mux2_enum =
9615 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11,
9616 dmic_mux_text);
9617
9618static const struct soc_enum tx_dmic_mux3_enum =
9619 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11,
9620 dmic_mux_text);
9621
9622static const struct soc_enum tx_dmic_mux4_enum =
9623 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7,
9624 dmic_mux_alt_text);
9625
9626static const struct soc_enum tx_dmic_mux5_enum =
9627 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7,
9628 dmic_mux_alt_text);
9629
9630static const struct soc_enum tx_dmic_mux6_enum =
9631 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7,
9632 dmic_mux_alt_text);
9633
9634static const struct soc_enum tx_dmic_mux7_enum =
9635 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7,
9636 dmic_mux_alt_text);
9637
9638static const struct soc_enum tx_dmic_mux8_enum =
9639 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7,
9640 dmic_mux_alt_text);
9641
9642static const struct soc_enum tx_dmic_mux10_enum =
9643 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, 7,
9644 dmic_mux_alt_text);
9645
9646static const struct soc_enum tx_dmic_mux11_enum =
9647 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, 7,
9648 dmic_mux_alt_text);
9649
9650static const struct soc_enum tx_dmic_mux12_enum =
9651 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 3, 7,
9652 dmic_mux_alt_text);
9653
9654static const struct soc_enum tx_dmic_mux13_enum =
9655 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 3, 7,
9656 dmic_mux_alt_text);
9657
9658static const struct soc_enum tx_amic_mux0_enum =
9659 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7,
9660 amic_mux_text);
9661
9662static const struct soc_enum tx_amic_mux1_enum =
9663 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7,
9664 amic_mux_text);
9665
9666static const struct soc_enum tx_amic_mux2_enum =
9667 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7,
9668 amic_mux_text);
9669
9670static const struct soc_enum tx_amic_mux3_enum =
9671 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7,
9672 amic_mux_text);
9673
9674static const struct soc_enum tx_amic_mux4_enum =
9675 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7,
9676 amic_mux_text);
9677
9678static const struct soc_enum tx_amic_mux5_enum =
9679 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7,
9680 amic_mux_text);
9681
9682static const struct soc_enum tx_amic_mux6_enum =
9683 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7,
9684 amic_mux_text);
9685
9686static const struct soc_enum tx_amic_mux7_enum =
9687 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7,
9688 amic_mux_text);
9689
9690static const struct soc_enum tx_amic_mux8_enum =
9691 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7,
9692 amic_mux_text);
9693
9694static const struct soc_enum tx_amic_mux10_enum =
9695 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, 7,
9696 amic_mux_text);
9697
9698static const struct soc_enum tx_amic_mux11_enum =
9699 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, 7,
9700 amic_mux_text);
9701
9702static const struct soc_enum tx_amic_mux12_enum =
9703 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, 7,
9704 amic_mux_text);
9705
9706static const struct soc_enum tx_amic_mux13_enum =
9707 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, 7,
9708 amic_mux_text);
9709
9710static const struct soc_enum sb_tx0_mux_enum =
9711 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4,
9712 sb_tx0_mux_text);
9713
9714static const struct soc_enum sb_tx1_mux_enum =
9715 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4,
9716 sb_tx1_mux_text);
9717
9718static const struct soc_enum sb_tx2_mux_enum =
9719 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4,
9720 sb_tx2_mux_text);
9721
9722static const struct soc_enum sb_tx3_mux_enum =
9723 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4,
9724 sb_tx3_mux_text);
9725
9726static const struct soc_enum sb_tx4_mux_enum =
9727 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4,
9728 sb_tx4_mux_text);
9729
9730static const struct soc_enum sb_tx5_mux_enum =
9731 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4,
9732 sb_tx5_mux_text);
9733
9734static const struct soc_enum sb_tx6_mux_enum =
9735 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4,
9736 sb_tx6_mux_text);
9737
9738static const struct soc_enum sb_tx7_mux_enum =
9739 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4,
9740 sb_tx7_mux_text);
9741
9742static const struct soc_enum sb_tx8_mux_enum =
9743 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4,
9744 sb_tx8_mux_text);
9745
9746static const struct soc_enum sb_tx9_mux_enum =
9747 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 2, 3,
9748 sb_tx9_mux_text);
9749
9750static const struct soc_enum sb_tx10_mux_enum =
9751 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 4, 3,
9752 sb_tx10_mux_text);
9753
9754static const struct soc_enum sb_tx11_mux_enum =
9755 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG, 0, 4,
9756 sb_tx11_mux_text);
9757
9758static const struct soc_enum sb_tx11_inp1_mux_enum =
9759 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 0, 10,
9760 sb_tx11_inp1_mux_text);
9761
9762static const struct soc_enum sb_tx13_mux_enum =
9763 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 4, 3,
9764 sb_tx13_mux_text);
9765
9766static const struct soc_enum tx13_inp_mux_enum =
9767 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0, 3,
9768 tx13_inp_mux_text);
9769
9770static const struct soc_enum rx_mix_tx0_mux_enum =
9771 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, 14,
9772 rx_echo_mux_text);
9773
9774static const struct soc_enum rx_mix_tx1_mux_enum =
9775 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, 14,
9776 rx_echo_mux_text);
9777
9778static const struct soc_enum rx_mix_tx2_mux_enum =
9779 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, 14,
9780 rx_echo_mux_text);
9781
9782static const struct soc_enum rx_mix_tx3_mux_enum =
9783 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, 14,
9784 rx_echo_mux_text);
9785
9786static const struct soc_enum rx_mix_tx4_mux_enum =
9787 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, 14,
9788 rx_echo_mux_text);
9789
9790static const struct soc_enum rx_mix_tx5_mux_enum =
9791 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, 14,
9792 rx_echo_mux_text);
9793
9794static const struct soc_enum rx_mix_tx6_mux_enum =
9795 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, 14,
9796 rx_echo_mux_text);
9797
9798static const struct soc_enum rx_mix_tx7_mux_enum =
9799 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, 14,
9800 rx_echo_mux_text);
9801
9802static const struct soc_enum rx_mix_tx8_mux_enum =
9803 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 14,
9804 rx_echo_mux_text);
9805
9806static const struct soc_enum iir0_inp0_mux_enum =
9807 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, 18,
9808 iir_inp_mux_text);
9809
9810static const struct soc_enum iir0_inp1_mux_enum =
9811 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, 18,
9812 iir_inp_mux_text);
9813
9814static const struct soc_enum iir0_inp2_mux_enum =
9815 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, 18,
9816 iir_inp_mux_text);
9817
9818static const struct soc_enum iir0_inp3_mux_enum =
9819 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, 18,
9820 iir_inp_mux_text);
9821
9822static const struct soc_enum iir1_inp0_mux_enum =
9823 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0, 18,
9824 iir_inp_mux_text);
9825
9826static const struct soc_enum iir1_inp1_mux_enum =
9827 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0, 18,
9828 iir_inp_mux_text);
9829
9830static const struct soc_enum iir1_inp2_mux_enum =
9831 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0, 18,
9832 iir_inp_mux_text);
9833
9834static const struct soc_enum iir1_inp3_mux_enum =
9835 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0, 18,
9836 iir_inp_mux_text);
9837
9838static const struct soc_enum rx_int0_dem_inp_mux_enum =
9839 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0,
9840 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9841 rx_int_dem_inp_mux_text);
9842
9843static const struct soc_enum rx_int1_dem_inp_mux_enum =
9844 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0,
9845 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9846 rx_int_dem_inp_mux_text);
9847
9848static const struct soc_enum rx_int2_dem_inp_mux_enum =
9849 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0,
9850 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9851 rx_int_dem_inp_mux_text);
9852
9853static const struct soc_enum rx_int0_interp_mux_enum =
9854 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2,
9855 rx_int0_interp_mux_text);
9856
9857static const struct soc_enum rx_int1_interp_mux_enum =
9858 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2,
9859 rx_int1_interp_mux_text);
9860
9861static const struct soc_enum rx_int2_interp_mux_enum =
9862 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2,
9863 rx_int2_interp_mux_text);
9864
9865static const struct soc_enum rx_int3_interp_mux_enum =
9866 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2,
9867 rx_int3_interp_mux_text);
9868
9869static const struct soc_enum rx_int4_interp_mux_enum =
9870 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2,
9871 rx_int4_interp_mux_text);
9872
9873static const struct soc_enum rx_int5_interp_mux_enum =
9874 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2,
9875 rx_int5_interp_mux_text);
9876
9877static const struct soc_enum rx_int6_interp_mux_enum =
9878 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2,
9879 rx_int6_interp_mux_text);
9880
9881static const struct soc_enum rx_int7_interp_mux_enum =
9882 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2,
9883 rx_int7_interp_mux_text);
9884
9885static const struct soc_enum rx_int8_interp_mux_enum =
9886 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2,
9887 rx_int8_interp_mux_text);
9888
9889static const struct soc_enum mad_sel_enum =
9890 SOC_ENUM_SINGLE(WCD9335_CPE_SS_CFG, 0, 2, mad_sel_text);
9891
9892static const struct soc_enum anc0_fb_mux_enum =
9893 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 0, 5,
9894 anc0_fb_mux_text);
9895
9896static const struct soc_enum anc1_fb_mux_enum =
9897 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 3, 3,
9898 anc1_fb_mux_text);
9899
9900static const struct snd_kcontrol_new rx_int0_dem_inp_mux =
9901 SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum,
9902 snd_soc_dapm_get_enum_double,
9903 tasha_int_dem_inp_mux_put);
9904
9905static const struct snd_kcontrol_new rx_int1_dem_inp_mux =
9906 SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum,
9907 snd_soc_dapm_get_enum_double,
9908 tasha_int_dem_inp_mux_put);
9909
9910static const struct snd_kcontrol_new rx_int2_dem_inp_mux =
9911 SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum,
9912 snd_soc_dapm_get_enum_double,
9913 tasha_int_dem_inp_mux_put);
9914
9915static const struct snd_kcontrol_new spl_src0_mux =
9916 SOC_DAPM_ENUM("SPL SRC0 MUX Mux", spl_src0_mux_chain_enum);
9917
9918static const struct snd_kcontrol_new spl_src1_mux =
9919 SOC_DAPM_ENUM("SPL SRC1 MUX Mux", spl_src1_mux_chain_enum);
9920
9921static const struct snd_kcontrol_new spl_src2_mux =
9922 SOC_DAPM_ENUM("SPL SRC2 MUX Mux", spl_src2_mux_chain_enum);
9923
9924static const struct snd_kcontrol_new spl_src3_mux =
9925 SOC_DAPM_ENUM("SPL SRC3 MUX Mux", spl_src3_mux_chain_enum);
9926
9927static const struct snd_kcontrol_new rx_int0_2_mux =
9928 SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum);
9929
9930static const struct snd_kcontrol_new rx_int1_2_mux =
9931 SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum);
9932
9933static const struct snd_kcontrol_new rx_int2_2_mux =
9934 SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum);
9935
9936static const struct snd_kcontrol_new rx_int3_2_mux =
9937 SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum);
9938
9939static const struct snd_kcontrol_new rx_int4_2_mux =
9940 SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum);
9941
9942static const struct snd_kcontrol_new rx_int5_2_mux =
9943 SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum);
9944
9945static const struct snd_kcontrol_new rx_int6_2_mux =
9946 SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum);
9947
9948static const struct snd_kcontrol_new rx_int7_2_mux =
9949 SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum);
9950
9951static const struct snd_kcontrol_new rx_int8_2_mux =
9952 SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum);
9953
9954static const struct snd_kcontrol_new int1_1_native_mux =
9955 SOC_DAPM_ENUM("RX INT1_1 NATIVE MUX Mux", int1_1_native_enum);
9956
9957static const struct snd_kcontrol_new int2_1_native_mux =
9958 SOC_DAPM_ENUM("RX INT2_1 NATIVE MUX Mux", int2_1_native_enum);
9959
9960static const struct snd_kcontrol_new int3_1_native_mux =
9961 SOC_DAPM_ENUM("RX INT3_1 NATIVE MUX Mux", int3_1_native_enum);
9962
9963static const struct snd_kcontrol_new int4_1_native_mux =
9964 SOC_DAPM_ENUM("RX INT4_1 NATIVE MUX Mux", int4_1_native_enum);
9965
9966static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux =
9967 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum);
9968
9969static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux =
9970 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum);
9971
9972static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux =
9973 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum);
9974
9975static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux =
9976 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum);
9977
9978static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux =
9979 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum);
9980
9981static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux =
9982 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum);
9983
9984static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux =
9985 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum);
9986
9987static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux =
9988 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum);
9989
9990static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux =
9991 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum);
9992
9993static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux =
9994 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum);
9995
9996static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux =
9997 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum);
9998
9999static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux =
10000 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum);
10001
10002static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux =
10003 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum);
10004
10005static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux =
10006 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum);
10007
10008static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux =
10009 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum);
10010
10011static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux =
10012 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum);
10013
10014static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux =
10015 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum);
10016
10017static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux =
10018 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum);
10019
10020static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux =
10021 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum);
10022
10023static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux =
10024 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum);
10025
10026static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux =
10027 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum);
10028
10029static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux =
10030 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum);
10031
10032static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux =
10033 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum);
10034
10035static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux =
10036 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum);
10037
10038static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux =
10039 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum);
10040
10041static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux =
10042 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum);
10043
10044static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux =
10045 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum);
10046
10047static const struct snd_kcontrol_new rx_int0_mix2_inp_mux =
10048 SOC_DAPM_ENUM("RX INT0 MIX2 INP Mux", rx_int0_sidetone_mix_chain_enum);
10049
10050static const struct snd_kcontrol_new rx_int1_mix2_inp_mux =
10051 SOC_DAPM_ENUM("RX INT1 MIX2 INP Mux", rx_int1_sidetone_mix_chain_enum);
10052
10053static const struct snd_kcontrol_new rx_int2_mix2_inp_mux =
10054 SOC_DAPM_ENUM("RX INT2 MIX2 INP Mux", rx_int2_sidetone_mix_chain_enum);
10055
10056static const struct snd_kcontrol_new rx_int3_mix2_inp_mux =
10057 SOC_DAPM_ENUM("RX INT3 MIX2 INP Mux", rx_int3_sidetone_mix_chain_enum);
10058
10059static const struct snd_kcontrol_new rx_int4_mix2_inp_mux =
10060 SOC_DAPM_ENUM("RX INT4 MIX2 INP Mux", rx_int4_sidetone_mix_chain_enum);
10061
10062static const struct snd_kcontrol_new rx_int7_mix2_inp_mux =
10063 SOC_DAPM_ENUM("RX INT7 MIX2 INP Mux", rx_int7_sidetone_mix_chain_enum);
10064
10065static const struct snd_kcontrol_new tx_adc_mux0 =
10066 SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum,
10067 snd_soc_dapm_get_enum_double,
10068 tasha_put_dec_enum);
10069
10070static const struct snd_kcontrol_new tx_adc_mux1 =
10071 SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum,
10072 snd_soc_dapm_get_enum_double,
10073 tasha_put_dec_enum);
10074
10075static const struct snd_kcontrol_new tx_adc_mux2 =
10076 SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum,
10077 snd_soc_dapm_get_enum_double,
10078 tasha_put_dec_enum);
10079
10080static const struct snd_kcontrol_new tx_adc_mux3 =
10081 SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum,
10082 snd_soc_dapm_get_enum_double,
10083 tasha_put_dec_enum);
10084
10085static const struct snd_kcontrol_new tx_adc_mux4 =
10086 SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum,
10087 snd_soc_dapm_get_enum_double,
10088 tasha_put_dec_enum);
10089
10090static const struct snd_kcontrol_new tx_adc_mux5 =
10091 SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum,
10092 snd_soc_dapm_get_enum_double,
10093 tasha_put_dec_enum);
10094
10095static const struct snd_kcontrol_new tx_adc_mux6 =
10096 SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum,
10097 snd_soc_dapm_get_enum_double,
10098 tasha_put_dec_enum);
10099
10100static const struct snd_kcontrol_new tx_adc_mux7 =
10101 SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum,
10102 snd_soc_dapm_get_enum_double,
10103 tasha_put_dec_enum);
10104
10105static const struct snd_kcontrol_new tx_adc_mux8 =
10106 SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum,
10107 snd_soc_dapm_get_enum_double,
10108 tasha_put_dec_enum);
10109
10110static const struct snd_kcontrol_new tx_adc_mux10 =
10111 SOC_DAPM_ENUM("ADC MUX10 Mux", tx_adc_mux10_chain_enum);
10112
10113static const struct snd_kcontrol_new tx_adc_mux11 =
10114 SOC_DAPM_ENUM("ADC MUX11 Mux", tx_adc_mux11_chain_enum);
10115
10116static const struct snd_kcontrol_new tx_adc_mux12 =
10117 SOC_DAPM_ENUM("ADC MUX12 Mux", tx_adc_mux12_chain_enum);
10118
10119static const struct snd_kcontrol_new tx_adc_mux13 =
10120 SOC_DAPM_ENUM("ADC MUX13 Mux", tx_adc_mux13_chain_enum);
10121
10122static const struct snd_kcontrol_new tx_dmic_mux0 =
10123 SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum);
10124
10125static const struct snd_kcontrol_new tx_dmic_mux1 =
10126 SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum);
10127
10128static const struct snd_kcontrol_new tx_dmic_mux2 =
10129 SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum);
10130
10131static const struct snd_kcontrol_new tx_dmic_mux3 =
10132 SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum);
10133
10134static const struct snd_kcontrol_new tx_dmic_mux4 =
10135 SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum);
10136
10137static const struct snd_kcontrol_new tx_dmic_mux5 =
10138 SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum);
10139
10140static const struct snd_kcontrol_new tx_dmic_mux6 =
10141 SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum);
10142
10143static const struct snd_kcontrol_new tx_dmic_mux7 =
10144 SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum);
10145
10146static const struct snd_kcontrol_new tx_dmic_mux8 =
10147 SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum);
10148
10149static const struct snd_kcontrol_new tx_dmic_mux10 =
10150 SOC_DAPM_ENUM("DMIC MUX10 Mux", tx_dmic_mux10_enum);
10151
10152static const struct snd_kcontrol_new tx_dmic_mux11 =
10153 SOC_DAPM_ENUM("DMIC MUX11 Mux", tx_dmic_mux11_enum);
10154
10155static const struct snd_kcontrol_new tx_dmic_mux12 =
10156 SOC_DAPM_ENUM("DMIC MUX12 Mux", tx_dmic_mux12_enum);
10157
10158static const struct snd_kcontrol_new tx_dmic_mux13 =
10159 SOC_DAPM_ENUM("DMIC MUX13 Mux", tx_dmic_mux13_enum);
10160
10161static const struct snd_kcontrol_new tx_amic_mux0 =
10162 SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum);
10163
10164static const struct snd_kcontrol_new tx_amic_mux1 =
10165 SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum);
10166
10167static const struct snd_kcontrol_new tx_amic_mux2 =
10168 SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum);
10169
10170static const struct snd_kcontrol_new tx_amic_mux3 =
10171 SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum);
10172
10173static const struct snd_kcontrol_new tx_amic_mux4 =
10174 SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum);
10175
10176static const struct snd_kcontrol_new tx_amic_mux5 =
10177 SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum);
10178
10179static const struct snd_kcontrol_new tx_amic_mux6 =
10180 SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum);
10181
10182static const struct snd_kcontrol_new tx_amic_mux7 =
10183 SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum);
10184
10185static const struct snd_kcontrol_new tx_amic_mux8 =
10186 SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum);
10187
10188static const struct snd_kcontrol_new tx_amic_mux10 =
10189 SOC_DAPM_ENUM("AMIC MUX10 Mux", tx_amic_mux10_enum);
10190
10191static const struct snd_kcontrol_new tx_amic_mux11 =
10192 SOC_DAPM_ENUM("AMIC MUX11 Mux", tx_amic_mux11_enum);
10193
10194static const struct snd_kcontrol_new tx_amic_mux12 =
10195 SOC_DAPM_ENUM("AMIC MUX12 Mux", tx_amic_mux12_enum);
10196
10197static const struct snd_kcontrol_new tx_amic_mux13 =
10198 SOC_DAPM_ENUM("AMIC MUX13 Mux", tx_amic_mux13_enum);
10199
10200static const struct snd_kcontrol_new sb_tx0_mux =
10201 SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum);
10202
10203static const struct snd_kcontrol_new sb_tx1_mux =
10204 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
10205
10206static const struct snd_kcontrol_new sb_tx2_mux =
10207 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
10208
10209static const struct snd_kcontrol_new sb_tx3_mux =
10210 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
10211
10212static const struct snd_kcontrol_new sb_tx4_mux =
10213 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
10214
10215static const struct snd_kcontrol_new sb_tx5_mux =
10216 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
10217
10218static const struct snd_kcontrol_new sb_tx6_mux =
10219 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
10220
10221static const struct snd_kcontrol_new sb_tx7_mux =
10222 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
10223
10224static const struct snd_kcontrol_new sb_tx8_mux =
10225 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
10226
10227static const struct snd_kcontrol_new sb_tx9_mux =
10228 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
10229
10230static const struct snd_kcontrol_new sb_tx10_mux =
10231 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
10232
10233static const struct snd_kcontrol_new sb_tx11_mux =
10234 SOC_DAPM_ENUM("SLIM TX11 MUX Mux", sb_tx11_mux_enum);
10235
10236static const struct snd_kcontrol_new sb_tx11_inp1_mux =
10237 SOC_DAPM_ENUM("SLIM TX11 INP1 MUX Mux", sb_tx11_inp1_mux_enum);
10238
10239static const struct snd_kcontrol_new sb_tx13_mux =
10240 SOC_DAPM_ENUM("SLIM TX13 MUX Mux", sb_tx13_mux_enum);
10241
10242static const struct snd_kcontrol_new tx13_inp_mux =
10243 SOC_DAPM_ENUM("TX13 INP MUX Mux", tx13_inp_mux_enum);
10244
10245static const struct snd_kcontrol_new rx_mix_tx0_mux =
10246 SOC_DAPM_ENUM("RX MIX TX0 MUX Mux", rx_mix_tx0_mux_enum);
10247
10248static const struct snd_kcontrol_new rx_mix_tx1_mux =
10249 SOC_DAPM_ENUM("RX MIX TX1 MUX Mux", rx_mix_tx1_mux_enum);
10250
10251static const struct snd_kcontrol_new rx_mix_tx2_mux =
10252 SOC_DAPM_ENUM("RX MIX TX2 MUX Mux", rx_mix_tx2_mux_enum);
10253
10254static const struct snd_kcontrol_new rx_mix_tx3_mux =
10255 SOC_DAPM_ENUM("RX MIX TX3 MUX Mux", rx_mix_tx3_mux_enum);
10256
10257static const struct snd_kcontrol_new rx_mix_tx4_mux =
10258 SOC_DAPM_ENUM("RX MIX TX4 MUX Mux", rx_mix_tx4_mux_enum);
10259
10260static const struct snd_kcontrol_new rx_mix_tx5_mux =
10261 SOC_DAPM_ENUM("RX MIX TX5 MUX Mux", rx_mix_tx5_mux_enum);
10262
10263static const struct snd_kcontrol_new rx_mix_tx6_mux =
10264 SOC_DAPM_ENUM("RX MIX TX6 MUX Mux", rx_mix_tx6_mux_enum);
10265
10266static const struct snd_kcontrol_new rx_mix_tx7_mux =
10267 SOC_DAPM_ENUM("RX MIX TX7 MUX Mux", rx_mix_tx7_mux_enum);
10268
10269static const struct snd_kcontrol_new rx_mix_tx8_mux =
10270 SOC_DAPM_ENUM("RX MIX TX8 MUX Mux", rx_mix_tx8_mux_enum);
10271
10272static const struct snd_kcontrol_new iir0_inp0_mux =
10273 SOC_DAPM_ENUM("IIR0 INP0 Mux", iir0_inp0_mux_enum);
10274
10275static const struct snd_kcontrol_new iir0_inp1_mux =
10276 SOC_DAPM_ENUM("IIR0 INP1 Mux", iir0_inp1_mux_enum);
10277
10278static const struct snd_kcontrol_new iir0_inp2_mux =
10279 SOC_DAPM_ENUM("IIR0 INP2 Mux", iir0_inp2_mux_enum);
10280
10281static const struct snd_kcontrol_new iir0_inp3_mux =
10282 SOC_DAPM_ENUM("IIR0 INP3 Mux", iir0_inp3_mux_enum);
10283
10284static const struct snd_kcontrol_new iir1_inp0_mux =
10285 SOC_DAPM_ENUM("IIR1 INP0 Mux", iir1_inp0_mux_enum);
10286
10287static const struct snd_kcontrol_new iir1_inp1_mux =
10288 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
10289
10290static const struct snd_kcontrol_new iir1_inp2_mux =
10291 SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
10292
10293static const struct snd_kcontrol_new iir1_inp3_mux =
10294 SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
10295
10296static const struct snd_kcontrol_new rx_int0_interp_mux =
10297 SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum);
10298
10299static const struct snd_kcontrol_new rx_int1_interp_mux =
10300 SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum);
10301
10302static const struct snd_kcontrol_new rx_int2_interp_mux =
10303 SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum);
10304
10305static const struct snd_kcontrol_new rx_int3_interp_mux =
10306 SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum);
10307
10308static const struct snd_kcontrol_new rx_int4_interp_mux =
10309 SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum);
10310
10311static const struct snd_kcontrol_new rx_int5_interp_mux =
10312 SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum);
10313
10314static const struct snd_kcontrol_new rx_int6_interp_mux =
10315 SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum);
10316
10317static const struct snd_kcontrol_new rx_int7_interp_mux =
10318 SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum);
10319
10320static const struct snd_kcontrol_new rx_int8_interp_mux =
10321 SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum);
10322
10323static const struct snd_kcontrol_new mad_sel_mux =
10324 SOC_DAPM_ENUM("MAD_SEL MUX Mux", mad_sel_enum);
10325
10326static const struct snd_kcontrol_new aif4_mad_switch =
10327 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 5, 1, 0);
10328
10329static const struct snd_kcontrol_new mad_brdcst_switch =
10330 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 6, 1, 0);
10331
10332static const struct snd_kcontrol_new aif4_switch_mixer_controls =
10333 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
10334 0, 1, 0, tasha_codec_aif4_mixer_switch_get,
10335 tasha_codec_aif4_mixer_switch_put);
10336
10337static const struct snd_kcontrol_new anc_hphl_switch =
10338 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10339
10340static const struct snd_kcontrol_new anc_hphr_switch =
10341 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10342
10343static const struct snd_kcontrol_new anc_ear_switch =
10344 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10345
10346static const struct snd_kcontrol_new anc_ear_spkr_switch =
10347 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10348
10349static const struct snd_kcontrol_new anc_lineout1_switch =
10350 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10351
10352static const struct snd_kcontrol_new anc_lineout2_switch =
10353 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10354
10355static const struct snd_kcontrol_new anc_spkr_pa_switch =
10356 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10357
10358static const struct snd_kcontrol_new adc_us_mux0_switch =
10359 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10360
10361static const struct snd_kcontrol_new adc_us_mux1_switch =
10362 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10363
10364static const struct snd_kcontrol_new adc_us_mux2_switch =
10365 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10366
10367static const struct snd_kcontrol_new adc_us_mux3_switch =
10368 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10369
10370static const struct snd_kcontrol_new adc_us_mux4_switch =
10371 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10372
10373static const struct snd_kcontrol_new adc_us_mux5_switch =
10374 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10375
10376static const struct snd_kcontrol_new adc_us_mux6_switch =
10377 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10378
10379static const struct snd_kcontrol_new adc_us_mux7_switch =
10380 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10381
10382static const struct snd_kcontrol_new adc_us_mux8_switch =
10383 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10384
10385static const struct snd_kcontrol_new anc0_fb_mux =
10386 SOC_DAPM_ENUM("ANC0 FB MUX Mux", anc0_fb_mux_enum);
10387
10388static const struct snd_kcontrol_new anc1_fb_mux =
10389 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
10390
10391static int tasha_codec_ec_buf_mux_enable(struct snd_soc_dapm_widget *w,
10392 struct snd_kcontrol *kcontrol,
10393 int event)
10394{
10395 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
10396
10397 dev_dbg(codec->dev, "%s: event = %d name = %s\n",
10398 __func__, event, w->name);
10399
10400 switch (event) {
10401 case SND_SOC_DAPM_POST_PMU:
10402 snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B);
10403 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x08);
10404 snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10405 0x08, 0x08);
10406 break;
10407 case SND_SOC_DAPM_POST_PMD:
10408 snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10409 0x08, 0x00);
10410 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x00);
10411 snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00);
10412 break;
10413 }
10414
10415 return 0;
10416};
10417
10418static const char * const ec_buf_mux_text[] = {
10419 "ZERO", "RXMIXEC", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3",
10420 "I2S_RX_SD0_L", "I2S_RX_SD0_R", "I2S_RX_SD1_L", "I2S_RX_SD1_R",
10421 "DEC1"
10422};
10423
10424static SOC_ENUM_SINGLE_DECL(ec_buf_mux_enum, WCD9335_CPE_SS_US_EC_MUX_CFG,
10425 0, ec_buf_mux_text);
10426
10427static const struct snd_kcontrol_new ec_buf_mux =
10428 SOC_DAPM_ENUM("EC BUF Mux", ec_buf_mux_enum);
10429
10430static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
10431 SND_SOC_DAPM_OUTPUT("EAR"),
10432 SND_SOC_DAPM_OUTPUT("ANC EAR"),
10433 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
10434 AIF1_PB, 0, tasha_codec_enable_slimrx,
10435 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10436 SND_SOC_DAPM_POST_PMD),
10437 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
10438 AIF2_PB, 0, tasha_codec_enable_slimrx,
10439 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10440 SND_SOC_DAPM_POST_PMD),
10441 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
10442 AIF3_PB, 0, tasha_codec_enable_slimrx,
10443 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10444 SND_SOC_DAPM_POST_PMD),
10445 SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
10446 AIF4_PB, 0, tasha_codec_enable_slimrx,
10447 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10448 SND_SOC_DAPM_POST_PMD),
10449 SND_SOC_DAPM_AIF_IN_E("AIF MIX1 PB", "AIF Mix Playback", 0,
10450 SND_SOC_NOPM, AIF_MIX1_PB, 0,
10451 tasha_codec_enable_slimrx,
10452 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10453 SND_SOC_DAPM_POST_PMD),
10454
10455 SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, TASHA_RX0, 0,
10456 &slim_rx_mux[TASHA_RX0]),
10457 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TASHA_RX1, 0,
10458 &slim_rx_mux[TASHA_RX1]),
10459 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TASHA_RX2, 0,
10460 &slim_rx_mux[TASHA_RX2]),
10461 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TASHA_RX3, 0,
10462 &slim_rx_mux[TASHA_RX3]),
10463 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TASHA_RX4, 0,
10464 &slim_rx_mux[TASHA_RX4]),
10465 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TASHA_RX5, 0,
10466 &slim_rx_mux[TASHA_RX5]),
10467 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TASHA_RX6, 0,
10468 &slim_rx_mux[TASHA_RX6]),
10469 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TASHA_RX7, 0,
10470 &slim_rx_mux[TASHA_RX7]),
10471
10472 SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
10473 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10474 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10475 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
10476 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
10477 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
10478 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
10479 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
10480
10481 SND_SOC_DAPM_MUX_E("SPL SRC0 MUX", SND_SOC_NOPM, SPLINE_SRC0, 0,
10482 &spl_src0_mux, tasha_codec_enable_spline_resampler,
10483 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10484 SND_SOC_DAPM_MUX_E("SPL SRC1 MUX", SND_SOC_NOPM, SPLINE_SRC1, 0,
10485 &spl_src1_mux, tasha_codec_enable_spline_resampler,
10486 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10487 SND_SOC_DAPM_MUX_E("SPL SRC2 MUX", SND_SOC_NOPM, SPLINE_SRC2, 0,
10488 &spl_src2_mux, tasha_codec_enable_spline_resampler,
10489 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10490 SND_SOC_DAPM_MUX_E("SPL SRC3 MUX", SND_SOC_NOPM, SPLINE_SRC3, 0,
10491 &spl_src3_mux, tasha_codec_enable_spline_resampler,
10492 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10493
10494 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
10495 5, 0, &rx_int0_2_mux, tasha_codec_enable_mix_path,
10496 SND_SOC_DAPM_POST_PMU),
10497 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
10498 5, 0, &rx_int1_2_mux, tasha_codec_enable_mix_path,
10499 SND_SOC_DAPM_POST_PMU),
10500 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
10501 5, 0, &rx_int2_2_mux, tasha_codec_enable_mix_path,
10502 SND_SOC_DAPM_POST_PMU),
10503 SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL,
10504 5, 0, &rx_int3_2_mux, tasha_codec_enable_mix_path,
10505 SND_SOC_DAPM_POST_PMU),
10506 SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL,
10507 5, 0, &rx_int4_2_mux, tasha_codec_enable_mix_path,
10508 SND_SOC_DAPM_POST_PMU),
10509 SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL,
10510 5, 0, &rx_int5_2_mux, tasha_codec_enable_mix_path,
10511 SND_SOC_DAPM_POST_PMU),
10512 SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL,
10513 5, 0, &rx_int6_2_mux, tasha_codec_enable_mix_path,
10514 SND_SOC_DAPM_POST_PMU),
10515 SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL,
10516 5, 0, &rx_int7_2_mux, tasha_codec_enable_mix_path,
10517 SND_SOC_DAPM_POST_PMU),
10518 SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL,
10519 5, 0, &rx_int8_2_mux, tasha_codec_enable_mix_path,
10520 SND_SOC_DAPM_POST_PMU),
10521
10522 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10523 &rx_int0_1_mix_inp0_mux),
10524 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10525 &rx_int0_1_mix_inp1_mux),
10526 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10527 &rx_int0_1_mix_inp2_mux),
10528 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10529 &rx_int1_1_mix_inp0_mux),
10530 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10531 &rx_int1_1_mix_inp1_mux),
10532 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10533 &rx_int1_1_mix_inp2_mux),
10534 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10535 &rx_int2_1_mix_inp0_mux),
10536 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10537 &rx_int2_1_mix_inp1_mux),
10538 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10539 &rx_int2_1_mix_inp2_mux),
10540 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10541 &rx_int3_1_mix_inp0_mux),
10542 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10543 &rx_int3_1_mix_inp1_mux),
10544 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10545 &rx_int3_1_mix_inp2_mux),
10546 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10547 &rx_int4_1_mix_inp0_mux),
10548 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10549 &rx_int4_1_mix_inp1_mux),
10550 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10551 &rx_int4_1_mix_inp2_mux),
10552 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10553 &rx_int5_1_mix_inp0_mux),
10554 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10555 &rx_int5_1_mix_inp1_mux),
10556 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10557 &rx_int5_1_mix_inp2_mux),
10558 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10559 &rx_int6_1_mix_inp0_mux),
10560 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10561 &rx_int6_1_mix_inp1_mux),
10562 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10563 &rx_int6_1_mix_inp2_mux),
10564 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10565 &rx_int7_1_mix_inp0_mux, tasha_codec_enable_swr,
10566 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10567 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10568 &rx_int7_1_mix_inp1_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 INP2", SND_SOC_NOPM, 0, 0,
10571 &rx_int7_1_mix_inp2_mux, tasha_codec_enable_swr,
10572 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10573 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10574 &rx_int8_1_mix_inp0_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 INP1", SND_SOC_NOPM, 0, 0,
10577 &rx_int8_1_mix_inp1_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 INP2", SND_SOC_NOPM, 0, 0,
10580 &rx_int8_1_mix_inp2_mux, tasha_codec_enable_swr,
10581 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10582
10583 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10584 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10585 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10586 SND_SOC_DAPM_MIXER("RX INT1 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10587 rx_int1_spline_mix_switch,
10588 ARRAY_SIZE(rx_int1_spline_mix_switch)),
10589 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10590 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10591 SND_SOC_DAPM_MIXER("RX INT2 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10592 rx_int2_spline_mix_switch,
10593 ARRAY_SIZE(rx_int2_spline_mix_switch)),
10594 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10595 SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10596 SND_SOC_DAPM_MIXER("RX INT3 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10597 rx_int3_spline_mix_switch,
10598 ARRAY_SIZE(rx_int3_spline_mix_switch)),
10599 SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10600 SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10601 SND_SOC_DAPM_MIXER("RX INT4 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10602 rx_int4_spline_mix_switch,
10603 ARRAY_SIZE(rx_int4_spline_mix_switch)),
10604 SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10605 SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10606 SND_SOC_DAPM_MIXER("RX INT5 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10607 rx_int5_spline_mix_switch,
10608 ARRAY_SIZE(rx_int5_spline_mix_switch)),
10609 SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10610
10611 SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10612 SND_SOC_DAPM_MIXER("RX INT6 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10613 rx_int6_spline_mix_switch,
10614 ARRAY_SIZE(rx_int6_spline_mix_switch)),
10615 SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10616
10617 SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10618 SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10619 SND_SOC_DAPM_MIXER("RX INT7 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10620 rx_int7_spline_mix_switch,
10621 ARRAY_SIZE(rx_int7_spline_mix_switch)),
10622
10623 SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10624 SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10625 SND_SOC_DAPM_MIXER("RX INT8 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10626 rx_int8_spline_mix_switch,
10627 ARRAY_SIZE(rx_int8_spline_mix_switch)),
10628
10629 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10630 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10631 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10632 SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10633 SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10634 SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10635 SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10636 SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10637 SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0,
10638 NULL, 0, tasha_codec_spk_boost_event,
10639 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10640 SND_SOC_DAPM_MIXER_E("RX INT8 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
10644 SND_SOC_DAPM_MIXER_E("RX INT5 VBAT", SND_SOC_NOPM, 0, 0,
10645 rx_int5_vbat_mix_switch,
10646 ARRAY_SIZE(rx_int5_vbat_mix_switch),
10647 tasha_codec_vbat_enable_event,
10648 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10649 SND_SOC_DAPM_MIXER_E("RX INT6 VBAT", SND_SOC_NOPM, 0, 0,
10650 rx_int6_vbat_mix_switch,
10651 ARRAY_SIZE(rx_int6_vbat_mix_switch),
10652 tasha_codec_vbat_enable_event,
10653 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10654 SND_SOC_DAPM_MIXER_E("RX INT7 VBAT", SND_SOC_NOPM, 0, 0,
10655 rx_int7_vbat_mix_switch,
10656 ARRAY_SIZE(rx_int7_vbat_mix_switch),
10657 tasha_codec_vbat_enable_event,
10658 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10659 SND_SOC_DAPM_MIXER_E("RX INT8 VBAT", SND_SOC_NOPM, 0, 0,
10660 rx_int8_vbat_mix_switch,
10661 ARRAY_SIZE(rx_int8_vbat_mix_switch),
10662 tasha_codec_vbat_enable_event,
10663 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10664
10665 SND_SOC_DAPM_MUX("RX INT0 MIX2 INP", WCD9335_CDC_RX0_RX_PATH_CFG1, 4,
10666 0, &rx_int0_mix2_inp_mux),
10667 SND_SOC_DAPM_MUX("RX INT1 MIX2 INP", WCD9335_CDC_RX1_RX_PATH_CFG1, 4,
10668 0, &rx_int1_mix2_inp_mux),
10669 SND_SOC_DAPM_MUX("RX INT2 MIX2 INP", WCD9335_CDC_RX2_RX_PATH_CFG1, 4,
10670 0, &rx_int2_mix2_inp_mux),
10671 SND_SOC_DAPM_MUX("RX INT3 MIX2 INP", WCD9335_CDC_RX3_RX_PATH_CFG1, 4,
10672 0, &rx_int3_mix2_inp_mux),
10673 SND_SOC_DAPM_MUX("RX INT4 MIX2 INP", WCD9335_CDC_RX4_RX_PATH_CFG1, 4,
10674 0, &rx_int4_mix2_inp_mux),
10675 SND_SOC_DAPM_MUX("RX INT7 MIX2 INP", WCD9335_CDC_RX7_RX_PATH_CFG1, 4,
10676 0, &rx_int7_mix2_inp_mux),
10677
10678 SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, TASHA_TX0, 0,
10679 &sb_tx0_mux),
10680 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TASHA_TX1, 0,
10681 &sb_tx1_mux),
10682 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TASHA_TX2, 0,
10683 &sb_tx2_mux),
10684 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TASHA_TX3, 0,
10685 &sb_tx3_mux),
10686 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TASHA_TX4, 0,
10687 &sb_tx4_mux),
10688 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TASHA_TX5, 0,
10689 &sb_tx5_mux),
10690 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TASHA_TX6, 0,
10691 &sb_tx6_mux),
10692 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TASHA_TX7, 0,
10693 &sb_tx7_mux),
10694 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TASHA_TX8, 0,
10695 &sb_tx8_mux),
10696 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TASHA_TX9, 0,
10697 &sb_tx9_mux),
10698 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TASHA_TX10, 0,
10699 &sb_tx10_mux),
10700 SND_SOC_DAPM_MUX("SLIM TX11 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10701 &sb_tx11_mux),
10702 SND_SOC_DAPM_MUX("SLIM TX11 INP1 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10703 &sb_tx11_inp1_mux),
10704 SND_SOC_DAPM_MUX("SLIM TX13 MUX", SND_SOC_NOPM, TASHA_TX13, 0,
10705 &sb_tx13_mux),
10706 SND_SOC_DAPM_MUX("TX13 INP MUX", SND_SOC_NOPM, 0, 0,
10707 &tx13_inp_mux),
10708
10709 SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0,
10710 &tx_adc_mux0, tasha_codec_enable_dec,
10711 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10712 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10713
10714 SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0,
10715 &tx_adc_mux1, tasha_codec_enable_dec,
10716 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10717 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10718
10719 SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0,
10720 &tx_adc_mux2, tasha_codec_enable_dec,
10721 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10722 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10723
10724 SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0,
10725 &tx_adc_mux3, tasha_codec_enable_dec,
10726 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10727 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10728
10729 SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0,
10730 &tx_adc_mux4, tasha_codec_enable_dec,
10731 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10732 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10733
10734 SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0,
10735 &tx_adc_mux5, tasha_codec_enable_dec,
10736 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10737 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10738
10739 SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0,
10740 &tx_adc_mux6, tasha_codec_enable_dec,
10741 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10742 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10743
10744 SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0,
10745 &tx_adc_mux7, tasha_codec_enable_dec,
10746 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10747 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10748
10749 SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0,
10750 &tx_adc_mux8, tasha_codec_enable_dec,
10751 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10752 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10753
10754 SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0,
10755 &tx_adc_mux10, tasha_codec_tx_adc_cfg,
10756 SND_SOC_DAPM_POST_PMU),
10757
10758 SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0,
10759 &tx_adc_mux11, tasha_codec_tx_adc_cfg,
10760 SND_SOC_DAPM_POST_PMU),
10761
10762 SND_SOC_DAPM_MUX_E("ADC MUX12", SND_SOC_NOPM, 12, 0,
10763 &tx_adc_mux12, tasha_codec_tx_adc_cfg,
10764 SND_SOC_DAPM_POST_PMU),
10765
10766 SND_SOC_DAPM_MUX_E("ADC MUX13", SND_SOC_NOPM, 13, 0,
10767 &tx_adc_mux13, tasha_codec_tx_adc_cfg,
10768 SND_SOC_DAPM_POST_PMU),
10769
10770 SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0,
10771 &tx_dmic_mux0),
10772 SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0,
10773 &tx_dmic_mux1),
10774 SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0,
10775 &tx_dmic_mux2),
10776 SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0,
10777 &tx_dmic_mux3),
10778 SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0,
10779 &tx_dmic_mux4),
10780 SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0,
10781 &tx_dmic_mux5),
10782 SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0,
10783 &tx_dmic_mux6),
10784 SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0,
10785 &tx_dmic_mux7),
10786 SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0,
10787 &tx_dmic_mux8),
10788 SND_SOC_DAPM_MUX("DMIC MUX10", SND_SOC_NOPM, 0, 0,
10789 &tx_dmic_mux10),
10790 SND_SOC_DAPM_MUX("DMIC MUX11", SND_SOC_NOPM, 0, 0,
10791 &tx_dmic_mux11),
10792 SND_SOC_DAPM_MUX("DMIC MUX12", SND_SOC_NOPM, 0, 0,
10793 &tx_dmic_mux12),
10794 SND_SOC_DAPM_MUX("DMIC MUX13", SND_SOC_NOPM, 0, 0,
10795 &tx_dmic_mux13),
10796
10797 SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0,
10798 &tx_amic_mux0),
10799 SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0,
10800 &tx_amic_mux1),
10801 SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0,
10802 &tx_amic_mux2),
10803 SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0,
10804 &tx_amic_mux3),
10805 SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0,
10806 &tx_amic_mux4),
10807 SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0,
10808 &tx_amic_mux5),
10809 SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0,
10810 &tx_amic_mux6),
10811 SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0,
10812 &tx_amic_mux7),
10813 SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0,
10814 &tx_amic_mux8),
10815 SND_SOC_DAPM_MUX("AMIC MUX10", SND_SOC_NOPM, 0, 0,
10816 &tx_amic_mux10),
10817 SND_SOC_DAPM_MUX("AMIC MUX11", SND_SOC_NOPM, 0, 0,
10818 &tx_amic_mux11),
10819 SND_SOC_DAPM_MUX("AMIC MUX12", SND_SOC_NOPM, 0, 0,
10820 &tx_amic_mux12),
10821 SND_SOC_DAPM_MUX("AMIC MUX13", SND_SOC_NOPM, 0, 0,
10822 &tx_amic_mux13),
10823
10824 SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0,
10825 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10826 SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0,
10827 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10828 SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0,
10829 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10830 SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0,
10831 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10832 SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0,
10833 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10834 SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0,
10835 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10836
10837 SND_SOC_DAPM_SUPPLY("RX INT1 NATIVE SUPPLY", SND_SOC_NOPM,
10838 INTERP_HPHL, 0, tasha_enable_native_supply,
10839 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10840
10841 SND_SOC_DAPM_SUPPLY("RX INT2 NATIVE SUPPLY", SND_SOC_NOPM,
10842 INTERP_HPHR, 0, tasha_enable_native_supply,
10843 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10844
10845 SND_SOC_DAPM_SUPPLY("RX INT3 NATIVE SUPPLY", SND_SOC_NOPM,
10846 INTERP_LO1, 0, tasha_enable_native_supply,
10847 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10848
10849 SND_SOC_DAPM_SUPPLY("RX INT4 NATIVE SUPPLY", SND_SOC_NOPM,
10850 INTERP_LO2, 0, tasha_enable_native_supply,
10851 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10852
10853 SND_SOC_DAPM_INPUT("AMIC1"),
10854 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0,
10855 tasha_codec_enable_micbias,
10856 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10857 SND_SOC_DAPM_POST_PMD),
10858 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0,
10859 tasha_codec_enable_micbias,
10860 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10861 SND_SOC_DAPM_POST_PMD),
10862 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0,
10863 tasha_codec_enable_micbias,
10864 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10865 SND_SOC_DAPM_POST_PMD),
10866 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0,
10867 tasha_codec_enable_micbias,
10868 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10869 SND_SOC_DAPM_POST_PMD),
10870
10871 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0,
10872 tasha_codec_force_enable_micbias,
10873 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10874 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_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_MICBIAS3_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_MICBIAS4_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_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0,
10884 tasha_codec_force_enable_ldo_h,
10885 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10886
10887 SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux),
10888 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
10889
10890 SND_SOC_DAPM_INPUT("AMIC2"),
10891 SND_SOC_DAPM_INPUT("AMIC3"),
10892 SND_SOC_DAPM_INPUT("AMIC4"),
10893 SND_SOC_DAPM_INPUT("AMIC5"),
10894 SND_SOC_DAPM_INPUT("AMIC6"),
10895
10896 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
10897 AIF1_CAP, 0, tasha_codec_enable_slimtx,
10898 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10899
10900 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
10901 AIF2_CAP, 0, tasha_codec_enable_slimtx,
10902 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10903
10904 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
10905 AIF3_CAP, 0, tasha_codec_enable_slimtx,
10906 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10907
10908 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
10909 AIF4_VIFEED, 0, tasha_codec_enable_slimvi_feedback,
10910 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10911 SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0,
10912 aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)),
10913
10914 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
10915 aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
10916
10917 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
10918 aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
10919
10920 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
10921 aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
10922
10923 SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0,
10924 aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)),
10925
10926 SND_SOC_DAPM_INPUT("VIINPUT"),
10927
10928 SND_SOC_DAPM_AIF_OUT("AIF5 CPE", "AIF5 CPE TX", 0, SND_SOC_NOPM,
10929 AIF5_CPE_TX, 0),
10930
10931 SND_SOC_DAPM_MUX_E("EC BUF MUX INP", SND_SOC_NOPM, 0, 0, &ec_buf_mux,
10932 tasha_codec_ec_buf_mux_enable,
10933 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10934
10935 /* Digital Mic Inputs */
10936 SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
10937 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10938 SND_SOC_DAPM_POST_PMD),
10939
10940 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
10941 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10942 SND_SOC_DAPM_POST_PMD),
10943
10944 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
10945 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10946 SND_SOC_DAPM_POST_PMD),
10947
10948 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
10949 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10950 SND_SOC_DAPM_POST_PMD),
10951
10952 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
10953 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10954 SND_SOC_DAPM_POST_PMD),
10955
10956 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
10957 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10958 SND_SOC_DAPM_POST_PMD),
10959
10960 SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux),
10961 SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux),
10962 SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux),
10963 SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux),
10964 SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux),
10965 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
10966 SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux),
10967 SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux),
10968
10969 SND_SOC_DAPM_MIXER_E("IIR0", WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL,
10970 4, 0, NULL, 0, tasha_codec_set_iir_gain,
10971 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
10972 SND_SOC_DAPM_MIXER_E("IIR1", WCD9335_CDC_SIDETONE_IIR1_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("SRC0", WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL,
10976 4, 0, NULL, 0),
10977 SND_SOC_DAPM_MIXER("SRC1", WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL,
10978 4, 0, NULL, 0),
10979 SND_SOC_DAPM_MIXER_E("CPE IN Mixer", SND_SOC_NOPM, 0, 0,
10980 cpe_in_mix_switch,
10981 ARRAY_SIZE(cpe_in_mix_switch),
10982 tasha_codec_configure_cpe_input,
10983 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10984
10985 SND_SOC_DAPM_MUX("RX INT1_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10986 &int1_1_native_mux),
10987 SND_SOC_DAPM_MUX("RX INT2_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10988 &int2_1_native_mux),
10989 SND_SOC_DAPM_MUX("RX INT3_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10990 &int3_1_native_mux),
10991 SND_SOC_DAPM_MUX("RX INT4_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10992 &int4_1_native_mux),
10993 SND_SOC_DAPM_MUX("RX MIX TX0 MUX", SND_SOC_NOPM, 0, 0,
10994 &rx_mix_tx0_mux),
10995 SND_SOC_DAPM_MUX("RX MIX TX1 MUX", SND_SOC_NOPM, 0, 0,
10996 &rx_mix_tx1_mux),
10997 SND_SOC_DAPM_MUX("RX MIX TX2 MUX", SND_SOC_NOPM, 0, 0,
10998 &rx_mix_tx2_mux),
10999 SND_SOC_DAPM_MUX("RX MIX TX3 MUX", SND_SOC_NOPM, 0, 0,
11000 &rx_mix_tx3_mux),
11001 SND_SOC_DAPM_MUX("RX MIX TX4 MUX", SND_SOC_NOPM, 0, 0,
11002 &rx_mix_tx4_mux),
11003 SND_SOC_DAPM_MUX("RX MIX TX5 MUX", SND_SOC_NOPM, 0, 0,
11004 &rx_mix_tx5_mux),
11005 SND_SOC_DAPM_MUX("RX MIX TX6 MUX", SND_SOC_NOPM, 0, 0,
11006 &rx_mix_tx6_mux),
11007 SND_SOC_DAPM_MUX("RX MIX TX7 MUX", SND_SOC_NOPM, 0, 0,
11008 &rx_mix_tx7_mux),
11009 SND_SOC_DAPM_MUX("RX MIX TX8 MUX", SND_SOC_NOPM, 0, 0,
11010 &rx_mix_tx8_mux),
11011
11012 SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0,
11013 &rx_int0_dem_inp_mux),
11014 SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0,
11015 &rx_int1_dem_inp_mux),
11016 SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0,
11017 &rx_int2_dem_inp_mux),
11018
11019 SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM,
11020 INTERP_EAR, 0, &rx_int0_interp_mux,
11021 tasha_codec_enable_interpolator,
11022 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11023 SND_SOC_DAPM_POST_PMD),
11024 SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM,
11025 INTERP_HPHL, 0, &rx_int1_interp_mux,
11026 tasha_codec_enable_interpolator,
11027 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11028 SND_SOC_DAPM_POST_PMD),
11029 SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM,
11030 INTERP_HPHR, 0, &rx_int2_interp_mux,
11031 tasha_codec_enable_interpolator,
11032 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11033 SND_SOC_DAPM_POST_PMD),
11034 SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM,
11035 INTERP_LO1, 0, &rx_int3_interp_mux,
11036 tasha_codec_enable_interpolator,
11037 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11038 SND_SOC_DAPM_POST_PMD),
11039 SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM,
11040 INTERP_LO2, 0, &rx_int4_interp_mux,
11041 tasha_codec_enable_interpolator,
11042 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11043 SND_SOC_DAPM_POST_PMD),
11044 SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM,
11045 INTERP_LO3, 0, &rx_int5_interp_mux,
11046 tasha_codec_enable_interpolator,
11047 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11048 SND_SOC_DAPM_POST_PMD),
11049 SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM,
11050 INTERP_LO4, 0, &rx_int6_interp_mux,
11051 tasha_codec_enable_interpolator,
11052 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11053 SND_SOC_DAPM_POST_PMD),
11054 SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM,
11055 INTERP_SPKR1, 0, &rx_int7_interp_mux,
11056 tasha_codec_enable_interpolator,
11057 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11058 SND_SOC_DAPM_POST_PMD),
11059 SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM,
11060 INTERP_SPKR2, 0, &rx_int8_interp_mux,
11061 tasha_codec_enable_interpolator,
11062 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11063 SND_SOC_DAPM_POST_PMD),
11064
11065 SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
11066 0, 0, tasha_codec_ear_dac_event,
11067 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11068 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11069 SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH,
11070 5, 0, tasha_codec_hphl_dac_event,
11071 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11072 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11073 SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH,
11074 4, 0, tasha_codec_hphr_dac_event,
11075 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11076 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11077 SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM,
11078 0, 0, tasha_codec_lineout_dac_event,
11079 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11080 SND_SOC_DAPM_DAC_E("RX INT4 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 INT5 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 INT6 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_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0,
11090 tasha_codec_enable_hphl_pa,
11091 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11092 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11093 SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0,
11094 tasha_codec_enable_hphr_pa,
11095 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11096 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11097 SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11098 tasha_codec_enable_ear_pa,
11099 SND_SOC_DAPM_POST_PMU |
11100 SND_SOC_DAPM_POST_PMD),
11101 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0,
11102 tasha_codec_enable_lineout_pa,
11103 SND_SOC_DAPM_POST_PMU |
11104 SND_SOC_DAPM_POST_PMD),
11105 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0,
11106 tasha_codec_enable_lineout_pa,
11107 SND_SOC_DAPM_POST_PMU |
11108 SND_SOC_DAPM_POST_PMD),
11109 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0,
11110 tasha_codec_enable_lineout_pa,
11111 SND_SOC_DAPM_POST_PMU |
11112 SND_SOC_DAPM_POST_PMD),
11113 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0,
11114 tasha_codec_enable_lineout_pa,
11115 SND_SOC_DAPM_POST_PMU |
11116 SND_SOC_DAPM_POST_PMD),
11117 SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11118 tasha_codec_enable_ear_pa,
11119 SND_SOC_DAPM_POST_PMU |
11120 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11121 SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11122 tasha_codec_enable_hphl_pa,
11123 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11124 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11125 SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11126 tasha_codec_enable_hphr_pa,
11127 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11128 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11129 SND_SOC_DAPM_PGA_E("ANC LINEOUT1 PA", WCD9335_ANA_LO_1_2,
11130 7, 0, NULL, 0,
11131 tasha_codec_enable_lineout_pa,
11132 SND_SOC_DAPM_POST_PMU |
11133 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11134 SND_SOC_DAPM_PGA_E("ANC LINEOUT2 PA", WCD9335_ANA_LO_1_2,
11135 6, 0, NULL, 0,
11136 tasha_codec_enable_lineout_pa,
11137 SND_SOC_DAPM_POST_PMU |
11138 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11139 SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11140 tasha_codec_enable_spk_anc,
11141 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11142
11143 SND_SOC_DAPM_OUTPUT("HPHL"),
11144 SND_SOC_DAPM_OUTPUT("HPHR"),
11145 SND_SOC_DAPM_OUTPUT("ANC HPHL"),
11146 SND_SOC_DAPM_OUTPUT("ANC HPHR"),
11147 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
11148 tasha_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
11149 SND_SOC_DAPM_POST_PMD),
11150 SND_SOC_DAPM_OUTPUT("SPK1 OUT"),
11151 SND_SOC_DAPM_OUTPUT("SPK2 OUT"),
11152 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
11153 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
11154 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
11155 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
11156 SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"),
11157 SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"),
11158 SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
11159 ON_DEMAND_MICBIAS, 0,
11160 tasha_codec_enable_on_demand_supply,
11161 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11162
11163 SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0,
11164 0, &adc_us_mux0_switch),
11165 SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9335_CDC_TX1_TX_PATH_192_CTL, 0,
11166 0, &adc_us_mux1_switch),
11167 SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9335_CDC_TX2_TX_PATH_192_CTL, 0,
11168 0, &adc_us_mux2_switch),
11169 SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9335_CDC_TX3_TX_PATH_192_CTL, 0,
11170 0, &adc_us_mux3_switch),
11171 SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9335_CDC_TX4_TX_PATH_192_CTL, 0,
11172 0, &adc_us_mux4_switch),
11173 SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9335_CDC_TX5_TX_PATH_192_CTL, 0,
11174 0, &adc_us_mux5_switch),
11175 SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9335_CDC_TX6_TX_PATH_192_CTL, 0,
11176 0, &adc_us_mux6_switch),
11177 SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9335_CDC_TX7_TX_PATH_192_CTL, 0,
11178 0, &adc_us_mux7_switch),
11179 SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9335_CDC_TX8_TX_PATH_192_CTL, 0,
11180 0, &adc_us_mux8_switch),
11181 /* MAD related widgets */
11182 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
11183 SND_SOC_NOPM, 0, 0,
11184 tasha_codec_enable_mad,
11185 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11186
11187 SND_SOC_DAPM_MUX("MAD_SEL MUX", SND_SOC_NOPM, 0, 0,
11188 &mad_sel_mux),
11189 SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"),
11190 SND_SOC_DAPM_INPUT("MADINPUT"),
11191 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
11192 &aif4_mad_switch),
11193 SND_SOC_DAPM_SWITCH("MAD_BROADCAST", SND_SOC_NOPM, 0, 0,
11194 &mad_brdcst_switch),
11195 SND_SOC_DAPM_SWITCH("AIF4", SND_SOC_NOPM, 0, 0,
11196 &aif4_switch_mixer_controls),
11197 SND_SOC_DAPM_SWITCH("ANC HPHL Enable", SND_SOC_NOPM, 0, 0,
11198 &anc_hphl_switch),
11199 SND_SOC_DAPM_SWITCH("ANC HPHR Enable", SND_SOC_NOPM, 0, 0,
11200 &anc_hphr_switch),
11201 SND_SOC_DAPM_SWITCH("ANC EAR Enable", SND_SOC_NOPM, 0, 0,
11202 &anc_ear_switch),
11203 SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0,
11204 &anc_ear_spkr_switch),
11205 SND_SOC_DAPM_SWITCH("ANC LINEOUT1 Enable", SND_SOC_NOPM, 0, 0,
11206 &anc_lineout1_switch),
11207 SND_SOC_DAPM_SWITCH("ANC LINEOUT2 Enable", SND_SOC_NOPM, 0, 0,
11208 &anc_lineout2_switch),
11209 SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0,
11210 &anc_spkr_pa_switch),
11211};
11212
11213static int tasha_get_channel_map(struct snd_soc_dai *dai,
11214 unsigned int *tx_num, unsigned int *tx_slot,
11215 unsigned int *rx_num, unsigned int *rx_slot)
11216{
11217 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(dai->codec);
11218 u32 i = 0;
11219 struct wcd9xxx_ch *ch;
11220
11221 switch (dai->id) {
11222 case AIF1_PB:
11223 case AIF2_PB:
11224 case AIF3_PB:
11225 case AIF4_PB:
11226 case AIF_MIX1_PB:
11227 if (!rx_slot || !rx_num) {
11228 pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n",
11229 __func__, rx_slot, rx_num);
11230 return -EINVAL;
11231 }
11232 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11233 list) {
11234 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11235 __func__, i, ch->ch_num);
11236 rx_slot[i++] = ch->ch_num;
11237 }
11238 pr_debug("%s: rx_num %d\n", __func__, i);
11239 *rx_num = i;
11240 break;
11241 case AIF1_CAP:
11242 case AIF2_CAP:
11243 case AIF3_CAP:
11244 case AIF4_MAD_TX:
11245 case AIF4_VIFEED:
11246 if (!tx_slot || !tx_num) {
11247 pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n",
11248 __func__, tx_slot, tx_num);
11249 return -EINVAL;
11250 }
11251 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11252 list) {
11253 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11254 __func__, i, ch->ch_num);
11255 tx_slot[i++] = ch->ch_num;
11256 }
11257 pr_debug("%s: tx_num %d\n", __func__, i);
11258 *tx_num = i;
11259 break;
11260
11261 default:
11262 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
11263 break;
11264 }
11265
11266 return 0;
11267}
11268
11269static int tasha_set_channel_map(struct snd_soc_dai *dai,
11270 unsigned int tx_num, unsigned int *tx_slot,
11271 unsigned int rx_num, unsigned int *rx_slot)
11272{
11273 struct tasha_priv *tasha;
11274 struct wcd9xxx *core;
11275 struct wcd9xxx_codec_dai_data *dai_data = NULL;
11276
11277 if (!dai) {
11278 pr_err("%s: dai is empty\n", __func__);
11279 return -EINVAL;
11280 }
11281 tasha = snd_soc_codec_get_drvdata(dai->codec);
11282 core = dev_get_drvdata(dai->codec->dev->parent);
11283
11284 if (!tx_slot || !rx_slot) {
11285 pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n",
11286 __func__, tx_slot, rx_slot);
11287 return -EINVAL;
11288 }
11289 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
11290 "tasha->intf_type %d\n",
11291 __func__, dai->name, dai->id, tx_num, rx_num,
11292 tasha->intf_type);
11293
11294 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
11295 wcd9xxx_init_slimslave(core, core->slim->laddr,
11296 tx_num, tx_slot, rx_num, rx_slot);
11297 /* Reserve TX12/TX13 for MAD data channel */
11298 dai_data = &tasha->dai[AIF4_MAD_TX];
11299 if (dai_data) {
11300 if (TASHA_IS_2_0(tasha->wcd9xxx))
11301 list_add_tail(&core->tx_chs[TASHA_TX13].list,
11302 &dai_data->wcd9xxx_ch_list);
11303 else
11304 list_add_tail(&core->tx_chs[TASHA_TX12].list,
11305 &dai_data->wcd9xxx_ch_list);
11306 }
11307 }
11308 return 0;
11309}
11310
11311static int tasha_startup(struct snd_pcm_substream *substream,
11312 struct snd_soc_dai *dai)
11313{
11314 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11315 substream->name, substream->stream);
11316
11317 return 0;
11318}
11319
11320static void tasha_shutdown(struct snd_pcm_substream *substream,
11321 struct snd_soc_dai *dai)
11322{
11323 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11324
11325 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11326 substream->name, substream->stream);
11327
11328 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
11329 return;
11330
11331 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
11332 test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
11333 tasha_codec_vote_max_bw(dai->codec, false);
11334 clear_bit(SB_CLK_GEAR, &tasha->status_mask);
11335 }
11336}
11337
11338static int tasha_set_decimator_rate(struct snd_soc_dai *dai,
11339 u8 tx_fs_rate_reg_val, u32 sample_rate)
11340{
11341 struct snd_soc_codec *codec = dai->codec;
11342 struct wcd9xxx_ch *ch;
11343 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11344 u32 tx_port = 0;
11345 u8 shift = 0, shift_val = 0, tx_mux_sel = 0;
11346 int decimator = -1;
11347 u16 tx_port_reg = 0, tx_fs_reg = 0;
11348
11349 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11350 tx_port = ch->port;
11351 dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d",
11352 __func__, dai->id, tx_port);
11353
11354 if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) {
11355 dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n",
11356 __func__, tx_port, dai->id);
11357 return -EINVAL;
11358 }
11359 /* Find the SB TX MUX input - which decimator is connected */
11360 if (tx_port < 4) {
11361 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0;
11362 shift = (tx_port << 1);
11363 shift_val = 0x03;
11364 } else if ((tx_port >= 4) && (tx_port < 8)) {
11365 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1;
11366 shift = ((tx_port - 4) << 1);
11367 shift_val = 0x03;
11368 } else if ((tx_port >= 8) && (tx_port < 11)) {
11369 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2;
11370 shift = ((tx_port - 8) << 1);
11371 shift_val = 0x03;
11372 } else if (tx_port == 11) {
11373 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11374 shift = 0;
11375 shift_val = 0x0F;
11376 } else if (tx_port == 13) {
11377 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11378 shift = 4;
11379 shift_val = 0x03;
11380 }
11381 tx_mux_sel = snd_soc_read(codec, tx_port_reg) &
11382 (shift_val << shift);
11383 tx_mux_sel = tx_mux_sel >> shift;
11384
11385 if (tx_port <= 8) {
11386 if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
11387 decimator = tx_port;
11388 } else if (tx_port <= 10) {
11389 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11390 decimator = ((tx_port == 9) ? 7 : 6);
11391 } else if (tx_port == 11) {
11392 if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
11393 decimator = tx_mux_sel - 1;
11394 } else if (tx_port == 13) {
11395 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11396 decimator = 5;
11397 }
11398
11399 if (decimator >= 0) {
11400 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
11401 16 * decimator;
11402 dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
11403 __func__, decimator, tx_port, sample_rate);
11404 snd_soc_update_bits(codec, tx_fs_reg, 0x0F,
11405 tx_fs_rate_reg_val);
11406 } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) {
11407 /* Check if the TX Mux input is RX MIX TXn */
11408 dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to SLIM TX%u\n",
11409 __func__, tx_port, tx_port);
11410 } else {
11411 dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n",
11412 __func__, decimator);
11413 return -EINVAL;
11414 }
11415 }
11416 return 0;
11417}
11418
11419static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai,
11420 u8 int_mix_fs_rate_reg_val,
11421 u32 sample_rate)
11422{
11423 u8 int_2_inp;
11424 u32 j;
11425 u16 int_mux_cfg1, int_fs_reg;
11426 u8 int_mux_cfg1_val;
11427 struct snd_soc_codec *codec = dai->codec;
11428 struct wcd9xxx_ch *ch;
11429 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11430
11431 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11432 int_2_inp = ch->port + INTn_2_INP_SEL_RX0 -
11433 TASHA_RX_PORT_START_NUMBER;
11434 if ((int_2_inp < INTn_2_INP_SEL_RX0) ||
11435 (int_2_inp > INTn_2_INP_SEL_RX7)) {
11436 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11437 __func__,
11438 (ch->port - TASHA_RX_PORT_START_NUMBER),
11439 dai->id);
11440 return -EINVAL;
11441 }
11442
11443 int_mux_cfg1 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1;
11444 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11445 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) &
11446 0x0F;
11447 if (int_mux_cfg1_val == int_2_inp) {
11448 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_MIX_CTL +
11449 20 * j;
11450 pr_debug("%s: AIF_MIX_PB DAI(%d) connected to INT%u_2\n",
11451 __func__, dai->id, j);
11452 pr_debug("%s: set INT%u_2 sample rate to %u\n",
11453 __func__, j, sample_rate);
11454 snd_soc_update_bits(codec, int_fs_reg,
11455 0x0F, int_mix_fs_rate_reg_val);
11456 }
11457 int_mux_cfg1 += 2;
11458 }
11459 }
11460 return 0;
11461}
11462
11463static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai,
11464 u8 int_prim_fs_rate_reg_val,
11465 u32 sample_rate)
11466{
11467 u8 int_1_mix1_inp;
11468 u32 j;
11469 u16 int_mux_cfg0, int_mux_cfg1;
11470 u16 int_fs_reg;
11471 u8 int_mux_cfg0_val, int_mux_cfg1_val;
11472 u8 inp0_sel, inp1_sel, inp2_sel;
11473 struct snd_soc_codec *codec = dai->codec;
11474 struct wcd9xxx_ch *ch;
11475 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11476
11477 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11478 int_1_mix1_inp = ch->port + INTn_1_MIX_INP_SEL_RX0 -
11479 TASHA_RX_PORT_START_NUMBER;
11480 if ((int_1_mix1_inp < INTn_1_MIX_INP_SEL_RX0) ||
11481 (int_1_mix1_inp > INTn_1_MIX_INP_SEL_RX7)) {
11482 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11483 __func__,
11484 (ch->port - TASHA_RX_PORT_START_NUMBER),
11485 dai->id);
11486 return -EINVAL;
11487 }
11488
11489 int_mux_cfg0 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0;
11490
11491 /*
11492 * Loop through all interpolator MUX inputs and find out
11493 * to which interpolator input, the slim rx port
11494 * is connected
11495 */
11496 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11497 int_mux_cfg1 = int_mux_cfg0 + 1;
11498
11499 int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0);
11500 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1);
11501 inp0_sel = int_mux_cfg0_val & 0x0F;
11502 inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F;
11503 inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F;
11504 if ((inp0_sel == int_1_mix1_inp) ||
11505 (inp1_sel == int_1_mix1_inp) ||
11506 (inp2_sel == int_1_mix1_inp)) {
11507 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_CTL +
11508 20 * j;
11509 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
11510 __func__, dai->id, j);
11511 pr_debug("%s: set INT%u_1 sample rate to %u\n",
11512 __func__, j, sample_rate);
11513 /* sample_rate is in Hz */
11514 if ((j == 0) && (sample_rate == 44100)) {
11515 pr_info("%s: Cannot set 44.1KHz on INT0\n",
11516 __func__);
11517 } else
11518 snd_soc_update_bits(codec, int_fs_reg,
11519 0x0F, int_prim_fs_rate_reg_val);
11520 }
11521 int_mux_cfg0 += 2;
11522 }
11523 }
11524
11525 return 0;
11526}
11527
11528
11529static int tasha_set_interpolator_rate(struct snd_soc_dai *dai,
11530 u32 sample_rate)
11531{
11532 int rate_val = 0;
11533 int i, ret;
11534
11535 /* set mixing path rate */
11536 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
11537 if (sample_rate ==
11538 int_mix_sample_rate_val[i].sample_rate) {
11539 rate_val =
11540 int_mix_sample_rate_val[i].rate_val;
11541 break;
11542 }
11543 }
11544 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
11545 (rate_val < 0))
11546 goto prim_rate;
11547 ret = tasha_set_mix_interpolator_rate(dai,
11548 (u8) rate_val, sample_rate);
11549prim_rate:
11550 /* set primary path sample rate */
11551 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
11552 if (sample_rate ==
11553 int_prim_sample_rate_val[i].sample_rate) {
11554 rate_val =
11555 int_prim_sample_rate_val[i].rate_val;
11556 break;
11557 }
11558 }
11559 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
11560 (rate_val < 0))
11561 return -EINVAL;
11562 ret = tasha_set_prim_interpolator_rate(dai,
11563 (u8) rate_val, sample_rate);
11564 return ret;
11565}
11566
11567static int tasha_prepare(struct snd_pcm_substream *substream,
11568 struct snd_soc_dai *dai)
11569{
11570 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11571
11572 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11573 substream->name, substream->stream);
11574 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
11575 test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
11576 tasha_codec_vote_max_bw(dai->codec, false);
11577 clear_bit(SB_CLK_GEAR, &tasha->status_mask);
11578 }
11579 return 0;
11580}
11581
11582static int tasha_hw_params(struct snd_pcm_substream *substream,
11583 struct snd_pcm_hw_params *params,
11584 struct snd_soc_dai *dai)
11585{
11586 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11587 int ret;
11588 int tx_fs_rate = -EINVAL;
11589 int rx_fs_rate = -EINVAL;
11590 int i2s_bit_mode;
11591 struct snd_soc_codec *codec = dai->codec;
11592
11593 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
11594 dai->name, dai->id, params_rate(params),
11595 params_channels(params));
11596
11597 switch (substream->stream) {
11598 case SNDRV_PCM_STREAM_PLAYBACK:
11599 ret = tasha_set_interpolator_rate(dai, params_rate(params));
11600 if (ret) {
11601 pr_err("%s: cannot set sample rate: %u\n",
11602 __func__, params_rate(params));
11603 return ret;
11604 }
11605 switch (params_width(params)) {
11606 case 16:
11607 tasha->dai[dai->id].bit_width = 16;
11608 i2s_bit_mode = 0x01;
11609 break;
11610 case 24:
11611 tasha->dai[dai->id].bit_width = 24;
11612 i2s_bit_mode = 0x00;
11613 break;
11614 default:
11615 return -EINVAL;
11616 }
11617 tasha->dai[dai->id].rate = params_rate(params);
11618 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11619 switch (params_rate(params)) {
11620 case 8000:
11621 rx_fs_rate = 0;
11622 break;
11623 case 16000:
11624 rx_fs_rate = 1;
11625 break;
11626 case 32000:
11627 rx_fs_rate = 2;
11628 break;
11629 case 48000:
11630 rx_fs_rate = 3;
11631 break;
11632 case 96000:
11633 rx_fs_rate = 4;
11634 break;
11635 case 192000:
11636 rx_fs_rate = 5;
11637 break;
11638 default:
11639 dev_err(tasha->dev,
11640 "%s: Invalid RX sample rate: %d\n",
11641 __func__, params_rate(params));
11642 return -EINVAL;
11643 };
11644 snd_soc_update_bits(codec,
11645 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11646 0x20, i2s_bit_mode << 5);
11647 snd_soc_update_bits(codec,
11648 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11649 0x1c, (rx_fs_rate << 2));
11650 }
11651 break;
11652 case SNDRV_PCM_STREAM_CAPTURE:
11653 switch (params_rate(params)) {
11654 case 8000:
11655 tx_fs_rate = 0;
11656 break;
11657 case 16000:
11658 tx_fs_rate = 1;
11659 break;
11660 case 32000:
11661 tx_fs_rate = 3;
11662 break;
11663 case 48000:
11664 tx_fs_rate = 4;
11665 break;
11666 case 96000:
11667 tx_fs_rate = 5;
11668 break;
11669 case 192000:
11670 tx_fs_rate = 6;
11671 break;
11672 case 384000:
11673 tx_fs_rate = 7;
11674 break;
11675 default:
11676 dev_err(tasha->dev, "%s: Invalid TX sample rate: %d\n",
11677 __func__, params_rate(params));
11678 return -EINVAL;
11679
11680 };
11681 if (dai->id != AIF4_VIFEED &&
11682 dai->id != AIF4_MAD_TX) {
11683 ret = tasha_set_decimator_rate(dai, tx_fs_rate,
11684 params_rate(params));
11685 if (ret < 0) {
11686 dev_err(tasha->dev, "%s: cannot set TX Decimator rate: %d\n",
11687 __func__, tx_fs_rate);
11688 return ret;
11689 }
11690 }
11691 tasha->dai[dai->id].rate = params_rate(params);
11692 switch (params_width(params)) {
11693 case 16:
11694 tasha->dai[dai->id].bit_width = 16;
11695 i2s_bit_mode = 0x01;
11696 break;
11697 case 24:
11698 tasha->dai[dai->id].bit_width = 24;
11699 i2s_bit_mode = 0x00;
11700 break;
11701 case 32:
11702 tasha->dai[dai->id].bit_width = 32;
11703 i2s_bit_mode = 0x00;
11704 break;
11705 default:
11706 dev_err(tasha->dev, "%s: Invalid format 0x%x\n",
11707 __func__, params_width(params));
11708 return -EINVAL;
11709 };
11710 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11711 snd_soc_update_bits(codec,
11712 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11713 0x20, i2s_bit_mode << 5);
11714 if (tx_fs_rate > 1)
11715 tx_fs_rate--;
11716 snd_soc_update_bits(codec,
11717 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11718 0x1c, tx_fs_rate << 2);
11719 snd_soc_update_bits(codec,
11720 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG,
11721 0x05, 0x05);
11722
11723 snd_soc_update_bits(codec,
11724 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG,
11725 0x05, 0x05);
11726
11727 snd_soc_update_bits(codec,
11728 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG,
11729 0x05, 0x05);
11730
11731 snd_soc_update_bits(codec,
11732 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG,
11733 0x05, 0x05);
11734 }
11735 break;
11736 default:
11737 pr_err("%s: Invalid stream type %d\n", __func__,
11738 substream->stream);
11739 return -EINVAL;
11740 };
11741 if (dai->id == AIF4_VIFEED)
11742 tasha->dai[dai->id].bit_width = 32;
11743
11744 return 0;
11745}
11746
11747static int tasha_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
11748{
11749 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11750
11751 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
11752 case SND_SOC_DAIFMT_CBS_CFS:
11753 /* CPU is master */
11754 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11755 if (dai->id == AIF1_CAP)
11756 snd_soc_update_bits(dai->codec,
11757 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11758 0x2, 0);
11759 else if (dai->id == AIF1_PB)
11760 snd_soc_update_bits(dai->codec,
11761 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11762 0x2, 0);
11763 }
11764 break;
11765 case SND_SOC_DAIFMT_CBM_CFM:
11766 /* CPU is slave */
11767 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11768 if (dai->id == AIF1_CAP)
11769 snd_soc_update_bits(dai->codec,
11770 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11771 0x2, 0x2);
11772 else if (dai->id == AIF1_PB)
11773 snd_soc_update_bits(dai->codec,
11774 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11775 0x2, 0x2);
11776 }
11777 break;
11778 default:
11779 return -EINVAL;
11780 }
11781 return 0;
11782}
11783
11784static int tasha_set_dai_sysclk(struct snd_soc_dai *dai,
11785 int clk_id, unsigned int freq, int dir)
11786{
11787 pr_debug("%s\n", __func__);
11788 return 0;
11789}
11790
11791static struct snd_soc_dai_ops tasha_dai_ops = {
11792 .startup = tasha_startup,
11793 .shutdown = tasha_shutdown,
11794 .hw_params = tasha_hw_params,
11795 .prepare = tasha_prepare,
11796 .set_sysclk = tasha_set_dai_sysclk,
11797 .set_fmt = tasha_set_dai_fmt,
11798 .set_channel_map = tasha_set_channel_map,
11799 .get_channel_map = tasha_get_channel_map,
11800};
11801
11802static struct snd_soc_dai_driver tasha_dai[] = {
11803 {
11804 .name = "tasha_rx1",
11805 .id = AIF1_PB,
11806 .playback = {
11807 .stream_name = "AIF1 Playback",
11808 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11809 .formats = TASHA_FORMATS_S16_S24_LE,
11810 .rate_max = 192000,
11811 .rate_min = 8000,
11812 .channels_min = 1,
11813 .channels_max = 2,
11814 },
11815 .ops = &tasha_dai_ops,
11816 },
11817 {
11818 .name = "tasha_tx1",
11819 .id = AIF1_CAP,
11820 .capture = {
11821 .stream_name = "AIF1 Capture",
11822 .rates = WCD9335_RATES_MASK,
11823 .formats = TASHA_FORMATS_S16_S24_LE,
11824 .rate_max = 192000,
11825 .rate_min = 8000,
11826 .channels_min = 1,
11827 .channels_max = 4,
11828 },
11829 .ops = &tasha_dai_ops,
11830 },
11831 {
11832 .name = "tasha_rx2",
11833 .id = AIF2_PB,
11834 .playback = {
11835 .stream_name = "AIF2 Playback",
11836 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11837 .formats = TASHA_FORMATS_S16_S24_LE,
11838 .rate_min = 8000,
11839 .rate_max = 192000,
11840 .channels_min = 1,
11841 .channels_max = 2,
11842 },
11843 .ops = &tasha_dai_ops,
11844 },
11845 {
11846 .name = "tasha_tx2",
11847 .id = AIF2_CAP,
11848 .capture = {
11849 .stream_name = "AIF2 Capture",
11850 .rates = WCD9335_RATES_MASK,
11851 .formats = TASHA_FORMATS_S16_S24_LE,
11852 .rate_max = 192000,
11853 .rate_min = 8000,
11854 .channels_min = 1,
11855 .channels_max = 8,
11856 },
11857 .ops = &tasha_dai_ops,
11858 },
11859 {
11860 .name = "tasha_rx3",
11861 .id = AIF3_PB,
11862 .playback = {
11863 .stream_name = "AIF3 Playback",
11864 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11865 .formats = TASHA_FORMATS_S16_S24_LE,
11866 .rate_min = 8000,
11867 .rate_max = 192000,
11868 .channels_min = 1,
11869 .channels_max = 2,
11870 },
11871 .ops = &tasha_dai_ops,
11872 },
11873 {
11874 .name = "tasha_tx3",
11875 .id = AIF3_CAP,
11876 .capture = {
11877 .stream_name = "AIF3 Capture",
11878 .rates = WCD9335_RATES_MASK,
11879 .formats = TASHA_FORMATS_S16_S24_LE,
11880 .rate_max = 48000,
11881 .rate_min = 8000,
11882 .channels_min = 1,
11883 .channels_max = 2,
11884 },
11885 .ops = &tasha_dai_ops,
11886 },
11887 {
11888 .name = "tasha_rx4",
11889 .id = AIF4_PB,
11890 .playback = {
11891 .stream_name = "AIF4 Playback",
11892 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11893 .formats = TASHA_FORMATS_S16_S24_LE,
11894 .rate_min = 8000,
11895 .rate_max = 192000,
11896 .channels_min = 1,
11897 .channels_max = 2,
11898 },
11899 .ops = &tasha_dai_ops,
11900 },
11901 {
11902 .name = "tasha_mix_rx1",
11903 .id = AIF_MIX1_PB,
11904 .playback = {
11905 .stream_name = "AIF Mix Playback",
11906 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11907 .formats = TASHA_FORMATS_S16_S24_LE,
11908 .rate_min = 8000,
11909 .rate_max = 192000,
11910 .channels_min = 1,
11911 .channels_max = 8,
11912 },
11913 .ops = &tasha_dai_ops,
11914 },
11915 {
11916 .name = "tasha_mad1",
11917 .id = AIF4_MAD_TX,
11918 .capture = {
11919 .stream_name = "AIF4 MAD TX",
11920 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
11921 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000,
11922 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11923 .rate_min = 16000,
11924 .rate_max = 384000,
11925 .channels_min = 1,
11926 .channels_max = 1,
11927 },
11928 .ops = &tasha_dai_ops,
11929 },
11930 {
11931 .name = "tasha_vifeedback",
11932 .id = AIF4_VIFEED,
11933 .capture = {
11934 .stream_name = "VIfeed",
11935 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
11936 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11937 .rate_max = 48000,
11938 .rate_min = 8000,
11939 .channels_min = 1,
11940 .channels_max = 4,
11941 },
11942 .ops = &tasha_dai_ops,
11943 },
11944 {
11945 .name = "tasha_cpe",
11946 .id = AIF5_CPE_TX,
11947 .capture = {
11948 .stream_name = "AIF5 CPE TX",
11949 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
11950 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11951 .rate_min = 16000,
11952 .rate_max = 48000,
11953 .channels_min = 1,
11954 .channels_max = 1,
11955 },
11956 },
11957};
11958
11959static struct snd_soc_dai_driver tasha_i2s_dai[] = {
11960 {
11961 .name = "tasha_i2s_rx1",
11962 .id = AIF1_PB,
11963 .playback = {
11964 .stream_name = "AIF1 Playback",
11965 .rates = WCD9335_RATES_MASK,
11966 .formats = TASHA_FORMATS_S16_S24_LE,
11967 .rate_max = 192000,
11968 .rate_min = 8000,
11969 .channels_min = 1,
11970 .channels_max = 2,
11971 },
11972 .ops = &tasha_dai_ops,
11973 },
11974 {
11975 .name = "tasha_i2s_tx1",
11976 .id = AIF1_CAP,
11977 .capture = {
11978 .stream_name = "AIF1 Capture",
11979 .rates = WCD9335_RATES_MASK,
11980 .formats = TASHA_FORMATS_S16_S24_LE,
11981 .rate_max = 192000,
11982 .rate_min = 8000,
11983 .channels_min = 1,
11984 .channels_max = 4,
11985 },
11986 .ops = &tasha_dai_ops,
11987 },
11988 {
11989 .name = "tasha_i2s_rx2",
11990 .id = AIF2_PB,
11991 .playback = {
11992 .stream_name = "AIF2 Playback",
11993 .rates = WCD9335_RATES_MASK,
11994 .formats = TASHA_FORMATS_S16_S24_LE,
11995 .rate_max = 192000,
11996 .rate_min = 8000,
11997 .channels_min = 1,
11998 .channels_max = 2,
11999 },
12000 .ops = &tasha_dai_ops,
12001 },
12002 {
12003 .name = "tasha_i2s_tx2",
12004 .id = AIF2_CAP,
12005 .capture = {
12006 .stream_name = "AIF2 Capture",
12007 .rates = WCD9335_RATES_MASK,
12008 .formats = TASHA_FORMATS_S16_S24_LE,
12009 .rate_max = 192000,
12010 .rate_min = 8000,
12011 .channels_min = 1,
12012 .channels_max = 4,
12013 },
12014 .ops = &tasha_dai_ops,
12015 },
12016};
12017
12018static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha)
12019{
12020 struct snd_soc_codec *codec = tasha->codec;
12021
12022 if (!codec)
12023 return;
12024
12025 mutex_lock(&tasha->power_lock);
12026 dev_dbg(codec->dev, "%s: Entering power gating function, %d\n",
12027 __func__, tasha->power_active_ref);
12028
12029 if (tasha->power_active_ref > 0)
12030 goto exit;
12031
12032 wcd9xxx_set_power_state(tasha->wcd9xxx,
12033 WCD_REGION_POWER_COLLAPSE_BEGIN,
12034 WCD9XXX_DIG_CORE_REGION_1);
12035 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12036 0x04, 0x04);
12037 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12038 0x01, 0x00);
12039 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12040 0x02, 0x00);
12041 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12042 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
12043 wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_DOWN,
12044 WCD9XXX_DIG_CORE_REGION_1);
12045exit:
12046 dev_dbg(codec->dev, "%s: Exiting power gating function, %d\n",
12047 __func__, tasha->power_active_ref);
12048 mutex_unlock(&tasha->power_lock);
12049}
12050
12051static void tasha_codec_power_gate_work(struct work_struct *work)
12052{
12053 struct tasha_priv *tasha;
12054 struct delayed_work *dwork;
12055 struct snd_soc_codec *codec;
12056
12057 dwork = to_delayed_work(work);
12058 tasha = container_of(dwork, struct tasha_priv, power_gate_work);
12059 codec = tasha->codec;
12060
12061 if (!codec)
12062 return;
12063
12064 tasha_codec_power_gate_digital_core(tasha);
12065}
12066
12067/* called under power_lock acquisition */
12068static int tasha_dig_core_remove_power_collapse(struct snd_soc_codec *codec)
12069{
12070 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12071
12072 tasha_codec_vote_max_bw(codec, true);
12073 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
12074 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
12075 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
12076 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x00);
12077 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x02);
12078
12079 wcd9xxx_set_power_state(tasha->wcd9xxx,
12080 WCD_REGION_POWER_COLLAPSE_REMOVE,
12081 WCD9XXX_DIG_CORE_REGION_1);
12082 regcache_mark_dirty(codec->component.regmap);
12083 regcache_sync_region(codec->component.regmap,
12084 TASHA_DIG_CORE_REG_MIN, TASHA_DIG_CORE_REG_MAX);
12085 tasha_codec_vote_max_bw(codec, false);
12086
12087 return 0;
12088}
12089
12090static int tasha_dig_core_power_collapse(struct tasha_priv *tasha,
12091 int req_state)
12092{
12093 struct snd_soc_codec *codec;
12094 int cur_state;
12095
12096 /* Exit if feature is disabled */
12097 if (!dig_core_collapse_enable)
12098 return 0;
12099
12100 mutex_lock(&tasha->power_lock);
12101 if (req_state == POWER_COLLAPSE)
12102 tasha->power_active_ref--;
12103 else if (req_state == POWER_RESUME)
12104 tasha->power_active_ref++;
12105 else
12106 goto unlock_mutex;
12107
12108 if (tasha->power_active_ref < 0) {
12109 dev_dbg(tasha->dev, "%s: power_active_ref is negative\n",
12110 __func__);
12111 goto unlock_mutex;
12112 }
12113
12114 codec = tasha->codec;
12115 if (!codec)
12116 goto unlock_mutex;
12117
12118 if (req_state == POWER_COLLAPSE) {
12119 if (tasha->power_active_ref == 0) {
12120 schedule_delayed_work(&tasha->power_gate_work,
12121 msecs_to_jiffies(dig_core_collapse_timer * 1000));
12122 }
12123 } else if (req_state == POWER_RESUME) {
12124 if (tasha->power_active_ref == 1) {
12125 /*
12126 * At this point, there can be two cases:
12127 * 1. Core already in power collapse state
12128 * 2. Timer kicked in and still did not expire or
12129 * waiting for the power_lock
12130 */
12131 cur_state = wcd9xxx_get_current_power_state(
12132 tasha->wcd9xxx,
12133 WCD9XXX_DIG_CORE_REGION_1);
12134 if (cur_state == WCD_REGION_POWER_DOWN)
12135 tasha_dig_core_remove_power_collapse(codec);
12136 else {
12137 mutex_unlock(&tasha->power_lock);
12138 cancel_delayed_work_sync(
12139 &tasha->power_gate_work);
12140 mutex_lock(&tasha->power_lock);
12141 }
12142 }
12143 }
12144
12145unlock_mutex:
12146 mutex_unlock(&tasha->power_lock);
12147
12148 return 0;
12149}
12150
12151static int __tasha_cdc_mclk_enable_locked(struct tasha_priv *tasha,
12152 bool enable)
12153{
12154 int ret = 0;
12155
12156 if (!tasha->wcd_ext_clk) {
12157 dev_err(tasha->dev, "%s: wcd ext clock is NULL\n", __func__);
12158 return -EINVAL;
12159 }
12160
12161 dev_dbg(tasha->dev, "%s: mclk_enable = %u\n", __func__, enable);
12162
12163 if (enable) {
12164 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12165 ret = tasha_cdc_req_mclk_enable(tasha, true);
12166 if (ret)
12167 goto err;
12168
12169 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
12170 tasha_codec_apply_sido_voltage(tasha,
12171 SIDO_VOLTAGE_NOMINAL_MV);
12172 } else {
12173 if (!dig_core_collapse_enable) {
12174 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12175 tasha_codec_update_sido_voltage(tasha,
12176 sido_buck_svs_voltage);
12177 }
12178 tasha_cdc_req_mclk_enable(tasha, false);
12179 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12180 }
12181
12182err:
12183 return ret;
12184}
12185
12186static int __tasha_cdc_mclk_enable(struct tasha_priv *tasha,
12187 bool enable)
12188{
12189 int ret;
12190
12191 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12192 ret = __tasha_cdc_mclk_enable_locked(tasha, enable);
12193 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12194
12195 return ret;
12196}
12197
12198int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, bool dapm)
12199{
12200 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12201
12202 return __tasha_cdc_mclk_enable(tasha, enable);
12203}
12204EXPORT_SYMBOL(tasha_cdc_mclk_enable);
12205
12206int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, bool dapm)
12207{
12208 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12209 int ret = 0;
12210
12211 dev_dbg(tasha->dev, "%s: clk_mode: %d, enable: %d, clk_internal: %d\n",
12212 __func__, tasha->clk_mode, enable, tasha->clk_internal);
12213 if (tasha->clk_mode || tasha->clk_internal) {
12214 if (enable) {
12215 tasha_cdc_sido_ccl_enable(tasha, true);
12216 wcd_resmgr_enable_master_bias(tasha->resmgr);
12217 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12218 snd_soc_update_bits(codec,
12219 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
12220 0x01, 0x01);
12221 snd_soc_update_bits(codec,
12222 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
12223 0x01, 0x01);
12224 set_bit(CPE_NOMINAL, &tasha->status_mask);
12225 tasha_codec_update_sido_voltage(tasha,
12226 SIDO_VOLTAGE_NOMINAL_MV);
12227 tasha->clk_internal = true;
12228 } else {
12229 tasha->clk_internal = false;
12230 clear_bit(CPE_NOMINAL, &tasha->status_mask);
12231 tasha_codec_update_sido_voltage(tasha,
12232 sido_buck_svs_voltage);
12233 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12234 wcd_resmgr_disable_master_bias(tasha->resmgr);
12235 tasha_cdc_sido_ccl_enable(tasha, false);
12236 }
12237 } else {
12238 ret = __tasha_cdc_mclk_enable(tasha, enable);
12239 }
12240 return ret;
12241}
12242EXPORT_SYMBOL(tasha_cdc_mclk_tx_enable);
12243
12244static ssize_t tasha_codec_version_read(struct snd_info_entry *entry,
12245 void *file_private_data, struct file *file,
12246 char __user *buf, size_t count, loff_t pos)
12247{
12248 struct tasha_priv *tasha;
12249 struct wcd9xxx *wcd9xxx;
12250 char buffer[TASHA_VERSION_ENTRY_SIZE];
12251 int len = 0;
12252
12253 tasha = (struct tasha_priv *) entry->private_data;
12254 if (!tasha) {
12255 pr_err("%s: tasha priv is null\n", __func__);
12256 return -EINVAL;
12257 }
12258
12259 wcd9xxx = tasha->wcd9xxx;
12260
12261 if (wcd9xxx->codec_type->id_major == TASHA_MAJOR) {
12262 if (TASHA_IS_1_0(wcd9xxx))
12263 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_0\n");
12264 else if (TASHA_IS_1_1(wcd9xxx))
12265 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_1\n");
12266 else
12267 snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12268 } else if (wcd9xxx->codec_type->id_major == TASHA2P0_MAJOR) {
12269 len = snprintf(buffer, sizeof(buffer), "WCD9335_2_0\n");
12270 } else
12271 len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12272
12273 return simple_read_from_buffer(buf, count, &pos, buffer, len);
12274}
12275
12276static struct snd_info_entry_ops tasha_codec_info_ops = {
12277 .read = tasha_codec_version_read,
12278};
12279
12280/*
12281 * tasha_codec_info_create_codec_entry - creates wcd9335 module
12282 * @codec_root: The parent directory
12283 * @codec: Codec instance
12284 *
12285 * Creates wcd9335 module and version entry under the given
12286 * parent directory.
12287 *
12288 * Return: 0 on success or negative error code on failure.
12289 */
12290int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
12291 struct snd_soc_codec *codec)
12292{
12293 struct snd_info_entry *version_entry;
12294 struct tasha_priv *tasha;
12295 struct snd_soc_card *card;
12296
12297 if (!codec_root || !codec)
12298 return -EINVAL;
12299
12300 tasha = snd_soc_codec_get_drvdata(codec);
12301 card = codec->component.card;
Banajit Goswami7f40ea42017-01-30 13:32:41 -080012302 tasha->entry = snd_info_create_subdir(codec_root->module,
12303 "tasha", codec_root);
Banajit Goswamide8271c2017-01-18 00:28:59 -080012304 if (!tasha->entry) {
12305 dev_dbg(codec->dev, "%s: failed to create wcd9335 entry\n",
12306 __func__);
12307 return -ENOMEM;
12308 }
12309
12310 version_entry = snd_info_create_card_entry(card->snd_card,
12311 "version",
12312 tasha->entry);
12313 if (!version_entry) {
12314 dev_dbg(codec->dev, "%s: failed to create wcd9335 version entry\n",
12315 __func__);
12316 return -ENOMEM;
12317 }
12318
12319 version_entry->private_data = tasha;
12320 version_entry->size = TASHA_VERSION_ENTRY_SIZE;
12321 version_entry->content = SNDRV_INFO_CONTENT_DATA;
12322 version_entry->c.ops = &tasha_codec_info_ops;
12323
12324 if (snd_info_register(version_entry) < 0) {
12325 snd_info_free_entry(version_entry);
12326 return -ENOMEM;
12327 }
12328 tasha->version_entry = version_entry;
12329
12330 return 0;
12331}
12332EXPORT_SYMBOL(tasha_codec_info_create_codec_entry);
12333
12334static int __tasha_codec_internal_rco_ctrl(
12335 struct snd_soc_codec *codec, bool enable)
12336{
12337 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12338 int ret = 0;
12339
12340 if (enable) {
12341 tasha_cdc_sido_ccl_enable(tasha, true);
12342 if (wcd_resmgr_get_clk_type(tasha->resmgr) ==
12343 WCD_CLK_RCO) {
12344 ret = wcd_resmgr_enable_clk_block(tasha->resmgr,
12345 WCD_CLK_RCO);
12346 } else {
12347 ret = tasha_cdc_req_mclk_enable(tasha, true);
12348 ret |= wcd_resmgr_enable_clk_block(tasha->resmgr,
12349 WCD_CLK_RCO);
12350 ret |= tasha_cdc_req_mclk_enable(tasha, false);
12351 }
12352
12353 } else {
12354 ret = wcd_resmgr_disable_clk_block(tasha->resmgr,
12355 WCD_CLK_RCO);
12356 tasha_cdc_sido_ccl_enable(tasha, false);
12357 }
12358
12359 if (ret) {
12360 dev_err(codec->dev, "%s: Error in %s RCO\n",
12361 __func__, (enable ? "enabling" : "disabling"));
12362 ret = -EINVAL;
12363 }
12364
12365 return ret;
12366}
12367
12368/*
12369 * tasha_codec_internal_rco_ctrl()
12370 * Make sure that the caller does not acquire
12371 * BG_CLK_LOCK.
12372 */
12373static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
12374 bool enable)
12375{
12376 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12377 int ret = 0;
12378
12379 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12380 ret = __tasha_codec_internal_rco_ctrl(codec, enable);
12381 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12382 return ret;
12383}
12384
12385/*
12386 * tasha_mbhc_hs_detect: starts mbhc insertion/removal functionality
12387 * @codec: handle to snd_soc_codec *
12388 * @mbhc_cfg: handle to mbhc configuration structure
12389 * return 0 if mbhc_start is success or error code in case of failure
12390 */
12391int tasha_mbhc_hs_detect(struct snd_soc_codec *codec,
12392 struct wcd_mbhc_config *mbhc_cfg)
12393{
12394 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12395
12396 return wcd_mbhc_start(&tasha->mbhc, mbhc_cfg);
12397}
12398EXPORT_SYMBOL(tasha_mbhc_hs_detect);
12399
12400/*
12401 * tasha_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality
12402 * @codec: handle to snd_soc_codec *
12403 */
12404void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec)
12405{
12406 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12407
12408 wcd_mbhc_stop(&tasha->mbhc);
12409}
12410EXPORT_SYMBOL(tasha_mbhc_hs_detect_exit);
12411
12412static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv)
12413{
12414 /* min micbias voltage is 1V and maximum is 2.85V */
12415 if (micb_mv < 1000 || micb_mv > 2850) {
12416 pr_err("%s: unsupported micbias voltage\n", __func__);
12417 return -EINVAL;
12418 }
12419
12420 return (micb_mv - 1000) / 50;
12421}
12422
12423static const struct tasha_reg_mask_val tasha_reg_update_reset_val_1_1[] = {
12424 {WCD9335_RCO_CTRL_2, 0xFF, 0x47},
12425 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12426};
12427
12428static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_1[] = {
12429 {WCD9335_FLYBACK_VNEG_DAC_CTRL_1, 0xFF, 0x65},
12430 {WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0xFF, 0x52},
12431 {WCD9335_FLYBACK_VNEG_DAC_CTRL_3, 0xFF, 0xAF},
12432 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12433 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0xF4},
12434 {WCD9335_FLYBACK_VNEG_CTRL_9, 0xFF, 0x40},
12435 {WCD9335_FLYBACK_VNEG_CTRL_2, 0xFF, 0x4F},
12436 {WCD9335_FLYBACK_EN, 0xFF, 0x6E},
12437 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xF8, 0xF8},
12438 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xF8, 0xF8},
12439};
12440
12441static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_0[] = {
12442 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0x54},
12443 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xFC, 0xFC},
12444 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xFC, 0xFC},
12445};
12446
12447static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
12448 {WCD9335_RCO_CTRL_2, 0x0F, 0x08},
12449 {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
12450 {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
12451 {WCD9335_HPH_OCP_CTL, 0xFF, 0x7A},
12452 {WCD9335_HPH_L_TEST, 0x01, 0x01},
12453 {WCD9335_HPH_R_TEST, 0x01, 0x01},
12454 {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
12455 {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
12456 {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
12457 {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
12458 {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
12459 {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
12460 {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
12461 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
12462 {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
12463 {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
12464 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xA0},
12465 {WCD9335_SE_LO_COM1, 0xFF, 0xC0},
12466 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xFC, 0xF4},
12467 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xFC, 0xF4},
12468 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xFC, 0xF8},
12469 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xFC, 0xF8},
12470};
12471
12472static const struct tasha_reg_mask_val tasha_codec_reg_defaults[] = {
12473 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00},
12474 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01},
12475 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x04, 0x04},
12476};
12477
12478static const struct tasha_reg_mask_val tasha_codec_reg_i2c_defaults[] = {
12479 {WCD9335_ANA_CLK_TOP, 0x20, 0x20},
12480 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x01},
12481 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x00},
12482 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x05, 0x05},
12483 {WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG, 0x01, 0x01},
12484 {WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG, 0x01, 0x01},
12485 {WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG, 0x01, 0x01},
12486 {WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG, 0x01, 0x01},
12487 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, 0x05, 0x05},
12488 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, 0x05, 0x05},
12489 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, 0x05, 0x05},
12490 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, 0x05, 0x05},
12491};
12492
12493static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = {
12494 /* Rbuckfly/R_EAR(32) */
12495 {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00},
12496 {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60},
12497 {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00},
12498 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50},
12499 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50},
12500 {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
12501 {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
12502 {WCD9335_ANA_LO_1_2, 0x3C, 0X3C},
12503 {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00},
12504 {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03},
12505 {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02},
12506 {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01},
12507 {WCD9335_EAR_CMBUFF, 0x08, 0x00},
12508 {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12509 {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12510 {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12511 {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12512 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
12513 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
12514 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
12515 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
12516 {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
12517 {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
12518 {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
12519 {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
12520 {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
12521 {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
12522 {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
12523 {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
12524 {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
12525 {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
12526 {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
12527 {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
12528 {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
12529 {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
12530 {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
12531 {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
12532 {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
12533 {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
12534 {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08},
12535};
12536
12537static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = {
12538 /* Enable TX HPF Filter & Linear Phase */
12539 {WCD9335_CDC_TX0_TX_PATH_CFG0, 0x11, 0x11},
12540 {WCD9335_CDC_TX1_TX_PATH_CFG0, 0x11, 0x11},
12541 {WCD9335_CDC_TX2_TX_PATH_CFG0, 0x11, 0x11},
12542 {WCD9335_CDC_TX3_TX_PATH_CFG0, 0x11, 0x11},
12543 {WCD9335_CDC_TX4_TX_PATH_CFG0, 0x11, 0x11},
12544 {WCD9335_CDC_TX5_TX_PATH_CFG0, 0x11, 0x11},
12545 {WCD9335_CDC_TX6_TX_PATH_CFG0, 0x11, 0x11},
12546 {WCD9335_CDC_TX7_TX_PATH_CFG0, 0x11, 0x11},
12547 {WCD9335_CDC_TX8_TX_PATH_CFG0, 0x11, 0x11},
12548 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xF8, 0xF8},
12549 {WCD9335_CDC_RX0_RX_PATH_SEC1, 0x08, 0x08},
12550 {WCD9335_CDC_RX1_RX_PATH_SEC1, 0x08, 0x08},
12551 {WCD9335_CDC_RX2_RX_PATH_SEC1, 0x08, 0x08},
12552 {WCD9335_CDC_RX3_RX_PATH_SEC1, 0x08, 0x08},
12553 {WCD9335_CDC_RX4_RX_PATH_SEC1, 0x08, 0x08},
12554 {WCD9335_CDC_RX5_RX_PATH_SEC1, 0x08, 0x08},
12555 {WCD9335_CDC_RX6_RX_PATH_SEC1, 0x08, 0x08},
12556 {WCD9335_CDC_RX7_RX_PATH_SEC1, 0x08, 0x08},
12557 {WCD9335_CDC_RX8_RX_PATH_SEC1, 0x08, 0x08},
12558 {WCD9335_CDC_RX0_RX_PATH_MIX_SEC0, 0x08, 0x08},
12559 {WCD9335_CDC_RX1_RX_PATH_MIX_SEC0, 0x08, 0x08},
12560 {WCD9335_CDC_RX2_RX_PATH_MIX_SEC0, 0x08, 0x08},
12561 {WCD9335_CDC_RX3_RX_PATH_MIX_SEC0, 0x08, 0x08},
12562 {WCD9335_CDC_RX4_RX_PATH_MIX_SEC0, 0x08, 0x08},
12563 {WCD9335_CDC_RX5_RX_PATH_MIX_SEC0, 0x08, 0x08},
12564 {WCD9335_CDC_RX6_RX_PATH_MIX_SEC0, 0x08, 0x08},
12565 {WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, 0x08, 0x08},
12566 {WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, 0x08, 0x08},
12567 {WCD9335_CDC_TX0_TX_PATH_SEC2, 0x01, 0x01},
12568 {WCD9335_CDC_TX1_TX_PATH_SEC2, 0x01, 0x01},
12569 {WCD9335_CDC_TX2_TX_PATH_SEC2, 0x01, 0x01},
12570 {WCD9335_CDC_TX3_TX_PATH_SEC2, 0x01, 0x01},
12571 {WCD9335_CDC_TX4_TX_PATH_SEC2, 0x01, 0x01},
12572 {WCD9335_CDC_TX5_TX_PATH_SEC2, 0x01, 0x01},
12573 {WCD9335_CDC_TX6_TX_PATH_SEC2, 0x01, 0x01},
12574 {WCD9335_CDC_TX7_TX_PATH_SEC2, 0x01, 0x01},
12575 {WCD9335_CDC_TX8_TX_PATH_SEC2, 0x01, 0x01},
12576 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xF8, 0xF0},
12577 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xF8, 0xF0},
12578 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xF8, 0xF8},
12579 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xF8, 0xF8},
12580 {WCD9335_RX_OCP_COUNT, 0xFF, 0xFF},
12581 {WCD9335_HPH_OCP_CTL, 0xF0, 0x70},
12582 {WCD9335_CPE_SS_CPAR_CFG, 0xFF, 0x00},
12583 {WCD9335_FLYBACK_VNEG_CTRL_1, 0xFF, 0x63},
12584 {WCD9335_FLYBACK_VNEG_CTRL_4, 0xFF, 0x7F},
12585 {WCD9335_CLASSH_CTRL_VCL_1, 0xFF, 0x60},
12586 {WCD9335_CLASSH_CTRL_CCL_5, 0xFF, 0x40},
12587 {WCD9335_RX_TIMER_DIV, 0xFF, 0x32},
12588 {WCD9335_SE_LO_COM2, 0xFF, 0x01},
12589 {WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, 0x07},
12590 {WCD9335_RX_BIAS_HPH_PA, 0xF0, 0x60},
12591 {WCD9335_HPH_RDAC_LDO_CTL, 0x88, 0x88},
12592 {WCD9335_HPH_L_EN, 0x20, 0x20},
12593 {WCD9335_HPH_R_EN, 0x20, 0x20},
12594 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xD8},
12595 {WCD9335_CDC_RX5_RX_PATH_SEC3, 0xBD, 0xBD},
12596 {WCD9335_CDC_RX6_RX_PATH_SEC3, 0xBD, 0xBD},
12597 {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40},
12598};
12599
12600static void tasha_update_reg_reset_values(struct snd_soc_codec *codec)
12601{
12602 u32 i;
12603 struct wcd9xxx *tasha_core = dev_get_drvdata(codec->dev->parent);
12604
12605 if (TASHA_IS_1_1(tasha_core)) {
12606 for (i = 0; i < ARRAY_SIZE(tasha_reg_update_reset_val_1_1);
12607 i++)
12608 snd_soc_write(codec,
12609 tasha_reg_update_reset_val_1_1[i].reg,
12610 tasha_reg_update_reset_val_1_1[i].val);
12611 }
12612}
12613
12614static void tasha_codec_init_reg(struct snd_soc_codec *codec)
12615{
12616 u32 i;
12617 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
12618
12619 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_common_val); i++)
12620 snd_soc_update_bits(codec,
12621 tasha_codec_reg_init_common_val[i].reg,
12622 tasha_codec_reg_init_common_val[i].mask,
12623 tasha_codec_reg_init_common_val[i].val);
12624
12625 if (TASHA_IS_1_1(wcd9xxx) ||
12626 TASHA_IS_1_0(wcd9xxx))
12627 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_1_x_val); i++)
12628 snd_soc_update_bits(codec,
12629 tasha_codec_reg_init_1_x_val[i].reg,
12630 tasha_codec_reg_init_1_x_val[i].mask,
12631 tasha_codec_reg_init_1_x_val[i].val);
12632
12633 if (TASHA_IS_1_1(wcd9xxx)) {
12634 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_1); i++)
12635 snd_soc_update_bits(codec,
12636 tasha_codec_reg_init_val_1_1[i].reg,
12637 tasha_codec_reg_init_val_1_1[i].mask,
12638 tasha_codec_reg_init_val_1_1[i].val);
12639 } else if (TASHA_IS_1_0(wcd9xxx)) {
12640 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_0); i++)
12641 snd_soc_update_bits(codec,
12642 tasha_codec_reg_init_val_1_0[i].reg,
12643 tasha_codec_reg_init_val_1_0[i].mask,
12644 tasha_codec_reg_init_val_1_0[i].val);
12645 } else if (TASHA_IS_2_0(wcd9xxx)) {
12646 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_2_0); i++)
12647 snd_soc_update_bits(codec,
12648 tasha_codec_reg_init_val_2_0[i].reg,
12649 tasha_codec_reg_init_val_2_0[i].mask,
12650 tasha_codec_reg_init_val_2_0[i].val);
12651 }
12652}
12653
12654static void tasha_update_reg_defaults(struct tasha_priv *tasha)
12655{
12656 u32 i;
12657 struct wcd9xxx *wcd9xxx;
12658
12659 wcd9xxx = tasha->wcd9xxx;
12660 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_defaults); i++)
12661 regmap_update_bits(wcd9xxx->regmap,
12662 tasha_codec_reg_defaults[i].reg,
12663 tasha_codec_reg_defaults[i].mask,
12664 tasha_codec_reg_defaults[i].val);
12665
12666 tasha->intf_type = wcd9xxx_get_intf_type();
12667 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
12668 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_i2c_defaults); i++)
12669 regmap_update_bits(wcd9xxx->regmap,
12670 tasha_codec_reg_i2c_defaults[i].reg,
12671 tasha_codec_reg_i2c_defaults[i].mask,
12672 tasha_codec_reg_i2c_defaults[i].val);
12673
12674}
12675
12676static void tasha_slim_interface_init_reg(struct snd_soc_codec *codec)
12677{
12678 int i;
12679 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12680
12681 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
12682 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12683 TASHA_SLIM_PGD_PORT_INT_EN0 + i,
12684 0xFF);
12685}
12686
12687static irqreturn_t tasha_slimbus_irq(int irq, void *data)
12688{
12689 struct tasha_priv *priv = data;
12690 unsigned long status = 0;
12691 int i, j, port_id, k;
12692 u32 bit;
12693 u8 val, int_val = 0;
12694 bool tx, cleared;
12695 unsigned short reg = 0;
12696
12697 for (i = TASHA_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
12698 i <= TASHA_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
12699 val = wcd9xxx_interface_reg_read(priv->wcd9xxx, i);
12700 status |= ((u32)val << (8 * j));
12701 }
12702
12703 for_each_set_bit(j, &status, 32) {
12704 tx = (j >= 16 ? true : false);
12705 port_id = (tx ? j - 16 : j);
12706 val = wcd9xxx_interface_reg_read(priv->wcd9xxx,
12707 TASHA_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
12708 if (val) {
12709 if (!tx)
12710 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
12711 (port_id / 8);
12712 else
12713 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
12714 (port_id / 8);
12715 int_val = wcd9xxx_interface_reg_read(
12716 priv->wcd9xxx, reg);
12717 /*
12718 * Ignore interrupts for ports for which the
12719 * interrupts are not specifically enabled.
12720 */
12721 if (!(int_val & (1 << (port_id % 8))))
12722 continue;
12723 }
12724 if (val & TASHA_SLIM_IRQ_OVERFLOW)
12725 pr_err_ratelimited(
12726 "%s: overflow error on %s port %d, value %x\n",
12727 __func__, (tx ? "TX" : "RX"), port_id, val);
12728 if (val & TASHA_SLIM_IRQ_UNDERFLOW)
12729 pr_err_ratelimited(
12730 "%s: underflow error on %s port %d, value %x\n",
12731 __func__, (tx ? "TX" : "RX"), port_id, val);
12732 if ((val & TASHA_SLIM_IRQ_OVERFLOW) ||
12733 (val & TASHA_SLIM_IRQ_UNDERFLOW)) {
12734 if (!tx)
12735 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
12736 (port_id / 8);
12737 else
12738 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
12739 (port_id / 8);
12740 int_val = wcd9xxx_interface_reg_read(
12741 priv->wcd9xxx, reg);
12742 if (int_val & (1 << (port_id % 8))) {
12743 int_val = int_val ^ (1 << (port_id % 8));
12744 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12745 reg, int_val);
12746 }
12747 }
12748 if (val & TASHA_SLIM_IRQ_PORT_CLOSED) {
12749 /*
12750 * INT SOURCE register starts from RX to TX
12751 * but port number in the ch_mask is in opposite way
12752 */
12753 bit = (tx ? j - 16 : j + 16);
12754 pr_debug("%s: %s port %d closed value %x, bit %u\n",
12755 __func__, (tx ? "TX" : "RX"), port_id, val,
12756 bit);
12757 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
12758 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
12759 __func__, k, priv->dai[k].ch_mask);
12760 if (test_and_clear_bit(bit,
12761 &priv->dai[k].ch_mask)) {
12762 cleared = true;
12763 if (!priv->dai[k].ch_mask)
12764 wake_up(&priv->dai[k].dai_wait);
12765 /*
12766 * There are cases when multiple DAIs
12767 * might be using the same slimbus
12768 * channel. Hence don't break here.
12769 */
12770 }
12771 }
12772 WARN(!cleared,
12773 "Couldn't find slimbus %s port %d for closing\n",
12774 (tx ? "TX" : "RX"), port_id);
12775 }
12776 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12777 TASHA_SLIM_PGD_PORT_INT_CLR_RX_0 +
12778 (j / 8),
12779 1 << (j % 8));
12780 }
12781
12782 return IRQ_HANDLED;
12783}
12784
12785static int tasha_setup_irqs(struct tasha_priv *tasha)
12786{
12787 int ret = 0;
12788 struct snd_soc_codec *codec = tasha->codec;
12789 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
12790 struct wcd9xxx_core_resource *core_res =
12791 &wcd9xxx->core_res;
12792
12793 ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS,
12794 tasha_slimbus_irq, "SLIMBUS Slave", tasha);
12795 if (ret)
12796 pr_err("%s: Failed to request irq %d\n", __func__,
12797 WCD9XXX_IRQ_SLIMBUS);
12798 else
12799 tasha_slim_interface_init_reg(codec);
12800
12801 return ret;
12802}
12803
12804static void tasha_init_slim_slave_cfg(struct snd_soc_codec *codec)
12805{
12806 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12807 struct afe_param_cdc_slimbus_slave_cfg *cfg;
12808 struct wcd9xxx *wcd9xxx = priv->wcd9xxx;
12809 uint64_t eaddr = 0;
12810
12811 cfg = &priv->slimbus_slave_cfg;
12812 cfg->minor_version = 1;
12813 cfg->tx_slave_port_offset = 0;
12814 cfg->rx_slave_port_offset = 16;
12815
12816 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
12817 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
12818 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
12819 cfg->device_enum_addr_msw = eaddr >> 32;
12820
12821 dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n",
12822 __func__, eaddr);
12823}
12824
12825static void tasha_cleanup_irqs(struct tasha_priv *tasha)
12826{
12827 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
12828 struct wcd9xxx_core_resource *core_res =
12829 &wcd9xxx->core_res;
12830
12831 wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, tasha);
12832}
12833
12834static int tasha_handle_pdata(struct tasha_priv *tasha,
12835 struct wcd9xxx_pdata *pdata)
12836{
12837 struct snd_soc_codec *codec = tasha->codec;
12838 u8 dmic_ctl_val, mad_dmic_ctl_val;
12839 u8 anc_ctl_value;
12840 u32 def_dmic_rate, dmic_clk_drv;
12841 int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
12842 int rc = 0;
12843
12844 if (!pdata) {
12845 dev_err(codec->dev, "%s: NULL pdata\n", __func__);
12846 return -ENODEV;
12847 }
12848
12849 /* set micbias voltage */
12850 vout_ctl_1 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb1_mv);
12851 vout_ctl_2 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb2_mv);
12852 vout_ctl_3 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb3_mv);
12853 vout_ctl_4 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb4_mv);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080012854 if (vout_ctl_1 < 0 || vout_ctl_2 < 0 ||
12855 vout_ctl_3 < 0 || vout_ctl_4 < 0) {
Banajit Goswamide8271c2017-01-18 00:28:59 -080012856 rc = -EINVAL;
12857 goto done;
12858 }
12859 snd_soc_update_bits(codec, WCD9335_ANA_MICB1, 0x3F, vout_ctl_1);
12860 snd_soc_update_bits(codec, WCD9335_ANA_MICB2, 0x3F, vout_ctl_2);
12861 snd_soc_update_bits(codec, WCD9335_ANA_MICB3, 0x3F, vout_ctl_3);
12862 snd_soc_update_bits(codec, WCD9335_ANA_MICB4, 0x3F, vout_ctl_4);
12863
12864 /* Set the DMIC sample rate */
12865 switch (pdata->mclk_rate) {
12866 case TASHA_MCLK_CLK_9P6MHZ:
12867 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
12868 break;
12869 case TASHA_MCLK_CLK_12P288MHZ:
12870 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ;
12871 break;
12872 default:
12873 /* should never happen */
12874 dev_err(codec->dev, "%s: Invalid mclk_rate %d\n",
12875 __func__, pdata->mclk_rate);
12876 rc = -EINVAL;
12877 goto done;
12878 };
12879
12880 if (pdata->dmic_sample_rate ==
12881 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12882 dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n",
12883 __func__, def_dmic_rate);
12884 pdata->dmic_sample_rate = def_dmic_rate;
12885 }
12886 if (pdata->mad_dmic_sample_rate ==
12887 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12888 dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n",
12889 __func__, def_dmic_rate);
12890 /*
12891 * use dmic_sample_rate as the default for MAD
12892 * if mad dmic sample rate is undefined
12893 */
12894 pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate;
12895 }
12896 if (pdata->ecpp_dmic_sample_rate ==
12897 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12898 dev_info(codec->dev,
12899 "%s: ecpp_dmic_rate invalid default = %d\n",
12900 __func__, def_dmic_rate);
12901 /*
12902 * use dmic_sample_rate as the default for ECPP DMIC
12903 * if ecpp dmic sample rate is undefined
12904 */
12905 pdata->ecpp_dmic_sample_rate = pdata->dmic_sample_rate;
12906 }
12907
12908 if (pdata->dmic_clk_drv ==
12909 WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) {
12910 pdata->dmic_clk_drv = WCD9335_DMIC_CLK_DRIVE_DEFAULT;
12911 dev_info(codec->dev,
12912 "%s: dmic_clk_strength invalid, default = %d\n",
12913 __func__, pdata->dmic_clk_drv);
12914 }
12915
12916 switch (pdata->dmic_clk_drv) {
12917 case 2:
12918 dmic_clk_drv = 0;
12919 break;
12920 case 4:
12921 dmic_clk_drv = 1;
12922 break;
12923 case 8:
12924 dmic_clk_drv = 2;
12925 break;
12926 case 16:
12927 dmic_clk_drv = 3;
12928 break;
12929 default:
12930 dev_err(codec->dev,
12931 "%s: invalid dmic_clk_drv %d, using default\n",
12932 __func__, pdata->dmic_clk_drv);
12933 dmic_clk_drv = 0;
12934 break;
12935 }
12936
12937 snd_soc_update_bits(codec, WCD9335_TEST_DEBUG_PAD_DRVCTL,
12938 0x0C, dmic_clk_drv << 2);
12939
12940 /*
12941 * Default the DMIC clk rates to mad_dmic_sample_rate,
12942 * whereas, the anc/txfe dmic rates to dmic_sample_rate
12943 * since the anc/txfe are independent of mad block.
12944 */
12945 mad_dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec,
12946 pdata->mclk_rate,
12947 pdata->mad_dmic_sample_rate);
12948 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC0_CTL,
12949 0x0E, mad_dmic_ctl_val << 1);
12950 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC1_CTL,
12951 0x0E, mad_dmic_ctl_val << 1);
12952 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC2_CTL,
12953 0x0E, mad_dmic_ctl_val << 1);
12954
12955 dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec,
12956 pdata->mclk_rate,
12957 pdata->dmic_sample_rate);
12958
12959 if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2)
12960 anc_ctl_value = WCD9335_ANC_DMIC_X2_FULL_RATE;
12961 else
12962 anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE;
12963
12964 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL,
12965 0x40, anc_ctl_value << 6);
12966 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL,
12967 0x20, anc_ctl_value << 5);
12968 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL,
12969 0x40, anc_ctl_value << 6);
12970 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL,
12971 0x20, anc_ctl_value << 5);
12972done:
12973 return rc;
12974}
12975
12976static struct wcd_cpe_core *tasha_codec_get_cpe_core(
12977 struct snd_soc_codec *codec)
12978{
12979 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12980
12981 return priv->cpe_core;
12982}
12983
12984static int tasha_codec_cpe_fll_update_divider(
12985 struct snd_soc_codec *codec, u32 cpe_fll_rate)
12986{
12987 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
12988 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12989
12990 u32 div_val = 0, l_val = 0;
12991 u32 computed_cpe_fll;
12992
12993 if (cpe_fll_rate != CPE_FLL_CLK_75MHZ &&
12994 cpe_fll_rate != CPE_FLL_CLK_150MHZ) {
12995 dev_err(codec->dev,
12996 "%s: Invalid CPE fll rate request %u\n",
12997 __func__, cpe_fll_rate);
12998 return -EINVAL;
12999 }
13000
13001 if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) {
13002 /* update divider to 10 and enable 5x divider */
13003 snd_soc_write(codec, WCD9335_CPE_FLL_USER_CTL_1,
13004 0x55);
13005 div_val = 10;
13006 } else if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) {
13007 /* update divider to 8 and enable 2x divider */
13008 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13009 0x7C, 0x70);
13010 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_1,
13011 0xE0, 0x20);
13012 div_val = 8;
13013 } else {
13014 dev_err(codec->dev,
13015 "%s: Invalid MCLK rate %u\n",
13016 __func__, wcd9xxx->mclk_rate);
13017 return -EINVAL;
13018 }
13019
13020 l_val = ((cpe_fll_rate / 1000) * div_val) /
13021 (wcd9xxx->mclk_rate / 1000);
13022
13023 /* If l_val was integer truncated, increment l_val once */
13024 computed_cpe_fll = (wcd9xxx->mclk_rate / div_val) * l_val;
13025 if (computed_cpe_fll < cpe_fll_rate)
13026 l_val++;
13027
13028
13029 /* update L value LSB and MSB */
13030 snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_0,
13031 (l_val & 0xFF));
13032 snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_1,
13033 ((l_val >> 8) & 0xFF));
13034
13035 tasha->current_cpe_clk_freq = cpe_fll_rate;
13036 dev_dbg(codec->dev,
13037 "%s: updated l_val to %u for cpe_clk %u and mclk %u\n",
13038 __func__, l_val, cpe_fll_rate, wcd9xxx->mclk_rate);
13039
13040 return 0;
13041}
13042
13043static int __tasha_cdc_change_cpe_clk(struct snd_soc_codec *codec,
13044 u32 clk_freq)
13045{
13046 int ret = 0;
13047 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13048
13049 if (!tasha_cdc_is_svs_enabled(tasha)) {
13050 dev_dbg(codec->dev,
13051 "%s: SVS not enabled or tasha is not 2p0, return\n",
13052 __func__);
13053 return 0;
13054 }
13055 dev_dbg(codec->dev, "%s: clk_freq = %u\n", __func__, clk_freq);
13056
13057 if (clk_freq == CPE_FLL_CLK_75MHZ) {
13058 /* Change to SVS */
13059 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13060 0x08, 0x08);
13061 if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) {
13062 ret = -EINVAL;
13063 goto done;
13064 }
13065
13066 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13067 0x10, 0x10);
13068
13069 clear_bit(CPE_NOMINAL, &tasha->status_mask);
13070 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
13071
13072 } else if (clk_freq == CPE_FLL_CLK_150MHZ) {
13073 /* change to nominal */
13074 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13075 0x08, 0x08);
13076
13077 set_bit(CPE_NOMINAL, &tasha->status_mask);
13078 tasha_codec_update_sido_voltage(tasha, SIDO_VOLTAGE_NOMINAL_MV);
13079
13080 if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) {
13081 ret = -EINVAL;
13082 goto done;
13083 }
13084 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13085 0x10, 0x10);
13086 } else {
13087 dev_err(codec->dev,
13088 "%s: Invalid clk_freq request %d for CPE FLL\n",
13089 __func__, clk_freq);
13090 ret = -EINVAL;
13091 }
13092
13093done:
13094 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13095 0x10, 0x00);
13096 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13097 0x08, 0x00);
13098 return ret;
13099}
13100
13101
13102static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec,
13103 bool enable)
13104{
13105 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
13106 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13107 u8 clk_sel_reg_val = 0x00;
13108
13109 dev_dbg(codec->dev, "%s: enable = %s\n",
13110 __func__, enable ? "true" : "false");
13111
13112 if (enable) {
13113 if (tasha_cdc_is_svs_enabled(tasha)) {
13114 /* FLL enable is always at SVS */
13115 if (__tasha_cdc_change_cpe_clk(codec,
13116 CPE_FLL_CLK_75MHZ)) {
13117 dev_err(codec->dev,
13118 "%s: clk change to %d failed\n",
13119 __func__, CPE_FLL_CLK_75MHZ);
13120 return -EINVAL;
13121 }
13122 } else {
13123 if (tasha_codec_cpe_fll_update_divider(codec,
13124 CPE_FLL_CLK_75MHZ)) {
13125 dev_err(codec->dev,
13126 "%s: clk change to %d failed\n",
13127 __func__, CPE_FLL_CLK_75MHZ);
13128 return -EINVAL;
13129 }
13130 }
13131
13132 if (TASHA_IS_1_0(wcd9xxx)) {
13133 tasha_cdc_mclk_enable(codec, true, false);
13134 clk_sel_reg_val = 0x02;
13135 }
13136
13137 /* Setup CPE reference clk */
13138 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13139 0x02, clk_sel_reg_val);
13140
13141 /* enable CPE FLL reference clk */
13142 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13143 0x01, 0x01);
13144
13145 /* program the PLL */
13146 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13147 0x01, 0x01);
13148
13149 /* TEST clk setting */
13150 snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0,
13151 0x80, 0x80);
13152 /* set FLL mode to HW controlled */
13153 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13154 0x60, 0x00);
13155 snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x80);
13156 } else {
13157 /* disable CPE FLL reference clk */
13158 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13159 0x01, 0x00);
13160 /* undo TEST clk setting */
13161 snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0,
13162 0x80, 0x00);
13163 /* undo FLL mode to HW control */
13164 snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x00);
13165 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13166 0x60, 0x20);
13167 /* undo the PLL */
13168 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13169 0x01, 0x00);
13170
13171 if (TASHA_IS_1_0(wcd9xxx))
13172 tasha_cdc_mclk_enable(codec, false, false);
13173
13174 /*
13175 * FLL could get disabled while at nominal,
13176 * scale it back to SVS
13177 */
13178 if (tasha_cdc_is_svs_enabled(tasha))
13179 __tasha_cdc_change_cpe_clk(codec,
13180 CPE_FLL_CLK_75MHZ);
13181 }
13182
13183 return 0;
13184
13185}
13186
13187static void tasha_cdc_query_cpe_clk_plan(void *data,
13188 struct cpe_svc_cfg_clk_plan *clk_freq)
13189{
13190 struct snd_soc_codec *codec = data;
13191 struct tasha_priv *tasha;
13192 u32 cpe_clk_khz;
13193
13194 if (!codec) {
13195 pr_err("%s: Invalid codec handle\n",
13196 __func__);
13197 return;
13198 }
13199
13200 tasha = snd_soc_codec_get_drvdata(codec);
13201 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13202
13203 dev_dbg(codec->dev,
13204 "%s: current_clk_freq = %u\n",
13205 __func__, tasha->current_cpe_clk_freq);
13206
13207 clk_freq->current_clk_feq = cpe_clk_khz;
13208 clk_freq->num_clk_freqs = 2;
13209
13210 if (tasha_cdc_is_svs_enabled(tasha)) {
13211 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ / 1000;
13212 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ / 1000;
13213 } else {
13214 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ;
13215 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ;
13216 }
13217}
13218
13219static void tasha_cdc_change_cpe_clk(void *data,
13220 u32 clk_freq)
13221{
13222 struct snd_soc_codec *codec = data;
13223 struct tasha_priv *tasha;
13224 u32 cpe_clk_khz, req_freq = 0;
13225
13226 if (!codec) {
13227 pr_err("%s: Invalid codec handle\n",
13228 __func__);
13229 return;
13230 }
13231
13232 tasha = snd_soc_codec_get_drvdata(codec);
13233 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13234
13235 if (tasha_cdc_is_svs_enabled(tasha)) {
13236 if ((clk_freq * 1000) <= CPE_FLL_CLK_75MHZ)
13237 req_freq = CPE_FLL_CLK_75MHZ;
13238 else
13239 req_freq = CPE_FLL_CLK_150MHZ;
13240 }
13241
13242 dev_dbg(codec->dev,
13243 "%s: requested clk_freq = %u, current clk_freq = %u\n",
13244 __func__, clk_freq * 1000,
13245 tasha->current_cpe_clk_freq);
13246
13247 if (tasha_cdc_is_svs_enabled(tasha)) {
13248 if (__tasha_cdc_change_cpe_clk(codec, req_freq))
13249 dev_err(codec->dev,
13250 "%s: clock/voltage scaling failed\n",
13251 __func__);
13252 }
13253}
13254
13255static int tasha_codec_slim_reserve_bw(struct snd_soc_codec *codec,
13256 u32 bw_ops, bool commit)
13257{
13258 struct wcd9xxx *wcd9xxx;
13259
13260 if (!codec) {
13261 pr_err("%s: Invalid handle to codec\n",
13262 __func__);
13263 return -EINVAL;
13264 }
13265
13266 wcd9xxx = dev_get_drvdata(codec->dev->parent);
13267
13268 if (!wcd9xxx) {
13269 dev_err(codec->dev, "%s: Invalid parent drv_data\n",
13270 __func__);
13271 return -EINVAL;
13272 }
13273
13274 return wcd9xxx_slim_reserve_bw(wcd9xxx, bw_ops, commit);
13275}
13276
13277static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
13278 bool vote)
13279{
13280 u32 bw_ops;
13281 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13282
13283 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
13284 return 0;
13285
13286 if (vote)
13287 bw_ops = SLIM_BW_CLK_GEAR_9;
13288 else
13289 bw_ops = SLIM_BW_UNVOTE;
13290
13291 return tasha_codec_slim_reserve_bw(codec,
13292 bw_ops, true);
13293}
13294
13295static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec,
13296 enum cpe_err_irq_cntl_type cntl_type, u8 *status)
13297{
13298 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13299 u8 irq_bits;
13300
13301 if (TASHA_IS_2_0(tasha->wcd9xxx))
13302 irq_bits = 0xFF;
13303 else
13304 irq_bits = 0x3F;
13305
13306 if (status)
13307 irq_bits = (*status) & irq_bits;
13308
13309 switch (cntl_type) {
13310 case CPE_ERR_IRQ_MASK:
13311 snd_soc_update_bits(codec,
13312 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13313 irq_bits, irq_bits);
13314 break;
13315 case CPE_ERR_IRQ_UNMASK:
13316 snd_soc_update_bits(codec,
13317 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13318 irq_bits, 0x00);
13319 break;
13320 case CPE_ERR_IRQ_CLEAR:
13321 snd_soc_write(codec, WCD9335_CPE_SS_SS_ERROR_INT_CLEAR,
13322 irq_bits);
13323 break;
13324 case CPE_ERR_IRQ_STATUS:
13325 if (!status)
13326 return -EINVAL;
13327 *status = snd_soc_read(codec,
13328 WCD9335_CPE_SS_SS_ERROR_INT_STATUS);
13329 break;
13330 }
13331
13332 return 0;
13333}
13334
13335static const struct wcd_cpe_cdc_cb cpe_cb = {
13336 .cdc_clk_en = tasha_codec_internal_rco_ctrl,
13337 .cpe_clk_en = tasha_codec_cpe_fll_enable,
13338 .get_afe_out_port_id = tasha_codec_get_mad_port_id,
13339 .lab_cdc_ch_ctl = tasha_codec_enable_slimtx_mad,
13340 .cdc_ext_clk = tasha_cdc_mclk_enable,
13341 .bus_vote_bw = tasha_codec_vote_max_bw,
13342 .cpe_err_irq_control = tasha_cpe_err_irq_control,
13343};
13344
13345static struct cpe_svc_init_param cpe_svc_params = {
13346 .version = CPE_SVC_INIT_PARAM_V1,
13347 .query_freq_plans_cb = tasha_cdc_query_cpe_clk_plan,
13348 .change_freq_plan_cb = tasha_cdc_change_cpe_clk,
13349};
13350
13351static int tasha_cpe_initialize(struct snd_soc_codec *codec)
13352{
13353 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13354 struct wcd_cpe_params cpe_params;
13355
13356 memset(&cpe_params, 0,
13357 sizeof(struct wcd_cpe_params));
13358 cpe_params.codec = codec;
13359 cpe_params.get_cpe_core = tasha_codec_get_cpe_core;
13360 cpe_params.cdc_cb = &cpe_cb;
13361 cpe_params.dbg_mode = cpe_debug_mode;
13362 cpe_params.cdc_major_ver = CPE_SVC_CODEC_WCD9335;
13363 cpe_params.cdc_minor_ver = CPE_SVC_CODEC_V1P0;
13364 cpe_params.cdc_id = CPE_SVC_CODEC_WCD9335;
13365
13366 cpe_params.cdc_irq_info.cpe_engine_irq =
13367 WCD9335_IRQ_SVA_OUTBOX1;
13368 cpe_params.cdc_irq_info.cpe_err_irq =
13369 WCD9335_IRQ_SVA_ERROR;
13370 cpe_params.cdc_irq_info.cpe_fatal_irqs =
13371 TASHA_CPE_FATAL_IRQS;
13372
13373 cpe_svc_params.context = codec;
13374 cpe_params.cpe_svc_params = &cpe_svc_params;
13375
13376 tasha->cpe_core = wcd_cpe_init("cpe_9335", codec,
13377 &cpe_params);
13378 if (IS_ERR_OR_NULL(tasha->cpe_core)) {
13379 dev_err(codec->dev,
13380 "%s: Failed to enable CPE\n",
13381 __func__);
13382 return -EINVAL;
13383 }
13384
13385 return 0;
13386}
13387
13388static const struct wcd_resmgr_cb tasha_resmgr_cb = {
13389 .cdc_rco_ctrl = __tasha_codec_internal_rco_ctrl,
13390};
13391
13392static int tasha_device_down(struct wcd9xxx *wcd9xxx)
13393{
13394 struct snd_soc_codec *codec;
13395 struct tasha_priv *priv;
13396 int count;
13397 int i = 0;
13398
13399 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
13400 priv = snd_soc_codec_get_drvdata(codec);
13401 wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT);
13402 for (i = 0; i < priv->nr; i++)
13403 swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev,
13404 SWR_DEVICE_DOWN, NULL);
13405 snd_soc_card_change_online_state(codec->component.card, 0);
13406 for (count = 0; count < NUM_CODEC_DAIS; count++)
13407 priv->dai[count].bus_down_in_recovery = true;
13408
13409 priv->resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
13410
13411 return 0;
13412}
13413
13414static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx)
13415{
13416 int i, ret = 0;
13417 struct wcd9xxx *control;
13418 struct snd_soc_codec *codec;
13419 struct tasha_priv *tasha;
13420 struct wcd9xxx_pdata *pdata;
13421
13422 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
13423 tasha = snd_soc_codec_get_drvdata(codec);
13424 control = dev_get_drvdata(codec->dev->parent);
13425
13426 wcd9xxx_set_power_state(tasha->wcd9xxx,
13427 WCD_REGION_POWER_COLLAPSE_REMOVE,
13428 WCD9XXX_DIG_CORE_REGION_1);
13429
13430 mutex_lock(&tasha->codec_mutex);
13431
13432 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13433 control->slim_slave->laddr;
13434 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13435 control->slim->laddr;
13436 tasha_init_slim_slave_cfg(codec);
13437 if (tasha->machine_codec_event_cb)
13438 tasha->machine_codec_event_cb(codec,
13439 WCD9335_CODEC_EVENT_CODEC_UP);
13440 snd_soc_card_change_online_state(codec->component.card, 1);
13441
13442 /* Class-H Init*/
13443 wcd_clsh_init(&tasha->clsh_d);
Banajit Goswamide8271c2017-01-18 00:28:59 -080013444
13445 for (i = 0; i < TASHA_MAX_MICBIAS; i++)
13446 tasha->micb_ref[i] = 0;
13447
13448 tasha_update_reg_defaults(tasha);
13449
13450 tasha->codec = codec;
Banajit Goswamide8271c2017-01-18 00:28:59 -080013451
13452 dev_dbg(codec->dev, "%s: MCLK Rate = %x\n",
13453 __func__, control->mclk_rate);
13454
13455 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
13456 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13457 0x03, 0x00);
13458 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
13459 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13460 0x03, 0x01);
13461 tasha_codec_init_reg(codec);
13462
13463 wcd_resmgr_post_ssr_v2(tasha->resmgr);
13464
13465 tasha_enable_efuse_sensing(codec);
13466
13467 regcache_mark_dirty(codec->component.regmap);
13468 regcache_sync(codec->component.regmap);
13469
13470 pdata = dev_get_platdata(codec->dev->parent);
13471 ret = tasha_handle_pdata(tasha, pdata);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080013472 if (ret < 0)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013473 dev_err(codec->dev, "%s: invalid pdata\n", __func__);
13474
13475 /* MBHC Init */
13476 wcd_mbhc_deinit(&tasha->mbhc);
13477 tasha->mbhc_started = false;
13478
13479 /* Initialize MBHC module */
13480 ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
13481 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13482 if (ret)
13483 dev_err(codec->dev, "%s: mbhc initialization failed\n",
13484 __func__);
13485 else
13486 tasha_mbhc_hs_detect(codec, tasha->mbhc.mbhc_cfg);
13487
13488 tasha_cleanup_irqs(tasha);
13489 ret = tasha_setup_irqs(tasha);
13490 if (ret) {
13491 dev_err(codec->dev, "%s: tasha irq setup failed %d\n",
13492 __func__, ret);
13493 goto err;
13494 }
13495
13496 tasha_set_spkr_mode(codec, tasha->spkr_mode);
13497 wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT);
13498
13499err:
13500 mutex_unlock(&tasha->codec_mutex);
13501 return ret;
13502}
13503
13504static struct regulator *tasha_codec_find_ondemand_regulator(
13505 struct snd_soc_codec *codec, const char *name)
13506{
13507 int i;
13508 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13509 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
13510 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
13511
13512 for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
13513 if (pdata->regulator[i].ondemand &&
13514 wcd9xxx->supplies[i].supply &&
13515 !strcmp(wcd9xxx->supplies[i].supply, name))
13516 return wcd9xxx->supplies[i].consumer;
13517 }
13518
13519 dev_dbg(tasha->dev, "Warning: regulator not found:%s\n",
13520 name);
13521 return NULL;
13522}
13523
Banajit Goswami2be7b482017-02-03 23:32:37 -080013524static int tasha_codec_probe(struct snd_soc_codec *codec)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013525{
13526 struct wcd9xxx *control;
13527 struct tasha_priv *tasha;
13528 struct wcd9xxx_pdata *pdata;
13529 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
13530 int i, ret;
13531 void *ptr = NULL;
13532 struct regulator *supply;
13533
13534 control = dev_get_drvdata(codec->dev->parent);
13535
13536 dev_info(codec->dev, "%s()\n", __func__);
13537 tasha = snd_soc_codec_get_drvdata(codec);
13538 tasha->intf_type = wcd9xxx_get_intf_type();
13539
13540 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13541 control->dev_down = tasha_device_down;
13542 control->post_reset = tasha_post_reset_cb;
13543 control->ssr_priv = (void *)codec;
13544 }
13545
13546 /* Resource Manager post Init */
13547 ret = wcd_resmgr_post_init(tasha->resmgr, &tasha_resmgr_cb, codec);
13548 if (ret) {
13549 dev_err(codec->dev, "%s: wcd resmgr post init failed\n",
13550 __func__);
13551 goto err;
13552 }
13553 /* Class-H Init*/
13554 wcd_clsh_init(&tasha->clsh_d);
13555 /* Default HPH Mode to Class-H HiFi */
13556 tasha->hph_mode = CLS_H_HIFI;
13557
13558 tasha->codec = codec;
13559 for (i = 0; i < COMPANDER_MAX; i++)
13560 tasha->comp_enabled[i] = 0;
13561
13562 tasha->spkr_gain_offset = RX_GAIN_OFFSET_0_DB;
13563 tasha->intf_type = wcd9xxx_get_intf_type();
13564 tasha_update_reg_reset_values(codec);
13565 pr_debug("%s: MCLK Rate = %x\n", __func__, control->mclk_rate);
13566 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
13567 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13568 0x03, 0x00);
13569 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
13570 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13571 0x03, 0x01);
13572 tasha_codec_init_reg(codec);
13573
13574 tasha_enable_efuse_sensing(codec);
13575
13576 pdata = dev_get_platdata(codec->dev->parent);
13577 ret = tasha_handle_pdata(tasha, pdata);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080013578 if (ret < 0) {
Banajit Goswamide8271c2017-01-18 00:28:59 -080013579 pr_err("%s: bad pdata\n", __func__);
13580 goto err;
13581 }
13582
13583 supply = tasha_codec_find_ondemand_regulator(codec,
13584 on_demand_supply_name[ON_DEMAND_MICBIAS]);
13585 if (supply) {
13586 tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply;
13587 tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count =
13588 0;
13589 }
13590
13591 tasha->fw_data = devm_kzalloc(codec->dev,
13592 sizeof(*(tasha->fw_data)), GFP_KERNEL);
13593 if (!tasha->fw_data)
13594 goto err;
13595 set_bit(WCD9XXX_ANC_CAL, tasha->fw_data->cal_bit);
13596 set_bit(WCD9XXX_MBHC_CAL, tasha->fw_data->cal_bit);
13597 set_bit(WCD9XXX_MAD_CAL, tasha->fw_data->cal_bit);
13598 set_bit(WCD9XXX_VBAT_CAL, tasha->fw_data->cal_bit);
13599
13600 ret = wcd_cal_create_hwdep(tasha->fw_data,
13601 WCD9XXX_CODEC_HWDEP_NODE, codec);
13602 if (ret < 0) {
13603 dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret);
13604 goto err_hwdep;
13605 }
13606
13607 /* Initialize MBHC module */
13608 if (TASHA_IS_2_0(tasha->wcd9xxx)) {
13609 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].reg =
13610 WCD9335_MBHC_FSM_STATUS;
13611 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].mask = 0x01;
13612 }
13613 ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
13614 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13615 if (ret) {
13616 pr_err("%s: mbhc initialization failed\n", __func__);
13617 goto err_hwdep;
13618 }
13619
13620 ptr = devm_kzalloc(codec->dev, (sizeof(tasha_rx_chs) +
13621 sizeof(tasha_tx_chs)), GFP_KERNEL);
13622 if (!ptr) {
13623 ret = -ENOMEM;
13624 goto err_hwdep;
13625 }
13626
13627 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
13628 snd_soc_dapm_new_controls(dapm, tasha_dapm_i2s_widgets,
13629 ARRAY_SIZE(tasha_dapm_i2s_widgets));
13630 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
13631 ARRAY_SIZE(audio_i2s_map));
13632 for (i = 0; i < ARRAY_SIZE(tasha_i2s_dai); i++) {
13633 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
13634 init_waitqueue_head(&tasha->dai[i].dai_wait);
13635 }
13636 } else if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13637 for (i = 0; i < NUM_CODEC_DAIS; i++) {
13638 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
13639 init_waitqueue_head(&tasha->dai[i].dai_wait);
13640 }
13641 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13642 control->slim_slave->laddr;
13643 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13644 control->slim->laddr;
13645 tasha_slimbus_slave_port_cfg.slave_port_mapping[0] =
13646 TASHA_TX13;
13647 tasha_init_slim_slave_cfg(codec);
13648 }
13649
13650 snd_soc_add_codec_controls(codec, impedance_detect_controls,
13651 ARRAY_SIZE(impedance_detect_controls));
13652 snd_soc_add_codec_controls(codec, hph_type_detect_controls,
13653 ARRAY_SIZE(hph_type_detect_controls));
13654
13655 snd_soc_add_codec_controls(codec,
13656 tasha_analog_gain_controls,
13657 ARRAY_SIZE(tasha_analog_gain_controls));
13658 control->num_rx_port = TASHA_RX_MAX;
13659 control->rx_chs = ptr;
13660 memcpy(control->rx_chs, tasha_rx_chs, sizeof(tasha_rx_chs));
13661 control->num_tx_port = TASHA_TX_MAX;
13662 control->tx_chs = ptr + sizeof(tasha_rx_chs);
13663 memcpy(control->tx_chs, tasha_tx_chs, sizeof(tasha_tx_chs));
13664
13665 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
13666 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
13667 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback");
13668 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture");
13669
13670 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13671 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback");
13672 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture");
13673 snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback");
13674 snd_soc_dapm_ignore_suspend(dapm, "AIF Mix Playback");
13675 snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX");
13676 snd_soc_dapm_ignore_suspend(dapm, "VIfeed");
13677 snd_soc_dapm_ignore_suspend(dapm, "AIF5 CPE TX");
13678 }
13679
13680 snd_soc_dapm_sync(dapm);
13681
13682 ret = tasha_setup_irqs(tasha);
13683 if (ret) {
13684 pr_err("%s: tasha irq setup failed %d\n", __func__, ret);
13685 goto err_pdata;
13686 }
13687
13688 ret = tasha_cpe_initialize(codec);
13689 if (ret) {
13690 dev_err(codec->dev,
13691 "%s: cpe initialization failed, err = %d\n",
13692 __func__, ret);
13693 /* Do not fail probe if CPE failed */
13694 ret = 0;
13695 }
13696
13697 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
13698 tasha->tx_hpf_work[i].tasha = tasha;
13699 tasha->tx_hpf_work[i].decimator = i;
13700 INIT_DELAYED_WORK(&tasha->tx_hpf_work[i].dwork,
13701 tasha_tx_hpf_corner_freq_callback);
13702 }
13703
13704 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
13705 tasha->tx_mute_dwork[i].tasha = tasha;
13706 tasha->tx_mute_dwork[i].decimator = i;
13707 INIT_DELAYED_WORK(&tasha->tx_mute_dwork[i].dwork,
13708 tasha_tx_mute_update_callback);
13709 }
13710
13711 tasha->spk_anc_dwork.tasha = tasha;
13712 INIT_DELAYED_WORK(&tasha->spk_anc_dwork.dwork,
13713 tasha_spk_anc_update_callback);
13714
13715 mutex_lock(&tasha->codec_mutex);
13716 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
13717 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
13718 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
13719 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
13720 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
13721 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
13722 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
13723 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
13724 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
13725 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
13726 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
13727 mutex_unlock(&tasha->codec_mutex);
13728 snd_soc_dapm_sync(dapm);
13729
13730 return ret;
13731
13732err_pdata:
13733 devm_kfree(codec->dev, ptr);
13734 control->rx_chs = NULL;
13735 control->tx_chs = NULL;
13736err_hwdep:
13737 devm_kfree(codec->dev, tasha->fw_data);
13738 tasha->fw_data = NULL;
13739err:
13740 return ret;
13741}
13742
Banajit Goswami2be7b482017-02-03 23:32:37 -080013743static int tasha_codec_remove(struct snd_soc_codec *codec)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013744{
13745 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13746 struct wcd9xxx *control;
13747
13748 control = dev_get_drvdata(codec->dev->parent);
13749 control->rx_chs = NULL;
13750 control->tx_chs = NULL;
13751
13752 tasha_cleanup_irqs(tasha);
13753 /* Cleanup MBHC */
13754 /* Cleanup resmgr */
Banajit Goswamie0b20e12017-02-05 18:11:11 -080013755
13756 return 0;
Banajit Goswamide8271c2017-01-18 00:28:59 -080013757}
13758
13759static struct regmap *tasha_get_regmap(struct device *dev)
13760{
13761 struct wcd9xxx *control = dev_get_drvdata(dev->parent);
13762
13763 return control->regmap;
13764}
13765
13766static struct snd_soc_codec_driver soc_codec_dev_tasha = {
Banajit Goswami2be7b482017-02-03 23:32:37 -080013767 .probe = tasha_codec_probe,
13768 .remove = tasha_codec_remove,
Banajit Goswamide8271c2017-01-18 00:28:59 -080013769 .get_regmap = tasha_get_regmap,
Banajit Goswami8e306f02016-12-15 20:49:07 -080013770 .component_driver = {
Banajit Goswamiaf472112017-01-29 22:15:11 -080013771 .controls = tasha_snd_controls,
13772 .num_controls = ARRAY_SIZE(tasha_snd_controls),
Banajit Goswami8e306f02016-12-15 20:49:07 -080013773 .dapm_widgets = tasha_dapm_widgets,
13774 .num_dapm_widgets = ARRAY_SIZE(tasha_dapm_widgets),
13775 .dapm_routes = audio_map,
13776 .num_dapm_routes = ARRAY_SIZE(audio_map),
13777 },
Banajit Goswamide8271c2017-01-18 00:28:59 -080013778};
13779
13780#ifdef CONFIG_PM
13781static int tasha_suspend(struct device *dev)
13782{
13783 struct platform_device *pdev = to_platform_device(dev);
13784 struct tasha_priv *tasha = platform_get_drvdata(pdev);
13785
13786 dev_dbg(dev, "%s: system suspend\n", __func__);
13787 if (cancel_delayed_work_sync(&tasha->power_gate_work))
13788 tasha_codec_power_gate_digital_core(tasha);
13789
13790 return 0;
13791}
13792
13793static int tasha_resume(struct device *dev)
13794{
13795 struct platform_device *pdev = to_platform_device(dev);
13796 struct tasha_priv *tasha = platform_get_drvdata(pdev);
13797
13798 if (!tasha) {
13799 dev_err(dev, "%s: tasha private data is NULL\n", __func__);
13800 return -EINVAL;
13801 }
13802 dev_dbg(dev, "%s: system resume\n", __func__);
13803 return 0;
13804}
13805
13806static const struct dev_pm_ops tasha_pm_ops = {
13807 .suspend = tasha_suspend,
13808 .resume = tasha_resume,
13809};
13810#endif
13811
13812static int tasha_swrm_read(void *handle, int reg)
13813{
13814 struct tasha_priv *tasha;
13815 struct wcd9xxx *wcd9xxx;
13816 unsigned short swr_rd_addr_base;
13817 unsigned short swr_rd_data_base;
13818 int val, ret;
13819
13820 if (!handle) {
13821 pr_err("%s: NULL handle\n", __func__);
13822 return -EINVAL;
13823 }
13824 tasha = (struct tasha_priv *)handle;
13825 wcd9xxx = tasha->wcd9xxx;
13826
13827 dev_dbg(tasha->dev, "%s: Reading soundwire register, 0x%x\n",
13828 __func__, reg);
13829 swr_rd_addr_base = WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0;
13830 swr_rd_data_base = WCD9335_SWR_AHB_BRIDGE_RD_DATA_0;
13831 /* read_lock */
13832 mutex_lock(&tasha->swr_read_lock);
13833 ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base,
13834 (u8 *)&reg, 4);
13835 if (ret < 0) {
13836 pr_err("%s: RD Addr Failure\n", __func__);
13837 goto err;
13838 }
13839 /* Check for RD status */
13840 ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base,
13841 (u8 *)&val, 4);
13842 if (ret < 0) {
13843 pr_err("%s: RD Data Failure\n", __func__);
13844 goto err;
13845 }
13846 ret = val;
13847err:
13848 /* read_unlock */
13849 mutex_unlock(&tasha->swr_read_lock);
13850 return ret;
13851}
13852
13853static int tasha_swrm_i2s_bulk_write(struct wcd9xxx *wcd9xxx,
13854 struct wcd9xxx_reg_val *bulk_reg,
13855 size_t len)
13856{
13857 int i, ret = 0;
13858 unsigned short swr_wr_addr_base;
13859 unsigned short swr_wr_data_base;
13860
13861 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13862 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13863
13864 for (i = 0; i < (len * 2); i += 2) {
13865 /* First Write the Data to register */
13866 ret = regmap_bulk_write(wcd9xxx->regmap,
13867 swr_wr_data_base, bulk_reg[i].buf, 4);
13868 if (ret < 0) {
13869 dev_err(wcd9xxx->dev, "%s: WR Data Failure\n",
13870 __func__);
13871 break;
13872 }
13873 /* Next Write Address */
13874 ret = regmap_bulk_write(wcd9xxx->regmap,
13875 swr_wr_addr_base, bulk_reg[i+1].buf, 4);
13876 if (ret < 0) {
13877 dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n",
13878 __func__);
13879 break;
13880 }
13881 }
13882 return ret;
13883}
13884
13885static int tasha_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len)
13886{
13887 struct tasha_priv *tasha;
13888 struct wcd9xxx *wcd9xxx;
13889 struct wcd9xxx_reg_val *bulk_reg;
13890 unsigned short swr_wr_addr_base;
13891 unsigned short swr_wr_data_base;
13892 int i, j, ret;
13893
13894 if (!handle) {
13895 pr_err("%s: NULL handle\n", __func__);
13896 return -EINVAL;
13897 }
13898 if (len <= 0) {
13899 pr_err("%s: Invalid size: %zu\n", __func__, len);
13900 return -EINVAL;
13901 }
13902 tasha = (struct tasha_priv *)handle;
13903 wcd9xxx = tasha->wcd9xxx;
13904
13905 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13906 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13907
13908 bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)),
13909 GFP_KERNEL);
13910 if (!bulk_reg)
13911 return -ENOMEM;
13912
13913 for (i = 0, j = 0; i < (len * 2); i += 2, j++) {
13914 bulk_reg[i].reg = swr_wr_data_base;
13915 bulk_reg[i].buf = (u8 *)(&val[j]);
13916 bulk_reg[i].bytes = 4;
13917 bulk_reg[i+1].reg = swr_wr_addr_base;
13918 bulk_reg[i+1].buf = (u8 *)(&reg[j]);
13919 bulk_reg[i+1].bytes = 4;
13920 }
13921 mutex_lock(&tasha->swr_write_lock);
13922
13923 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
13924 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, len);
13925 if (ret) {
13926 dev_err(tasha->dev, "%s: i2s bulk write failed, ret: %d\n",
13927 __func__, ret);
13928 }
13929 } else {
13930 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
13931 (len * 2), false);
13932 if (ret) {
13933 dev_err(tasha->dev, "%s: swrm bulk write failed, ret: %d\n",
13934 __func__, ret);
13935 }
13936 }
13937
13938 mutex_unlock(&tasha->swr_write_lock);
13939 kfree(bulk_reg);
13940
13941 return ret;
13942}
13943
13944static int tasha_swrm_write(void *handle, int reg, int val)
13945{
13946 struct tasha_priv *tasha;
13947 struct wcd9xxx *wcd9xxx;
13948 unsigned short swr_wr_addr_base;
13949 unsigned short swr_wr_data_base;
13950 struct wcd9xxx_reg_val bulk_reg[2];
13951 int ret;
13952
13953 if (!handle) {
13954 pr_err("%s: NULL handle\n", __func__);
13955 return -EINVAL;
13956 }
13957 tasha = (struct tasha_priv *)handle;
13958 wcd9xxx = tasha->wcd9xxx;
13959
13960 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13961 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13962
13963 /* First Write the Data to register */
13964 bulk_reg[0].reg = swr_wr_data_base;
13965 bulk_reg[0].buf = (u8 *)(&val);
13966 bulk_reg[0].bytes = 4;
13967 bulk_reg[1].reg = swr_wr_addr_base;
13968 bulk_reg[1].buf = (u8 *)(&reg);
13969 bulk_reg[1].bytes = 4;
13970
13971 mutex_lock(&tasha->swr_write_lock);
13972
13973 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
13974 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, 1);
13975 if (ret) {
13976 dev_err(tasha->dev, "%s: i2s swrm write failed, ret: %d\n",
13977 __func__, ret);
13978 }
13979 } else {
13980 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false);
13981 if (ret < 0)
13982 pr_err("%s: WR Data Failure\n", __func__);
13983 }
13984
13985 mutex_unlock(&tasha->swr_write_lock);
13986 return ret;
13987}
13988
13989static int tasha_swrm_clock(void *handle, bool enable)
13990{
13991 struct tasha_priv *tasha = (struct tasha_priv *) handle;
13992
13993 mutex_lock(&tasha->swr_clk_lock);
13994
13995 dev_dbg(tasha->dev, "%s: swrm clock %s\n",
13996 __func__, (enable?"enable" : "disable"));
13997 if (enable) {
13998 tasha->swr_clk_users++;
13999 if (tasha->swr_clk_users == 1) {
14000 if (TASHA_IS_2_0(tasha->wcd9xxx))
14001 regmap_update_bits(
14002 tasha->wcd9xxx->regmap,
14003 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
14004 0x10, 0x00);
14005 __tasha_cdc_mclk_enable(tasha, true);
14006 regmap_update_bits(tasha->wcd9xxx->regmap,
14007 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
14008 0x01, 0x01);
14009 }
14010 } else {
14011 tasha->swr_clk_users--;
14012 if (tasha->swr_clk_users == 0) {
14013 regmap_update_bits(tasha->wcd9xxx->regmap,
14014 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
14015 0x01, 0x00);
14016 __tasha_cdc_mclk_enable(tasha, false);
14017 if (TASHA_IS_2_0(tasha->wcd9xxx))
14018 regmap_update_bits(
14019 tasha->wcd9xxx->regmap,
14020 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
14021 0x10, 0x10);
14022 }
14023 }
14024 dev_dbg(tasha->dev, "%s: swrm clock users %d\n",
14025 __func__, tasha->swr_clk_users);
14026 mutex_unlock(&tasha->swr_clk_lock);
14027 return 0;
14028}
14029
14030static int tasha_swrm_handle_irq(void *handle,
14031 irqreturn_t (*swrm_irq_handler)(int irq,
14032 void *data),
14033 void *swrm_handle,
14034 int action)
14035{
14036 struct tasha_priv *tasha;
14037 int ret = 0;
14038 struct wcd9xxx *wcd9xxx;
14039
14040 if (!handle) {
14041 pr_err("%s: null handle received\n", __func__);
14042 return -EINVAL;
14043 }
14044 tasha = (struct tasha_priv *) handle;
14045 wcd9xxx = tasha->wcd9xxx;
14046
14047 if (action) {
14048 ret = wcd9xxx_request_irq(&wcd9xxx->core_res,
14049 WCD9335_IRQ_SOUNDWIRE,
14050 swrm_irq_handler,
14051 "Tasha SWR Master", swrm_handle);
14052 if (ret)
14053 dev_err(tasha->dev, "%s: Failed to request irq %d\n",
14054 __func__, WCD9335_IRQ_SOUNDWIRE);
14055 } else
14056 wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9335_IRQ_SOUNDWIRE,
14057 swrm_handle);
14058
14059 return ret;
14060}
14061
14062static void tasha_add_child_devices(struct work_struct *work)
14063{
14064 struct tasha_priv *tasha;
14065 struct platform_device *pdev;
14066 struct device_node *node;
14067 struct wcd9xxx *wcd9xxx;
14068 struct tasha_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
14069 int ret, ctrl_num = 0;
14070 struct wcd_swr_ctrl_platform_data *platdata;
14071 char plat_dev_name[WCD9335_STRING_LEN];
14072
14073 tasha = container_of(work, struct tasha_priv,
14074 tasha_add_child_devices_work);
14075 if (!tasha) {
14076 pr_err("%s: Memory for WCD9335 does not exist\n",
14077 __func__);
14078 return;
14079 }
14080 wcd9xxx = tasha->wcd9xxx;
14081 if (!wcd9xxx) {
14082 pr_err("%s: Memory for WCD9XXX does not exist\n",
14083 __func__);
14084 return;
14085 }
14086 if (!wcd9xxx->dev->of_node) {
14087 pr_err("%s: DT node for wcd9xxx does not exist\n",
14088 __func__);
14089 return;
14090 }
14091
14092 platdata = &tasha->swr_plat_data;
14093
14094 for_each_child_of_node(wcd9xxx->dev->of_node, node) {
14095 if (!strcmp(node->name, "swr_master"))
14096 strlcpy(plat_dev_name, "tasha_swr_ctrl",
14097 (WCD9335_STRING_LEN - 1));
14098 else if (strnstr(node->name, "msm_cdc_pinctrl",
14099 strlen("msm_cdc_pinctrl")) != NULL)
14100 strlcpy(plat_dev_name, node->name,
14101 (WCD9335_STRING_LEN - 1));
14102 else
14103 continue;
14104
14105 pdev = platform_device_alloc(plat_dev_name, -1);
14106 if (!pdev) {
14107 dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n",
14108 __func__);
14109 ret = -ENOMEM;
14110 goto err;
14111 }
14112 pdev->dev.parent = tasha->dev;
14113 pdev->dev.of_node = node;
14114
14115 if (!strcmp(node->name, "swr_master")) {
14116 ret = platform_device_add_data(pdev, platdata,
14117 sizeof(*platdata));
14118 if (ret) {
14119 dev_err(&pdev->dev,
14120 "%s: cannot add plat data ctrl:%d\n",
14121 __func__, ctrl_num);
14122 goto fail_pdev_add;
14123 }
14124 }
14125
14126 ret = platform_device_add(pdev);
14127 if (ret) {
14128 dev_err(&pdev->dev,
14129 "%s: Cannot add platform device\n",
14130 __func__);
14131 goto fail_pdev_add;
14132 }
14133
14134 if (!strcmp(node->name, "swr_master")) {
14135 temp = krealloc(swr_ctrl_data,
14136 (ctrl_num + 1) * sizeof(
14137 struct tasha_swr_ctrl_data),
14138 GFP_KERNEL);
14139 if (!temp) {
14140 dev_err(wcd9xxx->dev, "out of memory\n");
14141 ret = -ENOMEM;
14142 goto err;
14143 }
14144 swr_ctrl_data = temp;
14145 swr_ctrl_data[ctrl_num].swr_pdev = pdev;
14146 ctrl_num++;
14147 dev_dbg(&pdev->dev,
14148 "%s: Added soundwire ctrl device(s)\n",
14149 __func__);
14150 tasha->nr = ctrl_num;
14151 tasha->swr_ctrl_data = swr_ctrl_data;
14152 }
14153 }
14154
14155 return;
14156fail_pdev_add:
14157 platform_device_put(pdev);
14158err:
14159 return;
14160}
14161
14162/*
14163 * tasha_codec_ver: to get tasha codec version
14164 * @codec: handle to snd_soc_codec *
14165 * return enum codec_variant - version
14166 */
14167enum codec_variant tasha_codec_ver(void)
14168{
14169 return codec_ver;
14170}
14171EXPORT_SYMBOL(tasha_codec_ver);
14172
14173static int __tasha_enable_efuse_sensing(struct tasha_priv *tasha)
14174{
14175 int val, rc;
14176
14177 __tasha_cdc_mclk_enable(tasha, true);
14178
14179 regmap_update_bits(tasha->wcd9xxx->regmap,
14180 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x20);
14181 regmap_update_bits(tasha->wcd9xxx->regmap,
14182 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01);
14183
14184 /*
14185 * 5ms sleep required after enabling efuse control
14186 * before checking the status.
14187 */
14188 usleep_range(5000, 5500);
14189 rc = regmap_read(tasha->wcd9xxx->regmap,
14190 WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS, &val);
14191
14192 if (rc || (!(val & 0x01)))
14193 WARN(1, "%s: Efuse sense is not complete\n", __func__);
14194
14195 __tasha_cdc_mclk_enable(tasha, false);
14196
14197 return rc;
14198}
14199
14200void tasha_get_codec_ver(struct tasha_priv *tasha)
14201{
14202 int i;
14203 int val;
14204 struct tasha_reg_mask_val codec_reg[] = {
14205 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0xFF, 0xFF},
14206 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0xFF, 0x83},
14207 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12, 0xFF, 0x0A},
14208 };
14209
14210 __tasha_enable_efuse_sensing(tasha);
14211 for (i = 0; i < ARRAY_SIZE(codec_reg); i++) {
14212 regmap_read(tasha->wcd9xxx->regmap, codec_reg[i].reg, &val);
14213 if (!(val && codec_reg[i].val)) {
14214 codec_ver = WCD9335;
14215 goto ret;
14216 }
14217 }
14218 codec_ver = WCD9326;
14219ret:
14220 pr_debug("%s: codec is %d\n", __func__, codec_ver);
14221}
14222EXPORT_SYMBOL(tasha_get_codec_ver);
14223
14224static int tasha_probe(struct platform_device *pdev)
14225{
14226 int ret = 0;
14227 struct tasha_priv *tasha;
14228 struct clk *wcd_ext_clk, *wcd_native_clk;
14229 struct wcd9xxx_resmgr_v2 *resmgr;
14230 struct wcd9xxx_power_region *cdc_pwr;
14231
14232 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
14233 if (apr_get_subsys_state() == APR_SUBSYS_DOWN) {
14234 dev_err(&pdev->dev, "%s: dsp down\n", __func__);
14235 return -EPROBE_DEFER;
14236 }
14237 }
14238
14239 tasha = devm_kzalloc(&pdev->dev, sizeof(struct tasha_priv),
14240 GFP_KERNEL);
14241 if (!tasha)
14242 return -ENOMEM;
14243 platform_set_drvdata(pdev, tasha);
14244
14245 tasha->wcd9xxx = dev_get_drvdata(pdev->dev.parent);
14246 tasha->dev = &pdev->dev;
14247 INIT_DELAYED_WORK(&tasha->power_gate_work, tasha_codec_power_gate_work);
14248 mutex_init(&tasha->power_lock);
14249 mutex_init(&tasha->sido_lock);
14250 INIT_WORK(&tasha->tasha_add_child_devices_work,
14251 tasha_add_child_devices);
14252 BLOCKING_INIT_NOTIFIER_HEAD(&tasha->notifier);
14253 mutex_init(&tasha->micb_lock);
14254 mutex_init(&tasha->swr_read_lock);
14255 mutex_init(&tasha->swr_write_lock);
14256 mutex_init(&tasha->swr_clk_lock);
14257 mutex_init(&tasha->mclk_lock);
14258
14259 cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region),
14260 GFP_KERNEL);
14261 if (!cdc_pwr) {
14262 ret = -ENOMEM;
14263 goto err_cdc_pwr;
14264 }
14265 tasha->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr;
14266 cdc_pwr->pwr_collapse_reg_min = TASHA_DIG_CORE_REG_MIN;
14267 cdc_pwr->pwr_collapse_reg_max = TASHA_DIG_CORE_REG_MAX;
14268 wcd9xxx_set_power_state(tasha->wcd9xxx,
14269 WCD_REGION_POWER_COLLAPSE_REMOVE,
14270 WCD9XXX_DIG_CORE_REGION_1);
14271
14272 mutex_init(&tasha->codec_mutex);
14273 /*
14274 * Init resource manager so that if child nodes such as SoundWire
14275 * requests for clock, resource manager can honor the request
14276 */
14277 resmgr = wcd_resmgr_init(&tasha->wcd9xxx->core_res, NULL);
14278 if (IS_ERR(resmgr)) {
14279 ret = PTR_ERR(resmgr);
14280 dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n",
14281 __func__);
14282 goto err_resmgr;
14283 }
14284 tasha->resmgr = resmgr;
14285 tasha->swr_plat_data.handle = (void *) tasha;
14286 tasha->swr_plat_data.read = tasha_swrm_read;
14287 tasha->swr_plat_data.write = tasha_swrm_write;
14288 tasha->swr_plat_data.bulk_write = tasha_swrm_bulk_write;
14289 tasha->swr_plat_data.clk = tasha_swrm_clock;
14290 tasha->swr_plat_data.handle_irq = tasha_swrm_handle_irq;
14291
14292 /* Register for Clock */
14293 wcd_ext_clk = clk_get(tasha->wcd9xxx->dev, "wcd_clk");
14294 if (IS_ERR(wcd_ext_clk)) {
14295 dev_err(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14296 __func__, "wcd_ext_clk");
14297 goto err_clk;
14298 }
14299 tasha->wcd_ext_clk = wcd_ext_clk;
14300 tasha->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV;
14301 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
14302 tasha->sido_ccl_cnt = 0;
14303
14304 /* Register native clk for 44.1 playback */
14305 wcd_native_clk = clk_get(tasha->wcd9xxx->dev, "wcd_native_clk");
14306 if (IS_ERR(wcd_native_clk))
14307 dev_dbg(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14308 __func__, "wcd_native_clk");
14309 else
14310 tasha->wcd_native_clk = wcd_native_clk;
14311
14312 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
14313 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha,
14314 tasha_dai, ARRAY_SIZE(tasha_dai));
14315 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
14316 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha,
14317 tasha_i2s_dai,
14318 ARRAY_SIZE(tasha_i2s_dai));
14319 else
14320 ret = -EINVAL;
14321 if (ret) {
14322 dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n",
14323 __func__, ret);
14324 goto err_cdc_reg;
14325 }
14326 /* Update codec register default values */
14327 tasha_update_reg_defaults(tasha);
14328 schedule_work(&tasha->tasha_add_child_devices_work);
14329 tasha_get_codec_ver(tasha);
14330
14331 dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__);
14332 return ret;
14333
14334err_cdc_reg:
14335 clk_put(tasha->wcd_ext_clk);
14336 if (tasha->wcd_native_clk)
14337 clk_put(tasha->wcd_native_clk);
14338err_clk:
14339 wcd_resmgr_remove(tasha->resmgr);
14340err_resmgr:
14341 devm_kfree(&pdev->dev, cdc_pwr);
14342err_cdc_pwr:
14343 mutex_destroy(&tasha->mclk_lock);
14344 devm_kfree(&pdev->dev, tasha);
14345 return ret;
14346}
14347
14348static int tasha_remove(struct platform_device *pdev)
14349{
14350 struct tasha_priv *tasha;
14351
14352 tasha = platform_get_drvdata(pdev);
14353
14354 mutex_destroy(&tasha->codec_mutex);
14355 clk_put(tasha->wcd_ext_clk);
14356 if (tasha->wcd_native_clk)
14357 clk_put(tasha->wcd_native_clk);
14358 mutex_destroy(&tasha->mclk_lock);
14359 devm_kfree(&pdev->dev, tasha);
14360 snd_soc_unregister_codec(&pdev->dev);
14361 return 0;
14362}
14363
14364static struct platform_driver tasha_codec_driver = {
14365 .probe = tasha_probe,
14366 .remove = tasha_remove,
14367 .driver = {
14368 .name = "tasha_codec",
14369 .owner = THIS_MODULE,
14370#ifdef CONFIG_PM
14371 .pm = &tasha_pm_ops,
14372#endif
14373 },
14374};
14375
14376module_platform_driver(tasha_codec_driver);
14377
14378MODULE_DESCRIPTION("Tasha Codec driver");
14379MODULE_LICENSE("GPL v2");