blob: 009e614d0eac9ad001d88cac81e50d4bc741c743 [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302/*
Aditya Bavanaribaab9b12019-02-03 22:15:21 +05303 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304 */
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/firmware.h>
8#include <linux/slab.h>
9#include <linux/platform_device.h>
10#include <linux/device.h>
11#include <linux/printk.h>
12#include <linux/ratelimit.h>
13#include <linux/debugfs.h>
14#include <linux/wait.h>
15#include <linux/bitops.h>
16#include <linux/regmap.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053017#include <linux/regulator/consumer.h>
18#include <linux/clk.h>
19#include <linux/delay.h>
20#include <linux/pm_runtime.h>
21#include <linux/kernel.h>
22#include <linux/gpio.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053023#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
24#include <soc/swr-wcd.h>
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053025#include <soc/snd_event.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053026#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/tlv.h>
31#include <sound/info.h>
Meng Wang11a25cf2018-10-31 14:11:26 +080032#include <asoc/core.h>
33#include <asoc/pdata.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053034#include "wcd9335.h"
Meng Wang11a25cf2018-10-31 14:11:26 +080035#include <asoc/wcd-mbhc-v2.h>
36#include <asoc/wcd9xxx-common-v2.h>
37#include <asoc/wcd9xxx-resmgr-v2.h>
38#include <asoc/wcd9xxx-irq.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053039#include "wcd9335_registers.h"
40#include "wcd9335_irq.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053041#include "wcd_cpe_core.h"
Meng Wang11a25cf2018-10-31 14:11:26 +080042#include <asoc/wcdcal-hwdep.h>
43#include <asoc/wcd-mbhc-v2-api.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053044
Meng Wang15c825d2018-09-06 10:49:18 +080045#define DRV_NAME "tasha_codec"
46
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053047#define TASHA_RX_PORT_START_NUMBER 16
48
49#define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
50 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
51 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
52/* Fractional Rates */
53#define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100)
54
55#define WCD9335_MIX_RATES_MASK (SNDRV_PCM_RATE_48000 |\
56 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
57
58#define TASHA_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
59 SNDRV_PCM_FMTBIT_S24_LE | \
60 SNDRV_PCM_FMTBIT_S24_3LE)
61
62#define TASHA_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
63 SNDRV_PCM_FMTBIT_S24_LE | \
64 SNDRV_PCM_FMTBIT_S24_3LE | \
65 SNDRV_PCM_FMTBIT_S32_LE)
66
67#define TASHA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
68
69/*
70 * Timeout in milli seconds and it is the wait time for
71 * slim channel removal interrupt to receive.
72 */
73#define TASHA_SLIM_CLOSE_TIMEOUT 1000
74#define TASHA_SLIM_IRQ_OVERFLOW (1 << 0)
75#define TASHA_SLIM_IRQ_UNDERFLOW (1 << 1)
76#define TASHA_SLIM_IRQ_PORT_CLOSED (1 << 2)
77#define TASHA_MCLK_CLK_12P288MHZ 12288000
78#define TASHA_MCLK_CLK_9P6MHZ 9600000
79
80#define TASHA_SLIM_PGD_PORT_INT_TX_EN0 (TASHA_SLIM_PGD_PORT_INT_EN0 + 2)
81
82#define TASHA_NUM_INTERPOLATORS 9
83#define TASHA_NUM_DECIMATORS 9
84
Meng Wang3b194492017-09-27 12:20:22 +080085#define WCD9335_CHILD_DEVICES_MAX 6
86
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053087#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
88#define TASHA_MAD_AUDIO_FIRMWARE_PATH "wcd9335/wcd9335_mad_audio.bin"
89#define TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS (1 << 0)
90#define TASHA_CPE_SS_ERR_STATUS_WDOG_BITE (1 << 1)
91
92#define TASHA_CPE_FATAL_IRQS \
93 (TASHA_CPE_SS_ERR_STATUS_WDOG_BITE | \
94 TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS)
95
96#define SLIM_BW_CLK_GEAR_9 6200000
97#define SLIM_BW_UNVOTE 0
98
99#define CPE_FLL_CLK_75MHZ 75000000
100#define CPE_FLL_CLK_150MHZ 150000000
101#define WCD9335_REG_BITS 8
102
103#define WCD9335_MAX_VALID_ADC_MUX 13
104#define WCD9335_INVALID_ADC_MUX 9
105
106#define TASHA_DIG_CORE_REG_MIN WCD9335_CDC_ANC0_CLK_RESET_CTL
107#define TASHA_DIG_CORE_REG_MAX 0xDFF
108
109/* Convert from vout ctl to micbias voltage in mV */
110#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
111
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +0530112#define TASHA_ZDET_NUM_MEASUREMENTS 900
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530113#define TASHA_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
114#define TASHA_MBHC_GET_X1(x) (x & 0x3FFF)
115/* z value compared in milliOhm */
116#define TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
117#define TASHA_MBHC_ZDET_CONST (86 * 16384)
118#define TASHA_MBHC_MOISTURE_VREF V_45_MV
119#define TASHA_MBHC_MOISTURE_IREF I_3P0_UA
120
121#define TASHA_VERSION_ENTRY_SIZE 17
122
123#define WCD9335_AMIC_PWR_LEVEL_LP 0
124#define WCD9335_AMIC_PWR_LEVEL_DEFAULT 1
125#define WCD9335_AMIC_PWR_LEVEL_HP 2
126#define WCD9335_AMIC_PWR_LVL_MASK 0x60
127#define WCD9335_AMIC_PWR_LVL_SHIFT 0x5
128
129#define WCD9335_DEC_PWR_LVL_MASK 0x06
130#define WCD9335_DEC_PWR_LVL_LP 0x02
131#define WCD9335_DEC_PWR_LVL_HP 0x04
132#define WCD9335_DEC_PWR_LVL_DF 0x00
133#define WCD9335_STRING_LEN 100
134
135#define CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25)
136
137static int cpe_debug_mode;
138
139#define TASHA_MAX_MICBIAS 4
140#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone"
141#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone"
142#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone"
143#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone"
144
145#define DAPM_LDO_H_STANDALONE "LDO_H"
146module_param(cpe_debug_mode, int, 0664);
147MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode");
148
149#define TASHA_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000)
150
151#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64
152
153static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
154 "cdc-vdd-mic-bias",
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +0530155 "cdc-vdd-tx-h",
156 "cdc-vdd-rx-h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530157};
158
159enum {
160 POWER_COLLAPSE,
161 POWER_RESUME,
162};
163
164enum tasha_sido_voltage {
165 SIDO_VOLTAGE_SVS_MV = 950,
166 SIDO_VOLTAGE_NOMINAL_MV = 1100,
167};
168
169static enum codec_variant codec_ver;
170
171static int dig_core_collapse_enable = 1;
172module_param(dig_core_collapse_enable, int, 0664);
173MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating");
174
175/* dig_core_collapse timer in seconds */
176static int dig_core_collapse_timer = (TASHA_DIG_CORE_COLLAPSE_TIMER_MS/1000);
177module_param(dig_core_collapse_timer, int, 0664);
178MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating");
179
180/* SVS Scaling enable/disable */
181static int svs_scaling_enabled = 1;
182module_param(svs_scaling_enabled, int, 0664);
183MODULE_PARM_DESC(svs_scaling_enabled, "enable/disable svs scaling");
184
185/* SVS buck setting */
186static int sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV;
187module_param(sido_buck_svs_voltage, int, 0664);
188MODULE_PARM_DESC(sido_buck_svs_voltage,
189 "setting for SVS voltage for SIDO BUCK");
190
191#define TASHA_TX_UNMUTE_DELAY_MS 40
192
193static int tx_unmute_delay = TASHA_TX_UNMUTE_DELAY_MS;
194module_param(tx_unmute_delay, int, 0664);
195MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
196
197static struct afe_param_slimbus_slave_port_cfg tasha_slimbus_slave_port_cfg = {
198 .minor_version = 1,
199 .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1,
200 .slave_dev_pgd_la = 0,
201 .slave_dev_intfdev_la = 0,
202 .bit_width = 16,
203 .data_format = 0,
204 .num_channels = 1
205};
206
207struct tasha_mbhc_zdet_param {
208 u16 ldo_ctl;
209 u16 noff;
210 u16 nshift;
211 u16 btn5;
212 u16 btn6;
213 u16 btn7;
214};
215
216static struct afe_param_cdc_reg_page_cfg tasha_cdc_reg_page_cfg = {
217 .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG,
218 .enable = 1,
219 .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1,
220};
221
222static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
223 {
224 1,
225 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_MAIN_CTL_1),
226 HW_MAD_AUDIO_ENABLE, 0x1, WCD9335_REG_BITS, 0
227 },
228 {
229 1,
230 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_3),
231 HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD9335_REG_BITS, 0
232 },
233 {
234 1,
235 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_4),
236 HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD9335_REG_BITS, 0
237 },
238 {
239 1,
240 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
241 MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
242 },
243 {
244 1,
245 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
246 MAD_AUDIO_INT_MASK_REG, 0x1, WCD9335_REG_BITS, 0
247 },
248 {
249 1,
250 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
251 MAD_AUDIO_INT_STATUS_REG, 0x1, WCD9335_REG_BITS, 0
252 },
253 {
254 1,
255 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
256 MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD9335_REG_BITS, 0
257 },
258 {
259 1,
260 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
261 VBAT_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
262 },
263 {
264 1,
265 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
266 VBAT_INT_MASK_REG, 0x08, WCD9335_REG_BITS, 0
267 },
268 {
269 1,
270 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
271 VBAT_INT_STATUS_REG, 0x08, WCD9335_REG_BITS, 0
272 },
273 {
274 1,
275 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
276 VBAT_INT_CLEAR_REG, 0x08, WCD9335_REG_BITS, 0
277 },
278 {
279 1,
280 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
281 VBAT_RELEASE_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
282 },
283 {
284 1,
285 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
286 VBAT_RELEASE_INT_MASK_REG, 0x10, WCD9335_REG_BITS, 0
287 },
288 {
289 1,
290 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
291 VBAT_RELEASE_INT_STATUS_REG, 0x10, WCD9335_REG_BITS, 0
292 },
293 {
294 1,
295 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
296 VBAT_RELEASE_INT_CLEAR_REG, 0x10, WCD9335_REG_BITS, 0
297 },
298 {
299 1,
300 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE),
301 SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1
302 },
303 {
304 1,
305 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE),
306 SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1
307 },
308 {
309 1,
310 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE),
311 SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1
312 },
313 {
314 1,
315 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE),
316 SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1
317 },
318 { 1,
319 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL),
320 AANC_FF_GAIN_ADAPTIVE, 0x4, WCD9335_REG_BITS, 0
321 },
322 { 1,
323 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL),
324 AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD9335_REG_BITS, 0
325 },
326 {
327 1,
328 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_FF_A_GAIN_CTL),
329 AANC_GAIN_CONTROL, 0xFF, WCD9335_REG_BITS, 0
330 },
331};
332
333static struct afe_param_cdc_reg_cfg_data tasha_audio_reg_cfg = {
334 .num_registers = ARRAY_SIZE(audio_reg_cfg),
335 .reg_data = audio_reg_cfg,
336};
337
338static struct afe_param_id_cdc_aanc_version tasha_cdc_aanc_version = {
339 .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
340 .aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
341};
342
343enum {
344 VI_SENSE_1,
345 VI_SENSE_2,
346 AIF4_SWITCH_VALUE,
347 AUDIO_NOMINAL,
348 CPE_NOMINAL,
349 HPH_PA_DELAY,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530350 ANC_MIC_AMIC1,
351 ANC_MIC_AMIC2,
352 ANC_MIC_AMIC3,
353 ANC_MIC_AMIC4,
354 ANC_MIC_AMIC5,
355 ANC_MIC_AMIC6,
356 CLASSH_CONFIG,
357};
358
359enum {
360 AIF1_PB = 0,
361 AIF1_CAP,
362 AIF2_PB,
363 AIF2_CAP,
364 AIF3_PB,
365 AIF3_CAP,
366 AIF4_PB,
367 AIF_MIX1_PB,
368 AIF4_MAD_TX,
369 AIF4_VIFEED,
370 AIF5_CPE_TX,
371 NUM_CODEC_DAIS,
372};
373
374enum {
375 INTn_1_MIX_INP_SEL_ZERO = 0,
376 INTn_1_MIX_INP_SEL_DEC0,
377 INTn_1_MIX_INP_SEL_DEC1,
378 INTn_1_MIX_INP_SEL_IIR0,
379 INTn_1_MIX_INP_SEL_IIR1,
380 INTn_1_MIX_INP_SEL_RX0,
381 INTn_1_MIX_INP_SEL_RX1,
382 INTn_1_MIX_INP_SEL_RX2,
383 INTn_1_MIX_INP_SEL_RX3,
384 INTn_1_MIX_INP_SEL_RX4,
385 INTn_1_MIX_INP_SEL_RX5,
386 INTn_1_MIX_INP_SEL_RX6,
387 INTn_1_MIX_INP_SEL_RX7,
388
389};
390
391#define IS_VALID_NATIVE_FIFO_PORT(inp) \
392 ((inp >= INTn_1_MIX_INP_SEL_RX0) && \
393 (inp <= INTn_1_MIX_INP_SEL_RX3))
394
395enum {
396 INTn_2_INP_SEL_ZERO = 0,
397 INTn_2_INP_SEL_RX0,
398 INTn_2_INP_SEL_RX1,
399 INTn_2_INP_SEL_RX2,
400 INTn_2_INP_SEL_RX3,
401 INTn_2_INP_SEL_RX4,
402 INTn_2_INP_SEL_RX5,
403 INTn_2_INP_SEL_RX6,
404 INTn_2_INP_SEL_RX7,
405 INTn_2_INP_SEL_PROXIMITY,
406};
407
408enum {
409 INTERP_EAR = 0,
410 INTERP_HPHL,
411 INTERP_HPHR,
412 INTERP_LO1,
413 INTERP_LO2,
414 INTERP_LO3,
415 INTERP_LO4,
416 INTERP_SPKR1,
417 INTERP_SPKR2,
418};
419
420struct interp_sample_rate {
421 int sample_rate;
422 int rate_val;
423};
424
425static struct interp_sample_rate int_prim_sample_rate_val[] = {
426 {8000, 0x0}, /* 8K */
427 {16000, 0x1}, /* 16K */
428 {24000, -EINVAL},/* 24K */
429 {32000, 0x3}, /* 32K */
430 {48000, 0x4}, /* 48K */
431 {96000, 0x5}, /* 96K */
432 {192000, 0x6}, /* 192K */
433 {384000, 0x7}, /* 384K */
434 {44100, 0x8}, /* 44.1K */
435};
436
437static struct interp_sample_rate int_mix_sample_rate_val[] = {
438 {48000, 0x4}, /* 48K */
439 {96000, 0x5}, /* 96K */
440 {192000, 0x6}, /* 192K */
441};
442
443static const struct wcd9xxx_ch tasha_rx_chs[TASHA_RX_MAX] = {
444 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER, 0),
445 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 1, 1),
446 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 2, 2),
447 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 3, 3),
448 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 4, 4),
449 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 5, 5),
450 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 6, 6),
451 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 7, 7),
452 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 8, 8),
453 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 9, 9),
454 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 10, 10),
455 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 11, 11),
456 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 12, 12),
457};
458
459static const struct wcd9xxx_ch tasha_tx_chs[TASHA_TX_MAX] = {
460 WCD9XXX_CH(0, 0),
461 WCD9XXX_CH(1, 1),
462 WCD9XXX_CH(2, 2),
463 WCD9XXX_CH(3, 3),
464 WCD9XXX_CH(4, 4),
465 WCD9XXX_CH(5, 5),
466 WCD9XXX_CH(6, 6),
467 WCD9XXX_CH(7, 7),
468 WCD9XXX_CH(8, 8),
469 WCD9XXX_CH(9, 9),
470 WCD9XXX_CH(10, 10),
471 WCD9XXX_CH(11, 11),
472 WCD9XXX_CH(12, 12),
473 WCD9XXX_CH(13, 13),
474 WCD9XXX_CH(14, 14),
475 WCD9XXX_CH(15, 15),
476};
477
478static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = {
479 /* Needs to define in the same order of DAI enum definitions */
480 0,
481 BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
482 0,
483 BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
484 0,
485 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
486 0,
487 0,
488 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF5_CPE_TX),
489 0,
490 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX),
491};
492
493static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
494 0, /* AIF1_PB */
495 BIT(AIF2_CAP), /* AIF1_CAP */
496 0, /* AIF2_PB */
497 BIT(AIF1_CAP), /* AIF2_CAP */
498};
499
500/* Codec supports 2 IIR filters */
501enum {
502 IIR0 = 0,
503 IIR1,
504 IIR_MAX,
505};
506
507/* Each IIR has 5 Filter Stages */
508enum {
509 BAND1 = 0,
510 BAND2,
511 BAND3,
512 BAND4,
513 BAND5,
514 BAND_MAX,
515};
516
517enum {
518 COMPANDER_1, /* HPH_L */
519 COMPANDER_2, /* HPH_R */
520 COMPANDER_3, /* LO1_DIFF */
521 COMPANDER_4, /* LO2_DIFF */
522 COMPANDER_5, /* LO3_SE */
523 COMPANDER_6, /* LO4_SE */
524 COMPANDER_7, /* SWR SPK CH1 */
525 COMPANDER_8, /* SWR SPK CH2 */
526 COMPANDER_MAX,
527};
528
529enum {
530 SRC_IN_HPHL,
531 SRC_IN_LO1,
532 SRC_IN_HPHR,
533 SRC_IN_LO2,
534 SRC_IN_SPKRL,
535 SRC_IN_LO3,
536 SRC_IN_SPKRR,
537 SRC_IN_LO4,
538};
539
540enum {
541 SPLINE_SRC0,
542 SPLINE_SRC1,
543 SPLINE_SRC2,
544 SPLINE_SRC3,
545 SPLINE_SRC_MAX,
546};
547
548static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
549static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
550static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
551
552static struct snd_soc_dai_driver tasha_dai[];
553static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv);
554
Meng Wang15c825d2018-09-06 10:49:18 +0800555static int tasha_config_compander(struct snd_soc_component *, int, int);
556static void tasha_codec_set_tx_hold(struct snd_soc_component *, u16, bool);
557static int tasha_codec_internal_rco_ctrl(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530558 bool enable);
559
560/* Hold instance to soundwire platform device */
561struct tasha_swr_ctrl_data {
562 struct platform_device *swr_pdev;
563 struct ida swr_ida;
564};
565
566struct wcd_swr_ctrl_platform_data {
567 void *handle; /* holds codec private data */
568 int (*read)(void *handle, int reg);
569 int (*write)(void *handle, int reg, int val);
570 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
571 int (*clk)(void *handle, bool enable);
572 int (*handle_irq)(void *handle,
573 irqreturn_t (*swrm_irq_handler)(int irq,
574 void *data),
575 void *swrm_handle,
576 int action);
577};
578
579static struct wcd_mbhc_register
580 wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = {
581 WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN",
582 WCD9335_ANA_MBHC_MECH, 0x80, 7, 0),
583 WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN",
584 WCD9335_ANA_MBHC_MECH, 0x40, 6, 0),
585 WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE",
586 WCD9335_ANA_MBHC_MECH, 0x20, 5, 0),
587 WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL",
588 WCD9335_MBHC_PLUG_DETECT_CTL, 0x30, 4, 0),
589 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE",
590 WCD9335_ANA_MBHC_ELECT, 0x08, 3, 0),
591 WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL",
592 WCD9335_MBHC_PLUG_DETECT_CTL, 0xC0, 6, 0),
593 WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL",
594 WCD9335_ANA_MBHC_MECH, 0x04, 2, 0),
595 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE",
596 WCD9335_ANA_MBHC_MECH, 0x10, 4, 0),
597 WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE",
598 WCD9335_ANA_MBHC_MECH, 0x08, 3, 0),
599 WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND",
600 WCD9335_ANA_MBHC_MECH, 0x01, 0, 0),
601 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC",
602 WCD9335_ANA_MBHC_ELECT, 0x06, 1, 0),
603 WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN",
604 WCD9335_ANA_MBHC_ELECT, 0x80, 7, 0),
605 WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC",
606 WCD9335_MBHC_PLUG_DETECT_CTL, 0x0F, 0, 0),
607 WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC",
608 WCD9335_MBHC_CTL_1, 0x03, 0, 0),
609 WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF",
610 WCD9335_MBHC_CTL_2, 0x03, 0, 0),
611 WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT",
612 WCD9335_ANA_MBHC_RESULT_3, 0x08, 3, 0),
Karthikeyan Mani4d7fb3f2018-08-31 11:02:53 -0700613 WCD_MBHC_REGISTER("WCD_MBHC_IN2P_CLAMP_STATE",
614 WCD9335_ANA_MBHC_RESULT_3, 0x10, 4, 0),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530615 WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT",
616 WCD9335_ANA_MBHC_RESULT_3, 0x20, 5, 0),
617 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT",
618 WCD9335_ANA_MBHC_RESULT_3, 0x80, 7, 0),
619 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT",
620 WCD9335_ANA_MBHC_RESULT_3, 0x40, 6, 0),
621 WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN",
622 WCD9335_HPH_OCP_CTL, 0x10, 4, 0),
623 WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT",
624 WCD9335_ANA_MBHC_RESULT_3, 0x07, 0, 0),
625 WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL",
626 WCD9335_ANA_MBHC_ELECT, 0x70, 4, 0),
627 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT",
628 WCD9335_ANA_MBHC_RESULT_3, 0xFF, 0, 0),
629 WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL",
630 WCD9335_ANA_MICB2, 0xC0, 6, 0),
631 WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME",
632 WCD9335_HPH_CNP_WG_TIME, 0xFF, 0, 0),
633 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN",
634 WCD9335_ANA_HPH, 0x40, 6, 0),
635 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN",
636 WCD9335_ANA_HPH, 0x80, 7, 0),
637 WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN",
638 WCD9335_ANA_HPH, 0xC0, 6, 0),
639 WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE",
640 WCD9335_ANA_MBHC_RESULT_3, 0x10, 4, 0),
641 WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL",
642 0, 0, 0, 0),
643 WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN",
644 WCD9335_ANA_MBHC_ZDET, 0x01, 0, 0),
645 /*
646 * MBHC FSM status register is only available in Tasha 2.0.
647 * So, init with 0 later once the version is known, then values
648 * will be updated.
649 */
650 WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS",
651 0, 0, 0, 0),
652 WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
653 WCD9335_MBHC_CTL_2, 0x70, 4, 0),
Meng Wang6f901622017-09-19 10:21:57 +0800654 WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS",
655 WCD9335_MBHC_FSM_STATUS, 0X20, 5, 0),
656 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND",
657 WCD9335_HPH_PA_CTL2, 0x40, 6, 0),
658 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND",
659 WCD9335_HPH_PA_CTL2, 0x10, 4, 0),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530660};
661
662static const struct wcd_mbhc_intr intr_ids = {
663 .mbhc_sw_intr = WCD9335_IRQ_MBHC_SW_DET,
664 .mbhc_btn_press_intr = WCD9335_IRQ_MBHC_BUTTON_PRESS_DET,
665 .mbhc_btn_release_intr = WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET,
666 .mbhc_hs_ins_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
667 .mbhc_hs_rem_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_DET,
668 .hph_left_ocp = WCD9335_IRQ_HPH_PA_OCPL_FAULT,
669 .hph_right_ocp = WCD9335_IRQ_HPH_PA_OCPR_FAULT,
670};
671
672struct wcd_vbat {
673 bool is_enabled;
674 bool adc_config;
675 /* Variables to cache Vbat ADC output values */
676 u16 dcp1;
677 u16 dcp2;
678};
679
680struct hpf_work {
681 struct tasha_priv *tasha;
682 u8 decimator;
683 u8 hpf_cut_off_freq;
684 struct delayed_work dwork;
685};
686
687#define WCD9335_SPK_ANC_EN_DELAY_MS 350
688static int spk_anc_en_delay = WCD9335_SPK_ANC_EN_DELAY_MS;
689module_param(spk_anc_en_delay, int, 0664);
690MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path");
691
692struct spk_anc_work {
693 struct tasha_priv *tasha;
694 struct delayed_work dwork;
695};
696
697struct tx_mute_work {
698 struct tasha_priv *tasha;
699 u8 decimator;
700 struct delayed_work dwork;
701};
702
703struct tasha_priv {
704 struct device *dev;
705 struct wcd9xxx *wcd9xxx;
706
Meng Wang15c825d2018-09-06 10:49:18 +0800707 struct snd_soc_component *component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530708 u32 adc_count;
709 u32 rx_bias_count;
710 s32 dmic_0_1_clk_cnt;
711 s32 dmic_2_3_clk_cnt;
712 s32 dmic_4_5_clk_cnt;
713 s32 ldo_h_users;
714 s32 micb_ref[TASHA_MAX_MICBIAS];
715 s32 pullup_ref[TASHA_MAX_MICBIAS];
716
717 u32 anc_slot;
718 bool anc_func;
Laxminath Kasamf2687c92018-06-14 12:44:04 +0530719 bool is_wsa_attach;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530720
721 /* Vbat module */
722 struct wcd_vbat vbat;
723
724 /* cal info for codec */
725 struct fw_info *fw_data;
726
727 /*track tasha interface type*/
728 u8 intf_type;
729
730 /* num of slim ports required */
731 struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
732
733 /* SoundWire data structure */
734 struct tasha_swr_ctrl_data *swr_ctrl_data;
735 int nr;
736
737 /*compander*/
738 int comp_enabled[COMPANDER_MAX];
739
740 /* Maintain the status of AUX PGA */
741 int aux_pga_cnt;
742 u8 aux_l_gain;
743 u8 aux_r_gain;
744
745 bool spkr_pa_widget_on;
746 struct regulator *spkdrv_reg;
747 struct regulator *spkdrv2_reg;
748
749 bool mbhc_started;
750 /* class h specific data */
751 struct wcd_clsh_cdc_data clsh_d;
752
753 struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
754
755 /*
756 * list used to save/restore registers at start and
757 * end of impedance measurement
758 */
759 struct list_head reg_save_restore;
760
761 /* handle to cpe core */
762 struct wcd_cpe_core *cpe_core;
763 u32 current_cpe_clk_freq;
764 enum tasha_sido_voltage sido_voltage;
765 int sido_ccl_cnt;
766
767 u32 ana_rx_supplies;
768 /* Multiplication factor used for impedance detection */
769 int zdet_gain_mul_fact;
770
771 /* to track the status */
772 unsigned long status_mask;
773
774 struct work_struct tasha_add_child_devices_work;
775 struct wcd_swr_ctrl_platform_data swr_plat_data;
776
777 /* Port values for Rx and Tx codec_dai */
778 unsigned int rx_port_value[TASHA_RX_MAX];
779 unsigned int tx_port_value;
780
781 unsigned int vi_feed_value;
782 /* Tasha Interpolator Mode Select for EAR, HPH_L and HPH_R */
783 u32 hph_mode;
784
785 u16 prim_int_users[TASHA_NUM_INTERPOLATORS];
786 int spl_src_users[SPLINE_SRC_MAX];
787
788 struct wcd9xxx_resmgr_v2 *resmgr;
789 struct delayed_work power_gate_work;
790 struct mutex power_lock;
791 struct mutex sido_lock;
792
793 /* mbhc module */
794 struct wcd_mbhc mbhc;
795 struct blocking_notifier_head notifier;
796 struct mutex micb_lock;
797
798 struct clk *wcd_ext_clk;
799 struct clk *wcd_native_clk;
800 struct mutex swr_read_lock;
801 struct mutex swr_write_lock;
802 struct mutex swr_clk_lock;
803 int swr_clk_users;
804 int native_clk_users;
Meng Wang15c825d2018-09-06 10:49:18 +0800805 int (*zdet_gpio_cb)(struct snd_soc_component *component, bool high);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530806
807 struct snd_info_entry *entry;
808 struct snd_info_entry *version_entry;
809 int power_active_ref;
810
811 struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
812
Meng Wang15c825d2018-09-06 10:49:18 +0800813 int (*machine_codec_event_cb)(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530814 enum wcd9335_codec_event);
815 int spkr_gain_offset;
816 int spkr_mode;
817 int ear_spkr_gain;
818 struct hpf_work tx_hpf_work[TASHA_NUM_DECIMATORS];
819 struct tx_mute_work tx_mute_dwork[TASHA_NUM_DECIMATORS];
820 struct spk_anc_work spk_anc_dwork;
821 struct mutex codec_mutex;
822 int hph_l_gain;
823 int hph_r_gain;
824 int rx_7_count;
825 int rx_8_count;
826 bool clk_mode;
827 bool clk_internal;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +0530828 /* Lock to prevent multiple functions voting at same time */
829 struct mutex sb_clk_gear_lock;
830 /* Count for functions voting or un-voting */
831 u32 ref_count;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530832 /* Lock to protect mclk enablement */
833 struct mutex mclk_lock;
Meng Wang3b194492017-09-27 12:20:22 +0800834
835 struct platform_device *pdev_child_devices
836 [WCD9335_CHILD_DEVICES_MAX];
837 int child_count;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530838};
839
Meng Wang15c825d2018-09-06 10:49:18 +0800840static int tasha_codec_vote_max_bw(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530841 bool vote);
842
843static const struct tasha_reg_mask_val tasha_spkr_default[] = {
844 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
845 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
846 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
847 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
Xiaojun Sang09cd2ac2018-02-12 19:03:02 +0800848 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x58},
849 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x58},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530850};
851
852static const struct tasha_reg_mask_val tasha_spkr_mode1[] = {
853 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x00},
854 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x00},
855 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x00},
856 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x00},
857 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44},
858 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44},
859};
860
861/**
862 * tasha_set_spkr_gain_offset - offset the speaker path
863 * gain with the given offset value.
864 *
Meng Wang15c825d2018-09-06 10:49:18 +0800865 * @component: codec component instance
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530866 * @offset: Indicates speaker path gain offset value.
867 *
868 * Returns 0 on success or -EINVAL on error.
869 */
Meng Wang15c825d2018-09-06 10:49:18 +0800870int tasha_set_spkr_gain_offset(struct snd_soc_component *component, int offset)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530871{
Meng Wang15c825d2018-09-06 10:49:18 +0800872 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530873
874 if (!priv)
875 return -EINVAL;
876
877 priv->spkr_gain_offset = offset;
878 return 0;
879}
880EXPORT_SYMBOL(tasha_set_spkr_gain_offset);
881
882/**
883 * tasha_set_spkr_mode - Configures speaker compander and smartboost
884 * settings based on speaker mode.
885 *
Meng Wang15c825d2018-09-06 10:49:18 +0800886 * @component: codec component instance
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530887 * @mode: Indicates speaker configuration mode.
888 *
889 * Returns 0 on success or -EINVAL on error.
890 */
Meng Wang15c825d2018-09-06 10:49:18 +0800891int tasha_set_spkr_mode(struct snd_soc_component *component, int mode)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530892{
Meng Wang15c825d2018-09-06 10:49:18 +0800893 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530894 int i;
895 const struct tasha_reg_mask_val *regs;
896 int size;
897
898 if (!priv)
899 return -EINVAL;
900
901 switch (mode) {
902 case SPKR_MODE_1:
903 regs = tasha_spkr_mode1;
904 size = ARRAY_SIZE(tasha_spkr_mode1);
905 break;
906 default:
907 regs = tasha_spkr_default;
908 size = ARRAY_SIZE(tasha_spkr_default);
909 break;
910 }
911
912 priv->spkr_mode = mode;
913 for (i = 0; i < size; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800914 snd_soc_component_update_bits(component, regs[i].reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530915 regs[i].mask, regs[i].val);
916 return 0;
917}
918EXPORT_SYMBOL(tasha_set_spkr_mode);
919
Meng Wang15c825d2018-09-06 10:49:18 +0800920static void tasha_enable_sido_buck(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530921{
Meng Wang15c825d2018-09-06 10:49:18 +0800922 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530923
Meng Wang15c825d2018-09-06 10:49:18 +0800924 snd_soc_component_update_bits(component, WCD9335_ANA_RCO, 0x80, 0x80);
925 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
926 0x02, 0x02);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530927 /* 100us sleep needed after IREF settings */
928 usleep_range(100, 110);
Meng Wang15c825d2018-09-06 10:49:18 +0800929 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
930 0x04, 0x04);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530931 /* 100us sleep needed after VREF settings */
932 usleep_range(100, 110);
933 tasha->resmgr->sido_input_src = SIDO_SOURCE_RCO_BG;
934}
935
936static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag)
937{
Meng Wang15c825d2018-09-06 10:49:18 +0800938 struct snd_soc_component *component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530939
Meng Wang15c825d2018-09-06 10:49:18 +0800940 if (!component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530941 return;
942
943 if (!TASHA_IS_2_0(tasha->wcd9xxx)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800944 dev_dbg(component->dev, "%s: tasha version < 2p0, return\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530945 __func__);
946 return;
947 }
Meng Wang15c825d2018-09-06 10:49:18 +0800948 dev_dbg(component->dev, "%s: sido_ccl_cnt=%d, ccl_flag:%d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530949 __func__, tasha->sido_ccl_cnt, ccl_flag);
950 if (ccl_flag) {
951 if (++tasha->sido_ccl_cnt == 1)
Meng Wang15c825d2018-09-06 10:49:18 +0800952 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530953 WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x6E);
954 } else {
955 if (tasha->sido_ccl_cnt == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +0800956 dev_dbg(component->dev, "%s: sido_ccl already disabled\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530957 __func__);
958 return;
959 }
960 if (--tasha->sido_ccl_cnt == 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800961 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530962 WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x02);
963 }
964}
965
966static bool tasha_cdc_is_svs_enabled(struct tasha_priv *tasha)
967{
968 if (TASHA_IS_2_0(tasha->wcd9xxx) &&
969 svs_scaling_enabled)
970 return true;
971
972 return false;
973}
974
975static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha,
976 bool enable)
977{
978 int ret = 0;
979
980 mutex_lock(&tasha->mclk_lock);
981 if (enable) {
982 tasha_cdc_sido_ccl_enable(tasha, true);
983 ret = clk_prepare_enable(tasha->wcd_ext_clk);
984 if (ret) {
985 dev_err(tasha->dev, "%s: ext clk enable failed\n",
986 __func__);
987 goto unlock_mutex;
988 }
989 /* get BG */
990 wcd_resmgr_enable_master_bias(tasha->resmgr);
991 /* get MCLK */
992 wcd_resmgr_enable_clk_block(tasha->resmgr, WCD_CLK_MCLK);
993 } else {
994 /* put MCLK */
995 wcd_resmgr_disable_clk_block(tasha->resmgr, WCD_CLK_MCLK);
996 /* put BG */
997 wcd_resmgr_disable_master_bias(tasha->resmgr);
998 clk_disable_unprepare(tasha->wcd_ext_clk);
999 tasha_cdc_sido_ccl_enable(tasha, false);
1000 }
1001unlock_mutex:
1002 mutex_unlock(&tasha->mclk_lock);
1003 return ret;
1004}
1005
1006static int tasha_cdc_check_sido_value(enum tasha_sido_voltage req_mv)
1007{
1008 if ((req_mv != SIDO_VOLTAGE_SVS_MV) &&
1009 (req_mv != SIDO_VOLTAGE_NOMINAL_MV))
1010 return -EINVAL;
1011
1012 return 0;
1013}
1014
1015static void tasha_codec_apply_sido_voltage(
1016 struct tasha_priv *tasha,
1017 enum tasha_sido_voltage req_mv)
1018{
1019 u32 vout_d_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001020 struct snd_soc_component *component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301021 int ret;
1022
Meng Wang15c825d2018-09-06 10:49:18 +08001023 if (!component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301024 return;
1025
1026 if (!tasha_cdc_is_svs_enabled(tasha))
1027 return;
1028
1029 if ((sido_buck_svs_voltage != SIDO_VOLTAGE_SVS_MV) &&
1030 (sido_buck_svs_voltage != SIDO_VOLTAGE_NOMINAL_MV))
1031 sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV;
1032
1033 ret = tasha_cdc_check_sido_value(req_mv);
1034 if (ret < 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001035 dev_dbg(component->dev, "%s: requested mv=%d not in range\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301036 __func__, req_mv);
1037 return;
1038 }
1039 if (req_mv == tasha->sido_voltage) {
Meng Wang15c825d2018-09-06 10:49:18 +08001040 dev_dbg(component->dev, "%s: Already at requested mv=%d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301041 __func__, req_mv);
1042 return;
1043 }
1044 if (req_mv == sido_buck_svs_voltage) {
1045 if (test_bit(AUDIO_NOMINAL, &tasha->status_mask) ||
1046 test_bit(CPE_NOMINAL, &tasha->status_mask)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001047 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301048 "%s: nominal client running, status_mask=%lu\n",
1049 __func__, tasha->status_mask);
1050 return;
1051 }
1052 }
1053 /* compute the vout_d step value */
1054 vout_d_val = CALCULATE_VOUT_D(req_mv);
Meng Wang15c825d2018-09-06 10:49:18 +08001055 snd_soc_component_write(component, WCD9335_ANA_BUCK_VOUT_D,
1056 vout_d_val & 0xFF);
1057 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
1058 0x80, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301059
1060 /* 1 msec sleep required after SIDO Vout_D voltage change */
1061 usleep_range(1000, 1100);
1062 tasha->sido_voltage = req_mv;
Meng Wang15c825d2018-09-06 10:49:18 +08001063 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301064 "%s: updated SIDO buck Vout_D to %d, vout_d step = %u\n",
1065 __func__, tasha->sido_voltage, vout_d_val);
1066
Meng Wang15c825d2018-09-06 10:49:18 +08001067 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301068 0x80, 0x00);
1069}
1070
1071static int tasha_codec_update_sido_voltage(
1072 struct tasha_priv *tasha,
1073 enum tasha_sido_voltage req_mv)
1074{
1075 int ret = 0;
1076
1077 if (!tasha_cdc_is_svs_enabled(tasha))
1078 return ret;
1079
1080 mutex_lock(&tasha->sido_lock);
1081 /* enable mclk before setting SIDO voltage */
1082 ret = tasha_cdc_req_mclk_enable(tasha, true);
1083 if (ret) {
1084 dev_err(tasha->dev, "%s: ext clk enable failed\n",
1085 __func__);
1086 goto err;
1087 }
1088 tasha_codec_apply_sido_voltage(tasha, req_mv);
1089 tasha_cdc_req_mclk_enable(tasha, false);
1090
1091err:
1092 mutex_unlock(&tasha->sido_lock);
1093 return ret;
1094}
1095
Meng Wang15c825d2018-09-06 10:49:18 +08001096int tasha_enable_efuse_sensing(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301097{
Meng Wang15c825d2018-09-06 10:49:18 +08001098 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301099
Meng Wang15c825d2018-09-06 10:49:18 +08001100 tasha_cdc_mclk_enable(component, true, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301101
1102 if (!TASHA_IS_2_0(priv->wcd9xxx))
Meng Wang15c825d2018-09-06 10:49:18 +08001103 snd_soc_component_update_bits(component,
1104 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
1105 0x1E, 0x02);
1106 snd_soc_component_update_bits(component,
1107 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
1108 0x01, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301109 /*
1110 * 5ms sleep required after enabling efuse control
1111 * before checking the status.
1112 */
1113 usleep_range(5000, 5500);
Meng Wang15c825d2018-09-06 10:49:18 +08001114 if (!(snd_soc_component_read32(
1115 component, WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301116 WARN(1, "%s: Efuse sense is not complete\n", __func__);
1117
1118 if (TASHA_IS_2_0(priv->wcd9xxx)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001119 if (!(snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301120 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0) & 0x40))
Meng Wang15c825d2018-09-06 10:49:18 +08001121 snd_soc_component_update_bits(component,
1122 WCD9335_HPH_R_ATEST,
1123 0x04, 0x00);
1124 tasha_enable_sido_buck(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301125 }
1126
Meng Wang15c825d2018-09-06 10:49:18 +08001127 tasha_cdc_mclk_enable(component, false, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301128
1129 return 0;
1130}
1131EXPORT_SYMBOL(tasha_enable_efuse_sensing);
1132
Meng Wang15c825d2018-09-06 10:49:18 +08001133void *tasha_get_afe_config(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301134 enum afe_config_type config_type)
1135{
Meng Wang15c825d2018-09-06 10:49:18 +08001136 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301137
1138 switch (config_type) {
1139 case AFE_SLIMBUS_SLAVE_CONFIG:
1140 return &priv->slimbus_slave_cfg;
1141 case AFE_CDC_REGISTERS_CONFIG:
1142 return &tasha_audio_reg_cfg;
1143 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
1144 return &tasha_slimbus_slave_port_cfg;
1145 case AFE_AANC_VERSION:
1146 return &tasha_cdc_aanc_version;
1147 case AFE_CLIP_BANK_SEL:
1148 return NULL;
1149 case AFE_CDC_CLIP_REGISTERS_CONFIG:
1150 return NULL;
1151 case AFE_CDC_REGISTER_PAGE_CONFIG:
1152 return &tasha_cdc_reg_page_cfg;
1153 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001154 dev_err(component->dev, "%s: Unknown config_type 0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301155 __func__, config_type);
1156 return NULL;
1157 }
1158}
1159EXPORT_SYMBOL(tasha_get_afe_config);
1160
1161/*
1162 * tasha_event_register: Registers a machine driver callback
1163 * function with codec private data for post ADSP sub-system
1164 * restart (SSR). This callback function will be called from
1165 * codec driver once codec comes out of reset after ADSP SSR.
1166 *
1167 * @machine_event_cb: callback function from machine driver
Meng Wang15c825d2018-09-06 10:49:18 +08001168 * @component: Codec component instance
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301169 *
1170 * Return: none
1171 */
1172void tasha_event_register(
Meng Wang15c825d2018-09-06 10:49:18 +08001173 int (*machine_event_cb)(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301174 enum wcd9335_codec_event),
Meng Wang15c825d2018-09-06 10:49:18 +08001175 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301176{
Meng Wang15c825d2018-09-06 10:49:18 +08001177 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301178
1179 if (tasha)
1180 tasha->machine_codec_event_cb = machine_event_cb;
1181 else
Meng Wang15c825d2018-09-06 10:49:18 +08001182 dev_dbg(component->dev, "%s: Invalid tasha_priv data\n",
1183 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301184}
1185EXPORT_SYMBOL(tasha_event_register);
1186
Meng Wang15c825d2018-09-06 10:49:18 +08001187static int tasha_mbhc_request_irq(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301188 int irq, irq_handler_t handler,
1189 const char *name, void *data)
1190{
Meng Wang15c825d2018-09-06 10:49:18 +08001191 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301192 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1193 struct wcd9xxx_core_resource *core_res =
1194 &wcd9xxx->core_res;
1195
1196 return wcd9xxx_request_irq(core_res, irq, handler, name, data);
1197}
1198
Meng Wang15c825d2018-09-06 10:49:18 +08001199static void tasha_mbhc_irq_control(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301200 int irq, bool enable)
1201{
Meng Wang15c825d2018-09-06 10:49:18 +08001202 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301203 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1204 struct wcd9xxx_core_resource *core_res =
1205 &wcd9xxx->core_res;
1206 if (enable)
1207 wcd9xxx_enable_irq(core_res, irq);
1208 else
1209 wcd9xxx_disable_irq(core_res, irq);
1210}
1211
Meng Wang15c825d2018-09-06 10:49:18 +08001212static int tasha_mbhc_free_irq(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301213 int irq, void *data)
1214{
Meng Wang15c825d2018-09-06 10:49:18 +08001215 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301216 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1217 struct wcd9xxx_core_resource *core_res =
1218 &wcd9xxx->core_res;
1219
1220 wcd9xxx_free_irq(core_res, irq, data);
1221 return 0;
1222}
1223
Meng Wang15c825d2018-09-06 10:49:18 +08001224static void tasha_mbhc_clk_setup(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301225 bool enable)
1226{
1227 if (enable)
Meng Wang15c825d2018-09-06 10:49:18 +08001228 snd_soc_component_update_bits(component, WCD9335_MBHC_CTL_1,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301229 0x80, 0x80);
1230 else
Meng Wang15c825d2018-09-06 10:49:18 +08001231 snd_soc_component_update_bits(component, WCD9335_MBHC_CTL_1,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301232 0x80, 0x00);
1233}
1234
Meng Wang15c825d2018-09-06 10:49:18 +08001235static int tasha_mbhc_btn_to_num(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301236{
Meng Wang15c825d2018-09-06 10:49:18 +08001237 return snd_soc_component_read32(
1238 component, WCD9335_ANA_MBHC_RESULT_3) & 0x7;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301239}
1240
Meng Wang15c825d2018-09-06 10:49:18 +08001241static void tasha_mbhc_mbhc_bias_control(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301242 bool enable)
1243{
1244 if (enable)
Meng Wang15c825d2018-09-06 10:49:18 +08001245 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_ELECT,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301246 0x01, 0x01);
1247 else
Meng Wang15c825d2018-09-06 10:49:18 +08001248 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_ELECT,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301249 0x01, 0x00);
1250}
1251
Meng Wang15c825d2018-09-06 10:49:18 +08001252static void tasha_mbhc_program_btn_thr(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301253 s16 *btn_low, s16 *btn_high,
1254 int num_btn, bool is_micbias)
1255{
1256 int i;
1257 int vth;
1258
1259 if (num_btn > WCD_MBHC_DEF_BUTTONS) {
Meng Wang15c825d2018-09-06 10:49:18 +08001260 dev_err(component->dev, "%s: invalid number of buttons: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301261 __func__, num_btn);
1262 return;
1263 }
1264 /*
1265 * Tasha just needs one set of thresholds for button detection
1266 * due to micbias voltage ramp to pullup upon button press. So
1267 * btn_low and is_micbias are ignored and always program button
1268 * thresholds using btn_high.
1269 */
1270 for (i = 0; i < num_btn; i++) {
1271 vth = ((btn_high[i] * 2) / 25) & 0x3F;
Meng Wang15c825d2018-09-06 10:49:18 +08001272 snd_soc_component_update_bits(
1273 component, WCD9335_ANA_MBHC_BTN0 + i,
1274 0xFC, vth << 2);
1275 dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301276 __func__, i, btn_high[i], vth);
1277 }
1278}
1279
1280static bool tasha_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock)
1281{
Meng Wang15c825d2018-09-06 10:49:18 +08001282 struct snd_soc_component *component = mbhc->component;
1283 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301284 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1285 struct wcd9xxx_core_resource *core_res =
1286 &wcd9xxx->core_res;
1287 if (lock)
1288 return wcd9xxx_lock_sleep(core_res);
1289 else {
1290 wcd9xxx_unlock_sleep(core_res);
1291 return 0;
1292 }
1293}
1294
1295static int tasha_mbhc_register_notifier(struct wcd_mbhc *mbhc,
1296 struct notifier_block *nblock,
1297 bool enable)
1298{
Meng Wang15c825d2018-09-06 10:49:18 +08001299 struct snd_soc_component *component = mbhc->component;
1300 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301301
1302 if (enable)
1303 return blocking_notifier_chain_register(&tasha->notifier,
1304 nblock);
1305 else
1306 return blocking_notifier_chain_unregister(&tasha->notifier,
1307 nblock);
1308}
1309
1310static bool tasha_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num)
1311{
1312 u8 val;
1313
1314 if (micb_num == MIC_BIAS_2) {
Meng Wang15c825d2018-09-06 10:49:18 +08001315 val = (snd_soc_component_read32(
1316 mbhc->component, WCD9335_ANA_MICB2) >> 6);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301317 if (val == 0x01)
1318 return true;
1319 }
1320 return false;
1321}
1322
Meng Wang15c825d2018-09-06 10:49:18 +08001323static bool tasha_mbhc_hph_pa_on_status(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301324{
Meng Wang15c825d2018-09-06 10:49:18 +08001325 return (snd_soc_component_read32(component, WCD9335_ANA_HPH) & 0xC0) ?
1326 true : false;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301327}
1328
Meng Wang15c825d2018-09-06 10:49:18 +08001329static void tasha_mbhc_hph_l_pull_up_control(
1330 struct snd_soc_component *component,
1331 enum mbhc_hs_pullup_iref pull_up_cur)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301332{
Meng Wang15c825d2018-09-06 10:49:18 +08001333 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301334
1335 if (!tasha)
1336 return;
1337
1338 /* Default pull up current to 2uA */
1339 if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA ||
1340 pull_up_cur == I_DEFAULT)
1341 pull_up_cur = I_2P0_UA;
1342
Meng Wang15c825d2018-09-06 10:49:18 +08001343 dev_dbg(component->dev, "%s: HS pull up current:%d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301344 __func__, pull_up_cur);
1345
1346 if (TASHA_IS_2_0(tasha->wcd9xxx))
Meng Wang15c825d2018-09-06 10:49:18 +08001347 snd_soc_component_update_bits(component,
1348 WCD9335_MBHC_PLUG_DETECT_CTL,
1349 0xC0, pull_up_cur << 6);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301350 else
Meng Wang15c825d2018-09-06 10:49:18 +08001351 snd_soc_component_update_bits(component,
1352 WCD9335_MBHC_PLUG_DETECT_CTL,
1353 0xC0, 0x40);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301354}
1355
1356static int tasha_enable_ext_mb_source(struct wcd_mbhc *mbhc,
1357 bool turn_on)
1358{
Meng Wang15c825d2018-09-06 10:49:18 +08001359 struct snd_soc_component *component = mbhc->component;
1360 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301361 int ret = 0;
1362 struct on_demand_supply *supply;
1363
1364 if (!tasha)
1365 return -EINVAL;
1366
1367 supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS];
1368 if (!supply->supply) {
Meng Wang15c825d2018-09-06 10:49:18 +08001369 dev_dbg(component->dev, "%s: warning supply not present ond for %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301370 __func__, "onDemand Micbias");
1371 return ret;
1372 }
1373
Meng Wang15c825d2018-09-06 10:49:18 +08001374 dev_dbg(component->dev, "%s turn_on: %d count: %d\n", __func__, turn_on,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301375 supply->ondemand_supply_count);
1376
1377 if (turn_on) {
1378 if (!(supply->ondemand_supply_count)) {
1379 ret = snd_soc_dapm_force_enable_pin(
Meng Wang15c825d2018-09-06 10:49:18 +08001380 snd_soc_component_get_dapm(component),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301381 "MICBIAS_REGULATOR");
Meng Wang15c825d2018-09-06 10:49:18 +08001382 snd_soc_dapm_sync(
1383 snd_soc_component_get_dapm(component));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301384 }
1385 supply->ondemand_supply_count++;
1386 } else {
1387 if (supply->ondemand_supply_count > 0)
1388 supply->ondemand_supply_count--;
1389 if (!(supply->ondemand_supply_count)) {
1390 ret = snd_soc_dapm_disable_pin(
Meng Wang15c825d2018-09-06 10:49:18 +08001391 snd_soc_component_get_dapm(component),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301392 "MICBIAS_REGULATOR");
Meng Wang15c825d2018-09-06 10:49:18 +08001393 snd_soc_dapm_sync(snd_soc_component_get_dapm(component));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301394 }
1395 }
1396
1397 if (ret)
Meng Wang15c825d2018-09-06 10:49:18 +08001398 dev_err(component->dev, "%s: Failed to %s external micbias source\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301399 __func__, turn_on ? "enable" : "disabled");
1400 else
Meng Wang15c825d2018-09-06 10:49:18 +08001401 dev_dbg(component->dev, "%s: %s external micbias source\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301402 __func__, turn_on ? "Enabled" : "Disabled");
1403
1404 return ret;
1405}
1406
Meng Wang15c825d2018-09-06 10:49:18 +08001407static int tasha_micbias_control(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301408 int micb_num,
1409 int req, bool is_dapm)
1410{
Meng Wang15c825d2018-09-06 10:49:18 +08001411 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301412 int micb_index = micb_num - 1;
1413 u16 micb_reg;
1414 int pre_off_event = 0, post_off_event = 0;
1415 int post_on_event = 0, post_dapm_off = 0;
1416 int post_dapm_on = 0;
1417
1418 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001419 dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301420 __func__, micb_index);
1421 return -EINVAL;
1422 }
1423 switch (micb_num) {
1424 case MIC_BIAS_1:
1425 micb_reg = WCD9335_ANA_MICB1;
1426 break;
1427 case MIC_BIAS_2:
1428 micb_reg = WCD9335_ANA_MICB2;
1429 pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF;
1430 post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF;
1431 post_on_event = WCD_EVENT_POST_MICBIAS_2_ON;
1432 post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON;
1433 post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF;
1434 break;
1435 case MIC_BIAS_3:
1436 micb_reg = WCD9335_ANA_MICB3;
1437 break;
1438 case MIC_BIAS_4:
1439 micb_reg = WCD9335_ANA_MICB4;
1440 break;
1441 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001442 dev_err(component->dev, "%s: Invalid micbias number: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301443 __func__, micb_num);
1444 return -EINVAL;
1445 }
1446 mutex_lock(&tasha->micb_lock);
1447
1448 switch (req) {
1449 case MICB_PULLUP_ENABLE:
1450 tasha->pullup_ref[micb_index]++;
1451 if ((tasha->pullup_ref[micb_index] == 1) &&
1452 (tasha->micb_ref[micb_index] == 0))
Meng Wang15c825d2018-09-06 10:49:18 +08001453 snd_soc_component_update_bits(component, micb_reg,
1454 0xC0, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301455 break;
1456 case MICB_PULLUP_DISABLE:
1457 if (tasha->pullup_ref[micb_index] > 0)
1458 tasha->pullup_ref[micb_index]--;
1459 if ((tasha->pullup_ref[micb_index] == 0) &&
1460 (tasha->micb_ref[micb_index] == 0))
Meng Wang15c825d2018-09-06 10:49:18 +08001461 snd_soc_component_update_bits(component, micb_reg,
1462 0xC0, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301463 break;
1464 case MICB_ENABLE:
1465 tasha->micb_ref[micb_index]++;
1466 if (tasha->micb_ref[micb_index] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001467 snd_soc_component_update_bits(component, micb_reg,
1468 0xC0, 0x40);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301469 if (post_on_event)
1470 blocking_notifier_call_chain(&tasha->notifier,
1471 post_on_event, &tasha->mbhc);
1472 }
1473 if (is_dapm && post_dapm_on)
1474 blocking_notifier_call_chain(&tasha->notifier,
1475 post_dapm_on, &tasha->mbhc);
1476 break;
1477 case MICB_DISABLE:
1478 if (tasha->micb_ref[micb_index] > 0)
1479 tasha->micb_ref[micb_index]--;
1480 if ((tasha->micb_ref[micb_index] == 0) &&
1481 (tasha->pullup_ref[micb_index] > 0))
Meng Wang15c825d2018-09-06 10:49:18 +08001482 snd_soc_component_update_bits(component, micb_reg,
1483 0xC0, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301484 else if ((tasha->micb_ref[micb_index] == 0) &&
1485 (tasha->pullup_ref[micb_index] == 0)) {
1486 if (pre_off_event)
1487 blocking_notifier_call_chain(&tasha->notifier,
1488 pre_off_event, &tasha->mbhc);
Meng Wang15c825d2018-09-06 10:49:18 +08001489 snd_soc_component_update_bits(component, micb_reg,
1490 0xC0, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301491 if (post_off_event)
1492 blocking_notifier_call_chain(&tasha->notifier,
1493 post_off_event, &tasha->mbhc);
1494 }
1495 if (is_dapm && post_dapm_off)
1496 blocking_notifier_call_chain(&tasha->notifier,
1497 post_dapm_off, &tasha->mbhc);
1498 break;
1499 };
1500
Meng Wang15c825d2018-09-06 10:49:18 +08001501 dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301502 __func__, micb_num, tasha->micb_ref[micb_index],
1503 tasha->pullup_ref[micb_index]);
1504
1505 mutex_unlock(&tasha->micb_lock);
1506
1507 return 0;
1508}
1509
Meng Wang15c825d2018-09-06 10:49:18 +08001510static int tasha_mbhc_request_micbias(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301511 int micb_num, int req)
1512{
1513 int ret;
1514
1515 /*
1516 * If micbias is requested, make sure that there
1517 * is vote to enable mclk
1518 */
1519 if (req == MICB_ENABLE)
Meng Wang15c825d2018-09-06 10:49:18 +08001520 tasha_cdc_mclk_enable(component, true, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301521
Meng Wang15c825d2018-09-06 10:49:18 +08001522 ret = tasha_micbias_control(component, micb_num, req, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301523
1524 /*
1525 * Release vote for mclk while requesting for
1526 * micbias disable
1527 */
1528 if (req == MICB_DISABLE)
Meng Wang15c825d2018-09-06 10:49:18 +08001529 tasha_cdc_mclk_enable(component, false, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301530
1531 return ret;
1532}
1533
Meng Wang15c825d2018-09-06 10:49:18 +08001534static void tasha_mbhc_micb_ramp_control(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301535 bool enable)
1536{
1537 if (enable) {
Meng Wang15c825d2018-09-06 10:49:18 +08001538 snd_soc_component_update_bits(component, WCD9335_ANA_MICB2_RAMP,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301539 0x1C, 0x0C);
Meng Wang15c825d2018-09-06 10:49:18 +08001540 snd_soc_component_update_bits(component, WCD9335_ANA_MICB2_RAMP,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301541 0x80, 0x80);
1542 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001543 snd_soc_component_update_bits(component, WCD9335_ANA_MICB2_RAMP,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301544 0x80, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001545 snd_soc_component_update_bits(component, WCD9335_ANA_MICB2_RAMP,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301546 0x1C, 0x00);
1547 }
1548}
1549
1550static struct firmware_cal *tasha_get_hwdep_fw_cal(struct wcd_mbhc *mbhc,
1551 enum wcd_cal_type type)
1552{
1553 struct tasha_priv *tasha;
1554 struct firmware_cal *hwdep_cal;
Meng Wang15c825d2018-09-06 10:49:18 +08001555 struct snd_soc_component *component = mbhc->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301556
Meng Wang15c825d2018-09-06 10:49:18 +08001557 if (!component) {
1558 pr_err("%s: NULL component pointer\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301559 return NULL;
1560 }
Meng Wang15c825d2018-09-06 10:49:18 +08001561 tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301562 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, type);
1563 if (!hwdep_cal)
Meng Wang15c825d2018-09-06 10:49:18 +08001564 dev_err(component->dev, "%s: cal not sent by %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301565 __func__, type);
1566
1567 return hwdep_cal;
1568}
1569
Meng Wang15c825d2018-09-06 10:49:18 +08001570static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301571 int req_volt,
1572 int micb_num)
1573{
1574 int cur_vout_ctl, req_vout_ctl;
1575 int micb_reg, micb_val, micb_en;
1576
1577 switch (micb_num) {
1578 case MIC_BIAS_1:
1579 micb_reg = WCD9335_ANA_MICB1;
1580 break;
1581 case MIC_BIAS_2:
1582 micb_reg = WCD9335_ANA_MICB2;
1583 break;
1584 case MIC_BIAS_3:
1585 micb_reg = WCD9335_ANA_MICB3;
1586 break;
1587 case MIC_BIAS_4:
1588 micb_reg = WCD9335_ANA_MICB4;
1589 break;
1590 default:
1591 return -EINVAL;
1592 }
1593
1594 /*
1595 * If requested micbias voltage is same as current micbias
1596 * voltage, then just return. Otherwise, adjust voltage as
1597 * per requested value. If micbias is already enabled, then
1598 * to avoid slow micbias ramp-up or down enable pull-up
1599 * momentarily, change the micbias value and then re-enable
1600 * micbias.
1601 */
Meng Wang15c825d2018-09-06 10:49:18 +08001602 micb_val = snd_soc_component_read32(component, micb_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301603 micb_en = (micb_val & 0xC0) >> 6;
1604 cur_vout_ctl = micb_val & 0x3F;
1605
1606 req_vout_ctl = wcd9335_get_micb_vout_ctl_val(req_volt);
1607 if (req_vout_ctl < 0)
1608 return -EINVAL;
1609 if (cur_vout_ctl == req_vout_ctl)
1610 return 0;
1611
Meng Wang15c825d2018-09-06 10:49:18 +08001612 dev_dbg(component->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301613 __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl),
1614 req_volt, micb_en);
1615
1616 if (micb_en == 0x1)
Meng Wang15c825d2018-09-06 10:49:18 +08001617 snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301618
Meng Wang15c825d2018-09-06 10:49:18 +08001619 snd_soc_component_update_bits(component, micb_reg, 0x3F, req_vout_ctl);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301620
1621 if (micb_en == 0x1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001622 snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x40);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301623 /*
1624 * Add 2ms delay as per HW requirement after enabling
1625 * micbias
1626 */
1627 usleep_range(2000, 2100);
1628 }
1629
1630 return 0;
1631}
1632
Meng Wang15c825d2018-09-06 10:49:18 +08001633static int tasha_mbhc_micb_ctrl_threshold_mic(
1634 struct snd_soc_component *component,
1635 int micb_num, bool req_en)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301636{
Meng Wang15c825d2018-09-06 10:49:18 +08001637 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
1638 struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301639 int rc, micb_mv;
1640
1641 if (micb_num != MIC_BIAS_2)
1642 return -EINVAL;
1643
1644 /*
1645 * If device tree micbias level is already above the minimum
1646 * voltage needed to detect threshold microphone, then do
1647 * not change the micbias, just return.
1648 */
1649 if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
1650 return 0;
1651
1652 micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv;
1653
1654 mutex_lock(&tasha->micb_lock);
Meng Wang15c825d2018-09-06 10:49:18 +08001655 rc = tasha_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301656 mutex_unlock(&tasha->micb_lock);
1657
1658 return rc;
1659}
1660
1661static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx,
1662 s16 *d1_a, u16 noff,
1663 int32_t *zdet)
1664{
1665 int i;
1666 int val, val1;
1667 s16 c1;
1668 s32 x1, d1;
1669 int32_t denom;
1670 int minCode_param[] = {
1671 3277, 1639, 820, 410, 205, 103, 52, 26
1672 };
1673
1674 regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x20);
1675 for (i = 0; i < TASHA_ZDET_NUM_MEASUREMENTS; i++) {
1676 regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_2, &val);
1677 if (val & 0x80)
1678 break;
1679 }
1680 val = val << 0x8;
1681 regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_1, &val1);
1682 val |= val1;
1683 regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x00);
1684 x1 = TASHA_MBHC_GET_X1(val);
1685 c1 = TASHA_MBHC_GET_C1(val);
1686 /* If ramp is not complete, give additional 5ms */
1687 if ((c1 < 2) && x1)
1688 usleep_range(5000, 5050);
1689
1690 if (!c1 || !x1) {
1691 dev_dbg(wcd9xxx->dev,
1692 "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
1693 __func__, c1, x1);
1694 goto ramp_down;
1695 }
1696 d1 = d1_a[c1];
1697 denom = (x1 * d1) - (1 << (14 - noff));
1698 if (denom > 0)
1699 *zdet = (TASHA_MBHC_ZDET_CONST * 1000) / denom;
1700 else if (x1 < minCode_param[noff])
1701 *zdet = TASHA_ZDET_FLOATING_IMPEDANCE;
1702
1703 dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
1704 __func__, d1, c1, x1, *zdet);
1705ramp_down:
1706 i = 0;
1707 while (x1) {
1708 regmap_bulk_read(wcd9xxx->regmap,
1709 WCD9335_ANA_MBHC_RESULT_1, (u8 *)&val, 2);
1710 x1 = TASHA_MBHC_GET_X1(val);
1711 i++;
1712 if (i == TASHA_ZDET_NUM_MEASUREMENTS)
1713 break;
1714 }
1715}
1716
1717/*
1718 * tasha_mbhc_zdet_gpio_ctrl: Register callback function for
1719 * controlling the switch on hifi amps. Default switch state
1720 * will put a 51ohm load in parallel to the hph load. So,
1721 * impedance detection function will pull the gpio high
1722 * to make the switch open.
1723 *
1724 * @zdet_gpio_cb: callback function from machine driver
Meng Wang15c825d2018-09-06 10:49:18 +08001725 * @component: Codec instance
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301726 *
1727 * Return: none
1728 */
1729void tasha_mbhc_zdet_gpio_ctrl(
Meng Wang15c825d2018-09-06 10:49:18 +08001730 int (*zdet_gpio_cb)(
1731 struct snd_soc_component *component, bool high),
1732 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301733{
Meng Wang15c825d2018-09-06 10:49:18 +08001734 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301735
1736 tasha->zdet_gpio_cb = zdet_gpio_cb;
1737}
1738EXPORT_SYMBOL(tasha_mbhc_zdet_gpio_ctrl);
1739
Meng Wang15c825d2018-09-06 10:49:18 +08001740static void tasha_mbhc_zdet_ramp(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301741 struct tasha_mbhc_zdet_param *zdet_param,
1742 int32_t *zl, int32_t *zr, s16 *d1_a)
1743{
Meng Wang15c825d2018-09-06 10:49:18 +08001744 struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301745 int32_t zdet = 0;
1746
Meng Wang15c825d2018-09-06 10:49:18 +08001747 snd_soc_component_update_bits(component, WCD9335_MBHC_ZDET_ANA_CTL,
1748 0x70, zdet_param->ldo_ctl << 4);
1749 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_BTN5, 0xFC,
1750 zdet_param->btn5);
1751 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_BTN6, 0xFC,
1752 zdet_param->btn6);
1753 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_BTN7, 0xFC,
1754 zdet_param->btn7);
1755 snd_soc_component_update_bits(component, WCD9335_MBHC_ZDET_ANA_CTL,
1756 0x0F, zdet_param->noff);
1757 snd_soc_component_update_bits(component, WCD9335_MBHC_ZDET_RAMP_CTL,
1758 0x0F, zdet_param->nshift);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301759
1760 if (!zl)
1761 goto z_right;
1762 /* Start impedance measurement for HPH_L */
1763 regmap_update_bits(wcd9xxx->regmap,
1764 WCD9335_ANA_MBHC_ZDET, 0x80, 0x80);
1765 dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n",
1766 __func__, zdet_param->noff);
1767 tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet);
1768 regmap_update_bits(wcd9xxx->regmap,
1769 WCD9335_ANA_MBHC_ZDET, 0x80, 0x00);
1770
1771 *zl = zdet;
1772
1773z_right:
1774 if (!zr)
1775 return;
1776 /* Start impedance measurement for HPH_R */
1777 regmap_update_bits(wcd9xxx->regmap,
1778 WCD9335_ANA_MBHC_ZDET, 0x40, 0x40);
1779 dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n",
1780 __func__, zdet_param->noff);
1781 tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet);
1782 regmap_update_bits(wcd9xxx->regmap,
1783 WCD9335_ANA_MBHC_ZDET, 0x40, 0x00);
1784
1785 *zr = zdet;
1786}
1787
Meng Wang15c825d2018-09-06 10:49:18 +08001788static inline void tasha_wcd_mbhc_qfuse_cal(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301789 int32_t *z_val, int flag_l_r)
1790{
1791 s16 q1;
1792 int q1_cal;
1793
1794 if (*z_val < (TASHA_ZDET_VAL_400/1000))
Meng Wang15c825d2018-09-06 10:49:18 +08001795 q1 = snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301796 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r));
1797 else
Meng Wang15c825d2018-09-06 10:49:18 +08001798 q1 = snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301799 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r));
1800 if (q1 & 0x80)
1801 q1_cal = (10000 - ((q1 & 0x7F) * 25));
1802 else
1803 q1_cal = (10000 + (q1 * 25));
1804 if (q1_cal > 0)
1805 *z_val = ((*z_val) * 10000) / q1_cal;
1806}
1807
1808static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
1809 uint32_t *zr)
1810{
Meng Wang15c825d2018-09-06 10:49:18 +08001811 struct snd_soc_component *component = mbhc->component;
1812 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301813 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1814 s16 reg0, reg1, reg2, reg3, reg4;
1815 int32_t z1L, z1R, z1Ls;
1816 int zMono, z_diff1, z_diff2;
1817 bool is_fsm_disable = false;
1818 bool is_change = false;
1819 struct tasha_mbhc_zdet_param zdet_param[] = {
1820 {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
1821 {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
1822 {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
1823 {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
1824 };
1825 struct tasha_mbhc_zdet_param *zdet_param_ptr = NULL;
1826 s16 d1_a[][4] = {
1827 {0, 30, 90, 30},
1828 {0, 30, 30, 5},
1829 {0, 30, 30, 5},
1830 {0, 30, 30, 5},
1831 };
1832 s16 *d1 = NULL;
1833
1834 if (!TASHA_IS_2_0(wcd9xxx)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001835 dev_dbg(component->dev, "%s: Z-det is not supported for this codec version\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301836 __func__);
1837 *zl = 0;
1838 *zr = 0;
1839 return;
1840 }
1841 WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
1842
1843 if (tasha->zdet_gpio_cb)
Meng Wang15c825d2018-09-06 10:49:18 +08001844 is_change = tasha->zdet_gpio_cb(component, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301845
Meng Wang15c825d2018-09-06 10:49:18 +08001846 reg0 = snd_soc_component_read32(component, WCD9335_ANA_MBHC_BTN5);
1847 reg1 = snd_soc_component_read32(component, WCD9335_ANA_MBHC_BTN6);
1848 reg2 = snd_soc_component_read32(component, WCD9335_ANA_MBHC_BTN7);
1849 reg3 = snd_soc_component_read32(component, WCD9335_MBHC_CTL_1);
1850 reg4 = snd_soc_component_read32(component, WCD9335_MBHC_ZDET_ANA_CTL);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301851
Meng Wang15c825d2018-09-06 10:49:18 +08001852 if (snd_soc_component_read32(
1853 component, WCD9335_ANA_MBHC_ELECT) & 0x80) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301854 is_fsm_disable = true;
1855 regmap_update_bits(wcd9xxx->regmap,
1856 WCD9335_ANA_MBHC_ELECT, 0x80, 0x00);
1857 }
1858
1859 /* For NO-jack, disable L_DET_EN before Z-det measurements */
1860 if (mbhc->hphl_swh)
1861 regmap_update_bits(wcd9xxx->regmap,
1862 WCD9335_ANA_MBHC_MECH, 0x80, 0x00);
1863
1864 /* Enable AZ */
Meng Wang15c825d2018-09-06 10:49:18 +08001865 snd_soc_component_update_bits(component, WCD9335_MBHC_CTL_1,
1866 0x0C, 0x04);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301867 /* Turn off 100k pull down on HPHL */
1868 regmap_update_bits(wcd9xxx->regmap,
1869 WCD9335_ANA_MBHC_MECH, 0x01, 0x00);
1870
1871 /* First get impedance on Left */
1872 d1 = d1_a[1];
1873 zdet_param_ptr = &zdet_param[1];
Meng Wang15c825d2018-09-06 10:49:18 +08001874 tasha_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301875
1876 if (!TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
1877 goto left_ch_impedance;
1878
1879 /* second ramp for left ch */
1880 if (z1L < TASHA_ZDET_VAL_32) {
1881 zdet_param_ptr = &zdet_param[0];
1882 d1 = d1_a[0];
1883 } else if ((z1L > TASHA_ZDET_VAL_400) && (z1L <= TASHA_ZDET_VAL_1200)) {
1884 zdet_param_ptr = &zdet_param[2];
1885 d1 = d1_a[2];
1886 } else if (z1L > TASHA_ZDET_VAL_1200) {
1887 zdet_param_ptr = &zdet_param[3];
1888 d1 = d1_a[3];
1889 }
Meng Wang15c825d2018-09-06 10:49:18 +08001890 tasha_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301891
1892left_ch_impedance:
1893 if ((z1L == TASHA_ZDET_FLOATING_IMPEDANCE) ||
1894 (z1L > TASHA_ZDET_VAL_100K)) {
1895 *zl = TASHA_ZDET_FLOATING_IMPEDANCE;
1896 zdet_param_ptr = &zdet_param[1];
1897 d1 = d1_a[1];
1898 } else {
1899 *zl = z1L/1000;
Meng Wang15c825d2018-09-06 10:49:18 +08001900 tasha_wcd_mbhc_qfuse_cal(component, zl, 0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301901 }
Meng Wang15c825d2018-09-06 10:49:18 +08001902 dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301903 __func__, *zl);
1904
1905 /* start of right impedance ramp and calculation */
Meng Wang15c825d2018-09-06 10:49:18 +08001906 tasha_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301907 if (TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
1908 if (((z1R > TASHA_ZDET_VAL_1200) &&
1909 (zdet_param_ptr->noff == 0x6)) ||
1910 ((*zl) != TASHA_ZDET_FLOATING_IMPEDANCE))
1911 goto right_ch_impedance;
1912 /* second ramp for right ch */
1913 if (z1R < TASHA_ZDET_VAL_32) {
1914 zdet_param_ptr = &zdet_param[0];
1915 d1 = d1_a[0];
1916 } else if ((z1R > TASHA_ZDET_VAL_400) &&
1917 (z1R <= TASHA_ZDET_VAL_1200)) {
1918 zdet_param_ptr = &zdet_param[2];
1919 d1 = d1_a[2];
1920 } else if (z1R > TASHA_ZDET_VAL_1200) {
1921 zdet_param_ptr = &zdet_param[3];
1922 d1 = d1_a[3];
1923 }
Meng Wang15c825d2018-09-06 10:49:18 +08001924 tasha_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301925 }
1926right_ch_impedance:
1927 if ((z1R == TASHA_ZDET_FLOATING_IMPEDANCE) ||
1928 (z1R > TASHA_ZDET_VAL_100K)) {
1929 *zr = TASHA_ZDET_FLOATING_IMPEDANCE;
1930 } else {
1931 *zr = z1R/1000;
Meng Wang15c825d2018-09-06 10:49:18 +08001932 tasha_wcd_mbhc_qfuse_cal(component, zr, 1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301933 }
Meng Wang15c825d2018-09-06 10:49:18 +08001934 dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301935 __func__, *zr);
1936
1937 /* mono/stereo detection */
1938 if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) &&
1939 (*zr == TASHA_ZDET_FLOATING_IMPEDANCE)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001940 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301941 "%s: plug type is invalid or extension cable\n",
1942 __func__);
1943 goto zdet_complete;
1944 }
1945 if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) ||
1946 (*zr == TASHA_ZDET_FLOATING_IMPEDANCE) ||
1947 ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
1948 ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
Meng Wang15c825d2018-09-06 10:49:18 +08001949 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301950 "%s: Mono plug type with one ch floating or shorted to GND\n",
1951 __func__);
1952 mbhc->hph_type = WCD_MBHC_HPH_MONO;
1953 goto zdet_complete;
1954 }
Meng Wang15c825d2018-09-06 10:49:18 +08001955 snd_soc_component_update_bits(component, WCD9335_HPH_R_ATEST,
1956 0x02, 0x02);
1957 snd_soc_component_update_bits(component, WCD9335_HPH_PA_CTL2,
1958 0x40, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301959 if (*zl < (TASHA_ZDET_VAL_32/1000))
Meng Wang15c825d2018-09-06 10:49:18 +08001960 tasha_mbhc_zdet_ramp(component, &zdet_param[0],
1961 &z1Ls, NULL, d1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301962 else
Meng Wang15c825d2018-09-06 10:49:18 +08001963 tasha_mbhc_zdet_ramp(component, &zdet_param[1],
1964 &z1Ls, NULL, d1);
1965 snd_soc_component_update_bits(component, WCD9335_HPH_PA_CTL2,
1966 0x40, 0x00);
1967 snd_soc_component_update_bits(component, WCD9335_HPH_R_ATEST,
1968 0x02, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301969 z1Ls /= 1000;
Meng Wang15c825d2018-09-06 10:49:18 +08001970 tasha_wcd_mbhc_qfuse_cal(component, &z1Ls, 0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301971 /* parallel of left Z and 9 ohm pull down resistor */
1972 zMono = ((*zl) * 9) / ((*zl) + 9);
1973 z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
1974 z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
1975 if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
Meng Wang15c825d2018-09-06 10:49:18 +08001976 dev_dbg(component->dev, "%s: stereo plug type detected\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301977 __func__);
1978 mbhc->hph_type = WCD_MBHC_HPH_STEREO;
1979 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001980 dev_dbg(component->dev, "%s: MONO plug type detected\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301981 __func__);
1982 mbhc->hph_type = WCD_MBHC_HPH_MONO;
1983 }
1984
1985zdet_complete:
Meng Wang15c825d2018-09-06 10:49:18 +08001986 snd_soc_component_write(component, WCD9335_ANA_MBHC_BTN5, reg0);
1987 snd_soc_component_write(component, WCD9335_ANA_MBHC_BTN6, reg1);
1988 snd_soc_component_write(component, WCD9335_ANA_MBHC_BTN7, reg2);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301989 /* Turn on 100k pull down on HPHL */
1990 regmap_update_bits(wcd9xxx->regmap,
1991 WCD9335_ANA_MBHC_MECH, 0x01, 0x01);
1992
1993 /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
1994 if (mbhc->hphl_swh)
1995 regmap_update_bits(wcd9xxx->regmap,
1996 WCD9335_ANA_MBHC_MECH, 0x80, 0x80);
1997
Meng Wang15c825d2018-09-06 10:49:18 +08001998 snd_soc_component_write(component, WCD9335_MBHC_ZDET_ANA_CTL, reg4);
1999 snd_soc_component_write(component, WCD9335_MBHC_CTL_1, reg3);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302000 if (is_fsm_disable)
2001 regmap_update_bits(wcd9xxx->regmap,
2002 WCD9335_ANA_MBHC_ELECT, 0x80, 0x80);
2003 if (tasha->zdet_gpio_cb && is_change)
Meng Wang15c825d2018-09-06 10:49:18 +08002004 tasha->zdet_gpio_cb(component, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302005}
2006
Meng Wang15c825d2018-09-06 10:49:18 +08002007static void tasha_mbhc_gnd_det_ctrl(
2008 struct snd_soc_component *component, bool enable)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302009{
2010 if (enable) {
Meng Wang15c825d2018-09-06 10:49:18 +08002011 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302012 0x02, 0x02);
Meng Wang15c825d2018-09-06 10:49:18 +08002013 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302014 0x40, 0x40);
2015 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08002016 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302017 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002018 snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302019 0x02, 0x00);
2020 }
2021}
2022
Meng Wang15c825d2018-09-06 10:49:18 +08002023static void tasha_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302024 bool enable)
2025{
Meng Wang15c825d2018-09-06 10:49:18 +08002026 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302027
2028 if (enable) {
Meng Wang15c825d2018-09-06 10:49:18 +08002029 snd_soc_component_update_bits(component, WCD9335_HPH_PA_CTL2,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302030 0x40, 0x40);
2031 if (TASHA_IS_2_0(tasha->wcd9xxx))
Meng Wang15c825d2018-09-06 10:49:18 +08002032 snd_soc_component_update_bits(component,
2033 WCD9335_HPH_PA_CTL2,
2034 0x10, 0x10);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302035 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08002036 snd_soc_component_update_bits(component, WCD9335_HPH_PA_CTL2,
2037 0x40, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302038 if (TASHA_IS_2_0(tasha->wcd9xxx))
Meng Wang15c825d2018-09-06 10:49:18 +08002039 snd_soc_component_update_bits(component,
2040 WCD9335_HPH_PA_CTL2,
2041 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302042 }
2043}
2044
2045static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc)
2046{
Meng Wang15c825d2018-09-06 10:49:18 +08002047 struct snd_soc_component *component = mbhc->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302048
2049 if (mbhc->moist_vref == V_OFF)
2050 return;
2051
2052 /* Donot enable moisture detection if jack type is NC */
2053 if (!mbhc->hphl_swh) {
Meng Wang15c825d2018-09-06 10:49:18 +08002054 dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302055 __func__);
2056 return;
2057 }
2058
Meng Wang15c825d2018-09-06 10:49:18 +08002059 snd_soc_component_update_bits(component, WCD9335_MBHC_CTL_2,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302060 0x0C, mbhc->moist_vref << 2);
Meng Wang15c825d2018-09-06 10:49:18 +08002061 tasha_mbhc_hph_l_pull_up_control(component, mbhc->moist_iref);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302062}
2063
Meng Wang15c825d2018-09-06 10:49:18 +08002064static void tasha_update_anc_state(struct snd_soc_component *component,
2065 bool enable, int anc_num)
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302066{
2067 if (enable)
Meng Wang15c825d2018-09-06 10:49:18 +08002068 snd_soc_component_update_bits(component,
2069 WCD9335_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num),
2070 0x10, 0x10);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302071 else
Meng Wang15c825d2018-09-06 10:49:18 +08002072 snd_soc_component_update_bits(component,
2073 WCD9335_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num),
2074 0x10, 0x00);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302075}
2076
2077static bool tasha_is_anc_on(struct wcd_mbhc *mbhc)
2078{
2079 bool anc_on = false;
2080 u16 ancl, ancr;
2081
2082 ancl =
Meng Wang15c825d2018-09-06 10:49:18 +08002083 (snd_soc_component_read32(
2084 mbhc->component, WCD9335_CDC_RX1_RX_PATH_CFG0)) & 0x10;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302085 ancr =
Meng Wang15c825d2018-09-06 10:49:18 +08002086 (snd_soc_component_read32(
2087 mbhc->component, WCD9335_CDC_RX2_RX_PATH_CFG0)) & 0x10;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302088
2089 anc_on = !!(ancl | ancr);
2090
2091 return anc_on;
2092}
2093
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302094static const struct wcd_mbhc_cb mbhc_cb = {
2095 .request_irq = tasha_mbhc_request_irq,
2096 .irq_control = tasha_mbhc_irq_control,
2097 .free_irq = tasha_mbhc_free_irq,
2098 .clk_setup = tasha_mbhc_clk_setup,
2099 .map_btn_code_to_num = tasha_mbhc_btn_to_num,
2100 .enable_mb_source = tasha_enable_ext_mb_source,
2101 .mbhc_bias = tasha_mbhc_mbhc_bias_control,
2102 .set_btn_thr = tasha_mbhc_program_btn_thr,
2103 .lock_sleep = tasha_mbhc_lock_sleep,
2104 .register_notifier = tasha_mbhc_register_notifier,
2105 .micbias_enable_status = tasha_mbhc_micb_en_status,
2106 .hph_pa_on_status = tasha_mbhc_hph_pa_on_status,
2107 .hph_pull_up_control = tasha_mbhc_hph_l_pull_up_control,
2108 .mbhc_micbias_control = tasha_mbhc_request_micbias,
2109 .mbhc_micb_ramp_control = tasha_mbhc_micb_ramp_control,
2110 .get_hwdep_fw_cal = tasha_get_hwdep_fw_cal,
2111 .mbhc_micb_ctrl_thr_mic = tasha_mbhc_micb_ctrl_threshold_mic,
2112 .compute_impedance = tasha_wcd_mbhc_calc_impedance,
2113 .mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl,
2114 .hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl,
2115 .mbhc_moisture_config = tasha_mbhc_moisture_config,
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302116 .update_anc_state = tasha_update_anc_state,
2117 .is_anc_on = tasha_is_anc_on,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302118};
2119
2120static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol,
2121 struct snd_ctl_elem_value *ucontrol)
2122{
Meng Wang15c825d2018-09-06 10:49:18 +08002123 struct snd_soc_component *component =
2124 snd_soc_kcontrol_component(kcontrol);
2125 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302126
2127 ucontrol->value.integer.value[0] = tasha->anc_slot;
2128 return 0;
2129}
2130
2131static int tasha_put_anc_slot(struct snd_kcontrol *kcontrol,
2132 struct snd_ctl_elem_value *ucontrol)
2133{
Meng Wang15c825d2018-09-06 10:49:18 +08002134 struct snd_soc_component *component =
2135 snd_soc_kcontrol_component(kcontrol);
2136 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302137
2138 tasha->anc_slot = ucontrol->value.integer.value[0];
2139 return 0;
2140}
2141
2142static int tasha_get_anc_func(struct snd_kcontrol *kcontrol,
2143 struct snd_ctl_elem_value *ucontrol)
2144{
Meng Wang15c825d2018-09-06 10:49:18 +08002145 struct snd_soc_component *component =
2146 snd_soc_kcontrol_component(kcontrol);
2147 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302148
2149 ucontrol->value.integer.value[0] = (tasha->anc_func == true ? 1 : 0);
2150 return 0;
2151}
2152
2153static int tasha_put_anc_func(struct snd_kcontrol *kcontrol,
2154 struct snd_ctl_elem_value *ucontrol)
2155{
Meng Wang15c825d2018-09-06 10:49:18 +08002156 struct snd_soc_component *component =
2157 snd_soc_kcontrol_component(kcontrol);
2158 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
2159 struct snd_soc_dapm_context *dapm =
2160 snd_soc_component_get_dapm(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302161
2162 mutex_lock(&tasha->codec_mutex);
2163 tasha->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
2164
Meng Wang15c825d2018-09-06 10:49:18 +08002165 dev_dbg(component->dev, "%s: anc_func %x", __func__, tasha->anc_func);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302166
2167 if (tasha->anc_func == true) {
2168 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2 PA");
2169 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2");
2170 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1 PA");
2171 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1");
2172 snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA");
2173 snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
2174 snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA");
2175 snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
2176 snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
2177 snd_soc_dapm_enable_pin(dapm, "ANC EAR");
2178 snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
2179 snd_soc_dapm_disable_pin(dapm, "LINEOUT2");
2180 snd_soc_dapm_disable_pin(dapm, "LINEOUT2 PA");
2181 snd_soc_dapm_disable_pin(dapm, "LINEOUT1");
2182 snd_soc_dapm_disable_pin(dapm, "LINEOUT1 PA");
2183 snd_soc_dapm_disable_pin(dapm, "HPHR");
2184 snd_soc_dapm_disable_pin(dapm, "HPHL");
2185 snd_soc_dapm_disable_pin(dapm, "HPHR PA");
2186 snd_soc_dapm_disable_pin(dapm, "HPHL PA");
2187 snd_soc_dapm_disable_pin(dapm, "EAR PA");
2188 snd_soc_dapm_disable_pin(dapm, "EAR");
2189 } else {
2190 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
2191 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
2192 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
2193 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
2194 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
2195 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
2196 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
2197 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
2198 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
2199 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
2200 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
2201 snd_soc_dapm_enable_pin(dapm, "LINEOUT2");
2202 snd_soc_dapm_enable_pin(dapm, "LINEOUT2 PA");
2203 snd_soc_dapm_enable_pin(dapm, "LINEOUT1");
2204 snd_soc_dapm_enable_pin(dapm, "LINEOUT1 PA");
2205 snd_soc_dapm_enable_pin(dapm, "HPHR");
2206 snd_soc_dapm_enable_pin(dapm, "HPHL");
2207 snd_soc_dapm_enable_pin(dapm, "HPHR PA");
2208 snd_soc_dapm_enable_pin(dapm, "HPHL PA");
2209 snd_soc_dapm_enable_pin(dapm, "EAR PA");
2210 snd_soc_dapm_enable_pin(dapm, "EAR");
2211 }
2212 mutex_unlock(&tasha->codec_mutex);
2213 snd_soc_dapm_sync(dapm);
2214 return 0;
2215}
2216
2217static int tasha_get_clkmode(struct snd_kcontrol *kcontrol,
2218 struct snd_ctl_elem_value *ucontrol)
2219{
Meng Wang15c825d2018-09-06 10:49:18 +08002220 struct snd_soc_component *component =
2221 snd_soc_kcontrol_component(kcontrol);
2222 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302223
2224 ucontrol->value.enumerated.item[0] = tasha->clk_mode;
Meng Wang15c825d2018-09-06 10:49:18 +08002225 dev_dbg(component->dev, "%s: clk_mode: %d\n", __func__,
2226 tasha->clk_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302227
2228 return 0;
2229}
2230
2231static int tasha_put_clkmode(struct snd_kcontrol *kcontrol,
2232 struct snd_ctl_elem_value *ucontrol)
2233{
Meng Wang15c825d2018-09-06 10:49:18 +08002234 struct snd_soc_component *component =
2235 snd_soc_kcontrol_component(kcontrol);
2236 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302237
2238 tasha->clk_mode = ucontrol->value.enumerated.item[0];
Meng Wang15c825d2018-09-06 10:49:18 +08002239 dev_dbg(component->dev, "%s: clk_mode: %d\n", __func__,
2240 tasha->clk_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302241
2242 return 0;
2243}
2244
2245static int tasha_get_iir_enable_audio_mixer(
2246 struct snd_kcontrol *kcontrol,
2247 struct snd_ctl_elem_value *ucontrol)
2248{
Meng Wang15c825d2018-09-06 10:49:18 +08002249 struct snd_soc_component *component =
2250 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302251 int iir_idx = ((struct soc_multi_mixer_control *)
2252 kcontrol->private_value)->reg;
2253 int band_idx = ((struct soc_multi_mixer_control *)
2254 kcontrol->private_value)->shift;
2255 /* IIR filter band registers are at integer multiples of 16 */
2256 u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
2257
Meng Wang15c825d2018-09-06 10:49:18 +08002258 ucontrol->value.integer.value[0] = (
2259 snd_soc_component_read32(component, iir_reg) &
2260 (1 << band_idx)) != 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302261
Meng Wang15c825d2018-09-06 10:49:18 +08002262 dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302263 iir_idx, band_idx,
2264 (uint32_t)ucontrol->value.integer.value[0]);
2265 return 0;
2266}
2267
2268static int tasha_hph_impedance_get(struct snd_kcontrol *kcontrol,
2269 struct snd_ctl_elem_value *ucontrol)
2270{
2271 uint32_t zl, zr;
2272 bool hphr;
2273 struct soc_multi_mixer_control *mc;
Meng Wang15c825d2018-09-06 10:49:18 +08002274 struct snd_soc_component *component =
2275 snd_soc_kcontrol_component(kcontrol);
2276 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302277
2278 mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
2279 hphr = mc->shift;
2280 wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
Meng Wang15c825d2018-09-06 10:49:18 +08002281 dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__,
2282 zl, zr);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302283 ucontrol->value.integer.value[0] = hphr ? zr : zl;
2284
2285 return 0;
2286}
2287
2288static const struct snd_kcontrol_new impedance_detect_controls[] = {
2289 SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
2290 tasha_hph_impedance_get, NULL),
2291 SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
2292 tasha_hph_impedance_get, NULL),
2293};
2294
2295static int tasha_get_hph_type(struct snd_kcontrol *kcontrol,
2296 struct snd_ctl_elem_value *ucontrol)
2297{
Meng Wang15c825d2018-09-06 10:49:18 +08002298 struct snd_soc_component *component =
2299 snd_soc_kcontrol_component(kcontrol);
2300 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302301 struct wcd_mbhc *mbhc;
2302
2303 if (!priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002304 dev_dbg(component->dev, "%s: wcd9335 private data is NULL\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302305 __func__);
2306 return 0;
2307 }
2308
2309 mbhc = &priv->mbhc;
2310 if (!mbhc) {
Meng Wang15c825d2018-09-06 10:49:18 +08002311 dev_dbg(component->dev, "%s: mbhc not initialized\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302312 return 0;
2313 }
2314
2315 ucontrol->value.integer.value[0] = (u32) mbhc->hph_type;
Meng Wang15c825d2018-09-06 10:49:18 +08002316 dev_dbg(component->dev, "%s: hph_type = %u\n", __func__,
2317 mbhc->hph_type);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302318
2319 return 0;
2320}
2321
2322static const struct snd_kcontrol_new hph_type_detect_controls[] = {
2323 SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0,
2324 tasha_get_hph_type, NULL),
2325};
2326
2327static int tasha_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2328 struct snd_ctl_elem_value *ucontrol)
2329{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302330 struct snd_soc_dapm_widget *widget =
Meng Wang15c825d2018-09-06 10:49:18 +08002331 snd_soc_dapm_kcontrol_widget(kcontrol);
2332 struct snd_soc_component *component =
2333 snd_soc_dapm_to_component(widget->dapm);
2334 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302335
2336 ucontrol->value.integer.value[0] = tasha_p->vi_feed_value;
2337
2338 return 0;
2339}
2340
2341static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2342 struct snd_ctl_elem_value *ucontrol)
2343{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302344 struct snd_soc_dapm_widget *widget =
Meng Wang15c825d2018-09-06 10:49:18 +08002345 snd_soc_dapm_kcontrol_widget(kcontrol);
2346 struct snd_soc_component *component =
2347 snd_soc_dapm_to_component(widget->dapm);
2348 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302349 struct wcd9xxx *core = tasha_p->wcd9xxx;
2350 struct soc_multi_mixer_control *mixer =
2351 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2352 u32 dai_id = widget->shift;
2353 u32 port_id = mixer->shift;
2354 u32 enable = ucontrol->value.integer.value[0];
2355
Meng Wang15c825d2018-09-06 10:49:18 +08002356 dev_dbg(component->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302357 __func__, enable, port_id, dai_id);
2358
2359 tasha_p->vi_feed_value = ucontrol->value.integer.value[0];
2360
2361 mutex_lock(&tasha_p->codec_mutex);
2362 if (enable) {
2363 if (port_id == TASHA_TX14 && !test_bit(VI_SENSE_1,
2364 &tasha_p->status_mask)) {
2365 list_add_tail(&core->tx_chs[TASHA_TX14].list,
2366 &tasha_p->dai[dai_id].wcd9xxx_ch_list);
2367 set_bit(VI_SENSE_1, &tasha_p->status_mask);
2368 }
2369 if (port_id == TASHA_TX15 && !test_bit(VI_SENSE_2,
2370 &tasha_p->status_mask)) {
2371 list_add_tail(&core->tx_chs[TASHA_TX15].list,
2372 &tasha_p->dai[dai_id].wcd9xxx_ch_list);
2373 set_bit(VI_SENSE_2, &tasha_p->status_mask);
2374 }
2375 } else {
2376 if (port_id == TASHA_TX14 && test_bit(VI_SENSE_1,
2377 &tasha_p->status_mask)) {
2378 list_del_init(&core->tx_chs[TASHA_TX14].list);
2379 clear_bit(VI_SENSE_1, &tasha_p->status_mask);
2380 }
2381 if (port_id == TASHA_TX15 && test_bit(VI_SENSE_2,
2382 &tasha_p->status_mask)) {
2383 list_del_init(&core->tx_chs[TASHA_TX15].list);
2384 clear_bit(VI_SENSE_2, &tasha_p->status_mask);
2385 }
2386 }
2387 mutex_unlock(&tasha_p->codec_mutex);
2388 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2389
2390 return 0;
2391}
2392
2393/* virtual port entries */
2394static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
2395 struct snd_ctl_elem_value *ucontrol)
2396{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302397 struct snd_soc_dapm_widget *widget =
2398 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002399 struct snd_soc_component *component =
2400 snd_soc_dapm_to_component(widget->dapm);
2401 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302402
2403 ucontrol->value.integer.value[0] = tasha_p->tx_port_value;
2404 return 0;
2405}
2406
2407static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
2408 struct snd_ctl_elem_value *ucontrol)
2409{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302410 struct snd_soc_dapm_widget *widget =
Meng Wang15c825d2018-09-06 10:49:18 +08002411 snd_soc_dapm_kcontrol_widget(kcontrol);
2412 struct snd_soc_component *component =
2413 snd_soc_dapm_to_component(widget->dapm);
2414 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
2415 struct wcd9xxx *core = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302416 struct snd_soc_dapm_update *update = NULL;
2417 struct soc_multi_mixer_control *mixer =
2418 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2419 u32 dai_id = widget->shift;
2420 u32 port_id = mixer->shift;
2421 u32 enable = ucontrol->value.integer.value[0];
2422 u32 vtable;
2423
2424
Meng Wang15c825d2018-09-06 10:49:18 +08002425 dev_dbg(component->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302426 __func__,
2427 widget->name, ucontrol->id.name, tasha_p->tx_port_value,
2428 widget->shift, ucontrol->value.integer.value[0]);
2429
2430 mutex_lock(&tasha_p->codec_mutex);
2431
Vaishnavi Kommaraju3b0d43d2018-07-31 18:02:56 +05302432 if (tasha_p->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Meng Wang15c825d2018-09-06 10:49:18 +08002433 if (dai_id != AIF1_CAP) {
2434 dev_err(component->dev, "%s: invalid AIF for I2C mode\n",
2435 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302436 mutex_unlock(&tasha_p->codec_mutex);
2437 return -EINVAL;
2438 }
2439 vtable = vport_slim_check_table[dai_id];
2440 } else {
2441 if (dai_id >= ARRAY_SIZE(vport_i2s_check_table)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002442 dev_err(component->dev, "%s: dai_id: %d, out of bounds\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302443 __func__, dai_id);
2444 return -EINVAL;
2445 }
2446 vtable = vport_i2s_check_table[dai_id];
2447 }
2448 switch (dai_id) {
2449 case AIF1_CAP:
2450 case AIF2_CAP:
2451 case AIF3_CAP:
2452 /* only add to the list if value not set */
2453 if (enable && !(tasha_p->tx_port_value & 1 << port_id)) {
2454
2455 if (wcd9xxx_tx_vport_validation(vtable, port_id,
2456 tasha_p->dai, NUM_CODEC_DAIS)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002457 dev_dbg(component->dev, "%s: TX%u is used by other virtual port\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302458 __func__, port_id);
2459 mutex_unlock(&tasha_p->codec_mutex);
2460 return 0;
2461 }
2462 tasha_p->tx_port_value |= 1 << port_id;
2463 list_add_tail(&core->tx_chs[port_id].list,
2464 &tasha_p->dai[dai_id].wcd9xxx_ch_list
2465 );
2466 } else if (!enable && (tasha_p->tx_port_value &
2467 1 << port_id)) {
2468 tasha_p->tx_port_value &= ~(1 << port_id);
2469 list_del_init(&core->tx_chs[port_id].list);
2470 } else {
2471 if (enable)
Meng Wang15c825d2018-09-06 10:49:18 +08002472 dev_dbg(component->dev, "%s: TX%u port is used by\n"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302473 "this virtual port\n",
2474 __func__, port_id);
2475 else
Meng Wang15c825d2018-09-06 10:49:18 +08002476 dev_dbg(component->dev, "%s: TX%u port is not used by\n"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302477 "this virtual port\n",
2478 __func__, port_id);
2479 /* avoid update power function */
2480 mutex_unlock(&tasha_p->codec_mutex);
2481 return 0;
2482 }
2483 break;
2484 case AIF4_MAD_TX:
2485 case AIF5_CPE_TX:
2486 break;
2487 default:
2488 pr_err("Unknown AIF %d\n", dai_id);
2489 mutex_unlock(&tasha_p->codec_mutex);
2490 return -EINVAL;
2491 }
2492 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
2493 widget->name, widget->sname, tasha_p->tx_port_value,
2494 widget->shift);
2495
2496 mutex_unlock(&tasha_p->codec_mutex);
2497 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
2498
2499 return 0;
2500}
2501
2502static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
2503 struct snd_ctl_elem_value *ucontrol)
2504{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302505 struct snd_soc_dapm_widget *widget =
2506 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002507 struct snd_soc_component *component =
2508 snd_soc_dapm_to_component(widget->dapm);
2509 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302510
2511 ucontrol->value.enumerated.item[0] =
2512 tasha_p->rx_port_value[widget->shift];
2513 return 0;
2514}
2515
2516static const char *const slim_rx_mux_text[] = {
2517 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", "AIF_MIX1_PB"
2518};
2519
2520static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
2521 struct snd_ctl_elem_value *ucontrol)
2522{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302523 struct snd_soc_dapm_widget *widget =
2524 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002525 struct snd_soc_component *component =
2526 snd_soc_dapm_to_component(widget->dapm);
2527 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
2528 struct wcd9xxx *core = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302529 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2530 struct snd_soc_dapm_update *update = NULL;
2531 unsigned int rx_port_value;
2532 u32 port_id = widget->shift;
2533
2534 tasha_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
2535 rx_port_value = tasha_p->rx_port_value[port_id];
2536
2537 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
2538 widget->name, ucontrol->id.name, rx_port_value,
2539 widget->shift, ucontrol->value.integer.value[0]);
2540
2541 mutex_lock(&tasha_p->codec_mutex);
2542
2543 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
2544 if (rx_port_value > 2) {
Meng Wang15c825d2018-09-06 10:49:18 +08002545 dev_err(component->dev, "%s: invalid AIF for I2C mode\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302546 __func__);
2547 goto err;
2548 }
2549 }
2550 /* value need to match the Virtual port and AIF number */
2551 switch (rx_port_value) {
2552 case 0:
2553 list_del_init(&core->rx_chs[port_id].list);
2554 break;
2555 case 1:
2556 if (wcd9xxx_rx_vport_validation(port_id +
2557 TASHA_RX_PORT_START_NUMBER,
2558 &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002559 dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302560 __func__, port_id);
2561 goto rtn;
2562 }
2563 list_add_tail(&core->rx_chs[port_id].list,
2564 &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list);
2565 break;
2566 case 2:
2567 if (wcd9xxx_rx_vport_validation(port_id +
2568 TASHA_RX_PORT_START_NUMBER,
2569 &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002570 dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302571 __func__, port_id);
2572 goto rtn;
2573 }
2574 list_add_tail(&core->rx_chs[port_id].list,
2575 &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list);
2576 break;
2577 case 3:
2578 if (wcd9xxx_rx_vport_validation(port_id +
2579 TASHA_RX_PORT_START_NUMBER,
2580 &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002581 dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302582 __func__, port_id);
2583 goto rtn;
2584 }
2585 list_add_tail(&core->rx_chs[port_id].list,
2586 &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list);
2587 break;
2588 case 4:
2589 if (wcd9xxx_rx_vport_validation(port_id +
2590 TASHA_RX_PORT_START_NUMBER,
2591 &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002592 dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302593 __func__, port_id);
2594 goto rtn;
2595 }
2596 list_add_tail(&core->rx_chs[port_id].list,
2597 &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list);
2598 break;
2599 case 5:
2600 if (wcd9xxx_rx_vport_validation(port_id +
2601 TASHA_RX_PORT_START_NUMBER,
2602 &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002603 dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302604 __func__, port_id);
2605 goto rtn;
2606 }
2607 list_add_tail(&core->rx_chs[port_id].list,
2608 &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list);
2609 break;
2610 default:
2611 pr_err("Unknown AIF %d\n", rx_port_value);
2612 goto err;
2613 }
2614rtn:
2615 mutex_unlock(&tasha_p->codec_mutex);
2616 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2617 rx_port_value, e, update);
2618
2619 return 0;
2620err:
2621 mutex_unlock(&tasha_p->codec_mutex);
2622 return -EINVAL;
2623}
2624
2625static const struct soc_enum slim_rx_mux_enum =
2626 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
2627
2628static const struct snd_kcontrol_new slim_rx_mux[TASHA_RX_MAX] = {
2629 SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum,
2630 slim_rx_mux_get, slim_rx_mux_put),
2631 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
2632 slim_rx_mux_get, slim_rx_mux_put),
2633 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
2634 slim_rx_mux_get, slim_rx_mux_put),
2635 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
2636 slim_rx_mux_get, slim_rx_mux_put),
2637 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
2638 slim_rx_mux_get, slim_rx_mux_put),
2639 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
2640 slim_rx_mux_get, slim_rx_mux_put),
2641 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
2642 slim_rx_mux_get, slim_rx_mux_put),
2643 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
2644 slim_rx_mux_get, slim_rx_mux_put),
2645};
2646
2647static const struct snd_kcontrol_new aif4_vi_mixer[] = {
2648 SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, TASHA_TX14, 1, 0,
2649 tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put),
2650 SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, TASHA_TX15, 1, 0,
2651 tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put),
2652};
2653
2654static const struct snd_kcontrol_new aif1_cap_mixer[] = {
2655 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2656 slim_tx_mixer_get, slim_tx_mixer_put),
2657 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2658 slim_tx_mixer_get, slim_tx_mixer_put),
2659 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2660 slim_tx_mixer_get, slim_tx_mixer_put),
2661 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2662 slim_tx_mixer_get, slim_tx_mixer_put),
2663 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2664 slim_tx_mixer_get, slim_tx_mixer_put),
2665 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2666 slim_tx_mixer_get, slim_tx_mixer_put),
2667 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2668 slim_tx_mixer_get, slim_tx_mixer_put),
2669 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2670 slim_tx_mixer_get, slim_tx_mixer_put),
2671 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2672 slim_tx_mixer_get, slim_tx_mixer_put),
2673 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2674 slim_tx_mixer_get, slim_tx_mixer_put),
2675 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2676 slim_tx_mixer_get, slim_tx_mixer_put),
2677 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2678 slim_tx_mixer_get, slim_tx_mixer_put),
2679 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2680 slim_tx_mixer_get, slim_tx_mixer_put),
2681};
2682
2683static const struct snd_kcontrol_new aif2_cap_mixer[] = {
2684 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2685 slim_tx_mixer_get, slim_tx_mixer_put),
2686 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2687 slim_tx_mixer_get, slim_tx_mixer_put),
2688 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2689 slim_tx_mixer_get, slim_tx_mixer_put),
2690 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2691 slim_tx_mixer_get, slim_tx_mixer_put),
2692 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2693 slim_tx_mixer_get, slim_tx_mixer_put),
2694 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2695 slim_tx_mixer_get, slim_tx_mixer_put),
2696 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2697 slim_tx_mixer_get, slim_tx_mixer_put),
2698 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2699 slim_tx_mixer_get, slim_tx_mixer_put),
2700 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2701 slim_tx_mixer_get, slim_tx_mixer_put),
2702 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2703 slim_tx_mixer_get, slim_tx_mixer_put),
2704 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2705 slim_tx_mixer_get, slim_tx_mixer_put),
2706 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2707 slim_tx_mixer_get, slim_tx_mixer_put),
2708 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2709 slim_tx_mixer_get, slim_tx_mixer_put),
2710};
2711
2712static const struct snd_kcontrol_new aif3_cap_mixer[] = {
2713 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2714 slim_tx_mixer_get, slim_tx_mixer_put),
2715 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2716 slim_tx_mixer_get, slim_tx_mixer_put),
2717 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2718 slim_tx_mixer_get, slim_tx_mixer_put),
2719 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2720 slim_tx_mixer_get, slim_tx_mixer_put),
2721 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2722 slim_tx_mixer_get, slim_tx_mixer_put),
2723 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2724 slim_tx_mixer_get, slim_tx_mixer_put),
2725 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2726 slim_tx_mixer_get, slim_tx_mixer_put),
2727 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2728 slim_tx_mixer_get, slim_tx_mixer_put),
2729 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2730 slim_tx_mixer_get, slim_tx_mixer_put),
2731 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2732 slim_tx_mixer_get, slim_tx_mixer_put),
2733 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2734 slim_tx_mixer_get, slim_tx_mixer_put),
2735 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2736 slim_tx_mixer_get, slim_tx_mixer_put),
2737 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2738 slim_tx_mixer_get, slim_tx_mixer_put),
2739};
2740
2741static const struct snd_kcontrol_new aif4_mad_mixer[] = {
2742 SOC_SINGLE_EXT("SLIM TX12", SND_SOC_NOPM, TASHA_TX12, 1, 0,
2743 slim_tx_mixer_get, slim_tx_mixer_put),
2744 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2745 slim_tx_mixer_get, slim_tx_mixer_put),
2746 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, 0, 1, 0,
2747 slim_tx_mixer_get, slim_tx_mixer_put),
2748
2749};
2750
2751static const struct snd_kcontrol_new rx_int1_spline_mix_switch[] = {
2752 SOC_DAPM_SINGLE("HPHL Switch", SND_SOC_NOPM, 0, 1, 0)
2753};
2754
2755static const struct snd_kcontrol_new rx_int2_spline_mix_switch[] = {
2756 SOC_DAPM_SINGLE("HPHR Switch", SND_SOC_NOPM, 0, 1, 0)
2757};
2758
2759static const struct snd_kcontrol_new rx_int3_spline_mix_switch[] = {
2760 SOC_DAPM_SINGLE("LO1 Switch", SND_SOC_NOPM, 0, 1, 0)
2761};
2762
2763static const struct snd_kcontrol_new rx_int4_spline_mix_switch[] = {
2764 SOC_DAPM_SINGLE("LO2 Switch", SND_SOC_NOPM, 0, 1, 0)
2765};
2766
2767static const struct snd_kcontrol_new rx_int5_spline_mix_switch[] = {
2768 SOC_DAPM_SINGLE("LO3 Switch", SND_SOC_NOPM, 0, 1, 0)
2769};
2770
2771static const struct snd_kcontrol_new rx_int6_spline_mix_switch[] = {
2772 SOC_DAPM_SINGLE("LO4 Switch", SND_SOC_NOPM, 0, 1, 0)
2773};
2774
2775static const struct snd_kcontrol_new rx_int7_spline_mix_switch[] = {
2776 SOC_DAPM_SINGLE("SPKRL Switch", SND_SOC_NOPM, 0, 1, 0)
2777};
2778
2779static const struct snd_kcontrol_new rx_int8_spline_mix_switch[] = {
2780 SOC_DAPM_SINGLE("SPKRR Switch", SND_SOC_NOPM, 0, 1, 0)
2781};
2782
2783static const struct snd_kcontrol_new rx_int5_vbat_mix_switch[] = {
2784 SOC_DAPM_SINGLE("LO3 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2785};
2786
2787static const struct snd_kcontrol_new rx_int6_vbat_mix_switch[] = {
2788 SOC_DAPM_SINGLE("LO4 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2789};
2790
2791static const struct snd_kcontrol_new rx_int7_vbat_mix_switch[] = {
2792 SOC_DAPM_SINGLE("SPKRL VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2793};
2794
2795static const struct snd_kcontrol_new rx_int8_vbat_mix_switch[] = {
2796 SOC_DAPM_SINGLE("SPKRR VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2797};
2798
2799static const struct snd_kcontrol_new cpe_in_mix_switch[] = {
2800 SOC_DAPM_SINGLE("MAD_BYPASS", SND_SOC_NOPM, 0, 1, 0)
2801};
2802
2803
2804
2805static int tasha_put_iir_enable_audio_mixer(
2806 struct snd_kcontrol *kcontrol,
2807 struct snd_ctl_elem_value *ucontrol)
2808{
Meng Wang15c825d2018-09-06 10:49:18 +08002809 struct snd_soc_component *component =
2810 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302811 int iir_idx = ((struct soc_multi_mixer_control *)
2812 kcontrol->private_value)->reg;
2813 int band_idx = ((struct soc_multi_mixer_control *)
2814 kcontrol->private_value)->shift;
2815 bool iir_band_en_status;
2816 int value = ucontrol->value.integer.value[0];
2817 u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
2818
2819 /* Mask first 5 bits, 6-8 are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002820 snd_soc_component_update_bits(component, iir_reg, (1 << band_idx),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302821 (value << band_idx));
2822
Meng Wang15c825d2018-09-06 10:49:18 +08002823 iir_band_en_status = ((snd_soc_component_read32(component, iir_reg) &
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302824 (1 << band_idx)) != 0);
2825 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
2826 iir_idx, band_idx, iir_band_en_status);
2827 return 0;
2828}
2829
Meng Wang15c825d2018-09-06 10:49:18 +08002830static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302831 int iir_idx, int band_idx,
2832 int coeff_idx)
2833{
2834 uint32_t value = 0;
2835
2836 /* Address does not automatically update if reading */
Meng Wang15c825d2018-09-06 10:49:18 +08002837 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302838 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2839 ((band_idx * BAND_MAX + coeff_idx)
2840 * sizeof(uint32_t)) & 0x7F);
2841
Meng Wang15c825d2018-09-06 10:49:18 +08002842 value |= snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302843 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx));
2844
Meng Wang15c825d2018-09-06 10:49:18 +08002845 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302846 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2847 ((band_idx * BAND_MAX + coeff_idx)
2848 * sizeof(uint32_t) + 1) & 0x7F);
2849
Meng Wang15c825d2018-09-06 10:49:18 +08002850 value |= (snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302851 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2852 16 * iir_idx)) << 8);
2853
Meng Wang15c825d2018-09-06 10:49:18 +08002854 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302855 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2856 ((band_idx * BAND_MAX + coeff_idx)
2857 * sizeof(uint32_t) + 2) & 0x7F);
2858
Meng Wang15c825d2018-09-06 10:49:18 +08002859 value |= (snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302860 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2861 16 * iir_idx)) << 16);
2862
Meng Wang15c825d2018-09-06 10:49:18 +08002863 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302864 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2865 ((band_idx * BAND_MAX + coeff_idx)
2866 * sizeof(uint32_t) + 3) & 0x7F);
2867
2868 /* Mask bits top 2 bits since they are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002869 value |= ((snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302870 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2871 16 * iir_idx)) & 0x3F) << 24);
2872
2873 return value;
2874}
2875
2876static int tasha_get_iir_band_audio_mixer(
2877 struct snd_kcontrol *kcontrol,
2878 struct snd_ctl_elem_value *ucontrol)
2879{
Meng Wang15c825d2018-09-06 10:49:18 +08002880 struct snd_soc_component *component =
2881 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302882 int iir_idx = ((struct soc_multi_mixer_control *)
2883 kcontrol->private_value)->reg;
2884 int band_idx = ((struct soc_multi_mixer_control *)
2885 kcontrol->private_value)->shift;
2886
2887 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002888 get_iir_band_coeff(component, iir_idx, band_idx, 0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302889 ucontrol->value.integer.value[1] =
Meng Wang15c825d2018-09-06 10:49:18 +08002890 get_iir_band_coeff(component, iir_idx, band_idx, 1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302891 ucontrol->value.integer.value[2] =
Meng Wang15c825d2018-09-06 10:49:18 +08002892 get_iir_band_coeff(component, iir_idx, band_idx, 2);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302893 ucontrol->value.integer.value[3] =
Meng Wang15c825d2018-09-06 10:49:18 +08002894 get_iir_band_coeff(component, iir_idx, band_idx, 3);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302895 ucontrol->value.integer.value[4] =
Meng Wang15c825d2018-09-06 10:49:18 +08002896 get_iir_band_coeff(component, iir_idx, band_idx, 4);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302897
2898 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
2899 "%s: IIR #%d band #%d b1 = 0x%x\n"
2900 "%s: IIR #%d band #%d b2 = 0x%x\n"
2901 "%s: IIR #%d band #%d a1 = 0x%x\n"
2902 "%s: IIR #%d band #%d a2 = 0x%x\n",
2903 __func__, iir_idx, band_idx,
2904 (uint32_t)ucontrol->value.integer.value[0],
2905 __func__, iir_idx, band_idx,
2906 (uint32_t)ucontrol->value.integer.value[1],
2907 __func__, iir_idx, band_idx,
2908 (uint32_t)ucontrol->value.integer.value[2],
2909 __func__, iir_idx, band_idx,
2910 (uint32_t)ucontrol->value.integer.value[3],
2911 __func__, iir_idx, band_idx,
2912 (uint32_t)ucontrol->value.integer.value[4]);
2913 return 0;
2914}
2915
Meng Wang15c825d2018-09-06 10:49:18 +08002916static void set_iir_band_coeff(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302917 int iir_idx, int band_idx,
2918 uint32_t value)
2919{
Meng Wang15c825d2018-09-06 10:49:18 +08002920 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302921 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
2922 (value & 0xFF));
2923
Meng Wang15c825d2018-09-06 10:49:18 +08002924 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302925 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
2926 (value >> 8) & 0xFF);
2927
Meng Wang15c825d2018-09-06 10:49:18 +08002928 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302929 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
2930 (value >> 16) & 0xFF);
2931
2932 /* Mask top 2 bits, 7-8 are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002933 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302934 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
2935 (value >> 24) & 0x3F);
2936}
2937
2938static void tasha_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai,
Meng Wang15c825d2018-09-06 10:49:18 +08002939 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302940{
2941 struct wcd9xxx_ch *ch;
2942 int port_num = 0;
2943 unsigned short reg = 0;
2944 u8 val = 0;
2945 struct tasha_priv *tasha_p;
2946
Meng Wang15c825d2018-09-06 10:49:18 +08002947 if (!dai || !component) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302948 pr_err("%s: Invalid params\n", __func__);
2949 return;
2950 }
2951
Meng Wang15c825d2018-09-06 10:49:18 +08002952 tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302953 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
2954 if (ch->port >= TASHA_RX_PORT_START_NUMBER) {
2955 port_num = ch->port - TASHA_RX_PORT_START_NUMBER;
2956 reg = TASHA_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
2957 val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx,
2958 reg);
2959 if (!(val & BYTE_BIT_MASK(port_num))) {
2960 val |= BYTE_BIT_MASK(port_num);
2961 wcd9xxx_interface_reg_write(
2962 tasha_p->wcd9xxx, reg, val);
2963 val = wcd9xxx_interface_reg_read(
2964 tasha_p->wcd9xxx, reg);
2965 }
2966 } else {
2967 port_num = ch->port;
2968 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
2969 val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx,
2970 reg);
2971 if (!(val & BYTE_BIT_MASK(port_num))) {
2972 val |= BYTE_BIT_MASK(port_num);
2973 wcd9xxx_interface_reg_write(tasha_p->wcd9xxx,
2974 reg, val);
2975 val = wcd9xxx_interface_reg_read(
2976 tasha_p->wcd9xxx, reg);
2977 }
2978 }
2979 }
2980}
2981
2982static int tasha_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
2983 bool up)
2984{
2985 int ret = 0;
2986 struct wcd9xxx_ch *ch;
2987
2988 if (up) {
2989 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
2990 ret = wcd9xxx_get_slave_port(ch->ch_num);
2991 if (ret < 0) {
2992 pr_err("%s: Invalid slave port ID: %d\n",
2993 __func__, ret);
2994 ret = -EINVAL;
2995 } else {
2996 set_bit(ret, &dai->ch_mask);
2997 }
2998 }
2999 } else {
3000 ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
3001 msecs_to_jiffies(
3002 TASHA_SLIM_CLOSE_TIMEOUT));
3003 if (!ret) {
3004 pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n",
3005 __func__, dai->ch_mask);
3006 ret = -ETIMEDOUT;
3007 } else {
3008 ret = 0;
3009 }
3010 }
3011 return ret;
3012}
3013
3014static int tasha_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
3015 struct snd_kcontrol *kcontrol,
3016 int event)
3017{
3018 struct wcd9xxx *core;
Meng Wang15c825d2018-09-06 10:49:18 +08003019 struct snd_soc_component *component =
3020 snd_soc_dapm_to_component(w->dapm);
3021 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303022 int ret = 0;
3023 struct wcd9xxx_codec_dai_data *dai;
3024
Meng Wang15c825d2018-09-06 10:49:18 +08003025 core = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303026
Meng Wang15c825d2018-09-06 10:49:18 +08003027 dev_dbg(component->dev, "%s: event called! component name %s num_dai %d\n"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303028 "stream name %s event %d\n",
Meng Wang15c825d2018-09-06 10:49:18 +08003029 __func__, component->name,
3030 component->num_dai, w->sname, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303031
3032 /* Execute the callback only if interface type is slimbus */
3033 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3034 return 0;
3035
3036 dai = &tasha_p->dai[w->shift];
Meng Wang15c825d2018-09-06 10:49:18 +08003037 dev_dbg(component->dev, "%s: w->name %s w->shift %d event %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303038 __func__, w->name, w->shift, event);
3039
3040 switch (event) {
3041 case SND_SOC_DAPM_POST_PMU:
3042 dai->bus_down_in_recovery = false;
Meng Wang15c825d2018-09-06 10:49:18 +08003043 tasha_codec_enable_int_port(dai, component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303044 (void) tasha_codec_enable_slim_chmask(dai, true);
3045 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3046 dai->rate, dai->bit_width,
3047 &dai->grph);
3048 break;
3049 case SND_SOC_DAPM_PRE_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08003050 tasha_codec_vote_max_bw(component, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303051 break;
3052 case SND_SOC_DAPM_POST_PMD:
3053 ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list,
3054 dai->grph);
Meng Wang15c825d2018-09-06 10:49:18 +08003055 dev_dbg(component->dev, "%s: Disconnect RX port, ret = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303056 __func__, ret);
3057
3058 if (!dai->bus_down_in_recovery)
3059 ret = tasha_codec_enable_slim_chmask(dai, false);
3060 else
Meng Wang15c825d2018-09-06 10:49:18 +08003061 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303062 "%s: bus in recovery skip enable slim_chmask",
3063 __func__);
3064 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3065 dai->grph);
3066 break;
3067 }
3068 return ret;
3069}
3070
3071static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
3072 struct snd_kcontrol *kcontrol,
3073 int event)
3074{
3075 struct wcd9xxx *core = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +08003076 struct snd_soc_component *component = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303077 struct tasha_priv *tasha_p = NULL;
3078 int ret = 0;
3079 struct wcd9xxx_codec_dai_data *dai = NULL;
3080
3081 if (!w) {
3082 pr_err("%s invalid params\n", __func__);
3083 return -EINVAL;
3084 }
Meng Wang15c825d2018-09-06 10:49:18 +08003085 component = snd_soc_dapm_to_component(w->dapm);
3086 tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303087 core = tasha_p->wcd9xxx;
3088
Meng Wang15c825d2018-09-06 10:49:18 +08003089 dev_dbg(component->dev, "%s: num_dai %d stream name %s\n",
3090 __func__, component->num_dai, w->sname);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303091
3092 /* Execute the callback only if interface type is slimbus */
3093 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Meng Wang15c825d2018-09-06 10:49:18 +08003094 dev_err(component->dev, "%s Interface is not correct",
3095 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303096 return 0;
3097 }
3098
Meng Wang15c825d2018-09-06 10:49:18 +08003099 dev_dbg(component->dev, "%s(): w->name %s event %d w->shift %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303100 __func__, w->name, event, w->shift);
3101 if (w->shift != AIF4_VIFEED) {
3102 pr_err("%s Error in enabling the tx path\n", __func__);
3103 ret = -EINVAL;
3104 goto out_vi;
3105 }
3106 dai = &tasha_p->dai[w->shift];
3107 switch (event) {
3108 case SND_SOC_DAPM_POST_PMU:
3109 if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) {
Meng Wang15c825d2018-09-06 10:49:18 +08003110 dev_dbg(component->dev, "%s: spkr1 enabled\n",
3111 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303112 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08003113 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303114 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003115 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303116 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3117 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003118 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303119 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003120 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303121 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F,
3122 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003123 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303124 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08003125 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303126 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
3127 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08003128 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303129 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003130 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303131 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3132 0x00);
3133 }
3134 if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) {
3135 pr_debug("%s: spkr2 enabled\n", __func__);
3136 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08003137 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303138 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3139 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003140 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303141 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3142 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003143 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303144 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F,
3145 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003146 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303147 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F,
3148 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003149 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303150 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
3151 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08003152 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303153 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
3154 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08003155 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303156 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3157 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003158 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303159 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3160 0x00);
3161 }
3162 dai->bus_down_in_recovery = false;
Meng Wang15c825d2018-09-06 10:49:18 +08003163 tasha_codec_enable_int_port(dai, component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303164 (void) tasha_codec_enable_slim_chmask(dai, true);
3165 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3166 dai->rate, dai->bit_width,
3167 &dai->grph);
3168 break;
3169 case SND_SOC_DAPM_POST_PMD:
3170 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3171 dai->grph);
3172 if (ret)
Meng Wang15c825d2018-09-06 10:49:18 +08003173 dev_err(component->dev, "%s error in close_slim_sch_tx %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303174 __func__, ret);
3175 if (!dai->bus_down_in_recovery)
3176 ret = tasha_codec_enable_slim_chmask(dai, false);
3177 if (ret < 0) {
3178 ret = wcd9xxx_disconnect_port(core,
3179 &dai->wcd9xxx_ch_list,
3180 dai->grph);
Meng Wang15c825d2018-09-06 10:49:18 +08003181 dev_dbg(component->dev, "%s: Disconnect TX port, ret = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303182 __func__, ret);
3183 }
3184 if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) {
3185 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08003186 dev_dbg(component->dev, "%s: spkr1 disabled\n",
3187 __func__);
3188 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303189 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003190 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303191 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3192 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003193 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303194 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003195 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303196 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
3197 0x00);
3198 }
3199 if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) {
3200 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08003201 dev_dbg(component->dev, "%s: spkr2 disabled\n",
3202 __func__);
3203 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303204 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3205 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003206 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303207 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3208 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003209 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303210 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
3211 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003212 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303213 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
3214 0x00);
3215 }
3216 break;
3217 }
3218out_vi:
3219 return ret;
3220}
3221
3222/*
3223 * __tasha_codec_enable_slimtx: Enable the slimbus slave port
3224 * for TX path
Meng Wang15c825d2018-09-06 10:49:18 +08003225 * @component: Handle to the codec for which the slave port is to be
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303226 * enabled.
3227 * @dai_data: The dai specific data for dai which is enabled.
3228 */
Meng Wang15c825d2018-09-06 10:49:18 +08003229static int __tasha_codec_enable_slimtx(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303230 int event, struct wcd9xxx_codec_dai_data *dai)
3231{
3232 struct wcd9xxx *core;
Meng Wang15c825d2018-09-06 10:49:18 +08003233 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303234 int ret = 0;
3235
3236 /* Execute the callback only if interface type is slimbus */
3237 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3238 return 0;
3239
Meng Wang15c825d2018-09-06 10:49:18 +08003240 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303241 "%s: event = %d\n", __func__, event);
Meng Wang15c825d2018-09-06 10:49:18 +08003242 core = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303243
3244 switch (event) {
3245 case SND_SOC_DAPM_POST_PMU:
3246 dai->bus_down_in_recovery = false;
Meng Wang15c825d2018-09-06 10:49:18 +08003247 tasha_codec_enable_int_port(dai, component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303248 (void) tasha_codec_enable_slim_chmask(dai, true);
3249 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3250 dai->rate, dai->bit_width,
3251 &dai->grph);
3252 break;
3253 case SND_SOC_DAPM_POST_PMD:
3254 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3255 dai->grph);
3256 if (!dai->bus_down_in_recovery)
3257 ret = tasha_codec_enable_slim_chmask(dai, false);
3258 if (ret < 0) {
3259 ret = wcd9xxx_disconnect_port(core,
3260 &dai->wcd9xxx_ch_list,
3261 dai->grph);
3262 pr_debug("%s: Disconnect TX port, ret = %d\n",
3263 __func__, ret);
3264 }
3265
3266 break;
3267 }
3268
3269 return ret;
3270}
3271
3272static int tasha_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
3273 struct snd_kcontrol *kcontrol,
3274 int event)
3275{
Meng Wang15c825d2018-09-06 10:49:18 +08003276 struct snd_soc_component *component =
3277 snd_soc_dapm_to_component(w->dapm);
3278 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303279 struct wcd9xxx_codec_dai_data *dai;
3280
Meng Wang15c825d2018-09-06 10:49:18 +08003281 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303282 "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n",
3283 __func__, w->name, w->shift,
Meng Wang15c825d2018-09-06 10:49:18 +08003284 component->num_dai, w->sname);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303285
3286 dai = &tasha_p->dai[w->shift];
Meng Wang15c825d2018-09-06 10:49:18 +08003287 return __tasha_codec_enable_slimtx(component, event, dai);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303288}
3289
Meng Wang15c825d2018-09-06 10:49:18 +08003290static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_component *component,
3291 int event)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303292{
Meng Wang15c825d2018-09-06 10:49:18 +08003293 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303294 struct wcd9xxx_codec_dai_data *dai;
3295 u8 bit_width, rate, buf_period;
3296
3297 dai = &tasha_p->dai[AIF4_MAD_TX];
3298 switch (event) {
3299 case SND_SOC_DAPM_POST_PMU:
3300 switch (dai->bit_width) {
3301 case 32:
3302 bit_width = 0xF;
3303 break;
3304 case 24:
3305 bit_width = 0xE;
3306 break;
3307 case 20:
3308 bit_width = 0xD;
3309 break;
3310 case 16:
3311 default:
3312 bit_width = 0x0;
3313 break;
3314 }
Meng Wang15c825d2018-09-06 10:49:18 +08003315 snd_soc_component_update_bits(component,
3316 WCD9335_CPE_SS_TX_PP_CFG, 0x0F, bit_width);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303317
3318 switch (dai->rate) {
3319 case 384000:
3320 rate = 0x30;
3321 break;
3322 case 192000:
3323 rate = 0x20;
3324 break;
3325 case 48000:
3326 rate = 0x10;
3327 break;
3328 case 16000:
3329 default:
3330 rate = 0x00;
3331 break;
3332 }
Meng Wang15c825d2018-09-06 10:49:18 +08003333 snd_soc_component_update_bits(component,
3334 WCD9335_CPE_SS_TX_PP_CFG, 0x70, rate);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303335
3336 buf_period = (dai->rate * (dai->bit_width/8)) / (16*1000);
Meng Wang15c825d2018-09-06 10:49:18 +08003337 snd_soc_component_update_bits(component,
3338 WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD,
3339 0xFF, buf_period);
3340 dev_dbg(component->dev, "%s: PP buffer period= 0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303341 __func__, buf_period);
3342 break;
3343
3344 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08003345 snd_soc_component_write(component, WCD9335_CPE_SS_TX_PP_CFG,
3346 0x3C);
3347 snd_soc_component_write(component,
3348 WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD,
3349 0x60);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303350 break;
3351
3352 default:
3353 break;
3354 }
3355}
3356
3357/*
3358 * tasha_codec_get_mad_port_id: Callback function that will be invoked
3359 * to get the port ID for MAD.
Meng Wang15c825d2018-09-06 10:49:18 +08003360 * @component: Handle to the codec
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303361 * @port_id: cpe port_id needs to enable
3362 */
Meng Wang15c825d2018-09-06 10:49:18 +08003363static int tasha_codec_get_mad_port_id(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303364 u16 *port_id)
3365{
3366 struct tasha_priv *tasha_p;
3367 struct wcd9xxx_codec_dai_data *dai;
3368 struct wcd9xxx_ch *ch;
3369
Meng Wang15c825d2018-09-06 10:49:18 +08003370 if (!port_id || !component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303371 return -EINVAL;
3372
Meng Wang15c825d2018-09-06 10:49:18 +08003373 tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303374 if (!tasha_p)
3375 return -EINVAL;
3376
3377 dai = &tasha_p->dai[AIF4_MAD_TX];
3378 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3379 if (ch->port == TASHA_TX12)
3380 *port_id = WCD_CPE_AFE_OUT_PORT_2;
3381 else if (ch->port == TASHA_TX13)
3382 *port_id = WCD_CPE_AFE_OUT_PORT_4;
3383 else {
Meng Wang15c825d2018-09-06 10:49:18 +08003384 dev_err(component->dev, "%s: invalid mad_port = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303385 __func__, ch->port);
3386 return -EINVAL;
3387 }
3388 }
Meng Wang15c825d2018-09-06 10:49:18 +08003389 dev_dbg(component->dev, "%s: port_id = %d\n", __func__, *port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303390
3391 return 0;
3392}
3393
3394/*
3395 * tasha_codec_enable_slimtx_mad: Callback function that will be invoked
3396 * to setup the slave port for MAD.
Meng Wang15c825d2018-09-06 10:49:18 +08003397 * @component: Handle to the codec
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303398 * @event: Indicates whether to enable or disable the slave port
3399 */
Meng Wang15c825d2018-09-06 10:49:18 +08003400static int tasha_codec_enable_slimtx_mad(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303401 u8 event)
3402{
Meng Wang15c825d2018-09-06 10:49:18 +08003403 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303404 struct wcd9xxx_codec_dai_data *dai;
3405 struct wcd9xxx_ch *ch;
3406 int dapm_event = SND_SOC_DAPM_POST_PMU;
3407 u16 port = 0;
3408 int ret = 0;
3409
3410 dai = &tasha_p->dai[AIF4_MAD_TX];
3411
3412 if (event == 0)
3413 dapm_event = SND_SOC_DAPM_POST_PMD;
3414
Meng Wang15c825d2018-09-06 10:49:18 +08003415 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303416 "%s: mad_channel, event = 0x%x\n",
3417 __func__, event);
3418
3419 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
Meng Wang15c825d2018-09-06 10:49:18 +08003420 dev_dbg(component->dev, "%s: mad_port = %d, event = 0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303421 __func__, ch->port, event);
3422 if (ch->port == TASHA_TX13) {
Meng Wang15c825d2018-09-06 10:49:18 +08003423 tasha_codec_cpe_pp_set_cfg(component, dapm_event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303424 port = TASHA_TX13;
3425 break;
3426 }
3427 }
3428
Meng Wang15c825d2018-09-06 10:49:18 +08003429 ret = __tasha_codec_enable_slimtx(component, dapm_event, dai);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303430
3431 if (port == TASHA_TX13) {
3432 switch (dapm_event) {
3433 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08003434 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303435 WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN,
3436 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003437 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303438 WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG,
3439 0x03, 0x02);
Meng Wang15c825d2018-09-06 10:49:18 +08003440 snd_soc_component_update_bits(component,
3441 WCD9335_CPE_SS_CFG,
3442 0x80, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303443 break;
3444 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08003445 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303446 WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN,
3447 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08003448 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303449 WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG,
3450 0x03, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003451 snd_soc_component_update_bits(component,
3452 WCD9335_CPE_SS_CFG,
3453 0x80, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303454 break;
3455 }
3456 }
3457
3458 return ret;
3459}
3460
3461static int tasha_put_iir_band_audio_mixer(
3462 struct snd_kcontrol *kcontrol,
3463 struct snd_ctl_elem_value *ucontrol)
3464{
Meng Wang15c825d2018-09-06 10:49:18 +08003465 struct snd_soc_component *component =
3466 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303467 int iir_idx = ((struct soc_multi_mixer_control *)
3468 kcontrol->private_value)->reg;
3469 int band_idx = ((struct soc_multi_mixer_control *)
3470 kcontrol->private_value)->shift;
3471
3472 /*
3473 * Mask top bit it is reserved
3474 * Updates addr automatically for each B2 write
3475 */
Meng Wang15c825d2018-09-06 10:49:18 +08003476 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303477 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
3478 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
3479
Meng Wang15c825d2018-09-06 10:49:18 +08003480 set_iir_band_coeff(component, iir_idx, band_idx,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303481 ucontrol->value.integer.value[0]);
Meng Wang15c825d2018-09-06 10:49:18 +08003482 set_iir_band_coeff(component, iir_idx, band_idx,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303483 ucontrol->value.integer.value[1]);
Meng Wang15c825d2018-09-06 10:49:18 +08003484 set_iir_band_coeff(component, iir_idx, band_idx,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303485 ucontrol->value.integer.value[2]);
Meng Wang15c825d2018-09-06 10:49:18 +08003486 set_iir_band_coeff(component, iir_idx, band_idx,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303487 ucontrol->value.integer.value[3]);
Meng Wang15c825d2018-09-06 10:49:18 +08003488 set_iir_band_coeff(component, iir_idx, band_idx,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303489 ucontrol->value.integer.value[4]);
3490
3491 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
3492 "%s: IIR #%d band #%d b1 = 0x%x\n"
3493 "%s: IIR #%d band #%d b2 = 0x%x\n"
3494 "%s: IIR #%d band #%d a1 = 0x%x\n"
3495 "%s: IIR #%d band #%d a2 = 0x%x\n",
3496 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08003497 get_iir_band_coeff(component, iir_idx, band_idx, 0),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303498 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08003499 get_iir_band_coeff(component, iir_idx, band_idx, 1),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303500 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08003501 get_iir_band_coeff(component, iir_idx, band_idx, 2),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303502 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08003503 get_iir_band_coeff(component, iir_idx, band_idx, 3),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303504 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08003505 get_iir_band_coeff(component, iir_idx, band_idx, 4));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303506 return 0;
3507}
3508
3509static int tasha_get_compander(struct snd_kcontrol *kcontrol,
3510 struct snd_ctl_elem_value *ucontrol)
3511{
3512
Meng Wang15c825d2018-09-06 10:49:18 +08003513 struct snd_soc_component *component =
3514 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303515 int comp = ((struct soc_multi_mixer_control *)
3516 kcontrol->private_value)->shift;
Meng Wang15c825d2018-09-06 10:49:18 +08003517 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303518
3519 ucontrol->value.integer.value[0] = tasha->comp_enabled[comp];
3520 return 0;
3521}
3522
3523static int tasha_set_compander(struct snd_kcontrol *kcontrol,
3524 struct snd_ctl_elem_value *ucontrol)
3525{
Meng Wang15c825d2018-09-06 10:49:18 +08003526 struct snd_soc_component *component =
3527 snd_soc_kcontrol_component(kcontrol);
3528 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303529 int comp = ((struct soc_multi_mixer_control *)
3530 kcontrol->private_value)->shift;
3531 int value = ucontrol->value.integer.value[0];
3532
3533 pr_debug("%s: Compander %d enable current %d, new %d\n",
3534 __func__, comp + 1, tasha->comp_enabled[comp], value);
3535 tasha->comp_enabled[comp] = value;
3536
3537 /* Any specific register configuration for compander */
3538 switch (comp) {
3539 case COMPANDER_1:
3540 /* Set Gain Source Select based on compander enable/disable */
Meng Wang15c825d2018-09-06 10:49:18 +08003541 snd_soc_component_update_bits(component, WCD9335_HPH_L_EN, 0x20,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303542 (value ? 0x00:0x20));
3543 break;
3544 case COMPANDER_2:
Meng Wang15c825d2018-09-06 10:49:18 +08003545 snd_soc_component_update_bits(component, WCD9335_HPH_R_EN, 0x20,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303546 (value ? 0x00:0x20));
3547 break;
3548 case COMPANDER_3:
3549 break;
3550 case COMPANDER_4:
3551 break;
3552 case COMPANDER_5:
Meng Wang15c825d2018-09-06 10:49:18 +08003553 snd_soc_component_update_bits(component, WCD9335_SE_LO_LO3_GAIN,
3554 0x20, (value ? 0x00:0x20));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303555 break;
3556 case COMPANDER_6:
Meng Wang15c825d2018-09-06 10:49:18 +08003557 snd_soc_component_update_bits(component, WCD9335_SE_LO_LO4_GAIN,
3558 0x20, (value ? 0x00:0x20));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303559 break;
3560 case COMPANDER_7:
3561 break;
3562 case COMPANDER_8:
3563 break;
3564 default:
3565 /*
3566 * if compander is not enabled for any interpolator,
3567 * it does not cause any audio failure, so do not
3568 * return error in this case, but just print a log
3569 */
Meng Wang15c825d2018-09-06 10:49:18 +08003570 dev_warn(component->dev, "%s: unknown compander: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303571 __func__, comp);
3572 };
3573 return 0;
3574}
3575
Meng Wang15c825d2018-09-06 10:49:18 +08003576static void tasha_codec_init_flyback(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303577{
Meng Wang15c825d2018-09-06 10:49:18 +08003578 snd_soc_component_update_bits(component, WCD9335_HPH_L_EN, 0xC0, 0x00);
3579 snd_soc_component_update_bits(component, WCD9335_HPH_R_EN, 0xC0, 0x00);
3580 snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF,
3581 0x0F, 0x00);
3582 snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF,
3583 0xF0, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303584}
3585
3586static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
3587 struct snd_kcontrol *kcontrol, int event)
3588{
Meng Wang15c825d2018-09-06 10:49:18 +08003589 struct snd_soc_component *component =
3590 snd_soc_dapm_to_component(w->dapm);
3591 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303592
Meng Wang15c825d2018-09-06 10:49:18 +08003593 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303594
3595 switch (event) {
3596 case SND_SOC_DAPM_PRE_PMU:
3597 tasha->rx_bias_count++;
3598 if (tasha->rx_bias_count == 1) {
3599 if (TASHA_IS_2_0(tasha->wcd9xxx))
Meng Wang15c825d2018-09-06 10:49:18 +08003600 tasha_codec_init_flyback(component);
3601 snd_soc_component_update_bits(component,
3602 WCD9335_ANA_RX_SUPPLIES,
3603 0x01, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303604 }
3605 break;
3606 case SND_SOC_DAPM_POST_PMD:
3607 tasha->rx_bias_count--;
3608 if (!tasha->rx_bias_count)
Meng Wang15c825d2018-09-06 10:49:18 +08003609 snd_soc_component_update_bits(component,
3610 WCD9335_ANA_RX_SUPPLIES,
3611 0x01, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303612 break;
3613 };
Meng Wang15c825d2018-09-06 10:49:18 +08003614 dev_dbg(component->dev, "%s: Current RX BIAS user count: %d\n",
3615 __func__, tasha->rx_bias_count);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303616
3617 return 0;
3618}
3619
Meng Wang15c825d2018-09-06 10:49:18 +08003620static void tasha_realign_anc_coeff(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303621 u16 reg1, u16 reg2)
3622{
3623 u8 val1, val2, tmpval1, tmpval2;
3624
Meng Wang15c825d2018-09-06 10:49:18 +08003625 snd_soc_component_write(component, reg1, 0x00);
3626 tmpval1 = snd_soc_component_read32(component, reg2);
3627 tmpval2 = snd_soc_component_read32(component, reg2);
3628 snd_soc_component_write(component, reg1, 0x00);
3629 snd_soc_component_write(component, reg2, 0xFF);
3630 snd_soc_component_write(component, reg1, 0x01);
3631 snd_soc_component_write(component, reg2, 0xFF);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303632
Meng Wang15c825d2018-09-06 10:49:18 +08003633 snd_soc_component_write(component, reg1, 0x00);
3634 val1 = snd_soc_component_read32(component, reg2);
3635 val2 = snd_soc_component_read32(component, reg2);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303636
3637 if (val1 == 0x0F && val2 == 0xFF) {
Meng Wang15c825d2018-09-06 10:49:18 +08003638 dev_dbg(component->dev, "%s: ANC0 co-eff index re-aligned\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303639 __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08003640 snd_soc_component_read32(component, reg2);
3641 snd_soc_component_write(component, reg1, 0x00);
3642 snd_soc_component_write(component, reg2, tmpval2);
3643 snd_soc_component_write(component, reg1, 0x01);
3644 snd_soc_component_write(component, reg2, tmpval1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303645 } else if (val1 == 0xFF && val2 == 0x0F) {
Meng Wang15c825d2018-09-06 10:49:18 +08003646 dev_dbg(component->dev, "%s: ANC1 co-eff index already aligned\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303647 __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08003648 snd_soc_component_write(component, reg1, 0x00);
3649 snd_soc_component_write(component, reg2, tmpval1);
3650 snd_soc_component_write(component, reg1, 0x01);
3651 snd_soc_component_write(component, reg2, tmpval2);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303652 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08003653 dev_err(component->dev, "%s: ANC0 co-eff index not aligned\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303654 __func__);
3655 }
3656}
3657
3658static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w,
3659 struct snd_kcontrol *kcontrol, int event)
3660{
Meng Wang15c825d2018-09-06 10:49:18 +08003661 struct snd_soc_component *component =
3662 snd_soc_dapm_to_component(w->dapm);
3663 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303664 const char *filename;
3665 const struct firmware *fw;
3666 int i;
3667 int ret = 0;
3668 int num_anc_slots;
3669 struct wcd9xxx_anc_header *anc_head;
3670 struct firmware_cal *hwdep_cal = NULL;
3671 u32 anc_writes_size = 0;
3672 u32 anc_cal_size = 0;
3673 int anc_size_remaining;
3674 u32 *anc_ptr;
3675 u16 reg;
3676 u8 mask, val;
3677 size_t cal_size;
3678 const void *data;
3679
3680 if (!tasha->anc_func)
3681 return 0;
3682
3683 switch (event) {
3684 case SND_SOC_DAPM_PRE_PMU:
3685 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_ANC_CAL);
3686 if (hwdep_cal) {
3687 data = hwdep_cal->data;
3688 cal_size = hwdep_cal->size;
Meng Wang15c825d2018-09-06 10:49:18 +08003689 dev_dbg(component->dev, "%s: using hwdep calibration\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303690 __func__);
3691 } else {
3692 filename = "wcd9335/wcd9335_anc.bin";
Meng Wang15c825d2018-09-06 10:49:18 +08003693 ret = request_firmware(&fw, filename, component->dev);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303694 if (ret != 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08003695 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303696 "Failed to acquire ANC data: %d\n", ret);
3697 return -ENODEV;
3698 }
3699 if (!fw) {
Meng Wang15c825d2018-09-06 10:49:18 +08003700 dev_err(component->dev, "failed to get anc fw");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303701 return -ENODEV;
3702 }
3703 data = fw->data;
3704 cal_size = fw->size;
Meng Wang15c825d2018-09-06 10:49:18 +08003705 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303706 "%s: using request_firmware calibration\n", __func__);
3707 }
3708 if (cal_size < sizeof(struct wcd9xxx_anc_header)) {
Meng Wang15c825d2018-09-06 10:49:18 +08003709 dev_err(component->dev, "Not enough data\n");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303710 ret = -ENOMEM;
3711 goto err;
3712 }
3713 /* First number is the number of register writes */
3714 anc_head = (struct wcd9xxx_anc_header *)(data);
3715 anc_ptr = (u32 *)(data +
3716 sizeof(struct wcd9xxx_anc_header));
3717 anc_size_remaining = cal_size -
3718 sizeof(struct wcd9xxx_anc_header);
3719 num_anc_slots = anc_head->num_anc_slots;
3720
3721 if (tasha->anc_slot >= num_anc_slots) {
Meng Wang15c825d2018-09-06 10:49:18 +08003722 dev_err(component->dev, "Invalid ANC slot selected\n");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303723 ret = -EINVAL;
3724 goto err;
3725 }
3726 for (i = 0; i < num_anc_slots; i++) {
3727 if (anc_size_remaining < TASHA_PACKED_REG_SIZE) {
Meng Wang15c825d2018-09-06 10:49:18 +08003728 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303729 "Invalid register format\n");
3730 ret = -EINVAL;
3731 goto err;
3732 }
3733 anc_writes_size = (u32)(*anc_ptr);
3734 anc_size_remaining -= sizeof(u32);
3735 anc_ptr += 1;
3736
3737 if (anc_writes_size * TASHA_PACKED_REG_SIZE
3738 > anc_size_remaining) {
Meng Wang15c825d2018-09-06 10:49:18 +08003739 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303740 "Invalid register format\n");
3741 ret = -EINVAL;
3742 goto err;
3743 }
3744
3745 if (tasha->anc_slot == i)
3746 break;
3747
3748 anc_size_remaining -= (anc_writes_size *
3749 TASHA_PACKED_REG_SIZE);
3750 anc_ptr += anc_writes_size;
3751 }
3752 if (i == num_anc_slots) {
Meng Wang15c825d2018-09-06 10:49:18 +08003753 dev_err(component->dev, "Selected ANC slot not present\n");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303754 ret = -EINVAL;
3755 goto err;
3756 }
3757
3758 i = 0;
3759 anc_cal_size = anc_writes_size;
3760
3761 if (!strcmp(w->name, "RX INT0 DAC") ||
3762 !strcmp(w->name, "ANC SPK1 PA"))
Meng Wang15c825d2018-09-06 10:49:18 +08003763 tasha_realign_anc_coeff(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303764 WCD9335_CDC_ANC0_IIR_COEFF_1_CTL,
3765 WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
3766
3767 if (!strcmp(w->name, "RX INT1 DAC") ||
3768 !strcmp(w->name, "RX INT3 DAC")) {
Meng Wang15c825d2018-09-06 10:49:18 +08003769 tasha_realign_anc_coeff(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303770 WCD9335_CDC_ANC0_IIR_COEFF_1_CTL,
3771 WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
3772 anc_writes_size = anc_cal_size / 2;
Meng Wang15c825d2018-09-06 10:49:18 +08003773 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303774 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39);
3775 } else if (!strcmp(w->name, "RX INT2 DAC") ||
3776 !strcmp(w->name, "RX INT4 DAC")) {
Meng Wang15c825d2018-09-06 10:49:18 +08003777 tasha_realign_anc_coeff(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303778 WCD9335_CDC_ANC1_IIR_COEFF_1_CTL,
3779 WCD9335_CDC_ANC1_IIR_COEFF_2_CTL);
3780 i = anc_cal_size / 2;
Meng Wang15c825d2018-09-06 10:49:18 +08003781 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303782 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39);
3783 }
3784
3785 for (; i < anc_writes_size; i++) {
3786 TASHA_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val);
Meng Wang15c825d2018-09-06 10:49:18 +08003787 snd_soc_component_write(component, reg, (val & mask));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303788 }
3789 if (!strcmp(w->name, "RX INT1 DAC") ||
3790 !strcmp(w->name, "RX INT3 DAC")) {
Meng Wang15c825d2018-09-06 10:49:18 +08003791 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303792 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08);
3793 } else if (!strcmp(w->name, "RX INT2 DAC") ||
3794 !strcmp(w->name, "RX INT4 DAC")) {
Meng Wang15c825d2018-09-06 10:49:18 +08003795 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303796 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08);
3797 }
3798
3799 if (!hwdep_cal)
3800 release_firmware(fw);
3801 break;
3802 case SND_SOC_DAPM_POST_PMU:
3803 /* Remove ANC Rx from reset */
Meng Wang15c825d2018-09-06 10:49:18 +08003804 snd_soc_component_update_bits(component,
3805 WCD9335_CDC_ANC0_CLK_RESET_CTL,
3806 0x08, 0x00);
3807 snd_soc_component_update_bits(component,
3808 WCD9335_CDC_ANC1_CLK_RESET_CTL,
3809 0x08, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303810 break;
3811 case SND_SOC_DAPM_POST_PMD:
3812 if (!strcmp(w->name, "ANC HPHL PA") ||
3813 !strcmp(w->name, "ANC EAR PA") ||
3814 !strcmp(w->name, "ANC SPK1 PA") ||
3815 !strcmp(w->name, "ANC LINEOUT1 PA")) {
Meng Wang15c825d2018-09-06 10:49:18 +08003816 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303817 WCD9335_CDC_ANC0_MODE_1_CTL, 0x30, 0x00);
3818 msleep(50);
Meng Wang15c825d2018-09-06 10:49:18 +08003819 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303820 WCD9335_CDC_ANC0_MODE_1_CTL, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003821 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303822 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x38);
Meng Wang15c825d2018-09-06 10:49:18 +08003823 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303824 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x07, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003825 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303826 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00);
3827 } else if (!strcmp(w->name, "ANC HPHR PA") ||
3828 !strcmp(w->name, "ANC LINEOUT2 PA")) {
Meng Wang15c825d2018-09-06 10:49:18 +08003829 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303830 WCD9335_CDC_ANC1_MODE_1_CTL, 0x30, 0x00);
3831 msleep(50);
Meng Wang15c825d2018-09-06 10:49:18 +08003832 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303833 WCD9335_CDC_ANC1_MODE_1_CTL, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003834 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303835 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x38);
Meng Wang15c825d2018-09-06 10:49:18 +08003836 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303837 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x07, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08003838 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303839 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x00);
3840 }
3841 break;
3842 }
3843
3844 return 0;
3845err:
3846 if (!hwdep_cal)
3847 release_firmware(fw);
3848 return ret;
3849}
3850
3851static void tasha_codec_clear_anc_tx_hold(struct tasha_priv *tasha)
3852{
3853 if (test_and_clear_bit(ANC_MIC_AMIC1, &tasha->status_mask))
Meng Wang15c825d2018-09-06 10:49:18 +08003854 tasha_codec_set_tx_hold(tasha->component,
3855 WCD9335_ANA_AMIC1, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303856 if (test_and_clear_bit(ANC_MIC_AMIC2, &tasha->status_mask))
Meng Wang15c825d2018-09-06 10:49:18 +08003857 tasha_codec_set_tx_hold(tasha->component,
3858 WCD9335_ANA_AMIC2, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303859 if (test_and_clear_bit(ANC_MIC_AMIC3, &tasha->status_mask))
Meng Wang15c825d2018-09-06 10:49:18 +08003860 tasha_codec_set_tx_hold(tasha->component,
3861 WCD9335_ANA_AMIC3, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303862 if (test_and_clear_bit(ANC_MIC_AMIC4, &tasha->status_mask))
Meng Wang15c825d2018-09-06 10:49:18 +08003863 tasha_codec_set_tx_hold(tasha->component,
3864 WCD9335_ANA_AMIC4, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303865 if (test_and_clear_bit(ANC_MIC_AMIC5, &tasha->status_mask))
Meng Wang15c825d2018-09-06 10:49:18 +08003866 tasha_codec_set_tx_hold(tasha->component,
3867 WCD9335_ANA_AMIC5, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303868 if (test_and_clear_bit(ANC_MIC_AMIC6, &tasha->status_mask))
Meng Wang15c825d2018-09-06 10:49:18 +08003869 tasha_codec_set_tx_hold(tasha->component,
3870 WCD9335_ANA_AMIC6, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303871}
3872
3873static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha,
3874 int mode, int event)
3875{
3876 u8 scale_val = 0;
3877
3878 if (!TASHA_IS_2_0(tasha->wcd9xxx))
3879 return;
3880
3881 switch (event) {
3882 case SND_SOC_DAPM_POST_PMU:
3883 switch (mode) {
3884 case CLS_H_HIFI:
3885 scale_val = 0x3;
3886 break;
3887 case CLS_H_LOHIFI:
3888 scale_val = 0x1;
3889 break;
3890 }
3891 if (tasha->anc_func) {
3892 /* Clear Tx FE HOLD if both PAs are enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08003893 if ((snd_soc_component_read32(
3894 tasha->component, WCD9335_ANA_HPH) &
3895 0xC0) == 0xC0) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303896 tasha_codec_clear_anc_tx_hold(tasha);
3897 }
3898 }
3899 break;
3900 case SND_SOC_DAPM_PRE_PMD:
3901 scale_val = 0x6;
3902 break;
3903 }
3904
3905 if (scale_val)
Meng Wang15c825d2018-09-06 10:49:18 +08003906 snd_soc_component_update_bits(tasha->component,
3907 WCD9335_HPH_PA_CTL1, 0x0E,
3908 scale_val << 1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303909 if (SND_SOC_DAPM_EVENT_ON(event)) {
3910 if (tasha->comp_enabled[COMPANDER_1] ||
3911 tasha->comp_enabled[COMPANDER_2]) {
Meng Wang15c825d2018-09-06 10:49:18 +08003912 snd_soc_component_update_bits(tasha->component,
3913 WCD9335_HPH_L_EN,
3914 0x20, 0x00);
3915 snd_soc_component_update_bits(tasha->component,
3916 WCD9335_HPH_R_EN,
3917 0x20, 0x00);
3918 snd_soc_component_update_bits(tasha->component,
3919 WCD9335_HPH_AUTO_CHOP,
3920 0x20, 0x20);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303921 }
Meng Wang15c825d2018-09-06 10:49:18 +08003922 snd_soc_component_update_bits(tasha->component,
3923 WCD9335_HPH_L_EN, 0x1F,
3924 tasha->hph_l_gain);
3925 snd_soc_component_update_bits(tasha->component,
3926 WCD9335_HPH_R_EN, 0x1F,
3927 tasha->hph_r_gain);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303928 }
3929
3930 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08003931 snd_soc_component_update_bits(tasha->component,
3932 WCD9335_HPH_AUTO_CHOP, 0x20,
3933 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303934 }
3935}
3936
Meng Wang15c825d2018-09-06 10:49:18 +08003937static void tasha_codec_override(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303938 int mode,
3939 int event)
3940{
3941 if (mode == CLS_AB) {
3942 switch (event) {
3943 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08003944 if (!(snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303945 WCD9335_CDC_RX2_RX_PATH_CTL) & 0x10) &&
Meng Wang15c825d2018-09-06 10:49:18 +08003946 (!(snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303947 WCD9335_CDC_RX1_RX_PATH_CTL) & 0x10)))
Meng Wang15c825d2018-09-06 10:49:18 +08003948 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303949 WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02);
3950 break;
3951 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08003952 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303953 WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00);
3954 break;
3955 }
3956 }
3957}
3958
3959static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
3960 struct snd_kcontrol *kcontrol,
3961 int event)
3962{
Meng Wang15c825d2018-09-06 10:49:18 +08003963 struct snd_soc_component *component =
3964 snd_soc_dapm_to_component(w->dapm);
3965 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303966 int hph_mode = tasha->hph_mode;
3967 int ret = 0;
3968
Meng Wang15c825d2018-09-06 10:49:18 +08003969 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303970
3971 switch (event) {
3972 case SND_SOC_DAPM_PRE_PMU:
3973 if ((!(strcmp(w->name, "ANC HPHR PA"))) &&
3974 (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
Meng Wang15c825d2018-09-06 10:49:18 +08003975 snd_soc_component_update_bits(
3976 component, WCD9335_ANA_HPH, 0xC0, 0xC0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303977 }
3978 set_bit(HPH_PA_DELAY, &tasha->status_mask);
Vatsal Buchae9a50072017-09-06 17:40:11 +05303979 if (!(strcmp(w->name, "HPHR PA")))
Meng Wang15c825d2018-09-06 10:49:18 +08003980 snd_soc_component_update_bits(
3981 component, WCD9335_ANA_HPH, 0x40, 0x40);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303982 break;
3983 case SND_SOC_DAPM_POST_PMU:
3984 if (!(strcmp(w->name, "ANC HPHR PA"))) {
Meng Wang15c825d2018-09-06 10:49:18 +08003985 if ((snd_soc_component_read32(
3986 component, WCD9335_ANA_HPH) & 0xC0) != 0xC0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303987 /*
3988 * If PA_EN is not set (potentially in ANC case)
3989 * then do nothing for POST_PMU and let left
3990 * channel handle everything.
3991 */
3992 break;
3993 }
3994 /*
3995 * 7ms sleep is required after PA is enabled as per
3996 * HW requirement
3997 */
3998 if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
3999 usleep_range(7000, 7100);
4000 clear_bit(HPH_PA_DELAY, &tasha->status_mask);
4001 }
4002 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
Meng Wang15c825d2018-09-06 10:49:18 +08004003 snd_soc_component_update_bits(component,
4004 WCD9335_CDC_RX2_RX_PATH_CTL,
4005 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304006 /* Remove mix path mute if it is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08004007 if ((snd_soc_component_read32(
4008 component, WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & 0x10)
4009 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304010 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
4011 0x10, 0x00);
4012
4013 if (!(strcmp(w->name, "ANC HPHR PA"))) {
4014 /* Do everything needed for left channel */
Meng Wang15c825d2018-09-06 10:49:18 +08004015 snd_soc_component_update_bits(component,
4016 WCD9335_CDC_RX1_RX_PATH_CTL,
4017 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304018 /* Remove mix path mute if it is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08004019 if ((snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304020 WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
4021 0x10)
Meng Wang15c825d2018-09-06 10:49:18 +08004022 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304023 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
4024 0x10, 0x00);
4025 /* Remove ANC Rx from reset */
4026 ret = tasha_codec_enable_anc(w, kcontrol, event);
4027 }
Meng Wang15c825d2018-09-06 10:49:18 +08004028 tasha_codec_override(component, hph_mode, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304029 break;
4030
4031 case SND_SOC_DAPM_PRE_PMD:
4032 blocking_notifier_call_chain(&tasha->notifier,
4033 WCD_EVENT_PRE_HPHR_PA_OFF,
4034 &tasha->mbhc);
4035 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
Vatsal Buchae9a50072017-09-06 17:40:11 +05304036 if (!(strcmp(w->name, "ANC HPHR PA")) ||
4037 !(strcmp(w->name, "HPHR PA")))
Meng Wang15c825d2018-09-06 10:49:18 +08004038 snd_soc_component_update_bits(component,
4039 WCD9335_ANA_HPH, 0x40, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304040 break;
4041 case SND_SOC_DAPM_POST_PMD:
4042 /* 5ms sleep is required after PA is disabled as per
4043 * HW requirement
4044 */
4045 usleep_range(5000, 5500);
Meng Wang15c825d2018-09-06 10:49:18 +08004046 tasha_codec_override(component, hph_mode, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304047 blocking_notifier_call_chain(&tasha->notifier,
4048 WCD_EVENT_POST_HPHR_PA_OFF,
4049 &tasha->mbhc);
4050
4051 if (!(strcmp(w->name, "ANC HPHR PA"))) {
4052 ret = tasha_codec_enable_anc(w, kcontrol, event);
Meng Wang15c825d2018-09-06 10:49:18 +08004053 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304054 WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x00);
4055 }
4056 break;
4057 };
4058
4059 return ret;
4060}
4061
4062static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
4063 struct snd_kcontrol *kcontrol,
4064 int event)
4065{
Meng Wang15c825d2018-09-06 10:49:18 +08004066 struct snd_soc_component *component =
4067 snd_soc_dapm_to_component(w->dapm);
4068 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304069 int hph_mode = tasha->hph_mode;
4070 int ret = 0;
4071
Meng Wang15c825d2018-09-06 10:49:18 +08004072 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304073
4074 switch (event) {
4075 case SND_SOC_DAPM_PRE_PMU:
4076 if ((!(strcmp(w->name, "ANC HPHL PA"))) &&
4077 (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
Meng Wang15c825d2018-09-06 10:49:18 +08004078 snd_soc_component_update_bits(component,
4079 WCD9335_ANA_HPH, 0xC0, 0xC0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304080 }
Vatsal Buchae9a50072017-09-06 17:40:11 +05304081 if (!(strcmp(w->name, "HPHL PA")))
Meng Wang15c825d2018-09-06 10:49:18 +08004082 snd_soc_component_update_bits(component,
4083 WCD9335_ANA_HPH, 0x80, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304084 set_bit(HPH_PA_DELAY, &tasha->status_mask);
4085 break;
4086 case SND_SOC_DAPM_POST_PMU:
4087 if (!(strcmp(w->name, "ANC HPHL PA"))) {
Meng Wang15c825d2018-09-06 10:49:18 +08004088 if ((snd_soc_component_read32(
4089 component, WCD9335_ANA_HPH) & 0xC0) != 0xC0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304090 /*
4091 * If PA_EN is not set (potentially in ANC case)
4092 * then do nothing for POST_PMU and let right
4093 * channel handle everything.
4094 */
4095 break;
4096 }
4097 /*
4098 * 7ms sleep is required after PA is enabled as per
4099 * HW requirement
4100 */
4101 if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
4102 usleep_range(7000, 7100);
4103 clear_bit(HPH_PA_DELAY, &tasha->status_mask);
4104 }
4105
4106 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
Meng Wang15c825d2018-09-06 10:49:18 +08004107 snd_soc_component_update_bits(component,
4108 WCD9335_CDC_RX1_RX_PATH_CTL,
4109 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304110 /* Remove mix path mute if it is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08004111 if ((snd_soc_component_read32(
4112 component, WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & 0x10)
4113 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304114 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
4115 0x10, 0x00);
4116
4117 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4118 /* Do everything needed for right channel */
Meng Wang15c825d2018-09-06 10:49:18 +08004119 snd_soc_component_update_bits(component,
4120 WCD9335_CDC_RX2_RX_PATH_CTL,
4121 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304122 /* Remove mix path mute if it is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08004123 if ((snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304124 WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
4125 0x10)
Meng Wang15c825d2018-09-06 10:49:18 +08004126 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304127 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
4128 0x10, 0x00);
4129
4130 /* Remove ANC Rx from reset */
4131 ret = tasha_codec_enable_anc(w, kcontrol, event);
4132 }
Meng Wang15c825d2018-09-06 10:49:18 +08004133 tasha_codec_override(component, hph_mode, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304134 break;
4135 case SND_SOC_DAPM_PRE_PMD:
4136 blocking_notifier_call_chain(&tasha->notifier,
4137 WCD_EVENT_PRE_HPHL_PA_OFF,
4138 &tasha->mbhc);
4139 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
Vatsal Buchae9a50072017-09-06 17:40:11 +05304140 if (!(strcmp(w->name, "ANC HPHL PA")) ||
4141 !(strcmp(w->name, "HPHL PA")))
Meng Wang15c825d2018-09-06 10:49:18 +08004142 snd_soc_component_update_bits(component,
4143 WCD9335_ANA_HPH, 0x80, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304144 break;
4145 case SND_SOC_DAPM_POST_PMD:
4146 /* 5ms sleep is required after PA is disabled as per
4147 * HW requirement
4148 */
4149 usleep_range(5000, 5500);
Meng Wang15c825d2018-09-06 10:49:18 +08004150 tasha_codec_override(component, hph_mode, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304151 blocking_notifier_call_chain(&tasha->notifier,
4152 WCD_EVENT_POST_HPHL_PA_OFF,
4153 &tasha->mbhc);
4154
4155 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4156 ret = tasha_codec_enable_anc(w, kcontrol, event);
Meng Wang15c825d2018-09-06 10:49:18 +08004157 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304158 WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00);
4159 }
4160 break;
4161 };
4162
4163 return ret;
4164}
4165
4166static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
4167 struct snd_kcontrol *kcontrol,
4168 int event)
4169{
Meng Wang15c825d2018-09-06 10:49:18 +08004170 struct snd_soc_component *component =
4171 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304172 u16 lineout_vol_reg = 0, lineout_mix_vol_reg = 0;
4173 int ret = 0;
4174
Meng Wang15c825d2018-09-06 10:49:18 +08004175 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304176
4177 if (w->reg == WCD9335_ANA_LO_1_2) {
4178 if (w->shift == 7) {
4179 lineout_vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4180 lineout_mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL;
4181 } else if (w->shift == 6) {
4182 lineout_vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4183 lineout_mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL;
4184 }
4185 } else if (w->reg == WCD9335_ANA_LO_3_4) {
4186 if (w->shift == 7) {
4187 lineout_vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4188 lineout_mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL;
4189 } else if (w->shift == 6) {
4190 lineout_vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4191 lineout_mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL;
4192 }
4193 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08004194 dev_err(component->dev, "%s: Error enabling lineout PA\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304195 __func__);
4196 return -EINVAL;
4197 }
4198
4199 switch (event) {
4200 case SND_SOC_DAPM_POST_PMU:
4201 /* 5ms sleep is required after PA is enabled as per
4202 * HW requirement
4203 */
4204 usleep_range(5000, 5500);
Meng Wang15c825d2018-09-06 10:49:18 +08004205 snd_soc_component_update_bits(component, lineout_vol_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304206 0x10, 0x00);
4207 /* Remove mix path mute if it is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08004208 if ((snd_soc_component_read32(
4209 component, lineout_mix_vol_reg)) & 0x10)
4210 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304211 lineout_mix_vol_reg,
4212 0x10, 0x00);
4213 if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
4214 !(strcmp(w->name, "ANC LINEOUT2 PA")))
4215 ret = tasha_codec_enable_anc(w, kcontrol, event);
Meng Wang15c825d2018-09-06 10:49:18 +08004216 tasha_codec_override(component, CLS_AB, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304217 break;
4218 case SND_SOC_DAPM_POST_PMD:
4219 /* 5ms sleep is required after PA is disabled as per
4220 * HW requirement
4221 */
4222 usleep_range(5000, 5500);
Meng Wang15c825d2018-09-06 10:49:18 +08004223 tasha_codec_override(component, CLS_AB, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304224 if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
4225 !(strcmp(w->name, "ANC LINEOUT2 PA"))) {
4226 ret = tasha_codec_enable_anc(w, kcontrol, event);
4227 if (!(strcmp(w->name, "ANC LINEOUT1 PA")))
Meng Wang15c825d2018-09-06 10:49:18 +08004228 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304229 WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10);
4230 else
Meng Wang15c825d2018-09-06 10:49:18 +08004231 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304232 WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10);
4233 }
4234 break;
4235 };
4236
4237 return ret;
4238}
4239
4240static void tasha_spk_anc_update_callback(struct work_struct *work)
4241{
4242 struct spk_anc_work *spk_anc_dwork;
4243 struct tasha_priv *tasha;
4244 struct delayed_work *delayed_work;
Meng Wang15c825d2018-09-06 10:49:18 +08004245 struct snd_soc_component *component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304246
4247 delayed_work = to_delayed_work(work);
4248 spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork);
4249 tasha = spk_anc_dwork->tasha;
Meng Wang15c825d2018-09-06 10:49:18 +08004250 component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304251
Meng Wang15c825d2018-09-06 10:49:18 +08004252 snd_soc_component_update_bits(component, WCD9335_CDC_RX7_RX_PATH_CFG0,
4253 0x10, 0x10);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304254}
4255
4256static int tasha_codec_enable_spk_anc(struct snd_soc_dapm_widget *w,
4257 struct snd_kcontrol *kcontrol,
4258 int event)
4259{
4260 int ret = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08004261 struct snd_soc_component *component =
4262 snd_soc_dapm_to_component(w->dapm);
4263 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304264
Meng Wang15c825d2018-09-06 10:49:18 +08004265 dev_dbg(component->dev, "%s %s %d %d\n", __func__, w->name, event,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304266 tasha->anc_func);
4267
4268 if (!tasha->anc_func)
4269 return 0;
4270
4271 switch (event) {
4272 case SND_SOC_DAPM_PRE_PMU:
4273 ret = tasha_codec_enable_anc(w, kcontrol, event);
4274 schedule_delayed_work(&tasha->spk_anc_dwork.dwork,
4275 msecs_to_jiffies(spk_anc_en_delay));
4276 break;
4277 case SND_SOC_DAPM_POST_PMD:
4278 cancel_delayed_work_sync(&tasha->spk_anc_dwork.dwork);
Meng Wang15c825d2018-09-06 10:49:18 +08004279 snd_soc_component_update_bits(component,
4280 WCD9335_CDC_RX7_RX_PATH_CFG0,
4281 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304282 ret = tasha_codec_enable_anc(w, kcontrol, event);
4283 break;
4284 }
4285 return ret;
4286}
4287
4288static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
4289 struct snd_kcontrol *kcontrol,
4290 int event)
4291{
Meng Wang15c825d2018-09-06 10:49:18 +08004292 struct snd_soc_component *component =
4293 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304294 int ret = 0;
4295
Meng Wang15c825d2018-09-06 10:49:18 +08004296 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304297
4298 switch (event) {
4299 case SND_SOC_DAPM_POST_PMU:
4300 /* 5ms sleep is required after PA is enabled as per
4301 * HW requirement
4302 */
4303 usleep_range(5000, 5500);
Meng Wang15c825d2018-09-06 10:49:18 +08004304 snd_soc_component_update_bits(component,
4305 WCD9335_CDC_RX0_RX_PATH_CTL,
4306 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304307 /* Remove mix path mute if it is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08004308 if ((snd_soc_component_read32(
4309 component, WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) & 0x10)
4310 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304311 WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
4312 0x10, 0x00);
4313 break;
4314 case SND_SOC_DAPM_POST_PMD:
4315 /* 5ms sleep is required after PA is disabled as per
4316 * HW requirement
4317 */
4318 usleep_range(5000, 5500);
4319
4320 if (!(strcmp(w->name, "ANC EAR PA"))) {
4321 ret = tasha_codec_enable_anc(w, kcontrol, event);
Meng Wang15c825d2018-09-06 10:49:18 +08004322 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304323 WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x00);
4324 }
4325 break;
4326 };
4327
4328 return ret;
4329}
4330
Meng Wang15c825d2018-09-06 10:49:18 +08004331static void tasha_codec_hph_mode_gain_opt(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304332 u8 gain)
4333{
Meng Wang15c825d2018-09-06 10:49:18 +08004334 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304335 u8 hph_l_en, hph_r_en;
4336 u8 l_val, r_val;
4337 u8 hph_pa_status;
4338 bool is_hphl_pa, is_hphr_pa;
4339
Meng Wang15c825d2018-09-06 10:49:18 +08004340 hph_pa_status = snd_soc_component_read32(component, WCD9335_ANA_HPH);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304341 is_hphl_pa = hph_pa_status >> 7;
4342 is_hphr_pa = (hph_pa_status & 0x40) >> 6;
4343
Meng Wang15c825d2018-09-06 10:49:18 +08004344 hph_l_en = snd_soc_component_read32(component, WCD9335_HPH_L_EN);
4345 hph_r_en = snd_soc_component_read32(component, WCD9335_HPH_R_EN);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304346
4347 l_val = (hph_l_en & 0xC0) | 0x20 | gain;
4348 r_val = (hph_r_en & 0xC0) | 0x20 | gain;
4349
4350 /*
4351 * Set HPH_L & HPH_R gain source selection to REGISTER
4352 * for better click and pop only if corresponding PAs are
4353 * not enabled. Also cache the values of the HPHL/R
4354 * PA gains to be applied after PAs are enabled
4355 */
4356 if ((l_val != hph_l_en) && !is_hphl_pa) {
Meng Wang15c825d2018-09-06 10:49:18 +08004357 snd_soc_component_write(component, WCD9335_HPH_L_EN, l_val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304358 tasha->hph_l_gain = hph_l_en & 0x1F;
4359 }
4360
4361 if ((r_val != hph_r_en) && !is_hphr_pa) {
Meng Wang15c825d2018-09-06 10:49:18 +08004362 snd_soc_component_write(component, WCD9335_HPH_R_EN, r_val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304363 tasha->hph_r_gain = hph_r_en & 0x1F;
4364 }
4365}
4366
Meng Wang15c825d2018-09-06 10:49:18 +08004367static void tasha_codec_hph_lohifi_config(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304368 int event)
4369{
4370 if (SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004371 snd_soc_component_update_bits(component,
4372 WCD9335_RX_BIAS_HPH_PA,
4373 0x0F, 0x06);
4374 snd_soc_component_update_bits(component,
4375 WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
4376 0xF0, 0x40);
4377 snd_soc_component_update_bits(component,
4378 WCD9335_HPH_CNP_WG_CTL,
4379 0x07, 0x03);
4380 snd_soc_component_update_bits(component,
4381 WCD9335_HPH_PA_CTL2,
4382 0x08, 0x08);
4383 snd_soc_component_update_bits(component,
4384 WCD9335_HPH_PA_CTL1,
4385 0x0E, 0x0C);
4386 tasha_codec_hph_mode_gain_opt(component, 0x11);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304387 }
4388
4389 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004390 snd_soc_component_update_bits(component,
4391 WCD9335_HPH_PA_CTL2,
4392 0x08, 0x00);
4393 snd_soc_component_update_bits(component,
4394 WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4395 snd_soc_component_write(component,
4396 WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A);
4397 snd_soc_component_update_bits(component,
4398 WCD9335_RX_BIAS_HPH_PA,
4399 0x0F, 0x0A);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304400 }
4401}
4402
Meng Wang15c825d2018-09-06 10:49:18 +08004403static void tasha_codec_hph_lp_config(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304404 int event)
4405{
4406 if (SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004407 snd_soc_component_update_bits(component,
4408 WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4409 tasha_codec_hph_mode_gain_opt(component, 0x10);
4410 snd_soc_component_update_bits(component,
4411 WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4412 snd_soc_component_update_bits(component,
4413 WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4414 snd_soc_component_update_bits(component,
4415 WCD9335_HPH_PA_CTL2, 0x04, 0x04);
4416 snd_soc_component_update_bits(component,
4417 WCD9335_HPH_PA_CTL2, 0x20, 0x20);
4418 snd_soc_component_update_bits(component,
4419 WCD9335_HPH_RDAC_LDO_CTL, 0x07, 0x01);
4420 snd_soc_component_update_bits(component,
4421 WCD9335_HPH_RDAC_LDO_CTL, 0x70, 0x10);
4422 snd_soc_component_update_bits(component,
4423 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x0F, 0x01);
4424 snd_soc_component_update_bits(component,
4425 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0xF0, 0x10);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304426 }
4427
4428 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004429 snd_soc_component_write(component,
4430 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88);
4431 snd_soc_component_write(component,
4432 WCD9335_HPH_RDAC_LDO_CTL, 0x33);
4433 snd_soc_component_update_bits(component,
4434 WCD9335_HPH_PA_CTL2, 0x20, 0x00);
4435 snd_soc_component_update_bits(component,
4436 WCD9335_HPH_PA_CTL2, 0x04, 0x00);
4437 snd_soc_component_update_bits(component,
4438 WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4439 snd_soc_component_update_bits(component,
4440 WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4441 snd_soc_component_update_bits(component,
4442 WCD9335_HPH_R_EN, 0xC0, 0x80);
4443 snd_soc_component_update_bits(component,
4444 WCD9335_HPH_L_EN, 0xC0, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304445 }
4446}
4447
Meng Wang15c825d2018-09-06 10:49:18 +08004448static void tasha_codec_hph_hifi_config(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304449 int event)
4450{
4451 if (SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004452 snd_soc_component_update_bits(component,
4453 WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4454 snd_soc_component_update_bits(component,
4455 WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4456 snd_soc_component_update_bits(component,
4457 WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4458 tasha_codec_hph_mode_gain_opt(component, 0x11);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304459 }
4460
4461 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004462 snd_soc_component_update_bits(component,
4463 WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4464 snd_soc_component_update_bits(component,
4465 WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304466 }
4467}
4468
Meng Wang15c825d2018-09-06 10:49:18 +08004469static void tasha_codec_hph_mode_config(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304470 int event, int mode)
4471{
Meng Wang15c825d2018-09-06 10:49:18 +08004472 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304473
4474 if (!TASHA_IS_2_0(tasha->wcd9xxx))
4475 return;
4476
4477 switch (mode) {
4478 case CLS_H_LP:
Meng Wang15c825d2018-09-06 10:49:18 +08004479 tasha_codec_hph_lp_config(component, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304480 break;
4481 case CLS_H_LOHIFI:
Meng Wang15c825d2018-09-06 10:49:18 +08004482 tasha_codec_hph_lohifi_config(component, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304483 break;
4484 case CLS_H_HIFI:
Meng Wang15c825d2018-09-06 10:49:18 +08004485 tasha_codec_hph_hifi_config(component, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304486 break;
4487 }
4488}
4489
4490static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
4491 struct snd_kcontrol *kcontrol,
4492 int event)
4493{
Meng Wang15c825d2018-09-06 10:49:18 +08004494 struct snd_soc_component *component =
4495 snd_soc_dapm_to_component(w->dapm);
4496 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
4497 struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304498 int hph_mode = tasha->hph_mode;
4499 u8 dem_inp;
4500 int ret = 0;
4501
Meng Wang15c825d2018-09-06 10:49:18 +08004502 dev_dbg(component->dev, "%s wname: %s event: %d hph_mode: %d\n",
4503 __func__, w->name, event, hph_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304504
4505 switch (event) {
4506 case SND_SOC_DAPM_PRE_PMU:
4507 if (tasha->anc_func) {
4508 ret = tasha_codec_enable_anc(w, kcontrol, event);
4509 /* 40 msec delay is needed to avoid click and pop */
4510 msleep(40);
4511 }
4512
4513 /* Read DEM INP Select */
Meng Wang15c825d2018-09-06 10:49:18 +08004514 dem_inp = snd_soc_component_read32(
4515 component, WCD9335_CDC_RX2_RX_PATH_SEC0) &
4516 0x03;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304517 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
4518 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004519 dev_err(component->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304520 __func__, hph_mode);
4521 return -EINVAL;
4522 }
Meng Wang15c825d2018-09-06 10:49:18 +08004523 wcd_clsh_fsm(component, &tasha->clsh_d,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304524 WCD_CLSH_EVENT_PRE_DAC,
4525 WCD_CLSH_STATE_HPHR,
4526 ((hph_mode == CLS_H_LOHIFI) ?
4527 CLS_H_HIFI : hph_mode));
4528
Vatsal Buchae9a50072017-09-06 17:40:11 +05304529 if (!(strcmp(w->name, "RX INT2 DAC")))
Meng Wang15c825d2018-09-06 10:49:18 +08004530 snd_soc_component_update_bits(component,
4531 WCD9335_ANA_HPH, 0x10, 0x10);
Vatsal Buchae9a50072017-09-06 17:40:11 +05304532
Meng Wang15c825d2018-09-06 10:49:18 +08004533 tasha_codec_hph_mode_config(component, event, hph_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304534
4535 if (tasha->anc_func)
Meng Wang15c825d2018-09-06 10:49:18 +08004536 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304537 WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10);
4538
4539 break;
4540 case SND_SOC_DAPM_POST_PMU:
4541 /* 1000us required as per HW requirement */
4542 usleep_range(1000, 1100);
4543 if ((hph_mode == CLS_H_LP) &&
4544 (TASHA_IS_1_1(wcd9xxx))) {
Meng Wang15c825d2018-09-06 10:49:18 +08004545 snd_soc_component_update_bits(component,
4546 WCD9335_HPH_L_DAC_CTL, 0x03, 0x03);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304547 }
4548 break;
4549 case SND_SOC_DAPM_PRE_PMD:
4550 if ((hph_mode == CLS_H_LP) &&
4551 (TASHA_IS_1_1(wcd9xxx))) {
Meng Wang15c825d2018-09-06 10:49:18 +08004552 snd_soc_component_update_bits(component,
4553 WCD9335_HPH_L_DAC_CTL,
4554 0x03, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304555 }
Vatsal Buchae9a50072017-09-06 17:40:11 +05304556 if (!(strcmp(w->name, "RX INT2 DAC")))
Meng Wang15c825d2018-09-06 10:49:18 +08004557 snd_soc_component_update_bits(component,
4558 WCD9335_ANA_HPH, 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304559 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))
Meng Wang15c825d2018-09-06 10:49:18 +08004566 tasha_codec_hph_mode_config(component, event, hph_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304567
Meng Wang15c825d2018-09-06 10:49:18 +08004568 wcd_clsh_fsm(component, &tasha->clsh_d,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304569 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{
Meng Wang15c825d2018-09-06 10:49:18 +08004583 struct snd_soc_component *component =
4584 snd_soc_dapm_to_component(w->dapm);
4585 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
4586 struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304587 int hph_mode = tasha->hph_mode;
4588 u8 dem_inp;
4589 int ret = 0;
4590 uint32_t impedl = 0, impedr = 0;
4591
Meng Wang15c825d2018-09-06 10:49:18 +08004592 dev_dbg(component->dev, "%s wname: %s event: %d hph_mode: %d\n",
4593 __func__, w->name, event, hph_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304594
4595 switch (event) {
4596 case SND_SOC_DAPM_PRE_PMU:
4597 if (tasha->anc_func) {
4598 ret = tasha_codec_enable_anc(w, kcontrol, event);
4599 /* 40 msec delay is needed to avoid click and pop */
4600 msleep(40);
4601 }
4602
4603 /* Read DEM INP Select */
Meng Wang15c825d2018-09-06 10:49:18 +08004604 dem_inp = snd_soc_component_read32(
4605 component, WCD9335_CDC_RX1_RX_PATH_SEC0) &
4606 0x03;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304607 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
4608 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004609 dev_err(component->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304610 __func__, hph_mode);
4611 return -EINVAL;
4612 }
Meng Wang15c825d2018-09-06 10:49:18 +08004613 wcd_clsh_fsm(component, &tasha->clsh_d,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304614 WCD_CLSH_EVENT_PRE_DAC,
4615 WCD_CLSH_STATE_HPHL,
4616 ((hph_mode == CLS_H_LOHIFI) ?
4617 CLS_H_HIFI : hph_mode));
4618
Vatsal Buchae9a50072017-09-06 17:40:11 +05304619 if (!(strcmp(w->name, "RX INT1 DAC")))
Meng Wang15c825d2018-09-06 10:49:18 +08004620 snd_soc_component_update_bits(component,
4621 WCD9335_ANA_HPH, 0x20, 0x20);
Vatsal Buchae9a50072017-09-06 17:40:11 +05304622
Meng Wang15c825d2018-09-06 10:49:18 +08004623 tasha_codec_hph_mode_config(component, event, hph_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304624
4625 if (tasha->anc_func)
Meng Wang15c825d2018-09-06 10:49:18 +08004626 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304627 WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);
4628
4629 ret = wcd_mbhc_get_impedance(&tasha->mbhc,
4630 &impedl, &impedr);
4631 if (!ret) {
Meng Wang15c825d2018-09-06 10:49:18 +08004632 wcd_clsh_imped_config(component, impedl, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304633 set_bit(CLASSH_CONFIG, &tasha->status_mask);
4634 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08004635 dev_dbg(component->dev, "%s: Failed to get mbhc impedance %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304636 __func__, ret);
4637 ret = 0;
4638 }
4639
4640
4641 break;
4642 case SND_SOC_DAPM_POST_PMU:
4643 /* 1000us required as per HW requirement */
4644 usleep_range(1000, 1100);
4645 if ((hph_mode == CLS_H_LP) &&
4646 (TASHA_IS_1_1(wcd9xxx))) {
Meng Wang15c825d2018-09-06 10:49:18 +08004647 snd_soc_component_update_bits(component,
4648 WCD9335_HPH_L_DAC_CTL,
4649 0x03, 0x03);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304650 }
4651 break;
4652 case SND_SOC_DAPM_PRE_PMD:
Vatsal Buchae9a50072017-09-06 17:40:11 +05304653 if (!(strcmp(w->name, "RX INT1 DAC")))
Meng Wang15c825d2018-09-06 10:49:18 +08004654 snd_soc_component_update_bits(component,
4655 WCD9335_ANA_HPH, 0x20, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304656 if ((hph_mode == CLS_H_LP) &&
4657 (TASHA_IS_1_1(wcd9xxx))) {
Meng Wang15c825d2018-09-06 10:49:18 +08004658 snd_soc_component_update_bits(component,
4659 WCD9335_HPH_L_DAC_CTL,
4660 0x03, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304661 }
4662 break;
4663 case SND_SOC_DAPM_POST_PMD:
4664 /* 1000us required as per HW requirement */
4665 usleep_range(1000, 1100);
4666
4667 if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
4668 WCD_CLSH_STATE_HPHR))
Meng Wang15c825d2018-09-06 10:49:18 +08004669 tasha_codec_hph_mode_config(component, event, hph_mode);
4670 wcd_clsh_fsm(component, &tasha->clsh_d,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304671 WCD_CLSH_EVENT_POST_PA,
4672 WCD_CLSH_STATE_HPHL,
4673 ((hph_mode == CLS_H_LOHIFI) ?
4674 CLS_H_HIFI : hph_mode));
4675
4676 if (test_bit(CLASSH_CONFIG, &tasha->status_mask)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004677 wcd_clsh_imped_config(component, impedl, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304678 clear_bit(CLASSH_CONFIG, &tasha->status_mask);
4679 } else
Meng Wang15c825d2018-09-06 10:49:18 +08004680 dev_dbg(component->dev, "%s: Failed to get mbhc impedance %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304681 __func__, ret);
4682
4683
4684 break;
4685 };
4686
4687 return ret;
4688}
4689
4690static int tasha_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
4691 struct snd_kcontrol *kcontrol,
4692 int event)
4693{
Meng Wang15c825d2018-09-06 10:49:18 +08004694 struct snd_soc_component *component =
4695 snd_soc_dapm_to_component(w->dapm);
4696 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304697 int ret = 0;
4698
Meng Wang15c825d2018-09-06 10:49:18 +08004699 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304700
4701 switch (event) {
4702 case SND_SOC_DAPM_PRE_PMU:
4703 if (tasha->anc_func &&
4704 (!strcmp(w->name, "RX INT3 DAC") ||
4705 !strcmp(w->name, "RX INT4 DAC")))
4706 ret = tasha_codec_enable_anc(w, kcontrol, event);
4707
Meng Wang15c825d2018-09-06 10:49:18 +08004708 wcd_clsh_fsm(component, &tasha->clsh_d,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304709 WCD_CLSH_EVENT_PRE_DAC,
4710 WCD_CLSH_STATE_LO,
4711 CLS_AB);
4712
4713 if (tasha->anc_func) {
4714 if (!strcmp(w->name, "RX INT3 DAC"))
Meng Wang15c825d2018-09-06 10:49:18 +08004715 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304716 WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10);
4717 else if (!strcmp(w->name, "RX INT4 DAC"))
Meng Wang15c825d2018-09-06 10:49:18 +08004718 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304719 WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10);
4720 }
4721 break;
4722 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08004723 wcd_clsh_fsm(component, &tasha->clsh_d,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304724 WCD_CLSH_EVENT_POST_PA,
4725 WCD_CLSH_STATE_LO,
4726 CLS_AB);
4727 break;
4728 }
4729
4730 return 0;
4731}
4732
4733static const struct snd_soc_dapm_widget tasha_dapm_i2s_widgets[] = {
4734 SND_SOC_DAPM_SUPPLY("RX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
4735 0, 0, NULL, 0),
4736 SND_SOC_DAPM_SUPPLY("TX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
4737 0, 0, NULL, 0),
4738};
4739
4740static int tasha_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
4741 struct snd_kcontrol *kcontrol,
4742 int event)
4743{
Meng Wang15c825d2018-09-06 10:49:18 +08004744 struct snd_soc_component *component =
4745 snd_soc_dapm_to_component(w->dapm);
4746 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304747 int ret = 0;
4748
Meng Wang15c825d2018-09-06 10:49:18 +08004749 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304750
4751 switch (event) {
4752 case SND_SOC_DAPM_PRE_PMU:
4753 if (tasha->anc_func)
4754 ret = tasha_codec_enable_anc(w, kcontrol, event);
4755
Meng Wang15c825d2018-09-06 10:49:18 +08004756 wcd_clsh_fsm(component, &tasha->clsh_d,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304757 WCD_CLSH_EVENT_PRE_DAC,
4758 WCD_CLSH_STATE_EAR,
4759 CLS_H_NORMAL);
4760 if (tasha->anc_func)
Meng Wang15c825d2018-09-06 10:49:18 +08004761 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304762 WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x10);
4763
4764 break;
4765 case SND_SOC_DAPM_POST_PMU:
4766 break;
4767 case SND_SOC_DAPM_PRE_PMD:
4768 break;
4769 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08004770 wcd_clsh_fsm(component, &tasha->clsh_d,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304771 WCD_CLSH_EVENT_POST_PA,
4772 WCD_CLSH_STATE_EAR,
4773 CLS_H_NORMAL);
4774 break;
4775 };
4776
4777 return ret;
4778}
4779
4780static int tasha_codec_spk_boost_event(struct snd_soc_dapm_widget *w,
4781 struct snd_kcontrol *kcontrol,
4782 int event)
4783{
Meng Wang15c825d2018-09-06 10:49:18 +08004784 struct snd_soc_component *component =
4785 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304786 u16 boost_path_ctl, boost_path_cfg1;
4787 u16 reg, reg_mix;
4788
Meng Wang15c825d2018-09-06 10:49:18 +08004789 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304790
4791 if (!strcmp(w->name, "RX INT7 CHAIN")) {
4792 boost_path_ctl = WCD9335_CDC_BOOST0_BOOST_PATH_CTL;
4793 boost_path_cfg1 = WCD9335_CDC_RX7_RX_PATH_CFG1;
4794 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4795 reg_mix = WCD9335_CDC_RX7_RX_PATH_MIX_CTL;
4796 } else if (!strcmp(w->name, "RX INT8 CHAIN")) {
4797 boost_path_ctl = WCD9335_CDC_BOOST1_BOOST_PATH_CTL;
4798 boost_path_cfg1 = WCD9335_CDC_RX8_RX_PATH_CFG1;
4799 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4800 reg_mix = WCD9335_CDC_RX8_RX_PATH_MIX_CTL;
4801 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08004802 dev_err(component->dev, "%s: unknown widget: %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304803 __func__, w->name);
4804 return -EINVAL;
4805 }
4806
4807 switch (event) {
4808 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08004809 snd_soc_component_update_bits(component, boost_path_ctl,
4810 0x10, 0x10);
4811 snd_soc_component_update_bits(component, boost_path_cfg1,
4812 0x01, 0x01);
4813 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
4814 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
4815 snd_soc_component_update_bits(component, reg_mix,
4816 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304817 break;
4818 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08004819 snd_soc_component_update_bits(component, boost_path_cfg1,
4820 0x01, 0x00);
4821 snd_soc_component_update_bits(component, boost_path_ctl,
4822 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304823 break;
4824 };
4825
4826 return 0;
4827}
4828
4829static u16 tasha_interp_get_primary_reg(u16 reg, u16 *ind)
4830{
4831 u16 prim_int_reg = 0;
4832
4833 switch (reg) {
4834 case WCD9335_CDC_RX0_RX_PATH_CTL:
4835 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
4836 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
4837 *ind = 0;
4838 break;
4839 case WCD9335_CDC_RX1_RX_PATH_CTL:
4840 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
4841 prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4842 *ind = 1;
4843 break;
4844 case WCD9335_CDC_RX2_RX_PATH_CTL:
4845 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
4846 prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
4847 *ind = 2;
4848 break;
4849 case WCD9335_CDC_RX3_RX_PATH_CTL:
4850 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
4851 prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4852 *ind = 3;
4853 break;
4854 case WCD9335_CDC_RX4_RX_PATH_CTL:
4855 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
4856 prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4857 *ind = 4;
4858 break;
4859 case WCD9335_CDC_RX5_RX_PATH_CTL:
4860 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
4861 prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4862 *ind = 5;
4863 break;
4864 case WCD9335_CDC_RX6_RX_PATH_CTL:
4865 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
4866 prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4867 *ind = 6;
4868 break;
4869 case WCD9335_CDC_RX7_RX_PATH_CTL:
4870 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
4871 prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4872 *ind = 7;
4873 break;
4874 case WCD9335_CDC_RX8_RX_PATH_CTL:
4875 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
4876 prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4877 *ind = 8;
4878 break;
4879 };
4880
4881 return prim_int_reg;
4882}
4883
Meng Wang15c825d2018-09-06 10:49:18 +08004884static void tasha_codec_hd2_control(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304885 u16 prim_int_reg, int event)
4886{
Meng Wang15c825d2018-09-06 10:49:18 +08004887 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304888 u16 hd2_scale_reg;
4889 u16 hd2_enable_reg = 0;
4890
4891 if (!TASHA_IS_2_0(tasha->wcd9xxx))
4892 return;
4893
4894 if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
4895 hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3;
4896 hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4897 }
4898 if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) {
4899 hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3;
4900 hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
4901 }
4902
4903 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004904 snd_soc_component_update_bits(component, hd2_scale_reg,
4905 0x3C, 0x10);
4906 snd_soc_component_update_bits(component, hd2_scale_reg,
4907 0x03, 0x01);
4908 snd_soc_component_update_bits(component, hd2_enable_reg,
4909 0x04, 0x04);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304910 }
4911
4912 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08004913 snd_soc_component_update_bits(component, hd2_enable_reg,
4914 0x04, 0x00);
4915 snd_soc_component_update_bits(component, hd2_scale_reg,
4916 0x03, 0x00);
4917 snd_soc_component_update_bits(component, hd2_scale_reg,
4918 0x3C, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304919 }
4920}
4921
4922static int tasha_codec_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08004923 struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304924 u16 reg, int event)
4925{
Meng Wang15c825d2018-09-06 10:49:18 +08004926 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304927 u16 prim_int_reg;
4928 u16 ind = 0;
4929
4930 prim_int_reg = tasha_interp_get_primary_reg(reg, &ind);
4931
4932 switch (event) {
4933 case SND_SOC_DAPM_PRE_PMU:
4934 tasha->prim_int_users[ind]++;
4935 if (tasha->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08004936 snd_soc_component_update_bits(component, prim_int_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304937 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08004938 tasha_codec_hd2_control(component, prim_int_reg, event);
4939 snd_soc_component_update_bits(component, prim_int_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304940 1 << 0x5, 1 << 0x5);
4941 }
4942 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08004943 ((snd_soc_component_read32(
4944 component, prim_int_reg)) & 0x10))
4945 snd_soc_component_update_bits(component, reg,
4946 0x10, 0x10);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304947 break;
4948 case SND_SOC_DAPM_POST_PMD:
4949 tasha->prim_int_users[ind]--;
4950 if (tasha->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08004951 snd_soc_component_update_bits(component, prim_int_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304952 1 << 0x5, 0 << 0x5);
Meng Wang15c825d2018-09-06 10:49:18 +08004953 snd_soc_component_update_bits(component, prim_int_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304954 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08004955 snd_soc_component_update_bits(component, prim_int_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304956 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08004957 tasha_codec_hd2_control(component, prim_int_reg, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304958 }
4959 break;
4960 };
4961
Meng Wang15c825d2018-09-06 10:49:18 +08004962 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304963 __func__, ind, tasha->prim_int_users[ind]);
4964 return 0;
4965}
4966
Meng Wang15c825d2018-09-06 10:49:18 +08004967static int tasha_codec_enable_spline_src(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304968 int src_num,
4969 int event)
4970{
4971 u16 src_paired_reg = 0;
4972 struct tasha_priv *tasha;
4973 u16 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4974 u16 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4975 int *src_users, count, spl_src = SPLINE_SRC0;
4976 u16 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4977
Meng Wang15c825d2018-09-06 10:49:18 +08004978 tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304979
4980 switch (src_num) {
4981 case SRC_IN_HPHL:
4982 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4983 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4984 src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4985 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4986 spl_src = SPLINE_SRC0;
4987 break;
4988 case SRC_IN_LO1:
4989 rx_path_cfg_reg = WCD9335_CDC_RX3_RX_PATH_CFG0;
4990 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4991 src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4992 rx_path_ctl_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4993 spl_src = SPLINE_SRC0;
4994 break;
4995 case SRC_IN_HPHR:
4996 rx_path_cfg_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
4997 src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4998 src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4999 rx_path_ctl_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
5000 spl_src = SPLINE_SRC1;
5001 break;
5002 case SRC_IN_LO2:
5003 rx_path_cfg_reg = WCD9335_CDC_RX4_RX_PATH_CFG0;
5004 src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
5005 src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
5006 rx_path_ctl_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
5007 spl_src = SPLINE_SRC1;
5008 break;
5009 case SRC_IN_SPKRL:
5010 rx_path_cfg_reg = WCD9335_CDC_RX7_RX_PATH_CFG0;
5011 src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
5012 src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
5013 rx_path_ctl_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
5014 spl_src = SPLINE_SRC2;
5015 break;
5016 case SRC_IN_LO3:
5017 rx_path_cfg_reg = WCD9335_CDC_RX5_RX_PATH_CFG0;
5018 src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
5019 src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
5020 rx_path_ctl_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
5021 spl_src = SPLINE_SRC2;
5022 break;
5023 case SRC_IN_SPKRR:
5024 rx_path_cfg_reg = WCD9335_CDC_RX8_RX_PATH_CFG0;
5025 src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
5026 src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
5027 rx_path_ctl_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
5028 spl_src = SPLINE_SRC3;
5029 break;
5030 case SRC_IN_LO4:
5031 rx_path_cfg_reg = WCD9335_CDC_RX6_RX_PATH_CFG0;
5032 src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
5033 src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
5034 rx_path_ctl_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
5035 spl_src = SPLINE_SRC3;
5036 break;
5037 };
5038
5039 src_users = &tasha->spl_src_users[spl_src];
5040
5041 switch (event) {
5042 case SND_SOC_DAPM_PRE_PMU:
5043 count = *src_users;
5044 count++;
5045 if (count == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08005046 if ((snd_soc_component_read32(
5047 component, src_clk_reg) & 0x02) ||
5048 (snd_soc_component_read32(
5049 component, src_paired_reg) & 0x02)) {
5050 snd_soc_component_update_bits(component,
5051 src_clk_reg, 0x02, 0x00);
5052 snd_soc_component_update_bits(component,
5053 src_paired_reg, 0x02, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305054 }
Meng Wang15c825d2018-09-06 10:49:18 +08005055 snd_soc_component_update_bits(component, src_clk_reg,
5056 0x01, 0x01);
5057 snd_soc_component_update_bits(component,
5058 rx_path_cfg_reg, 0x80, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305059 }
5060 *src_users = count;
5061 break;
5062 case SND_SOC_DAPM_POST_PMD:
5063 count = *src_users;
5064 count--;
5065 if (count == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08005066 snd_soc_component_update_bits(component,
5067 rx_path_cfg_reg, 0x80, 0x00);
5068 snd_soc_component_update_bits(component,
5069 src_clk_reg, 0x03, 0x02);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305070 /* default sample rate */
Meng Wang15c825d2018-09-06 10:49:18 +08005071 snd_soc_component_update_bits(component,
5072 rx_path_ctl_reg, 0x0f, 0x04);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305073 }
5074 *src_users = count;
5075 break;
5076 };
5077
Meng Wang15c825d2018-09-06 10:49:18 +08005078 dev_dbg(component->dev, "%s: Spline SRC%d, users: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305079 __func__, spl_src, *src_users);
5080 return 0;
5081}
5082
5083static int tasha_codec_enable_spline_resampler(struct snd_soc_dapm_widget *w,
5084 struct snd_kcontrol *kcontrol,
5085 int event)
5086{
Meng Wang15c825d2018-09-06 10:49:18 +08005087 struct snd_soc_component *component =
5088 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305089 int ret = 0;
5090 u8 src_in;
5091
Meng Wang15c825d2018-09-06 10:49:18 +08005092 src_in = snd_soc_component_read32(
5093 component, WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305094 if (!(src_in & 0xFF)) {
Meng Wang15c825d2018-09-06 10:49:18 +08005095 dev_err(component->dev, "%s: Spline SRC%u input not selected\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305096 __func__, w->shift);
5097 return -EINVAL;
5098 }
5099
5100 switch (w->shift) {
5101 case SPLINE_SRC0:
Meng Wang15c825d2018-09-06 10:49:18 +08005102 ret = tasha_codec_enable_spline_src(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305103 ((src_in & 0x03) == 1) ? SRC_IN_HPHL : SRC_IN_LO1,
5104 event);
5105 break;
5106 case SPLINE_SRC1:
Meng Wang15c825d2018-09-06 10:49:18 +08005107 ret = tasha_codec_enable_spline_src(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305108 ((src_in & 0x0C) == 4) ? SRC_IN_HPHR : SRC_IN_LO2,
5109 event);
5110 break;
5111 case SPLINE_SRC2:
Meng Wang15c825d2018-09-06 10:49:18 +08005112 ret = tasha_codec_enable_spline_src(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305113 ((src_in & 0x30) == 0x10) ? SRC_IN_LO3 : SRC_IN_SPKRL,
5114 event);
5115 break;
5116 case SPLINE_SRC3:
Meng Wang15c825d2018-09-06 10:49:18 +08005117 ret = tasha_codec_enable_spline_src(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305118 ((src_in & 0xC0) == 0x40) ? SRC_IN_LO4 : SRC_IN_SPKRR,
5119 event);
5120 break;
5121 default:
Meng Wang15c825d2018-09-06 10:49:18 +08005122 dev_err(component->dev, "%s: Invalid spline src:%u\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305123 w->shift);
5124 ret = -EINVAL;
5125 };
5126
5127 return ret;
5128}
5129
5130static int tasha_codec_enable_swr(struct snd_soc_dapm_widget *w,
5131 struct snd_kcontrol *kcontrol, int event)
5132{
Meng Wang15c825d2018-09-06 10:49:18 +08005133 struct snd_soc_component *component =
5134 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305135 struct tasha_priv *tasha;
5136 int i, ch_cnt;
5137
Meng Wang15c825d2018-09-06 10:49:18 +08005138 tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305139
5140 if (!tasha->nr)
5141 return 0;
5142
5143 switch (event) {
5144 case SND_SOC_DAPM_PRE_PMU:
5145 if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) &&
5146 !tasha->rx_7_count)
5147 tasha->rx_7_count++;
5148 if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
5149 !tasha->rx_8_count)
5150 tasha->rx_8_count++;
5151 ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
5152
5153 for (i = 0; i < tasha->nr; i++) {
5154 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5155 SWR_DEVICE_UP, NULL);
5156 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5157 SWR_SET_NUM_RX_CH, &ch_cnt);
5158 }
5159 break;
5160 case SND_SOC_DAPM_POST_PMD:
5161 if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) &&
5162 tasha->rx_7_count)
5163 tasha->rx_7_count--;
5164 if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
5165 tasha->rx_8_count)
5166 tasha->rx_8_count--;
5167 ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
5168
5169 for (i = 0; i < tasha->nr; i++)
5170 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5171 SWR_SET_NUM_RX_CH, &ch_cnt);
5172
5173 break;
5174 }
5175 dev_dbg(tasha->dev, "%s: current swr ch cnt: %d\n",
5176 __func__, tasha->rx_7_count + tasha->rx_8_count);
5177
5178 return 0;
5179}
5180
Meng Wang15c825d2018-09-06 10:49:18 +08005181static int tasha_codec_config_ear_spkr_gain(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305182 int event, int gain_reg)
5183{
5184 int comp_gain_offset, val;
Meng Wang15c825d2018-09-06 10:49:18 +08005185 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305186
5187 switch (tasha->spkr_mode) {
5188 /* Compander gain in SPKR_MODE1 case is 12 dB */
5189 case SPKR_MODE_1:
5190 comp_gain_offset = -12;
5191 break;
5192 /* Default case compander gain is 15 dB */
5193 default:
5194 comp_gain_offset = -15;
5195 break;
5196 }
5197
5198 switch (event) {
5199 case SND_SOC_DAPM_POST_PMU:
5200 /* Apply ear spkr gain only if compander is enabled */
5201 if (tasha->comp_enabled[COMPANDER_7] &&
5202 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5203 gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) &&
5204 (tasha->ear_spkr_gain != 0)) {
5205 /* For example, val is -8(-12+5-1) for 4dB of gain */
5206 val = comp_gain_offset + tasha->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08005207 snd_soc_component_write(component, gain_reg, val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305208
Meng Wang15c825d2018-09-06 10:49:18 +08005209 dev_dbg(component->dev, "%s: RX7 Volume %d dB\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305210 __func__, val);
5211 }
5212 break;
5213 case SND_SOC_DAPM_POST_PMD:
5214 /*
5215 * Reset RX7 volume to 0 dB if compander is enabled and
5216 * ear_spkr_gain is non-zero.
5217 */
5218 if (tasha->comp_enabled[COMPANDER_7] &&
5219 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5220 gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) &&
5221 (tasha->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08005222 snd_soc_component_write(component, gain_reg, 0x0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305223
Meng Wang15c825d2018-09-06 10:49:18 +08005224 dev_dbg(component->dev, "%s: Reset RX7 Volume to 0 dB\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305225 __func__);
5226 }
5227 break;
5228 }
5229
5230 return 0;
5231}
5232
5233static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
5234 struct snd_kcontrol *kcontrol, int event)
5235{
Meng Wang15c825d2018-09-06 10:49:18 +08005236 struct snd_soc_component *component =
5237 snd_soc_dapm_to_component(w->dapm);
5238 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305239 u16 gain_reg;
5240 int offset_val = 0;
5241 int val = 0;
5242
Meng Wang15c825d2018-09-06 10:49:18 +08005243 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305244
5245 switch (w->reg) {
5246 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
5247 gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL;
5248 break;
5249 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
5250 gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL;
5251 break;
5252 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
5253 gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL;
5254 break;
5255 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
5256 gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL;
5257 break;
5258 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
5259 gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL;
5260 break;
5261 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
5262 gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL;
5263 break;
5264 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
5265 gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL;
5266 break;
5267 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
5268 gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL;
5269 break;
5270 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
5271 gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL;
5272 break;
5273 default:
Meng Wang15c825d2018-09-06 10:49:18 +08005274 dev_err(component->dev, "%s: No gain register avail for %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305275 __func__, w->name);
5276 return 0;
5277 };
5278
5279 switch (event) {
5280 case SND_SOC_DAPM_POST_PMU:
5281 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5282 (tasha->comp_enabled[COMPANDER_7] ||
5283 tasha->comp_enabled[COMPANDER_8]) &&
5284 (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL ||
5285 gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08005286 snd_soc_component_update_bits(component,
5287 WCD9335_CDC_RX7_RX_PATH_SEC1,
5288 0x01, 0x01);
5289 snd_soc_component_update_bits(component,
5290 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5291 0x01, 0x01);
5292 snd_soc_component_update_bits(component,
5293 WCD9335_CDC_RX8_RX_PATH_SEC1,
5294 0x01, 0x01);
5295 snd_soc_component_update_bits(component,
5296 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5297 0x01, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305298 offset_val = -2;
5299 }
Meng Wang15c825d2018-09-06 10:49:18 +08005300 val = snd_soc_component_read32(component, gain_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305301 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08005302 snd_soc_component_write(component, gain_reg, val);
5303 tasha_codec_config_ear_spkr_gain(component, event, gain_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305304 break;
5305 case SND_SOC_DAPM_POST_PMD:
5306 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5307 (tasha->comp_enabled[COMPANDER_7] ||
5308 tasha->comp_enabled[COMPANDER_8]) &&
5309 (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL ||
5310 gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08005311 snd_soc_component_update_bits(component,
5312 WCD9335_CDC_RX7_RX_PATH_SEC1,
5313 0x01, 0x00);
5314 snd_soc_component_update_bits(component,
5315 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5316 0x01, 0x00);
5317 snd_soc_component_update_bits(component,
5318 WCD9335_CDC_RX8_RX_PATH_SEC1,
5319 0x01, 0x00);
5320 snd_soc_component_update_bits(component,
5321 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5322 0x01, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305323 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08005324 val = snd_soc_component_read32(component, gain_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305325 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08005326 snd_soc_component_write(component, gain_reg, val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305327 }
Meng Wang15c825d2018-09-06 10:49:18 +08005328 tasha_codec_config_ear_spkr_gain(component, event, gain_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305329 break;
5330 };
5331
5332 return 0;
5333}
5334
5335static int __tasha_cdc_native_clk_enable(struct tasha_priv *tasha,
5336 bool enable)
5337{
5338 int ret = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08005339 struct snd_soc_component *component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305340
5341 if (!tasha->wcd_native_clk) {
Meng Wang15c825d2018-09-06 10:49:18 +08005342 dev_err(tasha->dev, "%s: wcd native clock is NULL\n",
5343 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305344 return -EINVAL;
5345 }
5346
Meng Wang15c825d2018-09-06 10:49:18 +08005347 dev_dbg(tasha->dev, "%s: native_clk_enable = %u\n",
5348 __func__, enable);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305349
5350 if (enable) {
5351 ret = clk_prepare_enable(tasha->wcd_native_clk);
5352 if (ret) {
5353 dev_err(tasha->dev, "%s: native clk enable failed\n",
5354 __func__);
5355 goto err;
5356 }
5357 if (++tasha->native_clk_users == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08005358 snd_soc_component_update_bits(component,
5359 WCD9335_CLOCK_TEST_CTL,
5360 0x10, 0x10);
5361 snd_soc_component_update_bits(component,
5362 WCD9335_CLOCK_TEST_CTL,
5363 0x80, 0x80);
5364 snd_soc_component_update_bits(component,
5365 WCD9335_CODEC_RPM_CLK_GATE,
5366 0x04, 0x00);
5367 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305368 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
5369 0x02, 0x02);
5370 }
5371 } else {
5372 if (tasha->native_clk_users &&
5373 (--tasha->native_clk_users == 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08005374 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305375 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
5376 0x02, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08005377 snd_soc_component_update_bits(component,
5378 WCD9335_CODEC_RPM_CLK_GATE,
5379 0x04, 0x04);
5380 snd_soc_component_update_bits(component,
5381 WCD9335_CLOCK_TEST_CTL,
5382 0x80, 0x00);
5383 snd_soc_component_update_bits(component,
5384 WCD9335_CLOCK_TEST_CTL,
5385 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305386 }
5387 clk_disable_unprepare(tasha->wcd_native_clk);
5388 }
5389
Meng Wang15c825d2018-09-06 10:49:18 +08005390 dev_dbg(component->dev, "%s: native_clk_users: %d\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305391 tasha->native_clk_users);
5392err:
5393 return ret;
5394}
5395
Meng Wang15c825d2018-09-06 10:49:18 +08005396static int tasha_codec_get_native_fifo_sync_mask(
5397 struct snd_soc_component *component,
5398 int interp_n)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305399{
5400 int mask = 0;
5401 u16 reg;
5402 u8 val1, val2, inp0 = 0;
5403 u8 inp1 = 0, inp2 = 0;
5404
5405 reg = WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0 + (2 * interp_n) - 2;
5406
Meng Wang15c825d2018-09-06 10:49:18 +08005407 val1 = snd_soc_component_read32(component, reg);
5408 val2 = snd_soc_component_read32(component, reg + 1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305409
5410 inp0 = val1 & 0x0F;
5411 inp1 = (val1 >> 4) & 0x0F;
5412 inp2 = (val2 >> 4) & 0x0F;
5413
5414 if (IS_VALID_NATIVE_FIFO_PORT(inp0))
5415 mask |= (1 << (inp0 - 5));
5416 if (IS_VALID_NATIVE_FIFO_PORT(inp1))
5417 mask |= (1 << (inp1 - 5));
5418 if (IS_VALID_NATIVE_FIFO_PORT(inp2))
5419 mask |= (1 << (inp2 - 5));
5420
Meng Wang15c825d2018-09-06 10:49:18 +08005421 dev_dbg(component->dev, "%s: native fifo mask: 0x%x\n", __func__, mask);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305422 if (!mask)
Meng Wang15c825d2018-09-06 10:49:18 +08005423 dev_err(component->dev, "native fifo err,int:%d,inp0:%d,inp1:%d,inp2:%d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305424 interp_n, inp0, inp1, inp2);
5425 return mask;
5426}
5427
5428static int tasha_enable_native_supply(struct snd_soc_dapm_widget *w,
5429 struct snd_kcontrol *kcontrol, int event)
5430{
5431 int mask;
Meng Wang15c825d2018-09-06 10:49:18 +08005432 struct snd_soc_component *component =
5433 snd_soc_dapm_to_component(w->dapm);
5434 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305435 u16 interp_reg;
5436
Meng Wang15c825d2018-09-06 10:49:18 +08005437 dev_dbg(component->dev, "%s: event: %d, shift:%d\n", __func__, event,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305438 w->shift);
5439
5440 if (w->shift < INTERP_HPHL || w->shift > INTERP_LO2)
5441 return -EINVAL;
5442
5443 interp_reg = WCD9335_CDC_RX1_RX_PATH_CTL + 20 * (w->shift - 1);
5444
Meng Wang15c825d2018-09-06 10:49:18 +08005445 mask = tasha_codec_get_native_fifo_sync_mask(component, w->shift);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305446 if (!mask)
5447 return -EINVAL;
5448
5449 switch (event) {
5450 case SND_SOC_DAPM_PRE_PMU:
5451 /* Adjust interpolator rate to 44P1_NATIVE */
Meng Wang15c825d2018-09-06 10:49:18 +08005452 snd_soc_component_update_bits(component, interp_reg,
5453 0x0F, 0x09);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305454 __tasha_cdc_native_clk_enable(tasha, true);
Meng Wang15c825d2018-09-06 10:49:18 +08005455 snd_soc_component_update_bits(component,
5456 WCD9335_DATA_HUB_NATIVE_FIFO_SYNC,
5457 mask, mask);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305458 break;
5459 case SND_SOC_DAPM_PRE_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08005460 snd_soc_component_update_bits(component,
5461 WCD9335_DATA_HUB_NATIVE_FIFO_SYNC,
5462 mask, 0x0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305463 __tasha_cdc_native_clk_enable(tasha, false);
5464 /* Adjust interpolator rate to default */
Meng Wang15c825d2018-09-06 10:49:18 +08005465 snd_soc_component_update_bits(component, interp_reg,
5466 0x0F, 0x04);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305467 break;
5468 }
5469
5470 return 0;
5471}
5472
5473static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
5474 struct snd_kcontrol *kcontrol, int event)
5475{
Meng Wang15c825d2018-09-06 10:49:18 +08005476 struct snd_soc_component *component =
5477 snd_soc_dapm_to_component(w->dapm);
5478 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305479 u16 gain_reg;
5480 u16 reg;
5481 int val;
5482 int offset_val = 0;
5483
Meng Wang15c825d2018-09-06 10:49:18 +08005484 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305485
5486 if (!(strcmp(w->name, "RX INT0 INTERP"))) {
5487 reg = WCD9335_CDC_RX0_RX_PATH_CTL;
5488 gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL;
5489 } else if (!(strcmp(w->name, "RX INT1 INTERP"))) {
5490 reg = WCD9335_CDC_RX1_RX_PATH_CTL;
5491 gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL;
5492 } else if (!(strcmp(w->name, "RX INT2 INTERP"))) {
5493 reg = WCD9335_CDC_RX2_RX_PATH_CTL;
5494 gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL;
5495 } else if (!(strcmp(w->name, "RX INT3 INTERP"))) {
5496 reg = WCD9335_CDC_RX3_RX_PATH_CTL;
5497 gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL;
5498 } else if (!(strcmp(w->name, "RX INT4 INTERP"))) {
5499 reg = WCD9335_CDC_RX4_RX_PATH_CTL;
5500 gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL;
5501 } else if (!(strcmp(w->name, "RX INT5 INTERP"))) {
5502 reg = WCD9335_CDC_RX5_RX_PATH_CTL;
5503 gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL;
5504 } else if (!(strcmp(w->name, "RX INT6 INTERP"))) {
5505 reg = WCD9335_CDC_RX6_RX_PATH_CTL;
5506 gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL;
5507 } else if (!(strcmp(w->name, "RX INT7 INTERP"))) {
5508 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
5509 gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL;
5510 } else if (!(strcmp(w->name, "RX INT8 INTERP"))) {
5511 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
5512 gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL;
5513 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08005514 dev_err(component->dev, "%s: Interpolator reg not found\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305515 __func__);
5516 return -EINVAL;
5517 }
5518
5519 switch (event) {
5520 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08005521 tasha_codec_vote_max_bw(component, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305522 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08005523 tasha_codec_enable_prim_interpolator(component, reg, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305524 break;
5525 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08005526 tasha_config_compander(component, w->shift, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305527 /* apply gain after int clk is enabled */
5528 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5529 (tasha->comp_enabled[COMPANDER_7] ||
5530 tasha->comp_enabled[COMPANDER_8]) &&
5531 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5532 gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08005533 snd_soc_component_update_bits(component,
5534 WCD9335_CDC_RX7_RX_PATH_SEC1,
5535 0x01, 0x01);
5536 snd_soc_component_update_bits(component,
5537 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5538 0x01, 0x01);
5539 snd_soc_component_update_bits(component,
5540 WCD9335_CDC_RX8_RX_PATH_SEC1,
5541 0x01, 0x01);
5542 snd_soc_component_update_bits(component,
5543 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5544 0x01, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305545 offset_val = -2;
5546 }
Meng Wang15c825d2018-09-06 10:49:18 +08005547 val = snd_soc_component_read32(component, gain_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305548 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08005549 snd_soc_component_write(component, gain_reg, val);
5550 tasha_codec_config_ear_spkr_gain(component, event, gain_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305551 break;
5552 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08005553 tasha_config_compander(component, w->shift, event);
5554 tasha_codec_enable_prim_interpolator(component, reg, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305555 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5556 (tasha->comp_enabled[COMPANDER_7] ||
5557 tasha->comp_enabled[COMPANDER_8]) &&
5558 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5559 gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08005560 snd_soc_component_update_bits(component,
5561 WCD9335_CDC_RX7_RX_PATH_SEC1,
5562 0x01, 0x00);
5563 snd_soc_component_update_bits(component,
5564 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5565 0x01, 0x00);
5566 snd_soc_component_update_bits(component,
5567 WCD9335_CDC_RX8_RX_PATH_SEC1,
5568 0x01, 0x00);
5569 snd_soc_component_update_bits(component,
5570 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5571 0x01, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305572 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08005573 val = snd_soc_component_read32(component, gain_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305574 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08005575 snd_soc_component_write(component, gain_reg, val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305576 }
Meng Wang15c825d2018-09-06 10:49:18 +08005577 tasha_codec_config_ear_spkr_gain(component, event, gain_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305578 break;
5579 };
5580
5581 return 0;
5582}
5583
5584static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
5585 struct snd_kcontrol *kcontrol, int event)
5586{
Meng Wang15c825d2018-09-06 10:49:18 +08005587 struct snd_soc_component *component =
5588 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305589
Meng Wang15c825d2018-09-06 10:49:18 +08005590 dev_dbg(component->dev, "%s: event = %d\n", __func__, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305591
5592 switch (event) {
5593 case SND_SOC_DAPM_POST_PMU: /* fall through */
5594 case SND_SOC_DAPM_PRE_PMD:
5595 if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
Meng Wang15c825d2018-09-06 10:49:18 +08005596 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305597 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08005598 snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305599 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08005600 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305601 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08005602 snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305603 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08005604 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305605 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08005606 snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305607 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08005608 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305609 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08005610 snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305611 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
5612 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08005613 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305614 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08005615 snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305616 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08005617 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305618 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08005619 snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305620 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08005621 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305622 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08005623 snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305624 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL));
5625 }
5626 break;
5627 }
5628 return 0;
5629}
5630
5631static int tasha_codec_enable_on_demand_supply(
5632 struct snd_soc_dapm_widget *w,
5633 struct snd_kcontrol *kcontrol, int event)
5634{
5635 int ret = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08005636 struct snd_soc_component *component =
5637 snd_soc_dapm_to_component(w->dapm);
5638 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305639 struct on_demand_supply *supply;
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +05305640 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
5641 struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
5642 const char *supply_name;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305643
5644 if (w->shift >= ON_DEMAND_SUPPLIES_MAX) {
Meng Wang15c825d2018-09-06 10:49:18 +08005645 dev_err(component->dev, "%s: error index > MAX Demand supplies",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305646 __func__);
5647 ret = -EINVAL;
5648 goto out;
5649 }
5650
Meng Wang15c825d2018-09-06 10:49:18 +08005651 dev_dbg(component->dev, "%s: supply: %s event: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305652 __func__, on_demand_supply_name[w->shift], event);
5653
5654 supply = &tasha->on_demand_list[w->shift];
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +05305655 supply_name = on_demand_supply_name[w->shift];
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305656 WARN_ONCE(!supply->supply, "%s isn't defined\n",
5657 on_demand_supply_name[w->shift]);
5658 if (!supply->supply) {
Meng Wang15c825d2018-09-06 10:49:18 +08005659 dev_err(component->dev, "%s: err supply not present ond for %d",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305660 __func__, w->shift);
5661 goto out;
5662 }
5663
5664 switch (event) {
5665 case SND_SOC_DAPM_PRE_PMU:
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +05305666 if (pdata->vote_regulator_on_demand) {
5667 ret = wcd9xxx_vote_ondemand_regulator(wcd9xxx, pdata,
5668 supply_name,
5669 true);
5670 if (ret)
5671 dev_err(component->dev, "%s: Failed to vote %s\n",
5672 __func__,
5673 on_demand_supply_name[w->shift]);
5674 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305675 ret = regulator_enable(supply->supply);
5676 if (ret)
Meng Wang15c825d2018-09-06 10:49:18 +08005677 dev_err(component->dev, "%s: Failed to enable %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305678 __func__,
5679 on_demand_supply_name[w->shift]);
5680 break;
5681 case SND_SOC_DAPM_POST_PMD:
5682 ret = regulator_disable(supply->supply);
5683 if (ret)
Meng Wang15c825d2018-09-06 10:49:18 +08005684 dev_err(component->dev, "%s: Failed to disable %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305685 __func__,
5686 on_demand_supply_name[w->shift]);
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +05305687 if (pdata->vote_regulator_on_demand) {
5688 ret = wcd9xxx_vote_ondemand_regulator(wcd9xxx, pdata,
5689 supply_name,
5690 false);
5691 if (ret)
5692 dev_err(component->dev, "%s: Failed to unvote %s\n",
5693 __func__,
5694 on_demand_supply_name[w->shift]);
5695 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305696 break;
5697 default:
5698 break;
5699 };
5700
5701out:
5702 return ret;
5703}
5704
Meng Wang15c825d2018-09-06 10:49:18 +08005705static int tasha_codec_find_amic_input(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305706 int adc_mux_n)
5707{
5708 u16 mask, shift, adc_mux_in_reg;
5709 u16 amic_mux_sel_reg;
5710 bool is_amic;
5711
5712 if (adc_mux_n < 0 || adc_mux_n > WCD9335_MAX_VALID_ADC_MUX ||
5713 adc_mux_n == WCD9335_INVALID_ADC_MUX)
5714 return 0;
5715
5716 /* Check whether adc mux input is AMIC or DMIC */
5717 if (adc_mux_n < 4) {
5718 adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
5719 2 * adc_mux_n;
5720 amic_mux_sel_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
5721 2 * adc_mux_n;
5722 mask = 0x03;
5723 shift = 0;
5724 } else {
5725 adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
5726 adc_mux_n - 4;
5727 amic_mux_sel_reg = adc_mux_in_reg;
5728 mask = 0xC0;
5729 shift = 6;
5730 }
Meng Wang15c825d2018-09-06 10:49:18 +08005731 is_amic = (((snd_soc_component_read32(
5732 component, adc_mux_in_reg) & mask) >> shift) == 1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305733 if (!is_amic)
5734 return 0;
5735
Meng Wang15c825d2018-09-06 10:49:18 +08005736 return snd_soc_component_read32(component, amic_mux_sel_reg) & 0x07;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305737}
5738
Meng Wang15c825d2018-09-06 10:49:18 +08005739static void tasha_codec_set_tx_hold(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305740 u16 amic_reg, bool set)
5741{
5742 u8 mask = 0x20;
5743 u8 val;
5744
5745 if (amic_reg == WCD9335_ANA_AMIC1 ||
5746 amic_reg == WCD9335_ANA_AMIC3 ||
5747 amic_reg == WCD9335_ANA_AMIC5)
5748 mask = 0x40;
5749
5750 val = set ? mask : 0x00;
5751
5752 switch (amic_reg) {
5753 case WCD9335_ANA_AMIC1:
5754 case WCD9335_ANA_AMIC2:
Meng Wang15c825d2018-09-06 10:49:18 +08005755 snd_soc_component_update_bits(component, WCD9335_ANA_AMIC2,
5756 mask, val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305757 break;
5758 case WCD9335_ANA_AMIC3:
5759 case WCD9335_ANA_AMIC4:
Meng Wang15c825d2018-09-06 10:49:18 +08005760 snd_soc_component_update_bits(component, WCD9335_ANA_AMIC4,
5761 mask, val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305762 break;
5763 case WCD9335_ANA_AMIC5:
5764 case WCD9335_ANA_AMIC6:
Meng Wang15c825d2018-09-06 10:49:18 +08005765 snd_soc_component_update_bits(component, WCD9335_ANA_AMIC6,
5766 mask, val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305767 break;
5768 default:
Meng Wang15c825d2018-09-06 10:49:18 +08005769 dev_dbg(component->dev, "%s: invalid amic: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305770 __func__, amic_reg);
5771 break;
5772 }
5773}
5774
5775static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
5776 struct snd_kcontrol *kcontrol, int event)
5777{
5778 int adc_mux_n = w->shift;
Meng Wang15c825d2018-09-06 10:49:18 +08005779 struct snd_soc_component *component =
5780 snd_soc_dapm_to_component(w->dapm);
5781 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305782 int amic_n;
5783
Meng Wang15c825d2018-09-06 10:49:18 +08005784 dev_dbg(component->dev, "%s: event: %d\n", __func__, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305785
5786 switch (event) {
5787 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08005788 amic_n = tasha_codec_find_amic_input(component, adc_mux_n);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305789 if (amic_n) {
5790 /*
5791 * Prevent ANC Rx pop by leaving Tx FE in HOLD
5792 * state until PA is up. Track AMIC being used
5793 * so we can release the HOLD later.
5794 */
5795 set_bit(ANC_MIC_AMIC1 + amic_n - 1,
5796 &tasha->status_mask);
5797 }
5798 break;
5799 default:
5800 break;
5801 }
5802
5803 return 0;
5804}
5805
Meng Wang15c825d2018-09-06 10:49:18 +08005806static u16 tasha_codec_get_amic_pwlvl_reg(
5807 struct snd_soc_component *component, int amic)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305808{
5809 u16 pwr_level_reg = 0;
5810
5811 switch (amic) {
5812 case 1:
5813 case 2:
5814 pwr_level_reg = WCD9335_ANA_AMIC1;
5815 break;
5816
5817 case 3:
5818 case 4:
5819 pwr_level_reg = WCD9335_ANA_AMIC3;
5820 break;
5821
5822 case 5:
5823 case 6:
5824 pwr_level_reg = WCD9335_ANA_AMIC5;
5825 break;
5826 default:
Meng Wang15c825d2018-09-06 10:49:18 +08005827 dev_dbg(component->dev, "%s: invalid amic: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305828 __func__, amic);
5829 break;
5830 }
5831
5832 return pwr_level_reg;
5833}
5834
5835#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
5836#define CF_MIN_3DB_4HZ 0x0
5837#define CF_MIN_3DB_75HZ 0x1
5838#define CF_MIN_3DB_150HZ 0x2
5839
5840static void tasha_tx_hpf_corner_freq_callback(struct work_struct *work)
5841{
5842 struct delayed_work *hpf_delayed_work;
5843 struct hpf_work *hpf_work;
5844 struct tasha_priv *tasha;
Meng Wang15c825d2018-09-06 10:49:18 +08005845 struct snd_soc_component *component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305846 u16 dec_cfg_reg, amic_reg;
5847 u8 hpf_cut_off_freq;
5848 int amic_n;
5849
5850 hpf_delayed_work = to_delayed_work(work);
5851 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
5852 tasha = hpf_work->tasha;
Meng Wang15c825d2018-09-06 10:49:18 +08005853 component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305854 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
5855
5856 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator;
5857
Meng Wang15c825d2018-09-06 10:49:18 +08005858 dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305859 __func__, hpf_work->decimator, hpf_cut_off_freq);
5860
Meng Wang15c825d2018-09-06 10:49:18 +08005861 amic_n = tasha_codec_find_amic_input(component, hpf_work->decimator);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305862 if (amic_n) {
5863 amic_reg = WCD9335_ANA_AMIC1 + amic_n - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08005864 tasha_codec_set_tx_hold(component, amic_reg, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305865 }
Meng Wang15c825d2018-09-06 10:49:18 +08005866 tasha_codec_vote_max_bw(component, true);
5867 snd_soc_component_update_bits(component, dec_cfg_reg,
5868 TX_HPF_CUT_OFF_FREQ_MASK,
5869 hpf_cut_off_freq << 5);
5870 tasha_codec_vote_max_bw(component, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305871}
5872
5873static void tasha_tx_mute_update_callback(struct work_struct *work)
5874{
5875 struct tx_mute_work *tx_mute_dwork;
5876 struct tasha_priv *tasha;
5877 struct delayed_work *delayed_work;
Meng Wang15c825d2018-09-06 10:49:18 +08005878 struct snd_soc_component *component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305879 u16 tx_vol_ctl_reg, hpf_gate_reg;
5880
5881 delayed_work = to_delayed_work(work);
5882 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
5883 tasha = tx_mute_dwork->tasha;
Meng Wang15c825d2018-09-06 10:49:18 +08005884 component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305885
5886 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
5887 16 * tx_mute_dwork->decimator;
5888 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 +
5889 16 * tx_mute_dwork->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +08005890 snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x01);
5891 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305892}
5893
5894static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w,
5895 struct snd_kcontrol *kcontrol, int event)
5896{
Meng Wang15c825d2018-09-06 10:49:18 +08005897 struct snd_soc_component *component =
5898 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305899 unsigned int decimator;
5900 char *dec_adc_mux_name = NULL;
5901 char *widget_name = NULL;
5902 char *wname;
5903 int ret = 0, amic_n;
5904 u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
5905 u16 tx_gain_ctl_reg;
5906 char *dec;
5907 u8 hpf_cut_off_freq;
Meng Wang15c825d2018-09-06 10:49:18 +08005908 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305909
Meng Wang15c825d2018-09-06 10:49:18 +08005910 dev_dbg(component->dev, "%s %d\n", __func__, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305911
5912 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
5913 if (!widget_name)
5914 return -ENOMEM;
5915
5916 wname = widget_name;
5917 dec_adc_mux_name = strsep(&widget_name, " ");
5918 if (!dec_adc_mux_name) {
Meng Wang15c825d2018-09-06 10:49:18 +08005919 dev_err(component->dev, "%s: Invalid decimator = %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305920 __func__, w->name);
5921 ret = -EINVAL;
5922 goto out;
5923 }
5924 dec_adc_mux_name = widget_name;
5925
5926 dec = strpbrk(dec_adc_mux_name, "012345678");
5927 if (!dec) {
Meng Wang15c825d2018-09-06 10:49:18 +08005928 dev_err(component->dev, "%s: decimator index not found\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305929 __func__);
5930 ret = -EINVAL;
5931 goto out;
5932 }
5933
5934 ret = kstrtouint(dec, 10, &decimator);
5935 if (ret < 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08005936 dev_err(component->dev, "%s: Invalid decimator = %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305937 __func__, wname);
5938 ret = -EINVAL;
5939 goto out;
5940 }
5941
Meng Wang15c825d2018-09-06 10:49:18 +08005942 dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305943 w->name, decimator);
5944
5945 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator;
5946 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * decimator;
5947 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * decimator;
5948 tx_gain_ctl_reg = WCD9335_CDC_TX0_TX_VOL_CTL + 16 * decimator;
5949
5950 switch (event) {
5951 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08005952 amic_n = tasha_codec_find_amic_input(component, decimator);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305953 if (amic_n)
Meng Wang15c825d2018-09-06 10:49:18 +08005954 pwr_level_reg = tasha_codec_get_amic_pwlvl_reg(
5955 component, amic_n);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305956
5957 if (pwr_level_reg) {
Meng Wang15c825d2018-09-06 10:49:18 +08005958 switch (
5959 (snd_soc_component_read32(component, pwr_level_reg) &
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305960 WCD9335_AMIC_PWR_LVL_MASK) >>
5961 WCD9335_AMIC_PWR_LVL_SHIFT) {
5962 case WCD9335_AMIC_PWR_LEVEL_LP:
Meng Wang15c825d2018-09-06 10:49:18 +08005963 snd_soc_component_update_bits(
5964 component, dec_cfg_reg,
5965 WCD9335_DEC_PWR_LVL_MASK,
5966 WCD9335_DEC_PWR_LVL_LP);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305967 break;
5968
5969 case WCD9335_AMIC_PWR_LEVEL_HP:
Meng Wang15c825d2018-09-06 10:49:18 +08005970 snd_soc_component_update_bits(
5971 component, dec_cfg_reg,
5972 WCD9335_DEC_PWR_LVL_MASK,
5973 WCD9335_DEC_PWR_LVL_HP);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305974 break;
5975 case WCD9335_AMIC_PWR_LEVEL_DEFAULT:
5976 default:
Meng Wang15c825d2018-09-06 10:49:18 +08005977 snd_soc_component_update_bits(
5978 component, dec_cfg_reg,
5979 WCD9335_DEC_PWR_LVL_MASK,
5980 WCD9335_DEC_PWR_LVL_DF);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305981 break;
5982 }
5983 }
Meng Wang15c825d2018-09-06 10:49:18 +08005984 hpf_cut_off_freq = (
5985 snd_soc_component_read32(component, dec_cfg_reg) &
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305986 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
5987 tasha->tx_hpf_work[decimator].hpf_cut_off_freq =
5988 hpf_cut_off_freq;
5989
5990 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
Meng Wang15c825d2018-09-06 10:49:18 +08005991 snd_soc_component_update_bits(component, dec_cfg_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305992 TX_HPF_CUT_OFF_FREQ_MASK,
5993 CF_MIN_3DB_150HZ << 5);
5994 /* Enable TX PGA Mute */
Meng Wang15c825d2018-09-06 10:49:18 +08005995 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
5996 0x10, 0x10);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305997 break;
5998 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08005999 snd_soc_component_update_bits(component, hpf_gate_reg,
6000 0x01, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306001
6002 if (decimator == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08006003 snd_soc_component_write(component,
6004 WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
6005 snd_soc_component_write(component,
6006 WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3);
6007 snd_soc_component_write(component,
6008 WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
6009 snd_soc_component_write(component,
6010 WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306011 }
6012 /* schedule work queue to Remove Mute */
6013 schedule_delayed_work(&tasha->tx_mute_dwork[decimator].dwork,
6014 msecs_to_jiffies(tx_unmute_delay));
6015 if (tasha->tx_hpf_work[decimator].hpf_cut_off_freq !=
6016 CF_MIN_3DB_150HZ)
6017 schedule_delayed_work(
6018 &tasha->tx_hpf_work[decimator].dwork,
6019 msecs_to_jiffies(300));
6020 /* apply gain after decimator is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08006021 snd_soc_component_write(component, tx_gain_ctl_reg,
6022 snd_soc_component_read32(
6023 component, tx_gain_ctl_reg));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306024 break;
6025 case SND_SOC_DAPM_PRE_PMD:
6026 hpf_cut_off_freq =
6027 tasha->tx_hpf_work[decimator].hpf_cut_off_freq;
Meng Wang15c825d2018-09-06 10:49:18 +08006028 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
6029 0x10, 0x10);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306030 if (cancel_delayed_work_sync(
6031 &tasha->tx_hpf_work[decimator].dwork)) {
6032 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
Meng Wang15c825d2018-09-06 10:49:18 +08006033 tasha_codec_vote_max_bw(component, true);
6034 snd_soc_component_update_bits(component,
6035 dec_cfg_reg,
6036 TX_HPF_CUT_OFF_FREQ_MASK,
6037 hpf_cut_off_freq << 5);
6038 tasha_codec_vote_max_bw(component, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306039 }
6040 }
6041 cancel_delayed_work_sync(
6042 &tasha->tx_mute_dwork[decimator].dwork);
6043 break;
6044 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08006045 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
6046 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306047 break;
6048 };
6049out:
6050 kfree(wname);
6051 return ret;
6052}
6053
Meng Wang15c825d2018-09-06 10:49:18 +08006054static u32 tasha_get_dmic_sample_rate(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306055 unsigned int dmic, struct wcd9xxx_pdata *pdata)
6056{
6057 u8 tx_stream_fs;
6058 u8 adc_mux_index = 0, adc_mux_sel = 0;
6059 bool dec_found = false;
6060 u16 adc_mux_ctl_reg, tx_fs_reg;
6061 u32 dmic_fs;
6062
6063 while (dec_found == 0 && adc_mux_index < WCD9335_MAX_VALID_ADC_MUX) {
6064 if (adc_mux_index < 4) {
6065 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
6066 (adc_mux_index * 2);
Meng Wang15c825d2018-09-06 10:49:18 +08006067 adc_mux_sel = ((snd_soc_component_read32(component,
6068 adc_mux_ctl_reg) & 0x78) >> 3) - 1;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306069 } else if (adc_mux_index < 9) {
6070 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
6071 ((adc_mux_index - 4) * 1);
Meng Wang15c825d2018-09-06 10:49:18 +08006072 adc_mux_sel = ((snd_soc_component_read32(
6073 component, adc_mux_ctl_reg) & 0x38) >> 3) - 1;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306074 } else if (adc_mux_index == 9) {
6075 ++adc_mux_index;
6076 continue;
6077 }
6078 if (adc_mux_sel == dmic)
6079 dec_found = true;
6080 else
6081 ++adc_mux_index;
6082 }
6083
6084 if (dec_found == true && adc_mux_index <= 8) {
6085 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index);
Meng Wang15c825d2018-09-06 10:49:18 +08006086 tx_stream_fs =
6087 snd_soc_component_read32(component, tx_fs_reg) & 0x0F;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306088 dmic_fs = tx_stream_fs <= 4 ? WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ :
6089 WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
6090
6091 /*
6092 * Check for ECPP path selection and DEC1 not connected to
6093 * any other audio path to apply ECPP DMIC sample rate
6094 */
6095 if ((adc_mux_index == 1) &&
Meng Wang15c825d2018-09-06 10:49:18 +08006096 ((snd_soc_component_read32(
6097 component, WCD9335_CPE_SS_US_EC_MUX_CFG)
6098 & 0x0F) == 0x0A) &&
6099 ((snd_soc_component_read32(
6100 component, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0)
6101 & 0x0C) == 0x00)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306102 dmic_fs = pdata->ecpp_dmic_sample_rate;
6103 }
6104 } else {
6105 dmic_fs = pdata->dmic_sample_rate;
6106 }
6107
6108 return dmic_fs;
6109}
6110
Meng Wang15c825d2018-09-06 10:49:18 +08006111static u8 tasha_get_dmic_clk_val(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306112 u32 mclk_rate, u32 dmic_clk_rate)
6113{
6114 u32 div_factor;
6115 u8 dmic_ctl_val;
6116
Meng Wang15c825d2018-09-06 10:49:18 +08006117 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306118 "%s: mclk_rate = %d, dmic_sample_rate = %d\n",
6119 __func__, mclk_rate, dmic_clk_rate);
6120
6121 /* Default value to return in case of error */
6122 if (mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
6123 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
6124 else
6125 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
6126
6127 if (dmic_clk_rate == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08006128 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306129 "%s: dmic_sample_rate cannot be 0\n",
6130 __func__);
6131 goto done;
6132 }
6133
6134 div_factor = mclk_rate / dmic_clk_rate;
6135 switch (div_factor) {
6136 case 2:
6137 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
6138 break;
6139 case 3:
6140 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
6141 break;
6142 case 4:
6143 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4;
6144 break;
6145 case 6:
6146 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6;
6147 break;
6148 case 8:
6149 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8;
6150 break;
6151 case 16:
6152 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16;
6153 break;
6154 default:
Meng Wang15c825d2018-09-06 10:49:18 +08006155 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306156 "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n",
6157 __func__, div_factor, mclk_rate, dmic_clk_rate);
6158 break;
6159 }
6160
6161done:
6162 return dmic_ctl_val;
6163}
6164
6165static int tasha_codec_enable_adc(struct snd_soc_dapm_widget *w,
6166 struct snd_kcontrol *kcontrol, int event)
6167{
Meng Wang15c825d2018-09-06 10:49:18 +08006168 struct snd_soc_component *component =
6169 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306170
Meng Wang15c825d2018-09-06 10:49:18 +08006171 dev_dbg(component->dev, "%s: event:%d\n", __func__, event);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306172
6173 switch (event) {
6174 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08006175 tasha_codec_set_tx_hold(component, w->reg, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306176 break;
6177 default:
6178 break;
6179 }
6180
6181 return 0;
6182}
6183
6184static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w,
6185 struct snd_kcontrol *kcontrol, int event)
6186{
Meng Wang15c825d2018-09-06 10:49:18 +08006187 struct snd_soc_component *component =
6188 snd_soc_dapm_to_component(w->dapm);
6189 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
6190 struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306191 u8 dmic_clk_en = 0x01;
6192 u16 dmic_clk_reg;
6193 s32 *dmic_clk_cnt;
6194 u8 dmic_rate_val, dmic_rate_shift = 1;
6195 unsigned int dmic;
6196 u32 dmic_sample_rate;
6197 int ret;
6198 char *wname;
6199
6200 wname = strpbrk(w->name, "012345");
6201 if (!wname) {
Meng Wang15c825d2018-09-06 10:49:18 +08006202 dev_err(component->dev, "%s: widget not found\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306203 return -EINVAL;
6204 }
6205
6206 ret = kstrtouint(wname, 10, &dmic);
6207 if (ret < 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08006208 dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306209 __func__);
6210 return -EINVAL;
6211 }
6212
6213 switch (dmic) {
6214 case 0:
6215 case 1:
6216 dmic_clk_cnt = &(tasha->dmic_0_1_clk_cnt);
6217 dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL;
6218 break;
6219 case 2:
6220 case 3:
6221 dmic_clk_cnt = &(tasha->dmic_2_3_clk_cnt);
6222 dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL;
6223 break;
6224 case 4:
6225 case 5:
6226 dmic_clk_cnt = &(tasha->dmic_4_5_clk_cnt);
6227 dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL;
6228 break;
6229 default:
Meng Wang15c825d2018-09-06 10:49:18 +08006230 dev_err(component->dev, "%s: Invalid DMIC Selection\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306231 __func__);
6232 return -EINVAL;
6233 };
Meng Wang15c825d2018-09-06 10:49:18 +08006234 dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306235 __func__, event, dmic, *dmic_clk_cnt);
6236
6237 switch (event) {
6238 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08006239 dmic_sample_rate = tasha_get_dmic_sample_rate(component, dmic,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306240 pdata);
6241 dmic_rate_val =
Meng Wang15c825d2018-09-06 10:49:18 +08006242 tasha_get_dmic_clk_val(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306243 pdata->mclk_rate,
6244 dmic_sample_rate);
6245
6246 (*dmic_clk_cnt)++;
6247 if (*dmic_clk_cnt == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08006248 snd_soc_component_update_bits(component, dmic_clk_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306249 0x07 << dmic_rate_shift,
6250 dmic_rate_val << dmic_rate_shift);
Meng Wang15c825d2018-09-06 10:49:18 +08006251 snd_soc_component_update_bits(component, dmic_clk_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306252 dmic_clk_en, dmic_clk_en);
6253 }
6254
6255 break;
6256 case SND_SOC_DAPM_POST_PMD:
6257 dmic_rate_val =
Meng Wang15c825d2018-09-06 10:49:18 +08006258 tasha_get_dmic_clk_val(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306259 pdata->mclk_rate,
6260 pdata->mad_dmic_sample_rate);
6261 (*dmic_clk_cnt)--;
6262 if (*dmic_clk_cnt == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08006263 snd_soc_component_update_bits(component, dmic_clk_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306264 dmic_clk_en, 0);
Meng Wang15c825d2018-09-06 10:49:18 +08006265 snd_soc_component_update_bits(component, dmic_clk_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306266 0x07 << dmic_rate_shift,
6267 dmic_rate_val << dmic_rate_shift);
6268 }
6269 break;
6270 };
6271
6272 return 0;
6273}
6274
6275static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6276 int event)
6277{
Meng Wang15c825d2018-09-06 10:49:18 +08006278 struct snd_soc_component *component =
6279 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306280 int micb_num;
6281
Meng Wang15c825d2018-09-06 10:49:18 +08006282 dev_dbg(component->dev, "%s: wname: %s, event: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306283 __func__, w->name, event);
6284
6285 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1")))
6286 micb_num = MIC_BIAS_1;
6287 else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2")))
6288 micb_num = MIC_BIAS_2;
6289 else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))
6290 micb_num = MIC_BIAS_3;
6291 else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4")))
6292 micb_num = MIC_BIAS_4;
6293 else
6294 return -EINVAL;
6295
6296 switch (event) {
6297 case SND_SOC_DAPM_PRE_PMU:
6298 /*
6299 * MIC BIAS can also be requested by MBHC,
6300 * so use ref count to handle micbias pullup
6301 * and enable requests
6302 */
Meng Wang15c825d2018-09-06 10:49:18 +08006303 tasha_micbias_control(component, micb_num, MICB_ENABLE, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306304 break;
6305 case SND_SOC_DAPM_POST_PMU:
6306 /* wait for cnp time */
6307 usleep_range(1000, 1100);
6308 break;
6309 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08006310 tasha_micbias_control(component, micb_num, MICB_DISABLE, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306311 break;
6312 };
6313
6314 return 0;
6315}
6316
6317static int tasha_codec_ldo_h_control(struct snd_soc_dapm_widget *w,
6318 int event)
6319{
Meng Wang15c825d2018-09-06 10:49:18 +08006320 struct snd_soc_component *component =
6321 snd_soc_dapm_to_component(w->dapm);
6322 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306323
6324 if (SND_SOC_DAPM_EVENT_ON(event)) {
6325 tasha->ldo_h_users++;
6326
6327 if (tasha->ldo_h_users == 1)
Meng Wang15c825d2018-09-06 10:49:18 +08006328 snd_soc_component_update_bits(component,
6329 WCD9335_LDOH_MODE,
6330 0x80, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306331 }
6332
6333 if (SND_SOC_DAPM_EVENT_OFF(event)) {
6334 tasha->ldo_h_users--;
6335
6336 if (tasha->ldo_h_users < 0)
6337 tasha->ldo_h_users = 0;
6338
6339 if (tasha->ldo_h_users == 0)
Meng Wang15c825d2018-09-06 10:49:18 +08006340 snd_soc_component_update_bits(component,
6341 WCD9335_LDOH_MODE,
6342 0x80, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306343 }
6344
6345 return 0;
6346}
6347
6348static int tasha_codec_force_enable_ldo_h(struct snd_soc_dapm_widget *w,
6349 struct snd_kcontrol *kcontrol,
6350 int event)
6351{
Meng Wang15c825d2018-09-06 10:49:18 +08006352 struct snd_soc_component *component =
6353 snd_soc_dapm_to_component(w->dapm);
6354 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306355
6356 switch (event) {
6357 case SND_SOC_DAPM_PRE_PMU:
6358 wcd_resmgr_enable_master_bias(tasha->resmgr);
6359 tasha_codec_ldo_h_control(w, event);
6360 break;
6361 case SND_SOC_DAPM_POST_PMD:
6362 tasha_codec_ldo_h_control(w, event);
6363 wcd_resmgr_disable_master_bias(tasha->resmgr);
6364 break;
6365 }
6366
6367 return 0;
6368}
6369
6370static int tasha_codec_force_enable_micbias(struct snd_soc_dapm_widget *w,
6371 struct snd_kcontrol *kcontrol,
6372 int event)
6373{
6374 int ret = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08006375 struct snd_soc_component *component =
6376 snd_soc_dapm_to_component(w->dapm);
6377 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306378
6379 switch (event) {
6380 case SND_SOC_DAPM_PRE_PMU:
6381 wcd_resmgr_enable_master_bias(tasha->resmgr);
Meng Wang15c825d2018-09-06 10:49:18 +08006382 tasha_cdc_mclk_enable(component, true, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306383 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU);
6384 /* Wait for 1ms for better cnp */
6385 usleep_range(1000, 1100);
Meng Wang15c825d2018-09-06 10:49:18 +08006386 tasha_cdc_mclk_enable(component, false, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306387 break;
6388 case SND_SOC_DAPM_POST_PMD:
6389 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD);
6390 wcd_resmgr_disable_master_bias(tasha->resmgr);
6391 break;
6392 }
6393
6394 return ret;
6395}
6396
6397static int tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6398 struct snd_kcontrol *kcontrol, int event)
6399{
6400 return __tasha_codec_enable_micbias(w, event);
6401}
6402
Meng Wang15c825d2018-09-06 10:49:18 +08006403static int tasha_codec_enable_standalone_ldo_h(
6404 struct snd_soc_component *component,
6405 bool enable)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306406{
6407 int rc;
6408
6409 if (enable)
6410 rc = snd_soc_dapm_force_enable_pin(
Meng Wang15c825d2018-09-06 10:49:18 +08006411 snd_soc_component_get_dapm(component),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306412 DAPM_LDO_H_STANDALONE);
6413 else
6414 rc = snd_soc_dapm_disable_pin(
Meng Wang15c825d2018-09-06 10:49:18 +08006415 snd_soc_component_get_dapm(component),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306416 DAPM_LDO_H_STANDALONE);
6417
6418 if (!rc)
Meng Wang15c825d2018-09-06 10:49:18 +08006419 snd_soc_dapm_sync(snd_soc_component_get_dapm(component));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306420 else
Meng Wang15c825d2018-09-06 10:49:18 +08006421 dev_err(component->dev, "%s: ldo_h force %s pin failed\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306422 __func__, (enable ? "enable" : "disable"));
6423
6424 return rc;
6425}
6426
6427/*
6428 * tasha_codec_enable_standalone_micbias - enable micbias standalone
Meng Wang15c825d2018-09-06 10:49:18 +08006429 * @component: pointer to codec instance
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306430 * @micb_num: number of micbias to be enabled
6431 * @enable: true to enable micbias or false to disable
6432 *
6433 * This function is used to enable micbias (1, 2, 3 or 4) during
6434 * standalone independent of whether TX use-case is running or not
6435 *
6436 * Return: error code in case of failure or 0 for success
6437 */
Meng Wang15c825d2018-09-06 10:49:18 +08006438int tasha_codec_enable_standalone_micbias(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306439 int micb_num,
6440 bool enable)
6441{
6442 const char * const micb_names[] = {
6443 DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE,
6444 DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE
6445 };
6446 int micb_index = micb_num - 1;
6447 int rc;
6448
Meng Wang15c825d2018-09-06 10:49:18 +08006449 if (!component) {
6450 pr_err("%s: Component memory is NULL\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306451 return -EINVAL;
6452 }
6453
6454 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
Meng Wang15c825d2018-09-06 10:49:18 +08006455 dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306456 __func__, micb_index);
6457 return -EINVAL;
6458 }
6459
6460 if (enable)
6461 rc = snd_soc_dapm_force_enable_pin(
Meng Wang15c825d2018-09-06 10:49:18 +08006462 snd_soc_component_get_dapm(component),
6463 micb_names[micb_index]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306464 else
Meng Wang15c825d2018-09-06 10:49:18 +08006465 rc = snd_soc_dapm_disable_pin(
6466 snd_soc_component_get_dapm(component),
6467 micb_names[micb_index]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306468
6469 if (!rc)
Meng Wang15c825d2018-09-06 10:49:18 +08006470 snd_soc_dapm_sync(snd_soc_component_get_dapm(component));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306471 else
Meng Wang15c825d2018-09-06 10:49:18 +08006472 dev_err(component->dev, "%s: micbias%d force %s pin failed\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306473 __func__, micb_num, (enable ? "enable" : "disable"));
6474
6475 return rc;
6476}
6477EXPORT_SYMBOL(tasha_codec_enable_standalone_micbias);
6478
6479static const char *const tasha_anc_func_text[] = {"OFF", "ON"};
6480static const struct soc_enum tasha_anc_func_enum =
6481 SOC_ENUM_SINGLE_EXT(2, tasha_anc_func_text);
6482
6483static const char *const tasha_clkmode_text[] = {"EXTERNAL", "INTERNAL"};
6484static SOC_ENUM_SINGLE_EXT_DECL(tasha_clkmode_enum, tasha_clkmode_text);
6485
6486/* Cutoff frequency for high pass filter */
6487static const char * const cf_text[] = {
6488 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
6489};
6490
6491static const char * const rx_cf_text[] = {
6492 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
6493 "CF_NEG_3DB_0P48HZ"
6494};
6495
6496static const struct soc_enum cf_dec0_enum =
6497 SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text);
6498
6499static const struct soc_enum cf_dec1_enum =
6500 SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text);
6501
6502static const struct soc_enum cf_dec2_enum =
6503 SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text);
6504
6505static const struct soc_enum cf_dec3_enum =
6506 SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text);
6507
6508static const struct soc_enum cf_dec4_enum =
6509 SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text);
6510
6511static const struct soc_enum cf_dec5_enum =
6512 SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text);
6513
6514static const struct soc_enum cf_dec6_enum =
6515 SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text);
6516
6517static const struct soc_enum cf_dec7_enum =
6518 SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text);
6519
6520static const struct soc_enum cf_dec8_enum =
6521 SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text);
6522
6523static const struct soc_enum cf_int0_1_enum =
6524 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
6525
6526static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
6527 rx_cf_text);
6528
6529static const struct soc_enum cf_int1_1_enum =
6530 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
6531
6532static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
6533 rx_cf_text);
6534
6535static const struct soc_enum cf_int2_1_enum =
6536 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
6537
6538static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
6539 rx_cf_text);
6540
6541static const struct soc_enum cf_int3_1_enum =
6542 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
6543
6544static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
6545 rx_cf_text);
6546
6547static const struct soc_enum cf_int4_1_enum =
6548 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
6549
6550static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
6551 rx_cf_text);
6552
6553static const struct soc_enum cf_int5_1_enum =
6554 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
6555
6556static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
6557 rx_cf_text);
6558
6559static const struct soc_enum cf_int6_1_enum =
6560 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
6561
6562static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
6563 rx_cf_text);
6564
6565static const struct soc_enum cf_int7_1_enum =
6566 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
6567
6568static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
6569 rx_cf_text);
6570
6571static const struct soc_enum cf_int8_1_enum =
6572 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
6573
6574static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
6575 rx_cf_text);
6576
6577static const struct snd_soc_dapm_route audio_i2s_map[] = {
6578 {"SLIM RX0 MUX", NULL, "RX_I2S_CTL"},
6579 {"SLIM RX1 MUX", NULL, "RX_I2S_CTL"},
6580 {"SLIM RX2 MUX", NULL, "RX_I2S_CTL"},
6581 {"SLIM RX3 MUX", NULL, "RX_I2S_CTL"},
6582
6583 {"SLIM TX6 MUX", NULL, "TX_I2S_CTL"},
6584 {"SLIM TX7 MUX", NULL, "TX_I2S_CTL"},
6585 {"SLIM TX8 MUX", NULL, "TX_I2S_CTL"},
6586 {"SLIM TX11 MUX", NULL, "TX_I2S_CTL"},
6587};
6588
6589static const struct snd_soc_dapm_route audio_map[] = {
6590
6591 /* MAD */
6592 {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"},
6593 {"MAD_SEL MUX", "MSM", "MADINPUT"},
6594 {"MADONOFF", "Switch", "MAD_SEL MUX"},
6595 {"MAD_BROADCAST", "Switch", "MAD_SEL MUX"},
6596 {"TX13 INP MUX", "CPE_TX_PP", "MADONOFF"},
6597
6598 /* CPE HW MAD bypass */
6599 {"CPE IN Mixer", "MAD_BYPASS", "SLIM TX1 MUX"},
6600
6601 {"AIF4_MAD Mixer", "SLIM TX1", "CPE IN Mixer"},
6602 {"AIF4_MAD Mixer", "SLIM TX12", "MADONOFF"},
6603 {"AIF4_MAD Mixer", "SLIM TX13", "TX13 INP MUX"},
6604 {"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
6605 {"AIF4 MAD", NULL, "AIF4"},
6606
6607 {"EC BUF MUX INP", "DEC1", "ADC MUX1"},
6608 {"AIF5 CPE", NULL, "EC BUF MUX INP"},
6609
6610 /* SLIMBUS Connections */
6611 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
6612 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
6613 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
6614
6615 /* VI Feedback */
6616 {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"},
6617 {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"},
6618 {"AIF4 VI", NULL, "AIF4_VI Mixer"},
6619
6620 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
6621 {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6622 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6623 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6624 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6625 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6626 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6627 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6628 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6629 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6630 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6631 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6632 {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6633 {"AIF1_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6634 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
6635 {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6636 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6637 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6638 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6639 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6640 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6641 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6642 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6643 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6644 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6645 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6646 {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6647 {"AIF2_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6648 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
6649 {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6650 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6651 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6652 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6653 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6654 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6655 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6656 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6657 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6658 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6659 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6660 {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6661 {"AIF3_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6662
6663 {"SLIM TX0 MUX", "DEC0", "ADC MUX0"},
6664 {"SLIM TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
6665 {"SLIM TX0 MUX", "DEC0_192", "ADC US MUX0"},
6666
6667 {"SLIM TX1 MUX", "DEC1", "ADC MUX1"},
6668 {"SLIM TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"},
6669 {"SLIM TX1 MUX", "DEC1_192", "ADC US MUX1"},
6670
6671 {"SLIM TX2 MUX", "DEC2", "ADC MUX2"},
6672 {"SLIM TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"},
6673 {"SLIM TX2 MUX", "DEC2_192", "ADC US MUX2"},
6674
6675 {"SLIM TX3 MUX", "DEC3", "ADC MUX3"},
6676 {"SLIM TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"},
6677 {"SLIM TX3 MUX", "DEC3_192", "ADC US MUX3"},
6678
6679 {"SLIM TX4 MUX", "DEC4", "ADC MUX4"},
6680 {"SLIM TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"},
6681 {"SLIM TX4 MUX", "DEC4_192", "ADC US MUX4"},
6682
6683 {"SLIM TX5 MUX", "DEC5", "ADC MUX5"},
6684 {"SLIM TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6685 {"SLIM TX5 MUX", "DEC5_192", "ADC US MUX5"},
6686
6687 {"SLIM TX6 MUX", "DEC6", "ADC MUX6"},
6688 {"SLIM TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"},
6689 {"SLIM TX6 MUX", "DEC6_192", "ADC US MUX6"},
6690
6691 {"SLIM TX7 MUX", "DEC7", "ADC MUX7"},
6692 {"SLIM TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"},
6693 {"SLIM TX7 MUX", "DEC7_192", "ADC US MUX7"},
6694
6695 {"SLIM TX8 MUX", "DEC8", "ADC MUX8"},
6696 {"SLIM TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"},
6697 {"SLIM TX8 MUX", "DEC8_192", "ADC US MUX8"},
6698
6699 {"SLIM TX9 MUX", "DEC7", "ADC MUX7"},
6700 {"SLIM TX9 MUX", "DEC7_192", "ADC US MUX7"},
6701 {"SLIM TX10 MUX", "DEC6", "ADC MUX6"},
6702 {"SLIM TX10 MUX", "DEC6_192", "ADC US MUX6"},
6703
6704 {"SLIM TX11 MUX", "DEC_0_5", "SLIM TX11 INP1 MUX"},
6705 {"SLIM TX11 MUX", "DEC_9_12", "SLIM TX11 INP1 MUX"},
6706 {"SLIM TX11 INP1 MUX", "DEC0", "ADC MUX0"},
6707 {"SLIM TX11 INP1 MUX", "DEC1", "ADC MUX1"},
6708 {"SLIM TX11 INP1 MUX", "DEC2", "ADC MUX2"},
6709 {"SLIM TX11 INP1 MUX", "DEC3", "ADC MUX3"},
6710 {"SLIM TX11 INP1 MUX", "DEC4", "ADC MUX4"},
6711 {"SLIM TX11 INP1 MUX", "DEC5", "ADC MUX5"},
6712 {"SLIM TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6713
6714 {"TX13 INP MUX", "MAD_BRDCST", "MAD_BROADCAST"},
6715 {"TX13 INP MUX", "CDC_DEC_5", "SLIM TX13 MUX"},
6716 {"SLIM TX13 MUX", "DEC5", "ADC MUX5"},
6717
6718 {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6719 {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6720 {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6721 {"RX MIX TX0 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6722 {"RX MIX TX0 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6723 {"RX MIX TX0 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6724 {"RX MIX TX0 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6725 {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6726 {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6727 {"RX MIX TX0 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6728 {"RX MIX TX0 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6729 {"RX MIX TX0 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6730 {"RX MIX TX0 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6731
6732 {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6733 {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6734 {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6735 {"RX MIX TX1 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6736 {"RX MIX TX1 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6737 {"RX MIX TX1 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6738 {"RX MIX TX1 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6739 {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6740 {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6741 {"RX MIX TX1 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6742 {"RX MIX TX1 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6743 {"RX MIX TX1 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6744 {"RX MIX TX1 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6745
6746 {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6747 {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6748 {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6749 {"RX MIX TX2 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6750 {"RX MIX TX2 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6751 {"RX MIX TX2 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6752 {"RX MIX TX2 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6753 {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6754 {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6755 {"RX MIX TX2 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6756 {"RX MIX TX2 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6757 {"RX MIX TX2 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6758 {"RX MIX TX2 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6759
6760 {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6761 {"RX MIX TX3 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6762 {"RX MIX TX3 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6763 {"RX MIX TX3 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6764 {"RX MIX TX3 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6765 {"RX MIX TX3 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6766 {"RX MIX TX3 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6767 {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6768 {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6769 {"RX MIX TX3 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6770 {"RX MIX TX3 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6771 {"RX MIX TX3 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6772 {"RX MIX TX3 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6773
6774 {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6775 {"RX MIX TX4 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6776 {"RX MIX TX4 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6777 {"RX MIX TX4 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6778 {"RX MIX TX4 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6779 {"RX MIX TX4 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6780 {"RX MIX TX4 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6781 {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6782 {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6783 {"RX MIX TX4 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6784 {"RX MIX TX4 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6785 {"RX MIX TX4 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6786 {"RX MIX TX4 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6787
6788 {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6789 {"RX MIX TX5 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6790 {"RX MIX TX5 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6791 {"RX MIX TX5 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6792 {"RX MIX TX5 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6793 {"RX MIX TX5 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6794 {"RX MIX TX5 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6795 {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6796 {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6797 {"RX MIX TX5 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6798 {"RX MIX TX5 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6799 {"RX MIX TX5 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6800 {"RX MIX TX5 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6801
6802 {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6803 {"RX MIX TX6 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6804 {"RX MIX TX6 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6805 {"RX MIX TX6 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6806 {"RX MIX TX6 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6807 {"RX MIX TX6 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6808 {"RX MIX TX6 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6809 {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6810 {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6811 {"RX MIX TX6 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6812 {"RX MIX TX6 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6813 {"RX MIX TX6 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6814 {"RX MIX TX6 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6815
6816 {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6817 {"RX MIX TX7 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6818 {"RX MIX TX7 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6819 {"RX MIX TX7 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6820 {"RX MIX TX7 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6821 {"RX MIX TX7 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6822 {"RX MIX TX7 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6823 {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6824 {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6825 {"RX MIX TX7 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6826 {"RX MIX TX7 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6827 {"RX MIX TX7 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6828 {"RX MIX TX7 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6829
6830 {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6831 {"RX MIX TX8 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6832 {"RX MIX TX8 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6833 {"RX MIX TX8 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6834 {"RX MIX TX8 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6835 {"RX MIX TX8 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6836 {"RX MIX TX8 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6837 {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6838 {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6839 {"RX MIX TX8 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6840 {"RX MIX TX8 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6841 {"RX MIX TX8 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6842 {"RX MIX TX8 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6843
6844 {"ADC US MUX0", "US_Switch", "ADC MUX0"},
6845 {"ADC US MUX1", "US_Switch", "ADC MUX1"},
6846 {"ADC US MUX2", "US_Switch", "ADC MUX2"},
6847 {"ADC US MUX3", "US_Switch", "ADC MUX3"},
6848 {"ADC US MUX4", "US_Switch", "ADC MUX4"},
6849 {"ADC US MUX5", "US_Switch", "ADC MUX5"},
6850 {"ADC US MUX6", "US_Switch", "ADC MUX6"},
6851 {"ADC US MUX7", "US_Switch", "ADC MUX7"},
6852 {"ADC US MUX8", "US_Switch", "ADC MUX8"},
6853 {"ADC MUX0", "DMIC", "DMIC MUX0"},
6854 {"ADC MUX0", "AMIC", "AMIC MUX0"},
6855 {"ADC MUX1", "DMIC", "DMIC MUX1"},
6856 {"ADC MUX1", "AMIC", "AMIC MUX1"},
6857 {"ADC MUX2", "DMIC", "DMIC MUX2"},
6858 {"ADC MUX2", "AMIC", "AMIC MUX2"},
6859 {"ADC MUX3", "DMIC", "DMIC MUX3"},
6860 {"ADC MUX3", "AMIC", "AMIC MUX3"},
6861 {"ADC MUX4", "DMIC", "DMIC MUX4"},
6862 {"ADC MUX4", "AMIC", "AMIC MUX4"},
6863 {"ADC MUX5", "DMIC", "DMIC MUX5"},
6864 {"ADC MUX5", "AMIC", "AMIC MUX5"},
6865 {"ADC MUX6", "DMIC", "DMIC MUX6"},
6866 {"ADC MUX6", "AMIC", "AMIC MUX6"},
6867 {"ADC MUX7", "DMIC", "DMIC MUX7"},
6868 {"ADC MUX7", "AMIC", "AMIC MUX7"},
6869 {"ADC MUX8", "DMIC", "DMIC MUX8"},
6870 {"ADC MUX8", "AMIC", "AMIC MUX8"},
6871 {"ADC MUX10", "DMIC", "DMIC MUX10"},
6872 {"ADC MUX10", "AMIC", "AMIC MUX10"},
6873 {"ADC MUX11", "DMIC", "DMIC MUX11"},
6874 {"ADC MUX11", "AMIC", "AMIC MUX11"},
6875 {"ADC MUX12", "DMIC", "DMIC MUX12"},
6876 {"ADC MUX12", "AMIC", "AMIC MUX12"},
6877 {"ADC MUX13", "DMIC", "DMIC MUX13"},
6878 {"ADC MUX13", "AMIC", "AMIC MUX13"},
6879
6880 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"},
6881 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"},
6882 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX12"},
6883 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX13"},
6884 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"},
6885 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"},
6886 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX12"},
6887 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX13"},
6888 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"},
6889 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"},
6890 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX12"},
6891 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX13"},
6892 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"},
6893 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"},
6894 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX12"},
6895 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX13"},
6896 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"},
6897 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"},
6898 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX12"},
6899 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX13"},
6900 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"},
6901 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"},
6902 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX12"},
6903 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX13"},
6904 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"},
6905 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"},
6906 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX12"},
6907 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX13"},
6908 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"},
6909 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"},
6910 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX12"},
6911 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX13"},
6912 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"},
6913 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"},
6914 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX12"},
6915 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX13"},
6916
6917 {"DMIC MUX0", "DMIC0", "DMIC0"},
6918 {"DMIC MUX0", "DMIC1", "DMIC1"},
6919 {"DMIC MUX0", "DMIC2", "DMIC2"},
6920 {"DMIC MUX0", "DMIC3", "DMIC3"},
6921 {"DMIC MUX0", "DMIC4", "DMIC4"},
6922 {"DMIC MUX0", "DMIC5", "DMIC5"},
6923 {"AMIC MUX0", "ADC1", "ADC1"},
6924 {"AMIC MUX0", "ADC2", "ADC2"},
6925 {"AMIC MUX0", "ADC3", "ADC3"},
6926 {"AMIC MUX0", "ADC4", "ADC4"},
6927 {"AMIC MUX0", "ADC5", "ADC5"},
6928 {"AMIC MUX0", "ADC6", "ADC6"},
6929
6930 {"DMIC MUX1", "DMIC0", "DMIC0"},
6931 {"DMIC MUX1", "DMIC1", "DMIC1"},
6932 {"DMIC MUX1", "DMIC2", "DMIC2"},
6933 {"DMIC MUX1", "DMIC3", "DMIC3"},
6934 {"DMIC MUX1", "DMIC4", "DMIC4"},
6935 {"DMIC MUX1", "DMIC5", "DMIC5"},
6936 {"AMIC MUX1", "ADC1", "ADC1"},
6937 {"AMIC MUX1", "ADC2", "ADC2"},
6938 {"AMIC MUX1", "ADC3", "ADC3"},
6939 {"AMIC MUX1", "ADC4", "ADC4"},
6940 {"AMIC MUX1", "ADC5", "ADC5"},
6941 {"AMIC MUX1", "ADC6", "ADC6"},
6942
6943 {"DMIC MUX2", "DMIC0", "DMIC0"},
6944 {"DMIC MUX2", "DMIC1", "DMIC1"},
6945 {"DMIC MUX2", "DMIC2", "DMIC2"},
6946 {"DMIC MUX2", "DMIC3", "DMIC3"},
6947 {"DMIC MUX2", "DMIC4", "DMIC4"},
6948 {"DMIC MUX2", "DMIC5", "DMIC5"},
6949 {"AMIC MUX2", "ADC1", "ADC1"},
6950 {"AMIC MUX2", "ADC2", "ADC2"},
6951 {"AMIC MUX2", "ADC3", "ADC3"},
6952 {"AMIC MUX2", "ADC4", "ADC4"},
6953 {"AMIC MUX2", "ADC5", "ADC5"},
6954 {"AMIC MUX2", "ADC6", "ADC6"},
6955
6956 {"DMIC MUX3", "DMIC0", "DMIC0"},
6957 {"DMIC MUX3", "DMIC1", "DMIC1"},
6958 {"DMIC MUX3", "DMIC2", "DMIC2"},
6959 {"DMIC MUX3", "DMIC3", "DMIC3"},
6960 {"DMIC MUX3", "DMIC4", "DMIC4"},
6961 {"DMIC MUX3", "DMIC5", "DMIC5"},
6962 {"AMIC MUX3", "ADC1", "ADC1"},
6963 {"AMIC MUX3", "ADC2", "ADC2"},
6964 {"AMIC MUX3", "ADC3", "ADC3"},
6965 {"AMIC MUX3", "ADC4", "ADC4"},
6966 {"AMIC MUX3", "ADC5", "ADC5"},
6967 {"AMIC MUX3", "ADC6", "ADC6"},
6968
6969 {"DMIC MUX4", "DMIC0", "DMIC0"},
6970 {"DMIC MUX4", "DMIC1", "DMIC1"},
6971 {"DMIC MUX4", "DMIC2", "DMIC2"},
6972 {"DMIC MUX4", "DMIC3", "DMIC3"},
6973 {"DMIC MUX4", "DMIC4", "DMIC4"},
6974 {"DMIC MUX4", "DMIC5", "DMIC5"},
6975 {"AMIC MUX4", "ADC1", "ADC1"},
6976 {"AMIC MUX4", "ADC2", "ADC2"},
6977 {"AMIC MUX4", "ADC3", "ADC3"},
6978 {"AMIC MUX4", "ADC4", "ADC4"},
6979 {"AMIC MUX4", "ADC5", "ADC5"},
6980 {"AMIC MUX4", "ADC6", "ADC6"},
6981
6982 {"DMIC MUX5", "DMIC0", "DMIC0"},
6983 {"DMIC MUX5", "DMIC1", "DMIC1"},
6984 {"DMIC MUX5", "DMIC2", "DMIC2"},
6985 {"DMIC MUX5", "DMIC3", "DMIC3"},
6986 {"DMIC MUX5", "DMIC4", "DMIC4"},
6987 {"DMIC MUX5", "DMIC5", "DMIC5"},
6988 {"AMIC MUX5", "ADC1", "ADC1"},
6989 {"AMIC MUX5", "ADC2", "ADC2"},
6990 {"AMIC MUX5", "ADC3", "ADC3"},
6991 {"AMIC MUX5", "ADC4", "ADC4"},
6992 {"AMIC MUX5", "ADC5", "ADC5"},
6993 {"AMIC MUX5", "ADC6", "ADC6"},
6994
6995 {"DMIC MUX6", "DMIC0", "DMIC0"},
6996 {"DMIC MUX6", "DMIC1", "DMIC1"},
6997 {"DMIC MUX6", "DMIC2", "DMIC2"},
6998 {"DMIC MUX6", "DMIC3", "DMIC3"},
6999 {"DMIC MUX6", "DMIC4", "DMIC4"},
7000 {"DMIC MUX6", "DMIC5", "DMIC5"},
7001 {"AMIC MUX6", "ADC1", "ADC1"},
7002 {"AMIC MUX6", "ADC2", "ADC2"},
7003 {"AMIC MUX6", "ADC3", "ADC3"},
7004 {"AMIC MUX6", "ADC4", "ADC4"},
7005 {"AMIC MUX6", "ADC5", "ADC5"},
7006 {"AMIC MUX6", "ADC6", "ADC6"},
7007
7008 {"DMIC MUX7", "DMIC0", "DMIC0"},
7009 {"DMIC MUX7", "DMIC1", "DMIC1"},
7010 {"DMIC MUX7", "DMIC2", "DMIC2"},
7011 {"DMIC MUX7", "DMIC3", "DMIC3"},
7012 {"DMIC MUX7", "DMIC4", "DMIC4"},
7013 {"DMIC MUX7", "DMIC5", "DMIC5"},
7014 {"AMIC MUX7", "ADC1", "ADC1"},
7015 {"AMIC MUX7", "ADC2", "ADC2"},
7016 {"AMIC MUX7", "ADC3", "ADC3"},
7017 {"AMIC MUX7", "ADC4", "ADC4"},
7018 {"AMIC MUX7", "ADC5", "ADC5"},
7019 {"AMIC MUX7", "ADC6", "ADC6"},
7020
7021 {"DMIC MUX8", "DMIC0", "DMIC0"},
7022 {"DMIC MUX8", "DMIC1", "DMIC1"},
7023 {"DMIC MUX8", "DMIC2", "DMIC2"},
7024 {"DMIC MUX8", "DMIC3", "DMIC3"},
7025 {"DMIC MUX8", "DMIC4", "DMIC4"},
7026 {"DMIC MUX8", "DMIC5", "DMIC5"},
7027 {"AMIC MUX8", "ADC1", "ADC1"},
7028 {"AMIC MUX8", "ADC2", "ADC2"},
7029 {"AMIC MUX8", "ADC3", "ADC3"},
7030 {"AMIC MUX8", "ADC4", "ADC4"},
7031 {"AMIC MUX8", "ADC5", "ADC5"},
7032 {"AMIC MUX8", "ADC6", "ADC6"},
7033
7034 {"DMIC MUX10", "DMIC0", "DMIC0"},
7035 {"DMIC MUX10", "DMIC1", "DMIC1"},
7036 {"DMIC MUX10", "DMIC2", "DMIC2"},
7037 {"DMIC MUX10", "DMIC3", "DMIC3"},
7038 {"DMIC MUX10", "DMIC4", "DMIC4"},
7039 {"DMIC MUX10", "DMIC5", "DMIC5"},
7040 {"AMIC MUX10", "ADC1", "ADC1"},
7041 {"AMIC MUX10", "ADC2", "ADC2"},
7042 {"AMIC MUX10", "ADC3", "ADC3"},
7043 {"AMIC MUX10", "ADC4", "ADC4"},
7044 {"AMIC MUX10", "ADC5", "ADC5"},
7045 {"AMIC MUX10", "ADC6", "ADC6"},
7046
7047 {"DMIC MUX11", "DMIC0", "DMIC0"},
7048 {"DMIC MUX11", "DMIC1", "DMIC1"},
7049 {"DMIC MUX11", "DMIC2", "DMIC2"},
7050 {"DMIC MUX11", "DMIC3", "DMIC3"},
7051 {"DMIC MUX11", "DMIC4", "DMIC4"},
7052 {"DMIC MUX11", "DMIC5", "DMIC5"},
7053 {"AMIC MUX11", "ADC1", "ADC1"},
7054 {"AMIC MUX11", "ADC2", "ADC2"},
7055 {"AMIC MUX11", "ADC3", "ADC3"},
7056 {"AMIC MUX11", "ADC4", "ADC4"},
7057 {"AMIC MUX11", "ADC5", "ADC5"},
7058 {"AMIC MUX11", "ADC6", "ADC6"},
7059
7060 {"DMIC MUX12", "DMIC0", "DMIC0"},
7061 {"DMIC MUX12", "DMIC1", "DMIC1"},
7062 {"DMIC MUX12", "DMIC2", "DMIC2"},
7063 {"DMIC MUX12", "DMIC3", "DMIC3"},
7064 {"DMIC MUX12", "DMIC4", "DMIC4"},
7065 {"DMIC MUX12", "DMIC5", "DMIC5"},
7066 {"AMIC MUX12", "ADC1", "ADC1"},
7067 {"AMIC MUX12", "ADC2", "ADC2"},
7068 {"AMIC MUX12", "ADC3", "ADC3"},
7069 {"AMIC MUX12", "ADC4", "ADC4"},
7070 {"AMIC MUX12", "ADC5", "ADC5"},
7071 {"AMIC MUX12", "ADC6", "ADC6"},
7072
7073 {"DMIC MUX13", "DMIC0", "DMIC0"},
7074 {"DMIC MUX13", "DMIC1", "DMIC1"},
7075 {"DMIC MUX13", "DMIC2", "DMIC2"},
7076 {"DMIC MUX13", "DMIC3", "DMIC3"},
7077 {"DMIC MUX13", "DMIC4", "DMIC4"},
7078 {"DMIC MUX13", "DMIC5", "DMIC5"},
7079 {"AMIC MUX13", "ADC1", "ADC1"},
7080 {"AMIC MUX13", "ADC2", "ADC2"},
7081 {"AMIC MUX13", "ADC3", "ADC3"},
7082 {"AMIC MUX13", "ADC4", "ADC4"},
7083 {"AMIC MUX13", "ADC5", "ADC5"},
7084 {"AMIC MUX13", "ADC6", "ADC6"},
7085 /* ADC Connections */
7086 {"ADC1", NULL, "AMIC1"},
7087 {"ADC2", NULL, "AMIC2"},
7088 {"ADC3", NULL, "AMIC3"},
7089 {"ADC4", NULL, "AMIC4"},
7090 {"ADC5", NULL, "AMIC5"},
7091 {"ADC6", NULL, "AMIC6"},
7092
7093 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
7094 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
7095 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
7096 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
7097 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
7098 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
7099 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
7100 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
7101 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
7102 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP0"},
7103 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP1"},
7104 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP2"},
7105 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP0"},
7106 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP1"},
7107 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP2"},
7108 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP0"},
7109 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP1"},
7110 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP2"},
7111 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP0"},
7112 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP1"},
7113 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP2"},
7114 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"},
7115 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"},
7116 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"},
7117 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"},
7118 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"},
7119 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"},
7120
7121 {"RX INT0 SEC MIX", NULL, "RX INT0_1 MIX1"},
7122 {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
7123 {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
7124 {"RX INT0 INTERP", NULL, "RX INT0 MIX2"},
7125 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"},
7126 {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"},
7127 {"RX INT0 DAC", NULL, "RX_BIAS"},
7128 {"EAR PA", NULL, "RX INT0 DAC"},
7129 {"EAR", NULL, "EAR PA"},
7130
7131 {"SPL SRC0 MUX", "SRC_IN_HPHL", "RX INT1_1 MIX1"},
7132 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 MIX1"},
7133 {"RX INT1 SPLINE MIX", "HPHL Switch", "SPL SRC0 MUX"},
7134 {"RX INT1_1 NATIVE MUX", "ON", "RX INT1_1 MIX1"},
7135 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 NATIVE MUX"},
7136 {"RX INT1_1 NATIVE MUX", NULL, "RX INT1 NATIVE SUPPLY"},
7137 {"RX INT1 SEC MIX", NULL, "RX INT1 SPLINE MIX"},
7138 {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
7139 {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
7140 {"RX INT1 INTERP", NULL, "RX INT1 MIX2"},
7141 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"},
7142 {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"},
7143 {"RX INT1 DAC", NULL, "RX_BIAS"},
7144 {"HPHL PA", NULL, "RX INT1 DAC"},
7145 {"HPHL", NULL, "HPHL PA"},
7146
7147 {"SPL SRC1 MUX", "SRC_IN_HPHR", "RX INT2_1 MIX1"},
7148 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 MIX1"},
7149 {"RX INT2 SPLINE MIX", "HPHR Switch", "SPL SRC1 MUX"},
7150 {"RX INT2_1 NATIVE MUX", "ON", "RX INT2_1 MIX1"},
7151 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 NATIVE MUX"},
7152 {"RX INT2_1 NATIVE MUX", NULL, "RX INT2 NATIVE SUPPLY"},
7153 {"RX INT2 SEC MIX", NULL, "RX INT2 SPLINE MIX"},
7154 {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
7155 {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
7156 {"RX INT2 INTERP", NULL, "RX INT2 MIX2"},
7157 {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"},
7158 {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"},
7159 {"RX INT2 DAC", NULL, "RX_BIAS"},
7160 {"HPHR PA", NULL, "RX INT2 DAC"},
7161 {"HPHR", NULL, "HPHR PA"},
7162
7163 {"SPL SRC0 MUX", "SRC_IN_LO1", "RX INT3_1 MIX1"},
7164 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 MIX1"},
7165 {"RX INT3 SPLINE MIX", "LO1 Switch", "SPL SRC0 MUX"},
7166 {"RX INT3_1 NATIVE MUX", "ON", "RX INT3_1 MIX1"},
7167 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 NATIVE MUX"},
7168 {"RX INT3_1 NATIVE MUX", NULL, "RX INT3 NATIVE SUPPLY"},
7169 {"RX INT3 SEC MIX", NULL, "RX INT3 SPLINE MIX"},
7170 {"RX INT3 MIX2", NULL, "RX INT3 SEC MIX"},
7171 {"RX INT3 MIX2", NULL, "RX INT3 MIX2 INP"},
7172 {"RX INT3 INTERP", NULL, "RX INT3 MIX2"},
7173 {"RX INT3 DAC", NULL, "RX INT3 INTERP"},
7174 {"RX INT3 DAC", NULL, "RX_BIAS"},
7175 {"LINEOUT1 PA", NULL, "RX INT3 DAC"},
7176 {"LINEOUT1", NULL, "LINEOUT1 PA"},
7177
7178 {"SPL SRC1 MUX", "SRC_IN_LO2", "RX INT4_1 MIX1"},
7179 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 MIX1"},
7180 {"RX INT4 SPLINE MIX", "LO2 Switch", "SPL SRC1 MUX"},
7181 {"RX INT4_1 NATIVE MUX", "ON", "RX INT4_1 MIX1"},
7182 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 NATIVE MUX"},
7183 {"RX INT4_1 NATIVE MUX", NULL, "RX INT4 NATIVE SUPPLY"},
7184 {"RX INT4 SEC MIX", NULL, "RX INT4 SPLINE MIX"},
7185 {"RX INT4 MIX2", NULL, "RX INT4 SEC MIX"},
7186 {"RX INT4 MIX2", NULL, "RX INT4 MIX2 INP"},
7187 {"RX INT4 INTERP", NULL, "RX INT4 MIX2"},
7188 {"RX INT4 DAC", NULL, "RX INT4 INTERP"},
7189 {"RX INT4 DAC", NULL, "RX_BIAS"},
7190 {"LINEOUT2 PA", NULL, "RX INT4 DAC"},
7191 {"LINEOUT2", NULL, "LINEOUT2 PA"},
7192
7193 {"SPL SRC2 MUX", "SRC_IN_LO3", "RX INT5_1 MIX1"},
7194 {"RX INT5 SPLINE MIX", NULL, "RX INT5_1 MIX1"},
7195 {"RX INT5 SPLINE MIX", "LO3 Switch", "SPL SRC2 MUX"},
7196 {"RX INT5 SEC MIX", NULL, "RX INT5 SPLINE MIX"},
7197 {"RX INT5 MIX2", NULL, "RX INT5 SEC MIX"},
7198 {"RX INT5 INTERP", NULL, "RX INT5 MIX2"},
7199
7200 {"RX INT5 VBAT", "LO3 VBAT Enable", "RX INT5 INTERP"},
7201 {"RX INT5 DAC", NULL, "RX INT5 VBAT"},
7202
7203 {"RX INT5 DAC", NULL, "RX INT5 INTERP"},
7204 {"RX INT5 DAC", NULL, "RX_BIAS"},
7205 {"LINEOUT3 PA", NULL, "RX INT5 DAC"},
7206 {"LINEOUT3", NULL, "LINEOUT3 PA"},
7207
7208 {"SPL SRC3 MUX", "SRC_IN_LO4", "RX INT6_1 MIX1"},
7209 {"RX INT6 SPLINE MIX", NULL, "RX INT6_1 MIX1"},
7210 {"RX INT6 SPLINE MIX", "LO4 Switch", "SPL SRC3 MUX"},
7211 {"RX INT6 SEC MIX", NULL, "RX INT6 SPLINE MIX"},
7212 {"RX INT6 MIX2", NULL, "RX INT6 SEC MIX"},
7213 {"RX INT6 INTERP", NULL, "RX INT6 MIX2"},
7214
7215 {"RX INT6 VBAT", "LO4 VBAT Enable", "RX INT6 INTERP"},
7216 {"RX INT6 DAC", NULL, "RX INT6 VBAT"},
7217
7218 {"RX INT6 DAC", NULL, "RX INT6 INTERP"},
7219 {"RX INT6 DAC", NULL, "RX_BIAS"},
7220 {"LINEOUT4 PA", NULL, "RX INT6 DAC"},
7221 {"LINEOUT4", NULL, "LINEOUT4 PA"},
7222
7223 {"SPL SRC2 MUX", "SRC_IN_SPKRL", "RX INT7_1 MIX1"},
7224 {"RX INT7 SPLINE MIX", NULL, "RX INT7_1 MIX1"},
7225 {"RX INT7 SPLINE MIX", "SPKRL Switch", "SPL SRC2 MUX"},
7226 {"RX INT7 SEC MIX", NULL, "RX INT7 SPLINE MIX"},
7227 {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"},
7228 {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"},
7229
7230 {"RX INT7 INTERP", NULL, "RX INT7 MIX2"},
7231
7232 {"RX INT7 VBAT", "SPKRL VBAT Enable", "RX INT7 INTERP"},
7233 {"RX INT7 CHAIN", NULL, "RX INT7 VBAT"},
7234
7235 {"RX INT7 CHAIN", NULL, "RX INT7 INTERP"},
7236 {"RX INT7 CHAIN", NULL, "RX_BIAS"},
7237 {"SPK1 OUT", NULL, "RX INT7 CHAIN"},
7238
7239 {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"},
7240 {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"},
7241 {"SPK1 OUT", NULL, "ANC SPK1 PA"},
7242
7243 {"SPL SRC3 MUX", "SRC_IN_SPKRR", "RX INT8_1 MIX1"},
7244 {"RX INT8 SPLINE MIX", NULL, "RX INT8_1 MIX1"},
7245 {"RX INT8 SPLINE MIX", "SPKRR Switch", "SPL SRC3 MUX"},
7246 {"RX INT8 SEC MIX", NULL, "RX INT8 SPLINE MIX"},
7247 {"RX INT8 INTERP", NULL, "RX INT8 SEC MIX"},
7248
7249 {"RX INT8 VBAT", "SPKRR VBAT Enable", "RX INT8 INTERP"},
7250 {"RX INT8 CHAIN", NULL, "RX INT8 VBAT"},
7251
7252 {"RX INT8 CHAIN", NULL, "RX INT8 INTERP"},
7253 {"RX INT8 CHAIN", NULL, "RX_BIAS"},
7254 {"SPK2 OUT", NULL, "RX INT8 CHAIN"},
7255
7256 {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"},
7257 {"ANC0 FB MUX", "ANC_IN_HPHL", "RX INT1 MIX2"},
7258 {"ANC0 FB MUX", "ANC_IN_LO1", "RX INT3 MIX2"},
7259 {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"},
7260 {"ANC1 FB MUX", "ANC_IN_HPHR", "RX INT2 MIX2"},
7261 {"ANC1 FB MUX", "ANC_IN_LO2", "RX INT4 MIX2"},
7262
7263 {"ANC HPHL Enable", "Switch", "ADC MUX10"},
7264 {"ANC HPHL Enable", "Switch", "ADC MUX11"},
7265 {"RX INT1 MIX2", NULL, "ANC HPHL Enable"},
7266
7267 {"ANC HPHR Enable", "Switch", "ADC MUX12"},
7268 {"ANC HPHR Enable", "Switch", "ADC MUX13"},
7269 {"RX INT2 MIX2", NULL, "ANC HPHR Enable"},
7270
7271 {"ANC EAR Enable", "Switch", "ADC MUX10"},
7272 {"ANC EAR Enable", "Switch", "ADC MUX11"},
7273 {"RX INT0 MIX2", NULL, "ANC EAR Enable"},
7274
7275 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"},
7276 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"},
7277 {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"},
7278
7279 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX10"},
7280 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX11"},
7281 {"RX INT3 MIX2", NULL, "ANC LINEOUT1 Enable"},
7282
7283 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX12"},
7284 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX13"},
7285 {"RX INT4 MIX2", NULL, "ANC LINEOUT2 Enable"},
7286
7287 {"ANC EAR PA", NULL, "RX INT0 DAC"},
7288 {"ANC EAR", NULL, "ANC EAR PA"},
7289 {"ANC HPHL PA", NULL, "RX INT1 DAC"},
7290 {"ANC HPHL", NULL, "ANC HPHL PA"},
7291 {"ANC HPHR PA", NULL, "RX INT2 DAC"},
7292 {"ANC HPHR", NULL, "ANC HPHR PA"},
7293 {"ANC LINEOUT1 PA", NULL, "RX INT3 DAC"},
7294 {"ANC LINEOUT1", NULL, "ANC LINEOUT1 PA"},
7295 {"ANC LINEOUT2 PA", NULL, "RX INT4 DAC"},
7296 {"ANC LINEOUT2", NULL, "ANC LINEOUT2 PA"},
7297
7298 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
7299 {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
7300 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
7301 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
7302 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
7303 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
7304 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
7305 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
7306 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
7307 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
7308 {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"},
7309 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
7310 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
7311 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
7312 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
7313 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
7314 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
7315 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
7316 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
7317 {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"},
7318 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
7319 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
7320 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
7321 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
7322 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
7323 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
7324 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
7325 /* SLIM_MUX("AIF4_PB", "AIF4 PB"),*/
7326 {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
7327 {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
7328 {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
7329 {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
7330 {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
7331 {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
7332 {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
7333 {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
7334
7335 /* SLIM_MUX("AIF_MIX1_PB", "AIF MIX1 PB"),*/
7336 {"SLIM RX0 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7337 {"SLIM RX1 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7338 {"SLIM RX2 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7339 {"SLIM RX3 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7340 {"SLIM RX4 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7341 {"SLIM RX5 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7342 {"SLIM RX6 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7343 {"SLIM RX7 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7344
7345 {"SLIM RX0", NULL, "SLIM RX0 MUX"},
7346 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
7347 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
7348 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
7349 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
7350 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
7351 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
7352 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
7353
7354 {"RX INT0_1 MIX1 INP0", "RX0", "SLIM RX0"},
7355 {"RX INT0_1 MIX1 INP0", "RX1", "SLIM RX1"},
7356 {"RX INT0_1 MIX1 INP0", "RX2", "SLIM RX2"},
7357 {"RX INT0_1 MIX1 INP0", "RX3", "SLIM RX3"},
7358 {"RX INT0_1 MIX1 INP0", "RX4", "SLIM RX4"},
7359 {"RX INT0_1 MIX1 INP0", "RX5", "SLIM RX5"},
7360 {"RX INT0_1 MIX1 INP0", "RX6", "SLIM RX6"},
7361 {"RX INT0_1 MIX1 INP0", "RX7", "SLIM RX7"},
7362 {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
7363 {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
7364 {"RX INT0_1 MIX1 INP1", "RX0", "SLIM RX0"},
7365 {"RX INT0_1 MIX1 INP1", "RX1", "SLIM RX1"},
7366 {"RX INT0_1 MIX1 INP1", "RX2", "SLIM RX2"},
7367 {"RX INT0_1 MIX1 INP1", "RX3", "SLIM RX3"},
7368 {"RX INT0_1 MIX1 INP1", "RX4", "SLIM RX4"},
7369 {"RX INT0_1 MIX1 INP1", "RX5", "SLIM RX5"},
7370 {"RX INT0_1 MIX1 INP1", "RX6", "SLIM RX6"},
7371 {"RX INT0_1 MIX1 INP1", "RX7", "SLIM RX7"},
7372 {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
7373 {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
7374 {"RX INT0_1 MIX1 INP2", "RX0", "SLIM RX0"},
7375 {"RX INT0_1 MIX1 INP2", "RX1", "SLIM RX1"},
7376 {"RX INT0_1 MIX1 INP2", "RX2", "SLIM RX2"},
7377 {"RX INT0_1 MIX1 INP2", "RX3", "SLIM RX3"},
7378 {"RX INT0_1 MIX1 INP2", "RX4", "SLIM RX4"},
7379 {"RX INT0_1 MIX1 INP2", "RX5", "SLIM RX5"},
7380 {"RX INT0_1 MIX1 INP2", "RX6", "SLIM RX6"},
7381 {"RX INT0_1 MIX1 INP2", "RX7", "SLIM RX7"},
7382 {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
7383 {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
7384
7385 /* MIXing path INT0 */
7386 {"RX INT0_2 MUX", "RX0", "SLIM RX0"},
7387 {"RX INT0_2 MUX", "RX1", "SLIM RX1"},
7388 {"RX INT0_2 MUX", "RX2", "SLIM RX2"},
7389 {"RX INT0_2 MUX", "RX3", "SLIM RX3"},
7390 {"RX INT0_2 MUX", "RX4", "SLIM RX4"},
7391 {"RX INT0_2 MUX", "RX5", "SLIM RX5"},
7392 {"RX INT0_2 MUX", "RX6", "SLIM RX6"},
7393 {"RX INT0_2 MUX", "RX7", "SLIM RX7"},
7394 {"RX INT0 SEC MIX", NULL, "RX INT0_2 MUX"},
7395
7396 /* MIXing path INT1 */
7397 {"RX INT1_2 MUX", "RX0", "SLIM RX0"},
7398 {"RX INT1_2 MUX", "RX1", "SLIM RX1"},
7399 {"RX INT1_2 MUX", "RX2", "SLIM RX2"},
7400 {"RX INT1_2 MUX", "RX3", "SLIM RX3"},
7401 {"RX INT1_2 MUX", "RX4", "SLIM RX4"},
7402 {"RX INT1_2 MUX", "RX5", "SLIM RX5"},
7403 {"RX INT1_2 MUX", "RX6", "SLIM RX6"},
7404 {"RX INT1_2 MUX", "RX7", "SLIM RX7"},
7405 {"RX INT1 SEC MIX", NULL, "RX INT1_2 MUX"},
7406
7407 /* MIXing path INT2 */
7408 {"RX INT2_2 MUX", "RX0", "SLIM RX0"},
7409 {"RX INT2_2 MUX", "RX1", "SLIM RX1"},
7410 {"RX INT2_2 MUX", "RX2", "SLIM RX2"},
7411 {"RX INT2_2 MUX", "RX3", "SLIM RX3"},
7412 {"RX INT2_2 MUX", "RX4", "SLIM RX4"},
7413 {"RX INT2_2 MUX", "RX5", "SLIM RX5"},
7414 {"RX INT2_2 MUX", "RX6", "SLIM RX6"},
7415 {"RX INT2_2 MUX", "RX7", "SLIM RX7"},
7416 {"RX INT2 SEC MIX", NULL, "RX INT2_2 MUX"},
7417
7418 /* MIXing path INT3 */
7419 {"RX INT3_2 MUX", "RX0", "SLIM RX0"},
7420 {"RX INT3_2 MUX", "RX1", "SLIM RX1"},
7421 {"RX INT3_2 MUX", "RX2", "SLIM RX2"},
7422 {"RX INT3_2 MUX", "RX3", "SLIM RX3"},
7423 {"RX INT3_2 MUX", "RX4", "SLIM RX4"},
7424 {"RX INT3_2 MUX", "RX5", "SLIM RX5"},
7425 {"RX INT3_2 MUX", "RX6", "SLIM RX6"},
7426 {"RX INT3_2 MUX", "RX7", "SLIM RX7"},
7427 {"RX INT3 SEC MIX", NULL, "RX INT3_2 MUX"},
7428
7429 /* MIXing path INT4 */
7430 {"RX INT4_2 MUX", "RX0", "SLIM RX0"},
7431 {"RX INT4_2 MUX", "RX1", "SLIM RX1"},
7432 {"RX INT4_2 MUX", "RX2", "SLIM RX2"},
7433 {"RX INT4_2 MUX", "RX3", "SLIM RX3"},
7434 {"RX INT4_2 MUX", "RX4", "SLIM RX4"},
7435 {"RX INT4_2 MUX", "RX5", "SLIM RX5"},
7436 {"RX INT4_2 MUX", "RX6", "SLIM RX6"},
7437 {"RX INT4_2 MUX", "RX7", "SLIM RX7"},
7438 {"RX INT4 SEC MIX", NULL, "RX INT4_2 MUX"},
7439
7440 /* MIXing path INT5 */
7441 {"RX INT5_2 MUX", "RX0", "SLIM RX0"},
7442 {"RX INT5_2 MUX", "RX1", "SLIM RX1"},
7443 {"RX INT5_2 MUX", "RX2", "SLIM RX2"},
7444 {"RX INT5_2 MUX", "RX3", "SLIM RX3"},
7445 {"RX INT5_2 MUX", "RX4", "SLIM RX4"},
7446 {"RX INT5_2 MUX", "RX5", "SLIM RX5"},
7447 {"RX INT5_2 MUX", "RX6", "SLIM RX6"},
7448 {"RX INT5_2 MUX", "RX7", "SLIM RX7"},
7449 {"RX INT5 SEC MIX", NULL, "RX INT5_2 MUX"},
7450
7451 /* MIXing path INT6 */
7452 {"RX INT6_2 MUX", "RX0", "SLIM RX0"},
7453 {"RX INT6_2 MUX", "RX1", "SLIM RX1"},
7454 {"RX INT6_2 MUX", "RX2", "SLIM RX2"},
7455 {"RX INT6_2 MUX", "RX3", "SLIM RX3"},
7456 {"RX INT6_2 MUX", "RX4", "SLIM RX4"},
7457 {"RX INT6_2 MUX", "RX5", "SLIM RX5"},
7458 {"RX INT6_2 MUX", "RX6", "SLIM RX6"},
7459 {"RX INT6_2 MUX", "RX7", "SLIM RX7"},
7460 {"RX INT6 SEC MIX", NULL, "RX INT6_2 MUX"},
7461
7462 /* MIXing path INT7 */
7463 {"RX INT7_2 MUX", "RX0", "SLIM RX0"},
7464 {"RX INT7_2 MUX", "RX1", "SLIM RX1"},
7465 {"RX INT7_2 MUX", "RX2", "SLIM RX2"},
7466 {"RX INT7_2 MUX", "RX3", "SLIM RX3"},
7467 {"RX INT7_2 MUX", "RX4", "SLIM RX4"},
7468 {"RX INT7_2 MUX", "RX5", "SLIM RX5"},
7469 {"RX INT7_2 MUX", "RX6", "SLIM RX6"},
7470 {"RX INT7_2 MUX", "RX7", "SLIM RX7"},
7471 {"RX INT7 SEC MIX", NULL, "RX INT7_2 MUX"},
7472
7473 /* MIXing path INT8 */
7474 {"RX INT8_2 MUX", "RX0", "SLIM RX0"},
7475 {"RX INT8_2 MUX", "RX1", "SLIM RX1"},
7476 {"RX INT8_2 MUX", "RX2", "SLIM RX2"},
7477 {"RX INT8_2 MUX", "RX3", "SLIM RX3"},
7478 {"RX INT8_2 MUX", "RX4", "SLIM RX4"},
7479 {"RX INT8_2 MUX", "RX5", "SLIM RX5"},
7480 {"RX INT8_2 MUX", "RX6", "SLIM RX6"},
7481 {"RX INT8_2 MUX", "RX7", "SLIM RX7"},
7482 {"RX INT8 SEC MIX", NULL, "RX INT8_2 MUX"},
7483
7484 {"RX INT1_1 MIX1 INP0", "RX0", "SLIM RX0"},
7485 {"RX INT1_1 MIX1 INP0", "RX1", "SLIM RX1"},
7486 {"RX INT1_1 MIX1 INP0", "RX2", "SLIM RX2"},
7487 {"RX INT1_1 MIX1 INP0", "RX3", "SLIM RX3"},
7488 {"RX INT1_1 MIX1 INP0", "RX4", "SLIM RX4"},
7489 {"RX INT1_1 MIX1 INP0", "RX5", "SLIM RX5"},
7490 {"RX INT1_1 MIX1 INP0", "RX6", "SLIM RX6"},
7491 {"RX INT1_1 MIX1 INP0", "RX7", "SLIM RX7"},
7492 {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
7493 {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
7494 {"RX INT1_1 MIX1 INP1", "RX0", "SLIM RX0"},
7495 {"RX INT1_1 MIX1 INP1", "RX1", "SLIM RX1"},
7496 {"RX INT1_1 MIX1 INP1", "RX2", "SLIM RX2"},
7497 {"RX INT1_1 MIX1 INP1", "RX3", "SLIM RX3"},
7498 {"RX INT1_1 MIX1 INP1", "RX4", "SLIM RX4"},
7499 {"RX INT1_1 MIX1 INP1", "RX5", "SLIM RX5"},
7500 {"RX INT1_1 MIX1 INP1", "RX6", "SLIM RX6"},
7501 {"RX INT1_1 MIX1 INP1", "RX7", "SLIM RX7"},
7502 {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
7503 {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
7504 {"RX INT1_1 MIX1 INP2", "RX0", "SLIM RX0"},
7505 {"RX INT1_1 MIX1 INP2", "RX1", "SLIM RX1"},
7506 {"RX INT1_1 MIX1 INP2", "RX2", "SLIM RX2"},
7507 {"RX INT1_1 MIX1 INP2", "RX3", "SLIM RX3"},
7508 {"RX INT1_1 MIX1 INP2", "RX4", "SLIM RX4"},
7509 {"RX INT1_1 MIX1 INP2", "RX5", "SLIM RX5"},
7510 {"RX INT1_1 MIX1 INP2", "RX6", "SLIM RX6"},
7511 {"RX INT1_1 MIX1 INP2", "RX7", "SLIM RX7"},
7512 {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
7513 {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
7514 {"RX INT2_1 MIX1 INP0", "RX0", "SLIM RX0"},
7515 {"RX INT2_1 MIX1 INP0", "RX1", "SLIM RX1"},
7516 {"RX INT2_1 MIX1 INP0", "RX2", "SLIM RX2"},
7517 {"RX INT2_1 MIX1 INP0", "RX3", "SLIM RX3"},
7518 {"RX INT2_1 MIX1 INP0", "RX4", "SLIM RX4"},
7519 {"RX INT2_1 MIX1 INP0", "RX5", "SLIM RX5"},
7520 {"RX INT2_1 MIX1 INP0", "RX6", "SLIM RX6"},
7521 {"RX INT2_1 MIX1 INP0", "RX7", "SLIM RX7"},
7522 {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
7523 {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
7524 {"RX INT2_1 MIX1 INP1", "RX0", "SLIM RX0"},
7525 {"RX INT2_1 MIX1 INP1", "RX1", "SLIM RX1"},
7526 {"RX INT2_1 MIX1 INP1", "RX2", "SLIM RX2"},
7527 {"RX INT2_1 MIX1 INP1", "RX3", "SLIM RX3"},
7528 {"RX INT2_1 MIX1 INP1", "RX4", "SLIM RX4"},
7529 {"RX INT2_1 MIX1 INP1", "RX5", "SLIM RX5"},
7530 {"RX INT2_1 MIX1 INP1", "RX6", "SLIM RX6"},
7531 {"RX INT2_1 MIX1 INP1", "RX7", "SLIM RX7"},
7532 {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
7533 {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
7534 {"RX INT2_1 MIX1 INP2", "RX0", "SLIM RX0"},
7535 {"RX INT2_1 MIX1 INP2", "RX1", "SLIM RX1"},
7536 {"RX INT2_1 MIX1 INP2", "RX2", "SLIM RX2"},
7537 {"RX INT2_1 MIX1 INP2", "RX3", "SLIM RX3"},
7538 {"RX INT2_1 MIX1 INP2", "RX4", "SLIM RX4"},
7539 {"RX INT2_1 MIX1 INP2", "RX5", "SLIM RX5"},
7540 {"RX INT2_1 MIX1 INP2", "RX6", "SLIM RX6"},
7541 {"RX INT2_1 MIX1 INP2", "RX7", "SLIM RX7"},
7542 {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
7543 {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
7544
7545 {"RX INT3_1 MIX1 INP0", "RX0", "SLIM RX0"},
7546 {"RX INT3_1 MIX1 INP0", "RX1", "SLIM RX1"},
7547 {"RX INT3_1 MIX1 INP0", "RX2", "SLIM RX2"},
7548 {"RX INT3_1 MIX1 INP0", "RX3", "SLIM RX3"},
7549 {"RX INT3_1 MIX1 INP0", "RX4", "SLIM RX4"},
7550 {"RX INT3_1 MIX1 INP0", "RX5", "SLIM RX5"},
7551 {"RX INT3_1 MIX1 INP0", "RX6", "SLIM RX6"},
7552 {"RX INT3_1 MIX1 INP0", "RX7", "SLIM RX7"},
7553 {"RX INT3_1 MIX1 INP0", "IIR0", "IIR0"},
7554 {"RX INT3_1 MIX1 INP0", "IIR1", "IIR1"},
7555 {"RX INT3_1 MIX1 INP1", "RX0", "SLIM RX0"},
7556 {"RX INT3_1 MIX1 INP1", "RX1", "SLIM RX1"},
7557 {"RX INT3_1 MIX1 INP1", "RX2", "SLIM RX2"},
7558 {"RX INT3_1 MIX1 INP1", "RX3", "SLIM RX3"},
7559 {"RX INT3_1 MIX1 INP1", "RX4", "SLIM RX4"},
7560 {"RX INT3_1 MIX1 INP1", "RX5", "SLIM RX5"},
7561 {"RX INT3_1 MIX1 INP1", "RX6", "SLIM RX6"},
7562 {"RX INT3_1 MIX1 INP1", "RX7", "SLIM RX7"},
7563 {"RX INT3_1 MIX1 INP1", "IIR0", "IIR0"},
7564 {"RX INT3_1 MIX1 INP1", "IIR1", "IIR1"},
7565 {"RX INT3_1 MIX1 INP2", "RX0", "SLIM RX0"},
7566 {"RX INT3_1 MIX1 INP2", "RX1", "SLIM RX1"},
7567 {"RX INT3_1 MIX1 INP2", "RX2", "SLIM RX2"},
7568 {"RX INT3_1 MIX1 INP2", "RX3", "SLIM RX3"},
7569 {"RX INT3_1 MIX1 INP2", "RX4", "SLIM RX4"},
7570 {"RX INT3_1 MIX1 INP2", "RX5", "SLIM RX5"},
7571 {"RX INT3_1 MIX1 INP2", "RX6", "SLIM RX6"},
7572 {"RX INT3_1 MIX1 INP2", "RX7", "SLIM RX7"},
7573 {"RX INT3_1 MIX1 INP2", "IIR0", "IIR0"},
7574 {"RX INT3_1 MIX1 INP2", "IIR1", "IIR1"},
7575
7576 {"RX INT4_1 MIX1 INP0", "RX0", "SLIM RX0"},
7577 {"RX INT4_1 MIX1 INP0", "RX1", "SLIM RX1"},
7578 {"RX INT4_1 MIX1 INP0", "RX2", "SLIM RX2"},
7579 {"RX INT4_1 MIX1 INP0", "RX3", "SLIM RX3"},
7580 {"RX INT4_1 MIX1 INP0", "RX4", "SLIM RX4"},
7581 {"RX INT4_1 MIX1 INP0", "RX5", "SLIM RX5"},
7582 {"RX INT4_1 MIX1 INP0", "RX6", "SLIM RX6"},
7583 {"RX INT4_1 MIX1 INP0", "RX7", "SLIM RX7"},
7584 {"RX INT4_1 MIX1 INP0", "IIR0", "IIR0"},
7585 {"RX INT4_1 MIX1 INP0", "IIR1", "IIR1"},
7586 {"RX INT4_1 MIX1 INP1", "RX0", "SLIM RX0"},
7587 {"RX INT4_1 MIX1 INP1", "RX1", "SLIM RX1"},
7588 {"RX INT4_1 MIX1 INP1", "RX2", "SLIM RX2"},
7589 {"RX INT4_1 MIX1 INP1", "RX3", "SLIM RX3"},
7590 {"RX INT4_1 MIX1 INP1", "RX4", "SLIM RX4"},
7591 {"RX INT4_1 MIX1 INP1", "RX5", "SLIM RX5"},
7592 {"RX INT4_1 MIX1 INP1", "RX6", "SLIM RX6"},
7593 {"RX INT4_1 MIX1 INP1", "RX7", "SLIM RX7"},
7594 {"RX INT4_1 MIX1 INP1", "IIR0", "IIR0"},
7595 {"RX INT4_1 MIX1 INP1", "IIR1", "IIR1"},
7596 {"RX INT4_1 MIX1 INP2", "RX0", "SLIM RX0"},
7597 {"RX INT4_1 MIX1 INP2", "RX1", "SLIM RX1"},
7598 {"RX INT4_1 MIX1 INP2", "RX2", "SLIM RX2"},
7599 {"RX INT4_1 MIX1 INP2", "RX3", "SLIM RX3"},
7600 {"RX INT4_1 MIX1 INP2", "RX4", "SLIM RX4"},
7601 {"RX INT4_1 MIX1 INP2", "RX5", "SLIM RX5"},
7602 {"RX INT4_1 MIX1 INP2", "RX6", "SLIM RX6"},
7603 {"RX INT4_1 MIX1 INP2", "RX7", "SLIM RX7"},
7604 {"RX INT4_1 MIX1 INP2", "IIR0", "IIR0"},
7605 {"RX INT4_1 MIX1 INP2", "IIR1", "IIR1"},
7606
7607 {"RX INT5_1 MIX1 INP0", "RX0", "SLIM RX0"},
7608 {"RX INT5_1 MIX1 INP0", "RX1", "SLIM RX1"},
7609 {"RX INT5_1 MIX1 INP0", "RX2", "SLIM RX2"},
7610 {"RX INT5_1 MIX1 INP0", "RX3", "SLIM RX3"},
7611 {"RX INT5_1 MIX1 INP0", "RX4", "SLIM RX4"},
7612 {"RX INT5_1 MIX1 INP0", "RX5", "SLIM RX5"},
7613 {"RX INT5_1 MIX1 INP0", "RX6", "SLIM RX6"},
7614 {"RX INT5_1 MIX1 INP0", "RX7", "SLIM RX7"},
7615 {"RX INT5_1 MIX1 INP0", "IIR0", "IIR0"},
7616 {"RX INT5_1 MIX1 INP0", "IIR1", "IIR1"},
7617 {"RX INT5_1 MIX1 INP1", "RX0", "SLIM RX0"},
7618 {"RX INT5_1 MIX1 INP1", "RX1", "SLIM RX1"},
7619 {"RX INT5_1 MIX1 INP1", "RX2", "SLIM RX2"},
7620 {"RX INT5_1 MIX1 INP1", "RX3", "SLIM RX3"},
7621 {"RX INT5_1 MIX1 INP1", "RX4", "SLIM RX4"},
7622 {"RX INT5_1 MIX1 INP1", "RX5", "SLIM RX5"},
7623 {"RX INT5_1 MIX1 INP1", "RX6", "SLIM RX6"},
7624 {"RX INT5_1 MIX1 INP1", "RX7", "SLIM RX7"},
7625 {"RX INT5_1 MIX1 INP1", "IIR0", "IIR0"},
7626 {"RX INT5_1 MIX1 INP1", "IIR1", "IIR1"},
7627 {"RX INT5_1 MIX1 INP2", "RX0", "SLIM RX0"},
7628 {"RX INT5_1 MIX1 INP2", "RX1", "SLIM RX1"},
7629 {"RX INT5_1 MIX1 INP2", "RX2", "SLIM RX2"},
7630 {"RX INT5_1 MIX1 INP2", "RX3", "SLIM RX3"},
7631 {"RX INT5_1 MIX1 INP2", "RX4", "SLIM RX4"},
7632 {"RX INT5_1 MIX1 INP2", "RX5", "SLIM RX5"},
7633 {"RX INT5_1 MIX1 INP2", "RX6", "SLIM RX6"},
7634 {"RX INT5_1 MIX1 INP2", "RX7", "SLIM RX7"},
7635 {"RX INT5_1 MIX1 INP2", "IIR0", "IIR0"},
7636 {"RX INT5_1 MIX1 INP2", "IIR1", "IIR1"},
7637
7638 {"RX INT6_1 MIX1 INP0", "RX0", "SLIM RX0"},
7639 {"RX INT6_1 MIX1 INP0", "RX1", "SLIM RX1"},
7640 {"RX INT6_1 MIX1 INP0", "RX2", "SLIM RX2"},
7641 {"RX INT6_1 MIX1 INP0", "RX3", "SLIM RX3"},
7642 {"RX INT6_1 MIX1 INP0", "RX4", "SLIM RX4"},
7643 {"RX INT6_1 MIX1 INP0", "RX5", "SLIM RX5"},
7644 {"RX INT6_1 MIX1 INP0", "RX6", "SLIM RX6"},
7645 {"RX INT6_1 MIX1 INP0", "RX7", "SLIM RX7"},
7646 {"RX INT6_1 MIX1 INP0", "IIR0", "IIR0"},
7647 {"RX INT6_1 MIX1 INP0", "IIR1", "IIR1"},
7648 {"RX INT6_1 MIX1 INP1", "RX0", "SLIM RX0"},
7649 {"RX INT6_1 MIX1 INP1", "RX1", "SLIM RX1"},
7650 {"RX INT6_1 MIX1 INP1", "RX2", "SLIM RX2"},
7651 {"RX INT6_1 MIX1 INP1", "RX3", "SLIM RX3"},
7652 {"RX INT6_1 MIX1 INP1", "RX4", "SLIM RX4"},
7653 {"RX INT6_1 MIX1 INP1", "RX5", "SLIM RX5"},
7654 {"RX INT6_1 MIX1 INP1", "RX6", "SLIM RX6"},
7655 {"RX INT6_1 MIX1 INP1", "RX7", "SLIM RX7"},
7656 {"RX INT6_1 MIX1 INP1", "IIR0", "IIR0"},
7657 {"RX INT6_1 MIX1 INP1", "IIR1", "IIR1"},
7658 {"RX INT6_1 MIX1 INP2", "RX0", "SLIM RX0"},
7659 {"RX INT6_1 MIX1 INP2", "RX1", "SLIM RX1"},
7660 {"RX INT6_1 MIX1 INP2", "RX2", "SLIM RX2"},
7661 {"RX INT6_1 MIX1 INP2", "RX3", "SLIM RX3"},
7662 {"RX INT6_1 MIX1 INP2", "RX4", "SLIM RX4"},
7663 {"RX INT6_1 MIX1 INP2", "RX5", "SLIM RX5"},
7664 {"RX INT6_1 MIX1 INP2", "RX6", "SLIM RX6"},
7665 {"RX INT6_1 MIX1 INP2", "RX7", "SLIM RX7"},
7666 {"RX INT6_1 MIX1 INP2", "IIR0", "IIR0"},
7667 {"RX INT6_1 MIX1 INP2", "IIR1", "IIR1"},
7668
7669 {"RX INT7_1 MIX1 INP0", "RX0", "SLIM RX0"},
7670 {"RX INT7_1 MIX1 INP0", "RX1", "SLIM RX1"},
7671 {"RX INT7_1 MIX1 INP0", "RX2", "SLIM RX2"},
7672 {"RX INT7_1 MIX1 INP0", "RX3", "SLIM RX3"},
7673 {"RX INT7_1 MIX1 INP0", "RX4", "SLIM RX4"},
7674 {"RX INT7_1 MIX1 INP0", "RX5", "SLIM RX5"},
7675 {"RX INT7_1 MIX1 INP0", "RX6", "SLIM RX6"},
7676 {"RX INT7_1 MIX1 INP0", "RX7", "SLIM RX7"},
7677 {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"},
7678 {"RX INT7_1 MIX1 INP0", "IIR1", "IIR1"},
7679 {"RX INT7_1 MIX1 INP1", "RX0", "SLIM RX0"},
7680 {"RX INT7_1 MIX1 INP1", "RX1", "SLIM RX1"},
7681 {"RX INT7_1 MIX1 INP1", "RX2", "SLIM RX2"},
7682 {"RX INT7_1 MIX1 INP1", "RX3", "SLIM RX3"},
7683 {"RX INT7_1 MIX1 INP1", "RX4", "SLIM RX4"},
7684 {"RX INT7_1 MIX1 INP1", "RX5", "SLIM RX5"},
7685 {"RX INT7_1 MIX1 INP1", "RX6", "SLIM RX6"},
7686 {"RX INT7_1 MIX1 INP1", "RX7", "SLIM RX7"},
7687 {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"},
7688 {"RX INT7_1 MIX1 INP1", "IIR1", "IIR1"},
7689 {"RX INT7_1 MIX1 INP2", "RX0", "SLIM RX0"},
7690 {"RX INT7_1 MIX1 INP2", "RX1", "SLIM RX1"},
7691 {"RX INT7_1 MIX1 INP2", "RX2", "SLIM RX2"},
7692 {"RX INT7_1 MIX1 INP2", "RX3", "SLIM RX3"},
7693 {"RX INT7_1 MIX1 INP2", "RX4", "SLIM RX4"},
7694 {"RX INT7_1 MIX1 INP2", "RX5", "SLIM RX5"},
7695 {"RX INT7_1 MIX1 INP2", "RX6", "SLIM RX6"},
7696 {"RX INT7_1 MIX1 INP2", "RX7", "SLIM RX7"},
7697 {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"},
7698 {"RX INT7_1 MIX1 INP2", "IIR1", "IIR1"},
7699
7700 {"RX INT8_1 MIX1 INP0", "RX0", "SLIM RX0"},
7701 {"RX INT8_1 MIX1 INP0", "RX1", "SLIM RX1"},
7702 {"RX INT8_1 MIX1 INP0", "RX2", "SLIM RX2"},
7703 {"RX INT8_1 MIX1 INP0", "RX3", "SLIM RX3"},
7704 {"RX INT8_1 MIX1 INP0", "RX4", "SLIM RX4"},
7705 {"RX INT8_1 MIX1 INP0", "RX5", "SLIM RX5"},
7706 {"RX INT8_1 MIX1 INP0", "RX6", "SLIM RX6"},
7707 {"RX INT8_1 MIX1 INP0", "RX7", "SLIM RX7"},
7708 {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"},
7709 {"RX INT8_1 MIX1 INP0", "IIR1", "IIR1"},
7710 {"RX INT8_1 MIX1 INP1", "RX0", "SLIM RX0"},
7711 {"RX INT8_1 MIX1 INP1", "RX1", "SLIM RX1"},
7712 {"RX INT8_1 MIX1 INP1", "RX2", "SLIM RX2"},
7713 {"RX INT8_1 MIX1 INP1", "RX3", "SLIM RX3"},
7714 {"RX INT8_1 MIX1 INP1", "RX4", "SLIM RX4"},
7715 {"RX INT8_1 MIX1 INP1", "RX5", "SLIM RX5"},
7716 {"RX INT8_1 MIX1 INP1", "RX6", "SLIM RX6"},
7717 {"RX INT8_1 MIX1 INP1", "RX7", "SLIM RX7"},
7718 {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"},
7719 {"RX INT8_1 MIX1 INP1", "IIR1", "IIR1"},
7720 {"RX INT8_1 MIX1 INP2", "RX0", "SLIM RX0"},
7721 {"RX INT8_1 MIX1 INP2", "RX1", "SLIM RX1"},
7722 {"RX INT8_1 MIX1 INP2", "RX2", "SLIM RX2"},
7723 {"RX INT8_1 MIX1 INP2", "RX3", "SLIM RX3"},
7724 {"RX INT8_1 MIX1 INP2", "RX4", "SLIM RX4"},
7725 {"RX INT8_1 MIX1 INP2", "RX5", "SLIM RX5"},
7726 {"RX INT8_1 MIX1 INP2", "RX6", "SLIM RX6"},
7727 {"RX INT8_1 MIX1 INP2", "RX7", "SLIM RX7"},
7728 {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"},
7729 {"RX INT8_1 MIX1 INP2", "IIR1", "IIR1"},
7730
7731 /* SRC0, SRC1 inputs to Sidetone RX Mixer
7732 * on RX0, RX1, RX2, RX3, RX4 and RX7 chains
7733 */
7734 {"IIR0", NULL, "IIR0 INP0 MUX"},
7735 {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"},
7736 {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"},
7737 {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"},
7738 {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"},
7739 {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"},
7740 {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"},
7741 {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"},
7742 {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"},
7743 {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"},
7744 {"IIR0 INP0 MUX", "RX0", "SLIM RX0"},
7745 {"IIR0 INP0 MUX", "RX1", "SLIM RX1"},
7746 {"IIR0 INP0 MUX", "RX2", "SLIM RX2"},
7747 {"IIR0 INP0 MUX", "RX3", "SLIM RX3"},
7748 {"IIR0 INP0 MUX", "RX4", "SLIM RX4"},
7749 {"IIR0 INP0 MUX", "RX5", "SLIM RX5"},
7750 {"IIR0 INP0 MUX", "RX6", "SLIM RX6"},
7751 {"IIR0 INP0 MUX", "RX7", "SLIM RX7"},
7752 {"IIR0", NULL, "IIR0 INP1 MUX"},
7753 {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"},
7754 {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"},
7755 {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"},
7756 {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"},
7757 {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"},
7758 {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"},
7759 {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"},
7760 {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"},
7761 {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"},
7762 {"IIR0 INP1 MUX", "RX0", "SLIM RX0"},
7763 {"IIR0 INP1 MUX", "RX1", "SLIM RX1"},
7764 {"IIR0 INP1 MUX", "RX2", "SLIM RX2"},
7765 {"IIR0 INP1 MUX", "RX3", "SLIM RX3"},
7766 {"IIR0 INP1 MUX", "RX4", "SLIM RX4"},
7767 {"IIR0 INP1 MUX", "RX5", "SLIM RX5"},
7768 {"IIR0 INP1 MUX", "RX6", "SLIM RX6"},
7769 {"IIR0 INP1 MUX", "RX7", "SLIM RX7"},
7770 {"IIR0", NULL, "IIR0 INP2 MUX"},
7771 {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"},
7772 {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"},
7773 {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"},
7774 {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"},
7775 {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"},
7776 {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"},
7777 {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"},
7778 {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"},
7779 {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"},
7780 {"IIR0 INP2 MUX", "RX0", "SLIM RX0"},
7781 {"IIR0 INP2 MUX", "RX1", "SLIM RX1"},
7782 {"IIR0 INP2 MUX", "RX2", "SLIM RX2"},
7783 {"IIR0 INP2 MUX", "RX3", "SLIM RX3"},
7784 {"IIR0 INP2 MUX", "RX4", "SLIM RX4"},
7785 {"IIR0 INP2 MUX", "RX5", "SLIM RX5"},
7786 {"IIR0 INP2 MUX", "RX6", "SLIM RX6"},
7787 {"IIR0 INP2 MUX", "RX7", "SLIM RX7"},
7788 {"IIR0", NULL, "IIR0 INP3 MUX"},
7789 {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"},
7790 {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"},
7791 {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"},
7792 {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"},
7793 {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"},
7794 {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"},
7795 {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"},
7796 {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"},
7797 {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"},
7798 {"IIR0 INP3 MUX", "RX0", "SLIM RX0"},
7799 {"IIR0 INP3 MUX", "RX1", "SLIM RX1"},
7800 {"IIR0 INP3 MUX", "RX2", "SLIM RX2"},
7801 {"IIR0 INP3 MUX", "RX3", "SLIM RX3"},
7802 {"IIR0 INP3 MUX", "RX4", "SLIM RX4"},
7803 {"IIR0 INP3 MUX", "RX5", "SLIM RX5"},
7804 {"IIR0 INP3 MUX", "RX6", "SLIM RX6"},
7805 {"IIR0 INP3 MUX", "RX7", "SLIM RX7"},
7806
7807 {"IIR1", NULL, "IIR1 INP0 MUX"},
7808 {"IIR1 INP0 MUX", "DEC0", "ADC MUX0"},
7809 {"IIR1 INP0 MUX", "DEC1", "ADC MUX1"},
7810 {"IIR1 INP0 MUX", "DEC2", "ADC MUX2"},
7811 {"IIR1 INP0 MUX", "DEC3", "ADC MUX3"},
7812 {"IIR1 INP0 MUX", "DEC4", "ADC MUX4"},
7813 {"IIR1 INP0 MUX", "DEC5", "ADC MUX5"},
7814 {"IIR1 INP0 MUX", "DEC6", "ADC MUX6"},
7815 {"IIR1 INP0 MUX", "DEC7", "ADC MUX7"},
7816 {"IIR1 INP0 MUX", "DEC8", "ADC MUX8"},
7817 {"IIR1 INP0 MUX", "RX0", "SLIM RX0"},
7818 {"IIR1 INP0 MUX", "RX1", "SLIM RX1"},
7819 {"IIR1 INP0 MUX", "RX2", "SLIM RX2"},
7820 {"IIR1 INP0 MUX", "RX3", "SLIM RX3"},
7821 {"IIR1 INP0 MUX", "RX4", "SLIM RX4"},
7822 {"IIR1 INP0 MUX", "RX5", "SLIM RX5"},
7823 {"IIR1 INP0 MUX", "RX6", "SLIM RX6"},
7824 {"IIR1 INP0 MUX", "RX7", "SLIM RX7"},
7825 {"IIR1", NULL, "IIR1 INP1 MUX"},
7826 {"IIR1 INP1 MUX", "DEC0", "ADC MUX0"},
7827 {"IIR1 INP1 MUX", "DEC1", "ADC MUX1"},
7828 {"IIR1 INP1 MUX", "DEC2", "ADC MUX2"},
7829 {"IIR1 INP1 MUX", "DEC3", "ADC MUX3"},
7830 {"IIR1 INP1 MUX", "DEC4", "ADC MUX4"},
7831 {"IIR1 INP1 MUX", "DEC5", "ADC MUX5"},
7832 {"IIR1 INP1 MUX", "DEC6", "ADC MUX6"},
7833 {"IIR1 INP1 MUX", "DEC7", "ADC MUX7"},
7834 {"IIR1 INP1 MUX", "DEC8", "ADC MUX8"},
7835 {"IIR1 INP1 MUX", "RX0", "SLIM RX0"},
7836 {"IIR1 INP1 MUX", "RX1", "SLIM RX1"},
7837 {"IIR1 INP1 MUX", "RX2", "SLIM RX2"},
7838 {"IIR1 INP1 MUX", "RX3", "SLIM RX3"},
7839 {"IIR1 INP1 MUX", "RX4", "SLIM RX4"},
7840 {"IIR1 INP1 MUX", "RX5", "SLIM RX5"},
7841 {"IIR1 INP1 MUX", "RX6", "SLIM RX6"},
7842 {"IIR1 INP1 MUX", "RX7", "SLIM RX7"},
7843 {"IIR1", NULL, "IIR1 INP2 MUX"},
7844 {"IIR1 INP2 MUX", "DEC0", "ADC MUX0"},
7845 {"IIR1 INP2 MUX", "DEC1", "ADC MUX1"},
7846 {"IIR1 INP2 MUX", "DEC2", "ADC MUX2"},
7847 {"IIR1 INP2 MUX", "DEC3", "ADC MUX3"},
7848 {"IIR1 INP2 MUX", "DEC4", "ADC MUX4"},
7849 {"IIR1 INP2 MUX", "DEC5", "ADC MUX5"},
7850 {"IIR1 INP2 MUX", "DEC6", "ADC MUX6"},
7851 {"IIR1 INP2 MUX", "DEC7", "ADC MUX7"},
7852 {"IIR1 INP2 MUX", "DEC8", "ADC MUX8"},
7853 {"IIR1 INP2 MUX", "RX0", "SLIM RX0"},
7854 {"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
7855 {"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
7856 {"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
7857 {"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
7858 {"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
7859 {"IIR1 INP2 MUX", "RX6", "SLIM RX6"},
7860 {"IIR1 INP2 MUX", "RX7", "SLIM RX7"},
7861 {"IIR1", NULL, "IIR1 INP3 MUX"},
7862 {"IIR1 INP3 MUX", "DEC0", "ADC MUX0"},
7863 {"IIR1 INP3 MUX", "DEC1", "ADC MUX1"},
7864 {"IIR1 INP3 MUX", "DEC2", "ADC MUX2"},
7865 {"IIR1 INP3 MUX", "DEC3", "ADC MUX3"},
7866 {"IIR1 INP3 MUX", "DEC4", "ADC MUX4"},
7867 {"IIR1 INP3 MUX", "DEC5", "ADC MUX5"},
7868 {"IIR1 INP3 MUX", "DEC6", "ADC MUX6"},
7869 {"IIR1 INP3 MUX", "DEC7", "ADC MUX7"},
7870 {"IIR1 INP3 MUX", "DEC8", "ADC MUX8"},
7871 {"IIR1 INP3 MUX", "RX0", "SLIM RX0"},
7872 {"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
7873 {"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
7874 {"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
7875 {"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
7876 {"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
7877 {"IIR1 INP3 MUX", "RX6", "SLIM RX6"},
7878 {"IIR1 INP3 MUX", "RX7", "SLIM RX7"},
7879
7880 {"SRC0", NULL, "IIR0"},
7881 {"SRC1", NULL, "IIR1"},
7882 {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
7883 {"RX INT0 MIX2 INP", "SRC1", "SRC1"},
7884 {"RX INT1 MIX2 INP", "SRC0", "SRC0"},
7885 {"RX INT1 MIX2 INP", "SRC1", "SRC1"},
7886 {"RX INT2 MIX2 INP", "SRC0", "SRC0"},
7887 {"RX INT2 MIX2 INP", "SRC1", "SRC1"},
7888 {"RX INT3 MIX2 INP", "SRC0", "SRC0"},
7889 {"RX INT3 MIX2 INP", "SRC1", "SRC1"},
7890 {"RX INT4 MIX2 INP", "SRC0", "SRC0"},
7891 {"RX INT4 MIX2 INP", "SRC1", "SRC1"},
7892 {"RX INT7 MIX2 INP", "SRC0", "SRC0"},
7893 {"RX INT7 MIX2 INP", "SRC1", "SRC1"},
7894};
7895
7896static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol,
7897 struct snd_ctl_elem_value *ucontrol)
7898{
Meng Wang15c825d2018-09-06 10:49:18 +08007899 struct snd_soc_component *component =
7900 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307901 u16 amic_reg;
7902
7903 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7904 amic_reg = WCD9335_ANA_AMIC1;
7905 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7906 amic_reg = WCD9335_ANA_AMIC3;
7907 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7908 amic_reg = WCD9335_ANA_AMIC5;
7909
7910 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08007911 (snd_soc_component_read32(component, amic_reg) &
7912 WCD9335_AMIC_PWR_LVL_MASK) >>
7913 WCD9335_AMIC_PWR_LVL_SHIFT;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307914
7915 return 0;
7916}
7917
7918static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol,
7919 struct snd_ctl_elem_value *ucontrol)
7920{
Meng Wang15c825d2018-09-06 10:49:18 +08007921 struct snd_soc_component *component =
7922 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307923 u32 mode_val;
7924 u16 amic_reg;
7925
7926 mode_val = ucontrol->value.enumerated.item[0];
7927
Meng Wang15c825d2018-09-06 10:49:18 +08007928 dev_dbg(component->dev, "%s: mode: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307929 __func__, mode_val);
7930
7931 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7932 amic_reg = WCD9335_ANA_AMIC1;
7933 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7934 amic_reg = WCD9335_ANA_AMIC3;
7935 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7936 amic_reg = WCD9335_ANA_AMIC5;
7937
Meng Wang15c825d2018-09-06 10:49:18 +08007938 snd_soc_component_update_bits(component, amic_reg,
7939 WCD9335_AMIC_PWR_LVL_MASK,
7940 mode_val << WCD9335_AMIC_PWR_LVL_SHIFT);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307941
7942 return 0;
7943}
7944
7945static int tasha_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
7946 struct snd_ctl_elem_value *ucontrol)
7947{
Meng Wang15c825d2018-09-06 10:49:18 +08007948 struct snd_soc_component *component =
7949 snd_soc_kcontrol_component(kcontrol);
7950 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307951
7952 ucontrol->value.integer.value[0] = tasha->hph_mode;
7953 return 0;
7954}
7955
7956static int tasha_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
7957 struct snd_ctl_elem_value *ucontrol)
7958{
Meng Wang15c825d2018-09-06 10:49:18 +08007959 struct snd_soc_component *component =
7960 snd_soc_kcontrol_component(kcontrol);
7961 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307962 u32 mode_val;
7963
7964 mode_val = ucontrol->value.enumerated.item[0];
7965
Meng Wang15c825d2018-09-06 10:49:18 +08007966 dev_dbg(component->dev, "%s: mode: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307967 __func__, mode_val);
7968
7969 if (mode_val == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08007970 dev_warn(component->dev, "%s:Invalid HPH Mode, default to Cls-H HiFi\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307971 __func__);
7972 mode_val = CLS_H_HIFI;
7973 }
7974 tasha->hph_mode = mode_val;
7975 return 0;
7976}
7977
7978static const char *const tasha_conn_mad_text[] = {
7979 "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6",
7980 "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4",
7981 "DMIC5", "NOTUSED3", "NOTUSED4"
7982};
7983
7984static const struct soc_enum tasha_conn_mad_enum =
7985 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_conn_mad_text),
7986 tasha_conn_mad_text);
7987
7988static int tasha_enable_ldo_h_get(struct snd_kcontrol *kcontrol,
7989 struct snd_ctl_elem_value *ucontrol)
7990{
Meng Wang15c825d2018-09-06 10:49:18 +08007991 struct snd_soc_component *component =
7992 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307993 u8 val = 0;
7994
Meng Wang15c825d2018-09-06 10:49:18 +08007995 if (component)
7996 val = snd_soc_component_read32(component, WCD9335_LDOH_MODE) &
7997 0x80;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307998
7999 ucontrol->value.integer.value[0] = !!val;
8000
8001 return 0;
8002}
8003
8004static int tasha_enable_ldo_h_put(struct snd_kcontrol *kcontrol,
8005 struct snd_ctl_elem_value *ucontrol)
8006{
Meng Wang15c825d2018-09-06 10:49:18 +08008007 struct snd_soc_component *component =
8008 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308009 int value = ucontrol->value.integer.value[0];
8010 bool enable;
8011
8012 enable = !!value;
Meng Wang15c825d2018-09-06 10:49:18 +08008013 if (component)
8014 tasha_codec_enable_standalone_ldo_h(component, enable);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308015
8016 return 0;
8017}
8018
8019static int tasha_mad_input_get(struct snd_kcontrol *kcontrol,
8020 struct snd_ctl_elem_value *ucontrol)
8021{
8022 u8 tasha_mad_input;
Meng Wang15c825d2018-09-06 10:49:18 +08008023 struct snd_soc_component *component =
8024 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308025
Meng Wang15c825d2018-09-06 10:49:18 +08008026 tasha_mad_input = snd_soc_component_read32(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308027 WCD9335_SOC_MAD_INP_SEL) & 0x0F;
8028 ucontrol->value.integer.value[0] = tasha_mad_input;
8029
Meng Wang15c825d2018-09-06 10:49:18 +08008030 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308031 "%s: tasha_mad_input = %s\n", __func__,
8032 tasha_conn_mad_text[tasha_mad_input]);
8033 return 0;
8034}
8035
8036static int tasha_mad_input_put(struct snd_kcontrol *kcontrol,
8037 struct snd_ctl_elem_value *ucontrol)
8038{
8039 u8 tasha_mad_input;
Meng Wang15c825d2018-09-06 10:49:18 +08008040 struct snd_soc_component *component =
8041 snd_soc_kcontrol_component(kcontrol);
8042 struct snd_soc_card *card = component->card;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308043 char mad_amic_input_widget[6];
8044 const char *mad_input_widget;
8045 const char *source_widget = NULL;
8046 u32 adc, i, mic_bias_found = 0;
8047 int ret = 0;
8048 char *mad_input;
8049
8050 tasha_mad_input = ucontrol->value.integer.value[0];
8051
8052 if (tasha_mad_input >= ARRAY_SIZE(tasha_conn_mad_text)) {
Meng Wang15c825d2018-09-06 10:49:18 +08008053 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308054 "%s: tasha_mad_input = %d out of bounds\n",
8055 __func__, tasha_mad_input);
8056 return -EINVAL;
8057 }
8058
8059 if (!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED1") ||
8060 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED2") ||
8061 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED3") ||
8062 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED4")) {
Meng Wang15c825d2018-09-06 10:49:18 +08008063 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308064 "%s: Unsupported tasha_mad_input = %s\n",
8065 __func__, tasha_conn_mad_text[tasha_mad_input]);
8066 return -EINVAL;
8067 }
8068
8069 if (strnstr(tasha_conn_mad_text[tasha_mad_input],
8070 "ADC", sizeof("ADC"))) {
8071 mad_input = strpbrk(tasha_conn_mad_text[tasha_mad_input],
8072 "123456");
8073 if (!mad_input) {
Meng Wang15c825d2018-09-06 10:49:18 +08008074 dev_err(component->dev, "%s: Invalid MAD input %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308075 __func__,
8076 tasha_conn_mad_text[tasha_mad_input]);
8077 return -EINVAL;
8078 }
8079 ret = kstrtouint(mad_input, 10, &adc);
8080 if ((ret < 0) || (adc > 6)) {
Meng Wang15c825d2018-09-06 10:49:18 +08008081 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308082 "%s: Invalid ADC = %s\n", __func__,
8083 tasha_conn_mad_text[tasha_mad_input]);
8084 ret = -EINVAL;
8085 }
8086
8087 snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc);
8088
8089 mad_input_widget = mad_amic_input_widget;
8090 } else {
8091 /* DMIC type input widget*/
8092 mad_input_widget = tasha_conn_mad_text[tasha_mad_input];
8093 }
8094
Meng Wang15c825d2018-09-06 10:49:18 +08008095 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308096 "%s: tasha input widget = %s\n", __func__,
8097 mad_input_widget);
8098
8099 for (i = 0; i < card->num_of_dapm_routes; i++) {
8100 if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) {
8101 source_widget = card->of_dapm_routes[i].source;
8102 if (!source_widget) {
Meng Wang15c825d2018-09-06 10:49:18 +08008103 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308104 "%s: invalid source widget\n",
8105 __func__);
8106 return -EINVAL;
8107 }
8108
8109 if (strnstr(source_widget,
8110 "MIC BIAS1", sizeof("MIC BIAS1"))) {
8111 mic_bias_found = 1;
8112 break;
8113 } else if (strnstr(source_widget,
8114 "MIC BIAS2", sizeof("MIC BIAS2"))) {
8115 mic_bias_found = 2;
8116 break;
8117 } else if (strnstr(source_widget,
8118 "MIC BIAS3", sizeof("MIC BIAS3"))) {
8119 mic_bias_found = 3;
8120 break;
8121 } else if (strnstr(source_widget,
8122 "MIC BIAS4", sizeof("MIC BIAS4"))) {
8123 mic_bias_found = 4;
8124 break;
8125 }
8126 }
8127 }
8128
8129 if (!mic_bias_found) {
Meng Wang15c825d2018-09-06 10:49:18 +08008130 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308131 "%s: mic bias source not found for input = %s\n",
8132 __func__, mad_input_widget);
8133 return -EINVAL;
8134 }
8135
Meng Wang15c825d2018-09-06 10:49:18 +08008136 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308137 "%s: mic_bias found = %d\n", __func__,
8138 mic_bias_found);
8139
Meng Wang15c825d2018-09-06 10:49:18 +08008140 snd_soc_component_update_bits(component, WCD9335_SOC_MAD_INP_SEL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308141 0x0F, tasha_mad_input);
Meng Wang15c825d2018-09-06 10:49:18 +08008142 snd_soc_component_update_bits(component, WCD9335_ANA_MAD_SETUP,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308143 0x07, mic_bias_found);
8144
8145 return 0;
8146}
8147
8148static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol,
8149 struct snd_ctl_elem_value *ucontrol)
8150{
Meng Wang15c825d2018-09-06 10:49:18 +08008151 struct snd_soc_component *component =
8152 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308153 u16 ctl_reg;
8154 u8 reg_val, pinctl_position;
8155
8156 pinctl_position = ((struct soc_multi_mixer_control *)
8157 kcontrol->private_value)->shift;
8158 switch (pinctl_position >> 3) {
8159 case 0:
8160 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
8161 break;
8162 case 1:
8163 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
8164 break;
8165 case 2:
8166 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
8167 break;
8168 case 3:
8169 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
8170 break;
8171 default:
Meng Wang15c825d2018-09-06 10:49:18 +08008172 dev_err(component->dev, "%s: Invalid pinctl position = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308173 __func__, pinctl_position);
8174 return -EINVAL;
8175 }
8176
Meng Wang15c825d2018-09-06 10:49:18 +08008177 reg_val = snd_soc_component_read32(component, ctl_reg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308178 reg_val = (reg_val >> (pinctl_position & 0x07)) & 0x1;
8179 ucontrol->value.integer.value[0] = reg_val;
8180
8181 return 0;
8182}
8183
8184static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol,
8185 struct snd_ctl_elem_value *ucontrol)
8186{
Meng Wang15c825d2018-09-06 10:49:18 +08008187 struct snd_soc_component *component =
8188 snd_soc_kcontrol_component(kcontrol);
8189 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308190 u16 ctl_reg, cfg_reg;
8191 u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask;
8192
8193 /* 1- high or low; 0- high Z */
8194 pinctl_mode = ucontrol->value.integer.value[0];
8195 pinctl_position = ((struct soc_multi_mixer_control *)
8196 kcontrol->private_value)->shift;
8197
8198 switch (pinctl_position >> 3) {
8199 case 0:
8200 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
8201 break;
8202 case 1:
8203 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
8204 break;
8205 case 2:
8206 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
8207 break;
8208 case 3:
8209 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
8210 break;
8211 default:
Meng Wang15c825d2018-09-06 10:49:18 +08008212 dev_err(component->dev, "%s: Invalid pinctl position = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308213 __func__, pinctl_position);
8214 return -EINVAL;
8215 }
8216
8217 ctl_val = pinctl_mode << (pinctl_position & 0x07);
8218 mask = 1 << (pinctl_position & 0x07);
Meng Wang15c825d2018-09-06 10:49:18 +08008219 snd_soc_component_update_bits(component, ctl_reg, mask, ctl_val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308220
8221 cfg_reg = WCD9335_TLMM_BIST_MODE_PINCFG + pinctl_position;
8222 if (!pinctl_mode) {
8223 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
8224 cfg_val = 0x4;
8225 else
8226 cfg_val = 0xC;
8227 } else {
8228 cfg_val = 0;
8229 }
Meng Wang15c825d2018-09-06 10:49:18 +08008230 snd_soc_component_update_bits(component, cfg_reg, 0x07, cfg_val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308231
Meng Wang15c825d2018-09-06 10:49:18 +08008232 dev_dbg(component->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308233 __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val);
8234
8235 return 0;
8236}
8237
8238static void wcd_vbat_adc_out_config_2_0(struct wcd_vbat *vbat,
Meng Wang15c825d2018-09-06 10:49:18 +08008239 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308240{
8241 u8 val1, val2;
8242
8243 /*
8244 * Measure dcp1 by using "ALT" branch of band gap
8245 * voltage(Vbg) and use it in FAST mode
8246 */
Meng Wang15c825d2018-09-06 10:49:18 +08008247 snd_soc_component_update_bits(component, WCD9335_BIAS_CTL,
8248 0x82, 0x82);
8249 snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_PATH_CTL,
8250 0x10, 0x10);
8251 snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_DEBUG1,
8252 0x01, 0x01);
8253 snd_soc_component_update_bits(component, WCD9335_ANA_VBADC,
8254 0x80, 0x80);
8255 snd_soc_component_update_bits(component, WCD9335_VBADC_SUBBLOCK_EN,
8256 0x20, 0x00);
8257 snd_soc_component_update_bits(component, WCD9335_VBADC_FE_CTRL,
8258 0x20, 0x20);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308259 /* Wait 100 usec after calibration select as Vbg */
8260 usleep_range(100, 110);
8261
Meng Wang15c825d2018-09-06 10:49:18 +08008262 snd_soc_component_update_bits(component, WCD9335_VBADC_ADC_IO,
8263 0x40, 0x40);
8264 val1 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTMSB);
8265 val2 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTLSB);
8266 snd_soc_component_update_bits(component, WCD9335_VBADC_ADC_IO,
8267 0x40, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308268
8269 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8270
Meng Wang15c825d2018-09-06 10:49:18 +08008271 snd_soc_component_update_bits(component, WCD9335_BIAS_CTL, 0x40, 0x40);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308272 /* Wait 100 usec after selecting Vbg as 1.05V */
8273 usleep_range(100, 110);
8274
Meng Wang15c825d2018-09-06 10:49:18 +08008275 snd_soc_component_update_bits(component, WCD9335_VBADC_ADC_IO,
8276 0x40, 0x40);
8277 val1 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTMSB);
8278 val2 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTLSB);
8279 snd_soc_component_update_bits(component, WCD9335_VBADC_ADC_IO,
8280 0x40, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308281
8282 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8283
Meng Wang15c825d2018-09-06 10:49:18 +08008284 dev_dbg(component->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308285 __func__, vbat->dcp1, vbat->dcp2);
8286
Meng Wang15c825d2018-09-06 10:49:18 +08008287 snd_soc_component_write(component, WCD9335_BIAS_CTL, 0x28);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308288 /* Wait 100 usec after selecting Vbg as 0.85V */
8289 usleep_range(100, 110);
8290
Meng Wang15c825d2018-09-06 10:49:18 +08008291 snd_soc_component_update_bits(component, WCD9335_VBADC_FE_CTRL,
8292 0x20, 0x00);
8293 snd_soc_component_update_bits(component, WCD9335_VBADC_SUBBLOCK_EN,
8294 0x20, 0x20);
8295 snd_soc_component_update_bits(component, WCD9335_ANA_VBADC,
8296 0x80, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308297
Meng Wang15c825d2018-09-06 10:49:18 +08008298 snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_PATH_CTL,
8299 0x10, 0x00);
8300 snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_DEBUG1,
8301 0x01, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308302}
8303
8304static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat,
Meng Wang15c825d2018-09-06 10:49:18 +08008305 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308306{
8307 u8 val1, val2;
8308
8309 /*
8310 * Measure dcp1 by applying band gap voltage(Vbg)
8311 * of 0.85V
8312 */
Meng Wang15c825d2018-09-06 10:49:18 +08008313 snd_soc_component_write(component, WCD9335_ANA_BIAS, 0x20);
8314 snd_soc_component_write(component, WCD9335_BIAS_CTL, 0x28);
8315 snd_soc_component_write(component, WCD9335_BIAS_VBG_FINE_ADJ, 0x05);
8316 snd_soc_component_write(component, WCD9335_ANA_BIAS, 0xA0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308317 /* Wait 2 sec after enabling band gap bias */
8318 usleep_range(2000000, 2000100);
8319
Meng Wang15c825d2018-09-06 10:49:18 +08008320 snd_soc_component_write(component, WCD9335_ANA_CLK_TOP, 0x82);
8321 snd_soc_component_write(component, WCD9335_ANA_CLK_TOP, 0x87);
8322 snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_PATH_CTL,
8323 0x10, 0x10);
8324 snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_CFG, 0x0D);
8325 snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308326
Meng Wang15c825d2018-09-06 10:49:18 +08008327 snd_soc_component_write(component, WCD9335_ANA_VBADC, 0x80);
8328 snd_soc_component_write(component, WCD9335_VBADC_SUBBLOCK_EN, 0xDE);
8329 snd_soc_component_write(component, WCD9335_VBADC_FE_CTRL, 0x3C);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308330 /* Wait 1 msec after calibration select as Vbg */
8331 usleep_range(1000, 1100);
8332
Meng Wang15c825d2018-09-06 10:49:18 +08008333 snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0xC0);
8334 val1 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTMSB);
8335 val2 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTLSB);
8336 snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308337
8338 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8339
8340 /*
8341 * Measure dcp2 by applying band gap voltage(Vbg)
8342 * of 1.05V
8343 */
Meng Wang15c825d2018-09-06 10:49:18 +08008344 snd_soc_component_write(component, WCD9335_ANA_BIAS, 0x80);
8345 snd_soc_component_write(component, WCD9335_ANA_BIAS, 0xC0);
8346 snd_soc_component_write(component, WCD9335_BIAS_CTL, 0x68);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308347 /* Wait 2 msec after selecting Vbg as 1.05V */
8348 usleep_range(2000, 2100);
8349
Meng Wang15c825d2018-09-06 10:49:18 +08008350 snd_soc_component_write(component, WCD9335_ANA_BIAS, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308351 /* Wait 1 sec after enabling band gap bias */
8352 usleep_range(1000000, 1000100);
8353
Meng Wang15c825d2018-09-06 10:49:18 +08008354 snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0xC0);
8355 val1 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTMSB);
8356 val2 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTLSB);
8357 snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308358
8359 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8360
Meng Wang15c825d2018-09-06 10:49:18 +08008361 dev_dbg(component->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308362 __func__, vbat->dcp1, vbat->dcp2);
8363
8364 /* Reset the Vbat ADC configuration */
Meng Wang15c825d2018-09-06 10:49:18 +08008365 snd_soc_component_write(component, WCD9335_ANA_BIAS, 0x80);
8366 snd_soc_component_write(component, WCD9335_ANA_BIAS, 0xC0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308367
Meng Wang15c825d2018-09-06 10:49:18 +08008368 snd_soc_component_write(component, WCD9335_BIAS_CTL, 0x28);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308369 /* Wait 2 msec after selecting Vbg as 0.85V */
8370 usleep_range(2000, 2100);
8371
Meng Wang15c825d2018-09-06 10:49:18 +08008372 snd_soc_component_write(component, WCD9335_ANA_BIAS, 0xA0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308373 /* Wait 1 sec after enabling band gap bias */
8374 usleep_range(1000000, 1000100);
8375
Meng Wang15c825d2018-09-06 10:49:18 +08008376 snd_soc_component_write(component, WCD9335_VBADC_FE_CTRL, 0x1C);
8377 snd_soc_component_write(component, WCD9335_VBADC_SUBBLOCK_EN, 0xFE);
8378 snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0x80);
8379 snd_soc_component_write(component, WCD9335_ANA_VBADC, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308380
Meng Wang15c825d2018-09-06 10:49:18 +08008381 snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00);
8382 snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_PATH_CTL,
8383 0x00);
8384 snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_CFG, 0x0A);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308385}
8386
8387static void wcd_vbat_adc_out_config(struct wcd_vbat *vbat,
Meng Wang15c825d2018-09-06 10:49:18 +08008388 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308389{
Meng Wang15c825d2018-09-06 10:49:18 +08008390 struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308391
8392 if (!vbat->adc_config) {
Meng Wang15c825d2018-09-06 10:49:18 +08008393 tasha_cdc_mclk_enable(component, true, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308394
8395 if (TASHA_IS_2_0(wcd9xxx))
Meng Wang15c825d2018-09-06 10:49:18 +08008396 wcd_vbat_adc_out_config_2_0(vbat, component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308397 else
Meng Wang15c825d2018-09-06 10:49:18 +08008398 wcd_vbat_adc_out_config_1_x(vbat, component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308399
Meng Wang15c825d2018-09-06 10:49:18 +08008400 tasha_cdc_mclk_enable(component, false, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308401 vbat->adc_config = true;
8402 }
8403}
8404
Meng Wang15c825d2018-09-06 10:49:18 +08008405static int tasha_update_vbat_reg_config(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308406{
Meng Wang15c825d2018-09-06 10:49:18 +08008407 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308408 struct firmware_cal *hwdep_cal = NULL;
8409 struct vbat_monitor_reg *vbat_reg_ptr = NULL;
8410 const void *data;
8411 size_t cal_size, vbat_size_remaining;
8412 int ret = 0, i;
8413 u32 vbat_writes_size = 0;
8414 u16 reg;
8415 u8 mask, val, old_val;
8416
8417 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_VBAT_CAL);
8418 if (hwdep_cal) {
8419 data = hwdep_cal->data;
8420 cal_size = hwdep_cal->size;
Meng Wang15c825d2018-09-06 10:49:18 +08008421 dev_dbg(component->dev, "%s: using hwdep calibration\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308422 __func__);
8423 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08008424 dev_err(component->dev, "%s: Vbat cal not received\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308425 __func__);
8426 ret = -EINVAL;
8427 goto done;
8428 }
8429
8430 if (cal_size < sizeof(*vbat_reg_ptr)) {
Meng Wang15c825d2018-09-06 10:49:18 +08008431 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308432 "%s: Incorrect size %zd for Vbat Cal, expected %zd\n",
8433 __func__, cal_size, sizeof(*vbat_reg_ptr));
8434 ret = -EINVAL;
8435 goto done;
8436 }
8437
8438 vbat_reg_ptr = (struct vbat_monitor_reg *) (data);
8439
8440 if (!vbat_reg_ptr) {
Meng Wang15c825d2018-09-06 10:49:18 +08008441 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308442 "%s: Invalid calibration data for Vbat\n",
8443 __func__);
8444 ret = -EINVAL;
8445 goto done;
8446 }
8447
8448 vbat_writes_size = vbat_reg_ptr->size;
8449 vbat_size_remaining = cal_size - sizeof(u32);
Meng Wang15c825d2018-09-06 10:49:18 +08008450 dev_dbg(component->dev, "%s: vbat_writes_sz: %d, vbat_sz_remaining: %zd\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308451 __func__, vbat_writes_size, vbat_size_remaining);
8452
8453 if ((vbat_writes_size * TASHA_PACKED_REG_SIZE)
8454 > vbat_size_remaining) {
8455 pr_err("%s: Incorrect Vbat calibration data\n", __func__);
8456 ret = -EINVAL;
8457 goto done;
8458 }
8459
8460 for (i = 0 ; i < vbat_writes_size; i++) {
8461 TASHA_CODEC_UNPACK_ENTRY(vbat_reg_ptr->writes[i],
8462 reg, mask, val);
Meng Wang15c825d2018-09-06 10:49:18 +08008463 old_val = snd_soc_component_read32(component, reg);
8464 snd_soc_component_write(component, reg, (old_val & ~mask) |
8465 (val & mask));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308466 }
8467
8468done:
8469 return ret;
8470}
8471
8472static int tasha_vbat_adc_data_get(struct snd_kcontrol *kcontrol,
8473 struct snd_ctl_elem_value *ucontrol)
8474{
Meng Wang15c825d2018-09-06 10:49:18 +08008475 struct snd_soc_component *component =
8476 snd_soc_kcontrol_component(kcontrol);
8477 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308478
Meng Wang15c825d2018-09-06 10:49:18 +08008479 wcd_vbat_adc_out_config(&tasha->vbat, component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308480
8481 ucontrol->value.integer.value[0] = tasha->vbat.dcp1;
8482 ucontrol->value.integer.value[1] = tasha->vbat.dcp2;
8483
Meng Wang15c825d2018-09-06 10:49:18 +08008484 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308485 "%s: Vbat ADC output values, Dcp1 : %lu, Dcp2: %lu\n",
8486 __func__, ucontrol->value.integer.value[0],
8487 ucontrol->value.integer.value[1]);
8488
8489 return 0;
8490}
8491
8492static const char * const tasha_vbat_gsm_mode_text[] = {
8493 "OFF", "ON"};
8494
8495static const struct soc_enum tasha_vbat_gsm_mode_enum =
8496 SOC_ENUM_SINGLE_EXT(2, tasha_vbat_gsm_mode_text);
8497
8498static int tasha_vbat_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
8499 struct snd_ctl_elem_value *ucontrol)
8500{
Meng Wang15c825d2018-09-06 10:49:18 +08008501 struct snd_soc_component *component =
8502 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308503
8504 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08008505 ((snd_soc_component_read32(
8506 component, WCD9335_CDC_VBAT_VBAT_CFG) & 0x04) ? 1 : 0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308507
Meng Wang15c825d2018-09-06 10:49:18 +08008508 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308509 ucontrol->value.integer.value[0]);
8510
8511 return 0;
8512}
8513
8514static int tasha_vbat_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
8515 struct snd_ctl_elem_value *ucontrol)
8516{
Meng Wang15c825d2018-09-06 10:49:18 +08008517 struct snd_soc_component *component =
8518 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308519
Meng Wang15c825d2018-09-06 10:49:18 +08008520 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308521 ucontrol->value.integer.value[0]);
8522
8523 /* Set Vbat register configuration for GSM mode bit based on value */
8524 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08008525 snd_soc_component_update_bits(component,
8526 WCD9335_CDC_VBAT_VBAT_CFG,
8527 0x04, 0x04);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308528 else
Meng Wang15c825d2018-09-06 10:49:18 +08008529 snd_soc_component_update_bits(component,
8530 WCD9335_CDC_VBAT_VBAT_CFG,
8531 0x04, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308532
8533 return 0;
8534}
8535
8536static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w,
8537 struct snd_kcontrol *kcontrol,
8538 int event)
8539{
8540 int ret = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08008541 struct snd_soc_component *component =
8542 snd_soc_dapm_to_component(w->dapm);
8543 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308544 u16 vbat_path_ctl, vbat_cfg, vbat_path_cfg;
8545
8546 vbat_path_ctl = WCD9335_CDC_VBAT_VBAT_PATH_CTL;
8547 vbat_cfg = WCD9335_CDC_VBAT_VBAT_CFG;
8548 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8549
8550 if (!strcmp(w->name, "RX INT8 VBAT"))
8551 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8552 else if (!strcmp(w->name, "RX INT7 VBAT"))
8553 vbat_path_cfg = WCD9335_CDC_RX7_RX_PATH_CFG1;
8554 else if (!strcmp(w->name, "RX INT6 VBAT"))
8555 vbat_path_cfg = WCD9335_CDC_RX6_RX_PATH_CFG1;
8556 else if (!strcmp(w->name, "RX INT5 VBAT"))
8557 vbat_path_cfg = WCD9335_CDC_RX5_RX_PATH_CFG1;
8558
8559 switch (event) {
8560 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08008561 ret = tasha_update_vbat_reg_config(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308562 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +08008563 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308564 "%s : VBAT isn't calibrated, So not enabling it\n",
8565 __func__);
8566 return 0;
8567 }
Meng Wang15c825d2018-09-06 10:49:18 +08008568 snd_soc_component_write(component, WCD9335_ANA_VBADC, 0x80);
8569 snd_soc_component_update_bits(component, vbat_path_cfg,
8570 0x02, 0x02);
8571 snd_soc_component_update_bits(component, vbat_path_ctl,
8572 0x10, 0x10);
8573 snd_soc_component_update_bits(component, vbat_cfg, 0x01, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308574 tasha->vbat.is_enabled = true;
8575 break;
8576 case SND_SOC_DAPM_POST_PMD:
8577 if (tasha->vbat.is_enabled) {
Meng Wang15c825d2018-09-06 10:49:18 +08008578 snd_soc_component_update_bits(component, vbat_cfg,
8579 0x01, 0x00);
8580 snd_soc_component_update_bits(component, vbat_path_ctl,
8581 0x10, 0x00);
8582 snd_soc_component_update_bits(component, vbat_path_cfg,
8583 0x02, 0x00);
8584 snd_soc_component_write(component, WCD9335_ANA_VBADC,
8585 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308586 tasha->vbat.is_enabled = false;
8587 }
8588 break;
8589 };
8590
8591 return ret;
8592}
8593
8594static const char * const rx_hph_mode_mux_text[] = {
8595 "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI"
8596};
8597
8598static const struct soc_enum rx_hph_mode_mux_enum =
8599 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
8600 rx_hph_mode_mux_text);
8601
8602static const char * const amic_pwr_lvl_text[] = {
8603 "LOW_PWR", "DEFAULT", "HIGH_PERF"
8604};
8605
8606static const struct soc_enum amic_pwr_lvl_enum =
8607 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(amic_pwr_lvl_text),
8608 amic_pwr_lvl_text);
8609
8610static const struct snd_kcontrol_new tasha_snd_controls[] = {
8611 SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
8612 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8613 SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
8614 0, -84, 40, digital_gain),
8615 SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
8616 0, -84, 40, digital_gain),
8617 SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
8618 0, -84, 40, digital_gain),
8619 SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
8620 0, -84, 40, digital_gain),
8621 SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
8622 0, -84, 40, digital_gain),
8623 SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
8624 0, -84, 40, digital_gain),
8625 SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
8626 0, -84, 40, digital_gain),
8627 SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
8628 0, -84, 40, digital_gain),
8629
8630 SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
8631 WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
8632 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8633 SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
8634 WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
8635 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8636 SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
8637 WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
8638 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8639 SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
8640 WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
8641 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8642 SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
8643 WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
8644 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8645 SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
8646 WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
8647 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8648 SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
8649 WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
8650 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8651 SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
8652 WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
8653 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8654 SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
8655 WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
8656 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8657
8658 SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9335_CDC_TX0_TX_VOL_CTL, 0,
8659 -84, 40, digital_gain),
8660 SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9335_CDC_TX1_TX_VOL_CTL, 0,
8661 -84, 40, digital_gain),
8662 SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9335_CDC_TX2_TX_VOL_CTL, 0,
8663 -84, 40, digital_gain),
8664 SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9335_CDC_TX3_TX_VOL_CTL, 0,
8665 -84, 40, digital_gain),
8666 SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9335_CDC_TX4_TX_VOL_CTL, 0,
8667 -84, 40, digital_gain),
8668 SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9335_CDC_TX5_TX_VOL_CTL, 0,
8669 -84, 40, digital_gain),
8670 SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9335_CDC_TX6_TX_VOL_CTL, 0,
8671 -84, 40, digital_gain),
8672 SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9335_CDC_TX7_TX_VOL_CTL, 0,
8673 -84, 40, digital_gain),
8674 SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9335_CDC_TX8_TX_VOL_CTL, 0,
8675 -84, 40, digital_gain),
8676
8677 SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
8678 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84,
8679 40, digital_gain),
8680 SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
8681 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84,
8682 40, digital_gain),
8683 SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
8684 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84,
8685 40, digital_gain),
8686 SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
8687 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84,
8688 40, digital_gain),
8689 SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
8690 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84,
8691 40, digital_gain),
8692 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
8693 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84,
8694 40, digital_gain),
8695 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
8696 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84,
8697 40, digital_gain),
8698 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
8699 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84,
8700 40, digital_gain),
8701
8702 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tasha_get_anc_slot,
8703 tasha_put_anc_slot),
8704 SOC_ENUM_EXT("ANC Function", tasha_anc_func_enum, tasha_get_anc_func,
8705 tasha_put_anc_func),
8706
8707 SOC_ENUM_EXT("CLK MODE", tasha_clkmode_enum, tasha_get_clkmode,
8708 tasha_put_clkmode),
8709
8710 SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
8711 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
8712 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
8713 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
8714 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
8715 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
8716 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
8717 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
8718 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
8719
8720 SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
8721 SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
8722 SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
8723 SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
8724 SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
8725 SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
8726 SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
8727 SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
8728 SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
8729 SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
8730 SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
8731 SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
8732 SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
8733 SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
8734 SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
8735 SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
8736 SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
8737 SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
8738
8739 SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
8740 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8741 SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
8742 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8743 SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
8744 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8745 SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
8746 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8747 SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
8748 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8749 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
8750 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8751 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
8752 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8753 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
8754 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8755 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
8756 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8757 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
8758 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8759
8760 SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
8761 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8762 SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
8763 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8764 SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
8765 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8766 SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
8767 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8768 SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
8769 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8770 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
8771 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8772 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
8773 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8774 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
8775 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8776 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
8777 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8778 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
8779 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8780
8781 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
8782 tasha_get_compander, tasha_set_compander),
8783 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
8784 tasha_get_compander, tasha_set_compander),
8785 SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0,
8786 tasha_get_compander, tasha_set_compander),
8787 SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0,
8788 tasha_get_compander, tasha_set_compander),
8789 SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0,
8790 tasha_get_compander, tasha_set_compander),
8791 SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0,
8792 tasha_get_compander, tasha_set_compander),
8793 SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
8794 tasha_get_compander, tasha_set_compander),
8795 SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
8796 tasha_get_compander, tasha_set_compander),
8797
8798 SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
8799 tasha_rx_hph_mode_get, tasha_rx_hph_mode_put),
8800
8801 SOC_ENUM_EXT("MAD Input", tasha_conn_mad_enum,
8802 tasha_mad_input_get, tasha_mad_input_put),
8803 SOC_SINGLE_EXT("LDO_H Enable", SND_SOC_NOPM, 0, 1, 0,
8804 tasha_enable_ldo_h_get, tasha_enable_ldo_h_put),
8805
8806 SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0,
8807 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8808
8809 SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0,
8810 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8811
8812 SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 19, 1, 0,
8813 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8814
8815 SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 20, 1, 0,
8816 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8817
8818 SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 21, 1, 0,
8819 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8820
8821 SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 22, 1, 0,
8822 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8823 SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum,
8824 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8825 SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum,
8826 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8827 SOC_ENUM_EXT("AMIC_5_6 PWR MODE", amic_pwr_lvl_enum,
8828 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8829
8830 SOC_SINGLE_MULTI_EXT("Vbat ADC data", SND_SOC_NOPM, 0, 0xFFFF, 0, 2,
8831 tasha_vbat_adc_data_get, NULL),
8832
8833 SOC_ENUM_EXT("GSM mode Enable", tasha_vbat_gsm_mode_enum,
8834 tasha_vbat_gsm_mode_func_get,
8835 tasha_vbat_gsm_mode_func_put),
8836};
8837
8838static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol,
8839 struct snd_ctl_elem_value *ucontrol)
8840{
Asish Bhattacharya34504582017-08-08 12:55:01 +05308841 struct snd_soc_dapm_widget *widget =
Meng Wang15c825d2018-09-06 10:49:18 +08008842 snd_soc_dapm_kcontrol_widget(kcontrol);
8843 struct snd_soc_component *component =
8844 snd_soc_dapm_to_component(widget->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308845 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8846 unsigned int val;
8847 u16 mic_sel_reg;
8848 u8 mic_sel;
8849
8850 val = ucontrol->value.enumerated.item[0];
8851 if (val > e->items - 1)
8852 return -EINVAL;
8853
Meng Wang15c825d2018-09-06 10:49:18 +08008854 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308855 widget->name, val);
8856
8857 switch (e->reg) {
8858 case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1:
8859 mic_sel_reg = WCD9335_CDC_TX0_TX_PATH_CFG0;
8860 break;
8861 case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1:
8862 mic_sel_reg = WCD9335_CDC_TX1_TX_PATH_CFG0;
8863 break;
8864 case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1:
8865 mic_sel_reg = WCD9335_CDC_TX2_TX_PATH_CFG0;
8866 break;
8867 case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1:
8868 mic_sel_reg = WCD9335_CDC_TX3_TX_PATH_CFG0;
8869 break;
8870 case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
8871 mic_sel_reg = WCD9335_CDC_TX4_TX_PATH_CFG0;
8872 break;
8873 case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
8874 mic_sel_reg = WCD9335_CDC_TX5_TX_PATH_CFG0;
8875 break;
8876 case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
8877 mic_sel_reg = WCD9335_CDC_TX6_TX_PATH_CFG0;
8878 break;
8879 case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
8880 mic_sel_reg = WCD9335_CDC_TX7_TX_PATH_CFG0;
8881 break;
8882 case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0:
8883 mic_sel_reg = WCD9335_CDC_TX8_TX_PATH_CFG0;
8884 break;
8885 default:
Meng Wang15c825d2018-09-06 10:49:18 +08008886 dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308887 __func__, e->reg);
8888 return -EINVAL;
8889 }
8890
8891 /* ADC: 0, DMIC: 1 */
8892 mic_sel = val ? 0x0 : 0x1;
Meng Wang15c825d2018-09-06 10:49:18 +08008893 snd_soc_component_update_bits(component, mic_sel_reg,
8894 1 << 7, mic_sel << 7);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308895
8896 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8897}
8898
8899static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
8900 struct snd_ctl_elem_value *ucontrol)
8901{
Asish Bhattacharya34504582017-08-08 12:55:01 +05308902 struct snd_soc_dapm_widget *widget =
Meng Wang15c825d2018-09-06 10:49:18 +08008903 snd_soc_dapm_kcontrol_widget(kcontrol);
8904 struct snd_soc_component *component =
8905 snd_soc_dapm_to_component(widget->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308906 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8907 unsigned int val;
8908 unsigned short look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8909
8910 val = ucontrol->value.enumerated.item[0];
8911 if (val >= e->items)
8912 return -EINVAL;
8913
Meng Wang15c825d2018-09-06 10:49:18 +08008914 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308915 widget->name, val);
8916
8917 if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0)
8918 look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8919 else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0)
8920 look_ahead_dly_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
8921 else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0)
8922 look_ahead_dly_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
8923
8924 /* Set Look Ahead Delay */
Meng Wang15c825d2018-09-06 10:49:18 +08008925 snd_soc_component_update_bits(component, look_ahead_dly_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308926 0x08, (val ? 0x08 : 0x00));
8927 /* Set DEM INP Select */
8928 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8929}
8930
8931static int tasha_ear_pa_gain_get(struct snd_kcontrol *kcontrol,
8932 struct snd_ctl_elem_value *ucontrol)
8933{
8934 u8 ear_pa_gain;
Meng Wang15c825d2018-09-06 10:49:18 +08008935 struct snd_soc_component *component =
8936 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308937
Meng Wang15c825d2018-09-06 10:49:18 +08008938 ear_pa_gain = snd_soc_component_read32(component, WCD9335_ANA_EAR);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308939
8940 ear_pa_gain = (ear_pa_gain & 0x70) >> 4;
8941
8942 ucontrol->value.integer.value[0] = ear_pa_gain;
8943
Meng Wang15c825d2018-09-06 10:49:18 +08008944 dev_dbg(component->dev, "%s: ear_pa_gain = 0x%x\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308945 ear_pa_gain);
8946
8947 return 0;
8948}
8949
8950static int tasha_ear_pa_gain_put(struct snd_kcontrol *kcontrol,
8951 struct snd_ctl_elem_value *ucontrol)
8952{
8953 u8 ear_pa_gain;
Meng Wang15c825d2018-09-06 10:49:18 +08008954 struct snd_soc_component *component =
8955 snd_soc_kcontrol_component(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308956
Meng Wang15c825d2018-09-06 10:49:18 +08008957 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308958 __func__, ucontrol->value.integer.value[0]);
8959
8960 ear_pa_gain = ucontrol->value.integer.value[0] << 4;
8961
Meng Wang15c825d2018-09-06 10:49:18 +08008962 snd_soc_component_update_bits(component, WCD9335_ANA_EAR,
8963 0x70, ear_pa_gain);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308964 return 0;
8965}
8966
8967static int tasha_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
8968 struct snd_ctl_elem_value *ucontrol)
8969{
Meng Wang15c825d2018-09-06 10:49:18 +08008970 struct snd_soc_component *component =
8971 snd_soc_kcontrol_component(kcontrol);
8972 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308973
8974 ucontrol->value.integer.value[0] = tasha->ear_spkr_gain;
8975
Meng Wang15c825d2018-09-06 10:49:18 +08008976 dev_dbg(component->dev, "%s: ear_spkr_gain = %ld\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308977 ucontrol->value.integer.value[0]);
8978
8979 return 0;
8980}
8981
8982static int tasha_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
8983 struct snd_ctl_elem_value *ucontrol)
8984{
Meng Wang15c825d2018-09-06 10:49:18 +08008985 struct snd_soc_component *component =
8986 snd_soc_kcontrol_component(kcontrol);
8987 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308988
Meng Wang15c825d2018-09-06 10:49:18 +08008989 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308990 __func__, ucontrol->value.integer.value[0]);
8991
8992 tasha->ear_spkr_gain = ucontrol->value.integer.value[0];
8993
8994 return 0;
8995}
8996
Xiaojun Sang24daae82017-09-22 16:50:24 +08008997static int tasha_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
8998 struct snd_ctl_elem_value *ucontrol)
8999{
9000 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08009001 struct snd_soc_component *component =
9002 snd_soc_kcontrol_component(kcontrol);
Xiaojun Sang24daae82017-09-22 16:50:24 +08009003
Meng Wang15c825d2018-09-06 10:49:18 +08009004 bst_state_max = snd_soc_component_read32(
9005 component, WCD9335_CDC_BOOST0_BOOST_CTL);
Xiaojun Sang24daae82017-09-22 16:50:24 +08009006 bst_state_max = (bst_state_max & 0x0c) >> 2;
9007 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08009008 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Xiaojun Sang24daae82017-09-22 16:50:24 +08009009 __func__, ucontrol->value.integer.value[0]);
9010
9011 return 0;
9012}
9013
9014static int tasha_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
9015 struct snd_ctl_elem_value *ucontrol)
9016{
9017 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08009018 struct snd_soc_component *component =
9019 snd_soc_kcontrol_component(kcontrol);
Xiaojun Sang24daae82017-09-22 16:50:24 +08009020
Meng Wang15c825d2018-09-06 10:49:18 +08009021 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Xiaojun Sang24daae82017-09-22 16:50:24 +08009022 __func__, ucontrol->value.integer.value[0]);
9023 bst_state_max = ucontrol->value.integer.value[0] << 2;
Meng Wang15c825d2018-09-06 10:49:18 +08009024 snd_soc_component_update_bits(component, WCD9335_CDC_BOOST0_BOOST_CTL,
Xiaojun Sang24daae82017-09-22 16:50:24 +08009025 0x0c, bst_state_max);
9026
9027 return 0;
9028}
9029
9030static int tasha_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
9031 struct snd_ctl_elem_value *ucontrol)
9032{
9033 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08009034 struct snd_soc_component *component =
9035 snd_soc_kcontrol_component(kcontrol);
Xiaojun Sang24daae82017-09-22 16:50:24 +08009036
Meng Wang15c825d2018-09-06 10:49:18 +08009037 bst_state_max = snd_soc_component_read32(
9038 component, WCD9335_CDC_BOOST1_BOOST_CTL);
Xiaojun Sang24daae82017-09-22 16:50:24 +08009039 bst_state_max = (bst_state_max & 0x0c) >> 2;
9040 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08009041 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Xiaojun Sang24daae82017-09-22 16:50:24 +08009042 __func__, ucontrol->value.integer.value[0]);
9043
9044 return 0;
9045}
9046
9047static int tasha_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
9048 struct snd_ctl_elem_value *ucontrol)
9049{
9050 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08009051 struct snd_soc_component *component =
9052 snd_soc_kcontrol_component(kcontrol);
Xiaojun Sang24daae82017-09-22 16:50:24 +08009053
Meng Wang15c825d2018-09-06 10:49:18 +08009054 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Xiaojun Sang24daae82017-09-22 16:50:24 +08009055 __func__, ucontrol->value.integer.value[0]);
9056 bst_state_max = ucontrol->value.integer.value[0] << 2;
Meng Wang15c825d2018-09-06 10:49:18 +08009057 snd_soc_component_update_bits(component, WCD9335_CDC_BOOST1_BOOST_CTL,
Xiaojun Sang24daae82017-09-22 16:50:24 +08009058 0x0c, bst_state_max);
9059
9060 return 0;
9061}
9062
Meng Wang15c825d2018-09-06 10:49:18 +08009063static int tasha_config_compander(struct snd_soc_component *component,
9064 int interp_n, int event)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309065{
Meng Wang15c825d2018-09-06 10:49:18 +08009066 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309067 int comp;
9068 u16 comp_ctl0_reg, rx_path_cfg0_reg;
9069
9070 /* EAR does not have compander */
9071 if (!interp_n)
9072 return 0;
9073
9074 comp = interp_n - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08009075 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309076 __func__, event, comp + 1, tasha->comp_enabled[comp]);
9077
9078 if (!tasha->comp_enabled[comp])
9079 return 0;
9080
9081 comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL0 + (comp * 8);
9082 rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG0 + (comp * 20);
9083
9084 if (SND_SOC_DAPM_EVENT_ON(event)) {
9085 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08009086 snd_soc_component_update_bits(component, comp_ctl0_reg,
9087 0x01, 0x01);
9088 snd_soc_component_update_bits(component, comp_ctl0_reg,
9089 0x02, 0x02);
9090 snd_soc_component_update_bits(component, comp_ctl0_reg,
9091 0x02, 0x00);
9092 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
9093 0x02, 0x02);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309094 }
9095
9096 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08009097 snd_soc_component_update_bits(component, comp_ctl0_reg,
9098 0x04, 0x04);
9099 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
9100 0x02, 0x00);
9101 snd_soc_component_update_bits(component, comp_ctl0_reg,
9102 0x02, 0x02);
9103 snd_soc_component_update_bits(component, comp_ctl0_reg,
9104 0x02, 0x00);
9105 snd_soc_component_update_bits(component, comp_ctl0_reg,
9106 0x01, 0x00);
9107 snd_soc_component_update_bits(component, comp_ctl0_reg,
9108 0x04, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309109 }
9110
9111 return 0;
9112}
9113
Meng Wang15c825d2018-09-06 10:49:18 +08009114static int tasha_codec_config_mad(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309115{
9116 int ret = 0;
9117 int idx;
9118 const struct firmware *fw;
9119 struct firmware_cal *hwdep_cal = NULL;
9120 struct wcd_mad_audio_cal *mad_cal = NULL;
9121 const void *data;
9122 const char *filename = TASHA_MAD_AUDIO_FIRMWARE_PATH;
Meng Wang15c825d2018-09-06 10:49:18 +08009123 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309124 size_t cal_size;
9125
9126 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_MAD_CAL);
9127 if (hwdep_cal) {
9128 data = hwdep_cal->data;
9129 cal_size = hwdep_cal->size;
Meng Wang15c825d2018-09-06 10:49:18 +08009130 dev_dbg(component->dev, "%s: using hwdep calibration\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309131 __func__);
9132 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08009133 ret = request_firmware(&fw, filename, component->dev);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309134 if (ret || !fw) {
Meng Wang15c825d2018-09-06 10:49:18 +08009135 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309136 "%s: MAD firmware acquire failed, err = %d\n",
9137 __func__, ret);
9138 return -ENODEV;
9139 }
9140 data = fw->data;
9141 cal_size = fw->size;
Meng Wang15c825d2018-09-06 10:49:18 +08009142 dev_dbg(component->dev, "%s: using request_firmware calibration\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309143 __func__);
9144 }
9145
9146 if (cal_size < sizeof(*mad_cal)) {
Meng Wang15c825d2018-09-06 10:49:18 +08009147 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309148 "%s: Incorrect size %zd for MAD Cal, expected %zd\n",
9149 __func__, cal_size, sizeof(*mad_cal));
9150 ret = -ENOMEM;
9151 goto done;
9152 }
9153
9154 mad_cal = (struct wcd_mad_audio_cal *) (data);
9155 if (!mad_cal) {
Meng Wang15c825d2018-09-06 10:49:18 +08009156 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309157 "%s: Invalid calibration data\n",
9158 __func__);
9159 ret = -EINVAL;
9160 goto done;
9161 }
9162
Meng Wang15c825d2018-09-06 10:49:18 +08009163 snd_soc_component_write(component, WCD9335_SOC_MAD_MAIN_CTL_2,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309164 mad_cal->microphone_info.cycle_time);
Meng Wang15c825d2018-09-06 10:49:18 +08009165 snd_soc_component_update_bits(component, WCD9335_SOC_MAD_MAIN_CTL_1,
9166 0xFF << 3,
9167 ((uint16_t)mad_cal->microphone_info.settle_time) << 3);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309168
9169 /* Audio */
Meng Wang15c825d2018-09-06 10:49:18 +08009170 snd_soc_component_write(component, WCD9335_SOC_MAD_AUDIO_CTL_8,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309171 mad_cal->audio_info.rms_omit_samples);
Meng Wang15c825d2018-09-06 10:49:18 +08009172 snd_soc_component_update_bits(component, WCD9335_SOC_MAD_AUDIO_CTL_1,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309173 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
Meng Wang15c825d2018-09-06 10:49:18 +08009174 snd_soc_component_update_bits(component, WCD9335_SOC_MAD_AUDIO_CTL_2,
9175 0x03 << 2,
9176 mad_cal->audio_info.detection_mechanism << 2);
9177 snd_soc_component_write(component, WCD9335_SOC_MAD_AUDIO_CTL_7,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309178 mad_cal->audio_info.rms_diff_threshold & 0x3F);
Meng Wang15c825d2018-09-06 10:49:18 +08009179 snd_soc_component_write(component, WCD9335_SOC_MAD_AUDIO_CTL_5,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309180 mad_cal->audio_info.rms_threshold_lsb);
Meng Wang15c825d2018-09-06 10:49:18 +08009181 snd_soc_component_write(component, WCD9335_SOC_MAD_AUDIO_CTL_6,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309182 mad_cal->audio_info.rms_threshold_msb);
9183
9184 for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients);
9185 idx++) {
Meng Wang15c825d2018-09-06 10:49:18 +08009186 snd_soc_component_update_bits(component,
9187 WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR, 0x3F, idx);
9188 snd_soc_component_write(component,
9189 WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL,
9190 mad_cal->audio_info.iir_coefficients[idx]);
9191 dev_dbg(component->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309192 __func__, idx,
9193 mad_cal->audio_info.iir_coefficients[idx]);
9194 }
9195
9196 /* Beacon */
Meng Wang15c825d2018-09-06 10:49:18 +08009197 snd_soc_component_write(component, WCD9335_SOC_MAD_BEACON_CTL_8,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309198 mad_cal->beacon_info.rms_omit_samples);
Meng Wang15c825d2018-09-06 10:49:18 +08009199 snd_soc_component_update_bits(component, WCD9335_SOC_MAD_BEACON_CTL_1,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309200 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4);
Meng Wang15c825d2018-09-06 10:49:18 +08009201 snd_soc_component_update_bits(component, WCD9335_SOC_MAD_BEACON_CTL_2,
9202 0x03 << 2,
9203 mad_cal->beacon_info.detection_mechanism << 2);
9204 snd_soc_component_write(component, WCD9335_SOC_MAD_BEACON_CTL_7,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309205 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
Meng Wang15c825d2018-09-06 10:49:18 +08009206 snd_soc_component_write(component, WCD9335_SOC_MAD_BEACON_CTL_5,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309207 mad_cal->beacon_info.rms_threshold_lsb);
Meng Wang15c825d2018-09-06 10:49:18 +08009208 snd_soc_component_write(component, WCD9335_SOC_MAD_BEACON_CTL_6,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309209 mad_cal->beacon_info.rms_threshold_msb);
9210
9211 for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients);
9212 idx++) {
Meng Wang15c825d2018-09-06 10:49:18 +08009213 snd_soc_component_update_bits(component,
9214 WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR,
9215 0x3F, idx);
9216 snd_soc_component_write(component,
9217 WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL,
9218 mad_cal->beacon_info.iir_coefficients[idx]);
9219 dev_dbg(component->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309220 __func__, idx,
9221 mad_cal->beacon_info.iir_coefficients[idx]);
9222 }
9223
9224 /* Ultrasound */
Meng Wang15c825d2018-09-06 10:49:18 +08009225 snd_soc_component_update_bits(component, WCD9335_SOC_MAD_ULTR_CTL_1,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309226 0x07 << 4,
9227 mad_cal->ultrasound_info.rms_comp_time << 4);
Meng Wang15c825d2018-09-06 10:49:18 +08009228 snd_soc_component_update_bits(component, WCD9335_SOC_MAD_ULTR_CTL_2,
9229 0x03 << 2,
9230 mad_cal->ultrasound_info.detection_mechanism << 2);
9231 snd_soc_component_write(component, WCD9335_SOC_MAD_ULTR_CTL_7,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309232 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
Meng Wang15c825d2018-09-06 10:49:18 +08009233 snd_soc_component_write(component, WCD9335_SOC_MAD_ULTR_CTL_5,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309234 mad_cal->ultrasound_info.rms_threshold_lsb);
Meng Wang15c825d2018-09-06 10:49:18 +08009235 snd_soc_component_write(component, WCD9335_SOC_MAD_ULTR_CTL_6,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309236 mad_cal->ultrasound_info.rms_threshold_msb);
9237
9238done:
9239 if (!hwdep_cal)
9240 release_firmware(fw);
9241
9242 return ret;
9243}
9244
9245static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w,
9246 struct snd_kcontrol *kcontrol, int event)
9247{
Meng Wang15c825d2018-09-06 10:49:18 +08009248 struct snd_soc_component *component =
9249 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309250 int ret = 0;
9251
Meng Wang15c825d2018-09-06 10:49:18 +08009252 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309253 "%s: event = %d\n", __func__, event);
9254
9255 /* Return if CPE INPUT is DEC1 */
Meng Wang15c825d2018-09-06 10:49:18 +08009256 if (snd_soc_component_read32(component, WCD9335_CPE_SS_SVA_CFG) & 0x01)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309257 return ret;
9258
9259 switch (event) {
9260 case SND_SOC_DAPM_PRE_PMU:
9261
9262 /* Turn on MAD clk */
Meng Wang15c825d2018-09-06 10:49:18 +08009263 snd_soc_component_update_bits(component, WCD9335_CPE_SS_MAD_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309264 0x01, 0x01);
9265
9266 /* Undo reset for MAD */
Meng Wang15c825d2018-09-06 10:49:18 +08009267 snd_soc_component_update_bits(component, WCD9335_CPE_SS_MAD_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309268 0x02, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08009269 ret = tasha_codec_config_mad(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309270 if (ret)
Meng Wang15c825d2018-09-06 10:49:18 +08009271 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309272 "%s: Failed to config MAD, err = %d\n",
9273 __func__, ret);
9274 break;
9275 case SND_SOC_DAPM_POST_PMD:
9276 /* Reset the MAD block */
Meng Wang15c825d2018-09-06 10:49:18 +08009277 snd_soc_component_update_bits(component, WCD9335_CPE_SS_MAD_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309278 0x02, 0x02);
9279 /* Turn off MAD clk */
Meng Wang15c825d2018-09-06 10:49:18 +08009280 snd_soc_component_update_bits(component, WCD9335_CPE_SS_MAD_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309281 0x01, 0x00);
9282 break;
9283 }
9284
9285 return ret;
9286}
9287
9288static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w,
9289 struct snd_kcontrol *kcontrol, int event)
9290{
Meng Wang15c825d2018-09-06 10:49:18 +08009291 struct snd_soc_component *component =
9292 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309293
Meng Wang15c825d2018-09-06 10:49:18 +08009294 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309295 "%s: event = %d\n", __func__, event);
9296
9297 switch (event) {
9298 case SND_SOC_DAPM_PRE_PMU:
9299 /* Configure CPE input as DEC1 */
Meng Wang15c825d2018-09-06 10:49:18 +08009300 snd_soc_component_update_bits(component, WCD9335_CPE_SS_SVA_CFG,
9301 0x01, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309302
9303 /* Configure DEC1 Tx out with sample rate as 16K */
Meng Wang15c825d2018-09-06 10:49:18 +08009304 snd_soc_component_update_bits(component,
9305 WCD9335_CDC_TX1_TX_PATH_CTL,
9306 0x0F, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309307
9308 break;
9309 case SND_SOC_DAPM_POST_PMD:
9310 /* Reset DEC1 Tx out sample rate */
Meng Wang15c825d2018-09-06 10:49:18 +08009311 snd_soc_component_update_bits(component,
9312 WCD9335_CDC_TX1_TX_PATH_CTL,
9313 0x0F, 0x04);
9314 snd_soc_component_update_bits(component, WCD9335_CPE_SS_SVA_CFG,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309315 0x01, 0x00);
9316
9317 break;
9318 }
9319
9320 return 0;
9321}
9322
9323
9324static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol,
9325 struct snd_ctl_elem_value *ucontrol)
9326{
Asish Bhattacharya34504582017-08-08 12:55:01 +05309327 struct snd_soc_dapm_widget *widget =
9328 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08009329 struct snd_soc_component *component =
9330 snd_soc_dapm_to_component(widget->dapm);
9331 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309332
9333 if (test_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask))
9334 ucontrol->value.integer.value[0] = 1;
9335 else
9336 ucontrol->value.integer.value[0] = 0;
9337
Meng Wang15c825d2018-09-06 10:49:18 +08009338 dev_dbg(component->dev, "%s: AIF4 switch value = %ld\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309339 __func__, ucontrol->value.integer.value[0]);
9340 return 0;
9341}
9342
9343static int tasha_codec_aif4_mixer_switch_put(struct snd_kcontrol *kcontrol,
9344 struct snd_ctl_elem_value *ucontrol)
9345{
Asish Bhattacharya34504582017-08-08 12:55:01 +05309346 struct snd_soc_dapm_widget *widget =
9347 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309348 struct snd_soc_dapm_update *update = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +08009349 struct snd_soc_component *component =
9350 snd_soc_dapm_to_component(widget->dapm);
9351 struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309352
Meng Wang15c825d2018-09-06 10:49:18 +08009353 dev_dbg(component->dev, "%s: AIF4 switch value = %ld\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309354 __func__, ucontrol->value.integer.value[0]);
9355
9356 if (ucontrol->value.integer.value[0]) {
9357 snd_soc_dapm_mixer_update_power(widget->dapm,
9358 kcontrol, 1, update);
9359 set_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9360 } else {
9361 snd_soc_dapm_mixer_update_power(widget->dapm,
9362 kcontrol, 0, update);
9363 clear_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9364 }
9365
9366 return 1;
9367}
9368
9369static const char * const tasha_ear_pa_gain_text[] = {
9370 "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB",
9371 "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB"
9372};
9373
9374static const char * const tasha_ear_spkr_pa_gain_text[] = {
9375 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", "G_4_DB",
9376 "G_5_DB", "G_6_DB"
9377};
9378
Xiaojun Sang24daae82017-09-22 16:50:24 +08009379static const char * const tasha_speaker_boost_stage_text[] = {
9380 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
9381};
9382
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309383static const struct soc_enum tasha_ear_pa_gain_enum =
9384 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_pa_gain_text),
9385 tasha_ear_pa_gain_text);
9386
9387static const struct soc_enum tasha_ear_spkr_pa_gain_enum =
9388 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_spkr_pa_gain_text),
9389 tasha_ear_spkr_pa_gain_text);
9390
Xiaojun Sang24daae82017-09-22 16:50:24 +08009391static const struct soc_enum tasha_spkr_boost_stage_enum =
9392 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_speaker_boost_stage_text),
9393 tasha_speaker_boost_stage_text);
9394
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309395static const struct snd_kcontrol_new tasha_analog_gain_controls[] = {
9396 SOC_ENUM_EXT("EAR PA Gain", tasha_ear_pa_gain_enum,
9397 tasha_ear_pa_gain_get, tasha_ear_pa_gain_put),
9398
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309399 SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1,
9400 line_gain),
9401 SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
9402 line_gain),
9403 SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
9404 3, 16, 1, line_gain),
9405 SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
9406 3, 16, 1, line_gain),
9407 SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
9408 line_gain),
9409 SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
9410 line_gain),
9411
9412 SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
9413 analog_gain),
9414 SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0,
9415 analog_gain),
9416 SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0,
9417 analog_gain),
9418 SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0,
9419 analog_gain),
9420 SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0,
9421 analog_gain),
9422 SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0,
9423 analog_gain),
9424};
9425
Laxminath Kasamf2687c92018-06-14 12:44:04 +05309426static const struct snd_kcontrol_new tasha_spkr_wsa_controls[] = {
9427 SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum,
9428 tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put),
9429
9430 SOC_ENUM_EXT("SPKR Left Boost Max State", tasha_spkr_boost_stage_enum,
9431 tasha_spkr_left_boost_stage_get,
9432 tasha_spkr_left_boost_stage_put),
9433
9434 SOC_ENUM_EXT("SPKR Right Boost Max State", tasha_spkr_boost_stage_enum,
9435 tasha_spkr_right_boost_stage_get,
9436 tasha_spkr_right_boost_stage_put),
9437};
9438
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309439static const char * const spl_src0_mux_text[] = {
9440 "ZERO", "SRC_IN_HPHL", "SRC_IN_LO1",
9441};
9442
9443static const char * const spl_src1_mux_text[] = {
9444 "ZERO", "SRC_IN_HPHR", "SRC_IN_LO2",
9445};
9446
9447static const char * const spl_src2_mux_text[] = {
9448 "ZERO", "SRC_IN_LO3", "SRC_IN_SPKRL",
9449};
9450
9451static const char * const spl_src3_mux_text[] = {
9452 "ZERO", "SRC_IN_LO4", "SRC_IN_SPKRR",
9453};
9454
9455static const char * const rx_int0_7_mix_mux_text[] = {
9456 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9457 "RX6", "RX7", "PROXIMITY"
9458};
9459
9460static const char * const rx_int_mix_mux_text[] = {
9461 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9462 "RX6", "RX7"
9463};
9464
9465static const char * const rx_prim_mix_text[] = {
9466 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
9467 "RX3", "RX4", "RX5", "RX6", "RX7"
9468};
9469
9470static const char * const rx_sidetone_mix_text[] = {
9471 "ZERO", "SRC0", "SRC1", "SRC_SUM"
9472};
9473
9474static const char * const sb_tx0_mux_text[] = {
9475 "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192"
9476};
9477
9478static const char * const sb_tx1_mux_text[] = {
9479 "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192"
9480};
9481
9482static const char * const sb_tx2_mux_text[] = {
9483 "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192"
9484};
9485
9486static const char * const sb_tx3_mux_text[] = {
9487 "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192"
9488};
9489
9490static const char * const sb_tx4_mux_text[] = {
9491 "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192"
9492};
9493
9494static const char * const sb_tx5_mux_text[] = {
9495 "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192"
9496};
9497
9498static const char * const sb_tx6_mux_text[] = {
9499 "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192"
9500};
9501
9502static const char * const sb_tx7_mux_text[] = {
9503 "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192"
9504};
9505
9506static const char * const sb_tx8_mux_text[] = {
9507 "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
9508};
9509
9510static const char * const sb_tx9_mux_text[] = {
9511 "ZERO", "DEC7", "DEC7_192"
9512};
9513
9514static const char * const sb_tx10_mux_text[] = {
9515 "ZERO", "DEC6", "DEC6_192"
9516};
9517
9518static const char * const sb_tx11_mux_text[] = {
9519 "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST"
9520};
9521
9522static const char * const sb_tx11_inp1_mux_text[] = {
9523 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4",
9524 "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12"
9525};
9526
9527static const char * const sb_tx13_mux_text[] = {
9528 "ZERO", "DEC5", "DEC5_192"
9529};
9530
9531static const char * const tx13_inp_mux_text[] = {
9532 "CDC_DEC_5", "MAD_BRDCST", "CPE_TX_PP"
9533};
9534
9535static const char * const iir_inp_mux_text[] = {
9536 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6",
9537 "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
9538};
9539
9540static const char * const rx_int_dem_inp_mux_text[] = {
9541 "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
9542};
9543
9544static const char * const rx_int0_interp_mux_text[] = {
9545 "ZERO", "RX INT0 MIX2",
9546};
9547
9548static const char * const rx_int1_interp_mux_text[] = {
9549 "ZERO", "RX INT1 MIX2",
9550};
9551
9552static const char * const rx_int2_interp_mux_text[] = {
9553 "ZERO", "RX INT2 MIX2",
9554};
9555
9556static const char * const rx_int3_interp_mux_text[] = {
9557 "ZERO", "RX INT3 MIX2",
9558};
9559
9560static const char * const rx_int4_interp_mux_text[] = {
9561 "ZERO", "RX INT4 MIX2",
9562};
9563
9564static const char * const rx_int5_interp_mux_text[] = {
9565 "ZERO", "RX INT5 MIX2",
9566};
9567
9568static const char * const rx_int6_interp_mux_text[] = {
9569 "ZERO", "RX INT6 MIX2",
9570};
9571
9572static const char * const rx_int7_interp_mux_text[] = {
9573 "ZERO", "RX INT7 MIX2",
9574};
9575
9576static const char * const rx_int8_interp_mux_text[] = {
9577 "ZERO", "RX INT8 SEC MIX"
9578};
9579
9580static const char * const mad_sel_text[] = {
9581 "SPE", "MSM"
9582};
9583
9584static const char * const adc_mux_text[] = {
9585 "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2"
9586};
9587
9588static const char * const dmic_mux_text[] = {
9589 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9590 "SMIC0", "SMIC1", "SMIC2", "SMIC3"
9591};
9592
9593static const char * const dmic_mux_alt_text[] = {
9594 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9595};
9596
9597static const char * const amic_mux_text[] = {
9598 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6"
9599};
9600
9601static const char * const rx_echo_mux_text[] = {
9602 "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2", "RX_MIX3", "RX_MIX4",
9603 "RX_MIX5", "RX_MIX6", "RX_MIX7", "RX_MIX8", "RX_MIX_VBAT5",
9604 "RX_MIX_VBAT6", "RX_MIX_VBAT7", "RX_MIX_VBAT8"
9605};
9606
9607static const char * const anc0_fb_mux_text[] = {
9608 "ZERO", "ANC_IN_HPHL", "ANC_IN_EAR", "ANC_IN_EAR_SPKR",
9609 "ANC_IN_LO1"
9610};
9611
9612static const char * const anc1_fb_mux_text[] = {
9613 "ZERO", "ANC_IN_HPHR", "ANC_IN_LO2"
9614};
9615
9616static const char * const native_mux_text[] = {
9617 "OFF", "ON",
9618};
9619
9620static const struct soc_enum spl_src0_mux_chain_enum =
9621 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 0, 3,
9622 spl_src0_mux_text);
9623
9624static const struct soc_enum spl_src1_mux_chain_enum =
9625 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 2, 3,
9626 spl_src1_mux_text);
9627
9628static const struct soc_enum spl_src2_mux_chain_enum =
9629 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 4, 3,
9630 spl_src2_mux_text);
9631
9632static const struct soc_enum spl_src3_mux_chain_enum =
9633 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 6, 3,
9634 spl_src3_mux_text);
9635
9636static const struct soc_enum rx_int0_2_mux_chain_enum =
9637 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10,
9638 rx_int0_7_mix_mux_text);
9639
9640static const struct soc_enum rx_int1_2_mux_chain_enum =
9641 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9,
9642 rx_int_mix_mux_text);
9643
9644static const struct soc_enum rx_int2_2_mux_chain_enum =
9645 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9,
9646 rx_int_mix_mux_text);
9647
9648static const struct soc_enum rx_int3_2_mux_chain_enum =
9649 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9,
9650 rx_int_mix_mux_text);
9651
9652static const struct soc_enum rx_int4_2_mux_chain_enum =
9653 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9,
9654 rx_int_mix_mux_text);
9655
9656static const struct soc_enum rx_int5_2_mux_chain_enum =
9657 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9,
9658 rx_int_mix_mux_text);
9659
9660static const struct soc_enum rx_int6_2_mux_chain_enum =
9661 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9,
9662 rx_int_mix_mux_text);
9663
9664static const struct soc_enum rx_int7_2_mux_chain_enum =
9665 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10,
9666 rx_int0_7_mix_mux_text);
9667
9668static const struct soc_enum rx_int8_2_mux_chain_enum =
9669 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9,
9670 rx_int_mix_mux_text);
9671
9672static const struct soc_enum int1_1_native_enum =
9673 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9674 native_mux_text);
9675
9676static const struct soc_enum int2_1_native_enum =
9677 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9678 native_mux_text);
9679
9680static const struct soc_enum int3_1_native_enum =
9681 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9682 native_mux_text);
9683
9684static const struct soc_enum int4_1_native_enum =
9685 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9686 native_mux_text);
9687
9688static const struct soc_enum rx_int0_1_mix_inp0_chain_enum =
9689 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13,
9690 rx_prim_mix_text);
9691
9692static const struct soc_enum rx_int0_1_mix_inp1_chain_enum =
9693 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13,
9694 rx_prim_mix_text);
9695
9696static const struct soc_enum rx_int0_1_mix_inp2_chain_enum =
9697 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13,
9698 rx_prim_mix_text);
9699
9700static const struct soc_enum rx_int1_1_mix_inp0_chain_enum =
9701 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13,
9702 rx_prim_mix_text);
9703
9704static const struct soc_enum rx_int1_1_mix_inp1_chain_enum =
9705 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13,
9706 rx_prim_mix_text);
9707
9708static const struct soc_enum rx_int1_1_mix_inp2_chain_enum =
9709 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13,
9710 rx_prim_mix_text);
9711
9712static const struct soc_enum rx_int2_1_mix_inp0_chain_enum =
9713 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13,
9714 rx_prim_mix_text);
9715
9716static const struct soc_enum rx_int2_1_mix_inp1_chain_enum =
9717 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13,
9718 rx_prim_mix_text);
9719
9720static const struct soc_enum rx_int2_1_mix_inp2_chain_enum =
9721 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13,
9722 rx_prim_mix_text);
9723
9724static const struct soc_enum rx_int3_1_mix_inp0_chain_enum =
9725 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13,
9726 rx_prim_mix_text);
9727
9728static const struct soc_enum rx_int3_1_mix_inp1_chain_enum =
9729 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13,
9730 rx_prim_mix_text);
9731
9732static const struct soc_enum rx_int3_1_mix_inp2_chain_enum =
9733 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13,
9734 rx_prim_mix_text);
9735
9736static const struct soc_enum rx_int4_1_mix_inp0_chain_enum =
9737 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13,
9738 rx_prim_mix_text);
9739
9740static const struct soc_enum rx_int4_1_mix_inp1_chain_enum =
9741 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13,
9742 rx_prim_mix_text);
9743
9744static const struct soc_enum rx_int4_1_mix_inp2_chain_enum =
9745 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13,
9746 rx_prim_mix_text);
9747
9748static const struct soc_enum rx_int5_1_mix_inp0_chain_enum =
9749 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13,
9750 rx_prim_mix_text);
9751
9752static const struct soc_enum rx_int5_1_mix_inp1_chain_enum =
9753 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13,
9754 rx_prim_mix_text);
9755
9756static const struct soc_enum rx_int5_1_mix_inp2_chain_enum =
9757 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13,
9758 rx_prim_mix_text);
9759
9760static const struct soc_enum rx_int6_1_mix_inp0_chain_enum =
9761 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13,
9762 rx_prim_mix_text);
9763
9764static const struct soc_enum rx_int6_1_mix_inp1_chain_enum =
9765 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13,
9766 rx_prim_mix_text);
9767
9768static const struct soc_enum rx_int6_1_mix_inp2_chain_enum =
9769 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13,
9770 rx_prim_mix_text);
9771
9772static const struct soc_enum rx_int7_1_mix_inp0_chain_enum =
9773 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13,
9774 rx_prim_mix_text);
9775
9776static const struct soc_enum rx_int7_1_mix_inp1_chain_enum =
9777 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13,
9778 rx_prim_mix_text);
9779
9780static const struct soc_enum rx_int7_1_mix_inp2_chain_enum =
9781 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13,
9782 rx_prim_mix_text);
9783
9784static const struct soc_enum rx_int8_1_mix_inp0_chain_enum =
9785 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13,
9786 rx_prim_mix_text);
9787
9788static const struct soc_enum rx_int8_1_mix_inp1_chain_enum =
9789 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13,
9790 rx_prim_mix_text);
9791
9792static const struct soc_enum rx_int8_1_mix_inp2_chain_enum =
9793 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13,
9794 rx_prim_mix_text);
9795
9796static const struct soc_enum rx_int0_sidetone_mix_chain_enum =
9797 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, 4,
9798 rx_sidetone_mix_text);
9799
9800static const struct soc_enum rx_int1_sidetone_mix_chain_enum =
9801 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 4,
9802 rx_sidetone_mix_text);
9803
9804static const struct soc_enum rx_int2_sidetone_mix_chain_enum =
9805 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, 4,
9806 rx_sidetone_mix_text);
9807
9808static const struct soc_enum rx_int3_sidetone_mix_chain_enum =
9809 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, 4,
9810 rx_sidetone_mix_text);
9811
9812static const struct soc_enum rx_int4_sidetone_mix_chain_enum =
9813 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0, 4,
9814 rx_sidetone_mix_text);
9815
9816static const struct soc_enum rx_int7_sidetone_mix_chain_enum =
9817 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, 4,
9818 rx_sidetone_mix_text);
9819
9820static const struct soc_enum tx_adc_mux0_chain_enum =
9821 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4,
9822 adc_mux_text);
9823
9824static const struct soc_enum tx_adc_mux1_chain_enum =
9825 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4,
9826 adc_mux_text);
9827
9828static const struct soc_enum tx_adc_mux2_chain_enum =
9829 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4,
9830 adc_mux_text);
9831
9832static const struct soc_enum tx_adc_mux3_chain_enum =
9833 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4,
9834 adc_mux_text);
9835
9836static const struct soc_enum tx_adc_mux4_chain_enum =
9837 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4,
9838 adc_mux_text);
9839
9840static const struct soc_enum tx_adc_mux5_chain_enum =
9841 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4,
9842 adc_mux_text);
9843
9844static const struct soc_enum tx_adc_mux6_chain_enum =
9845 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4,
9846 adc_mux_text);
9847
9848static const struct soc_enum tx_adc_mux7_chain_enum =
9849 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4,
9850 adc_mux_text);
9851
9852static const struct soc_enum tx_adc_mux8_chain_enum =
9853 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4,
9854 adc_mux_text);
9855
9856static const struct soc_enum tx_adc_mux10_chain_enum =
9857 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 6, 4,
9858 adc_mux_text);
9859
9860static const struct soc_enum tx_adc_mux11_chain_enum =
9861 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 6, 4,
9862 adc_mux_text);
9863
9864static const struct soc_enum tx_adc_mux12_chain_enum =
9865 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 6, 4,
9866 adc_mux_text);
9867
9868static const struct soc_enum tx_adc_mux13_chain_enum =
9869 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 6, 4,
9870 adc_mux_text);
9871
9872static const struct soc_enum tx_dmic_mux0_enum =
9873 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11,
9874 dmic_mux_text);
9875
9876static const struct soc_enum tx_dmic_mux1_enum =
9877 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11,
9878 dmic_mux_text);
9879
9880static const struct soc_enum tx_dmic_mux2_enum =
9881 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11,
9882 dmic_mux_text);
9883
9884static const struct soc_enum tx_dmic_mux3_enum =
9885 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11,
9886 dmic_mux_text);
9887
9888static const struct soc_enum tx_dmic_mux4_enum =
9889 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7,
9890 dmic_mux_alt_text);
9891
9892static const struct soc_enum tx_dmic_mux5_enum =
9893 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7,
9894 dmic_mux_alt_text);
9895
9896static const struct soc_enum tx_dmic_mux6_enum =
9897 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7,
9898 dmic_mux_alt_text);
9899
9900static const struct soc_enum tx_dmic_mux7_enum =
9901 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7,
9902 dmic_mux_alt_text);
9903
9904static const struct soc_enum tx_dmic_mux8_enum =
9905 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7,
9906 dmic_mux_alt_text);
9907
9908static const struct soc_enum tx_dmic_mux10_enum =
9909 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, 7,
9910 dmic_mux_alt_text);
9911
9912static const struct soc_enum tx_dmic_mux11_enum =
9913 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, 7,
9914 dmic_mux_alt_text);
9915
9916static const struct soc_enum tx_dmic_mux12_enum =
9917 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 3, 7,
9918 dmic_mux_alt_text);
9919
9920static const struct soc_enum tx_dmic_mux13_enum =
9921 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 3, 7,
9922 dmic_mux_alt_text);
9923
9924static const struct soc_enum tx_amic_mux0_enum =
9925 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7,
9926 amic_mux_text);
9927
9928static const struct soc_enum tx_amic_mux1_enum =
9929 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7,
9930 amic_mux_text);
9931
9932static const struct soc_enum tx_amic_mux2_enum =
9933 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7,
9934 amic_mux_text);
9935
9936static const struct soc_enum tx_amic_mux3_enum =
9937 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7,
9938 amic_mux_text);
9939
9940static const struct soc_enum tx_amic_mux4_enum =
9941 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7,
9942 amic_mux_text);
9943
9944static const struct soc_enum tx_amic_mux5_enum =
9945 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7,
9946 amic_mux_text);
9947
9948static const struct soc_enum tx_amic_mux6_enum =
9949 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7,
9950 amic_mux_text);
9951
9952static const struct soc_enum tx_amic_mux7_enum =
9953 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7,
9954 amic_mux_text);
9955
9956static const struct soc_enum tx_amic_mux8_enum =
9957 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7,
9958 amic_mux_text);
9959
9960static const struct soc_enum tx_amic_mux10_enum =
9961 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, 7,
9962 amic_mux_text);
9963
9964static const struct soc_enum tx_amic_mux11_enum =
9965 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, 7,
9966 amic_mux_text);
9967
9968static const struct soc_enum tx_amic_mux12_enum =
9969 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, 7,
9970 amic_mux_text);
9971
9972static const struct soc_enum tx_amic_mux13_enum =
9973 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, 7,
9974 amic_mux_text);
9975
9976static const struct soc_enum sb_tx0_mux_enum =
9977 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4,
9978 sb_tx0_mux_text);
9979
9980static const struct soc_enum sb_tx1_mux_enum =
9981 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4,
9982 sb_tx1_mux_text);
9983
9984static const struct soc_enum sb_tx2_mux_enum =
9985 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4,
9986 sb_tx2_mux_text);
9987
9988static const struct soc_enum sb_tx3_mux_enum =
9989 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4,
9990 sb_tx3_mux_text);
9991
9992static const struct soc_enum sb_tx4_mux_enum =
9993 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4,
9994 sb_tx4_mux_text);
9995
9996static const struct soc_enum sb_tx5_mux_enum =
9997 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4,
9998 sb_tx5_mux_text);
9999
10000static const struct soc_enum sb_tx6_mux_enum =
10001 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4,
10002 sb_tx6_mux_text);
10003
10004static const struct soc_enum sb_tx7_mux_enum =
10005 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4,
10006 sb_tx7_mux_text);
10007
10008static const struct soc_enum sb_tx8_mux_enum =
10009 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4,
10010 sb_tx8_mux_text);
10011
10012static const struct soc_enum sb_tx9_mux_enum =
10013 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 2, 3,
10014 sb_tx9_mux_text);
10015
10016static const struct soc_enum sb_tx10_mux_enum =
10017 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 4, 3,
10018 sb_tx10_mux_text);
10019
10020static const struct soc_enum sb_tx11_mux_enum =
10021 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG, 0, 4,
10022 sb_tx11_mux_text);
10023
10024static const struct soc_enum sb_tx11_inp1_mux_enum =
10025 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 0, 10,
10026 sb_tx11_inp1_mux_text);
10027
10028static const struct soc_enum sb_tx13_mux_enum =
10029 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 4, 3,
10030 sb_tx13_mux_text);
10031
10032static const struct soc_enum tx13_inp_mux_enum =
10033 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0, 3,
10034 tx13_inp_mux_text);
10035
10036static const struct soc_enum rx_mix_tx0_mux_enum =
10037 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, 14,
10038 rx_echo_mux_text);
10039
10040static const struct soc_enum rx_mix_tx1_mux_enum =
10041 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, 14,
10042 rx_echo_mux_text);
10043
10044static const struct soc_enum rx_mix_tx2_mux_enum =
10045 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, 14,
10046 rx_echo_mux_text);
10047
10048static const struct soc_enum rx_mix_tx3_mux_enum =
10049 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, 14,
10050 rx_echo_mux_text);
10051
10052static const struct soc_enum rx_mix_tx4_mux_enum =
10053 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, 14,
10054 rx_echo_mux_text);
10055
10056static const struct soc_enum rx_mix_tx5_mux_enum =
10057 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, 14,
10058 rx_echo_mux_text);
10059
10060static const struct soc_enum rx_mix_tx6_mux_enum =
10061 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, 14,
10062 rx_echo_mux_text);
10063
10064static const struct soc_enum rx_mix_tx7_mux_enum =
10065 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, 14,
10066 rx_echo_mux_text);
10067
10068static const struct soc_enum rx_mix_tx8_mux_enum =
10069 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 14,
10070 rx_echo_mux_text);
10071
10072static const struct soc_enum iir0_inp0_mux_enum =
10073 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, 18,
10074 iir_inp_mux_text);
10075
10076static const struct soc_enum iir0_inp1_mux_enum =
10077 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, 18,
10078 iir_inp_mux_text);
10079
10080static const struct soc_enum iir0_inp2_mux_enum =
10081 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, 18,
10082 iir_inp_mux_text);
10083
10084static const struct soc_enum iir0_inp3_mux_enum =
10085 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, 18,
10086 iir_inp_mux_text);
10087
10088static const struct soc_enum iir1_inp0_mux_enum =
10089 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0, 18,
10090 iir_inp_mux_text);
10091
10092static const struct soc_enum iir1_inp1_mux_enum =
10093 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0, 18,
10094 iir_inp_mux_text);
10095
10096static const struct soc_enum iir1_inp2_mux_enum =
10097 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0, 18,
10098 iir_inp_mux_text);
10099
10100static const struct soc_enum iir1_inp3_mux_enum =
10101 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0, 18,
10102 iir_inp_mux_text);
10103
10104static const struct soc_enum rx_int0_dem_inp_mux_enum =
10105 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0,
10106 ARRAY_SIZE(rx_int_dem_inp_mux_text),
10107 rx_int_dem_inp_mux_text);
10108
10109static const struct soc_enum rx_int1_dem_inp_mux_enum =
10110 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0,
10111 ARRAY_SIZE(rx_int_dem_inp_mux_text),
10112 rx_int_dem_inp_mux_text);
10113
10114static const struct soc_enum rx_int2_dem_inp_mux_enum =
10115 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0,
10116 ARRAY_SIZE(rx_int_dem_inp_mux_text),
10117 rx_int_dem_inp_mux_text);
10118
10119static const struct soc_enum rx_int0_interp_mux_enum =
10120 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2,
10121 rx_int0_interp_mux_text);
10122
10123static const struct soc_enum rx_int1_interp_mux_enum =
10124 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2,
10125 rx_int1_interp_mux_text);
10126
10127static const struct soc_enum rx_int2_interp_mux_enum =
10128 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2,
10129 rx_int2_interp_mux_text);
10130
10131static const struct soc_enum rx_int3_interp_mux_enum =
10132 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2,
10133 rx_int3_interp_mux_text);
10134
10135static const struct soc_enum rx_int4_interp_mux_enum =
10136 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2,
10137 rx_int4_interp_mux_text);
10138
10139static const struct soc_enum rx_int5_interp_mux_enum =
10140 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2,
10141 rx_int5_interp_mux_text);
10142
10143static const struct soc_enum rx_int6_interp_mux_enum =
10144 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2,
10145 rx_int6_interp_mux_text);
10146
10147static const struct soc_enum rx_int7_interp_mux_enum =
10148 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2,
10149 rx_int7_interp_mux_text);
10150
10151static const struct soc_enum rx_int8_interp_mux_enum =
10152 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2,
10153 rx_int8_interp_mux_text);
10154
10155static const struct soc_enum mad_sel_enum =
10156 SOC_ENUM_SINGLE(WCD9335_CPE_SS_CFG, 0, 2, mad_sel_text);
10157
10158static const struct soc_enum anc0_fb_mux_enum =
10159 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 0, 5,
10160 anc0_fb_mux_text);
10161
10162static const struct soc_enum anc1_fb_mux_enum =
10163 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 3, 3,
10164 anc1_fb_mux_text);
10165
10166static const struct snd_kcontrol_new rx_int0_dem_inp_mux =
10167 SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum,
10168 snd_soc_dapm_get_enum_double,
10169 tasha_int_dem_inp_mux_put);
10170
10171static const struct snd_kcontrol_new rx_int1_dem_inp_mux =
10172 SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum,
10173 snd_soc_dapm_get_enum_double,
10174 tasha_int_dem_inp_mux_put);
10175
10176static const struct snd_kcontrol_new rx_int2_dem_inp_mux =
10177 SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum,
10178 snd_soc_dapm_get_enum_double,
10179 tasha_int_dem_inp_mux_put);
10180
10181static const struct snd_kcontrol_new spl_src0_mux =
10182 SOC_DAPM_ENUM("SPL SRC0 MUX Mux", spl_src0_mux_chain_enum);
10183
10184static const struct snd_kcontrol_new spl_src1_mux =
10185 SOC_DAPM_ENUM("SPL SRC1 MUX Mux", spl_src1_mux_chain_enum);
10186
10187static const struct snd_kcontrol_new spl_src2_mux =
10188 SOC_DAPM_ENUM("SPL SRC2 MUX Mux", spl_src2_mux_chain_enum);
10189
10190static const struct snd_kcontrol_new spl_src3_mux =
10191 SOC_DAPM_ENUM("SPL SRC3 MUX Mux", spl_src3_mux_chain_enum);
10192
10193static const struct snd_kcontrol_new rx_int0_2_mux =
10194 SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum);
10195
10196static const struct snd_kcontrol_new rx_int1_2_mux =
10197 SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum);
10198
10199static const struct snd_kcontrol_new rx_int2_2_mux =
10200 SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum);
10201
10202static const struct snd_kcontrol_new rx_int3_2_mux =
10203 SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum);
10204
10205static const struct snd_kcontrol_new rx_int4_2_mux =
10206 SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum);
10207
10208static const struct snd_kcontrol_new rx_int5_2_mux =
10209 SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum);
10210
10211static const struct snd_kcontrol_new rx_int6_2_mux =
10212 SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum);
10213
10214static const struct snd_kcontrol_new rx_int7_2_mux =
10215 SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum);
10216
10217static const struct snd_kcontrol_new rx_int8_2_mux =
10218 SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum);
10219
10220static const struct snd_kcontrol_new int1_1_native_mux =
10221 SOC_DAPM_ENUM("RX INT1_1 NATIVE MUX Mux", int1_1_native_enum);
10222
10223static const struct snd_kcontrol_new int2_1_native_mux =
10224 SOC_DAPM_ENUM("RX INT2_1 NATIVE MUX Mux", int2_1_native_enum);
10225
10226static const struct snd_kcontrol_new int3_1_native_mux =
10227 SOC_DAPM_ENUM("RX INT3_1 NATIVE MUX Mux", int3_1_native_enum);
10228
10229static const struct snd_kcontrol_new int4_1_native_mux =
10230 SOC_DAPM_ENUM("RX INT4_1 NATIVE MUX Mux", int4_1_native_enum);
10231
10232static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux =
10233 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum);
10234
10235static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux =
10236 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum);
10237
10238static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux =
10239 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum);
10240
10241static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux =
10242 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum);
10243
10244static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux =
10245 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum);
10246
10247static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux =
10248 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum);
10249
10250static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux =
10251 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum);
10252
10253static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux =
10254 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum);
10255
10256static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux =
10257 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum);
10258
10259static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux =
10260 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum);
10261
10262static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux =
10263 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum);
10264
10265static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux =
10266 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum);
10267
10268static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux =
10269 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum);
10270
10271static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux =
10272 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum);
10273
10274static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux =
10275 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum);
10276
10277static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux =
10278 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum);
10279
10280static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux =
10281 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum);
10282
10283static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux =
10284 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum);
10285
10286static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux =
10287 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum);
10288
10289static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux =
10290 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum);
10291
10292static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux =
10293 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum);
10294
10295static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux =
10296 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum);
10297
10298static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux =
10299 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum);
10300
10301static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux =
10302 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum);
10303
10304static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux =
10305 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum);
10306
10307static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux =
10308 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum);
10309
10310static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux =
10311 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum);
10312
10313static const struct snd_kcontrol_new rx_int0_mix2_inp_mux =
10314 SOC_DAPM_ENUM("RX INT0 MIX2 INP Mux", rx_int0_sidetone_mix_chain_enum);
10315
10316static const struct snd_kcontrol_new rx_int1_mix2_inp_mux =
10317 SOC_DAPM_ENUM("RX INT1 MIX2 INP Mux", rx_int1_sidetone_mix_chain_enum);
10318
10319static const struct snd_kcontrol_new rx_int2_mix2_inp_mux =
10320 SOC_DAPM_ENUM("RX INT2 MIX2 INP Mux", rx_int2_sidetone_mix_chain_enum);
10321
10322static const struct snd_kcontrol_new rx_int3_mix2_inp_mux =
10323 SOC_DAPM_ENUM("RX INT3 MIX2 INP Mux", rx_int3_sidetone_mix_chain_enum);
10324
10325static const struct snd_kcontrol_new rx_int4_mix2_inp_mux =
10326 SOC_DAPM_ENUM("RX INT4 MIX2 INP Mux", rx_int4_sidetone_mix_chain_enum);
10327
10328static const struct snd_kcontrol_new rx_int7_mix2_inp_mux =
10329 SOC_DAPM_ENUM("RX INT7 MIX2 INP Mux", rx_int7_sidetone_mix_chain_enum);
10330
10331static const struct snd_kcontrol_new tx_adc_mux0 =
10332 SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum,
10333 snd_soc_dapm_get_enum_double,
10334 tasha_put_dec_enum);
10335
10336static const struct snd_kcontrol_new tx_adc_mux1 =
10337 SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum,
10338 snd_soc_dapm_get_enum_double,
10339 tasha_put_dec_enum);
10340
10341static const struct snd_kcontrol_new tx_adc_mux2 =
10342 SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum,
10343 snd_soc_dapm_get_enum_double,
10344 tasha_put_dec_enum);
10345
10346static const struct snd_kcontrol_new tx_adc_mux3 =
10347 SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum,
10348 snd_soc_dapm_get_enum_double,
10349 tasha_put_dec_enum);
10350
10351static const struct snd_kcontrol_new tx_adc_mux4 =
10352 SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum,
10353 snd_soc_dapm_get_enum_double,
10354 tasha_put_dec_enum);
10355
10356static const struct snd_kcontrol_new tx_adc_mux5 =
10357 SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum,
10358 snd_soc_dapm_get_enum_double,
10359 tasha_put_dec_enum);
10360
10361static const struct snd_kcontrol_new tx_adc_mux6 =
10362 SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum,
10363 snd_soc_dapm_get_enum_double,
10364 tasha_put_dec_enum);
10365
10366static const struct snd_kcontrol_new tx_adc_mux7 =
10367 SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum,
10368 snd_soc_dapm_get_enum_double,
10369 tasha_put_dec_enum);
10370
10371static const struct snd_kcontrol_new tx_adc_mux8 =
10372 SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum,
10373 snd_soc_dapm_get_enum_double,
10374 tasha_put_dec_enum);
10375
10376static const struct snd_kcontrol_new tx_adc_mux10 =
10377 SOC_DAPM_ENUM("ADC MUX10 Mux", tx_adc_mux10_chain_enum);
10378
10379static const struct snd_kcontrol_new tx_adc_mux11 =
10380 SOC_DAPM_ENUM("ADC MUX11 Mux", tx_adc_mux11_chain_enum);
10381
10382static const struct snd_kcontrol_new tx_adc_mux12 =
10383 SOC_DAPM_ENUM("ADC MUX12 Mux", tx_adc_mux12_chain_enum);
10384
10385static const struct snd_kcontrol_new tx_adc_mux13 =
10386 SOC_DAPM_ENUM("ADC MUX13 Mux", tx_adc_mux13_chain_enum);
10387
10388static const struct snd_kcontrol_new tx_dmic_mux0 =
10389 SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum);
10390
10391static const struct snd_kcontrol_new tx_dmic_mux1 =
10392 SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum);
10393
10394static const struct snd_kcontrol_new tx_dmic_mux2 =
10395 SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum);
10396
10397static const struct snd_kcontrol_new tx_dmic_mux3 =
10398 SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum);
10399
10400static const struct snd_kcontrol_new tx_dmic_mux4 =
10401 SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum);
10402
10403static const struct snd_kcontrol_new tx_dmic_mux5 =
10404 SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum);
10405
10406static const struct snd_kcontrol_new tx_dmic_mux6 =
10407 SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum);
10408
10409static const struct snd_kcontrol_new tx_dmic_mux7 =
10410 SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum);
10411
10412static const struct snd_kcontrol_new tx_dmic_mux8 =
10413 SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum);
10414
10415static const struct snd_kcontrol_new tx_dmic_mux10 =
10416 SOC_DAPM_ENUM("DMIC MUX10 Mux", tx_dmic_mux10_enum);
10417
10418static const struct snd_kcontrol_new tx_dmic_mux11 =
10419 SOC_DAPM_ENUM("DMIC MUX11 Mux", tx_dmic_mux11_enum);
10420
10421static const struct snd_kcontrol_new tx_dmic_mux12 =
10422 SOC_DAPM_ENUM("DMIC MUX12 Mux", tx_dmic_mux12_enum);
10423
10424static const struct snd_kcontrol_new tx_dmic_mux13 =
10425 SOC_DAPM_ENUM("DMIC MUX13 Mux", tx_dmic_mux13_enum);
10426
10427static const struct snd_kcontrol_new tx_amic_mux0 =
10428 SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum);
10429
10430static const struct snd_kcontrol_new tx_amic_mux1 =
10431 SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum);
10432
10433static const struct snd_kcontrol_new tx_amic_mux2 =
10434 SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum);
10435
10436static const struct snd_kcontrol_new tx_amic_mux3 =
10437 SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum);
10438
10439static const struct snd_kcontrol_new tx_amic_mux4 =
10440 SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum);
10441
10442static const struct snd_kcontrol_new tx_amic_mux5 =
10443 SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum);
10444
10445static const struct snd_kcontrol_new tx_amic_mux6 =
10446 SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum);
10447
10448static const struct snd_kcontrol_new tx_amic_mux7 =
10449 SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum);
10450
10451static const struct snd_kcontrol_new tx_amic_mux8 =
10452 SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum);
10453
10454static const struct snd_kcontrol_new tx_amic_mux10 =
10455 SOC_DAPM_ENUM("AMIC MUX10 Mux", tx_amic_mux10_enum);
10456
10457static const struct snd_kcontrol_new tx_amic_mux11 =
10458 SOC_DAPM_ENUM("AMIC MUX11 Mux", tx_amic_mux11_enum);
10459
10460static const struct snd_kcontrol_new tx_amic_mux12 =
10461 SOC_DAPM_ENUM("AMIC MUX12 Mux", tx_amic_mux12_enum);
10462
10463static const struct snd_kcontrol_new tx_amic_mux13 =
10464 SOC_DAPM_ENUM("AMIC MUX13 Mux", tx_amic_mux13_enum);
10465
10466static const struct snd_kcontrol_new sb_tx0_mux =
10467 SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum);
10468
10469static const struct snd_kcontrol_new sb_tx1_mux =
10470 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
10471
10472static const struct snd_kcontrol_new sb_tx2_mux =
10473 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
10474
10475static const struct snd_kcontrol_new sb_tx3_mux =
10476 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
10477
10478static const struct snd_kcontrol_new sb_tx4_mux =
10479 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
10480
10481static const struct snd_kcontrol_new sb_tx5_mux =
10482 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
10483
10484static const struct snd_kcontrol_new sb_tx6_mux =
10485 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
10486
10487static const struct snd_kcontrol_new sb_tx7_mux =
10488 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
10489
10490static const struct snd_kcontrol_new sb_tx8_mux =
10491 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
10492
10493static const struct snd_kcontrol_new sb_tx9_mux =
10494 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
10495
10496static const struct snd_kcontrol_new sb_tx10_mux =
10497 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
10498
10499static const struct snd_kcontrol_new sb_tx11_mux =
10500 SOC_DAPM_ENUM("SLIM TX11 MUX Mux", sb_tx11_mux_enum);
10501
10502static const struct snd_kcontrol_new sb_tx11_inp1_mux =
10503 SOC_DAPM_ENUM("SLIM TX11 INP1 MUX Mux", sb_tx11_inp1_mux_enum);
10504
10505static const struct snd_kcontrol_new sb_tx13_mux =
10506 SOC_DAPM_ENUM("SLIM TX13 MUX Mux", sb_tx13_mux_enum);
10507
10508static const struct snd_kcontrol_new tx13_inp_mux =
10509 SOC_DAPM_ENUM("TX13 INP MUX Mux", tx13_inp_mux_enum);
10510
10511static const struct snd_kcontrol_new rx_mix_tx0_mux =
10512 SOC_DAPM_ENUM("RX MIX TX0 MUX Mux", rx_mix_tx0_mux_enum);
10513
10514static const struct snd_kcontrol_new rx_mix_tx1_mux =
10515 SOC_DAPM_ENUM("RX MIX TX1 MUX Mux", rx_mix_tx1_mux_enum);
10516
10517static const struct snd_kcontrol_new rx_mix_tx2_mux =
10518 SOC_DAPM_ENUM("RX MIX TX2 MUX Mux", rx_mix_tx2_mux_enum);
10519
10520static const struct snd_kcontrol_new rx_mix_tx3_mux =
10521 SOC_DAPM_ENUM("RX MIX TX3 MUX Mux", rx_mix_tx3_mux_enum);
10522
10523static const struct snd_kcontrol_new rx_mix_tx4_mux =
10524 SOC_DAPM_ENUM("RX MIX TX4 MUX Mux", rx_mix_tx4_mux_enum);
10525
10526static const struct snd_kcontrol_new rx_mix_tx5_mux =
10527 SOC_DAPM_ENUM("RX MIX TX5 MUX Mux", rx_mix_tx5_mux_enum);
10528
10529static const struct snd_kcontrol_new rx_mix_tx6_mux =
10530 SOC_DAPM_ENUM("RX MIX TX6 MUX Mux", rx_mix_tx6_mux_enum);
10531
10532static const struct snd_kcontrol_new rx_mix_tx7_mux =
10533 SOC_DAPM_ENUM("RX MIX TX7 MUX Mux", rx_mix_tx7_mux_enum);
10534
10535static const struct snd_kcontrol_new rx_mix_tx8_mux =
10536 SOC_DAPM_ENUM("RX MIX TX8 MUX Mux", rx_mix_tx8_mux_enum);
10537
10538static const struct snd_kcontrol_new iir0_inp0_mux =
10539 SOC_DAPM_ENUM("IIR0 INP0 Mux", iir0_inp0_mux_enum);
10540
10541static const struct snd_kcontrol_new iir0_inp1_mux =
10542 SOC_DAPM_ENUM("IIR0 INP1 Mux", iir0_inp1_mux_enum);
10543
10544static const struct snd_kcontrol_new iir0_inp2_mux =
10545 SOC_DAPM_ENUM("IIR0 INP2 Mux", iir0_inp2_mux_enum);
10546
10547static const struct snd_kcontrol_new iir0_inp3_mux =
10548 SOC_DAPM_ENUM("IIR0 INP3 Mux", iir0_inp3_mux_enum);
10549
10550static const struct snd_kcontrol_new iir1_inp0_mux =
10551 SOC_DAPM_ENUM("IIR1 INP0 Mux", iir1_inp0_mux_enum);
10552
10553static const struct snd_kcontrol_new iir1_inp1_mux =
10554 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
10555
10556static const struct snd_kcontrol_new iir1_inp2_mux =
10557 SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
10558
10559static const struct snd_kcontrol_new iir1_inp3_mux =
10560 SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
10561
10562static const struct snd_kcontrol_new rx_int0_interp_mux =
10563 SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum);
10564
10565static const struct snd_kcontrol_new rx_int1_interp_mux =
10566 SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum);
10567
10568static const struct snd_kcontrol_new rx_int2_interp_mux =
10569 SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum);
10570
10571static const struct snd_kcontrol_new rx_int3_interp_mux =
10572 SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum);
10573
10574static const struct snd_kcontrol_new rx_int4_interp_mux =
10575 SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum);
10576
10577static const struct snd_kcontrol_new rx_int5_interp_mux =
10578 SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum);
10579
10580static const struct snd_kcontrol_new rx_int6_interp_mux =
10581 SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum);
10582
10583static const struct snd_kcontrol_new rx_int7_interp_mux =
10584 SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum);
10585
10586static const struct snd_kcontrol_new rx_int8_interp_mux =
10587 SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum);
10588
10589static const struct snd_kcontrol_new mad_sel_mux =
10590 SOC_DAPM_ENUM("MAD_SEL MUX Mux", mad_sel_enum);
10591
10592static const struct snd_kcontrol_new aif4_mad_switch =
10593 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 5, 1, 0);
10594
10595static const struct snd_kcontrol_new mad_brdcst_switch =
10596 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 6, 1, 0);
10597
10598static const struct snd_kcontrol_new aif4_switch_mixer_controls =
10599 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
10600 0, 1, 0, tasha_codec_aif4_mixer_switch_get,
10601 tasha_codec_aif4_mixer_switch_put);
10602
10603static const struct snd_kcontrol_new anc_hphl_switch =
10604 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10605
10606static const struct snd_kcontrol_new anc_hphr_switch =
10607 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10608
10609static const struct snd_kcontrol_new anc_ear_switch =
10610 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10611
10612static const struct snd_kcontrol_new anc_ear_spkr_switch =
10613 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10614
10615static const struct snd_kcontrol_new anc_lineout1_switch =
10616 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10617
10618static const struct snd_kcontrol_new anc_lineout2_switch =
10619 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10620
10621static const struct snd_kcontrol_new anc_spkr_pa_switch =
10622 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10623
10624static const struct snd_kcontrol_new adc_us_mux0_switch =
10625 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10626
10627static const struct snd_kcontrol_new adc_us_mux1_switch =
10628 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10629
10630static const struct snd_kcontrol_new adc_us_mux2_switch =
10631 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10632
10633static const struct snd_kcontrol_new adc_us_mux3_switch =
10634 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10635
10636static const struct snd_kcontrol_new adc_us_mux4_switch =
10637 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10638
10639static const struct snd_kcontrol_new adc_us_mux5_switch =
10640 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10641
10642static const struct snd_kcontrol_new adc_us_mux6_switch =
10643 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10644
10645static const struct snd_kcontrol_new adc_us_mux7_switch =
10646 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10647
10648static const struct snd_kcontrol_new adc_us_mux8_switch =
10649 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10650
10651static const struct snd_kcontrol_new anc0_fb_mux =
10652 SOC_DAPM_ENUM("ANC0 FB MUX Mux", anc0_fb_mux_enum);
10653
10654static const struct snd_kcontrol_new anc1_fb_mux =
10655 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
10656
10657static int tasha_codec_ec_buf_mux_enable(struct snd_soc_dapm_widget *w,
10658 struct snd_kcontrol *kcontrol,
10659 int event)
10660{
Meng Wang15c825d2018-09-06 10:49:18 +080010661 struct snd_soc_component *component =
10662 snd_soc_dapm_to_component(w->dapm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010663
Meng Wang15c825d2018-09-06 10:49:18 +080010664 dev_dbg(component->dev, "%s: event = %d name = %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010665 __func__, event, w->name);
10666
10667 switch (event) {
10668 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +080010669 snd_soc_component_write(component,
10670 WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B);
10671 snd_soc_component_update_bits(component,
10672 WCD9335_CPE_SS_CFG, 0x08, 0x08);
10673 snd_soc_component_update_bits(component,
10674 WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0x08, 0x08);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010675 break;
10676 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +080010677 snd_soc_component_update_bits(component,
10678 WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10679 0x08, 0x00);
10680 snd_soc_component_update_bits(component,
10681 WCD9335_CPE_SS_CFG, 0x08, 0x00);
10682 snd_soc_component_write(component,
10683 WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010684 break;
10685 }
10686
10687 return 0;
10688};
10689
10690static const char * const ec_buf_mux_text[] = {
10691 "ZERO", "RXMIXEC", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3",
10692 "I2S_RX_SD0_L", "I2S_RX_SD0_R", "I2S_RX_SD1_L", "I2S_RX_SD1_R",
10693 "DEC1"
10694};
10695
10696static SOC_ENUM_SINGLE_DECL(ec_buf_mux_enum, WCD9335_CPE_SS_US_EC_MUX_CFG,
10697 0, ec_buf_mux_text);
10698
10699static const struct snd_kcontrol_new ec_buf_mux =
10700 SOC_DAPM_ENUM("EC BUF Mux", ec_buf_mux_enum);
10701
10702static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
10703 SND_SOC_DAPM_OUTPUT("EAR"),
10704 SND_SOC_DAPM_OUTPUT("ANC EAR"),
10705 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
10706 AIF1_PB, 0, tasha_codec_enable_slimrx,
10707 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10708 SND_SOC_DAPM_POST_PMD),
10709 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
10710 AIF2_PB, 0, tasha_codec_enable_slimrx,
10711 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10712 SND_SOC_DAPM_POST_PMD),
10713 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
10714 AIF3_PB, 0, tasha_codec_enable_slimrx,
10715 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10716 SND_SOC_DAPM_POST_PMD),
10717 SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
10718 AIF4_PB, 0, tasha_codec_enable_slimrx,
10719 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10720 SND_SOC_DAPM_POST_PMD),
10721 SND_SOC_DAPM_AIF_IN_E("AIF MIX1 PB", "AIF Mix Playback", 0,
10722 SND_SOC_NOPM, AIF_MIX1_PB, 0,
10723 tasha_codec_enable_slimrx,
10724 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10725 SND_SOC_DAPM_POST_PMD),
10726
10727 SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, TASHA_RX0, 0,
10728 &slim_rx_mux[TASHA_RX0]),
10729 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TASHA_RX1, 0,
10730 &slim_rx_mux[TASHA_RX1]),
10731 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TASHA_RX2, 0,
10732 &slim_rx_mux[TASHA_RX2]),
10733 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TASHA_RX3, 0,
10734 &slim_rx_mux[TASHA_RX3]),
10735 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TASHA_RX4, 0,
10736 &slim_rx_mux[TASHA_RX4]),
10737 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TASHA_RX5, 0,
10738 &slim_rx_mux[TASHA_RX5]),
10739 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TASHA_RX6, 0,
10740 &slim_rx_mux[TASHA_RX6]),
10741 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TASHA_RX7, 0,
10742 &slim_rx_mux[TASHA_RX7]),
10743
10744 SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
10745 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10746 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10747 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
10748 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
10749 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
10750 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
10751 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
10752
10753 SND_SOC_DAPM_MUX_E("SPL SRC0 MUX", SND_SOC_NOPM, SPLINE_SRC0, 0,
10754 &spl_src0_mux, tasha_codec_enable_spline_resampler,
10755 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10756 SND_SOC_DAPM_MUX_E("SPL SRC1 MUX", SND_SOC_NOPM, SPLINE_SRC1, 0,
10757 &spl_src1_mux, tasha_codec_enable_spline_resampler,
10758 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10759 SND_SOC_DAPM_MUX_E("SPL SRC2 MUX", SND_SOC_NOPM, SPLINE_SRC2, 0,
10760 &spl_src2_mux, tasha_codec_enable_spline_resampler,
10761 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10762 SND_SOC_DAPM_MUX_E("SPL SRC3 MUX", SND_SOC_NOPM, SPLINE_SRC3, 0,
10763 &spl_src3_mux, tasha_codec_enable_spline_resampler,
10764 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10765
10766 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
10767 5, 0, &rx_int0_2_mux, tasha_codec_enable_mix_path,
10768 SND_SOC_DAPM_POST_PMU),
10769 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
10770 5, 0, &rx_int1_2_mux, tasha_codec_enable_mix_path,
10771 SND_SOC_DAPM_POST_PMU),
10772 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
10773 5, 0, &rx_int2_2_mux, tasha_codec_enable_mix_path,
10774 SND_SOC_DAPM_POST_PMU),
10775 SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL,
10776 5, 0, &rx_int3_2_mux, tasha_codec_enable_mix_path,
10777 SND_SOC_DAPM_POST_PMU),
10778 SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL,
10779 5, 0, &rx_int4_2_mux, tasha_codec_enable_mix_path,
10780 SND_SOC_DAPM_POST_PMU),
10781 SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL,
10782 5, 0, &rx_int5_2_mux, tasha_codec_enable_mix_path,
10783 SND_SOC_DAPM_POST_PMU),
10784 SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL,
10785 5, 0, &rx_int6_2_mux, tasha_codec_enable_mix_path,
10786 SND_SOC_DAPM_POST_PMU),
10787 SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL,
10788 5, 0, &rx_int7_2_mux, tasha_codec_enable_mix_path,
10789 SND_SOC_DAPM_POST_PMU),
10790 SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL,
10791 5, 0, &rx_int8_2_mux, tasha_codec_enable_mix_path,
10792 SND_SOC_DAPM_POST_PMU),
10793
10794 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10795 &rx_int0_1_mix_inp0_mux),
10796 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10797 &rx_int0_1_mix_inp1_mux),
10798 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10799 &rx_int0_1_mix_inp2_mux),
10800 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10801 &rx_int1_1_mix_inp0_mux),
10802 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10803 &rx_int1_1_mix_inp1_mux),
10804 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10805 &rx_int1_1_mix_inp2_mux),
10806 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10807 &rx_int2_1_mix_inp0_mux),
10808 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10809 &rx_int2_1_mix_inp1_mux),
10810 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10811 &rx_int2_1_mix_inp2_mux),
10812 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10813 &rx_int3_1_mix_inp0_mux),
10814 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10815 &rx_int3_1_mix_inp1_mux),
10816 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10817 &rx_int3_1_mix_inp2_mux),
10818 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10819 &rx_int4_1_mix_inp0_mux),
10820 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10821 &rx_int4_1_mix_inp1_mux),
10822 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10823 &rx_int4_1_mix_inp2_mux),
10824 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10825 &rx_int5_1_mix_inp0_mux),
10826 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10827 &rx_int5_1_mix_inp1_mux),
10828 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10829 &rx_int5_1_mix_inp2_mux),
10830 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10831 &rx_int6_1_mix_inp0_mux),
10832 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10833 &rx_int6_1_mix_inp1_mux),
10834 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10835 &rx_int6_1_mix_inp2_mux),
10836 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10837 &rx_int7_1_mix_inp0_mux, tasha_codec_enable_swr,
10838 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10839 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10840 &rx_int7_1_mix_inp1_mux, tasha_codec_enable_swr,
10841 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10842 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10843 &rx_int7_1_mix_inp2_mux, tasha_codec_enable_swr,
10844 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10845 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10846 &rx_int8_1_mix_inp0_mux, tasha_codec_enable_swr,
10847 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10848 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10849 &rx_int8_1_mix_inp1_mux, tasha_codec_enable_swr,
10850 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10851 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10852 &rx_int8_1_mix_inp2_mux, tasha_codec_enable_swr,
10853 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10854
10855 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10856 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10857 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10858 SND_SOC_DAPM_MIXER("RX INT1 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10859 rx_int1_spline_mix_switch,
10860 ARRAY_SIZE(rx_int1_spline_mix_switch)),
10861 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10862 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10863 SND_SOC_DAPM_MIXER("RX INT2 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10864 rx_int2_spline_mix_switch,
10865 ARRAY_SIZE(rx_int2_spline_mix_switch)),
10866 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10867 SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10868 SND_SOC_DAPM_MIXER("RX INT3 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10869 rx_int3_spline_mix_switch,
10870 ARRAY_SIZE(rx_int3_spline_mix_switch)),
10871 SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10872 SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10873 SND_SOC_DAPM_MIXER("RX INT4 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10874 rx_int4_spline_mix_switch,
10875 ARRAY_SIZE(rx_int4_spline_mix_switch)),
10876 SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10877 SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10878 SND_SOC_DAPM_MIXER("RX INT5 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10879 rx_int5_spline_mix_switch,
10880 ARRAY_SIZE(rx_int5_spline_mix_switch)),
10881 SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10882
10883 SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10884 SND_SOC_DAPM_MIXER("RX INT6 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10885 rx_int6_spline_mix_switch,
10886 ARRAY_SIZE(rx_int6_spline_mix_switch)),
10887 SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10888
10889 SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10890 SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10891 SND_SOC_DAPM_MIXER("RX INT7 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10892 rx_int7_spline_mix_switch,
10893 ARRAY_SIZE(rx_int7_spline_mix_switch)),
10894
10895 SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10896 SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10897 SND_SOC_DAPM_MIXER("RX INT8 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10898 rx_int8_spline_mix_switch,
10899 ARRAY_SIZE(rx_int8_spline_mix_switch)),
10900
10901 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10902 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10903 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10904 SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10905 SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10906 SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10907 SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10908 SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10909 SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0,
10910 NULL, 0, tasha_codec_spk_boost_event,
10911 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10912 SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0,
10913 NULL, 0, tasha_codec_spk_boost_event,
10914 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10915
10916 SND_SOC_DAPM_MIXER_E("RX INT5 VBAT", SND_SOC_NOPM, 0, 0,
10917 rx_int5_vbat_mix_switch,
10918 ARRAY_SIZE(rx_int5_vbat_mix_switch),
10919 tasha_codec_vbat_enable_event,
10920 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10921 SND_SOC_DAPM_MIXER_E("RX INT6 VBAT", SND_SOC_NOPM, 0, 0,
10922 rx_int6_vbat_mix_switch,
10923 ARRAY_SIZE(rx_int6_vbat_mix_switch),
10924 tasha_codec_vbat_enable_event,
10925 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10926 SND_SOC_DAPM_MIXER_E("RX INT7 VBAT", SND_SOC_NOPM, 0, 0,
10927 rx_int7_vbat_mix_switch,
10928 ARRAY_SIZE(rx_int7_vbat_mix_switch),
10929 tasha_codec_vbat_enable_event,
10930 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10931 SND_SOC_DAPM_MIXER_E("RX INT8 VBAT", SND_SOC_NOPM, 0, 0,
10932 rx_int8_vbat_mix_switch,
10933 ARRAY_SIZE(rx_int8_vbat_mix_switch),
10934 tasha_codec_vbat_enable_event,
10935 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10936
10937 SND_SOC_DAPM_MUX("RX INT0 MIX2 INP", WCD9335_CDC_RX0_RX_PATH_CFG1, 4,
10938 0, &rx_int0_mix2_inp_mux),
10939 SND_SOC_DAPM_MUX("RX INT1 MIX2 INP", WCD9335_CDC_RX1_RX_PATH_CFG1, 4,
10940 0, &rx_int1_mix2_inp_mux),
10941 SND_SOC_DAPM_MUX("RX INT2 MIX2 INP", WCD9335_CDC_RX2_RX_PATH_CFG1, 4,
10942 0, &rx_int2_mix2_inp_mux),
10943 SND_SOC_DAPM_MUX("RX INT3 MIX2 INP", WCD9335_CDC_RX3_RX_PATH_CFG1, 4,
10944 0, &rx_int3_mix2_inp_mux),
10945 SND_SOC_DAPM_MUX("RX INT4 MIX2 INP", WCD9335_CDC_RX4_RX_PATH_CFG1, 4,
10946 0, &rx_int4_mix2_inp_mux),
10947 SND_SOC_DAPM_MUX("RX INT7 MIX2 INP", WCD9335_CDC_RX7_RX_PATH_CFG1, 4,
10948 0, &rx_int7_mix2_inp_mux),
10949
10950 SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, TASHA_TX0, 0,
10951 &sb_tx0_mux),
10952 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TASHA_TX1, 0,
10953 &sb_tx1_mux),
10954 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TASHA_TX2, 0,
10955 &sb_tx2_mux),
10956 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TASHA_TX3, 0,
10957 &sb_tx3_mux),
10958 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TASHA_TX4, 0,
10959 &sb_tx4_mux),
10960 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TASHA_TX5, 0,
10961 &sb_tx5_mux),
10962 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TASHA_TX6, 0,
10963 &sb_tx6_mux),
10964 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TASHA_TX7, 0,
10965 &sb_tx7_mux),
10966 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TASHA_TX8, 0,
10967 &sb_tx8_mux),
10968 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TASHA_TX9, 0,
10969 &sb_tx9_mux),
10970 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TASHA_TX10, 0,
10971 &sb_tx10_mux),
10972 SND_SOC_DAPM_MUX("SLIM TX11 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10973 &sb_tx11_mux),
10974 SND_SOC_DAPM_MUX("SLIM TX11 INP1 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10975 &sb_tx11_inp1_mux),
10976 SND_SOC_DAPM_MUX("SLIM TX13 MUX", SND_SOC_NOPM, TASHA_TX13, 0,
10977 &sb_tx13_mux),
10978 SND_SOC_DAPM_MUX("TX13 INP MUX", SND_SOC_NOPM, 0, 0,
10979 &tx13_inp_mux),
10980
10981 SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0,
10982 &tx_adc_mux0, tasha_codec_enable_dec,
10983 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10984 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10985
10986 SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0,
10987 &tx_adc_mux1, tasha_codec_enable_dec,
10988 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10989 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10990
10991 SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0,
10992 &tx_adc_mux2, tasha_codec_enable_dec,
10993 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10994 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10995
10996 SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0,
10997 &tx_adc_mux3, tasha_codec_enable_dec,
10998 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10999 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11000
11001 SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0,
11002 &tx_adc_mux4, tasha_codec_enable_dec,
11003 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11004 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11005
11006 SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0,
11007 &tx_adc_mux5, tasha_codec_enable_dec,
11008 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11009 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11010
11011 SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0,
11012 &tx_adc_mux6, tasha_codec_enable_dec,
11013 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11014 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11015
11016 SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0,
11017 &tx_adc_mux7, tasha_codec_enable_dec,
11018 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11019 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11020
11021 SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0,
11022 &tx_adc_mux8, tasha_codec_enable_dec,
11023 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11024 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11025
11026 SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0,
11027 &tx_adc_mux10, tasha_codec_tx_adc_cfg,
11028 SND_SOC_DAPM_POST_PMU),
11029
11030 SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0,
11031 &tx_adc_mux11, tasha_codec_tx_adc_cfg,
11032 SND_SOC_DAPM_POST_PMU),
11033
11034 SND_SOC_DAPM_MUX_E("ADC MUX12", SND_SOC_NOPM, 12, 0,
11035 &tx_adc_mux12, tasha_codec_tx_adc_cfg,
11036 SND_SOC_DAPM_POST_PMU),
11037
11038 SND_SOC_DAPM_MUX_E("ADC MUX13", SND_SOC_NOPM, 13, 0,
11039 &tx_adc_mux13, tasha_codec_tx_adc_cfg,
11040 SND_SOC_DAPM_POST_PMU),
11041
11042 SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0,
11043 &tx_dmic_mux0),
11044 SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0,
11045 &tx_dmic_mux1),
11046 SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0,
11047 &tx_dmic_mux2),
11048 SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0,
11049 &tx_dmic_mux3),
11050 SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0,
11051 &tx_dmic_mux4),
11052 SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0,
11053 &tx_dmic_mux5),
11054 SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0,
11055 &tx_dmic_mux6),
11056 SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0,
11057 &tx_dmic_mux7),
11058 SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0,
11059 &tx_dmic_mux8),
11060 SND_SOC_DAPM_MUX("DMIC MUX10", SND_SOC_NOPM, 0, 0,
11061 &tx_dmic_mux10),
11062 SND_SOC_DAPM_MUX("DMIC MUX11", SND_SOC_NOPM, 0, 0,
11063 &tx_dmic_mux11),
11064 SND_SOC_DAPM_MUX("DMIC MUX12", SND_SOC_NOPM, 0, 0,
11065 &tx_dmic_mux12),
11066 SND_SOC_DAPM_MUX("DMIC MUX13", SND_SOC_NOPM, 0, 0,
11067 &tx_dmic_mux13),
11068
11069 SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0,
11070 &tx_amic_mux0),
11071 SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0,
11072 &tx_amic_mux1),
11073 SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0,
11074 &tx_amic_mux2),
11075 SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0,
11076 &tx_amic_mux3),
11077 SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0,
11078 &tx_amic_mux4),
11079 SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0,
11080 &tx_amic_mux5),
11081 SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0,
11082 &tx_amic_mux6),
11083 SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0,
11084 &tx_amic_mux7),
11085 SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0,
11086 &tx_amic_mux8),
11087 SND_SOC_DAPM_MUX("AMIC MUX10", SND_SOC_NOPM, 0, 0,
11088 &tx_amic_mux10),
11089 SND_SOC_DAPM_MUX("AMIC MUX11", SND_SOC_NOPM, 0, 0,
11090 &tx_amic_mux11),
11091 SND_SOC_DAPM_MUX("AMIC MUX12", SND_SOC_NOPM, 0, 0,
11092 &tx_amic_mux12),
11093 SND_SOC_DAPM_MUX("AMIC MUX13", SND_SOC_NOPM, 0, 0,
11094 &tx_amic_mux13),
11095
11096 SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0,
11097 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
11098 SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0,
11099 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
11100 SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0,
11101 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
11102 SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0,
11103 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
11104 SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0,
11105 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
11106 SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0,
11107 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
11108
11109 SND_SOC_DAPM_SUPPLY("RX INT1 NATIVE SUPPLY", SND_SOC_NOPM,
11110 INTERP_HPHL, 0, tasha_enable_native_supply,
11111 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
11112
11113 SND_SOC_DAPM_SUPPLY("RX INT2 NATIVE SUPPLY", SND_SOC_NOPM,
11114 INTERP_HPHR, 0, tasha_enable_native_supply,
11115 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
11116
11117 SND_SOC_DAPM_SUPPLY("RX INT3 NATIVE SUPPLY", SND_SOC_NOPM,
11118 INTERP_LO1, 0, tasha_enable_native_supply,
11119 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
11120
11121 SND_SOC_DAPM_SUPPLY("RX INT4 NATIVE SUPPLY", SND_SOC_NOPM,
11122 INTERP_LO2, 0, tasha_enable_native_supply,
11123 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
11124
11125 SND_SOC_DAPM_INPUT("AMIC1"),
11126 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0,
11127 tasha_codec_enable_micbias,
11128 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11129 SND_SOC_DAPM_POST_PMD),
11130 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0,
11131 tasha_codec_enable_micbias,
11132 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11133 SND_SOC_DAPM_POST_PMD),
11134 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0,
11135 tasha_codec_enable_micbias,
11136 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11137 SND_SOC_DAPM_POST_PMD),
11138 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0,
11139 tasha_codec_enable_micbias,
11140 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11141 SND_SOC_DAPM_POST_PMD),
11142
11143 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0,
11144 tasha_codec_force_enable_micbias,
11145 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11146 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0,
11147 tasha_codec_force_enable_micbias,
11148 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11149 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0,
11150 tasha_codec_force_enable_micbias,
11151 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11152 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0,
11153 tasha_codec_force_enable_micbias,
11154 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11155 SND_SOC_DAPM_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0,
11156 tasha_codec_force_enable_ldo_h,
11157 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +053011158 SND_SOC_DAPM_SUPPLY("tx regulator", SND_SOC_NOPM,
11159 ON_DEMAND_TX_SUPPLY, 0,
11160 tasha_codec_enable_on_demand_supply,
11161 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11162 SND_SOC_DAPM_SUPPLY("rx regulator", SND_SOC_NOPM,
11163 ON_DEMAND_RX_SUPPLY, 0,
11164 tasha_codec_enable_on_demand_supply,
11165 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011166 SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux),
11167 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
11168
11169 SND_SOC_DAPM_INPUT("AMIC2"),
11170 SND_SOC_DAPM_INPUT("AMIC3"),
11171 SND_SOC_DAPM_INPUT("AMIC4"),
11172 SND_SOC_DAPM_INPUT("AMIC5"),
11173 SND_SOC_DAPM_INPUT("AMIC6"),
11174
11175 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
11176 AIF1_CAP, 0, tasha_codec_enable_slimtx,
11177 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
11178
11179 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
11180 AIF2_CAP, 0, tasha_codec_enable_slimtx,
11181 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
11182
11183 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
11184 AIF3_CAP, 0, tasha_codec_enable_slimtx,
11185 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
11186
11187 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
11188 AIF4_VIFEED, 0, tasha_codec_enable_slimvi_feedback,
11189 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
11190 SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0,
11191 aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)),
11192
11193 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
11194 aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
11195
11196 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
11197 aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
11198
11199 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
11200 aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
11201
11202 SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0,
11203 aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)),
11204
11205 SND_SOC_DAPM_INPUT("VIINPUT"),
11206
11207 SND_SOC_DAPM_AIF_OUT("AIF5 CPE", "AIF5 CPE TX", 0, SND_SOC_NOPM,
11208 AIF5_CPE_TX, 0),
11209
11210 SND_SOC_DAPM_MUX_E("EC BUF MUX INP", SND_SOC_NOPM, 0, 0, &ec_buf_mux,
11211 tasha_codec_ec_buf_mux_enable,
11212 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
11213
11214 /* Digital Mic Inputs */
11215 SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
11216 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
11217 SND_SOC_DAPM_POST_PMD),
11218
11219 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
11220 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
11221 SND_SOC_DAPM_POST_PMD),
11222
11223 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
11224 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
11225 SND_SOC_DAPM_POST_PMD),
11226
11227 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
11228 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
11229 SND_SOC_DAPM_POST_PMD),
11230
11231 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
11232 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
11233 SND_SOC_DAPM_POST_PMD),
11234
11235 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
11236 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
11237 SND_SOC_DAPM_POST_PMD),
11238
11239 SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux),
11240 SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux),
11241 SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux),
11242 SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux),
11243 SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux),
11244 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
11245 SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux),
11246 SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux),
11247
11248 SND_SOC_DAPM_MIXER_E("IIR0", WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL,
11249 4, 0, NULL, 0, tasha_codec_set_iir_gain,
11250 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
11251 SND_SOC_DAPM_MIXER_E("IIR1", WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL,
11252 4, 0, NULL, 0, tasha_codec_set_iir_gain,
11253 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
11254 SND_SOC_DAPM_MIXER("SRC0", WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL,
11255 4, 0, NULL, 0),
11256 SND_SOC_DAPM_MIXER("SRC1", WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL,
11257 4, 0, NULL, 0),
11258 SND_SOC_DAPM_MIXER_E("CPE IN Mixer", SND_SOC_NOPM, 0, 0,
11259 cpe_in_mix_switch,
11260 ARRAY_SIZE(cpe_in_mix_switch),
11261 tasha_codec_configure_cpe_input,
11262 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11263
11264 SND_SOC_DAPM_MUX("RX INT1_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
11265 &int1_1_native_mux),
11266 SND_SOC_DAPM_MUX("RX INT2_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
11267 &int2_1_native_mux),
11268 SND_SOC_DAPM_MUX("RX INT3_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
11269 &int3_1_native_mux),
11270 SND_SOC_DAPM_MUX("RX INT4_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
11271 &int4_1_native_mux),
11272 SND_SOC_DAPM_MUX("RX MIX TX0 MUX", SND_SOC_NOPM, 0, 0,
11273 &rx_mix_tx0_mux),
11274 SND_SOC_DAPM_MUX("RX MIX TX1 MUX", SND_SOC_NOPM, 0, 0,
11275 &rx_mix_tx1_mux),
11276 SND_SOC_DAPM_MUX("RX MIX TX2 MUX", SND_SOC_NOPM, 0, 0,
11277 &rx_mix_tx2_mux),
11278 SND_SOC_DAPM_MUX("RX MIX TX3 MUX", SND_SOC_NOPM, 0, 0,
11279 &rx_mix_tx3_mux),
11280 SND_SOC_DAPM_MUX("RX MIX TX4 MUX", SND_SOC_NOPM, 0, 0,
11281 &rx_mix_tx4_mux),
11282 SND_SOC_DAPM_MUX("RX MIX TX5 MUX", SND_SOC_NOPM, 0, 0,
11283 &rx_mix_tx5_mux),
11284 SND_SOC_DAPM_MUX("RX MIX TX6 MUX", SND_SOC_NOPM, 0, 0,
11285 &rx_mix_tx6_mux),
11286 SND_SOC_DAPM_MUX("RX MIX TX7 MUX", SND_SOC_NOPM, 0, 0,
11287 &rx_mix_tx7_mux),
11288 SND_SOC_DAPM_MUX("RX MIX TX8 MUX", SND_SOC_NOPM, 0, 0,
11289 &rx_mix_tx8_mux),
11290
11291 SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0,
11292 &rx_int0_dem_inp_mux),
11293 SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0,
11294 &rx_int1_dem_inp_mux),
11295 SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0,
11296 &rx_int2_dem_inp_mux),
11297
11298 SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM,
11299 INTERP_EAR, 0, &rx_int0_interp_mux,
11300 tasha_codec_enable_interpolator,
11301 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11302 SND_SOC_DAPM_POST_PMD),
11303 SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM,
11304 INTERP_HPHL, 0, &rx_int1_interp_mux,
11305 tasha_codec_enable_interpolator,
11306 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11307 SND_SOC_DAPM_POST_PMD),
11308 SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM,
11309 INTERP_HPHR, 0, &rx_int2_interp_mux,
11310 tasha_codec_enable_interpolator,
11311 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11312 SND_SOC_DAPM_POST_PMD),
11313 SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM,
11314 INTERP_LO1, 0, &rx_int3_interp_mux,
11315 tasha_codec_enable_interpolator,
11316 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11317 SND_SOC_DAPM_POST_PMD),
11318 SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM,
11319 INTERP_LO2, 0, &rx_int4_interp_mux,
11320 tasha_codec_enable_interpolator,
11321 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11322 SND_SOC_DAPM_POST_PMD),
11323 SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM,
11324 INTERP_LO3, 0, &rx_int5_interp_mux,
11325 tasha_codec_enable_interpolator,
11326 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11327 SND_SOC_DAPM_POST_PMD),
11328 SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM,
11329 INTERP_LO4, 0, &rx_int6_interp_mux,
11330 tasha_codec_enable_interpolator,
11331 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11332 SND_SOC_DAPM_POST_PMD),
11333 SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM,
11334 INTERP_SPKR1, 0, &rx_int7_interp_mux,
11335 tasha_codec_enable_interpolator,
11336 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11337 SND_SOC_DAPM_POST_PMD),
11338 SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM,
11339 INTERP_SPKR2, 0, &rx_int8_interp_mux,
11340 tasha_codec_enable_interpolator,
11341 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11342 SND_SOC_DAPM_POST_PMD),
11343
11344 SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
11345 0, 0, tasha_codec_ear_dac_event,
11346 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11347 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
Vatsal Buchae9a50072017-09-06 17:40:11 +053011348 SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, SND_SOC_NOPM,
11349 0, 0, tasha_codec_hphl_dac_event,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011350 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11351 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
Vatsal Buchae9a50072017-09-06 17:40:11 +053011352 SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, SND_SOC_NOPM,
11353 0, 0, tasha_codec_hphr_dac_event,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011354 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11355 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11356 SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM,
11357 0, 0, tasha_codec_lineout_dac_event,
11358 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11359 SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM,
11360 0, 0, tasha_codec_lineout_dac_event,
11361 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11362 SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM,
11363 0, 0, tasha_codec_lineout_dac_event,
11364 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11365 SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM,
11366 0, 0, tasha_codec_lineout_dac_event,
11367 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Vatsal Buchae9a50072017-09-06 17:40:11 +053011368 SND_SOC_DAPM_PGA_E("HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011369 tasha_codec_enable_hphl_pa,
11370 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11371 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
Vatsal Buchae9a50072017-09-06 17:40:11 +053011372 SND_SOC_DAPM_PGA_E("HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011373 tasha_codec_enable_hphr_pa,
11374 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11375 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11376 SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11377 tasha_codec_enable_ear_pa,
11378 SND_SOC_DAPM_POST_PMU |
11379 SND_SOC_DAPM_POST_PMD),
11380 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0,
11381 tasha_codec_enable_lineout_pa,
11382 SND_SOC_DAPM_POST_PMU |
11383 SND_SOC_DAPM_POST_PMD),
11384 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0,
11385 tasha_codec_enable_lineout_pa,
11386 SND_SOC_DAPM_POST_PMU |
11387 SND_SOC_DAPM_POST_PMD),
11388 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0,
11389 tasha_codec_enable_lineout_pa,
11390 SND_SOC_DAPM_POST_PMU |
11391 SND_SOC_DAPM_POST_PMD),
11392 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0,
11393 tasha_codec_enable_lineout_pa,
11394 SND_SOC_DAPM_POST_PMU |
11395 SND_SOC_DAPM_POST_PMD),
11396 SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11397 tasha_codec_enable_ear_pa,
11398 SND_SOC_DAPM_POST_PMU |
11399 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11400 SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11401 tasha_codec_enable_hphl_pa,
11402 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11403 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11404 SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11405 tasha_codec_enable_hphr_pa,
11406 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11407 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11408 SND_SOC_DAPM_PGA_E("ANC LINEOUT1 PA", WCD9335_ANA_LO_1_2,
11409 7, 0, NULL, 0,
11410 tasha_codec_enable_lineout_pa,
11411 SND_SOC_DAPM_POST_PMU |
11412 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11413 SND_SOC_DAPM_PGA_E("ANC LINEOUT2 PA", WCD9335_ANA_LO_1_2,
11414 6, 0, NULL, 0,
11415 tasha_codec_enable_lineout_pa,
11416 SND_SOC_DAPM_POST_PMU |
11417 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11418 SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11419 tasha_codec_enable_spk_anc,
11420 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11421
11422 SND_SOC_DAPM_OUTPUT("HPHL"),
11423 SND_SOC_DAPM_OUTPUT("HPHR"),
11424 SND_SOC_DAPM_OUTPUT("ANC HPHL"),
11425 SND_SOC_DAPM_OUTPUT("ANC HPHR"),
11426 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
11427 tasha_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
11428 SND_SOC_DAPM_POST_PMD),
11429 SND_SOC_DAPM_OUTPUT("SPK1 OUT"),
11430 SND_SOC_DAPM_OUTPUT("SPK2 OUT"),
11431 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
11432 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
11433 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
11434 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
11435 SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"),
11436 SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"),
11437 SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
11438 ON_DEMAND_MICBIAS, 0,
11439 tasha_codec_enable_on_demand_supply,
11440 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11441
11442 SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0,
11443 0, &adc_us_mux0_switch),
11444 SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9335_CDC_TX1_TX_PATH_192_CTL, 0,
11445 0, &adc_us_mux1_switch),
11446 SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9335_CDC_TX2_TX_PATH_192_CTL, 0,
11447 0, &adc_us_mux2_switch),
11448 SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9335_CDC_TX3_TX_PATH_192_CTL, 0,
11449 0, &adc_us_mux3_switch),
11450 SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9335_CDC_TX4_TX_PATH_192_CTL, 0,
11451 0, &adc_us_mux4_switch),
11452 SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9335_CDC_TX5_TX_PATH_192_CTL, 0,
11453 0, &adc_us_mux5_switch),
11454 SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9335_CDC_TX6_TX_PATH_192_CTL, 0,
11455 0, &adc_us_mux6_switch),
11456 SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9335_CDC_TX7_TX_PATH_192_CTL, 0,
11457 0, &adc_us_mux7_switch),
11458 SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9335_CDC_TX8_TX_PATH_192_CTL, 0,
11459 0, &adc_us_mux8_switch),
11460 /* MAD related widgets */
11461 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
11462 SND_SOC_NOPM, 0, 0,
11463 tasha_codec_enable_mad,
11464 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11465
11466 SND_SOC_DAPM_MUX("MAD_SEL MUX", SND_SOC_NOPM, 0, 0,
11467 &mad_sel_mux),
11468 SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"),
11469 SND_SOC_DAPM_INPUT("MADINPUT"),
11470 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
11471 &aif4_mad_switch),
11472 SND_SOC_DAPM_SWITCH("MAD_BROADCAST", SND_SOC_NOPM, 0, 0,
11473 &mad_brdcst_switch),
11474 SND_SOC_DAPM_SWITCH("AIF4", SND_SOC_NOPM, 0, 0,
11475 &aif4_switch_mixer_controls),
11476 SND_SOC_DAPM_SWITCH("ANC HPHL Enable", SND_SOC_NOPM, 0, 0,
11477 &anc_hphl_switch),
11478 SND_SOC_DAPM_SWITCH("ANC HPHR Enable", SND_SOC_NOPM, 0, 0,
11479 &anc_hphr_switch),
11480 SND_SOC_DAPM_SWITCH("ANC EAR Enable", SND_SOC_NOPM, 0, 0,
11481 &anc_ear_switch),
11482 SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0,
11483 &anc_ear_spkr_switch),
11484 SND_SOC_DAPM_SWITCH("ANC LINEOUT1 Enable", SND_SOC_NOPM, 0, 0,
11485 &anc_lineout1_switch),
11486 SND_SOC_DAPM_SWITCH("ANC LINEOUT2 Enable", SND_SOC_NOPM, 0, 0,
11487 &anc_lineout2_switch),
11488 SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0,
11489 &anc_spkr_pa_switch),
11490};
11491
11492static int tasha_get_channel_map(struct snd_soc_dai *dai,
11493 unsigned int *tx_num, unsigned int *tx_slot,
11494 unsigned int *rx_num, unsigned int *rx_slot)
11495{
Meng Wang15c825d2018-09-06 10:49:18 +080011496 struct tasha_priv *tasha_p =
11497 snd_soc_component_get_drvdata(dai->component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011498 u32 i = 0;
11499 struct wcd9xxx_ch *ch;
11500
11501 switch (dai->id) {
11502 case AIF1_PB:
11503 case AIF2_PB:
11504 case AIF3_PB:
11505 case AIF4_PB:
11506 case AIF_MIX1_PB:
11507 if (!rx_slot || !rx_num) {
11508 pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n",
11509 __func__, rx_slot, rx_num);
11510 return -EINVAL;
11511 }
11512 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11513 list) {
11514 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11515 __func__, i, ch->ch_num);
11516 rx_slot[i++] = ch->ch_num;
11517 }
11518 pr_debug("%s: rx_num %d\n", __func__, i);
11519 *rx_num = i;
11520 break;
11521 case AIF1_CAP:
11522 case AIF2_CAP:
11523 case AIF3_CAP:
11524 case AIF4_MAD_TX:
11525 case AIF4_VIFEED:
11526 if (!tx_slot || !tx_num) {
11527 pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n",
11528 __func__, tx_slot, tx_num);
11529 return -EINVAL;
11530 }
11531 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11532 list) {
11533 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11534 __func__, i, ch->ch_num);
11535 tx_slot[i++] = ch->ch_num;
11536 }
11537 pr_debug("%s: tx_num %d\n", __func__, i);
11538 *tx_num = i;
11539 break;
11540
11541 default:
11542 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
11543 break;
11544 }
11545
11546 return 0;
11547}
11548
11549static int tasha_set_channel_map(struct snd_soc_dai *dai,
11550 unsigned int tx_num, unsigned int *tx_slot,
11551 unsigned int rx_num, unsigned int *rx_slot)
11552{
11553 struct tasha_priv *tasha;
11554 struct wcd9xxx *core;
11555 struct wcd9xxx_codec_dai_data *dai_data = NULL;
11556
11557 if (!dai) {
11558 pr_err("%s: dai is empty\n", __func__);
11559 return -EINVAL;
11560 }
Meng Wang15c825d2018-09-06 10:49:18 +080011561 tasha = snd_soc_component_get_drvdata(dai->component);
11562 core = dev_get_drvdata(dai->component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011563
11564 if (!tx_slot || !rx_slot) {
11565 pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n",
11566 __func__, tx_slot, rx_slot);
11567 return -EINVAL;
11568 }
11569 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
11570 "tasha->intf_type %d\n",
11571 __func__, dai->name, dai->id, tx_num, rx_num,
11572 tasha->intf_type);
11573
11574 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
11575 wcd9xxx_init_slimslave(core, core->slim->laddr,
11576 tx_num, tx_slot, rx_num, rx_slot);
11577 /* Reserve TX12/TX13 for MAD data channel */
11578 dai_data = &tasha->dai[AIF4_MAD_TX];
11579 if (dai_data) {
11580 if (TASHA_IS_2_0(tasha->wcd9xxx))
11581 list_add_tail(&core->tx_chs[TASHA_TX13].list,
11582 &dai_data->wcd9xxx_ch_list);
11583 else
11584 list_add_tail(&core->tx_chs[TASHA_TX12].list,
11585 &dai_data->wcd9xxx_ch_list);
11586 }
11587 }
11588 return 0;
11589}
11590
11591static int tasha_startup(struct snd_pcm_substream *substream,
11592 struct snd_soc_dai *dai)
11593{
11594 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11595 substream->name, substream->stream);
11596
11597 return 0;
11598}
11599
11600static void tasha_shutdown(struct snd_pcm_substream *substream,
11601 struct snd_soc_dai *dai)
11602{
Meng Wang15c825d2018-09-06 10:49:18 +080011603 struct tasha_priv *tasha =
11604 snd_soc_component_get_drvdata(dai->component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011605
11606 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11607 substream->name, substream->stream);
11608
11609 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
11610 return;
11611
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053011612 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
Meng Wang15c825d2018-09-06 10:49:18 +080011613 tasha_codec_vote_max_bw(dai->component, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011614}
11615
11616static int tasha_set_decimator_rate(struct snd_soc_dai *dai,
11617 u8 tx_fs_rate_reg_val, u32 sample_rate)
11618{
Meng Wang15c825d2018-09-06 10:49:18 +080011619 struct snd_soc_component *component = dai->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011620 struct wcd9xxx_ch *ch;
Meng Wang15c825d2018-09-06 10:49:18 +080011621 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011622 u32 tx_port = 0;
11623 u8 shift = 0, shift_val = 0, tx_mux_sel = 0;
11624 int decimator = -1;
11625 u16 tx_port_reg = 0, tx_fs_reg = 0;
11626
11627 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11628 tx_port = ch->port;
Meng Wang15c825d2018-09-06 10:49:18 +080011629 dev_dbg(component->dev, "%s: dai->id = %d, tx_port = %d",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011630 __func__, dai->id, tx_port);
11631
11632 if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) {
Meng Wang15c825d2018-09-06 10:49:18 +080011633 dev_err(component->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011634 __func__, tx_port, dai->id);
11635 return -EINVAL;
11636 }
11637 /* Find the SB TX MUX input - which decimator is connected */
11638 if (tx_port < 4) {
11639 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0;
11640 shift = (tx_port << 1);
11641 shift_val = 0x03;
11642 } else if ((tx_port >= 4) && (tx_port < 8)) {
11643 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1;
11644 shift = ((tx_port - 4) << 1);
11645 shift_val = 0x03;
11646 } else if ((tx_port >= 8) && (tx_port < 11)) {
11647 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2;
11648 shift = ((tx_port - 8) << 1);
11649 shift_val = 0x03;
11650 } else if (tx_port == 11) {
11651 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11652 shift = 0;
11653 shift_val = 0x0F;
11654 } else if (tx_port == 13) {
11655 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11656 shift = 4;
11657 shift_val = 0x03;
11658 }
Meng Wang15c825d2018-09-06 10:49:18 +080011659 tx_mux_sel = snd_soc_component_read32(component, tx_port_reg) &
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011660 (shift_val << shift);
11661 tx_mux_sel = tx_mux_sel >> shift;
11662
11663 if (tx_port <= 8) {
11664 if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
11665 decimator = tx_port;
11666 } else if (tx_port <= 10) {
11667 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11668 decimator = ((tx_port == 9) ? 7 : 6);
11669 } else if (tx_port == 11) {
11670 if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
11671 decimator = tx_mux_sel - 1;
11672 } else if (tx_port == 13) {
11673 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11674 decimator = 5;
11675 }
11676
11677 if (decimator >= 0) {
11678 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
11679 16 * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +080011680 dev_dbg(component->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011681 __func__, decimator, tx_port, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +080011682 snd_soc_component_update_bits(component, tx_fs_reg,
11683 0x0F, tx_fs_rate_reg_val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011684 } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) {
11685 /* Check if the TX Mux input is RX MIX TXn */
Meng Wang15c825d2018-09-06 10:49:18 +080011686 dev_dbg(component->dev, "%s: RX_MIX_TX%u going to SLIM TX%u\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011687 __func__, tx_port, tx_port);
11688 } else {
Meng Wang15c825d2018-09-06 10:49:18 +080011689 dev_err(component->dev, "%s: ERROR: Invalid decimator: %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011690 __func__, decimator);
11691 return -EINVAL;
11692 }
11693 }
11694 return 0;
11695}
11696
11697static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai,
11698 u8 int_mix_fs_rate_reg_val,
11699 u32 sample_rate)
11700{
11701 u8 int_2_inp;
11702 u32 j;
11703 u16 int_mux_cfg1, int_fs_reg;
11704 u8 int_mux_cfg1_val;
Meng Wang15c825d2018-09-06 10:49:18 +080011705 struct snd_soc_component *component = dai->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011706 struct wcd9xxx_ch *ch;
Meng Wang15c825d2018-09-06 10:49:18 +080011707 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011708
11709 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11710 int_2_inp = ch->port + INTn_2_INP_SEL_RX0 -
11711 TASHA_RX_PORT_START_NUMBER;
11712 if ((int_2_inp < INTn_2_INP_SEL_RX0) ||
11713 (int_2_inp > INTn_2_INP_SEL_RX7)) {
11714 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11715 __func__,
11716 (ch->port - TASHA_RX_PORT_START_NUMBER),
11717 dai->id);
11718 return -EINVAL;
11719 }
11720
11721 int_mux_cfg1 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1;
11722 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +080011723 int_mux_cfg1_val = snd_soc_component_read32(
11724 component, int_mux_cfg1) &
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011725 0x0F;
11726 if (int_mux_cfg1_val == int_2_inp) {
11727 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_MIX_CTL +
11728 20 * j;
11729 pr_debug("%s: AIF_MIX_PB DAI(%d) connected to INT%u_2\n",
11730 __func__, dai->id, j);
11731 pr_debug("%s: set INT%u_2 sample rate to %u\n",
11732 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +080011733 snd_soc_component_update_bits(component,
11734 int_fs_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011735 0x0F, int_mix_fs_rate_reg_val);
11736 }
11737 int_mux_cfg1 += 2;
11738 }
11739 }
11740 return 0;
11741}
11742
11743static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai,
11744 u8 int_prim_fs_rate_reg_val,
11745 u32 sample_rate)
11746{
11747 u8 int_1_mix1_inp;
11748 u32 j;
11749 u16 int_mux_cfg0, int_mux_cfg1;
11750 u16 int_fs_reg;
11751 u8 int_mux_cfg0_val, int_mux_cfg1_val;
11752 u8 inp0_sel, inp1_sel, inp2_sel;
Meng Wang15c825d2018-09-06 10:49:18 +080011753 struct snd_soc_component *component = dai->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011754 struct wcd9xxx_ch *ch;
Meng Wang15c825d2018-09-06 10:49:18 +080011755 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011756
11757 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11758 int_1_mix1_inp = ch->port + INTn_1_MIX_INP_SEL_RX0 -
11759 TASHA_RX_PORT_START_NUMBER;
11760 if ((int_1_mix1_inp < INTn_1_MIX_INP_SEL_RX0) ||
11761 (int_1_mix1_inp > INTn_1_MIX_INP_SEL_RX7)) {
11762 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11763 __func__,
11764 (ch->port - TASHA_RX_PORT_START_NUMBER),
11765 dai->id);
11766 return -EINVAL;
11767 }
11768
11769 int_mux_cfg0 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0;
11770
11771 /*
11772 * Loop through all interpolator MUX inputs and find out
11773 * to which interpolator input, the slim rx port
11774 * is connected
11775 */
11776 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11777 int_mux_cfg1 = int_mux_cfg0 + 1;
11778
Meng Wang15c825d2018-09-06 10:49:18 +080011779 int_mux_cfg0_val = snd_soc_component_read32(component,
11780 int_mux_cfg0);
11781 int_mux_cfg1_val = snd_soc_component_read32(component,
11782 int_mux_cfg1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011783 inp0_sel = int_mux_cfg0_val & 0x0F;
11784 inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F;
11785 inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F;
11786 if ((inp0_sel == int_1_mix1_inp) ||
11787 (inp1_sel == int_1_mix1_inp) ||
11788 (inp2_sel == int_1_mix1_inp)) {
11789 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_CTL +
11790 20 * j;
11791 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
11792 __func__, dai->id, j);
11793 pr_debug("%s: set INT%u_1 sample rate to %u\n",
11794 __func__, j, sample_rate);
11795 /* sample_rate is in Hz */
11796 if ((j == 0) && (sample_rate == 44100)) {
11797 pr_info("%s: Cannot set 44.1KHz on INT0\n",
11798 __func__);
11799 } else
Meng Wang15c825d2018-09-06 10:49:18 +080011800 snd_soc_component_update_bits(
11801 component, int_fs_reg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011802 0x0F, int_prim_fs_rate_reg_val);
11803 }
11804 int_mux_cfg0 += 2;
11805 }
11806 }
11807
11808 return 0;
11809}
11810
11811
11812static int tasha_set_interpolator_rate(struct snd_soc_dai *dai,
11813 u32 sample_rate)
11814{
11815 int rate_val = 0;
11816 int i, ret;
11817
11818 /* set mixing path rate */
11819 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
11820 if (sample_rate ==
11821 int_mix_sample_rate_val[i].sample_rate) {
11822 rate_val =
11823 int_mix_sample_rate_val[i].rate_val;
11824 break;
11825 }
11826 }
11827 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
11828 (rate_val < 0))
11829 goto prim_rate;
11830 ret = tasha_set_mix_interpolator_rate(dai,
11831 (u8) rate_val, sample_rate);
11832prim_rate:
11833 /* set primary path sample rate */
11834 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
11835 if (sample_rate ==
11836 int_prim_sample_rate_val[i].sample_rate) {
11837 rate_val =
11838 int_prim_sample_rate_val[i].rate_val;
11839 break;
11840 }
11841 }
11842 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
11843 (rate_val < 0))
11844 return -EINVAL;
11845 ret = tasha_set_prim_interpolator_rate(dai,
11846 (u8) rate_val, sample_rate);
11847 return ret;
11848}
11849
11850static int tasha_prepare(struct snd_pcm_substream *substream,
11851 struct snd_soc_dai *dai)
11852{
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011853 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11854 substream->name, substream->stream);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053011855
11856 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
Meng Wang15c825d2018-09-06 10:49:18 +080011857 tasha_codec_vote_max_bw(dai->component, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011858 return 0;
11859}
11860
11861static int tasha_hw_params(struct snd_pcm_substream *substream,
11862 struct snd_pcm_hw_params *params,
11863 struct snd_soc_dai *dai)
11864{
Meng Wang15c825d2018-09-06 10:49:18 +080011865 struct tasha_priv *tasha =
11866 snd_soc_component_get_drvdata(dai->component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011867 int ret;
11868 int tx_fs_rate = -EINVAL;
11869 int rx_fs_rate = -EINVAL;
11870 int i2s_bit_mode;
Meng Wang15c825d2018-09-06 10:49:18 +080011871 struct snd_soc_component *component = dai->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011872
11873 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
11874 dai->name, dai->id, params_rate(params),
11875 params_channels(params));
11876
11877 switch (substream->stream) {
11878 case SNDRV_PCM_STREAM_PLAYBACK:
11879 ret = tasha_set_interpolator_rate(dai, params_rate(params));
11880 if (ret) {
11881 pr_err("%s: cannot set sample rate: %u\n",
11882 __func__, params_rate(params));
11883 return ret;
11884 }
11885 switch (params_width(params)) {
11886 case 16:
11887 tasha->dai[dai->id].bit_width = 16;
11888 i2s_bit_mode = 0x01;
11889 break;
11890 case 24:
11891 tasha->dai[dai->id].bit_width = 24;
11892 i2s_bit_mode = 0x00;
11893 break;
11894 default:
11895 return -EINVAL;
11896 }
11897 tasha->dai[dai->id].rate = params_rate(params);
11898 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11899 switch (params_rate(params)) {
11900 case 8000:
11901 rx_fs_rate = 0;
11902 break;
11903 case 16000:
11904 rx_fs_rate = 1;
11905 break;
11906 case 32000:
11907 rx_fs_rate = 2;
11908 break;
11909 case 48000:
11910 rx_fs_rate = 3;
11911 break;
11912 case 96000:
11913 rx_fs_rate = 4;
11914 break;
11915 case 192000:
11916 rx_fs_rate = 5;
11917 break;
11918 default:
11919 dev_err(tasha->dev,
11920 "%s: Invalid RX sample rate: %d\n",
11921 __func__, params_rate(params));
11922 return -EINVAL;
11923 };
Meng Wang15c825d2018-09-06 10:49:18 +080011924 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011925 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11926 0x20, i2s_bit_mode << 5);
Meng Wang15c825d2018-09-06 10:49:18 +080011927 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011928 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11929 0x1c, (rx_fs_rate << 2));
11930 }
11931 break;
11932 case SNDRV_PCM_STREAM_CAPTURE:
11933 switch (params_rate(params)) {
11934 case 8000:
11935 tx_fs_rate = 0;
11936 break;
11937 case 16000:
11938 tx_fs_rate = 1;
11939 break;
11940 case 32000:
11941 tx_fs_rate = 3;
11942 break;
11943 case 48000:
11944 tx_fs_rate = 4;
11945 break;
11946 case 96000:
11947 tx_fs_rate = 5;
11948 break;
11949 case 192000:
11950 tx_fs_rate = 6;
11951 break;
11952 case 384000:
11953 tx_fs_rate = 7;
11954 break;
11955 default:
11956 dev_err(tasha->dev, "%s: Invalid TX sample rate: %d\n",
11957 __func__, params_rate(params));
11958 return -EINVAL;
11959
11960 };
11961 if (dai->id != AIF4_VIFEED &&
11962 dai->id != AIF4_MAD_TX) {
11963 ret = tasha_set_decimator_rate(dai, tx_fs_rate,
11964 params_rate(params));
11965 if (ret < 0) {
11966 dev_err(tasha->dev, "%s: cannot set TX Decimator rate: %d\n",
11967 __func__, tx_fs_rate);
11968 return ret;
11969 }
11970 }
11971 tasha->dai[dai->id].rate = params_rate(params);
11972 switch (params_width(params)) {
11973 case 16:
11974 tasha->dai[dai->id].bit_width = 16;
11975 i2s_bit_mode = 0x01;
11976 break;
11977 case 24:
11978 tasha->dai[dai->id].bit_width = 24;
11979 i2s_bit_mode = 0x00;
11980 break;
11981 case 32:
11982 tasha->dai[dai->id].bit_width = 32;
11983 i2s_bit_mode = 0x00;
11984 break;
11985 default:
11986 dev_err(tasha->dev, "%s: Invalid format 0x%x\n",
11987 __func__, params_width(params));
11988 return -EINVAL;
11989 };
11990 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
Meng Wang15c825d2018-09-06 10:49:18 +080011991 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011992 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11993 0x20, i2s_bit_mode << 5);
11994 if (tx_fs_rate > 1)
11995 tx_fs_rate--;
Meng Wang15c825d2018-09-06 10:49:18 +080011996 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011997 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11998 0x1c, tx_fs_rate << 2);
Meng Wang15c825d2018-09-06 10:49:18 +080011999 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012000 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG,
12001 0x05, 0x05);
12002
Meng Wang15c825d2018-09-06 10:49:18 +080012003 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012004 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG,
12005 0x05, 0x05);
12006
Meng Wang15c825d2018-09-06 10:49:18 +080012007 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012008 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG,
12009 0x05, 0x05);
12010
Meng Wang15c825d2018-09-06 10:49:18 +080012011 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012012 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG,
12013 0x05, 0x05);
12014 }
12015 break;
12016 default:
12017 pr_err("%s: Invalid stream type %d\n", __func__,
12018 substream->stream);
12019 return -EINVAL;
12020 };
12021 if (dai->id == AIF4_VIFEED)
12022 tasha->dai[dai->id].bit_width = 32;
12023
12024 return 0;
12025}
12026
12027static int tasha_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
12028{
Meng Wang15c825d2018-09-06 10:49:18 +080012029 struct tasha_priv *tasha =
12030 snd_soc_component_get_drvdata(dai->component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012031
12032 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
12033 case SND_SOC_DAIFMT_CBS_CFS:
12034 /* CPU is master */
12035 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
12036 if (dai->id == AIF1_CAP)
Meng Wang15c825d2018-09-06 10:49:18 +080012037 snd_soc_component_update_bits(dai->component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012038 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
12039 0x2, 0);
12040 else if (dai->id == AIF1_PB)
Meng Wang15c825d2018-09-06 10:49:18 +080012041 snd_soc_component_update_bits(dai->component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012042 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
12043 0x2, 0);
12044 }
12045 break;
12046 case SND_SOC_DAIFMT_CBM_CFM:
12047 /* CPU is slave */
12048 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
12049 if (dai->id == AIF1_CAP)
Meng Wang15c825d2018-09-06 10:49:18 +080012050 snd_soc_component_update_bits(dai->component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012051 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
12052 0x2, 0x2);
12053 else if (dai->id == AIF1_PB)
Meng Wang15c825d2018-09-06 10:49:18 +080012054 snd_soc_component_update_bits(dai->component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012055 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
12056 0x2, 0x2);
12057 }
12058 break;
12059 default:
12060 return -EINVAL;
12061 }
12062 return 0;
12063}
12064
12065static int tasha_set_dai_sysclk(struct snd_soc_dai *dai,
12066 int clk_id, unsigned int freq, int dir)
12067{
12068 pr_debug("%s\n", __func__);
12069 return 0;
12070}
12071
12072static struct snd_soc_dai_ops tasha_dai_ops = {
12073 .startup = tasha_startup,
12074 .shutdown = tasha_shutdown,
12075 .hw_params = tasha_hw_params,
12076 .prepare = tasha_prepare,
12077 .set_sysclk = tasha_set_dai_sysclk,
12078 .set_fmt = tasha_set_dai_fmt,
12079 .set_channel_map = tasha_set_channel_map,
12080 .get_channel_map = tasha_get_channel_map,
12081};
12082
12083static struct snd_soc_dai_driver tasha_dai[] = {
12084 {
12085 .name = "tasha_rx1",
12086 .id = AIF1_PB,
12087 .playback = {
12088 .stream_name = "AIF1 Playback",
12089 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
12090 .formats = TASHA_FORMATS_S16_S24_LE,
12091 .rate_max = 192000,
12092 .rate_min = 8000,
12093 .channels_min = 1,
12094 .channels_max = 2,
12095 },
12096 .ops = &tasha_dai_ops,
12097 },
12098 {
12099 .name = "tasha_tx1",
12100 .id = AIF1_CAP,
12101 .capture = {
12102 .stream_name = "AIF1 Capture",
12103 .rates = WCD9335_RATES_MASK,
12104 .formats = TASHA_FORMATS_S16_S24_LE,
12105 .rate_max = 192000,
12106 .rate_min = 8000,
12107 .channels_min = 1,
12108 .channels_max = 4,
12109 },
12110 .ops = &tasha_dai_ops,
12111 },
12112 {
12113 .name = "tasha_rx2",
12114 .id = AIF2_PB,
12115 .playback = {
12116 .stream_name = "AIF2 Playback",
12117 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
12118 .formats = TASHA_FORMATS_S16_S24_LE,
12119 .rate_min = 8000,
12120 .rate_max = 192000,
12121 .channels_min = 1,
12122 .channels_max = 2,
12123 },
12124 .ops = &tasha_dai_ops,
12125 },
12126 {
12127 .name = "tasha_tx2",
12128 .id = AIF2_CAP,
12129 .capture = {
12130 .stream_name = "AIF2 Capture",
12131 .rates = WCD9335_RATES_MASK,
12132 .formats = TASHA_FORMATS_S16_S24_LE,
12133 .rate_max = 192000,
12134 .rate_min = 8000,
12135 .channels_min = 1,
12136 .channels_max = 8,
12137 },
12138 .ops = &tasha_dai_ops,
12139 },
12140 {
12141 .name = "tasha_rx3",
12142 .id = AIF3_PB,
12143 .playback = {
12144 .stream_name = "AIF3 Playback",
12145 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
12146 .formats = TASHA_FORMATS_S16_S24_LE,
12147 .rate_min = 8000,
12148 .rate_max = 192000,
12149 .channels_min = 1,
12150 .channels_max = 2,
12151 },
12152 .ops = &tasha_dai_ops,
12153 },
12154 {
12155 .name = "tasha_tx3",
12156 .id = AIF3_CAP,
12157 .capture = {
12158 .stream_name = "AIF3 Capture",
12159 .rates = WCD9335_RATES_MASK,
12160 .formats = TASHA_FORMATS_S16_S24_LE,
12161 .rate_max = 48000,
12162 .rate_min = 8000,
12163 .channels_min = 1,
12164 .channels_max = 2,
12165 },
12166 .ops = &tasha_dai_ops,
12167 },
12168 {
12169 .name = "tasha_rx4",
12170 .id = AIF4_PB,
12171 .playback = {
12172 .stream_name = "AIF4 Playback",
12173 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
12174 .formats = TASHA_FORMATS_S16_S24_LE,
12175 .rate_min = 8000,
12176 .rate_max = 192000,
12177 .channels_min = 1,
12178 .channels_max = 2,
12179 },
12180 .ops = &tasha_dai_ops,
12181 },
12182 {
12183 .name = "tasha_mix_rx1",
12184 .id = AIF_MIX1_PB,
12185 .playback = {
12186 .stream_name = "AIF Mix Playback",
12187 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
12188 .formats = TASHA_FORMATS_S16_S24_LE,
12189 .rate_min = 8000,
12190 .rate_max = 192000,
12191 .channels_min = 1,
12192 .channels_max = 8,
12193 },
12194 .ops = &tasha_dai_ops,
12195 },
12196 {
12197 .name = "tasha_mad1",
12198 .id = AIF4_MAD_TX,
12199 .capture = {
12200 .stream_name = "AIF4 MAD TX",
12201 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
12202 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000,
12203 .formats = TASHA_FORMATS_S16_S24_S32_LE,
12204 .rate_min = 16000,
12205 .rate_max = 384000,
12206 .channels_min = 1,
12207 .channels_max = 1,
12208 },
12209 .ops = &tasha_dai_ops,
12210 },
12211 {
12212 .name = "tasha_vifeedback",
12213 .id = AIF4_VIFEED,
12214 .capture = {
12215 .stream_name = "VIfeed",
12216 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
12217 .formats = TASHA_FORMATS_S16_S24_S32_LE,
12218 .rate_max = 48000,
12219 .rate_min = 8000,
12220 .channels_min = 1,
12221 .channels_max = 4,
12222 },
12223 .ops = &tasha_dai_ops,
12224 },
12225 {
12226 .name = "tasha_cpe",
12227 .id = AIF5_CPE_TX,
12228 .capture = {
12229 .stream_name = "AIF5 CPE TX",
12230 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
12231 .formats = TASHA_FORMATS_S16_S24_S32_LE,
12232 .rate_min = 16000,
12233 .rate_max = 48000,
12234 .channels_min = 1,
12235 .channels_max = 1,
12236 },
12237 },
12238};
12239
12240static struct snd_soc_dai_driver tasha_i2s_dai[] = {
12241 {
12242 .name = "tasha_i2s_rx1",
12243 .id = AIF1_PB,
12244 .playback = {
12245 .stream_name = "AIF1 Playback",
12246 .rates = WCD9335_RATES_MASK,
12247 .formats = TASHA_FORMATS_S16_S24_LE,
12248 .rate_max = 192000,
12249 .rate_min = 8000,
12250 .channels_min = 1,
12251 .channels_max = 2,
12252 },
12253 .ops = &tasha_dai_ops,
12254 },
12255 {
12256 .name = "tasha_i2s_tx1",
12257 .id = AIF1_CAP,
12258 .capture = {
12259 .stream_name = "AIF1 Capture",
12260 .rates = WCD9335_RATES_MASK,
12261 .formats = TASHA_FORMATS_S16_S24_LE,
12262 .rate_max = 192000,
12263 .rate_min = 8000,
12264 .channels_min = 1,
12265 .channels_max = 4,
12266 },
12267 .ops = &tasha_dai_ops,
12268 },
12269 {
12270 .name = "tasha_i2s_rx2",
12271 .id = AIF2_PB,
12272 .playback = {
12273 .stream_name = "AIF2 Playback",
12274 .rates = WCD9335_RATES_MASK,
12275 .formats = TASHA_FORMATS_S16_S24_LE,
12276 .rate_max = 192000,
12277 .rate_min = 8000,
12278 .channels_min = 1,
12279 .channels_max = 2,
12280 },
12281 .ops = &tasha_dai_ops,
12282 },
12283 {
12284 .name = "tasha_i2s_tx2",
12285 .id = AIF2_CAP,
12286 .capture = {
12287 .stream_name = "AIF2 Capture",
12288 .rates = WCD9335_RATES_MASK,
12289 .formats = TASHA_FORMATS_S16_S24_LE,
12290 .rate_max = 192000,
12291 .rate_min = 8000,
12292 .channels_min = 1,
12293 .channels_max = 4,
12294 },
12295 .ops = &tasha_dai_ops,
12296 },
Raja Mallikf008d222018-06-01 07:48:38 +053012297 {
12298 .name = "tasha_mad1",
12299 .id = AIF4_MAD_TX,
12300 .capture = {
12301 .stream_name = "AIF4 MAD TX",
12302 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
12303 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000,
12304 .formats = TASHA_FORMATS_S16_S24_S32_LE,
12305 .rate_min = 16000,
12306 .rate_max = 384000,
12307 .channels_min = 1,
12308 .channels_max = 1,
12309 },
12310 .ops = &tasha_dai_ops,
12311 },
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012312};
12313
12314static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha)
12315{
Meng Wang15c825d2018-09-06 10:49:18 +080012316 struct snd_soc_component *component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012317
Meng Wang15c825d2018-09-06 10:49:18 +080012318 if (!component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012319 return;
12320
12321 mutex_lock(&tasha->power_lock);
Meng Wang15c825d2018-09-06 10:49:18 +080012322 dev_dbg(component->dev, "%s: Entering power gating function, %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012323 __func__, tasha->power_active_ref);
12324
12325 if (tasha->power_active_ref > 0)
12326 goto exit;
12327
12328 wcd9xxx_set_power_state(tasha->wcd9xxx,
12329 WCD_REGION_POWER_COLLAPSE_BEGIN,
12330 WCD9XXX_DIG_CORE_REGION_1);
Meng Wang15c825d2018-09-06 10:49:18 +080012331 snd_soc_component_update_bits(component,
12332 WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012333 0x04, 0x04);
Meng Wang15c825d2018-09-06 10:49:18 +080012334 snd_soc_component_update_bits(component,
12335 WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012336 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +080012337 snd_soc_component_update_bits(component,
12338 WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012339 0x02, 0x00);
12340 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12341 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
12342 wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_DOWN,
12343 WCD9XXX_DIG_CORE_REGION_1);
12344exit:
Meng Wang15c825d2018-09-06 10:49:18 +080012345 dev_dbg(component->dev, "%s: Exiting power gating function, %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012346 __func__, tasha->power_active_ref);
12347 mutex_unlock(&tasha->power_lock);
12348}
12349
12350static void tasha_codec_power_gate_work(struct work_struct *work)
12351{
12352 struct tasha_priv *tasha;
12353 struct delayed_work *dwork;
Meng Wang15c825d2018-09-06 10:49:18 +080012354 struct snd_soc_component *component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012355
12356 dwork = to_delayed_work(work);
12357 tasha = container_of(dwork, struct tasha_priv, power_gate_work);
Meng Wang15c825d2018-09-06 10:49:18 +080012358 component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012359
Meng Wang15c825d2018-09-06 10:49:18 +080012360 if (!component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012361 return;
12362
12363 tasha_codec_power_gate_digital_core(tasha);
12364}
12365
12366/* called under power_lock acquisition */
Meng Wang15c825d2018-09-06 10:49:18 +080012367static int tasha_dig_core_remove_power_collapse(
12368 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012369{
Meng Wang15c825d2018-09-06 10:49:18 +080012370 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012371
Meng Wang15c825d2018-09-06 10:49:18 +080012372 tasha_codec_vote_max_bw(component, true);
12373 snd_soc_component_write(component,
12374 WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
12375 snd_soc_component_write(component,
12376 WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
12377 snd_soc_component_write(component,
12378 WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
12379 snd_soc_component_update_bits(component, WCD9335_CODEC_RPM_RST_CTL,
12380 0x02, 0x00);
12381 snd_soc_component_update_bits(component, WCD9335_CODEC_RPM_RST_CTL,
12382 0x02, 0x02);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012383
12384 wcd9xxx_set_power_state(tasha->wcd9xxx,
12385 WCD_REGION_POWER_COLLAPSE_REMOVE,
12386 WCD9XXX_DIG_CORE_REGION_1);
Meng Wang15c825d2018-09-06 10:49:18 +080012387 regcache_mark_dirty(component->regmap);
12388 regcache_sync_region(component->regmap,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012389 TASHA_DIG_CORE_REG_MIN, TASHA_DIG_CORE_REG_MAX);
Meng Wang15c825d2018-09-06 10:49:18 +080012390 tasha_codec_vote_max_bw(component, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012391
12392 return 0;
12393}
12394
12395static int tasha_dig_core_power_collapse(struct tasha_priv *tasha,
12396 int req_state)
12397{
Meng Wang15c825d2018-09-06 10:49:18 +080012398 struct snd_soc_component *component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012399 int cur_state;
12400
12401 /* Exit if feature is disabled */
12402 if (!dig_core_collapse_enable)
12403 return 0;
12404
12405 mutex_lock(&tasha->power_lock);
12406 if (req_state == POWER_COLLAPSE)
12407 tasha->power_active_ref--;
12408 else if (req_state == POWER_RESUME)
12409 tasha->power_active_ref++;
12410 else
12411 goto unlock_mutex;
12412
12413 if (tasha->power_active_ref < 0) {
12414 dev_dbg(tasha->dev, "%s: power_active_ref is negative\n",
12415 __func__);
12416 goto unlock_mutex;
12417 }
12418
Meng Wang15c825d2018-09-06 10:49:18 +080012419 component = tasha->component;
12420 if (!component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012421 goto unlock_mutex;
12422
12423 if (req_state == POWER_COLLAPSE) {
12424 if (tasha->power_active_ref == 0) {
12425 schedule_delayed_work(&tasha->power_gate_work,
12426 msecs_to_jiffies(dig_core_collapse_timer * 1000));
12427 }
12428 } else if (req_state == POWER_RESUME) {
12429 if (tasha->power_active_ref == 1) {
12430 /*
12431 * At this point, there can be two cases:
12432 * 1. Core already in power collapse state
12433 * 2. Timer kicked in and still did not expire or
12434 * waiting for the power_lock
12435 */
12436 cur_state = wcd9xxx_get_current_power_state(
12437 tasha->wcd9xxx,
12438 WCD9XXX_DIG_CORE_REGION_1);
12439 if (cur_state == WCD_REGION_POWER_DOWN)
Meng Wang15c825d2018-09-06 10:49:18 +080012440 tasha_dig_core_remove_power_collapse(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012441 else {
12442 mutex_unlock(&tasha->power_lock);
12443 cancel_delayed_work_sync(
12444 &tasha->power_gate_work);
12445 mutex_lock(&tasha->power_lock);
12446 }
12447 }
12448 }
12449
12450unlock_mutex:
12451 mutex_unlock(&tasha->power_lock);
12452
12453 return 0;
12454}
12455
12456static int __tasha_cdc_mclk_enable_locked(struct tasha_priv *tasha,
12457 bool enable)
12458{
12459 int ret = 0;
12460
12461 if (!tasha->wcd_ext_clk) {
12462 dev_err(tasha->dev, "%s: wcd ext clock is NULL\n", __func__);
12463 return -EINVAL;
12464 }
12465
12466 dev_dbg(tasha->dev, "%s: mclk_enable = %u\n", __func__, enable);
12467
12468 if (enable) {
12469 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12470 ret = tasha_cdc_req_mclk_enable(tasha, true);
12471 if (ret)
12472 goto err;
12473
12474 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
12475 tasha_codec_apply_sido_voltage(tasha,
12476 SIDO_VOLTAGE_NOMINAL_MV);
12477 } else {
12478 if (!dig_core_collapse_enable) {
12479 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12480 tasha_codec_update_sido_voltage(tasha,
12481 sido_buck_svs_voltage);
12482 }
12483 tasha_cdc_req_mclk_enable(tasha, false);
12484 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12485 }
12486
12487err:
12488 return ret;
12489}
12490
12491static int __tasha_cdc_mclk_enable(struct tasha_priv *tasha,
12492 bool enable)
12493{
12494 int ret;
12495
12496 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12497 ret = __tasha_cdc_mclk_enable_locked(tasha, enable);
12498 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12499
12500 return ret;
12501}
12502
Meng Wang15c825d2018-09-06 10:49:18 +080012503int tasha_cdc_mclk_enable(struct snd_soc_component *component,
12504 int enable, bool dapm)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012505{
Meng Wang15c825d2018-09-06 10:49:18 +080012506 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012507
12508 return __tasha_cdc_mclk_enable(tasha, enable);
12509}
12510EXPORT_SYMBOL(tasha_cdc_mclk_enable);
12511
Meng Wang15c825d2018-09-06 10:49:18 +080012512int tasha_cdc_mclk_tx_enable(struct snd_soc_component *component,
12513 int enable, bool dapm)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012514{
Meng Wang15c825d2018-09-06 10:49:18 +080012515 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012516 int ret = 0;
12517
12518 dev_dbg(tasha->dev, "%s: clk_mode: %d, enable: %d, clk_internal: %d\n",
12519 __func__, tasha->clk_mode, enable, tasha->clk_internal);
12520 if (tasha->clk_mode || tasha->clk_internal) {
12521 if (enable) {
12522 tasha_cdc_sido_ccl_enable(tasha, true);
12523 wcd_resmgr_enable_master_bias(tasha->resmgr);
12524 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
Meng Wang15c825d2018-09-06 10:49:18 +080012525 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012526 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
12527 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +080012528 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012529 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
12530 0x01, 0x01);
12531 set_bit(CPE_NOMINAL, &tasha->status_mask);
12532 tasha_codec_update_sido_voltage(tasha,
12533 SIDO_VOLTAGE_NOMINAL_MV);
12534 tasha->clk_internal = true;
12535 } else {
12536 tasha->clk_internal = false;
12537 clear_bit(CPE_NOMINAL, &tasha->status_mask);
12538 tasha_codec_update_sido_voltage(tasha,
12539 sido_buck_svs_voltage);
12540 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12541 wcd_resmgr_disable_master_bias(tasha->resmgr);
12542 tasha_cdc_sido_ccl_enable(tasha, false);
12543 }
12544 } else {
12545 ret = __tasha_cdc_mclk_enable(tasha, enable);
12546 }
12547 return ret;
12548}
12549EXPORT_SYMBOL(tasha_cdc_mclk_tx_enable);
12550
12551static ssize_t tasha_codec_version_read(struct snd_info_entry *entry,
12552 void *file_private_data, struct file *file,
12553 char __user *buf, size_t count, loff_t pos)
12554{
12555 struct tasha_priv *tasha;
12556 struct wcd9xxx *wcd9xxx;
12557 char buffer[TASHA_VERSION_ENTRY_SIZE];
12558 int len = 0;
12559
12560 tasha = (struct tasha_priv *) entry->private_data;
12561 if (!tasha) {
12562 pr_err("%s: tasha priv is null\n", __func__);
12563 return -EINVAL;
12564 }
12565
12566 wcd9xxx = tasha->wcd9xxx;
12567
12568 if (wcd9xxx->codec_type->id_major == TASHA_MAJOR) {
12569 if (TASHA_IS_1_0(wcd9xxx))
12570 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_0\n");
12571 else if (TASHA_IS_1_1(wcd9xxx))
12572 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_1\n");
12573 else
12574 snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12575 } else if (wcd9xxx->codec_type->id_major == TASHA2P0_MAJOR) {
12576 len = snprintf(buffer, sizeof(buffer), "WCD9335_2_0\n");
12577 } else
12578 len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12579
12580 return simple_read_from_buffer(buf, count, &pos, buffer, len);
12581}
12582
12583static struct snd_info_entry_ops tasha_codec_info_ops = {
12584 .read = tasha_codec_version_read,
12585};
12586
12587/*
12588 * tasha_codec_info_create_codec_entry - creates wcd9335 module
12589 * @codec_root: The parent directory
Meng Wang15c825d2018-09-06 10:49:18 +080012590 * @component: Codec instance
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012591 *
12592 * Creates wcd9335 module and version entry under the given
12593 * parent directory.
12594 *
12595 * Return: 0 on success or negative error code on failure.
12596 */
12597int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
Meng Wang15c825d2018-09-06 10:49:18 +080012598 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012599{
12600 struct snd_info_entry *version_entry;
12601 struct tasha_priv *tasha;
12602 struct snd_soc_card *card;
12603
Meng Wang15c825d2018-09-06 10:49:18 +080012604 if (!codec_root || !component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012605 return -EINVAL;
12606
Meng Wang15c825d2018-09-06 10:49:18 +080012607 tasha = snd_soc_component_get_drvdata(component);
12608 card = component->card;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012609 tasha->entry = snd_info_create_subdir(codec_root->module,
12610 "tasha", codec_root);
12611 if (!tasha->entry) {
Meng Wang15c825d2018-09-06 10:49:18 +080012612 dev_dbg(component->dev, "%s: failed to create wcd9335 entry\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012613 __func__);
12614 return -ENOMEM;
12615 }
12616
12617 version_entry = snd_info_create_card_entry(card->snd_card,
12618 "version",
12619 tasha->entry);
12620 if (!version_entry) {
Meng Wang15c825d2018-09-06 10:49:18 +080012621 dev_dbg(component->dev, "%s: failed to create wcd9335 version entry\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012622 __func__);
12623 return -ENOMEM;
12624 }
12625
12626 version_entry->private_data = tasha;
12627 version_entry->size = TASHA_VERSION_ENTRY_SIZE;
12628 version_entry->content = SNDRV_INFO_CONTENT_DATA;
12629 version_entry->c.ops = &tasha_codec_info_ops;
12630
12631 if (snd_info_register(version_entry) < 0) {
12632 snd_info_free_entry(version_entry);
12633 return -ENOMEM;
12634 }
12635 tasha->version_entry = version_entry;
12636
12637 return 0;
12638}
12639EXPORT_SYMBOL(tasha_codec_info_create_codec_entry);
12640
12641static int __tasha_codec_internal_rco_ctrl(
Meng Wang15c825d2018-09-06 10:49:18 +080012642 struct snd_soc_component *component, bool enable)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012643{
Meng Wang15c825d2018-09-06 10:49:18 +080012644 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012645 int ret = 0;
12646
12647 if (enable) {
12648 tasha_cdc_sido_ccl_enable(tasha, true);
12649 if (wcd_resmgr_get_clk_type(tasha->resmgr) ==
12650 WCD_CLK_RCO) {
12651 ret = wcd_resmgr_enable_clk_block(tasha->resmgr,
12652 WCD_CLK_RCO);
12653 } else {
12654 ret = tasha_cdc_req_mclk_enable(tasha, true);
12655 ret |= wcd_resmgr_enable_clk_block(tasha->resmgr,
12656 WCD_CLK_RCO);
12657 ret |= tasha_cdc_req_mclk_enable(tasha, false);
12658 }
12659
12660 } else {
12661 ret = wcd_resmgr_disable_clk_block(tasha->resmgr,
12662 WCD_CLK_RCO);
12663 tasha_cdc_sido_ccl_enable(tasha, false);
12664 }
12665
12666 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +080012667 dev_err(component->dev, "%s: Error in %s RCO\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012668 __func__, (enable ? "enabling" : "disabling"));
12669 ret = -EINVAL;
12670 }
12671
12672 return ret;
12673}
12674
12675/*
12676 * tasha_codec_internal_rco_ctrl()
12677 * Make sure that the caller does not acquire
12678 * BG_CLK_LOCK.
12679 */
Meng Wang15c825d2018-09-06 10:49:18 +080012680static int tasha_codec_internal_rco_ctrl(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012681 bool enable)
12682{
Meng Wang15c825d2018-09-06 10:49:18 +080012683 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012684 int ret = 0;
12685
12686 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
Meng Wang15c825d2018-09-06 10:49:18 +080012687 ret = __tasha_codec_internal_rco_ctrl(component, enable);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012688 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12689 return ret;
12690}
12691
12692/*
12693 * tasha_mbhc_hs_detect: starts mbhc insertion/removal functionality
Meng Wang15c825d2018-09-06 10:49:18 +080012694 * @component: handle to snd_soc_component *
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012695 * @mbhc_cfg: handle to mbhc configuration structure
12696 * return 0 if mbhc_start is success or error code in case of failure
12697 */
Meng Wang15c825d2018-09-06 10:49:18 +080012698int tasha_mbhc_hs_detect(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012699 struct wcd_mbhc_config *mbhc_cfg)
12700{
Meng Wang15c825d2018-09-06 10:49:18 +080012701 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012702
12703 return wcd_mbhc_start(&tasha->mbhc, mbhc_cfg);
12704}
12705EXPORT_SYMBOL(tasha_mbhc_hs_detect);
12706
12707/*
12708 * tasha_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality
Meng Wang15c825d2018-09-06 10:49:18 +080012709 * @component: handle to snd_soc_component *
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012710 */
Meng Wang15c825d2018-09-06 10:49:18 +080012711void tasha_mbhc_hs_detect_exit(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012712{
Meng Wang15c825d2018-09-06 10:49:18 +080012713 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012714
12715 wcd_mbhc_stop(&tasha->mbhc);
12716}
12717EXPORT_SYMBOL(tasha_mbhc_hs_detect_exit);
12718
12719static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv)
12720{
12721 /* min micbias voltage is 1V and maximum is 2.85V */
12722 if (micb_mv < 1000 || micb_mv > 2850) {
12723 pr_err("%s: unsupported micbias voltage\n", __func__);
12724 return -EINVAL;
12725 }
12726
12727 return (micb_mv - 1000) / 50;
12728}
12729
12730static const struct tasha_reg_mask_val tasha_reg_update_reset_val_1_1[] = {
12731 {WCD9335_RCO_CTRL_2, 0xFF, 0x47},
12732 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12733};
12734
12735static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_1[] = {
12736 {WCD9335_FLYBACK_VNEG_DAC_CTRL_1, 0xFF, 0x65},
12737 {WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0xFF, 0x52},
12738 {WCD9335_FLYBACK_VNEG_DAC_CTRL_3, 0xFF, 0xAF},
12739 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12740 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0xF4},
12741 {WCD9335_FLYBACK_VNEG_CTRL_9, 0xFF, 0x40},
12742 {WCD9335_FLYBACK_VNEG_CTRL_2, 0xFF, 0x4F},
12743 {WCD9335_FLYBACK_EN, 0xFF, 0x6E},
12744 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xF8, 0xF8},
12745 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xF8, 0xF8},
12746};
12747
12748static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_0[] = {
12749 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0x54},
12750 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xFC, 0xFC},
12751 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xFC, 0xFC},
12752};
12753
12754static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
12755 {WCD9335_RCO_CTRL_2, 0x0F, 0x08},
12756 {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
12757 {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
12758 {WCD9335_HPH_OCP_CTL, 0xFF, 0x7A},
12759 {WCD9335_HPH_L_TEST, 0x01, 0x01},
12760 {WCD9335_HPH_R_TEST, 0x01, 0x01},
12761 {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
12762 {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
12763 {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
12764 {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
12765 {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
12766 {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
12767 {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
12768 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
12769 {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
12770 {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
12771 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xA0},
12772 {WCD9335_SE_LO_COM1, 0xFF, 0xC0},
12773 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xFC, 0xF4},
12774 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xFC, 0xF4},
12775 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xFC, 0xF8},
12776 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xFC, 0xF8},
12777};
12778
12779static const struct tasha_reg_mask_val tasha_codec_reg_defaults[] = {
12780 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00},
12781 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01},
12782 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x04, 0x04},
12783};
12784
12785static const struct tasha_reg_mask_val tasha_codec_reg_i2c_defaults[] = {
12786 {WCD9335_ANA_CLK_TOP, 0x20, 0x20},
12787 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x01},
12788 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x00},
12789 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x05, 0x05},
12790 {WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG, 0x01, 0x01},
12791 {WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG, 0x01, 0x01},
12792 {WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG, 0x01, 0x01},
12793 {WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG, 0x01, 0x01},
12794 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, 0x05, 0x05},
12795 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, 0x05, 0x05},
12796 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, 0x05, 0x05},
12797 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, 0x05, 0x05},
12798};
12799
12800static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = {
12801 /* Rbuckfly/R_EAR(32) */
12802 {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00},
12803 {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60},
12804 {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00},
Xiaojun Sange0c3f3f2018-06-01 11:15:31 +080012805 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x58},
12806 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x58},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012807 {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
12808 {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
12809 {WCD9335_ANA_LO_1_2, 0x3C, 0X3C},
12810 {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00},
12811 {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03},
12812 {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02},
12813 {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01},
12814 {WCD9335_EAR_CMBUFF, 0x08, 0x00},
12815 {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12816 {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12817 {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12818 {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12819 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
12820 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
12821 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
12822 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
12823 {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
12824 {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
12825 {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
12826 {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
12827 {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
12828 {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
12829 {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
12830 {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
12831 {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
12832 {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
12833 {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
12834 {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
12835 {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
12836 {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
12837 {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
12838 {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
12839 {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
12840 {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
12841 {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08},
12842};
12843
12844static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = {
12845 /* Enable TX HPF Filter & Linear Phase */
12846 {WCD9335_CDC_TX0_TX_PATH_CFG0, 0x11, 0x11},
12847 {WCD9335_CDC_TX1_TX_PATH_CFG0, 0x11, 0x11},
12848 {WCD9335_CDC_TX2_TX_PATH_CFG0, 0x11, 0x11},
12849 {WCD9335_CDC_TX3_TX_PATH_CFG0, 0x11, 0x11},
12850 {WCD9335_CDC_TX4_TX_PATH_CFG0, 0x11, 0x11},
12851 {WCD9335_CDC_TX5_TX_PATH_CFG0, 0x11, 0x11},
12852 {WCD9335_CDC_TX6_TX_PATH_CFG0, 0x11, 0x11},
12853 {WCD9335_CDC_TX7_TX_PATH_CFG0, 0x11, 0x11},
12854 {WCD9335_CDC_TX8_TX_PATH_CFG0, 0x11, 0x11},
12855 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xF8, 0xF8},
12856 {WCD9335_CDC_RX0_RX_PATH_SEC1, 0x08, 0x08},
12857 {WCD9335_CDC_RX1_RX_PATH_SEC1, 0x08, 0x08},
12858 {WCD9335_CDC_RX2_RX_PATH_SEC1, 0x08, 0x08},
12859 {WCD9335_CDC_RX3_RX_PATH_SEC1, 0x08, 0x08},
12860 {WCD9335_CDC_RX4_RX_PATH_SEC1, 0x08, 0x08},
12861 {WCD9335_CDC_RX5_RX_PATH_SEC1, 0x08, 0x08},
12862 {WCD9335_CDC_RX6_RX_PATH_SEC1, 0x08, 0x08},
12863 {WCD9335_CDC_RX7_RX_PATH_SEC1, 0x08, 0x08},
12864 {WCD9335_CDC_RX8_RX_PATH_SEC1, 0x08, 0x08},
12865 {WCD9335_CDC_RX0_RX_PATH_MIX_SEC0, 0x08, 0x08},
12866 {WCD9335_CDC_RX1_RX_PATH_MIX_SEC0, 0x08, 0x08},
12867 {WCD9335_CDC_RX2_RX_PATH_MIX_SEC0, 0x08, 0x08},
12868 {WCD9335_CDC_RX3_RX_PATH_MIX_SEC0, 0x08, 0x08},
12869 {WCD9335_CDC_RX4_RX_PATH_MIX_SEC0, 0x08, 0x08},
12870 {WCD9335_CDC_RX5_RX_PATH_MIX_SEC0, 0x08, 0x08},
12871 {WCD9335_CDC_RX6_RX_PATH_MIX_SEC0, 0x08, 0x08},
12872 {WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, 0x08, 0x08},
12873 {WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, 0x08, 0x08},
12874 {WCD9335_CDC_TX0_TX_PATH_SEC2, 0x01, 0x01},
12875 {WCD9335_CDC_TX1_TX_PATH_SEC2, 0x01, 0x01},
12876 {WCD9335_CDC_TX2_TX_PATH_SEC2, 0x01, 0x01},
12877 {WCD9335_CDC_TX3_TX_PATH_SEC2, 0x01, 0x01},
12878 {WCD9335_CDC_TX4_TX_PATH_SEC2, 0x01, 0x01},
12879 {WCD9335_CDC_TX5_TX_PATH_SEC2, 0x01, 0x01},
12880 {WCD9335_CDC_TX6_TX_PATH_SEC2, 0x01, 0x01},
12881 {WCD9335_CDC_TX7_TX_PATH_SEC2, 0x01, 0x01},
12882 {WCD9335_CDC_TX8_TX_PATH_SEC2, 0x01, 0x01},
12883 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xF8, 0xF0},
12884 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xF8, 0xF0},
12885 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xF8, 0xF8},
12886 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xF8, 0xF8},
12887 {WCD9335_RX_OCP_COUNT, 0xFF, 0xFF},
12888 {WCD9335_HPH_OCP_CTL, 0xF0, 0x70},
12889 {WCD9335_CPE_SS_CPAR_CFG, 0xFF, 0x00},
12890 {WCD9335_FLYBACK_VNEG_CTRL_1, 0xFF, 0x63},
12891 {WCD9335_FLYBACK_VNEG_CTRL_4, 0xFF, 0x7F},
12892 {WCD9335_CLASSH_CTRL_VCL_1, 0xFF, 0x60},
12893 {WCD9335_CLASSH_CTRL_CCL_5, 0xFF, 0x40},
12894 {WCD9335_RX_TIMER_DIV, 0xFF, 0x32},
12895 {WCD9335_SE_LO_COM2, 0xFF, 0x01},
12896 {WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, 0x07},
12897 {WCD9335_RX_BIAS_HPH_PA, 0xF0, 0x60},
12898 {WCD9335_HPH_RDAC_LDO_CTL, 0x88, 0x88},
12899 {WCD9335_HPH_L_EN, 0x20, 0x20},
12900 {WCD9335_HPH_R_EN, 0x20, 0x20},
12901 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xD8},
12902 {WCD9335_CDC_RX5_RX_PATH_SEC3, 0xBD, 0xBD},
12903 {WCD9335_CDC_RX6_RX_PATH_SEC3, 0xBD, 0xBD},
12904 {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40},
12905};
12906
Meng Wang15c825d2018-09-06 10:49:18 +080012907static void tasha_update_reg_reset_values(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012908{
12909 u32 i;
Meng Wang15c825d2018-09-06 10:49:18 +080012910 struct wcd9xxx *tasha_core = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012911
12912 if (TASHA_IS_1_1(tasha_core)) {
12913 for (i = 0; i < ARRAY_SIZE(tasha_reg_update_reset_val_1_1);
12914 i++)
Meng Wang15c825d2018-09-06 10:49:18 +080012915 snd_soc_component_write(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012916 tasha_reg_update_reset_val_1_1[i].reg,
12917 tasha_reg_update_reset_val_1_1[i].val);
12918 }
12919}
12920
Meng Wang15c825d2018-09-06 10:49:18 +080012921static void tasha_codec_init_reg(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012922{
12923 u32 i;
Meng Wang15c825d2018-09-06 10:49:18 +080012924 struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012925
12926 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_common_val); i++)
Meng Wang15c825d2018-09-06 10:49:18 +080012927 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012928 tasha_codec_reg_init_common_val[i].reg,
12929 tasha_codec_reg_init_common_val[i].mask,
12930 tasha_codec_reg_init_common_val[i].val);
12931
12932 if (TASHA_IS_1_1(wcd9xxx) ||
12933 TASHA_IS_1_0(wcd9xxx))
12934 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_1_x_val); i++)
Meng Wang15c825d2018-09-06 10:49:18 +080012935 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012936 tasha_codec_reg_init_1_x_val[i].reg,
12937 tasha_codec_reg_init_1_x_val[i].mask,
12938 tasha_codec_reg_init_1_x_val[i].val);
12939
12940 if (TASHA_IS_1_1(wcd9xxx)) {
12941 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_1); i++)
Meng Wang15c825d2018-09-06 10:49:18 +080012942 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012943 tasha_codec_reg_init_val_1_1[i].reg,
12944 tasha_codec_reg_init_val_1_1[i].mask,
12945 tasha_codec_reg_init_val_1_1[i].val);
12946 } else if (TASHA_IS_1_0(wcd9xxx)) {
12947 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_0); i++)
Meng Wang15c825d2018-09-06 10:49:18 +080012948 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012949 tasha_codec_reg_init_val_1_0[i].reg,
12950 tasha_codec_reg_init_val_1_0[i].mask,
12951 tasha_codec_reg_init_val_1_0[i].val);
12952 } else if (TASHA_IS_2_0(wcd9xxx)) {
12953 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_2_0); i++)
Meng Wang15c825d2018-09-06 10:49:18 +080012954 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012955 tasha_codec_reg_init_val_2_0[i].reg,
12956 tasha_codec_reg_init_val_2_0[i].mask,
12957 tasha_codec_reg_init_val_2_0[i].val);
12958 }
12959}
12960
12961static void tasha_update_reg_defaults(struct tasha_priv *tasha)
12962{
12963 u32 i;
12964 struct wcd9xxx *wcd9xxx;
12965
12966 wcd9xxx = tasha->wcd9xxx;
12967 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_defaults); i++)
12968 regmap_update_bits(wcd9xxx->regmap,
12969 tasha_codec_reg_defaults[i].reg,
12970 tasha_codec_reg_defaults[i].mask,
12971 tasha_codec_reg_defaults[i].val);
12972
12973 tasha->intf_type = wcd9xxx_get_intf_type();
12974 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
12975 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_i2c_defaults); i++)
12976 regmap_update_bits(wcd9xxx->regmap,
12977 tasha_codec_reg_i2c_defaults[i].reg,
12978 tasha_codec_reg_i2c_defaults[i].mask,
12979 tasha_codec_reg_i2c_defaults[i].val);
12980
12981}
12982
Meng Wang15c825d2018-09-06 10:49:18 +080012983static void tasha_slim_interface_init_reg(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012984{
12985 int i;
Meng Wang15c825d2018-09-06 10:49:18 +080012986 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012987
12988 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
12989 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12990 TASHA_SLIM_PGD_PORT_INT_EN0 + i,
12991 0xFF);
12992}
12993
12994static irqreturn_t tasha_slimbus_irq(int irq, void *data)
12995{
12996 struct tasha_priv *priv = data;
12997 unsigned long status = 0;
12998 int i, j, port_id, k;
12999 u32 bit;
13000 u8 val, int_val = 0;
13001 bool tx, cleared;
13002 unsigned short reg = 0;
13003
13004 for (i = TASHA_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
13005 i <= TASHA_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
13006 val = wcd9xxx_interface_reg_read(priv->wcd9xxx, i);
13007 status |= ((u32)val << (8 * j));
13008 }
13009
13010 for_each_set_bit(j, &status, 32) {
13011 tx = (j >= 16 ? true : false);
13012 port_id = (tx ? j - 16 : j);
13013 val = wcd9xxx_interface_reg_read(priv->wcd9xxx,
13014 TASHA_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
13015 if (val) {
13016 if (!tx)
13017 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
13018 (port_id / 8);
13019 else
13020 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
13021 (port_id / 8);
13022 int_val = wcd9xxx_interface_reg_read(
13023 priv->wcd9xxx, reg);
13024 /*
13025 * Ignore interrupts for ports for which the
13026 * interrupts are not specifically enabled.
13027 */
13028 if (!(int_val & (1 << (port_id % 8))))
13029 continue;
13030 }
13031 if (val & TASHA_SLIM_IRQ_OVERFLOW)
13032 pr_err_ratelimited(
13033 "%s: overflow error on %s port %d, value %x\n",
13034 __func__, (tx ? "TX" : "RX"), port_id, val);
13035 if (val & TASHA_SLIM_IRQ_UNDERFLOW)
13036 pr_err_ratelimited(
13037 "%s: underflow error on %s port %d, value %x\n",
13038 __func__, (tx ? "TX" : "RX"), port_id, val);
13039 if ((val & TASHA_SLIM_IRQ_OVERFLOW) ||
13040 (val & TASHA_SLIM_IRQ_UNDERFLOW)) {
13041 if (!tx)
13042 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
13043 (port_id / 8);
13044 else
13045 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
13046 (port_id / 8);
13047 int_val = wcd9xxx_interface_reg_read(
13048 priv->wcd9xxx, reg);
13049 if (int_val & (1 << (port_id % 8))) {
13050 int_val = int_val ^ (1 << (port_id % 8));
13051 wcd9xxx_interface_reg_write(priv->wcd9xxx,
13052 reg, int_val);
13053 }
13054 }
13055 if (val & TASHA_SLIM_IRQ_PORT_CLOSED) {
13056 /*
13057 * INT SOURCE register starts from RX to TX
13058 * but port number in the ch_mask is in opposite way
13059 */
13060 bit = (tx ? j - 16 : j + 16);
13061 pr_debug("%s: %s port %d closed value %x, bit %u\n",
13062 __func__, (tx ? "TX" : "RX"), port_id, val,
13063 bit);
13064 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
13065 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
13066 __func__, k, priv->dai[k].ch_mask);
13067 if (test_and_clear_bit(bit,
13068 &priv->dai[k].ch_mask)) {
13069 cleared = true;
13070 if (!priv->dai[k].ch_mask)
13071 wake_up(&priv->dai[k].dai_wait);
13072 /*
13073 * There are cases when multiple DAIs
13074 * might be using the same slimbus
13075 * channel. Hence don't break here.
13076 */
13077 }
13078 }
13079 WARN(!cleared,
13080 "Couldn't find slimbus %s port %d for closing\n",
13081 (tx ? "TX" : "RX"), port_id);
13082 }
13083 wcd9xxx_interface_reg_write(priv->wcd9xxx,
13084 TASHA_SLIM_PGD_PORT_INT_CLR_RX_0 +
13085 (j / 8),
13086 1 << (j % 8));
13087 }
13088
13089 return IRQ_HANDLED;
13090}
13091
13092static int tasha_setup_irqs(struct tasha_priv *tasha)
13093{
13094 int ret = 0;
Meng Wang15c825d2018-09-06 10:49:18 +080013095 struct snd_soc_component *component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013096 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
13097 struct wcd9xxx_core_resource *core_res =
13098 &wcd9xxx->core_res;
13099
13100 ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS,
13101 tasha_slimbus_irq, "SLIMBUS Slave", tasha);
13102 if (ret)
13103 pr_err("%s: Failed to request irq %d\n", __func__,
13104 WCD9XXX_IRQ_SLIMBUS);
13105 else
Meng Wang15c825d2018-09-06 10:49:18 +080013106 tasha_slim_interface_init_reg(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013107
13108 return ret;
13109}
13110
Meng Wang15c825d2018-09-06 10:49:18 +080013111static void tasha_init_slim_slave_cfg(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013112{
Meng Wang15c825d2018-09-06 10:49:18 +080013113 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013114 struct afe_param_cdc_slimbus_slave_cfg *cfg;
13115 struct wcd9xxx *wcd9xxx = priv->wcd9xxx;
13116 uint64_t eaddr = 0;
13117
13118 cfg = &priv->slimbus_slave_cfg;
13119 cfg->minor_version = 1;
13120 cfg->tx_slave_port_offset = 0;
13121 cfg->rx_slave_port_offset = 16;
13122
13123 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
13124 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
13125 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
13126 cfg->device_enum_addr_msw = eaddr >> 32;
13127
Meng Wang15c825d2018-09-06 10:49:18 +080013128 dev_dbg(component->dev, "%s: slimbus logical address 0x%llx\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013129 __func__, eaddr);
13130}
13131
13132static void tasha_cleanup_irqs(struct tasha_priv *tasha)
13133{
13134 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
13135 struct wcd9xxx_core_resource *core_res =
13136 &wcd9xxx->core_res;
13137
13138 wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, tasha);
13139}
13140
13141static int tasha_handle_pdata(struct tasha_priv *tasha,
13142 struct wcd9xxx_pdata *pdata)
13143{
Meng Wang15c825d2018-09-06 10:49:18 +080013144 struct snd_soc_component *component = tasha->component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013145 u8 dmic_ctl_val, mad_dmic_ctl_val;
13146 u8 anc_ctl_value;
13147 u32 def_dmic_rate, dmic_clk_drv;
13148 int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
13149 int rc = 0;
13150
13151 if (!pdata) {
Meng Wang15c825d2018-09-06 10:49:18 +080013152 dev_err(component->dev, "%s: NULL pdata\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013153 return -ENODEV;
13154 }
13155
13156 /* set micbias voltage */
13157 vout_ctl_1 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb1_mv);
13158 vout_ctl_2 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb2_mv);
13159 vout_ctl_3 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb3_mv);
13160 vout_ctl_4 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb4_mv);
13161 if (vout_ctl_1 < 0 || vout_ctl_2 < 0 ||
13162 vout_ctl_3 < 0 || vout_ctl_4 < 0) {
13163 rc = -EINVAL;
13164 goto done;
13165 }
Meng Wang15c825d2018-09-06 10:49:18 +080013166 snd_soc_component_update_bits(component, WCD9335_ANA_MICB1,
13167 0x3F, vout_ctl_1);
13168 snd_soc_component_update_bits(component, WCD9335_ANA_MICB2,
13169 0x3F, vout_ctl_2);
13170 snd_soc_component_update_bits(component, WCD9335_ANA_MICB3,
13171 0x3F, vout_ctl_3);
13172 snd_soc_component_update_bits(component, WCD9335_ANA_MICB4,
13173 0x3F, vout_ctl_4);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013174
13175 /* Set the DMIC sample rate */
13176 switch (pdata->mclk_rate) {
13177 case TASHA_MCLK_CLK_9P6MHZ:
13178 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
13179 break;
13180 case TASHA_MCLK_CLK_12P288MHZ:
13181 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ;
13182 break;
13183 default:
13184 /* should never happen */
Meng Wang15c825d2018-09-06 10:49:18 +080013185 dev_err(component->dev, "%s: Invalid mclk_rate %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013186 __func__, pdata->mclk_rate);
13187 rc = -EINVAL;
13188 goto done;
13189 };
13190
13191 if (pdata->dmic_sample_rate ==
13192 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
Meng Wang15c825d2018-09-06 10:49:18 +080013193 dev_info(component->dev, "%s: dmic_rate invalid default = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013194 __func__, def_dmic_rate);
13195 pdata->dmic_sample_rate = def_dmic_rate;
13196 }
13197 if (pdata->mad_dmic_sample_rate ==
13198 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
Meng Wang15c825d2018-09-06 10:49:18 +080013199 dev_info(component->dev, "%s: mad_dmic_rate invalid default = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013200 __func__, def_dmic_rate);
13201 /*
13202 * use dmic_sample_rate as the default for MAD
13203 * if mad dmic sample rate is undefined
13204 */
13205 pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate;
13206 }
13207 if (pdata->ecpp_dmic_sample_rate ==
13208 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
Meng Wang15c825d2018-09-06 10:49:18 +080013209 dev_info(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013210 "%s: ecpp_dmic_rate invalid default = %d\n",
13211 __func__, def_dmic_rate);
13212 /*
13213 * use dmic_sample_rate as the default for ECPP DMIC
13214 * if ecpp dmic sample rate is undefined
13215 */
13216 pdata->ecpp_dmic_sample_rate = pdata->dmic_sample_rate;
13217 }
13218
13219 if (pdata->dmic_clk_drv ==
13220 WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) {
13221 pdata->dmic_clk_drv = WCD9335_DMIC_CLK_DRIVE_DEFAULT;
Meng Wang15c825d2018-09-06 10:49:18 +080013222 dev_info(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013223 "%s: dmic_clk_strength invalid, default = %d\n",
13224 __func__, pdata->dmic_clk_drv);
13225 }
13226
13227 switch (pdata->dmic_clk_drv) {
13228 case 2:
13229 dmic_clk_drv = 0;
13230 break;
13231 case 4:
13232 dmic_clk_drv = 1;
13233 break;
13234 case 8:
13235 dmic_clk_drv = 2;
13236 break;
13237 case 16:
13238 dmic_clk_drv = 3;
13239 break;
13240 default:
Meng Wang15c825d2018-09-06 10:49:18 +080013241 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013242 "%s: invalid dmic_clk_drv %d, using default\n",
13243 __func__, pdata->dmic_clk_drv);
13244 dmic_clk_drv = 0;
13245 break;
13246 }
13247
Meng Wang15c825d2018-09-06 10:49:18 +080013248 snd_soc_component_update_bits(component, WCD9335_TEST_DEBUG_PAD_DRVCTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013249 0x0C, dmic_clk_drv << 2);
13250
13251 /*
13252 * Default the DMIC clk rates to mad_dmic_sample_rate,
13253 * whereas, the anc/txfe dmic rates to dmic_sample_rate
13254 * since the anc/txfe are independent of mad block.
13255 */
Meng Wang15c825d2018-09-06 10:49:18 +080013256 mad_dmic_ctl_val = tasha_get_dmic_clk_val(tasha->component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013257 pdata->mclk_rate,
13258 pdata->mad_dmic_sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +080013259 snd_soc_component_update_bits(component, WCD9335_CPE_SS_DMIC0_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013260 0x0E, mad_dmic_ctl_val << 1);
Meng Wang15c825d2018-09-06 10:49:18 +080013261 snd_soc_component_update_bits(component, WCD9335_CPE_SS_DMIC1_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013262 0x0E, mad_dmic_ctl_val << 1);
Meng Wang15c825d2018-09-06 10:49:18 +080013263 snd_soc_component_update_bits(component, WCD9335_CPE_SS_DMIC2_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013264 0x0E, mad_dmic_ctl_val << 1);
13265
Meng Wang15c825d2018-09-06 10:49:18 +080013266 dmic_ctl_val = tasha_get_dmic_clk_val(tasha->component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013267 pdata->mclk_rate,
13268 pdata->dmic_sample_rate);
13269
13270 if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2)
13271 anc_ctl_value = WCD9335_ANC_DMIC_X2_FULL_RATE;
13272 else
13273 anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE;
13274
Meng Wang15c825d2018-09-06 10:49:18 +080013275 snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_MODE_2_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013276 0x40, anc_ctl_value << 6);
Meng Wang15c825d2018-09-06 10:49:18 +080013277 snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_MODE_2_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013278 0x20, anc_ctl_value << 5);
Meng Wang15c825d2018-09-06 10:49:18 +080013279 snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_MODE_2_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013280 0x40, anc_ctl_value << 6);
Meng Wang15c825d2018-09-06 10:49:18 +080013281 snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_MODE_2_CTL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013282 0x20, anc_ctl_value << 5);
13283done:
13284 return rc;
13285}
13286
13287static struct wcd_cpe_core *tasha_codec_get_cpe_core(
Meng Wang15c825d2018-09-06 10:49:18 +080013288 struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013289{
Meng Wang15c825d2018-09-06 10:49:18 +080013290 struct tasha_priv *priv = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013291
13292 return priv->cpe_core;
13293}
13294
13295static int tasha_codec_cpe_fll_update_divider(
Meng Wang15c825d2018-09-06 10:49:18 +080013296 struct snd_soc_component *component, u32 cpe_fll_rate)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013297{
Meng Wang15c825d2018-09-06 10:49:18 +080013298 struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent);
13299 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013300
13301 u32 div_val = 0, l_val = 0;
13302 u32 computed_cpe_fll;
13303
13304 if (cpe_fll_rate != CPE_FLL_CLK_75MHZ &&
13305 cpe_fll_rate != CPE_FLL_CLK_150MHZ) {
Meng Wang15c825d2018-09-06 10:49:18 +080013306 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013307 "%s: Invalid CPE fll rate request %u\n",
13308 __func__, cpe_fll_rate);
13309 return -EINVAL;
13310 }
13311
13312 if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) {
13313 /* update divider to 10 and enable 5x divider */
Meng Wang15c825d2018-09-06 10:49:18 +080013314 snd_soc_component_write(component, WCD9335_CPE_FLL_USER_CTL_1,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013315 0x55);
13316 div_val = 10;
13317 } else if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) {
13318 /* update divider to 8 and enable 2x divider */
Meng Wang15c825d2018-09-06 10:49:18 +080013319 snd_soc_component_update_bits(component,
13320 WCD9335_CPE_FLL_USER_CTL_0,
13321 0x7C, 0x70);
13322 snd_soc_component_update_bits(component,
13323 WCD9335_CPE_FLL_USER_CTL_1,
13324 0xE0, 0x20);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013325 div_val = 8;
13326 } else {
Meng Wang15c825d2018-09-06 10:49:18 +080013327 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013328 "%s: Invalid MCLK rate %u\n",
13329 __func__, wcd9xxx->mclk_rate);
13330 return -EINVAL;
13331 }
13332
13333 l_val = ((cpe_fll_rate / 1000) * div_val) /
13334 (wcd9xxx->mclk_rate / 1000);
13335
13336 /* If l_val was integer truncated, increment l_val once */
13337 computed_cpe_fll = (wcd9xxx->mclk_rate / div_val) * l_val;
13338 if (computed_cpe_fll < cpe_fll_rate)
13339 l_val++;
13340
13341
13342 /* update L value LSB and MSB */
Meng Wang15c825d2018-09-06 10:49:18 +080013343 snd_soc_component_write(component, WCD9335_CPE_FLL_L_VAL_CTL_0,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013344 (l_val & 0xFF));
Meng Wang15c825d2018-09-06 10:49:18 +080013345 snd_soc_component_write(component, WCD9335_CPE_FLL_L_VAL_CTL_1,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013346 ((l_val >> 8) & 0xFF));
13347
13348 tasha->current_cpe_clk_freq = cpe_fll_rate;
Meng Wang15c825d2018-09-06 10:49:18 +080013349 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013350 "%s: updated l_val to %u for cpe_clk %u and mclk %u\n",
13351 __func__, l_val, cpe_fll_rate, wcd9xxx->mclk_rate);
13352
13353 return 0;
13354}
13355
Meng Wang15c825d2018-09-06 10:49:18 +080013356static int __tasha_cdc_change_cpe_clk(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013357 u32 clk_freq)
13358{
13359 int ret = 0;
Meng Wang15c825d2018-09-06 10:49:18 +080013360 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013361
13362 if (!tasha_cdc_is_svs_enabled(tasha)) {
Meng Wang15c825d2018-09-06 10:49:18 +080013363 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013364 "%s: SVS not enabled or tasha is not 2p0, return\n",
13365 __func__);
13366 return 0;
13367 }
Meng Wang15c825d2018-09-06 10:49:18 +080013368 dev_dbg(component->dev, "%s: clk_freq = %u\n", __func__, clk_freq);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013369
13370 if (clk_freq == CPE_FLL_CLK_75MHZ) {
13371 /* Change to SVS */
Meng Wang15c825d2018-09-06 10:49:18 +080013372 snd_soc_component_update_bits(component,
13373 WCD9335_CPE_FLL_FLL_MODE,
13374 0x08, 0x08);
13375 if (tasha_codec_cpe_fll_update_divider(component, clk_freq)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013376 ret = -EINVAL;
13377 goto done;
13378 }
13379
Meng Wang15c825d2018-09-06 10:49:18 +080013380 snd_soc_component_update_bits(component,
13381 WCD9335_CPE_FLL_FLL_MODE,
13382 0x10, 0x10);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013383
13384 clear_bit(CPE_NOMINAL, &tasha->status_mask);
13385 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
13386
13387 } else if (clk_freq == CPE_FLL_CLK_150MHZ) {
13388 /* change to nominal */
Meng Wang15c825d2018-09-06 10:49:18 +080013389 snd_soc_component_update_bits(component,
13390 WCD9335_CPE_FLL_FLL_MODE,
13391 0x08, 0x08);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013392
13393 set_bit(CPE_NOMINAL, &tasha->status_mask);
13394 tasha_codec_update_sido_voltage(tasha, SIDO_VOLTAGE_NOMINAL_MV);
13395
Meng Wang15c825d2018-09-06 10:49:18 +080013396 if (tasha_codec_cpe_fll_update_divider(component, clk_freq)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013397 ret = -EINVAL;
13398 goto done;
13399 }
Meng Wang15c825d2018-09-06 10:49:18 +080013400 snd_soc_component_update_bits(component,
13401 WCD9335_CPE_FLL_FLL_MODE,
13402 0x10, 0x10);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013403 } else {
Meng Wang15c825d2018-09-06 10:49:18 +080013404 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013405 "%s: Invalid clk_freq request %d for CPE FLL\n",
13406 __func__, clk_freq);
13407 ret = -EINVAL;
13408 }
13409
13410done:
Meng Wang15c825d2018-09-06 10:49:18 +080013411 snd_soc_component_update_bits(component, WCD9335_CPE_FLL_FLL_MODE,
13412 0x10, 0x00);
13413 snd_soc_component_update_bits(component, WCD9335_CPE_FLL_FLL_MODE,
13414 0x08, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013415 return ret;
13416}
13417
13418
Meng Wang15c825d2018-09-06 10:49:18 +080013419static int tasha_codec_cpe_fll_enable(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013420 bool enable)
13421{
Meng Wang15c825d2018-09-06 10:49:18 +080013422 struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent);
13423 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013424 u8 clk_sel_reg_val = 0x00;
13425
Meng Wang15c825d2018-09-06 10:49:18 +080013426 dev_dbg(component->dev, "%s: enable = %s\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013427 __func__, enable ? "true" : "false");
13428
13429 if (enable) {
13430 if (tasha_cdc_is_svs_enabled(tasha)) {
13431 /* FLL enable is always at SVS */
Meng Wang15c825d2018-09-06 10:49:18 +080013432 if (__tasha_cdc_change_cpe_clk(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013433 CPE_FLL_CLK_75MHZ)) {
Meng Wang15c825d2018-09-06 10:49:18 +080013434 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013435 "%s: clk change to %d failed\n",
13436 __func__, CPE_FLL_CLK_75MHZ);
13437 return -EINVAL;
13438 }
13439 } else {
Meng Wang15c825d2018-09-06 10:49:18 +080013440 if (tasha_codec_cpe_fll_update_divider(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013441 CPE_FLL_CLK_75MHZ)) {
Meng Wang15c825d2018-09-06 10:49:18 +080013442 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013443 "%s: clk change to %d failed\n",
13444 __func__, CPE_FLL_CLK_75MHZ);
13445 return -EINVAL;
13446 }
13447 }
13448
13449 if (TASHA_IS_1_0(wcd9xxx)) {
Meng Wang15c825d2018-09-06 10:49:18 +080013450 tasha_cdc_mclk_enable(component, true, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013451 clk_sel_reg_val = 0x02;
13452 }
13453
13454 /* Setup CPE reference clk */
Meng Wang15c825d2018-09-06 10:49:18 +080013455 snd_soc_component_update_bits(component, WCD9335_ANA_CLK_TOP,
13456 0x02, clk_sel_reg_val);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013457
13458 /* enable CPE FLL reference clk */
Meng Wang15c825d2018-09-06 10:49:18 +080013459 snd_soc_component_update_bits(component, WCD9335_ANA_CLK_TOP,
13460 0x01, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013461
13462 /* program the PLL */
Meng Wang15c825d2018-09-06 10:49:18 +080013463 snd_soc_component_update_bits(component,
13464 WCD9335_CPE_FLL_USER_CTL_0,
13465 0x01, 0x01);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013466
13467 /* TEST clk setting */
Meng Wang15c825d2018-09-06 10:49:18 +080013468 snd_soc_component_update_bits(component,
13469 WCD9335_CPE_FLL_TEST_CTL_0,
13470 0x80, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013471 /* set FLL mode to HW controlled */
Meng Wang15c825d2018-09-06 10:49:18 +080013472 snd_soc_component_update_bits(component,
13473 WCD9335_CPE_FLL_FLL_MODE,
13474 0x60, 0x00);
13475 snd_soc_component_write(component, WCD9335_CPE_FLL_FLL_MODE,
13476 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013477 } else {
13478 /* disable CPE FLL reference clk */
Meng Wang15c825d2018-09-06 10:49:18 +080013479 snd_soc_component_update_bits(component, WCD9335_ANA_CLK_TOP,
13480 0x01, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013481 /* undo TEST clk setting */
Meng Wang15c825d2018-09-06 10:49:18 +080013482 snd_soc_component_update_bits(component,
13483 WCD9335_CPE_FLL_TEST_CTL_0,
13484 0x80, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013485 /* undo FLL mode to HW control */
Meng Wang15c825d2018-09-06 10:49:18 +080013486 snd_soc_component_write(component,
13487 WCD9335_CPE_FLL_FLL_MODE, 0x00);
13488 snd_soc_component_update_bits(component,
13489 WCD9335_CPE_FLL_FLL_MODE,
13490 0x60, 0x20);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013491 /* undo the PLL */
Meng Wang15c825d2018-09-06 10:49:18 +080013492 snd_soc_component_update_bits(component,
13493 WCD9335_CPE_FLL_USER_CTL_0,
13494 0x01, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013495
13496 if (TASHA_IS_1_0(wcd9xxx))
Meng Wang15c825d2018-09-06 10:49:18 +080013497 tasha_cdc_mclk_enable(component, false, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013498
13499 /*
13500 * FLL could get disabled while at nominal,
13501 * scale it back to SVS
13502 */
13503 if (tasha_cdc_is_svs_enabled(tasha))
Meng Wang15c825d2018-09-06 10:49:18 +080013504 __tasha_cdc_change_cpe_clk(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013505 CPE_FLL_CLK_75MHZ);
13506 }
13507
13508 return 0;
13509
13510}
13511
13512static void tasha_cdc_query_cpe_clk_plan(void *data,
13513 struct cpe_svc_cfg_clk_plan *clk_freq)
13514{
Meng Wang15c825d2018-09-06 10:49:18 +080013515 struct snd_soc_component *component = data;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013516 struct tasha_priv *tasha;
13517 u32 cpe_clk_khz;
13518
Meng Wang15c825d2018-09-06 10:49:18 +080013519 if (!component) {
13520 pr_err("%s: Invalid component handle\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013521 __func__);
13522 return;
13523 }
13524
Meng Wang15c825d2018-09-06 10:49:18 +080013525 tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013526 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13527
Meng Wang15c825d2018-09-06 10:49:18 +080013528 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013529 "%s: current_clk_freq = %u\n",
13530 __func__, tasha->current_cpe_clk_freq);
13531
13532 clk_freq->current_clk_feq = cpe_clk_khz;
13533 clk_freq->num_clk_freqs = 2;
13534
13535 if (tasha_cdc_is_svs_enabled(tasha)) {
13536 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ / 1000;
13537 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ / 1000;
13538 } else {
13539 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ;
13540 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ;
13541 }
13542}
13543
13544static void tasha_cdc_change_cpe_clk(void *data,
13545 u32 clk_freq)
13546{
Meng Wang15c825d2018-09-06 10:49:18 +080013547 struct snd_soc_component *component = data;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013548 struct tasha_priv *tasha;
13549 u32 cpe_clk_khz, req_freq = 0;
13550
Meng Wang15c825d2018-09-06 10:49:18 +080013551 if (!component) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013552 pr_err("%s: Invalid codec handle\n",
13553 __func__);
13554 return;
13555 }
13556
Meng Wang15c825d2018-09-06 10:49:18 +080013557 tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013558 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13559
13560 if (tasha_cdc_is_svs_enabled(tasha)) {
13561 if ((clk_freq * 1000) <= CPE_FLL_CLK_75MHZ)
13562 req_freq = CPE_FLL_CLK_75MHZ;
13563 else
13564 req_freq = CPE_FLL_CLK_150MHZ;
13565 }
13566
Meng Wang15c825d2018-09-06 10:49:18 +080013567 dev_dbg(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013568 "%s: requested clk_freq = %u, current clk_freq = %u\n",
13569 __func__, clk_freq * 1000,
13570 tasha->current_cpe_clk_freq);
13571
13572 if (tasha_cdc_is_svs_enabled(tasha)) {
Meng Wang15c825d2018-09-06 10:49:18 +080013573 if (__tasha_cdc_change_cpe_clk(component, req_freq))
13574 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013575 "%s: clock/voltage scaling failed\n",
13576 __func__);
13577 }
13578}
13579
Meng Wang15c825d2018-09-06 10:49:18 +080013580static int tasha_codec_slim_reserve_bw(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013581 u32 bw_ops, bool commit)
13582{
13583 struct wcd9xxx *wcd9xxx;
13584
Meng Wang15c825d2018-09-06 10:49:18 +080013585 if (!component) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013586 pr_err("%s: Invalid handle to codec\n",
13587 __func__);
13588 return -EINVAL;
13589 }
13590
Meng Wang15c825d2018-09-06 10:49:18 +080013591 wcd9xxx = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013592
13593 if (!wcd9xxx) {
Meng Wang15c825d2018-09-06 10:49:18 +080013594 dev_err(component->dev, "%s: Invalid parent drv_data\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013595 __func__);
13596 return -EINVAL;
13597 }
13598
13599 return wcd9xxx_slim_reserve_bw(wcd9xxx, bw_ops, commit);
13600}
13601
Meng Wang15c825d2018-09-06 10:49:18 +080013602static int tasha_codec_vote_max_bw(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013603 bool vote)
13604{
13605 u32 bw_ops;
Meng Wang15c825d2018-09-06 10:49:18 +080013606 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013607
13608 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
13609 return 0;
13610
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053013611 mutex_lock(&tasha->sb_clk_gear_lock);
13612 if (vote) {
13613 tasha->ref_count++;
13614 if (tasha->ref_count == 1) {
13615 bw_ops = SLIM_BW_CLK_GEAR_9;
Meng Wang15c825d2018-09-06 10:49:18 +080013616 tasha_codec_slim_reserve_bw(component,
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053013617 bw_ops, true);
13618 }
13619 } else if (!vote && tasha->ref_count > 0) {
13620 tasha->ref_count--;
13621 if (tasha->ref_count == 0) {
13622 bw_ops = SLIM_BW_UNVOTE;
Meng Wang15c825d2018-09-06 10:49:18 +080013623 tasha_codec_slim_reserve_bw(component,
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053013624 bw_ops, true);
13625 }
13626 };
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013627
Meng Wang15c825d2018-09-06 10:49:18 +080013628 dev_dbg(component->dev, "%s Value of counter after vote or un-vote is %d\n",
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053013629 __func__, tasha->ref_count);
13630
13631 mutex_unlock(&tasha->sb_clk_gear_lock);
13632
13633 return 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013634}
13635
Meng Wang15c825d2018-09-06 10:49:18 +080013636static int tasha_cpe_err_irq_control(struct snd_soc_component *component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013637 enum cpe_err_irq_cntl_type cntl_type, u8 *status)
13638{
Meng Wang15c825d2018-09-06 10:49:18 +080013639 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013640 u8 irq_bits;
13641
13642 if (TASHA_IS_2_0(tasha->wcd9xxx))
13643 irq_bits = 0xFF;
13644 else
13645 irq_bits = 0x3F;
13646
13647 if (status)
13648 irq_bits = (*status) & irq_bits;
13649
13650 switch (cntl_type) {
13651 case CPE_ERR_IRQ_MASK:
Meng Wang15c825d2018-09-06 10:49:18 +080013652 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013653 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13654 irq_bits, irq_bits);
13655 break;
13656 case CPE_ERR_IRQ_UNMASK:
Meng Wang15c825d2018-09-06 10:49:18 +080013657 snd_soc_component_update_bits(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013658 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13659 irq_bits, 0x00);
13660 break;
13661 case CPE_ERR_IRQ_CLEAR:
Meng Wang15c825d2018-09-06 10:49:18 +080013662 snd_soc_component_write(component,
13663 WCD9335_CPE_SS_SS_ERROR_INT_CLEAR,
13664 irq_bits);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013665 break;
13666 case CPE_ERR_IRQ_STATUS:
13667 if (!status)
13668 return -EINVAL;
Meng Wang15c825d2018-09-06 10:49:18 +080013669 *status = snd_soc_component_read32(component,
13670 WCD9335_CPE_SS_SS_ERROR_INT_STATUS);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013671 break;
13672 }
13673
13674 return 0;
13675}
13676
13677static const struct wcd_cpe_cdc_cb cpe_cb = {
13678 .cdc_clk_en = tasha_codec_internal_rco_ctrl,
13679 .cpe_clk_en = tasha_codec_cpe_fll_enable,
13680 .get_afe_out_port_id = tasha_codec_get_mad_port_id,
13681 .lab_cdc_ch_ctl = tasha_codec_enable_slimtx_mad,
13682 .cdc_ext_clk = tasha_cdc_mclk_enable,
13683 .bus_vote_bw = tasha_codec_vote_max_bw,
13684 .cpe_err_irq_control = tasha_cpe_err_irq_control,
13685};
13686
13687static struct cpe_svc_init_param cpe_svc_params = {
13688 .version = CPE_SVC_INIT_PARAM_V1,
13689 .query_freq_plans_cb = tasha_cdc_query_cpe_clk_plan,
13690 .change_freq_plan_cb = tasha_cdc_change_cpe_clk,
13691};
13692
Meng Wang15c825d2018-09-06 10:49:18 +080013693static int tasha_cpe_initialize(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013694{
Meng Wang15c825d2018-09-06 10:49:18 +080013695 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013696 struct wcd_cpe_params cpe_params;
13697
13698 memset(&cpe_params, 0,
13699 sizeof(struct wcd_cpe_params));
Meng Wang15c825d2018-09-06 10:49:18 +080013700 cpe_params.component = component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013701 cpe_params.get_cpe_core = tasha_codec_get_cpe_core;
13702 cpe_params.cdc_cb = &cpe_cb;
13703 cpe_params.dbg_mode = cpe_debug_mode;
13704 cpe_params.cdc_major_ver = CPE_SVC_CODEC_WCD9335;
13705 cpe_params.cdc_minor_ver = CPE_SVC_CODEC_V1P0;
13706 cpe_params.cdc_id = CPE_SVC_CODEC_WCD9335;
13707
13708 cpe_params.cdc_irq_info.cpe_engine_irq =
13709 WCD9335_IRQ_SVA_OUTBOX1;
13710 cpe_params.cdc_irq_info.cpe_err_irq =
13711 WCD9335_IRQ_SVA_ERROR;
13712 cpe_params.cdc_irq_info.cpe_fatal_irqs =
13713 TASHA_CPE_FATAL_IRQS;
13714
Meng Wang15c825d2018-09-06 10:49:18 +080013715 cpe_svc_params.context = component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013716 cpe_params.cpe_svc_params = &cpe_svc_params;
13717
Meng Wang15c825d2018-09-06 10:49:18 +080013718 tasha->cpe_core = wcd_cpe_init("cpe_9335", component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013719 &cpe_params);
13720 if (IS_ERR_OR_NULL(tasha->cpe_core)) {
Meng Wang15c825d2018-09-06 10:49:18 +080013721 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013722 "%s: Failed to enable CPE\n",
13723 __func__);
13724 return -EINVAL;
13725 }
13726
13727 return 0;
13728}
13729
13730static const struct wcd_resmgr_cb tasha_resmgr_cb = {
13731 .cdc_rco_ctrl = __tasha_codec_internal_rco_ctrl,
13732};
13733
13734static int tasha_device_down(struct wcd9xxx *wcd9xxx)
13735{
Meng Wang15c825d2018-09-06 10:49:18 +080013736 struct snd_soc_component *component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013737 struct tasha_priv *priv;
13738 int count;
13739 int i = 0;
13740
Meng Wang15c825d2018-09-06 10:49:18 +080013741 component = (struct snd_soc_component *)(wcd9xxx->ssr_priv);
13742 priv = snd_soc_component_get_drvdata(component);
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053013743 snd_event_notify(priv->dev->parent, SND_EVENT_DOWN);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013744 wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT);
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053013745
13746 if (!priv->swr_ctrl_data)
13747 return -EINVAL;
13748
13749 for (i = 0; i < priv->nr; i++) {
13750 if (is_snd_event_fwk_enabled())
13751 swrm_wcd_notify(
13752 priv->swr_ctrl_data[i].swr_pdev,
13753 SWR_DEVICE_SSR_DOWN, NULL);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013754 swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev,
13755 SWR_DEVICE_DOWN, NULL);
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053013756 }
13757
13758 if (!is_snd_event_fwk_enabled())
13759 snd_soc_card_change_online_state(component->card, 0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013760 for (count = 0; count < NUM_CODEC_DAIS; count++)
13761 priv->dai[count].bus_down_in_recovery = true;
13762
13763 priv->resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
13764
13765 return 0;
13766}
13767
13768static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx)
13769{
13770 int i, ret = 0;
13771 struct wcd9xxx *control;
Meng Wang15c825d2018-09-06 10:49:18 +080013772 struct snd_soc_component *component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013773 struct tasha_priv *tasha;
13774 struct wcd9xxx_pdata *pdata;
13775
Meng Wang15c825d2018-09-06 10:49:18 +080013776 component = (struct snd_soc_component *)(wcd9xxx->ssr_priv);
13777 tasha = snd_soc_component_get_drvdata(component);
13778 control = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013779
13780 wcd9xxx_set_power_state(tasha->wcd9xxx,
13781 WCD_REGION_POWER_COLLAPSE_REMOVE,
13782 WCD9XXX_DIG_CORE_REGION_1);
13783
13784 mutex_lock(&tasha->codec_mutex);
13785
13786 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13787 control->slim_slave->laddr;
13788 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13789 control->slim->laddr;
Meng Wang15c825d2018-09-06 10:49:18 +080013790 tasha_init_slim_slave_cfg(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013791 if (tasha->machine_codec_event_cb)
Meng Wang15c825d2018-09-06 10:49:18 +080013792 tasha->machine_codec_event_cb(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013793 WCD9335_CODEC_EVENT_CODEC_UP);
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053013794 if (!is_snd_event_fwk_enabled())
13795 snd_soc_card_change_online_state(component->card, 1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013796
13797 /* Class-H Init*/
13798 wcd_clsh_init(&tasha->clsh_d);
13799
13800 for (i = 0; i < TASHA_MAX_MICBIAS; i++)
13801 tasha->micb_ref[i] = 0;
13802
13803 tasha_update_reg_defaults(tasha);
13804
Meng Wang15c825d2018-09-06 10:49:18 +080013805 tasha->component = component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013806
Meng Wang15c825d2018-09-06 10:49:18 +080013807 dev_dbg(component->dev, "%s: MCLK Rate = %x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013808 __func__, control->mclk_rate);
13809
13810 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
Meng Wang15c825d2018-09-06 10:49:18 +080013811 snd_soc_component_update_bits(component,
13812 WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13813 0x03, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013814 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
Meng Wang15c825d2018-09-06 10:49:18 +080013815 snd_soc_component_update_bits(component,
13816 WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13817 0x03, 0x01);
13818 tasha_codec_init_reg(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013819
13820 wcd_resmgr_post_ssr_v2(tasha->resmgr);
13821
Meng Wang15c825d2018-09-06 10:49:18 +080013822 tasha_enable_efuse_sensing(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013823
Meng Wang15c825d2018-09-06 10:49:18 +080013824 regcache_mark_dirty(component->regmap);
13825 regcache_sync(component->regmap);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013826
Meng Wang15c825d2018-09-06 10:49:18 +080013827 pdata = dev_get_platdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013828 ret = tasha_handle_pdata(tasha, pdata);
13829 if (ret < 0)
Meng Wang15c825d2018-09-06 10:49:18 +080013830 dev_err(component->dev, "%s: invalid pdata\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013831
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053013832 /* Reset reference counter for voting for max bw */
13833 tasha->ref_count = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013834 /* MBHC Init */
13835 wcd_mbhc_deinit(&tasha->mbhc);
13836 tasha->mbhc_started = false;
13837
13838 /* Initialize MBHC module */
Meng Wang15c825d2018-09-06 10:49:18 +080013839 ret = wcd_mbhc_init(&tasha->mbhc, component, &mbhc_cb, &intr_ids,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013840 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13841 if (ret)
Meng Wang15c825d2018-09-06 10:49:18 +080013842 dev_err(component->dev, "%s: mbhc initialization failed\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013843 __func__);
13844 else
Meng Wang15c825d2018-09-06 10:49:18 +080013845 tasha_mbhc_hs_detect(component, tasha->mbhc.mbhc_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013846
13847 tasha_cleanup_irqs(tasha);
13848 ret = tasha_setup_irqs(tasha);
13849 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +080013850 dev_err(component->dev, "%s: tasha irq setup failed %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013851 __func__, ret);
13852 goto err;
13853 }
13854
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053013855 if (!tasha->swr_ctrl_data) {
13856 ret = -EINVAL;
13857 goto err;
13858 }
13859
13860 if (is_snd_event_fwk_enabled()) {
13861 for (i = 0; i < tasha->nr; i++)
13862 swrm_wcd_notify(
13863 tasha->swr_ctrl_data[i].swr_pdev,
13864 SWR_DEVICE_SSR_UP, NULL);
13865 }
13866
Meng Wang15c825d2018-09-06 10:49:18 +080013867 tasha_set_spkr_mode(component, tasha->spkr_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013868 wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT);
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053013869 snd_event_notify(tasha->dev->parent, SND_EVENT_UP);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013870err:
13871 mutex_unlock(&tasha->codec_mutex);
13872 return ret;
13873}
13874
13875static struct regulator *tasha_codec_find_ondemand_regulator(
Meng Wang15c825d2018-09-06 10:49:18 +080013876 struct snd_soc_component *component, const char *name)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013877{
13878 int i;
Meng Wang15c825d2018-09-06 10:49:18 +080013879 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013880 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
Meng Wang15c825d2018-09-06 10:49:18 +080013881 struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013882
13883 for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
13884 if (pdata->regulator[i].ondemand &&
13885 wcd9xxx->supplies[i].supply &&
13886 !strcmp(wcd9xxx->supplies[i].supply, name))
13887 return wcd9xxx->supplies[i].consumer;
13888 }
13889
13890 dev_dbg(tasha->dev, "Warning: regulator not found:%s\n",
13891 name);
13892 return NULL;
13893}
13894
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053013895static void tasha_ssr_disable(struct device *dev, void *data)
13896{
13897 struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev);
13898 struct tasha_priv *tasha;
13899 struct snd_soc_component *component;
13900 int count = 0;
13901
13902 if (!wcd9xxx) {
13903 dev_dbg(dev, "%s: wcd9xxx pointer NULL.\n", __func__);
13904 return;
13905 }
13906 component = (struct snd_soc_component *)(wcd9xxx->ssr_priv);
13907 tasha = snd_soc_component_get_drvdata(component);
13908
13909 for (count = 0; count < NUM_CODEC_DAIS; count++)
13910 tasha->dai[count].bus_down_in_recovery = true;
13911}
13912
13913static const struct snd_event_ops tasha_ssr_ops = {
13914 .disable = tasha_ssr_disable,
13915};
13916
Meng Wang15c825d2018-09-06 10:49:18 +080013917static int tasha_codec_probe(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013918{
13919 struct wcd9xxx *control;
13920 struct tasha_priv *tasha;
13921 struct wcd9xxx_pdata *pdata;
Meng Wang15c825d2018-09-06 10:49:18 +080013922 struct snd_soc_dapm_context *dapm =
13923 snd_soc_component_get_dapm(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013924 int i, ret;
13925 void *ptr = NULL;
13926 struct regulator *supply;
13927
Meng Wang15c825d2018-09-06 10:49:18 +080013928 control = dev_get_drvdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013929
Meng Wang15c825d2018-09-06 10:49:18 +080013930 snd_soc_component_init_regmap(component, control->regmap);
13931
13932 dev_info(component->dev, "%s()\n", __func__);
13933 tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013934 tasha->intf_type = wcd9xxx_get_intf_type();
13935
13936 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13937 control->dev_down = tasha_device_down;
13938 control->post_reset = tasha_post_reset_cb;
Meng Wang15c825d2018-09-06 10:49:18 +080013939 control->ssr_priv = (void *)component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013940 }
13941
13942 /* Resource Manager post Init */
Meng Wang15c825d2018-09-06 10:49:18 +080013943 ret = wcd_resmgr_post_init(tasha->resmgr, &tasha_resmgr_cb, component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013944 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +080013945 dev_err(component->dev, "%s: wcd resmgr post init failed\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013946 __func__);
13947 goto err;
13948 }
13949 /* Class-H Init*/
13950 wcd_clsh_init(&tasha->clsh_d);
13951 /* Default HPH Mode to Class-H HiFi */
13952 tasha->hph_mode = CLS_H_HIFI;
13953
Meng Wang15c825d2018-09-06 10:49:18 +080013954 tasha->component = component;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013955 for (i = 0; i < COMPANDER_MAX; i++)
13956 tasha->comp_enabled[i] = 0;
13957
13958 tasha->spkr_gain_offset = RX_GAIN_OFFSET_0_DB;
13959 tasha->intf_type = wcd9xxx_get_intf_type();
Meng Wang15c825d2018-09-06 10:49:18 +080013960 tasha_update_reg_reset_values(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013961 pr_debug("%s: MCLK Rate = %x\n", __func__, control->mclk_rate);
13962 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
Meng Wang15c825d2018-09-06 10:49:18 +080013963 snd_soc_component_update_bits(component,
13964 WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13965 0x03, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013966 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
Meng Wang15c825d2018-09-06 10:49:18 +080013967 snd_soc_component_update_bits(component,
13968 WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13969 0x03, 0x01);
13970 tasha_codec_init_reg(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013971
Meng Wang15c825d2018-09-06 10:49:18 +080013972 tasha_enable_efuse_sensing(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013973
Meng Wang15c825d2018-09-06 10:49:18 +080013974 pdata = dev_get_platdata(component->dev->parent);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013975 ret = tasha_handle_pdata(tasha, pdata);
13976 if (ret < 0) {
13977 pr_err("%s: bad pdata\n", __func__);
13978 goto err;
13979 }
13980
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +053013981 for (i = ON_DEMAND_MICBIAS; i < ON_DEMAND_SUPPLIES_MAX; i++) {
13982 supply = tasha_codec_find_ondemand_regulator(component,
13983 on_demand_supply_name[i]);
13984 if (supply) {
13985 tasha->on_demand_list[i].supply = supply;
13986 tasha->on_demand_list[i].ondemand_supply_count =
13987 0;
13988 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013989 }
13990
Meng Wang15c825d2018-09-06 10:49:18 +080013991 tasha->fw_data = devm_kzalloc(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013992 sizeof(*(tasha->fw_data)), GFP_KERNEL);
13993 if (!tasha->fw_data)
13994 goto err;
13995 set_bit(WCD9XXX_ANC_CAL, tasha->fw_data->cal_bit);
13996 set_bit(WCD9XXX_MBHC_CAL, tasha->fw_data->cal_bit);
13997 set_bit(WCD9XXX_MAD_CAL, tasha->fw_data->cal_bit);
13998 set_bit(WCD9XXX_VBAT_CAL, tasha->fw_data->cal_bit);
13999
14000 ret = wcd_cal_create_hwdep(tasha->fw_data,
Meng Wang15c825d2018-09-06 10:49:18 +080014001 WCD9XXX_CODEC_HWDEP_NODE, component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014002 if (ret < 0) {
Meng Wang15c825d2018-09-06 10:49:18 +080014003 dev_err(component->dev, "%s hwdep failed %d\n", __func__, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014004 goto err_hwdep;
14005 }
14006
14007 /* Initialize MBHC module */
14008 if (TASHA_IS_2_0(tasha->wcd9xxx)) {
14009 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].reg =
14010 WCD9335_MBHC_FSM_STATUS;
14011 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].mask = 0x01;
14012 }
Meng Wang15c825d2018-09-06 10:49:18 +080014013 ret = wcd_mbhc_init(&tasha->mbhc, component, &mbhc_cb, &intr_ids,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014014 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
14015 if (ret) {
14016 pr_err("%s: mbhc initialization failed\n", __func__);
14017 goto err_hwdep;
14018 }
14019
Meng Wang15c825d2018-09-06 10:49:18 +080014020 ptr = devm_kzalloc(component->dev, (sizeof(tasha_rx_chs) +
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014021 sizeof(tasha_tx_chs)), GFP_KERNEL);
14022 if (!ptr) {
14023 ret = -ENOMEM;
14024 goto err_hwdep;
14025 }
14026
14027 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
14028 snd_soc_dapm_new_controls(dapm, tasha_dapm_i2s_widgets,
14029 ARRAY_SIZE(tasha_dapm_i2s_widgets));
14030 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
14031 ARRAY_SIZE(audio_i2s_map));
14032 for (i = 0; i < ARRAY_SIZE(tasha_i2s_dai); i++) {
14033 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
14034 init_waitqueue_head(&tasha->dai[i].dai_wait);
14035 }
14036 } else if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
14037 for (i = 0; i < NUM_CODEC_DAIS; i++) {
14038 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
14039 init_waitqueue_head(&tasha->dai[i].dai_wait);
14040 }
14041 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
14042 control->slim_slave->laddr;
14043 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
14044 control->slim->laddr;
14045 tasha_slimbus_slave_port_cfg.slave_port_mapping[0] =
14046 TASHA_TX13;
Meng Wang15c825d2018-09-06 10:49:18 +080014047 tasha_init_slim_slave_cfg(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014048 }
14049
Meng Wang15c825d2018-09-06 10:49:18 +080014050 snd_soc_add_component_controls(component, impedance_detect_controls,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014051 ARRAY_SIZE(impedance_detect_controls));
Meng Wang15c825d2018-09-06 10:49:18 +080014052 snd_soc_add_component_controls(component, hph_type_detect_controls,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014053 ARRAY_SIZE(hph_type_detect_controls));
14054
Meng Wang15c825d2018-09-06 10:49:18 +080014055 snd_soc_add_component_controls(component,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014056 tasha_analog_gain_controls,
14057 ARRAY_SIZE(tasha_analog_gain_controls));
Laxminath Kasamf2687c92018-06-14 12:44:04 +053014058 if (tasha->is_wsa_attach)
Meng Wang15c825d2018-09-06 10:49:18 +080014059 snd_soc_add_component_controls(component,
Laxminath Kasamf2687c92018-06-14 12:44:04 +053014060 tasha_spkr_wsa_controls,
Mangesh Kunchamwardaf02b02018-06-28 19:42:24 +053014061 ARRAY_SIZE(tasha_spkr_wsa_controls));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014062 control->num_rx_port = TASHA_RX_MAX;
14063 control->rx_chs = ptr;
14064 memcpy(control->rx_chs, tasha_rx_chs, sizeof(tasha_rx_chs));
14065 control->num_tx_port = TASHA_TX_MAX;
14066 control->tx_chs = ptr + sizeof(tasha_rx_chs);
14067 memcpy(control->tx_chs, tasha_tx_chs, sizeof(tasha_tx_chs));
14068
14069 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
14070 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
14071 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback");
14072 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture");
14073
14074 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
14075 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback");
14076 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture");
14077 snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback");
14078 snd_soc_dapm_ignore_suspend(dapm, "AIF Mix Playback");
14079 snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX");
14080 snd_soc_dapm_ignore_suspend(dapm, "VIfeed");
14081 snd_soc_dapm_ignore_suspend(dapm, "AIF5 CPE TX");
14082 }
14083
14084 snd_soc_dapm_sync(dapm);
14085
14086 ret = tasha_setup_irqs(tasha);
14087 if (ret) {
14088 pr_err("%s: tasha irq setup failed %d\n", __func__, ret);
14089 goto err_pdata;
14090 }
14091
Meng Wang15c825d2018-09-06 10:49:18 +080014092 ret = tasha_cpe_initialize(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014093 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +080014094 dev_err(component->dev,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014095 "%s: cpe initialization failed, err = %d\n",
14096 __func__, ret);
14097 /* Do not fail probe if CPE failed */
14098 ret = 0;
14099 }
14100
14101 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
14102 tasha->tx_hpf_work[i].tasha = tasha;
14103 tasha->tx_hpf_work[i].decimator = i;
14104 INIT_DELAYED_WORK(&tasha->tx_hpf_work[i].dwork,
14105 tasha_tx_hpf_corner_freq_callback);
14106 }
14107
14108 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
14109 tasha->tx_mute_dwork[i].tasha = tasha;
14110 tasha->tx_mute_dwork[i].decimator = i;
14111 INIT_DELAYED_WORK(&tasha->tx_mute_dwork[i].dwork,
14112 tasha_tx_mute_update_callback);
14113 }
14114
14115 tasha->spk_anc_dwork.tasha = tasha;
14116 INIT_DELAYED_WORK(&tasha->spk_anc_dwork.dwork,
14117 tasha_spk_anc_update_callback);
14118
14119 mutex_lock(&tasha->codec_mutex);
14120 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
14121 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
14122 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
14123 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
14124 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
14125 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
14126 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
14127 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
14128 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
14129 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
14130 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
14131 mutex_unlock(&tasha->codec_mutex);
14132 snd_soc_dapm_sync(dapm);
14133
14134 return ret;
14135
14136err_pdata:
Meng Wang15c825d2018-09-06 10:49:18 +080014137 devm_kfree(component->dev, ptr);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014138 control->rx_chs = NULL;
14139 control->tx_chs = NULL;
14140err_hwdep:
Meng Wang15c825d2018-09-06 10:49:18 +080014141 devm_kfree(component->dev, tasha->fw_data);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014142 tasha->fw_data = NULL;
14143err:
14144 return ret;
14145}
14146
Meng Wang15c825d2018-09-06 10:49:18 +080014147static void tasha_codec_remove(struct snd_soc_component *component)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014148{
Meng Wang15c825d2018-09-06 10:49:18 +080014149 struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014150 struct wcd9xxx *control;
14151
Meng Wang15c825d2018-09-06 10:49:18 +080014152 control = dev_get_drvdata(component->dev->parent);
Meng Wang3b194492017-09-27 12:20:22 +080014153 control->num_rx_port = 0;
14154 control->num_tx_port = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014155 control->rx_chs = NULL;
14156 control->tx_chs = NULL;
14157
14158 tasha_cleanup_irqs(tasha);
14159 /* Cleanup MBHC */
Meng Wang3b194492017-09-27 12:20:22 +080014160 wcd_mbhc_deinit(&tasha->mbhc);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014161 /* Cleanup resmgr */
14162
Meng Wang15c825d2018-09-06 10:49:18 +080014163 return;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014164}
14165
Meng Wang15c825d2018-09-06 10:49:18 +080014166static const struct snd_soc_component_driver soc_codec_dev_tasha = {
14167 .name = DRV_NAME,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014168 .probe = tasha_codec_probe,
14169 .remove = tasha_codec_remove,
Meng Wang15c825d2018-09-06 10:49:18 +080014170 .controls = tasha_snd_controls,
14171 .num_controls = ARRAY_SIZE(tasha_snd_controls),
14172 .dapm_widgets = tasha_dapm_widgets,
14173 .num_dapm_widgets = ARRAY_SIZE(tasha_dapm_widgets),
14174 .dapm_routes = audio_map,
14175 .num_dapm_routes = ARRAY_SIZE(audio_map),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014176};
14177
14178#ifdef CONFIG_PM
14179static int tasha_suspend(struct device *dev)
14180{
14181 struct platform_device *pdev = to_platform_device(dev);
14182 struct tasha_priv *tasha = platform_get_drvdata(pdev);
14183
14184 dev_dbg(dev, "%s: system suspend\n", __func__);
14185 if (cancel_delayed_work_sync(&tasha->power_gate_work))
14186 tasha_codec_power_gate_digital_core(tasha);
14187
14188 return 0;
14189}
14190
14191static int tasha_resume(struct device *dev)
14192{
14193 struct platform_device *pdev = to_platform_device(dev);
14194 struct tasha_priv *tasha = platform_get_drvdata(pdev);
14195
14196 if (!tasha) {
14197 dev_err(dev, "%s: tasha private data is NULL\n", __func__);
14198 return -EINVAL;
14199 }
14200 dev_dbg(dev, "%s: system resume\n", __func__);
14201 return 0;
14202}
14203
14204static const struct dev_pm_ops tasha_pm_ops = {
14205 .suspend = tasha_suspend,
14206 .resume = tasha_resume,
14207};
14208#endif
14209
14210static int tasha_swrm_read(void *handle, int reg)
14211{
14212 struct tasha_priv *tasha;
14213 struct wcd9xxx *wcd9xxx;
14214 unsigned short swr_rd_addr_base;
14215 unsigned short swr_rd_data_base;
14216 int val, ret;
14217
14218 if (!handle) {
14219 pr_err("%s: NULL handle\n", __func__);
14220 return -EINVAL;
14221 }
14222 tasha = (struct tasha_priv *)handle;
14223 wcd9xxx = tasha->wcd9xxx;
14224
14225 dev_dbg(tasha->dev, "%s: Reading soundwire register, 0x%x\n",
14226 __func__, reg);
14227 swr_rd_addr_base = WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0;
14228 swr_rd_data_base = WCD9335_SWR_AHB_BRIDGE_RD_DATA_0;
14229 /* read_lock */
14230 mutex_lock(&tasha->swr_read_lock);
14231 ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base,
14232 (u8 *)&reg, 4);
14233 if (ret < 0) {
14234 pr_err("%s: RD Addr Failure\n", __func__);
14235 goto err;
14236 }
14237 /* Check for RD status */
14238 ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base,
14239 (u8 *)&val, 4);
14240 if (ret < 0) {
14241 pr_err("%s: RD Data Failure\n", __func__);
14242 goto err;
14243 }
14244 ret = val;
14245err:
14246 /* read_unlock */
14247 mutex_unlock(&tasha->swr_read_lock);
14248 return ret;
14249}
14250
14251static int tasha_swrm_i2s_bulk_write(struct wcd9xxx *wcd9xxx,
14252 struct wcd9xxx_reg_val *bulk_reg,
14253 size_t len)
14254{
14255 int i, ret = 0;
14256 unsigned short swr_wr_addr_base;
14257 unsigned short swr_wr_data_base;
14258
14259 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
14260 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
14261
14262 for (i = 0; i < (len * 2); i += 2) {
14263 /* First Write the Data to register */
14264 ret = regmap_bulk_write(wcd9xxx->regmap,
14265 swr_wr_data_base, bulk_reg[i].buf, 4);
14266 if (ret < 0) {
14267 dev_err(wcd9xxx->dev, "%s: WR Data Failure\n",
14268 __func__);
14269 break;
14270 }
14271 /* Next Write Address */
14272 ret = regmap_bulk_write(wcd9xxx->regmap,
14273 swr_wr_addr_base, bulk_reg[i+1].buf, 4);
14274 if (ret < 0) {
14275 dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n",
14276 __func__);
14277 break;
14278 }
14279 }
14280 return ret;
14281}
14282
14283static int tasha_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len)
14284{
14285 struct tasha_priv *tasha;
14286 struct wcd9xxx *wcd9xxx;
14287 struct wcd9xxx_reg_val *bulk_reg;
14288 unsigned short swr_wr_addr_base;
14289 unsigned short swr_wr_data_base;
14290 int i, j, ret;
14291
14292 if (!handle) {
14293 pr_err("%s: NULL handle\n", __func__);
14294 return -EINVAL;
14295 }
14296 if (len <= 0) {
14297 pr_err("%s: Invalid size: %zu\n", __func__, len);
14298 return -EINVAL;
14299 }
14300 tasha = (struct tasha_priv *)handle;
14301 wcd9xxx = tasha->wcd9xxx;
14302
14303 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
14304 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
14305
14306 bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)),
14307 GFP_KERNEL);
14308 if (!bulk_reg)
14309 return -ENOMEM;
14310
14311 for (i = 0, j = 0; i < (len * 2); i += 2, j++) {
14312 bulk_reg[i].reg = swr_wr_data_base;
14313 bulk_reg[i].buf = (u8 *)(&val[j]);
14314 bulk_reg[i].bytes = 4;
14315 bulk_reg[i+1].reg = swr_wr_addr_base;
14316 bulk_reg[i+1].buf = (u8 *)(&reg[j]);
14317 bulk_reg[i+1].bytes = 4;
14318 }
14319 mutex_lock(&tasha->swr_write_lock);
14320
14321 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
14322 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, len);
14323 if (ret) {
14324 dev_err(tasha->dev, "%s: i2s bulk write failed, ret: %d\n",
14325 __func__, ret);
14326 }
14327 } else {
14328 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
14329 (len * 2), false);
14330 if (ret) {
14331 dev_err(tasha->dev, "%s: swrm bulk write failed, ret: %d\n",
14332 __func__, ret);
14333 }
14334 }
14335
14336 mutex_unlock(&tasha->swr_write_lock);
14337 kfree(bulk_reg);
14338
14339 return ret;
14340}
14341
14342static int tasha_swrm_write(void *handle, int reg, int val)
14343{
14344 struct tasha_priv *tasha;
14345 struct wcd9xxx *wcd9xxx;
14346 unsigned short swr_wr_addr_base;
14347 unsigned short swr_wr_data_base;
14348 struct wcd9xxx_reg_val bulk_reg[2];
14349 int ret;
14350
14351 if (!handle) {
14352 pr_err("%s: NULL handle\n", __func__);
14353 return -EINVAL;
14354 }
14355 tasha = (struct tasha_priv *)handle;
14356 wcd9xxx = tasha->wcd9xxx;
14357
14358 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
14359 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
14360
14361 /* First Write the Data to register */
14362 bulk_reg[0].reg = swr_wr_data_base;
14363 bulk_reg[0].buf = (u8 *)(&val);
14364 bulk_reg[0].bytes = 4;
14365 bulk_reg[1].reg = swr_wr_addr_base;
14366 bulk_reg[1].buf = (u8 *)(&reg);
14367 bulk_reg[1].bytes = 4;
14368
14369 mutex_lock(&tasha->swr_write_lock);
14370
14371 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
14372 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, 1);
14373 if (ret) {
14374 dev_err(tasha->dev, "%s: i2s swrm write failed, ret: %d\n",
14375 __func__, ret);
14376 }
14377 } else {
14378 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false);
14379 if (ret < 0)
14380 pr_err("%s: WR Data Failure\n", __func__);
14381 }
14382
14383 mutex_unlock(&tasha->swr_write_lock);
14384 return ret;
14385}
14386
14387static int tasha_swrm_clock(void *handle, bool enable)
14388{
14389 struct tasha_priv *tasha = (struct tasha_priv *) handle;
14390
14391 mutex_lock(&tasha->swr_clk_lock);
14392
14393 dev_dbg(tasha->dev, "%s: swrm clock %s\n",
14394 __func__, (enable?"enable" : "disable"));
14395 if (enable) {
14396 tasha->swr_clk_users++;
14397 if (tasha->swr_clk_users == 1) {
14398 if (TASHA_IS_2_0(tasha->wcd9xxx))
14399 regmap_update_bits(
14400 tasha->wcd9xxx->regmap,
14401 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
14402 0x10, 0x00);
14403 __tasha_cdc_mclk_enable(tasha, true);
14404 regmap_update_bits(tasha->wcd9xxx->regmap,
14405 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
14406 0x01, 0x01);
14407 }
14408 } else {
14409 tasha->swr_clk_users--;
14410 if (tasha->swr_clk_users == 0) {
14411 regmap_update_bits(tasha->wcd9xxx->regmap,
14412 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
14413 0x01, 0x00);
14414 __tasha_cdc_mclk_enable(tasha, false);
14415 if (TASHA_IS_2_0(tasha->wcd9xxx))
14416 regmap_update_bits(
14417 tasha->wcd9xxx->regmap,
14418 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
14419 0x10, 0x10);
14420 }
14421 }
14422 dev_dbg(tasha->dev, "%s: swrm clock users %d\n",
14423 __func__, tasha->swr_clk_users);
14424 mutex_unlock(&tasha->swr_clk_lock);
14425 return 0;
14426}
14427
14428static int tasha_swrm_handle_irq(void *handle,
14429 irqreturn_t (*swrm_irq_handler)(int irq,
14430 void *data),
14431 void *swrm_handle,
14432 int action)
14433{
14434 struct tasha_priv *tasha;
14435 int ret = 0;
14436 struct wcd9xxx *wcd9xxx;
14437
14438 if (!handle) {
14439 pr_err("%s: null handle received\n", __func__);
14440 return -EINVAL;
14441 }
14442 tasha = (struct tasha_priv *) handle;
14443 wcd9xxx = tasha->wcd9xxx;
14444
14445 if (action) {
14446 ret = wcd9xxx_request_irq(&wcd9xxx->core_res,
14447 WCD9335_IRQ_SOUNDWIRE,
14448 swrm_irq_handler,
14449 "Tasha SWR Master", swrm_handle);
14450 if (ret)
14451 dev_err(tasha->dev, "%s: Failed to request irq %d\n",
14452 __func__, WCD9335_IRQ_SOUNDWIRE);
14453 } else
14454 wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9335_IRQ_SOUNDWIRE,
14455 swrm_handle);
14456
14457 return ret;
14458}
14459
14460static void tasha_add_child_devices(struct work_struct *work)
14461{
14462 struct tasha_priv *tasha;
14463 struct platform_device *pdev;
14464 struct device_node *node;
14465 struct wcd9xxx *wcd9xxx;
14466 struct tasha_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
14467 int ret, ctrl_num = 0;
14468 struct wcd_swr_ctrl_platform_data *platdata;
14469 char plat_dev_name[WCD9335_STRING_LEN];
14470
14471 tasha = container_of(work, struct tasha_priv,
14472 tasha_add_child_devices_work);
14473 if (!tasha) {
14474 pr_err("%s: Memory for WCD9335 does not exist\n",
14475 __func__);
14476 return;
14477 }
14478 wcd9xxx = tasha->wcd9xxx;
14479 if (!wcd9xxx) {
14480 pr_err("%s: Memory for WCD9XXX does not exist\n",
14481 __func__);
14482 return;
14483 }
14484 if (!wcd9xxx->dev->of_node) {
14485 pr_err("%s: DT node for wcd9xxx does not exist\n",
14486 __func__);
14487 return;
14488 }
14489
14490 platdata = &tasha->swr_plat_data;
Meng Wang3b194492017-09-27 12:20:22 +080014491 tasha->child_count = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014492
14493 for_each_child_of_node(wcd9xxx->dev->of_node, node) {
14494 if (!strcmp(node->name, "swr_master"))
14495 strlcpy(plat_dev_name, "tasha_swr_ctrl",
14496 (WCD9335_STRING_LEN - 1));
14497 else if (strnstr(node->name, "msm_cdc_pinctrl",
14498 strlen("msm_cdc_pinctrl")) != NULL)
14499 strlcpy(plat_dev_name, node->name,
14500 (WCD9335_STRING_LEN - 1));
14501 else
14502 continue;
14503
14504 pdev = platform_device_alloc(plat_dev_name, -1);
14505 if (!pdev) {
14506 dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n",
14507 __func__);
14508 ret = -ENOMEM;
14509 goto err;
14510 }
14511 pdev->dev.parent = tasha->dev;
14512 pdev->dev.of_node = node;
14513
14514 if (!strcmp(node->name, "swr_master")) {
14515 ret = platform_device_add_data(pdev, platdata,
14516 sizeof(*platdata));
14517 if (ret) {
14518 dev_err(&pdev->dev,
14519 "%s: cannot add plat data ctrl:%d\n",
14520 __func__, ctrl_num);
14521 goto fail_pdev_add;
14522 }
Laxminath Kasamf2687c92018-06-14 12:44:04 +053014523 tasha->is_wsa_attach = true;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014524 }
14525
14526 ret = platform_device_add(pdev);
14527 if (ret) {
14528 dev_err(&pdev->dev,
14529 "%s: Cannot add platform device\n",
14530 __func__);
14531 goto fail_pdev_add;
14532 }
14533
14534 if (!strcmp(node->name, "swr_master")) {
14535 temp = krealloc(swr_ctrl_data,
14536 (ctrl_num + 1) * sizeof(
14537 struct tasha_swr_ctrl_data),
14538 GFP_KERNEL);
14539 if (!temp) {
14540 dev_err(wcd9xxx->dev, "out of memory\n");
14541 ret = -ENOMEM;
14542 goto err;
14543 }
14544 swr_ctrl_data = temp;
14545 swr_ctrl_data[ctrl_num].swr_pdev = pdev;
14546 ctrl_num++;
14547 dev_dbg(&pdev->dev,
14548 "%s: Added soundwire ctrl device(s)\n",
14549 __func__);
14550 tasha->nr = ctrl_num;
14551 tasha->swr_ctrl_data = swr_ctrl_data;
14552 }
Meng Wang3b194492017-09-27 12:20:22 +080014553
14554 if (tasha->child_count < WCD9335_CHILD_DEVICES_MAX)
14555 tasha->pdev_child_devices[tasha->child_count++] = pdev;
14556 else
14557 goto err;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014558 }
14559
14560 return;
14561fail_pdev_add:
14562 platform_device_put(pdev);
14563err:
14564 return;
14565}
14566
14567/*
14568 * tasha_codec_ver: to get tasha codec version
Meng Wang15c825d2018-09-06 10:49:18 +080014569 * @codec: handle to snd_soc_component *
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014570 * return enum codec_variant - version
14571 */
14572enum codec_variant tasha_codec_ver(void)
14573{
14574 return codec_ver;
14575}
14576EXPORT_SYMBOL(tasha_codec_ver);
14577
14578static int __tasha_enable_efuse_sensing(struct tasha_priv *tasha)
14579{
14580 int val, rc;
14581
14582 __tasha_cdc_mclk_enable(tasha, true);
14583
14584 regmap_update_bits(tasha->wcd9xxx->regmap,
14585 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x20);
14586 regmap_update_bits(tasha->wcd9xxx->regmap,
14587 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01);
14588
14589 /*
14590 * 5ms sleep required after enabling efuse control
14591 * before checking the status.
14592 */
14593 usleep_range(5000, 5500);
14594 rc = regmap_read(tasha->wcd9xxx->regmap,
14595 WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS, &val);
14596
14597 if (rc || (!(val & 0x01)))
14598 WARN(1, "%s: Efuse sense is not complete\n", __func__);
14599
14600 __tasha_cdc_mclk_enable(tasha, false);
14601
14602 return rc;
14603}
14604
14605void tasha_get_codec_ver(struct tasha_priv *tasha)
14606{
14607 int i;
14608 int val;
14609 struct tasha_reg_mask_val codec_reg[] = {
14610 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0xFF, 0xFF},
14611 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0xFF, 0x83},
14612 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12, 0xFF, 0x0A},
14613 };
14614
14615 __tasha_enable_efuse_sensing(tasha);
14616 for (i = 0; i < ARRAY_SIZE(codec_reg); i++) {
14617 regmap_read(tasha->wcd9xxx->regmap, codec_reg[i].reg, &val);
14618 if (!(val && codec_reg[i].val)) {
14619 codec_ver = WCD9335;
14620 goto ret;
14621 }
14622 }
14623 codec_ver = WCD9326;
14624ret:
14625 pr_debug("%s: codec is %d\n", __func__, codec_ver);
14626}
14627EXPORT_SYMBOL(tasha_get_codec_ver);
14628
14629static int tasha_probe(struct platform_device *pdev)
14630{
14631 int ret = 0;
14632 struct tasha_priv *tasha;
14633 struct clk *wcd_ext_clk, *wcd_native_clk;
14634 struct wcd9xxx_resmgr_v2 *resmgr;
14635 struct wcd9xxx_power_region *cdc_pwr;
14636
14637 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
14638 if (apr_get_subsys_state() == APR_SUBSYS_DOWN) {
14639 dev_err(&pdev->dev, "%s: dsp down\n", __func__);
14640 return -EPROBE_DEFER;
14641 }
14642 }
14643
14644 tasha = devm_kzalloc(&pdev->dev, sizeof(struct tasha_priv),
14645 GFP_KERNEL);
14646 if (!tasha)
14647 return -ENOMEM;
14648 platform_set_drvdata(pdev, tasha);
14649
14650 tasha->wcd9xxx = dev_get_drvdata(pdev->dev.parent);
14651 tasha->dev = &pdev->dev;
14652 INIT_DELAYED_WORK(&tasha->power_gate_work, tasha_codec_power_gate_work);
14653 mutex_init(&tasha->power_lock);
14654 mutex_init(&tasha->sido_lock);
14655 INIT_WORK(&tasha->tasha_add_child_devices_work,
14656 tasha_add_child_devices);
14657 BLOCKING_INIT_NOTIFIER_HEAD(&tasha->notifier);
14658 mutex_init(&tasha->micb_lock);
14659 mutex_init(&tasha->swr_read_lock);
14660 mutex_init(&tasha->swr_write_lock);
14661 mutex_init(&tasha->swr_clk_lock);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053014662 mutex_init(&tasha->sb_clk_gear_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014663 mutex_init(&tasha->mclk_lock);
14664
14665 cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region),
14666 GFP_KERNEL);
14667 if (!cdc_pwr) {
14668 ret = -ENOMEM;
14669 goto err_cdc_pwr;
14670 }
14671 tasha->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr;
14672 cdc_pwr->pwr_collapse_reg_min = TASHA_DIG_CORE_REG_MIN;
14673 cdc_pwr->pwr_collapse_reg_max = TASHA_DIG_CORE_REG_MAX;
14674 wcd9xxx_set_power_state(tasha->wcd9xxx,
14675 WCD_REGION_POWER_COLLAPSE_REMOVE,
14676 WCD9XXX_DIG_CORE_REGION_1);
14677
14678 mutex_init(&tasha->codec_mutex);
14679 /*
14680 * Init resource manager so that if child nodes such as SoundWire
14681 * requests for clock, resource manager can honor the request
14682 */
14683 resmgr = wcd_resmgr_init(&tasha->wcd9xxx->core_res, NULL);
14684 if (IS_ERR(resmgr)) {
14685 ret = PTR_ERR(resmgr);
14686 dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n",
14687 __func__);
14688 goto err_resmgr;
14689 }
14690 tasha->resmgr = resmgr;
14691 tasha->swr_plat_data.handle = (void *) tasha;
14692 tasha->swr_plat_data.read = tasha_swrm_read;
14693 tasha->swr_plat_data.write = tasha_swrm_write;
14694 tasha->swr_plat_data.bulk_write = tasha_swrm_bulk_write;
14695 tasha->swr_plat_data.clk = tasha_swrm_clock;
14696 tasha->swr_plat_data.handle_irq = tasha_swrm_handle_irq;
14697
14698 /* Register for Clock */
14699 wcd_ext_clk = clk_get(tasha->wcd9xxx->dev, "wcd_clk");
14700 if (IS_ERR(wcd_ext_clk)) {
14701 dev_err(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14702 __func__, "wcd_ext_clk");
14703 goto err_clk;
14704 }
14705 tasha->wcd_ext_clk = wcd_ext_clk;
14706 tasha->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV;
14707 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
14708 tasha->sido_ccl_cnt = 0;
14709
14710 /* Register native clk for 44.1 playback */
14711 wcd_native_clk = clk_get(tasha->wcd9xxx->dev, "wcd_native_clk");
14712 if (IS_ERR(wcd_native_clk))
14713 dev_dbg(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14714 __func__, "wcd_native_clk");
14715 else
14716 tasha->wcd_native_clk = wcd_native_clk;
14717
14718 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
Meng Wang15c825d2018-09-06 10:49:18 +080014719 ret = snd_soc_register_component(&pdev->dev,
14720 &soc_codec_dev_tasha,
14721 tasha_dai, ARRAY_SIZE(tasha_dai));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014722 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
Meng Wang15c825d2018-09-06 10:49:18 +080014723 ret = snd_soc_register_component(&pdev->dev,
14724 &soc_codec_dev_tasha,
14725 tasha_i2s_dai,
14726 ARRAY_SIZE(tasha_i2s_dai));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014727 else
14728 ret = -EINVAL;
14729 if (ret) {
14730 dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n",
14731 __func__, ret);
14732 goto err_cdc_reg;
14733 }
14734 /* Update codec register default values */
14735 tasha_update_reg_defaults(tasha);
14736 schedule_work(&tasha->tasha_add_child_devices_work);
14737 tasha_get_codec_ver(tasha);
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053014738 ret = snd_event_client_register(pdev->dev.parent, &tasha_ssr_ops, NULL);
14739 if (!ret) {
14740 snd_event_notify(pdev->dev.parent, SND_EVENT_UP);
14741 } else {
14742 pr_err("%s: Registration with SND event fwk failed ret = %d\n",
14743 __func__, ret);
14744 ret = 0;
14745 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014746
14747 dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__);
14748 return ret;
14749
14750err_cdc_reg:
14751 clk_put(tasha->wcd_ext_clk);
14752 if (tasha->wcd_native_clk)
14753 clk_put(tasha->wcd_native_clk);
14754err_clk:
14755 wcd_resmgr_remove(tasha->resmgr);
14756err_resmgr:
14757 devm_kfree(&pdev->dev, cdc_pwr);
14758err_cdc_pwr:
14759 mutex_destroy(&tasha->mclk_lock);
14760 devm_kfree(&pdev->dev, tasha);
14761 return ret;
14762}
14763
14764static int tasha_remove(struct platform_device *pdev)
14765{
14766 struct tasha_priv *tasha;
Meng Wang3b194492017-09-27 12:20:22 +080014767 int count = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014768
14769 tasha = platform_get_drvdata(pdev);
14770
Meng Wang3b194492017-09-27 12:20:22 +080014771 if (!tasha)
14772 return -EINVAL;
14773
Aditya Bavanaribaab9b12019-02-03 22:15:21 +053014774 snd_event_client_deregister(pdev->dev.parent);
Meng Wang3b194492017-09-27 12:20:22 +080014775 for (count = 0; count < tasha->child_count &&
14776 count < WCD9335_CHILD_DEVICES_MAX; count++)
14777 platform_device_unregister(tasha->pdev_child_devices[count]);
14778
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014779 mutex_destroy(&tasha->codec_mutex);
14780 clk_put(tasha->wcd_ext_clk);
14781 if (tasha->wcd_native_clk)
14782 clk_put(tasha->wcd_native_clk);
14783 mutex_destroy(&tasha->mclk_lock);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053014784 mutex_destroy(&tasha->sb_clk_gear_lock);
Meng Wang15c825d2018-09-06 10:49:18 +080014785 snd_soc_unregister_component(&pdev->dev);
Meng Wang3b194492017-09-27 12:20:22 +080014786 devm_kfree(&pdev->dev, tasha);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014787 return 0;
14788}
14789
14790static struct platform_driver tasha_codec_driver = {
14791 .probe = tasha_probe,
14792 .remove = tasha_remove,
14793 .driver = {
14794 .name = "tasha_codec",
14795 .owner = THIS_MODULE,
14796#ifdef CONFIG_PM
14797 .pm = &tasha_pm_ops,
14798#endif
Xiaojun Sang53cd13a2018-06-29 15:14:37 +080014799 .suppress_bind_attrs = true,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014800 },
14801};
14802
14803module_platform_driver(tasha_codec_driver);
14804
14805MODULE_DESCRIPTION("Tasha Codec driver");
14806MODULE_LICENSE("GPL v2");