blob: 2b0c9d385eb5129b9be57c094f60b73ae2109297 [file] [log] [blame]
Sudheer Papothi3fb420b2013-12-05 05:30:15 +05301/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
Kiran Kandic3b24402012-06-11 00:05:59 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/firmware.h>
15#include <linux/slab.h>
16#include <linux/platform_device.h>
17#include <linux/device.h>
18#include <linux/printk.h>
19#include <linux/ratelimit.h>
20#include <linux/debugfs.h>
Joonwoo Park9bbb4d12012-11-09 19:58:11 -080021#include <linux/wait.h>
22#include <linux/bitops.h>
Kiran Kandic3b24402012-06-11 00:05:59 -070023#include <linux/mfd/wcd9xxx/core.h>
24#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
25#include <linux/mfd/wcd9xxx/wcd9320_registers.h>
26#include <linux/mfd/wcd9xxx/pdata.h>
Joonwoo Park448a8fc2013-04-10 15:25:58 -070027#include <linux/regulator/consumer.h>
Kiran Kandic3b24402012-06-11 00:05:59 -070028#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/tlv.h>
33#include <linux/bitops.h>
34#include <linux/delay.h>
35#include <linux/pm_runtime.h>
36#include <linux/kernel.h>
37#include <linux/gpio.h>
38#include "wcd9320.h"
Joonwoo Parka8890262012-10-15 12:04:27 -070039#include "wcd9xxx-resmgr.h"
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -080040#include "wcd9xxx-common.h"
Kiran Kandic3b24402012-06-11 00:05:59 -070041
Joonwoo Park1d05bb92013-03-07 16:55:06 -080042#define TAIKO_MAD_SLIMBUS_TX_PORT 12
43#define TAIKO_MAD_AUDIO_FIRMWARE_PATH "wcd9320/wcd9320_mad_audio.bin"
Patrick Laiff5a5782013-05-05 00:13:00 -070044#define TAIKO_VALIDATE_RX_SBPORT_RANGE(port) ((port >= 16) && (port <= 22))
45#define TAIKO_CONVERT_RX_SBPORT_ID(port) (port - 16) /* RX1 port ID = 0 */
Joonwoo Park1d05bb92013-03-07 16:55:06 -080046
Bhalchandra Gajare9581aed2013-03-29 17:06:10 -070047#define TAIKO_HPH_PA_SETTLE_COMP_ON 3000
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -070048#define TAIKO_HPH_PA_SETTLE_COMP_OFF 13000
49
Joonwoo Parkccccba72013-04-26 11:19:46 -070050#define DAPM_MICBIAS2_EXTERNAL_STANDALONE "MIC BIAS2 External Standalone"
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -070051#define DAPM_MICBIAS3_EXTERNAL_STANDALONE "MIC BIAS3 External Standalone"
Joonwoo Parkccccba72013-04-26 11:19:46 -070052
Phani Kumar Uppalapati01a77e12013-08-08 15:31:35 -070053/* RX_HPH_CNP_WG_TIME increases by 0.24ms */
54#define TAIKO_WG_TIME_FACTOR_US 240
55
Joonwoo Park125cd4e2012-12-11 15:16:11 -080056static atomic_t kp_taiko_priv;
57static int spkr_drv_wrnd_param_set(const char *val,
58 const struct kernel_param *kp);
59static int spkr_drv_wrnd = 1;
60
61static struct kernel_param_ops spkr_drv_wrnd_param_ops = {
62 .set = spkr_drv_wrnd_param_set,
63 .get = param_get_int,
64};
Joonwoo Park1d05bb92013-03-07 16:55:06 -080065
66static struct afe_param_slimbus_slave_port_cfg taiko_slimbus_slave_port_cfg = {
67 .minor_version = 1,
68 .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1,
69 .slave_dev_pgd_la = 0,
70 .slave_dev_intfdev_la = 0,
71 .bit_width = 16,
72 .data_format = 0,
73 .num_channels = 1
74};
75
Damir Didjustodcfdff82013-03-21 23:26:41 -070076static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
Joonwoo Park1d05bb92013-03-07 16:55:06 -080077 {
78 1,
79 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_MAIN_CTL_1),
80 HW_MAD_AUDIO_ENABLE, 0x1, 8, 0
81 },
82 {
83 1,
84 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_AUDIO_CTL_3),
85 HW_MAD_AUDIO_SLEEP_TIME, 0xF, 8, 0
86 },
87 {
88 1,
89 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_AUDIO_CTL_4),
90 HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, 8, 0
91 },
92 {
93 1,
94 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_DESTN3),
95 MAD_AUDIO_INT_DEST_SELECT_REG, 0x1, 8, 0
96 },
97 {
98 1,
99 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_MASK3),
100 MAD_AUDIO_INT_MASK_REG, 0x1, 8, 0
101 },
102 {
103 1,
104 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_STATUS3),
105 MAD_AUDIO_INT_STATUS_REG, 0x1, 8, 0
106 },
107 {
108 1,
109 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_CLEAR3),
110 MAD_AUDIO_INT_CLEAR_REG, 0x1, 8, 0
111 },
112 {
113 1,
114 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_TX_BASE),
Damir Didjustod6aea992013-09-03 21:18:59 -0700115 SB_PGD_PORT_TX_WATERMARK_N, 0x1E, 8, 0x1
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800116 },
117 {
118 1,
119 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_TX_BASE),
Damir Didjustod6aea992013-09-03 21:18:59 -0700120 SB_PGD_PORT_TX_ENABLE_N, 0x1, 8, 0x1
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800121 },
122 {
123 1,
124 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_RX_BASE),
Damir Didjustod6aea992013-09-03 21:18:59 -0700125 SB_PGD_PORT_RX_WATERMARK_N, 0x1E, 8, 0x1
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800126 },
127 {
128 1,
129 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_RX_BASE),
Damir Didjustod6aea992013-09-03 21:18:59 -0700130 SB_PGD_PORT_RX_ENABLE_N, 0x1, 8, 0x1
Damir Didjustodcfdff82013-03-21 23:26:41 -0700131 },
132 { 1,
133 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_ANC1_IIR_B1_CTL),
134 AANC_FF_GAIN_ADAPTIVE, 0x4, 8, 0
135 },
136 { 1,
137 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_ANC1_IIR_B1_CTL),
138 AANC_FFGAIN_ADAPTIVE_EN, 0x8, 8, 0
139 },
140 {
141 1,
142 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_ANC1_GAIN_CTL),
143 AANC_GAIN_CONTROL, 0xFF, 8, 0
144 },
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400145 {
146 1,
147 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_DESTN3),
148 MAD_CLIP_INT_DEST_SELECT_REG, 0x8, 8, 0
149 },
150 {
151 1,
152 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_MASK3),
153 MAD_CLIP_INT_MASK_REG, 0x8, 8, 0
154 },
155 {
156 1,
157 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_STATUS3),
158 MAD_CLIP_INT_STATUS_REG, 0x8, 8, 0
159 },
160 {
161 1,
162 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_CLEAR3),
163 MAD_CLIP_INT_CLEAR_REG, 0x8, 8, 0
164 },
165};
166
167static struct afe_param_cdc_reg_cfg clip_reg_cfg[] = {
168 {
169 1,
170 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400171 SPKR_CLIP_PIPE_BANK_SEL, 0x3, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400172 },
173 {
174 1,
175 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL0),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400176 SPKR_CLIPDET_VAL0, 0xff, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400177 },
178 {
179 1,
180 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL1),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400181 SPKR_CLIPDET_VAL1, 0xff, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400182 },
183 {
184 1,
185 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL2),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400186 SPKR_CLIPDET_VAL2, 0xff, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400187 },
188 {
189 1,
190 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL3),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400191 SPKR_CLIPDET_VAL3, 0xff, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400192 },
193 {
194 1,
195 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL4),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400196 SPKR_CLIPDET_VAL4, 0xff, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400197 },
198 {
199 1,
200 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL5),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400201 SPKR_CLIPDET_VAL5, 0xff, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400202 },
203 {
204 1,
205 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL6),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400206 SPKR_CLIPDET_VAL6, 0xff, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400207 },
208 {
209 1,
210 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL7),
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -0400211 SPKR_CLIPDET_VAL7, 0xff, 8, 0
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400212 },
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800213};
214
Damir Didjustodcfdff82013-03-21 23:26:41 -0700215static struct afe_param_cdc_reg_cfg_data taiko_audio_reg_cfg = {
216 .num_registers = ARRAY_SIZE(audio_reg_cfg),
217 .reg_data = audio_reg_cfg,
218};
219
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400220static struct afe_param_cdc_reg_cfg_data taiko_clip_reg_cfg = {
221 .num_registers = ARRAY_SIZE(clip_reg_cfg),
222 .reg_data = clip_reg_cfg,
223};
224
Damir Didjustodcfdff82013-03-21 23:26:41 -0700225static struct afe_param_id_cdc_aanc_version taiko_cdc_aanc_version = {
226 .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
227 .aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800228};
229
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -0400230static struct afe_param_id_clip_bank_sel clip_bank_sel = {
231 .minor_version = AFE_API_VERSION_CLIP_BANK_SEL_CFG,
232 .num_banks = AFE_CLIP_MAX_BANKS,
233 .bank_map = {0, 1, 2, 3},
234};
235
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800236module_param_cb(spkr_drv_wrnd, &spkr_drv_wrnd_param_ops, &spkr_drv_wrnd, 0644);
237MODULE_PARM_DESC(spkr_drv_wrnd,
238 "Run software workaround to avoid leakage on the speaker drive");
239
Kiran Kandic3b24402012-06-11 00:05:59 -0700240#define WCD9320_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
241 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
242 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
243
Kiran Kandic3b24402012-06-11 00:05:59 -0700244#define NUM_DECIMATORS 10
245#define NUM_INTERPOLATORS 7
246#define BITS_PER_REG 8
Kuirong Wang906ac472012-07-09 12:54:44 -0700247#define TAIKO_TX_PORT_NUMBER 16
Kuirong Wang80aca0d2013-05-09 14:51:09 -0700248#define TAIKO_RX_PORT_START_NUMBER 16
Kiran Kandic3b24402012-06-11 00:05:59 -0700249
Kiran Kandic3b24402012-06-11 00:05:59 -0700250#define TAIKO_I2S_MASTER_MODE_MASK 0x08
Damir Didjusto1a353ce2013-04-02 11:45:47 -0700251
Joonwoo Park9bbb4d12012-11-09 19:58:11 -0800252#define TAIKO_SLIM_CLOSE_TIMEOUT 1000
253#define TAIKO_SLIM_IRQ_OVERFLOW (1 << 0)
254#define TAIKO_SLIM_IRQ_UNDERFLOW (1 << 1)
255#define TAIKO_SLIM_IRQ_PORT_CLOSED (1 << 2)
Venkat Sudhira50a3762012-11-26 12:12:15 -0800256#define TAIKO_MCLK_CLK_12P288MHZ 12288000
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -0700257#define TAIKO_MCLK_CLK_9P6MHZ 9600000
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -0800258
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -0800259#define TAIKO_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
260 SNDRV_PCM_FORMAT_S24_LE)
261
262#define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
263
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -0400264#define TAIKO_SLIM_PGD_PORT_INT_TX_EN0 (TAIKO_SLIM_PGD_PORT_INT_EN0 + 2)
265
Kuirong Wang906ac472012-07-09 12:54:44 -0700266enum {
267 AIF1_PB = 0,
268 AIF1_CAP,
269 AIF2_PB,
270 AIF2_CAP,
271 AIF3_PB,
272 AIF3_CAP,
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -0500273 AIF4_VIFEED,
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800274 AIF4_MAD_TX,
Kuirong Wang906ac472012-07-09 12:54:44 -0700275 NUM_CODEC_DAIS,
Kiran Kandic3b24402012-06-11 00:05:59 -0700276};
277
Kuirong Wang906ac472012-07-09 12:54:44 -0700278enum {
279 RX_MIX1_INP_SEL_ZERO = 0,
280 RX_MIX1_INP_SEL_SRC1,
281 RX_MIX1_INP_SEL_SRC2,
282 RX_MIX1_INP_SEL_IIR1,
283 RX_MIX1_INP_SEL_IIR2,
284 RX_MIX1_INP_SEL_RX1,
285 RX_MIX1_INP_SEL_RX2,
286 RX_MIX1_INP_SEL_RX3,
287 RX_MIX1_INP_SEL_RX4,
288 RX_MIX1_INP_SEL_RX5,
289 RX_MIX1_INP_SEL_RX6,
290 RX_MIX1_INP_SEL_RX7,
291 RX_MIX1_INP_SEL_AUXRX,
292};
293
294#define TAIKO_COMP_DIGITAL_GAIN_OFFSET 3
295
Kiran Kandic3b24402012-06-11 00:05:59 -0700296static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
297static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
298static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
299static struct snd_soc_dai_driver taiko_dai[];
300static const DECLARE_TLV_DB_SCALE(aux_pga_gain, 0, 2, 0);
301
Kiran Kandic3b24402012-06-11 00:05:59 -0700302/* Codec supports 2 IIR filters */
303enum {
304 IIR1 = 0,
305 IIR2,
306 IIR_MAX,
307};
308/* Codec supports 5 bands */
309enum {
310 BAND1 = 0,
311 BAND2,
312 BAND3,
313 BAND4,
314 BAND5,
315 BAND_MAX,
316};
317
318enum {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700319 COMPANDER_0,
320 COMPANDER_1,
Kiran Kandic3b24402012-06-11 00:05:59 -0700321 COMPANDER_2,
322 COMPANDER_MAX,
323};
324
325enum {
326 COMPANDER_FS_8KHZ = 0,
327 COMPANDER_FS_16KHZ,
328 COMPANDER_FS_32KHZ,
329 COMPANDER_FS_48KHZ,
330 COMPANDER_FS_96KHZ,
331 COMPANDER_FS_192KHZ,
332 COMPANDER_FS_MAX,
333};
334
Kiran Kandic3b24402012-06-11 00:05:59 -0700335struct comp_sample_dependent_params {
336 u32 peak_det_timeout;
337 u32 rms_meter_div_fact;
338 u32 rms_meter_resamp_fact;
339};
340
Kiran Kandic3b24402012-06-11 00:05:59 -0700341struct hpf_work {
342 struct taiko_priv *taiko;
343 u32 decimator;
344 u8 tx_hpf_cut_of_freq;
345 struct delayed_work dwork;
346};
347
348static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
349
Kuirong Wang906ac472012-07-09 12:54:44 -0700350static const struct wcd9xxx_ch taiko_rx_chs[TAIKO_RX_MAX] = {
Kuirong Wang80aca0d2013-05-09 14:51:09 -0700351 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER, 0),
352 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 1, 1),
353 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 2, 2),
354 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 3, 3),
355 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 4, 4),
356 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 5, 5),
357 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 6, 6),
358 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 7, 7),
359 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 8, 8),
360 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 9, 9),
361 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 10, 10),
362 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 11, 11),
363 WCD9XXX_CH(TAIKO_RX_PORT_START_NUMBER + 12, 12),
Kuirong Wang906ac472012-07-09 12:54:44 -0700364};
365
366static const struct wcd9xxx_ch taiko_tx_chs[TAIKO_TX_MAX] = {
367 WCD9XXX_CH(0, 0),
368 WCD9XXX_CH(1, 1),
369 WCD9XXX_CH(2, 2),
370 WCD9XXX_CH(3, 3),
371 WCD9XXX_CH(4, 4),
372 WCD9XXX_CH(5, 5),
373 WCD9XXX_CH(6, 6),
374 WCD9XXX_CH(7, 7),
375 WCD9XXX_CH(8, 8),
376 WCD9XXX_CH(9, 9),
377 WCD9XXX_CH(10, 10),
378 WCD9XXX_CH(11, 11),
379 WCD9XXX_CH(12, 12),
380 WCD9XXX_CH(13, 13),
381 WCD9XXX_CH(14, 14),
382 WCD9XXX_CH(15, 15),
383};
384
385static const u32 vport_check_table[NUM_CODEC_DAIS] = {
386 0, /* AIF1_PB */
387 (1 << AIF2_CAP) | (1 << AIF3_CAP), /* AIF1_CAP */
388 0, /* AIF2_PB */
389 (1 << AIF1_CAP) | (1 << AIF3_CAP), /* AIF2_CAP */
390 0, /* AIF2_PB */
391 (1 << AIF1_CAP) | (1 << AIF2_CAP), /* AIF2_CAP */
392};
393
Venkat Sudhir96dd28c2012-12-04 17:00:19 -0800394static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
395 0, /* AIF1_PB */
396 0, /* AIF1_CAP */
Venkat Sudhir994193b2012-12-17 17:30:51 -0800397 0, /* AIF2_PB */
398 0, /* AIF2_CAP */
Venkat Sudhir96dd28c2012-12-04 17:00:19 -0800399};
400
Kiran Kandic3b24402012-06-11 00:05:59 -0700401struct taiko_priv {
402 struct snd_soc_codec *codec;
Kiran Kandic3b24402012-06-11 00:05:59 -0700403 u32 adc_count;
Kiran Kandic3b24402012-06-11 00:05:59 -0700404 u32 rx_bias_count;
405 s32 dmic_1_2_clk_cnt;
406 s32 dmic_3_4_clk_cnt;
407 s32 dmic_5_6_clk_cnt;
Joonwoo Parkccccba72013-04-26 11:19:46 -0700408 s32 ldo_h_users;
409 s32 micb_2_users;
Kiran Kandic3b24402012-06-11 00:05:59 -0700410
Kiran Kandic3b24402012-06-11 00:05:59 -0700411 u32 anc_slot;
Damir Didjusto2cb06bd2013-01-30 23:14:55 -0800412 bool anc_func;
Kiran Kandic3b24402012-06-11 00:05:59 -0700413
Kiran Kandic3b24402012-06-11 00:05:59 -0700414 /*track taiko interface type*/
415 u8 intf_type;
416
Kiran Kandic3b24402012-06-11 00:05:59 -0700417 /* num of slim ports required */
Kuirong Wang906ac472012-07-09 12:54:44 -0700418 struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
Kiran Kandic3b24402012-06-11 00:05:59 -0700419
420 /*compander*/
421 int comp_enabled[COMPANDER_MAX];
422 u32 comp_fs[COMPANDER_MAX];
423
424 /* Maintain the status of AUX PGA */
425 int aux_pga_cnt;
426 u8 aux_l_gain;
427 u8 aux_r_gain;
428
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800429 bool spkr_pa_widget_on;
Joonwoo Park448a8fc2013-04-10 15:25:58 -0700430 struct regulator *spkdrv_reg;
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800431
Joonwoo Park88bfa842013-04-15 16:59:21 -0700432 bool mbhc_started;
433
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800434 struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
435
Joonwoo Parka8890262012-10-15 12:04:27 -0700436 /* resmgr module */
437 struct wcd9xxx_resmgr resmgr;
438 /* mbhc module */
439 struct wcd9xxx_mbhc mbhc;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -0800440
441 /* class h specific data */
442 struct wcd9xxx_clsh_cdc_data clsh_d;
Kiran Kandia1bed422013-05-28 18:29:12 -0700443
444 int (*machine_codec_event_cb)(struct snd_soc_codec *codec,
445 enum wcd9xxx_codec_event);
Phani Kumar Uppalapati01a77e12013-08-08 15:31:35 -0700446
447 /*
448 * list used to save/restore registers at start and
449 * end of impedance measurement
450 */
451 struct list_head reg_save_restore;
Kiran Kandic3b24402012-06-11 00:05:59 -0700452};
453
Kiran Kandic3b24402012-06-11 00:05:59 -0700454static const u32 comp_shift[] = {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700455 4, /* Compander 0's clock source is on interpolator 7 */
Kiran Kandic3b24402012-06-11 00:05:59 -0700456 0,
457 2,
458};
459
460static const int comp_rx_path[] = {
461 COMPANDER_1,
462 COMPANDER_1,
463 COMPANDER_2,
464 COMPANDER_2,
465 COMPANDER_2,
466 COMPANDER_2,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700467 COMPANDER_0,
Kiran Kandic3b24402012-06-11 00:05:59 -0700468 COMPANDER_MAX,
469};
470
471static const struct comp_sample_dependent_params comp_samp_params[] = {
472 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700473 /* 8 Khz */
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700474 .peak_det_timeout = 0x06,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700475 .rms_meter_div_fact = 0x09,
476 .rms_meter_resamp_fact = 0x06,
Kiran Kandic3b24402012-06-11 00:05:59 -0700477 },
478 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700479 /* 16 Khz */
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700480 .peak_det_timeout = 0x07,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700481 .rms_meter_div_fact = 0x0A,
482 .rms_meter_resamp_fact = 0x0C,
483 },
484 {
485 /* 32 Khz */
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700486 .peak_det_timeout = 0x08,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700487 .rms_meter_div_fact = 0x0B,
488 .rms_meter_resamp_fact = 0x1E,
489 },
490 {
491 /* 48 Khz */
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700492 .peak_det_timeout = 0x09,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700493 .rms_meter_div_fact = 0x0B,
Kiran Kandic3b24402012-06-11 00:05:59 -0700494 .rms_meter_resamp_fact = 0x28,
495 },
Kiran Kandic3b24402012-06-11 00:05:59 -0700496 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700497 /* 96 Khz */
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700498 .peak_det_timeout = 0x0A,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700499 .rms_meter_div_fact = 0x0C,
500 .rms_meter_resamp_fact = 0x50,
Kiran Kandic3b24402012-06-11 00:05:59 -0700501 },
Kiran Kandic3b24402012-06-11 00:05:59 -0700502 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700503 /* 192 Khz */
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700504 .peak_det_timeout = 0x0B,
505 .rms_meter_div_fact = 0xC,
506 .rms_meter_resamp_fact = 0x50,
Kiran Kandic3b24402012-06-11 00:05:59 -0700507 },
508};
509
510static unsigned short rx_digital_gain_reg[] = {
511 TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
512 TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
513 TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
514 TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
515 TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
516 TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
517 TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
518};
519
520
521static unsigned short tx_digital_gain_reg[] = {
522 TAIKO_A_CDC_TX1_VOL_CTL_GAIN,
523 TAIKO_A_CDC_TX2_VOL_CTL_GAIN,
524 TAIKO_A_CDC_TX3_VOL_CTL_GAIN,
525 TAIKO_A_CDC_TX4_VOL_CTL_GAIN,
526 TAIKO_A_CDC_TX5_VOL_CTL_GAIN,
527 TAIKO_A_CDC_TX6_VOL_CTL_GAIN,
528 TAIKO_A_CDC_TX7_VOL_CTL_GAIN,
529 TAIKO_A_CDC_TX8_VOL_CTL_GAIN,
530 TAIKO_A_CDC_TX9_VOL_CTL_GAIN,
531 TAIKO_A_CDC_TX10_VOL_CTL_GAIN,
532};
533
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800534static int spkr_drv_wrnd_param_set(const char *val,
535 const struct kernel_param *kp)
536{
537 struct snd_soc_codec *codec;
538 int ret, old;
539 struct taiko_priv *priv;
540
541 priv = (struct taiko_priv *)atomic_read(&kp_taiko_priv);
542 if (!priv) {
543 pr_debug("%s: codec isn't yet registered\n", __func__);
544 return 0;
545 }
546
Joonwoo Park973fd352013-06-19 11:38:53 -0700547 codec = priv->codec;
548 mutex_lock(&codec->mutex);
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800549 old = spkr_drv_wrnd;
550 ret = param_set_int(val, kp);
551 if (ret) {
Joonwoo Park973fd352013-06-19 11:38:53 -0700552 mutex_unlock(&codec->mutex);
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800553 return ret;
554 }
555
556 pr_debug("%s: spkr_drv_wrnd %d -> %d\n", __func__, old, spkr_drv_wrnd);
Joonwoo Park973fd352013-06-19 11:38:53 -0700557 if ((old == -1 || old == 0) && spkr_drv_wrnd == 1) {
Joonwoo Park533b3682013-06-13 11:41:21 -0700558 WCD9XXX_BG_CLK_LOCK(&priv->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800559 wcd9xxx_resmgr_get_bandgap(&priv->resmgr,
560 WCD9XXX_BANDGAP_AUDIO_MODE);
Joonwoo Park533b3682013-06-13 11:41:21 -0700561 WCD9XXX_BG_CLK_UNLOCK(&priv->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800562 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
563 } else if (old == 1 && spkr_drv_wrnd == 0) {
Joonwoo Park533b3682013-06-13 11:41:21 -0700564 WCD9XXX_BG_CLK_LOCK(&priv->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800565 wcd9xxx_resmgr_put_bandgap(&priv->resmgr,
566 WCD9XXX_BANDGAP_AUDIO_MODE);
Joonwoo Park533b3682013-06-13 11:41:21 -0700567 WCD9XXX_BG_CLK_UNLOCK(&priv->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800568 if (!priv->spkr_pa_widget_on)
569 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
570 0x00);
571 }
Joonwoo Park973fd352013-06-19 11:38:53 -0700572 mutex_unlock(&codec->mutex);
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800573
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800574 return 0;
575}
576
Kiran Kandic3b24402012-06-11 00:05:59 -0700577static int taiko_get_anc_slot(struct snd_kcontrol *kcontrol,
578 struct snd_ctl_elem_value *ucontrol)
579{
580 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
581 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
582 ucontrol->value.integer.value[0] = taiko->anc_slot;
583 return 0;
584}
585
586static int taiko_put_anc_slot(struct snd_kcontrol *kcontrol,
587 struct snd_ctl_elem_value *ucontrol)
588{
589 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
590 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
591 taiko->anc_slot = ucontrol->value.integer.value[0];
592 return 0;
593}
594
Damir Didjusto2cb06bd2013-01-30 23:14:55 -0800595static int taiko_get_anc_func(struct snd_kcontrol *kcontrol,
596 struct snd_ctl_elem_value *ucontrol)
597{
598 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
599 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
600
601 ucontrol->value.integer.value[0] = (taiko->anc_func == true ? 1 : 0);
602 return 0;
603}
604
605static int taiko_put_anc_func(struct snd_kcontrol *kcontrol,
606 struct snd_ctl_elem_value *ucontrol)
607{
608 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
609 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
610 struct snd_soc_dapm_context *dapm = &codec->dapm;
611
612 mutex_lock(&dapm->codec->mutex);
613 taiko->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
614
615 dev_dbg(codec->dev, "%s: anc_func %x", __func__, taiko->anc_func);
616
617 if (taiko->anc_func == true) {
618 snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
619 snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
620 snd_soc_dapm_enable_pin(dapm, "ANC HEADPHONE");
621 snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
622 snd_soc_dapm_enable_pin(dapm, "ANC EAR");
623 snd_soc_dapm_disable_pin(dapm, "HPHR");
624 snd_soc_dapm_disable_pin(dapm, "HPHL");
625 snd_soc_dapm_disable_pin(dapm, "HEADPHONE");
626 snd_soc_dapm_disable_pin(dapm, "EAR PA");
627 snd_soc_dapm_disable_pin(dapm, "EAR");
628 } else {
629 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
630 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
631 snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
632 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
633 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
634 snd_soc_dapm_enable_pin(dapm, "HPHR");
635 snd_soc_dapm_enable_pin(dapm, "HPHL");
636 snd_soc_dapm_enable_pin(dapm, "HEADPHONE");
637 snd_soc_dapm_enable_pin(dapm, "EAR PA");
638 snd_soc_dapm_enable_pin(dapm, "EAR");
639 }
640 snd_soc_dapm_sync(dapm);
641 mutex_unlock(&dapm->codec->mutex);
642 return 0;
643}
644
Kiran Kandic3b24402012-06-11 00:05:59 -0700645static int taiko_get_iir_enable_audio_mixer(
646 struct snd_kcontrol *kcontrol,
647 struct snd_ctl_elem_value *ucontrol)
648{
649 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
650 int iir_idx = ((struct soc_multi_mixer_control *)
651 kcontrol->private_value)->reg;
652 int band_idx = ((struct soc_multi_mixer_control *)
653 kcontrol->private_value)->shift;
654
655 ucontrol->value.integer.value[0] =
Ben Romberger205e14d2013-02-06 12:31:53 -0800656 (snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
657 (1 << band_idx)) != 0;
Kiran Kandic3b24402012-06-11 00:05:59 -0700658
659 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
660 iir_idx, band_idx,
661 (uint32_t)ucontrol->value.integer.value[0]);
662 return 0;
663}
664
665static int taiko_put_iir_enable_audio_mixer(
666 struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol)
668{
669 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
670 int iir_idx = ((struct soc_multi_mixer_control *)
671 kcontrol->private_value)->reg;
672 int band_idx = ((struct soc_multi_mixer_control *)
673 kcontrol->private_value)->shift;
674 int value = ucontrol->value.integer.value[0];
675
676 /* Mask first 5 bits, 6-8 are reserved */
677 snd_soc_update_bits(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx),
678 (1 << band_idx), (value << band_idx));
679
680 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
Ben Romberger205e14d2013-02-06 12:31:53 -0800681 iir_idx, band_idx,
682 ((snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
683 (1 << band_idx)) != 0));
Kiran Kandic3b24402012-06-11 00:05:59 -0700684 return 0;
685}
686static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
687 int iir_idx, int band_idx,
688 int coeff_idx)
689{
Ben Romberger205e14d2013-02-06 12:31:53 -0800690 uint32_t value = 0;
691
Kiran Kandic3b24402012-06-11 00:05:59 -0700692 /* Address does not automatically update if reading */
693 snd_soc_write(codec,
694 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
Ben Romberger205e14d2013-02-06 12:31:53 -0800695 ((band_idx * BAND_MAX + coeff_idx)
696 * sizeof(uint32_t)) & 0x7F);
697
698 value |= snd_soc_read(codec,
699 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx));
700
701 snd_soc_write(codec,
702 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
703 ((band_idx * BAND_MAX + coeff_idx)
704 * sizeof(uint32_t) + 1) & 0x7F);
705
706 value |= (snd_soc_read(codec,
707 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 8);
708
709 snd_soc_write(codec,
710 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
711 ((band_idx * BAND_MAX + coeff_idx)
712 * sizeof(uint32_t) + 2) & 0x7F);
713
714 value |= (snd_soc_read(codec,
715 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 16);
716
717 snd_soc_write(codec,
718 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
719 ((band_idx * BAND_MAX + coeff_idx)
720 * sizeof(uint32_t) + 3) & 0x7F);
Kiran Kandic3b24402012-06-11 00:05:59 -0700721
722 /* Mask bits top 2 bits since they are reserved */
Ben Romberger205e14d2013-02-06 12:31:53 -0800723 value |= ((snd_soc_read(codec,
724 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) & 0x3F) << 24);
725
726 return value;
Kiran Kandic3b24402012-06-11 00:05:59 -0700727}
728
729static int taiko_get_iir_band_audio_mixer(
730 struct snd_kcontrol *kcontrol,
731 struct snd_ctl_elem_value *ucontrol)
732{
733 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
734 int iir_idx = ((struct soc_multi_mixer_control *)
735 kcontrol->private_value)->reg;
736 int band_idx = ((struct soc_multi_mixer_control *)
737 kcontrol->private_value)->shift;
738
739 ucontrol->value.integer.value[0] =
740 get_iir_band_coeff(codec, iir_idx, band_idx, 0);
741 ucontrol->value.integer.value[1] =
742 get_iir_band_coeff(codec, iir_idx, band_idx, 1);
743 ucontrol->value.integer.value[2] =
744 get_iir_band_coeff(codec, iir_idx, band_idx, 2);
745 ucontrol->value.integer.value[3] =
746 get_iir_band_coeff(codec, iir_idx, band_idx, 3);
747 ucontrol->value.integer.value[4] =
748 get_iir_band_coeff(codec, iir_idx, band_idx, 4);
749
750 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
751 "%s: IIR #%d band #%d b1 = 0x%x\n"
752 "%s: IIR #%d band #%d b2 = 0x%x\n"
753 "%s: IIR #%d band #%d a1 = 0x%x\n"
754 "%s: IIR #%d band #%d a2 = 0x%x\n",
755 __func__, iir_idx, band_idx,
756 (uint32_t)ucontrol->value.integer.value[0],
757 __func__, iir_idx, band_idx,
758 (uint32_t)ucontrol->value.integer.value[1],
759 __func__, iir_idx, band_idx,
760 (uint32_t)ucontrol->value.integer.value[2],
761 __func__, iir_idx, band_idx,
762 (uint32_t)ucontrol->value.integer.value[3],
763 __func__, iir_idx, band_idx,
764 (uint32_t)ucontrol->value.integer.value[4]);
765 return 0;
766}
767
768static void set_iir_band_coeff(struct snd_soc_codec *codec,
769 int iir_idx, int band_idx,
Ben Romberger205e14d2013-02-06 12:31:53 -0800770 uint32_t value)
Kiran Kandic3b24402012-06-11 00:05:59 -0700771{
Kiran Kandic3b24402012-06-11 00:05:59 -0700772 snd_soc_write(codec,
Ben Romberger205e14d2013-02-06 12:31:53 -0800773 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
774 (value & 0xFF));
775
776 snd_soc_write(codec,
777 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
778 (value >> 8) & 0xFF);
779
780 snd_soc_write(codec,
781 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
782 (value >> 16) & 0xFF);
Kiran Kandic3b24402012-06-11 00:05:59 -0700783
784 /* Mask top 2 bits, 7-8 are reserved */
785 snd_soc_write(codec,
786 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
787 (value >> 24) & 0x3F);
Kiran Kandic3b24402012-06-11 00:05:59 -0700788}
789
790static int taiko_put_iir_band_audio_mixer(
791 struct snd_kcontrol *kcontrol,
792 struct snd_ctl_elem_value *ucontrol)
793{
794 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
795 int iir_idx = ((struct soc_multi_mixer_control *)
796 kcontrol->private_value)->reg;
797 int band_idx = ((struct soc_multi_mixer_control *)
798 kcontrol->private_value)->shift;
799
Ben Romberger205e14d2013-02-06 12:31:53 -0800800 /* Mask top bit it is reserved */
801 /* Updates addr automatically for each B2 write */
802 snd_soc_write(codec,
803 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
804 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
805
806 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700807 ucontrol->value.integer.value[0]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800808 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700809 ucontrol->value.integer.value[1]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800810 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700811 ucontrol->value.integer.value[2]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800812 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700813 ucontrol->value.integer.value[3]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800814 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700815 ucontrol->value.integer.value[4]);
816
817 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
818 "%s: IIR #%d band #%d b1 = 0x%x\n"
819 "%s: IIR #%d band #%d b2 = 0x%x\n"
820 "%s: IIR #%d band #%d a1 = 0x%x\n"
821 "%s: IIR #%d band #%d a2 = 0x%x\n",
822 __func__, iir_idx, band_idx,
823 get_iir_band_coeff(codec, iir_idx, band_idx, 0),
824 __func__, iir_idx, band_idx,
825 get_iir_band_coeff(codec, iir_idx, band_idx, 1),
826 __func__, iir_idx, band_idx,
827 get_iir_band_coeff(codec, iir_idx, band_idx, 2),
828 __func__, iir_idx, band_idx,
829 get_iir_band_coeff(codec, iir_idx, band_idx, 3),
830 __func__, iir_idx, band_idx,
831 get_iir_band_coeff(codec, iir_idx, band_idx, 4));
832 return 0;
833}
834
Kiran Kandic3b24402012-06-11 00:05:59 -0700835static int taiko_get_compander(struct snd_kcontrol *kcontrol,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700836 struct snd_ctl_elem_value *ucontrol)
Kiran Kandic3b24402012-06-11 00:05:59 -0700837{
838
839 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
840 int comp = ((struct soc_multi_mixer_control *)
Joonwoo Parkc7731432012-10-17 12:41:44 -0700841 kcontrol->private_value)->shift;
Kiran Kandic3b24402012-06-11 00:05:59 -0700842 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
843
844 ucontrol->value.integer.value[0] = taiko->comp_enabled[comp];
Kiran Kandic3b24402012-06-11 00:05:59 -0700845 return 0;
846}
847
848static int taiko_set_compander(struct snd_kcontrol *kcontrol,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700849 struct snd_ctl_elem_value *ucontrol)
Kiran Kandic3b24402012-06-11 00:05:59 -0700850{
851 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
852 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
853 int comp = ((struct soc_multi_mixer_control *)
Joonwoo Parkc7731432012-10-17 12:41:44 -0700854 kcontrol->private_value)->shift;
Kiran Kandic3b24402012-06-11 00:05:59 -0700855 int value = ucontrol->value.integer.value[0];
856
Joonwoo Parkc7731432012-10-17 12:41:44 -0700857 pr_debug("%s: Compander %d enable current %d, new %d\n",
858 __func__, comp, taiko->comp_enabled[comp], value);
Kiran Kandic3b24402012-06-11 00:05:59 -0700859 taiko->comp_enabled[comp] = value;
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -0700860
861 if (comp == COMPANDER_1 &&
862 taiko->comp_enabled[comp] == 1) {
863 /* Wavegen to 5 msec */
864 snd_soc_write(codec, TAIKO_A_RX_HPH_CNP_WG_CTL, 0xDA);
865 snd_soc_write(codec, TAIKO_A_RX_HPH_CNP_WG_TIME, 0x15);
866 snd_soc_write(codec, TAIKO_A_RX_HPH_BIAS_WG_OCP, 0x2A);
867
868 /* Enable Chopper */
869 snd_soc_update_bits(codec,
870 TAIKO_A_RX_HPH_CHOP_CTL, 0x80, 0x80);
Bhalchandra Gajare9581aed2013-03-29 17:06:10 -0700871
872 snd_soc_write(codec, TAIKO_A_NCP_DTEST, 0x20);
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -0700873 pr_debug("%s: Enabled Chopper and set wavegen to 5 msec\n",
874 __func__);
875 } else if (comp == COMPANDER_1 &&
876 taiko->comp_enabled[comp] == 0) {
877 /* Wavegen to 20 msec */
878 snd_soc_write(codec, TAIKO_A_RX_HPH_CNP_WG_CTL, 0xDB);
879 snd_soc_write(codec, TAIKO_A_RX_HPH_CNP_WG_TIME, 0x58);
880 snd_soc_write(codec, TAIKO_A_RX_HPH_BIAS_WG_OCP, 0x1A);
881
882 /* Disable CHOPPER block */
883 snd_soc_update_bits(codec,
884 TAIKO_A_RX_HPH_CHOP_CTL, 0x80, 0x00);
Bhalchandra Gajare9581aed2013-03-29 17:06:10 -0700885
886 snd_soc_write(codec, TAIKO_A_NCP_DTEST, 0x10);
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -0700887 pr_debug("%s: Disabled Chopper and set wavegen to 20 msec\n",
888 __func__);
889 }
Kiran Kandic3b24402012-06-11 00:05:59 -0700890 return 0;
891}
892
Joonwoo Parkc7731432012-10-17 12:41:44 -0700893static int taiko_config_gain_compander(struct snd_soc_codec *codec,
894 int comp, bool enable)
895{
896 int ret = 0;
897
898 switch (comp) {
899 case COMPANDER_0:
900 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_GAIN,
901 1 << 2, !enable << 2);
902 break;
903 case COMPANDER_1:
904 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_L_GAIN,
905 1 << 5, !enable << 5);
906 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_R_GAIN,
907 1 << 5, !enable << 5);
908 break;
909 case COMPANDER_2:
910 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_1_GAIN,
911 1 << 5, !enable << 5);
912 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_3_GAIN,
913 1 << 5, !enable << 5);
914 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_2_GAIN,
915 1 << 5, !enable << 5);
916 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_4_GAIN,
917 1 << 5, !enable << 5);
918 break;
919 default:
920 WARN_ON(1);
921 ret = -EINVAL;
922 }
923
924 return ret;
925}
926
927static void taiko_discharge_comp(struct snd_soc_codec *codec, int comp)
928{
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700929 /* Level meter DIV Factor to 5*/
Joonwoo Parkc7731432012-10-17 12:41:44 -0700930 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8), 0xF0,
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700931 0x05 << 4);
932 /* RMS meter Sampling to 0x01 */
933 snd_soc_write(codec, TAIKO_A_CDC_COMP0_B3_CTL + (comp * 8), 0x01);
934
935 /* Worst case timeout for compander CnP sleep timeout */
936 usleep_range(3000, 3000);
937}
938
939static enum wcd9xxx_buck_volt taiko_codec_get_buck_mv(
940 struct snd_soc_codec *codec)
941{
942 int buck_volt = WCD9XXX_CDC_BUCK_UNSUPPORTED;
943 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
944 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
945 int i;
946
947 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
948 if (!strncmp(pdata->regulator[i].name,
949 WCD9XXX_SUPPLY_BUCK_NAME,
950 sizeof(WCD9XXX_SUPPLY_BUCK_NAME))) {
951 if ((pdata->regulator[i].min_uV ==
952 WCD9XXX_CDC_BUCK_MV_1P8) ||
953 (pdata->regulator[i].min_uV ==
954 WCD9XXX_CDC_BUCK_MV_2P15))
955 buck_volt = pdata->regulator[i].min_uV;
956 break;
957 }
958 }
959 return buck_volt;
Joonwoo Parkc7731432012-10-17 12:41:44 -0700960}
Kiran Kandic3b24402012-06-11 00:05:59 -0700961
962static int taiko_config_compander(struct snd_soc_dapm_widget *w,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700963 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -0700964{
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700965 int mask, enable_mask;
Kiran Kandic3b24402012-06-11 00:05:59 -0700966 struct snd_soc_codec *codec = w->codec;
967 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parkc7731432012-10-17 12:41:44 -0700968 const int comp = w->shift;
969 const u32 rate = taiko->comp_fs[comp];
970 const struct comp_sample_dependent_params *comp_params =
971 &comp_samp_params[rate];
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700972 enum wcd9xxx_buck_volt buck_mv;
Kiran Kandic3b24402012-06-11 00:05:59 -0700973
Joonwoo Parkc7731432012-10-17 12:41:44 -0700974 pr_debug("%s: %s event %d compander %d, enabled %d", __func__,
975 w->name, event, comp, taiko->comp_enabled[comp]);
976
977 if (!taiko->comp_enabled[comp])
978 return 0;
979
980 /* Compander 0 has single channel */
981 mask = (comp == COMPANDER_0 ? 0x01 : 0x03);
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700982 enable_mask = (comp == COMPANDER_0 ? 0x02 : 0x03);
983 buck_mv = taiko_codec_get_buck_mv(codec);
Kiran Kandid2b46332012-10-05 12:04:00 -0700984
Kiran Kandic3b24402012-06-11 00:05:59 -0700985 switch (event) {
986 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700987 /* Set compander Sample rate */
988 snd_soc_update_bits(codec,
989 TAIKO_A_CDC_COMP0_FS_CFG + (comp * 8),
990 0x07, rate);
991 /* Set the static gain offset */
992 if (comp == COMPANDER_1
Kuirong Wang865534c2013-06-25 14:32:51 -0700993 && buck_mv == WCD9XXX_CDC_BUCK_MV_1P8) {
Bhalchandra Gajareed090e62013-03-29 16:11:49 -0700994 snd_soc_update_bits(codec,
995 TAIKO_A_CDC_COMP0_B4_CTL + (comp * 8),
996 0x80, 0x80);
997 } else {
998 snd_soc_update_bits(codec,
999 TAIKO_A_CDC_COMP0_B4_CTL + (comp * 8),
1000 0x80, 0x00);
1001 }
1002 /* Enable RX interpolation path compander clocks */
Joonwoo Parkc7731432012-10-17 12:41:44 -07001003 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
1004 mask << comp_shift[comp],
1005 mask << comp_shift[comp]);
Joonwoo Parkc7731432012-10-17 12:41:44 -07001006 /* Toggle compander reset bits */
1007 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
1008 mask << comp_shift[comp],
1009 mask << comp_shift[comp]);
1010 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
1011 mask << comp_shift[comp], 0);
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07001012
1013 /* Set gain source to compander */
1014 taiko_config_gain_compander(codec, comp, true);
1015
1016 /* Compander enable */
1017 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP0_B1_CTL +
1018 (comp * 8), enable_mask, enable_mask);
1019
1020 taiko_discharge_comp(codec, comp);
1021
Joonwoo Parkc7731432012-10-17 12:41:44 -07001022 /* Set sample rate dependent paramater */
Joonwoo Parkc7731432012-10-17 12:41:44 -07001023 snd_soc_write(codec, TAIKO_A_CDC_COMP0_B3_CTL + (comp * 8),
1024 comp_params->rms_meter_resamp_fact);
1025 snd_soc_update_bits(codec,
1026 TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8),
Joonwoo Parkc7731432012-10-17 12:41:44 -07001027 0xF0, comp_params->rms_meter_div_fact << 4);
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07001028 snd_soc_update_bits(codec,
1029 TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8),
1030 0x0F, comp_params->peak_det_timeout);
Kiran Kandic3b24402012-06-11 00:05:59 -07001031 break;
1032 case SND_SOC_DAPM_PRE_PMD:
Joonwoo Parkc7731432012-10-17 12:41:44 -07001033 /* Disable compander */
1034 snd_soc_update_bits(codec,
1035 TAIKO_A_CDC_COMP0_B1_CTL + (comp * 8),
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07001036 enable_mask, 0x00);
1037
1038 /* Toggle compander reset bits */
1039 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
1040 mask << comp_shift[comp],
1041 mask << comp_shift[comp]);
1042 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
1043 mask << comp_shift[comp], 0);
1044
Joonwoo Parkc7731432012-10-17 12:41:44 -07001045 /* Turn off the clock for compander in pair */
1046 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
1047 mask << comp_shift[comp], 0);
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07001048
Joonwoo Parkc7731432012-10-17 12:41:44 -07001049 /* Set gain source to register */
1050 taiko_config_gain_compander(codec, comp, false);
Kiran Kandic3b24402012-06-11 00:05:59 -07001051 break;
1052 }
1053 return 0;
1054}
1055
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001056
Kiran Kandic3b24402012-06-11 00:05:59 -07001057
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001058static const char *const taiko_anc_func_text[] = {"OFF", "ON"};
1059static const struct soc_enum taiko_anc_func_enum =
1060 SOC_ENUM_SINGLE_EXT(2, taiko_anc_func_text);
1061
1062static const char *const tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
1063static const struct soc_enum tabla_ear_pa_gain_enum[] = {
1064 SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
1065};
1066
Kiran Kandic3b24402012-06-11 00:05:59 -07001067/*cut of frequency for high pass filter*/
1068static const char * const cf_text[] = {
1069 "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
1070};
1071
1072static const struct soc_enum cf_dec1_enum =
1073 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX1_MUX_CTL, 4, 3, cf_text);
1074
1075static const struct soc_enum cf_dec2_enum =
1076 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX2_MUX_CTL, 4, 3, cf_text);
1077
1078static const struct soc_enum cf_dec3_enum =
1079 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX3_MUX_CTL, 4, 3, cf_text);
1080
1081static const struct soc_enum cf_dec4_enum =
1082 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX4_MUX_CTL, 4, 3, cf_text);
1083
1084static const struct soc_enum cf_dec5_enum =
1085 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX5_MUX_CTL, 4, 3, cf_text);
1086
1087static const struct soc_enum cf_dec6_enum =
1088 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX6_MUX_CTL, 4, 3, cf_text);
1089
1090static const struct soc_enum cf_dec7_enum =
1091 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX7_MUX_CTL, 4, 3, cf_text);
1092
1093static const struct soc_enum cf_dec8_enum =
1094 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX8_MUX_CTL, 4, 3, cf_text);
1095
1096static const struct soc_enum cf_dec9_enum =
1097 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX9_MUX_CTL, 4, 3, cf_text);
1098
1099static const struct soc_enum cf_dec10_enum =
1100 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX10_MUX_CTL, 4, 3, cf_text);
1101
1102static const struct soc_enum cf_rxmix1_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001103 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX1_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001104
1105static const struct soc_enum cf_rxmix2_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001106 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX2_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001107
1108static const struct soc_enum cf_rxmix3_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001109 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX3_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001110
1111static const struct soc_enum cf_rxmix4_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001112 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX4_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001113
1114static const struct soc_enum cf_rxmix5_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001115 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX5_B4_CTL, 0, 3, cf_text)
Kiran Kandic3b24402012-06-11 00:05:59 -07001116;
1117static const struct soc_enum cf_rxmix6_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001118 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX6_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001119
1120static const struct soc_enum cf_rxmix7_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001121 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX7_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001122
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08001123static const char * const class_h_dsm_text[] = {
1124 "ZERO", "DSM_HPHL_RX1", "DSM_SPKR_RX7"
1125};
1126
1127static const struct soc_enum class_h_dsm_enum =
1128 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_CLSH_CTL, 4, 3, class_h_dsm_text);
1129
1130static const struct snd_kcontrol_new class_h_dsm_mux =
1131 SOC_DAPM_ENUM("CLASS_H_DSM MUX Mux", class_h_dsm_enum);
1132
Sudheer Papothia26a6672014-03-22 00:03:34 +05301133static const char * const rx1_interpolator_text[] = {
1134 "ZERO", "RX1 MIX2"
1135};
1136static const struct soc_enum rx1_interpolator_enum =
1137 SOC_ENUM_SINGLE(TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 2, rx1_interpolator_text);
1138
1139static const struct snd_kcontrol_new rx1_interpolator =
1140 SOC_DAPM_ENUM("RX1 INTERP Mux", rx1_interpolator_enum);
1141
1142static const char * const rx2_interpolator_text[] = {
1143 "ZERO", "RX2 MIX2"
1144};
1145static const struct soc_enum rx2_interpolator_enum =
1146 SOC_ENUM_SINGLE(TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 2, rx2_interpolator_text);
1147
1148static const struct snd_kcontrol_new rx2_interpolator =
1149 SOC_DAPM_ENUM("RX2 INTERP Mux", rx2_interpolator_enum);
1150
Kiran Kandiddbeaa32013-10-06 14:40:11 -07001151static const char *const taiko_conn_mad_text[] = {
1152 "ADC_MB", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "NOTUSED1",
1153 "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6", "NOTUSED2",
1154 "NOTUSED3"};
1155
1156static const struct soc_enum taiko_conn_mad_enum =
1157 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(taiko_conn_mad_text),
1158 taiko_conn_mad_text);
1159
1160
1161static int taiko_mad_input_get(struct snd_kcontrol *kcontrol,
1162 struct snd_ctl_elem_value *ucontrol)
1163{
1164 u8 taiko_mad_input;
1165 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1166
1167 taiko_mad_input = snd_soc_read(codec, TAIKO_A_CDC_CONN_MAD);
1168
1169 taiko_mad_input = taiko_mad_input & 0x0F;
1170
1171 ucontrol->value.integer.value[0] = taiko_mad_input;
1172
1173 pr_debug("%s: taiko_mad_input = %s\n", __func__,
1174 taiko_conn_mad_text[taiko_mad_input]);
1175
1176 return 0;
1177}
1178
1179static int taiko_mad_input_put(struct snd_kcontrol *kcontrol,
1180 struct snd_ctl_elem_value *ucontrol)
1181{
1182 u8 taiko_mad_input;
1183 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1184 struct snd_soc_card *card = codec->card;
1185 char mad_amic_input_widget[6];
1186 u32 adc;
1187 const char *mad_input_widget;
1188 u32 mic_bias_found = 0;
1189 u32 i;
1190 int ret = 0;
1191
1192 taiko_mad_input = ucontrol->value.integer.value[0];
1193
1194 pr_debug("%s: taiko_mad_input = %s\n", __func__,
1195 taiko_conn_mad_text[taiko_mad_input]);
1196
1197 if (!strcmp(taiko_conn_mad_text[taiko_mad_input], "NOTUSED1") ||
1198 !strcmp(taiko_conn_mad_text[taiko_mad_input], "NOTUSED2") ||
1199 !strcmp(taiko_conn_mad_text[taiko_mad_input], "NOTUSED3") ||
1200 !strcmp(taiko_conn_mad_text[taiko_mad_input], "ADC_MB")) {
1201 pr_info("%s: taiko mad input is set to unsupported input = %s\n",
1202 __func__, taiko_conn_mad_text[taiko_mad_input]);
1203 return -EINVAL;
1204 }
1205
1206 if (strnstr(taiko_conn_mad_text[taiko_mad_input],
1207 "ADC", sizeof("ADC"))) {
1208 ret = kstrtouint(strpbrk(taiko_conn_mad_text[taiko_mad_input]
1209 , "123456"), 10, &adc);
1210 if ((ret < 0) || (adc > 6)) {
1211 pr_err("%s: Invalid ADC = %s\n", __func__,
1212 taiko_conn_mad_text[taiko_mad_input]);
1213 ret = -EINVAL;
1214 }
1215
1216 snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc);
1217
1218 mad_input_widget = mad_amic_input_widget;
1219 pr_debug("%s: taiko amic input widget = %s\n", __func__,
1220 mad_amic_input_widget);
1221 } else {
1222 /* DMIC type input widget*/
1223 mad_input_widget = taiko_conn_mad_text[taiko_mad_input];
1224 }
1225
1226 pr_debug("%s: taiko input widget = %s\n", __func__, mad_input_widget);
1227
1228 for (i = 0; i < card->num_dapm_routes; i++) {
1229
1230 if (!strncmp(card->dapm_routes[i].sink,
1231 mad_input_widget, strlen(mad_input_widget))) {
1232
1233 if (strnstr(card->dapm_routes[i].source,
1234 "MIC BIAS1", sizeof("MIC BIAS1"))) {
1235 mic_bias_found = 1;
1236 break;
1237 } else if (strnstr(card->dapm_routes[i].source,
1238 "MIC BIAS2", sizeof("MIC BIAS2"))) {
1239 mic_bias_found = 2;
1240 break;
1241 } else if (strnstr(card->dapm_routes[i].source,
1242 "MIC BIAS3", sizeof("MIC BIAS3"))) {
1243 mic_bias_found = 3;
1244 break;
1245 } else if (strnstr(card->dapm_routes[i].source,
1246 "MIC BIAS4", sizeof("MIC BIAS4"))) {
1247 mic_bias_found = 4;
1248 break;
1249 }
1250 }
1251 }
1252
1253 if (mic_bias_found) {
1254 pr_debug("%s: source mic bias = %s. sink = %s\n", __func__,
1255 card->dapm_routes[i].source,
1256 card->dapm_routes[i].sink);
1257
1258 snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_MAD,
1259 0x0F, taiko_mad_input);
1260 snd_soc_update_bits(codec, TAIKO_A_MAD_ANA_CTRL,
1261 0x07, mic_bias_found);
1262 return 0;
1263 } else {
1264 pr_err("%s: mic bias source not found for input = %s\n",
1265 __func__, mad_input_widget);
1266 return -EINVAL;
1267 }
1268}
1269
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08001270
Kiran Kandic3b24402012-06-11 00:05:59 -07001271static const struct snd_kcontrol_new taiko_snd_controls[] = {
1272
Kiran Kandic3b24402012-06-11 00:05:59 -07001273 SOC_SINGLE_S8_TLV("RX1 Digital Volume", TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
1274 -84, 40, digital_gain),
1275 SOC_SINGLE_S8_TLV("RX2 Digital Volume", TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
1276 -84, 40, digital_gain),
1277 SOC_SINGLE_S8_TLV("RX3 Digital Volume", TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
1278 -84, 40, digital_gain),
1279 SOC_SINGLE_S8_TLV("RX4 Digital Volume", TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
1280 -84, 40, digital_gain),
1281 SOC_SINGLE_S8_TLV("RX5 Digital Volume", TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
1282 -84, 40, digital_gain),
1283 SOC_SINGLE_S8_TLV("RX6 Digital Volume", TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
1284 -84, 40, digital_gain),
1285 SOC_SINGLE_S8_TLV("RX7 Digital Volume", TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
1286 -84, 40, digital_gain),
1287
1288 SOC_SINGLE_S8_TLV("DEC1 Volume", TAIKO_A_CDC_TX1_VOL_CTL_GAIN, -84, 40,
1289 digital_gain),
1290 SOC_SINGLE_S8_TLV("DEC2 Volume", TAIKO_A_CDC_TX2_VOL_CTL_GAIN, -84, 40,
1291 digital_gain),
1292 SOC_SINGLE_S8_TLV("DEC3 Volume", TAIKO_A_CDC_TX3_VOL_CTL_GAIN, -84, 40,
1293 digital_gain),
1294 SOC_SINGLE_S8_TLV("DEC4 Volume", TAIKO_A_CDC_TX4_VOL_CTL_GAIN, -84, 40,
1295 digital_gain),
1296 SOC_SINGLE_S8_TLV("DEC5 Volume", TAIKO_A_CDC_TX5_VOL_CTL_GAIN, -84, 40,
1297 digital_gain),
1298 SOC_SINGLE_S8_TLV("DEC6 Volume", TAIKO_A_CDC_TX6_VOL_CTL_GAIN, -84, 40,
1299 digital_gain),
1300 SOC_SINGLE_S8_TLV("DEC7 Volume", TAIKO_A_CDC_TX7_VOL_CTL_GAIN, -84, 40,
1301 digital_gain),
1302 SOC_SINGLE_S8_TLV("DEC8 Volume", TAIKO_A_CDC_TX8_VOL_CTL_GAIN, -84, 40,
1303 digital_gain),
1304 SOC_SINGLE_S8_TLV("DEC9 Volume", TAIKO_A_CDC_TX9_VOL_CTL_GAIN, -84, 40,
1305 digital_gain),
1306 SOC_SINGLE_S8_TLV("DEC10 Volume", TAIKO_A_CDC_TX10_VOL_CTL_GAIN, -84,
1307 40, digital_gain),
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001308
Kiran Kandic3b24402012-06-11 00:05:59 -07001309 SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, -84,
1310 40, digital_gain),
1311 SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", TAIKO_A_CDC_IIR1_GAIN_B2_CTL, -84,
1312 40, digital_gain),
1313 SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", TAIKO_A_CDC_IIR1_GAIN_B3_CTL, -84,
1314 40, digital_gain),
1315 SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", TAIKO_A_CDC_IIR1_GAIN_B4_CTL, -84,
1316 40, digital_gain),
Fred Oh456fcb52013-02-28 19:08:15 -08001317 SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", TAIKO_A_CDC_IIR2_GAIN_B1_CTL, -84,
1318 40, digital_gain),
1319 SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", TAIKO_A_CDC_IIR2_GAIN_B2_CTL, -84,
1320 40, digital_gain),
1321 SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", TAIKO_A_CDC_IIR2_GAIN_B3_CTL, -84,
1322 40, digital_gain),
1323 SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", TAIKO_A_CDC_IIR2_GAIN_B4_CTL, -84,
1324 40, digital_gain),
Kiran Kandic3b24402012-06-11 00:05:59 -07001325
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001326 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, taiko_get_anc_slot,
Kiran Kandic3b24402012-06-11 00:05:59 -07001327 taiko_put_anc_slot),
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001328 SOC_ENUM_EXT("ANC Function", taiko_anc_func_enum, taiko_get_anc_func,
1329 taiko_put_anc_func),
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001330
Kiran Kandic3b24402012-06-11 00:05:59 -07001331 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
1332 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
1333 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
1334 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
1335 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
1336 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
1337 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
1338 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
1339 SOC_ENUM("TX9 HPF cut off", cf_dec9_enum),
1340 SOC_ENUM("TX10 HPF cut off", cf_dec10_enum),
1341
1342 SOC_SINGLE("TX1 HPF Switch", TAIKO_A_CDC_TX1_MUX_CTL, 3, 1, 0),
1343 SOC_SINGLE("TX2 HPF Switch", TAIKO_A_CDC_TX2_MUX_CTL, 3, 1, 0),
1344 SOC_SINGLE("TX3 HPF Switch", TAIKO_A_CDC_TX3_MUX_CTL, 3, 1, 0),
1345 SOC_SINGLE("TX4 HPF Switch", TAIKO_A_CDC_TX4_MUX_CTL, 3, 1, 0),
1346 SOC_SINGLE("TX5 HPF Switch", TAIKO_A_CDC_TX5_MUX_CTL, 3, 1, 0),
1347 SOC_SINGLE("TX6 HPF Switch", TAIKO_A_CDC_TX6_MUX_CTL, 3, 1, 0),
1348 SOC_SINGLE("TX7 HPF Switch", TAIKO_A_CDC_TX7_MUX_CTL, 3, 1, 0),
1349 SOC_SINGLE("TX8 HPF Switch", TAIKO_A_CDC_TX8_MUX_CTL, 3, 1, 0),
1350 SOC_SINGLE("TX9 HPF Switch", TAIKO_A_CDC_TX9_MUX_CTL, 3, 1, 0),
1351 SOC_SINGLE("TX10 HPF Switch", TAIKO_A_CDC_TX10_MUX_CTL, 3, 1, 0),
1352
1353 SOC_SINGLE("RX1 HPF Switch", TAIKO_A_CDC_RX1_B5_CTL, 2, 1, 0),
1354 SOC_SINGLE("RX2 HPF Switch", TAIKO_A_CDC_RX2_B5_CTL, 2, 1, 0),
1355 SOC_SINGLE("RX3 HPF Switch", TAIKO_A_CDC_RX3_B5_CTL, 2, 1, 0),
1356 SOC_SINGLE("RX4 HPF Switch", TAIKO_A_CDC_RX4_B5_CTL, 2, 1, 0),
1357 SOC_SINGLE("RX5 HPF Switch", TAIKO_A_CDC_RX5_B5_CTL, 2, 1, 0),
1358 SOC_SINGLE("RX6 HPF Switch", TAIKO_A_CDC_RX6_B5_CTL, 2, 1, 0),
1359 SOC_SINGLE("RX7 HPF Switch", TAIKO_A_CDC_RX7_B5_CTL, 2, 1, 0),
1360
1361 SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
1362 SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
1363 SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
1364 SOC_ENUM("RX4 HPF cut off", cf_rxmix4_enum),
1365 SOC_ENUM("RX5 HPF cut off", cf_rxmix5_enum),
1366 SOC_ENUM("RX6 HPF cut off", cf_rxmix6_enum),
1367 SOC_ENUM("RX7 HPF cut off", cf_rxmix7_enum),
1368
1369 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
1370 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1371 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
1372 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1373 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
1374 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1375 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
1376 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1377 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
1378 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1379 SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
1380 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1381 SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
1382 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1383 SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
1384 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1385 SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
1386 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1387 SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
1388 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1389
1390 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
1391 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1392 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
1393 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1394 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
1395 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1396 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
1397 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1398 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
1399 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1400 SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
1401 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1402 SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
1403 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1404 SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
1405 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1406 SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
1407 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1408 SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
1409 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1410
Joonwoo Parkc7731432012-10-17 12:41:44 -07001411 SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_0, 1, 0,
1412 taiko_get_compander, taiko_set_compander),
1413 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
1414 taiko_get_compander, taiko_set_compander),
1415 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
1416 taiko_get_compander, taiko_set_compander),
Kiran Kandic3b24402012-06-11 00:05:59 -07001417
Kiran Kandiddbeaa32013-10-06 14:40:11 -07001418 SOC_ENUM_EXT("MAD Input", taiko_conn_mad_enum,
1419 taiko_mad_input_get, taiko_mad_input_put),
1420
Kiran Kandic3b24402012-06-11 00:05:59 -07001421};
1422
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001423static int taiko_pa_gain_get(struct snd_kcontrol *kcontrol,
1424 struct snd_ctl_elem_value *ucontrol)
1425{
1426 u8 ear_pa_gain;
1427 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1428
1429 ear_pa_gain = snd_soc_read(codec, TAIKO_A_RX_EAR_GAIN);
1430
1431 ear_pa_gain = ear_pa_gain >> 5;
1432
1433 ucontrol->value.integer.value[0] = ear_pa_gain;
1434
1435 pr_debug("%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
1436
1437 return 0;
1438}
1439
1440static int taiko_pa_gain_put(struct snd_kcontrol *kcontrol,
1441 struct snd_ctl_elem_value *ucontrol)
1442{
1443 u8 ear_pa_gain;
1444 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1445
1446 pr_debug("%s: ucontrol->value.integer.value[0] = %ld\n", __func__,
1447 ucontrol->value.integer.value[0]);
1448
1449 ear_pa_gain = ucontrol->value.integer.value[0] << 5;
1450
1451 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_GAIN, 0xE0, ear_pa_gain);
1452 return 0;
1453}
1454
1455static const char * const taiko_1_x_ear_pa_gain_text[] = {
1456 "POS_6_DB", "UNDEFINED_1", "UNDEFINED_2", "UNDEFINED_3", "POS_2_DB",
1457 "NEG_2P5_DB", "UNDEFINED_4", "NEG_12_DB"
1458};
1459
1460static const struct soc_enum taiko_1_x_ear_pa_gain_enum =
1461 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(taiko_1_x_ear_pa_gain_text),
1462 taiko_1_x_ear_pa_gain_text);
1463
1464static const struct snd_kcontrol_new taiko_1_x_analog_gain_controls[] = {
1465
1466 SOC_ENUM_EXT("EAR PA Gain", taiko_1_x_ear_pa_gain_enum,
1467 taiko_pa_gain_get, taiko_pa_gain_put),
1468
1469 SOC_SINGLE_TLV("HPHL Volume", TAIKO_A_RX_HPH_L_GAIN, 0, 20, 1,
1470 line_gain),
1471 SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 20, 1,
1472 line_gain),
1473
1474 SOC_SINGLE_TLV("LINEOUT1 Volume", TAIKO_A_RX_LINE_1_GAIN, 0, 20, 1,
1475 line_gain),
1476 SOC_SINGLE_TLV("LINEOUT2 Volume", TAIKO_A_RX_LINE_2_GAIN, 0, 20, 1,
1477 line_gain),
1478 SOC_SINGLE_TLV("LINEOUT3 Volume", TAIKO_A_RX_LINE_3_GAIN, 0, 20, 1,
1479 line_gain),
1480 SOC_SINGLE_TLV("LINEOUT4 Volume", TAIKO_A_RX_LINE_4_GAIN, 0, 20, 1,
1481 line_gain),
1482
1483 SOC_SINGLE_TLV("SPK DRV Volume", TAIKO_A_SPKR_DRV_GAIN, 3, 7, 1,
1484 line_gain),
1485
1486 SOC_SINGLE_TLV("ADC1 Volume", TAIKO_A_TX_1_2_EN, 5, 3, 0, analog_gain),
1487 SOC_SINGLE_TLV("ADC2 Volume", TAIKO_A_TX_1_2_EN, 1, 3, 0, analog_gain),
1488 SOC_SINGLE_TLV("ADC3 Volume", TAIKO_A_TX_3_4_EN, 5, 3, 0, analog_gain),
1489 SOC_SINGLE_TLV("ADC4 Volume", TAIKO_A_TX_3_4_EN, 1, 3, 0, analog_gain),
1490 SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_TX_5_6_EN, 5, 3, 0, analog_gain),
1491 SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_TX_5_6_EN, 1, 3, 0, analog_gain),
1492};
1493
1494static const char * const taiko_2_x_ear_pa_gain_text[] = {
1495 "POS_6_DB", "POS_4P5_DB", "POS_3_DB", "POS_1P5_DB",
1496 "POS_0_DB", "NEG_2P5_DB", "UNDEFINED", "NEG_12_DB"
1497};
1498
1499static const struct soc_enum taiko_2_x_ear_pa_gain_enum =
1500 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(taiko_2_x_ear_pa_gain_text),
1501 taiko_2_x_ear_pa_gain_text);
1502
1503static const struct snd_kcontrol_new taiko_2_x_analog_gain_controls[] = {
1504
1505 SOC_ENUM_EXT("EAR PA Gain", taiko_2_x_ear_pa_gain_enum,
1506 taiko_pa_gain_get, taiko_pa_gain_put),
1507
1508 SOC_SINGLE_TLV("HPHL Volume", TAIKO_A_RX_HPH_L_GAIN, 0, 20, 1,
1509 line_gain),
1510 SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 20, 1,
1511 line_gain),
1512
1513 SOC_SINGLE_TLV("LINEOUT1 Volume", TAIKO_A_RX_LINE_1_GAIN, 0, 20, 1,
1514 line_gain),
1515 SOC_SINGLE_TLV("LINEOUT2 Volume", TAIKO_A_RX_LINE_2_GAIN, 0, 20, 1,
1516 line_gain),
1517 SOC_SINGLE_TLV("LINEOUT3 Volume", TAIKO_A_RX_LINE_3_GAIN, 0, 20, 1,
1518 line_gain),
1519 SOC_SINGLE_TLV("LINEOUT4 Volume", TAIKO_A_RX_LINE_4_GAIN, 0, 20, 1,
1520 line_gain),
1521
1522 SOC_SINGLE_TLV("SPK DRV Volume", TAIKO_A_SPKR_DRV_GAIN, 3, 8, 1,
1523 line_gain),
1524
1525 SOC_SINGLE_TLV("ADC1 Volume", TAIKO_A_CDC_TX_1_GAIN, 2, 19, 0,
1526 analog_gain),
1527 SOC_SINGLE_TLV("ADC2 Volume", TAIKO_A_CDC_TX_2_GAIN, 2, 19, 0,
1528 analog_gain),
1529 SOC_SINGLE_TLV("ADC3 Volume", TAIKO_A_CDC_TX_3_GAIN, 2, 19, 0,
1530 analog_gain),
1531 SOC_SINGLE_TLV("ADC4 Volume", TAIKO_A_CDC_TX_4_GAIN, 2, 19, 0,
1532 analog_gain),
1533 SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_CDC_TX_5_GAIN, 2, 19, 0,
1534 analog_gain),
1535 SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_CDC_TX_6_GAIN, 2, 19, 0,
1536 analog_gain),
1537};
1538
Joonwoo Parkb755e9e2013-05-28 13:14:05 -07001539static int taiko_hph_impedance_get(struct snd_kcontrol *kcontrol,
1540 struct snd_ctl_elem_value *ucontrol)
1541{
1542 uint32_t zl, zr;
1543 bool hphr;
1544 struct soc_multi_mixer_control *mc;
1545 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1546 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
1547
1548 mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
1549
1550 hphr = mc->shift;
1551 wcd9xxx_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
1552 pr_debug("%s: zl %u, zr %u\n", __func__, zl, zr);
1553 ucontrol->value.integer.value[0] = hphr ? zr : zl;
1554
1555 return 0;
1556}
1557
1558static const struct snd_kcontrol_new impedance_detect_controls[] = {
1559 SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
1560 taiko_hph_impedance_get, NULL),
1561 SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
1562 taiko_hph_impedance_get, NULL),
1563};
1564
Kiran Kandic3b24402012-06-11 00:05:59 -07001565static const char * const rx_mix1_text[] = {
1566 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2", "RX1", "RX2", "RX3", "RX4",
1567 "RX5", "RX6", "RX7"
1568};
1569
1570static const char * const rx_mix2_text[] = {
1571 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2"
1572};
1573
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001574static const char * const rx_rdac5_text[] = {
1575 "DEM4", "DEM3_INV"
Kiran Kandic3b24402012-06-11 00:05:59 -07001576};
1577
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001578static const char * const rx_rdac7_text[] = {
1579 "DEM6", "DEM5_INV"
1580};
1581
1582
Kiran Kandic3b24402012-06-11 00:05:59 -07001583static const char * const sb_tx1_mux_text[] = {
1584 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1585 "DEC1"
1586};
1587
1588static const char * const sb_tx2_mux_text[] = {
1589 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1590 "DEC2"
1591};
1592
1593static const char * const sb_tx3_mux_text[] = {
1594 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1595 "DEC3"
1596};
1597
1598static const char * const sb_tx4_mux_text[] = {
1599 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1600 "DEC4"
1601};
1602
1603static const char * const sb_tx5_mux_text[] = {
1604 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1605 "DEC5"
1606};
1607
1608static const char * const sb_tx6_mux_text[] = {
1609 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1610 "DEC6"
1611};
1612
1613static const char * const sb_tx7_to_tx10_mux_text[] = {
1614 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1615 "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1616 "DEC9", "DEC10"
1617};
1618
1619static const char * const dec1_mux_text[] = {
1620 "ZERO", "DMIC1", "ADC6",
1621};
1622
1623static const char * const dec2_mux_text[] = {
1624 "ZERO", "DMIC2", "ADC5",
1625};
1626
1627static const char * const dec3_mux_text[] = {
1628 "ZERO", "DMIC3", "ADC4",
1629};
1630
1631static const char * const dec4_mux_text[] = {
1632 "ZERO", "DMIC4", "ADC3",
1633};
1634
1635static const char * const dec5_mux_text[] = {
1636 "ZERO", "DMIC5", "ADC2",
1637};
1638
1639static const char * const dec6_mux_text[] = {
1640 "ZERO", "DMIC6", "ADC1",
1641};
1642
1643static const char * const dec7_mux_text[] = {
1644 "ZERO", "DMIC1", "DMIC6", "ADC1", "ADC6", "ANC1_FB", "ANC2_FB",
1645};
1646
1647static const char * const dec8_mux_text[] = {
1648 "ZERO", "DMIC2", "DMIC5", "ADC2", "ADC5",
1649};
1650
1651static const char * const dec9_mux_text[] = {
1652 "ZERO", "DMIC4", "DMIC5", "ADC2", "ADC3", "ADCMB", "ANC1_FB", "ANC2_FB",
1653};
1654
1655static const char * const dec10_mux_text[] = {
1656 "ZERO", "DMIC3", "DMIC6", "ADC1", "ADC4", "ADCMB", "ANC1_FB", "ANC2_FB",
1657};
1658
1659static const char * const anc_mux_text[] = {
1660 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC_MB",
1661 "RSVD_1", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6"
1662};
1663
1664static const char * const anc1_fb_mux_text[] = {
1665 "ZERO", "EAR_HPH_L", "EAR_LINE_1",
1666};
1667
Fred Oh456fcb52013-02-28 19:08:15 -08001668static const char * const iir_inp1_text[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07001669 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1670 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1671};
1672
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05301673static const char * const iir_inp2_text[] = {
1674 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1675 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1676};
1677
1678static const char * const iir_inp3_text[] = {
1679 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1680 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1681};
1682
1683static const char * const iir_inp4_text[] = {
1684 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1685 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1686};
1687
Kiran Kandic3b24402012-06-11 00:05:59 -07001688static const struct soc_enum rx_mix1_inp1_chain_enum =
1689 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 0, 12, rx_mix1_text);
1690
1691static const struct soc_enum rx_mix1_inp2_chain_enum =
1692 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 4, 12, rx_mix1_text);
1693
1694static const struct soc_enum rx_mix1_inp3_chain_enum =
1695 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B2_CTL, 0, 12, rx_mix1_text);
1696
1697static const struct soc_enum rx2_mix1_inp1_chain_enum =
1698 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 0, 12, rx_mix1_text);
1699
1700static const struct soc_enum rx2_mix1_inp2_chain_enum =
1701 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 4, 12, rx_mix1_text);
1702
1703static const struct soc_enum rx3_mix1_inp1_chain_enum =
1704 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 0, 12, rx_mix1_text);
1705
1706static const struct soc_enum rx3_mix1_inp2_chain_enum =
1707 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 4, 12, rx_mix1_text);
1708
1709static const struct soc_enum rx4_mix1_inp1_chain_enum =
1710 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 0, 12, rx_mix1_text);
1711
1712static const struct soc_enum rx4_mix1_inp2_chain_enum =
1713 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 4, 12, rx_mix1_text);
1714
1715static const struct soc_enum rx5_mix1_inp1_chain_enum =
1716 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 0, 12, rx_mix1_text);
1717
1718static const struct soc_enum rx5_mix1_inp2_chain_enum =
1719 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 4, 12, rx_mix1_text);
1720
1721static const struct soc_enum rx6_mix1_inp1_chain_enum =
1722 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 0, 12, rx_mix1_text);
1723
1724static const struct soc_enum rx6_mix1_inp2_chain_enum =
1725 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 4, 12, rx_mix1_text);
1726
1727static const struct soc_enum rx7_mix1_inp1_chain_enum =
1728 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 0, 12, rx_mix1_text);
1729
1730static const struct soc_enum rx7_mix1_inp2_chain_enum =
1731 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 4, 12, rx_mix1_text);
1732
1733static const struct soc_enum rx1_mix2_inp1_chain_enum =
1734 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 0, 5, rx_mix2_text);
1735
1736static const struct soc_enum rx1_mix2_inp2_chain_enum =
1737 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 3, 5, rx_mix2_text);
1738
1739static const struct soc_enum rx2_mix2_inp1_chain_enum =
1740 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 0, 5, rx_mix2_text);
1741
1742static const struct soc_enum rx2_mix2_inp2_chain_enum =
1743 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 3, 5, rx_mix2_text);
1744
1745static const struct soc_enum rx7_mix2_inp1_chain_enum =
1746 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 0, 5, rx_mix2_text);
1747
1748static const struct soc_enum rx7_mix2_inp2_chain_enum =
1749 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 3, 5, rx_mix2_text);
1750
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001751static const struct soc_enum rx_rdac5_enum =
1752 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_MISC, 2, 2, rx_rdac5_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001753
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001754static const struct soc_enum rx_rdac7_enum =
1755 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_MISC, 1, 2, rx_rdac7_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001756
1757static const struct soc_enum sb_tx1_mux_enum =
1758 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0, 9, sb_tx1_mux_text);
1759
1760static const struct soc_enum sb_tx2_mux_enum =
1761 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0, 9, sb_tx2_mux_text);
1762
1763static const struct soc_enum sb_tx3_mux_enum =
1764 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0, 9, sb_tx3_mux_text);
1765
1766static const struct soc_enum sb_tx4_mux_enum =
1767 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0, 9, sb_tx4_mux_text);
1768
1769static const struct soc_enum sb_tx5_mux_enum =
1770 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0, 9, sb_tx5_mux_text);
1771
1772static const struct soc_enum sb_tx6_mux_enum =
1773 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0, 9, sb_tx6_mux_text);
1774
1775static const struct soc_enum sb_tx7_mux_enum =
1776 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0, 18,
1777 sb_tx7_to_tx10_mux_text);
1778
1779static const struct soc_enum sb_tx8_mux_enum =
1780 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0, 18,
1781 sb_tx7_to_tx10_mux_text);
1782
1783static const struct soc_enum sb_tx9_mux_enum =
1784 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0, 18,
1785 sb_tx7_to_tx10_mux_text);
1786
1787static const struct soc_enum sb_tx10_mux_enum =
1788 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0, 18,
1789 sb_tx7_to_tx10_mux_text);
1790
1791static const struct soc_enum dec1_mux_enum =
1792 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 0, 3, dec1_mux_text);
1793
1794static const struct soc_enum dec2_mux_enum =
1795 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 2, 3, dec2_mux_text);
1796
1797static const struct soc_enum dec3_mux_enum =
1798 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 4, 3, dec3_mux_text);
1799
1800static const struct soc_enum dec4_mux_enum =
1801 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 6, 3, dec4_mux_text);
1802
1803static const struct soc_enum dec5_mux_enum =
1804 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 0, 3, dec5_mux_text);
1805
1806static const struct soc_enum dec6_mux_enum =
1807 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 2, 3, dec6_mux_text);
1808
1809static const struct soc_enum dec7_mux_enum =
1810 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 4, 7, dec7_mux_text);
1811
1812static const struct soc_enum dec8_mux_enum =
1813 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 0, 7, dec8_mux_text);
1814
1815static const struct soc_enum dec9_mux_enum =
1816 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 3, 8, dec9_mux_text);
1817
1818static const struct soc_enum dec10_mux_enum =
1819 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B4_CTL, 0, 8, dec10_mux_text);
1820
1821static const struct soc_enum anc1_mux_enum =
1822 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 0, 16, anc_mux_text);
1823
1824static const struct soc_enum anc2_mux_enum =
1825 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 4, 16, anc_mux_text);
1826
1827static const struct soc_enum anc1_fb_mux_enum =
1828 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B2_CTL, 0, 3, anc1_fb_mux_text);
1829
1830static const struct soc_enum iir1_inp1_mux_enum =
Fred Oh456fcb52013-02-28 19:08:15 -08001831 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir_inp1_text);
1832
1833static const struct soc_enum iir2_inp1_mux_enum =
1834 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B1_CTL, 0, 18, iir_inp1_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001835
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05301836static const struct soc_enum iir1_inp2_mux_enum =
1837 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B2_CTL, 0, 18, iir_inp2_text);
1838
1839static const struct soc_enum iir2_inp2_mux_enum =
1840 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B2_CTL, 0, 18, iir_inp2_text);
1841
1842static const struct soc_enum iir1_inp3_mux_enum =
1843 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B3_CTL, 0, 18, iir_inp3_text);
1844
1845static const struct soc_enum iir2_inp3_mux_enum =
1846 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B3_CTL, 0, 18, iir_inp3_text);
1847
1848static const struct soc_enum iir1_inp4_mux_enum =
1849 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B4_CTL, 0, 18, iir_inp4_text);
1850
1851static const struct soc_enum iir2_inp4_mux_enum =
1852 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B4_CTL, 0, 18, iir_inp4_text);
1853
Kiran Kandic3b24402012-06-11 00:05:59 -07001854static const struct snd_kcontrol_new rx_mix1_inp1_mux =
1855 SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
1856
1857static const struct snd_kcontrol_new rx_mix1_inp2_mux =
1858 SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
1859
1860static const struct snd_kcontrol_new rx_mix1_inp3_mux =
1861 SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
1862
1863static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
1864 SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
1865
1866static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
1867 SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
1868
1869static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
1870 SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
1871
1872static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
1873 SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
1874
1875static const struct snd_kcontrol_new rx4_mix1_inp1_mux =
1876 SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum);
1877
1878static const struct snd_kcontrol_new rx4_mix1_inp2_mux =
1879 SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum);
1880
1881static const struct snd_kcontrol_new rx5_mix1_inp1_mux =
1882 SOC_DAPM_ENUM("RX5 MIX1 INP1 Mux", rx5_mix1_inp1_chain_enum);
1883
1884static const struct snd_kcontrol_new rx5_mix1_inp2_mux =
1885 SOC_DAPM_ENUM("RX5 MIX1 INP2 Mux", rx5_mix1_inp2_chain_enum);
1886
1887static const struct snd_kcontrol_new rx6_mix1_inp1_mux =
1888 SOC_DAPM_ENUM("RX6 MIX1 INP1 Mux", rx6_mix1_inp1_chain_enum);
1889
1890static const struct snd_kcontrol_new rx6_mix1_inp2_mux =
1891 SOC_DAPM_ENUM("RX6 MIX1 INP2 Mux", rx6_mix1_inp2_chain_enum);
1892
1893static const struct snd_kcontrol_new rx7_mix1_inp1_mux =
1894 SOC_DAPM_ENUM("RX7 MIX1 INP1 Mux", rx7_mix1_inp1_chain_enum);
1895
1896static const struct snd_kcontrol_new rx7_mix1_inp2_mux =
1897 SOC_DAPM_ENUM("RX7 MIX1 INP2 Mux", rx7_mix1_inp2_chain_enum);
1898
1899static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
1900 SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_mix2_inp1_chain_enum);
1901
1902static const struct snd_kcontrol_new rx1_mix2_inp2_mux =
1903 SOC_DAPM_ENUM("RX1 MIX2 INP2 Mux", rx1_mix2_inp2_chain_enum);
1904
1905static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
1906 SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
1907
1908static const struct snd_kcontrol_new rx2_mix2_inp2_mux =
1909 SOC_DAPM_ENUM("RX2 MIX2 INP2 Mux", rx2_mix2_inp2_chain_enum);
1910
1911static const struct snd_kcontrol_new rx7_mix2_inp1_mux =
1912 SOC_DAPM_ENUM("RX7 MIX2 INP1 Mux", rx7_mix2_inp1_chain_enum);
1913
1914static const struct snd_kcontrol_new rx7_mix2_inp2_mux =
1915 SOC_DAPM_ENUM("RX7 MIX2 INP2 Mux", rx7_mix2_inp2_chain_enum);
1916
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001917static const struct snd_kcontrol_new rx_dac5_mux =
1918 SOC_DAPM_ENUM("RDAC5 MUX Mux", rx_rdac5_enum);
Kiran Kandic3b24402012-06-11 00:05:59 -07001919
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001920static const struct snd_kcontrol_new rx_dac7_mux =
1921 SOC_DAPM_ENUM("RDAC7 MUX Mux", rx_rdac7_enum);
Kiran Kandic3b24402012-06-11 00:05:59 -07001922
1923static const struct snd_kcontrol_new sb_tx1_mux =
1924 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
1925
1926static const struct snd_kcontrol_new sb_tx2_mux =
1927 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
1928
1929static const struct snd_kcontrol_new sb_tx3_mux =
1930 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
1931
1932static const struct snd_kcontrol_new sb_tx4_mux =
1933 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
1934
1935static const struct snd_kcontrol_new sb_tx5_mux =
1936 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
1937
1938static const struct snd_kcontrol_new sb_tx6_mux =
1939 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
1940
1941static const struct snd_kcontrol_new sb_tx7_mux =
1942 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
1943
1944static const struct snd_kcontrol_new sb_tx8_mux =
1945 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
1946
1947static const struct snd_kcontrol_new sb_tx9_mux =
1948 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
1949
1950static const struct snd_kcontrol_new sb_tx10_mux =
1951 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
1952
1953
1954static int wcd9320_put_dec_enum(struct snd_kcontrol *kcontrol,
1955 struct snd_ctl_elem_value *ucontrol)
1956{
1957 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1958 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1959 struct snd_soc_codec *codec = w->codec;
1960 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1961 unsigned int dec_mux, decimator;
1962 char *dec_name = NULL;
1963 char *widget_name = NULL;
1964 char *temp;
1965 u16 tx_mux_ctl_reg;
1966 u8 adc_dmic_sel = 0x0;
1967 int ret = 0;
1968
1969 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1970 return -EINVAL;
1971
1972 dec_mux = ucontrol->value.enumerated.item[0];
1973
1974 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
1975 if (!widget_name)
1976 return -ENOMEM;
1977 temp = widget_name;
1978
1979 dec_name = strsep(&widget_name, " ");
1980 widget_name = temp;
1981 if (!dec_name) {
1982 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
1983 ret = -EINVAL;
1984 goto out;
1985 }
1986
1987 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
1988 if (ret < 0) {
1989 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
1990 ret = -EINVAL;
1991 goto out;
1992 }
1993
1994 dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
1995 , __func__, w->name, decimator, dec_mux);
1996
1997
1998 switch (decimator) {
1999 case 1:
2000 case 2:
2001 case 3:
2002 case 4:
2003 case 5:
2004 case 6:
2005 if (dec_mux == 1)
2006 adc_dmic_sel = 0x1;
2007 else
2008 adc_dmic_sel = 0x0;
2009 break;
2010 case 7:
2011 case 8:
2012 case 9:
2013 case 10:
2014 if ((dec_mux == 1) || (dec_mux == 2))
2015 adc_dmic_sel = 0x1;
2016 else
2017 adc_dmic_sel = 0x0;
2018 break;
2019 default:
2020 pr_err("%s: Invalid Decimator = %u\n", __func__, decimator);
2021 ret = -EINVAL;
2022 goto out;
2023 }
2024
2025 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
2026
2027 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
2028
2029 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
2030
2031out:
2032 kfree(widget_name);
2033 return ret;
2034}
2035
2036#define WCD9320_DEC_ENUM(xname, xenum) \
2037{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2038 .info = snd_soc_info_enum_double, \
2039 .get = snd_soc_dapm_get_enum_double, \
2040 .put = wcd9320_put_dec_enum, \
2041 .private_value = (unsigned long)&xenum }
2042
2043static const struct snd_kcontrol_new dec1_mux =
2044 WCD9320_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
2045
2046static const struct snd_kcontrol_new dec2_mux =
2047 WCD9320_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
2048
2049static const struct snd_kcontrol_new dec3_mux =
2050 WCD9320_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum);
2051
2052static const struct snd_kcontrol_new dec4_mux =
2053 WCD9320_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum);
2054
2055static const struct snd_kcontrol_new dec5_mux =
2056 WCD9320_DEC_ENUM("DEC5 MUX Mux", dec5_mux_enum);
2057
2058static const struct snd_kcontrol_new dec6_mux =
2059 WCD9320_DEC_ENUM("DEC6 MUX Mux", dec6_mux_enum);
2060
2061static const struct snd_kcontrol_new dec7_mux =
2062 WCD9320_DEC_ENUM("DEC7 MUX Mux", dec7_mux_enum);
2063
2064static const struct snd_kcontrol_new dec8_mux =
2065 WCD9320_DEC_ENUM("DEC8 MUX Mux", dec8_mux_enum);
2066
2067static const struct snd_kcontrol_new dec9_mux =
2068 WCD9320_DEC_ENUM("DEC9 MUX Mux", dec9_mux_enum);
2069
2070static const struct snd_kcontrol_new dec10_mux =
2071 WCD9320_DEC_ENUM("DEC10 MUX Mux", dec10_mux_enum);
2072
2073static const struct snd_kcontrol_new iir1_inp1_mux =
2074 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
2075
Fred Oh456fcb52013-02-28 19:08:15 -08002076static const struct snd_kcontrol_new iir2_inp1_mux =
2077 SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
2078
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05302079static const struct snd_kcontrol_new iir1_inp2_mux =
2080 SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
2081
2082static const struct snd_kcontrol_new iir2_inp2_mux =
2083 SOC_DAPM_ENUM("IIR2 INP2 Mux", iir2_inp2_mux_enum);
2084
2085static const struct snd_kcontrol_new iir1_inp3_mux =
2086 SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
2087
2088static const struct snd_kcontrol_new iir2_inp3_mux =
2089 SOC_DAPM_ENUM("IIR2 INP3 Mux", iir2_inp3_mux_enum);
2090
2091static const struct snd_kcontrol_new iir1_inp4_mux =
2092 SOC_DAPM_ENUM("IIR1 INP4 Mux", iir1_inp4_mux_enum);
2093
2094static const struct snd_kcontrol_new iir2_inp4_mux =
2095 SOC_DAPM_ENUM("IIR2 INP4 Mux", iir2_inp4_mux_enum);
2096
Kiran Kandic3b24402012-06-11 00:05:59 -07002097static const struct snd_kcontrol_new anc1_mux =
2098 SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
2099
2100static const struct snd_kcontrol_new anc2_mux =
2101 SOC_DAPM_ENUM("ANC2 MUX Mux", anc2_mux_enum);
2102
2103static const struct snd_kcontrol_new anc1_fb_mux =
2104 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
2105
2106static const struct snd_kcontrol_new dac1_switch[] = {
2107 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_EAR_EN, 5, 1, 0)
2108};
2109static const struct snd_kcontrol_new hphl_switch[] = {
2110 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
2111};
2112
2113static const struct snd_kcontrol_new hphl_pa_mix[] = {
2114 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2115 7, 1, 0),
2116};
2117
2118static const struct snd_kcontrol_new hphr_pa_mix[] = {
2119 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2120 6, 1, 0),
2121};
2122
2123static const struct snd_kcontrol_new ear_pa_mix[] = {
2124 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2125 5, 1, 0),
2126};
2127static const struct snd_kcontrol_new lineout1_pa_mix[] = {
2128 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2129 4, 1, 0),
2130};
2131
2132static const struct snd_kcontrol_new lineout2_pa_mix[] = {
2133 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2134 3, 1, 0),
2135};
2136
2137static const struct snd_kcontrol_new lineout3_pa_mix[] = {
2138 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2139 2, 1, 0),
2140};
2141
2142static const struct snd_kcontrol_new lineout4_pa_mix[] = {
2143 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2144 1, 1, 0),
2145};
2146
2147static const struct snd_kcontrol_new lineout3_ground_switch =
2148 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_3_DAC_CTL, 6, 1, 0);
2149
2150static const struct snd_kcontrol_new lineout4_ground_switch =
2151 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_4_DAC_CTL, 6, 1, 0);
2152
Joonwoo Park9ead0e92013-03-18 11:33:33 -07002153static const struct snd_kcontrol_new aif4_mad_switch =
2154 SOC_DAPM_SINGLE("Switch", TAIKO_A_CDC_CLK_OTHR_CTL, 4, 1, 0);
2155
Kuirong Wang906ac472012-07-09 12:54:44 -07002156/* virtual port entries */
2157static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
2158 struct snd_ctl_elem_value *ucontrol)
2159{
2160 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2161 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2162
2163 ucontrol->value.integer.value[0] = widget->value;
2164 return 0;
2165}
2166
2167static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
2168 struct snd_ctl_elem_value *ucontrol)
2169{
2170 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2171 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2172 struct snd_soc_codec *codec = widget->codec;
2173 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
2174 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2175 struct soc_multi_mixer_control *mixer =
2176 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2177 u32 dai_id = widget->shift;
2178 u32 port_id = mixer->shift;
2179 u32 enable = ucontrol->value.integer.value[0];
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08002180 u32 vtable = vport_check_table[dai_id];
Kuirong Wang906ac472012-07-09 12:54:44 -07002181
2182
2183 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
2184 widget->name, ucontrol->id.name, widget->value, widget->shift,
2185 ucontrol->value.integer.value[0]);
2186
2187 mutex_lock(&codec->mutex);
2188
2189 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
2190 if (dai_id != AIF1_CAP) {
2191 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2192 __func__);
2193 mutex_unlock(&codec->mutex);
2194 return -EINVAL;
2195 }
2196 }
Venkat Sudhira41630a2012-10-27 00:57:31 -07002197 switch (dai_id) {
2198 case AIF1_CAP:
2199 case AIF2_CAP:
2200 case AIF3_CAP:
2201 /* only add to the list if value not set
2202 */
2203 if (enable && !(widget->value & 1 << port_id)) {
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08002204
2205 if (taiko_p->intf_type ==
2206 WCD9XXX_INTERFACE_TYPE_SLIMBUS)
2207 vtable = vport_check_table[dai_id];
2208 if (taiko_p->intf_type ==
2209 WCD9XXX_INTERFACE_TYPE_I2C)
2210 vtable = vport_i2s_check_table[dai_id];
2211
Venkat Sudhira41630a2012-10-27 00:57:31 -07002212 if (wcd9xxx_tx_vport_validation(
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08002213 vtable,
Kuirong Wangdcc392e2012-10-19 00:33:38 -07002214 port_id,
Aravind Kumarb95c8492014-03-21 12:43:29 +05302215 taiko_p->dai, NUM_CODEC_DAIS)) {
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002216 dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n",
Venkat Sudhira41630a2012-10-27 00:57:31 -07002217 __func__, port_id + 1);
2218 mutex_unlock(&codec->mutex);
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002219 return 0;
Venkat Sudhira41630a2012-10-27 00:57:31 -07002220 }
2221 widget->value |= 1 << port_id;
2222 list_add_tail(&core->tx_chs[port_id].list,
Kuirong Wang906ac472012-07-09 12:54:44 -07002223 &taiko_p->dai[dai_id].wcd9xxx_ch_list
Venkat Sudhira41630a2012-10-27 00:57:31 -07002224 );
2225 } else if (!enable && (widget->value & 1 << port_id)) {
2226 widget->value &= ~(1 << port_id);
2227 list_del_init(&core->tx_chs[port_id].list);
2228 } else {
2229 if (enable)
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002230 dev_dbg(codec->dev, "%s: TX%u port is used by\n"
Venkat Sudhira41630a2012-10-27 00:57:31 -07002231 "this virtual port\n",
2232 __func__, port_id + 1);
2233 else
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002234 dev_dbg(codec->dev, "%s: TX%u port is not used by\n"
Venkat Sudhira41630a2012-10-27 00:57:31 -07002235 "this virtual port\n",
2236 __func__, port_id + 1);
2237 /* avoid update power function */
2238 mutex_unlock(&codec->mutex);
2239 return 0;
2240 }
2241 break;
2242 default:
2243 pr_err("Unknown AIF %d\n", dai_id);
Kuirong Wang906ac472012-07-09 12:54:44 -07002244 mutex_unlock(&codec->mutex);
Venkat Sudhira41630a2012-10-27 00:57:31 -07002245 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07002246 }
Kuirong Wang906ac472012-07-09 12:54:44 -07002247 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
2248 widget->name, widget->sname, widget->value, widget->shift);
2249
2250 snd_soc_dapm_mixer_update_power(widget, kcontrol, enable);
2251
2252 mutex_unlock(&codec->mutex);
2253 return 0;
2254}
2255
2256static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
2257 struct snd_ctl_elem_value *ucontrol)
2258{
2259 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2260 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2261
2262 ucontrol->value.enumerated.item[0] = widget->value;
2263 return 0;
2264}
2265
2266static const char *const slim_rx_mux_text[] = {
2267 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
2268};
2269
2270static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
2271 struct snd_ctl_elem_value *ucontrol)
2272{
2273 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2274 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2275 struct snd_soc_codec *codec = widget->codec;
2276 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
2277 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2278 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2279 u32 port_id = widget->shift;
2280
2281 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
2282 widget->name, ucontrol->id.name, widget->value, widget->shift,
2283 ucontrol->value.integer.value[0]);
2284
2285 widget->value = ucontrol->value.enumerated.item[0];
2286
2287 mutex_lock(&codec->mutex);
2288
2289 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Venkat Sudhir994193b2012-12-17 17:30:51 -08002290 if (widget->value > 2) {
Kuirong Wang906ac472012-07-09 12:54:44 -07002291 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2292 __func__);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07002293 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07002294 }
2295 }
2296 /* value need to match the Virtual port and AIF number
2297 */
2298 switch (widget->value) {
2299 case 0:
2300 list_del_init(&core->rx_chs[port_id].list);
2301 break;
2302 case 1:
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002303 if (wcd9xxx_rx_vport_validation(port_id +
2304 TAIKO_RX_PORT_START_NUMBER,
2305 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list)) {
2306 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2307 __func__, port_id + 1);
2308 goto rtn;
2309 }
Kuirong Wang906ac472012-07-09 12:54:44 -07002310 list_add_tail(&core->rx_chs[port_id].list,
2311 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list);
2312 break;
2313 case 2:
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002314 if (wcd9xxx_rx_vport_validation(port_id +
2315 TAIKO_RX_PORT_START_NUMBER,
2316 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list)) {
2317 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2318 __func__, port_id + 1);
2319 goto rtn;
2320 }
Kuirong Wang906ac472012-07-09 12:54:44 -07002321 list_add_tail(&core->rx_chs[port_id].list,
2322 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list);
2323 break;
2324 case 3:
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002325 if (wcd9xxx_rx_vport_validation(port_id +
2326 TAIKO_RX_PORT_START_NUMBER,
2327 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list)) {
2328 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2329 __func__, port_id + 1);
2330 goto rtn;
2331 }
Kuirong Wang906ac472012-07-09 12:54:44 -07002332 list_add_tail(&core->rx_chs[port_id].list,
2333 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list);
2334 break;
2335 default:
2336 pr_err("Unknown AIF %d\n", widget->value);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07002337 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07002338 }
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002339rtn:
Kuirong Wang906ac472012-07-09 12:54:44 -07002340 snd_soc_dapm_mux_update_power(widget, kcontrol, 1, widget->value, e);
2341
2342 mutex_unlock(&codec->mutex);
2343 return 0;
Kuirong Wangdcc392e2012-10-19 00:33:38 -07002344err:
2345 mutex_unlock(&codec->mutex);
2346 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07002347}
2348
2349static const struct soc_enum slim_rx_mux_enum =
2350 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
2351
2352static const struct snd_kcontrol_new slim_rx_mux[TAIKO_RX_MAX] = {
2353 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
2354 slim_rx_mux_get, slim_rx_mux_put),
2355 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
2356 slim_rx_mux_get, slim_rx_mux_put),
2357 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
2358 slim_rx_mux_get, slim_rx_mux_put),
2359 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
2360 slim_rx_mux_get, slim_rx_mux_put),
2361 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
2362 slim_rx_mux_get, slim_rx_mux_put),
2363 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
2364 slim_rx_mux_get, slim_rx_mux_put),
2365 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
2366 slim_rx_mux_get, slim_rx_mux_put),
2367};
2368
2369static const struct snd_kcontrol_new aif_cap_mixer[] = {
2370 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TAIKO_TX1, 1, 0,
2371 slim_tx_mixer_get, slim_tx_mixer_put),
2372 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TAIKO_TX2, 1, 0,
2373 slim_tx_mixer_get, slim_tx_mixer_put),
2374 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TAIKO_TX3, 1, 0,
2375 slim_tx_mixer_get, slim_tx_mixer_put),
2376 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TAIKO_TX4, 1, 0,
2377 slim_tx_mixer_get, slim_tx_mixer_put),
2378 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TAIKO_TX5, 1, 0,
2379 slim_tx_mixer_get, slim_tx_mixer_put),
2380 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TAIKO_TX6, 1, 0,
2381 slim_tx_mixer_get, slim_tx_mixer_put),
2382 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TAIKO_TX7, 1, 0,
2383 slim_tx_mixer_get, slim_tx_mixer_put),
2384 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TAIKO_TX8, 1, 0,
2385 slim_tx_mixer_get, slim_tx_mixer_put),
2386 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TAIKO_TX9, 1, 0,
2387 slim_tx_mixer_get, slim_tx_mixer_put),
2388 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TAIKO_TX10, 1, 0,
2389 slim_tx_mixer_get, slim_tx_mixer_put),
2390};
2391
Kiran Kandic3b24402012-06-11 00:05:59 -07002392static void taiko_codec_enable_adc_block(struct snd_soc_codec *codec,
2393 int enable)
2394{
2395 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2396
2397 pr_debug("%s %d\n", __func__, enable);
2398
2399 if (enable) {
2400 taiko->adc_count++;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002401 snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
2402 0x2, 0x2);
Kiran Kandic3b24402012-06-11 00:05:59 -07002403 } else {
2404 taiko->adc_count--;
2405 if (!taiko->adc_count)
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002406 snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
Kiran Kandic3b24402012-06-11 00:05:59 -07002407 0x2, 0x0);
2408 }
2409}
2410
2411static int taiko_codec_enable_adc(struct snd_soc_dapm_widget *w,
2412 struct snd_kcontrol *kcontrol, int event)
2413{
2414 struct snd_soc_codec *codec = w->codec;
2415 u16 adc_reg;
2416 u8 init_bit_shift;
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002417 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07002418
2419 pr_debug("%s %d\n", __func__, event);
2420
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002421 if (TAIKO_IS_1_0(core->version)) {
2422 if (w->reg == TAIKO_A_TX_1_2_EN) {
2423 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2424 } else if (w->reg == TAIKO_A_TX_3_4_EN) {
2425 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2426 } else if (w->reg == TAIKO_A_TX_5_6_EN) {
2427 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2428 } else {
2429 pr_err("%s: Error, invalid adc register\n", __func__);
2430 return -EINVAL;
2431 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002432
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002433 if (w->shift == 3) {
2434 init_bit_shift = 6;
2435 } else if (w->shift == 7) {
2436 init_bit_shift = 7;
2437 } else {
2438 pr_err("%s: Error, invalid init bit postion adc register\n",
2439 __func__);
2440 return -EINVAL;
2441 }
2442 } else {
2443 switch (w->reg) {
2444 case TAIKO_A_CDC_TX_1_GAIN:
2445 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2446 init_bit_shift = 7;
2447 break;
2448 case TAIKO_A_CDC_TX_2_GAIN:
2449 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2450 init_bit_shift = 6;
2451 break;
2452 case TAIKO_A_CDC_TX_3_GAIN:
2453 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2454 init_bit_shift = 7;
2455 break;
2456 case TAIKO_A_CDC_TX_4_GAIN:
2457 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2458 init_bit_shift = 6;
2459 break;
2460 case TAIKO_A_CDC_TX_5_GAIN:
2461 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2462 init_bit_shift = 7;
2463 break;
2464 case TAIKO_A_CDC_TX_6_GAIN:
2465 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2466 init_bit_shift = 6;
2467 break;
2468 default:
2469 pr_err("%s: Error, invalid adc register\n", __func__);
2470 return -EINVAL;
2471 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002472 }
2473
2474 switch (event) {
2475 case SND_SOC_DAPM_PRE_PMU:
2476 taiko_codec_enable_adc_block(codec, 1);
2477 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
2478 1 << init_bit_shift);
2479 break;
2480 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002481 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -07002482 break;
2483 case SND_SOC_DAPM_POST_PMD:
2484 taiko_codec_enable_adc_block(codec, 0);
2485 break;
2486 }
2487 return 0;
2488}
2489
Kiran Kandic3b24402012-06-11 00:05:59 -07002490static int taiko_codec_enable_aux_pga(struct snd_soc_dapm_widget *w,
2491 struct snd_kcontrol *kcontrol, int event)
2492{
2493 struct snd_soc_codec *codec = w->codec;
2494 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2495
2496 pr_debug("%s: %d\n", __func__, event);
2497
2498 switch (event) {
2499 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Park533b3682013-06-13 11:41:21 -07002500 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Joonwoo Parka8890262012-10-15 12:04:27 -07002501 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
2502 WCD9XXX_BANDGAP_AUDIO_MODE);
2503 /* AUX PGA requires RCO or MCLK */
2504 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
2505 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
Joonwoo Park533b3682013-06-13 11:41:21 -07002506 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07002507 break;
2508
2509 case SND_SOC_DAPM_POST_PMD:
Joonwoo Park533b3682013-06-13 11:41:21 -07002510 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Joonwoo Parka8890262012-10-15 12:04:27 -07002511 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
2512 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
2513 WCD9XXX_BANDGAP_AUDIO_MODE);
2514 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
Joonwoo Park533b3682013-06-13 11:41:21 -07002515 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07002516 break;
2517 }
2518 return 0;
2519}
2520
2521static int taiko_codec_enable_lineout(struct snd_soc_dapm_widget *w,
2522 struct snd_kcontrol *kcontrol, int event)
2523{
2524 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002525 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002526 u16 lineout_gain_reg;
2527
2528 pr_debug("%s %d %s\n", __func__, event, w->name);
2529
2530 switch (w->shift) {
2531 case 0:
2532 lineout_gain_reg = TAIKO_A_RX_LINE_1_GAIN;
2533 break;
2534 case 1:
2535 lineout_gain_reg = TAIKO_A_RX_LINE_2_GAIN;
2536 break;
2537 case 2:
2538 lineout_gain_reg = TAIKO_A_RX_LINE_3_GAIN;
2539 break;
2540 case 3:
2541 lineout_gain_reg = TAIKO_A_RX_LINE_4_GAIN;
2542 break;
2543 default:
2544 pr_err("%s: Error, incorrect lineout register value\n",
2545 __func__);
2546 return -EINVAL;
2547 }
2548
2549 switch (event) {
2550 case SND_SOC_DAPM_PRE_PMU:
2551 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
2552 break;
2553 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002554 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2555 WCD9XXX_CLSH_STATE_LO,
2556 WCD9XXX_CLSH_REQ_ENABLE,
2557 WCD9XXX_CLSH_EVENT_POST_PA);
2558 pr_debug("%s: sleeping 3 ms after %s PA turn on\n",
Kiran Kandic3b24402012-06-11 00:05:59 -07002559 __func__, w->name);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002560 usleep_range(3000, 3000);
Kiran Kandic3b24402012-06-11 00:05:59 -07002561 break;
2562 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002563 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2564 WCD9XXX_CLSH_STATE_LO,
2565 WCD9XXX_CLSH_REQ_DISABLE,
2566 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandic3b24402012-06-11 00:05:59 -07002567 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
2568 break;
2569 }
2570 return 0;
2571}
2572
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002573static int taiko_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
2574 struct snd_kcontrol *kcontrol, int event)
2575{
Joonwoo Park125cd4e2012-12-11 15:16:11 -08002576 struct snd_soc_codec *codec = w->codec;
2577 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2578
2579 pr_debug("%s: %d %s\n", __func__, event, w->name);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08002580 switch (event) {
2581 case SND_SOC_DAPM_PRE_PMU:
2582 taiko->spkr_pa_widget_on = true;
2583 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
2584 break;
2585 case SND_SOC_DAPM_POST_PMD:
2586 taiko->spkr_pa_widget_on = false;
2587 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x00);
2588 break;
2589 }
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002590 return 0;
2591}
Kiran Kandic3b24402012-06-11 00:05:59 -07002592
2593static int taiko_codec_enable_dmic(struct snd_soc_dapm_widget *w,
2594 struct snd_kcontrol *kcontrol, int event)
2595{
2596 struct snd_soc_codec *codec = w->codec;
2597 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2598 u8 dmic_clk_en;
2599 u16 dmic_clk_reg;
2600 s32 *dmic_clk_cnt;
2601 unsigned int dmic;
2602 int ret;
2603
2604 ret = kstrtouint(strpbrk(w->name, "123456"), 10, &dmic);
2605 if (ret < 0) {
2606 pr_err("%s: Invalid DMIC line on the codec\n", __func__);
2607 return -EINVAL;
2608 }
2609
2610 switch (dmic) {
2611 case 1:
2612 case 2:
2613 dmic_clk_en = 0x01;
2614 dmic_clk_cnt = &(taiko->dmic_1_2_clk_cnt);
2615 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
2616 pr_debug("%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
2617 __func__, event, dmic, *dmic_clk_cnt);
2618
2619 break;
2620
2621 case 3:
2622 case 4:
2623 dmic_clk_en = 0x10;
2624 dmic_clk_cnt = &(taiko->dmic_3_4_clk_cnt);
2625 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
2626
2627 pr_debug("%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n",
2628 __func__, event, dmic, *dmic_clk_cnt);
2629 break;
2630
2631 case 5:
2632 case 6:
2633 dmic_clk_en = 0x01;
2634 dmic_clk_cnt = &(taiko->dmic_5_6_clk_cnt);
2635 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B2_CTL;
2636
2637 pr_debug("%s() event %d DMIC%d dmic_5_6_clk_cnt %d\n",
2638 __func__, event, dmic, *dmic_clk_cnt);
2639
2640 break;
2641
2642 default:
2643 pr_err("%s: Invalid DMIC Selection\n", __func__);
2644 return -EINVAL;
2645 }
2646
2647 switch (event) {
2648 case SND_SOC_DAPM_PRE_PMU:
2649
2650 (*dmic_clk_cnt)++;
2651 if (*dmic_clk_cnt == 1)
2652 snd_soc_update_bits(codec, dmic_clk_reg,
2653 dmic_clk_en, dmic_clk_en);
2654
2655 break;
2656 case SND_SOC_DAPM_POST_PMD:
2657
2658 (*dmic_clk_cnt)--;
2659 if (*dmic_clk_cnt == 0)
2660 snd_soc_update_bits(codec, dmic_clk_reg,
2661 dmic_clk_en, 0);
2662 break;
2663 }
2664 return 0;
2665}
2666
Joonwoo Park1d05bb92013-03-07 16:55:06 -08002667static int taiko_codec_config_mad(struct snd_soc_codec *codec)
2668{
2669 int ret;
2670 const struct firmware *fw;
2671 struct mad_audio_cal *mad_cal;
2672 const char *filename = TAIKO_MAD_AUDIO_FIRMWARE_PATH;
2673
2674 pr_debug("%s: enter\n", __func__);
2675 ret = request_firmware(&fw, filename, codec->dev);
2676 if (ret != 0) {
2677 pr_err("Failed to acquire MAD firwmare data %s: %d\n", filename,
2678 ret);
2679 return -ENODEV;
2680 }
2681
2682 if (fw->size < sizeof(struct mad_audio_cal)) {
2683 pr_err("%s: incorrect firmware size %u\n", __func__, fw->size);
2684 release_firmware(fw);
2685 return -ENOMEM;
2686 }
2687
2688 mad_cal = (struct mad_audio_cal *)(fw->data);
2689 if (!mad_cal) {
2690 pr_err("%s: Invalid calibration data\n", __func__);
2691 release_firmware(fw);
2692 return -EINVAL;
2693 }
2694
Joonwoo Park1d05bb92013-03-07 16:55:06 -08002695 snd_soc_write(codec, TAIKO_A_CDC_MAD_MAIN_CTL_2,
2696 mad_cal->microphone_info.cycle_time);
2697 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_MAIN_CTL_1, 0xFF << 3,
2698 ((uint16_t)mad_cal->microphone_info.settle_time)
2699 << 3);
2700
2701 /* Audio */
2702 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_8,
2703 mad_cal->audio_info.rms_omit_samples);
2704 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_1,
2705 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
2706 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_2, 0x03 << 2,
2707 mad_cal->audio_info.detection_mechanism << 2);
2708 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_7,
2709 mad_cal->audio_info.rms_diff_threshold & 0x3F);
2710 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_5,
2711 mad_cal->audio_info.rms_threshold_lsb);
2712 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_6,
2713 mad_cal->audio_info.rms_threshold_msb);
2714
2715
2716 /* Beacon */
2717 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_8,
2718 mad_cal->beacon_info.rms_omit_samples);
2719 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_1,
2720 0x07 << 4, mad_cal->beacon_info.rms_comp_time);
2721 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_2, 0x03 << 2,
2722 mad_cal->beacon_info.detection_mechanism << 2);
2723 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_7,
2724 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
2725 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_5,
2726 mad_cal->beacon_info.rms_threshold_lsb);
2727 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_6,
2728 mad_cal->beacon_info.rms_threshold_msb);
2729
2730 /* Ultrasound */
2731 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_1,
2732 0x07 << 4, mad_cal->beacon_info.rms_comp_time);
2733 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_ULTR_CTL_2, 0x03 << 2,
2734 mad_cal->ultrasound_info.detection_mechanism);
2735 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_7,
2736 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
2737 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_5,
2738 mad_cal->ultrasound_info.rms_threshold_lsb);
2739 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_6,
2740 mad_cal->ultrasound_info.rms_threshold_msb);
2741
2742 release_firmware(fw);
2743 pr_debug("%s: leave ret %d\n", __func__, ret);
2744
2745 return ret;
2746}
2747
2748static int taiko_codec_enable_mad(struct snd_soc_dapm_widget *w,
2749 struct snd_kcontrol *kcontrol, int event)
2750{
2751 struct snd_soc_codec *codec = w->codec;
2752 int ret = 0;
2753
2754 pr_debug("%s %d\n", __func__, event);
2755 switch (event) {
2756 case SND_SOC_DAPM_PRE_PMU:
2757 ret = taiko_codec_config_mad(codec);
2758 if (ret) {
2759 pr_err("%s: Failed to config MAD\n", __func__);
2760 break;
2761 }
2762 break;
2763 }
2764 return ret;
2765}
2766
Kiran Kandic3b24402012-06-11 00:05:59 -07002767static int taiko_codec_enable_micbias(struct snd_soc_dapm_widget *w,
2768 struct snd_kcontrol *kcontrol, int event)
2769{
2770 struct snd_soc_codec *codec = w->codec;
2771 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Park3699ca32013-02-08 12:06:15 -08002772 u16 micb_int_reg = 0, micb_ctl_reg = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07002773 u8 cfilt_sel_val = 0;
2774 char *internal1_text = "Internal1";
2775 char *internal2_text = "Internal2";
2776 char *internal3_text = "Internal3";
Joonwoo Parka8890262012-10-15 12:04:27 -07002777 enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
Kiran Kandic3b24402012-06-11 00:05:59 -07002778
Joonwoo Park3699ca32013-02-08 12:06:15 -08002779 pr_debug("%s: w->name %s event %d\n", __func__, w->name, event);
2780 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) {
2781 micb_ctl_reg = TAIKO_A_MICB_1_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002782 micb_int_reg = TAIKO_A_MICB_1_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002783 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias1_cfilt_sel;
2784 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
2785 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
2786 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002787 } else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) {
2788 micb_ctl_reg = TAIKO_A_MICB_2_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002789 micb_int_reg = TAIKO_A_MICB_2_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002790 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias2_cfilt_sel;
2791 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
2792 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
2793 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002794 } else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) {
Damir Didjusto6e4f9d22013-03-07 10:10:57 -08002795 micb_ctl_reg = TAIKO_A_MICB_3_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002796 micb_int_reg = TAIKO_A_MICB_3_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002797 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias3_cfilt_sel;
2798 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
2799 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
2800 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002801 } else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) {
Damir Didjusto6e4f9d22013-03-07 10:10:57 -08002802 micb_ctl_reg = TAIKO_A_MICB_4_CTL;
Joonwoo Parka8890262012-10-15 12:04:27 -07002803 micb_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
2804 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias4_cfilt_sel;
2805 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_4_ON;
2806 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_4_ON;
2807 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_4_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002808 } else {
2809 pr_err("%s: Error, invalid micbias %s\n", __func__, w->name);
Kiran Kandic3b24402012-06-11 00:05:59 -07002810 return -EINVAL;
2811 }
2812
2813 switch (event) {
2814 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002815 /* Let MBHC module know so micbias switch to be off */
2816 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002817
Joonwoo Parka8890262012-10-15 12:04:27 -07002818 /* Get cfilt */
2819 wcd9xxx_resmgr_cfilt_get(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002820
2821 if (strnstr(w->name, internal1_text, 30))
2822 snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
2823 else if (strnstr(w->name, internal2_text, 30))
2824 snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
2825 else if (strnstr(w->name, internal3_text, 30))
2826 snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
2827
Joonwoo Parkccccba72013-04-26 11:19:46 -07002828 if (taiko->mbhc_started && micb_ctl_reg == TAIKO_A_MICB_2_CTL) {
2829 if (++taiko->micb_2_users == 1) {
2830 if (taiko->resmgr.pdata->
2831 micbias.bias2_is_headset_only)
2832 wcd9xxx_resmgr_add_cond_update_bits(
2833 &taiko->resmgr,
2834 WCD9XXX_COND_HPH_MIC,
2835 micb_ctl_reg, w->shift,
2836 false);
2837 else
2838 snd_soc_update_bits(codec, micb_ctl_reg,
2839 1 << w->shift,
2840 1 << w->shift);
2841 }
2842 pr_debug("%s: micb_2_users %d\n", __func__,
2843 taiko->micb_2_users);
2844 } else {
Joonwoo Park3699ca32013-02-08 12:06:15 -08002845 snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
2846 1 << w->shift);
Joonwoo Parkccccba72013-04-26 11:19:46 -07002847 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002848 break;
2849 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002850 usleep_range(20000, 20000);
Joonwoo Parka8890262012-10-15 12:04:27 -07002851 /* Let MBHC module know so micbias is on */
2852 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002853 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07002854 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parkccccba72013-04-26 11:19:46 -07002855 if (taiko->mbhc_started && micb_ctl_reg == TAIKO_A_MICB_2_CTL) {
2856 if (--taiko->micb_2_users == 0) {
2857 if (taiko->resmgr.pdata->
2858 micbias.bias2_is_headset_only)
2859 wcd9xxx_resmgr_rm_cond_update_bits(
2860 &taiko->resmgr,
2861 WCD9XXX_COND_HPH_MIC,
2862 micb_ctl_reg, 7, false);
2863 else
2864 snd_soc_update_bits(codec, micb_ctl_reg,
2865 1 << w->shift, 0);
2866 }
2867 pr_debug("%s: micb_2_users %d\n", __func__,
2868 taiko->micb_2_users);
2869 WARN(taiko->micb_2_users < 0,
2870 "Unexpected micbias users %d\n",
2871 taiko->micb_2_users);
2872 } else {
Joonwoo Park3699ca32013-02-08 12:06:15 -08002873 snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
2874 0);
Joonwoo Parkccccba72013-04-26 11:19:46 -07002875 }
Joonwoo Park3699ca32013-02-08 12:06:15 -08002876
Joonwoo Parka8890262012-10-15 12:04:27 -07002877 /* Let MBHC module know so micbias switch to be off */
2878 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
Kiran Kandic3b24402012-06-11 00:05:59 -07002879
2880 if (strnstr(w->name, internal1_text, 30))
2881 snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
2882 else if (strnstr(w->name, internal2_text, 30))
2883 snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
2884 else if (strnstr(w->name, internal3_text, 30))
2885 snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
2886
Joonwoo Parka8890262012-10-15 12:04:27 -07002887 /* Put cfilt */
2888 wcd9xxx_resmgr_cfilt_put(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002889 break;
2890 }
2891
2892 return 0;
2893}
2894
Joonwoo Parkccccba72013-04-26 11:19:46 -07002895/* called under codec_resource_lock acquisition */
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07002896static int taiko_enable_mbhc_micbias(struct snd_soc_codec *codec, bool enable,
2897 enum wcd9xxx_micbias_num micb_num)
Joonwoo Parkccccba72013-04-26 11:19:46 -07002898{
2899 int rc;
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07002900 const char *micbias;
2901
2902 if (micb_num != MBHC_MICBIAS3 &&
2903 micb_num != MBHC_MICBIAS2)
2904 return -EINVAL;
2905
2906 micbias = (micb_num == MBHC_MICBIAS3) ?
2907 DAPM_MICBIAS3_EXTERNAL_STANDALONE :
2908 DAPM_MICBIAS2_EXTERNAL_STANDALONE;
Joonwoo Parkccccba72013-04-26 11:19:46 -07002909
2910 if (enable)
2911 rc = snd_soc_dapm_force_enable_pin(&codec->dapm,
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07002912 micbias);
Joonwoo Parkccccba72013-04-26 11:19:46 -07002913 else
2914 rc = snd_soc_dapm_disable_pin(&codec->dapm,
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07002915 micbias);
Joonwoo Parkccccba72013-04-26 11:19:46 -07002916 if (!rc)
2917 snd_soc_dapm_sync(&codec->dapm);
2918 pr_debug("%s: leave ret %d\n", __func__, rc);
2919 return rc;
2920}
Kiran Kandic3b24402012-06-11 00:05:59 -07002921
2922static void tx_hpf_corner_freq_callback(struct work_struct *work)
2923{
2924 struct delayed_work *hpf_delayed_work;
2925 struct hpf_work *hpf_work;
2926 struct taiko_priv *taiko;
2927 struct snd_soc_codec *codec;
2928 u16 tx_mux_ctl_reg;
2929 u8 hpf_cut_of_freq;
2930
2931 hpf_delayed_work = to_delayed_work(work);
2932 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
2933 taiko = hpf_work->taiko;
2934 codec = hpf_work->taiko->codec;
2935 hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
2936
2937 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL +
2938 (hpf_work->decimator - 1) * 8;
2939
2940 pr_debug("%s(): decimator %u hpf_cut_of_freq 0x%x\n", __func__,
2941 hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
2942
2943 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
2944}
2945
2946#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30
2947#define CF_MIN_3DB_4HZ 0x0
2948#define CF_MIN_3DB_75HZ 0x1
2949#define CF_MIN_3DB_150HZ 0x2
2950
2951static int taiko_codec_enable_dec(struct snd_soc_dapm_widget *w,
2952 struct snd_kcontrol *kcontrol, int event)
2953{
2954 struct snd_soc_codec *codec = w->codec;
2955 unsigned int decimator;
2956 char *dec_name = NULL;
2957 char *widget_name = NULL;
2958 char *temp;
2959 int ret = 0;
2960 u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
2961 u8 dec_hpf_cut_of_freq;
2962 int offset;
2963
2964
2965 pr_debug("%s %d\n", __func__, event);
2966
2967 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
2968 if (!widget_name)
2969 return -ENOMEM;
2970 temp = widget_name;
2971
2972 dec_name = strsep(&widget_name, " ");
2973 widget_name = temp;
2974 if (!dec_name) {
2975 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
2976 ret = -EINVAL;
2977 goto out;
2978 }
2979
2980 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
2981 if (ret < 0) {
2982 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
2983 ret = -EINVAL;
2984 goto out;
2985 }
2986
2987 pr_debug("%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
2988 w->name, dec_name, decimator);
2989
2990 if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
2991 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B1_CTL;
2992 offset = 0;
2993 } else if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL) {
2994 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B2_CTL;
2995 offset = 8;
2996 } else {
2997 pr_err("%s: Error, incorrect dec\n", __func__);
2998 return -EINVAL;
2999 }
3000
3001 tx_vol_ctl_reg = TAIKO_A_CDC_TX1_VOL_CTL_CFG + 8 * (decimator - 1);
3002 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
3003
3004 switch (event) {
3005 case SND_SOC_DAPM_PRE_PMU:
3006
3007 /* Enableable TX digital mute */
3008 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
3009
3010 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
3011 1 << w->shift);
3012 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
3013
3014 dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
3015
3016 dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
3017
3018 tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
3019 dec_hpf_cut_of_freq;
3020
3021 if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
3022
3023 /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
3024 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
3025 CF_MIN_3DB_150HZ << 4);
3026 }
3027
3028 /* enable HPF */
3029 snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
3030
3031 break;
3032
3033 case SND_SOC_DAPM_POST_PMU:
3034
3035 /* Disable TX digital mute */
3036 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
3037
3038 if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
3039 CF_MIN_3DB_150HZ) {
3040
3041 schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
3042 msecs_to_jiffies(300));
3043 }
3044 /* apply the digital gain after the decimator is enabled*/
Damir Didjustoed406e22012-11-16 15:44:57 -08003045 if ((w->shift + offset) < ARRAY_SIZE(tx_digital_gain_reg))
Kiran Kandic3b24402012-06-11 00:05:59 -07003046 snd_soc_write(codec,
3047 tx_digital_gain_reg[w->shift + offset],
3048 snd_soc_read(codec,
3049 tx_digital_gain_reg[w->shift + offset])
3050 );
3051
3052 break;
3053
3054 case SND_SOC_DAPM_PRE_PMD:
3055
3056 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
3057 cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
3058 break;
3059
3060 case SND_SOC_DAPM_POST_PMD:
3061
3062 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
3063 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
3064 (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
3065
3066 break;
3067 }
3068out:
3069 kfree(widget_name);
3070 return ret;
3071}
3072
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003073static int taiko_codec_enable_vdd_spkr(struct snd_soc_dapm_widget *w,
3074 struct snd_kcontrol *kcontrol, int event)
3075{
3076 int ret = 0;
3077 struct snd_soc_codec *codec = w->codec;
3078 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Joonwoo Park448a8fc2013-04-10 15:25:58 -07003079 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003080
3081 pr_debug("%s: %d %s\n", __func__, event, w->name);
Joonwoo Park448a8fc2013-04-10 15:25:58 -07003082
3083 WARN_ONCE(!priv->spkdrv_reg, "SPKDRV supply %s isn't defined\n",
3084 WCD9XXX_VDD_SPKDRV_NAME);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003085 switch (event) {
3086 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Park448a8fc2013-04-10 15:25:58 -07003087 if (priv->spkdrv_reg) {
3088 ret = regulator_enable(priv->spkdrv_reg);
3089 if (ret)
3090 pr_err("%s: Failed to enable spkdrv_reg %s\n",
3091 __func__, WCD9XXX_VDD_SPKDRV_NAME);
3092 }
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003093 if (spkr_drv_wrnd > 0) {
3094 WARN_ON(!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
3095 0x80));
3096 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
3097 0x00);
3098 }
3099 if (TAIKO_IS_1_0(core->version))
3100 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
3101 0x24, 0x00);
3102 break;
3103 case SND_SOC_DAPM_POST_PMD:
3104 if (TAIKO_IS_1_0(core->version))
3105 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
3106 0x24, 0x24);
3107 if (spkr_drv_wrnd > 0) {
3108 WARN_ON(!!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
3109 0x80));
3110 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
3111 0x80);
3112 }
Joonwoo Park448a8fc2013-04-10 15:25:58 -07003113 if (priv->spkdrv_reg) {
3114 ret = regulator_disable(priv->spkdrv_reg);
3115 if (ret)
3116 pr_err("%s: Failed to disable spkdrv_reg %s\n",
3117 __func__, WCD9XXX_VDD_SPKDRV_NAME);
3118 }
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003119 break;
3120 }
3121
3122 return ret;
3123}
3124
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003125static int taiko_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07003126 struct snd_kcontrol *kcontrol, int event)
3127{
3128 struct snd_soc_codec *codec = w->codec;
3129
3130 pr_debug("%s %d %s\n", __func__, event, w->name);
3131
3132 switch (event) {
3133 case SND_SOC_DAPM_PRE_PMU:
3134 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
3135 1 << w->shift, 1 << w->shift);
3136 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
3137 1 << w->shift, 0x0);
3138 break;
3139 case SND_SOC_DAPM_POST_PMU:
3140 /* apply the digital gain after the interpolator is enabled*/
3141 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
3142 snd_soc_write(codec,
3143 rx_digital_gain_reg[w->shift],
3144 snd_soc_read(codec,
3145 rx_digital_gain_reg[w->shift])
3146 );
3147 break;
3148 }
3149 return 0;
3150}
3151
Joonwoo Parkccccba72013-04-26 11:19:46 -07003152/* called under codec_resource_lock acquisition */
3153static int __taiko_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
3154 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07003155{
Joonwoo Parkccccba72013-04-26 11:19:46 -07003156 struct snd_soc_codec *codec = w->codec;
3157 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
3158
3159 pr_debug("%s: enter\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07003160 switch (event) {
Joonwoo Parkccccba72013-04-26 11:19:46 -07003161 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Park533b3682013-06-13 11:41:21 -07003162 /*
3163 * ldo_h_users is protected by codec->mutex, don't need
3164 * additional mutex
3165 */
Joonwoo Parkccccba72013-04-26 11:19:46 -07003166 if (++priv->ldo_h_users == 1) {
Joonwoo Park533b3682013-06-13 11:41:21 -07003167 WCD9XXX_BG_CLK_LOCK(&priv->resmgr);
Joonwoo Parkccccba72013-04-26 11:19:46 -07003168 wcd9xxx_resmgr_get_bandgap(&priv->resmgr,
3169 WCD9XXX_BANDGAP_AUDIO_MODE);
3170 wcd9xxx_resmgr_get_clk_block(&priv->resmgr,
3171 WCD9XXX_CLK_RCO);
3172 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 1 << 7,
3173 1 << 7);
3174 wcd9xxx_resmgr_put_clk_block(&priv->resmgr,
3175 WCD9XXX_CLK_RCO);
Joonwoo Park533b3682013-06-13 11:41:21 -07003176 WCD9XXX_BG_CLK_UNLOCK(&priv->resmgr);
Joonwoo Parkccccba72013-04-26 11:19:46 -07003177 pr_debug("%s: ldo_h_users %d\n", __func__,
3178 priv->ldo_h_users);
3179 /* LDO enable requires 1ms to settle down */
3180 usleep_range(1000, 1000);
3181 }
3182 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07003183 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parkccccba72013-04-26 11:19:46 -07003184 if (--priv->ldo_h_users == 0) {
Joonwoo Park533b3682013-06-13 11:41:21 -07003185 WCD9XXX_BG_CLK_LOCK(&priv->resmgr);
Joonwoo Parkccccba72013-04-26 11:19:46 -07003186 wcd9xxx_resmgr_get_clk_block(&priv->resmgr,
3187 WCD9XXX_CLK_RCO);
3188 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 1 << 7,
3189 0);
3190 wcd9xxx_resmgr_put_clk_block(&priv->resmgr,
3191 WCD9XXX_CLK_RCO);
3192 wcd9xxx_resmgr_put_bandgap(&priv->resmgr,
3193 WCD9XXX_BANDGAP_AUDIO_MODE);
Joonwoo Park533b3682013-06-13 11:41:21 -07003194 WCD9XXX_BG_CLK_UNLOCK(&priv->resmgr);
Joonwoo Parkccccba72013-04-26 11:19:46 -07003195 pr_debug("%s: ldo_h_users %d\n", __func__,
3196 priv->ldo_h_users);
3197 }
3198 WARN(priv->ldo_h_users < 0, "Unexpected ldo_h users %d\n",
3199 priv->ldo_h_users);
Kiran Kandic3b24402012-06-11 00:05:59 -07003200 break;
3201 }
Joonwoo Parkccccba72013-04-26 11:19:46 -07003202 pr_debug("%s: leave\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07003203 return 0;
3204}
3205
Joonwoo Parkccccba72013-04-26 11:19:46 -07003206static int taiko_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
3207 struct snd_kcontrol *kcontrol, int event)
3208{
3209 int rc;
Joonwoo Parkccccba72013-04-26 11:19:46 -07003210 rc = __taiko_codec_enable_ldo_h(w, kcontrol, event);
Joonwoo Parkccccba72013-04-26 11:19:46 -07003211 return rc;
3212}
3213
Kiran Kandic3b24402012-06-11 00:05:59 -07003214static int taiko_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
3215 struct snd_kcontrol *kcontrol, int event)
3216{
3217 struct snd_soc_codec *codec = w->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07003218 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003219
3220 pr_debug("%s %d\n", __func__, event);
3221
3222 switch (event) {
3223 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07003224 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
Kiran Kandic3b24402012-06-11 00:05:59 -07003225 break;
3226 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07003227 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
Kiran Kandic3b24402012-06-11 00:05:59 -07003228 break;
3229 }
3230 return 0;
3231}
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003232
3233static int taiko_hphl_dac_event(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07003234 struct snd_kcontrol *kcontrol, int event)
3235{
3236 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003237 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Santosh Mardi93a69192013-07-03 23:37:29 +05303238 uint32_t impedl, impedr;
3239 int ret = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07003240
3241 pr_debug("%s %s %d\n", __func__, w->name, event);
3242
3243 switch (event) {
3244 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003245 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
3246 0x02, 0x02);
3247 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
3248 WCD9XXX_CLSH_STATE_HPHL,
3249 WCD9XXX_CLSH_REQ_ENABLE,
3250 WCD9XXX_CLSH_EVENT_PRE_DAC);
Santosh Mardi93a69192013-07-03 23:37:29 +05303251 ret = wcd9xxx_mbhc_get_impedance(&taiko_p->mbhc,
3252 &impedl, &impedr);
3253 if (!ret)
3254 wcd9xxx_clsh_imped_config(codec, impedl);
3255 else
3256 dev_err(codec->dev, "Failed to get mbhc impedance %d\n",
3257 ret);
Kiran Kandic3b24402012-06-11 00:05:59 -07003258 break;
3259 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003260 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
3261 0x02, 0x00);
Sudheer Papothia26a6672014-03-22 00:03:34 +05303262 break;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003263 }
3264 return 0;
3265}
3266
3267static int taiko_hphr_dac_event(struct snd_soc_dapm_widget *w,
3268 struct snd_kcontrol *kcontrol, int event)
3269{
3270 struct snd_soc_codec *codec = w->codec;
3271 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
3272
3273 pr_debug("%s %s %d\n", __func__, w->name, event);
3274
3275 switch (event) {
3276 case SND_SOC_DAPM_PRE_PMU:
3277 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
3278 0x04, 0x04);
3279 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
3280 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
3281 WCD9XXX_CLSH_STATE_HPHR,
3282 WCD9XXX_CLSH_REQ_ENABLE,
3283 WCD9XXX_CLSH_EVENT_PRE_DAC);
3284 break;
3285 case SND_SOC_DAPM_POST_PMD:
3286 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
3287 0x04, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -07003288 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
3289 break;
3290 }
3291 return 0;
3292}
3293
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003294static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
3295 struct snd_kcontrol *kcontrol, int event)
3296{
3297 struct snd_soc_codec *codec = w->codec;
3298 const char *filename;
3299 const struct firmware *fw;
3300 int i;
3301 int ret;
3302 int num_anc_slots;
Simmi Pateriyadf675e92013-04-05 01:15:54 +05303303 struct wcd9xxx_anc_header *anc_head;
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003304 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3305 u32 anc_writes_size = 0;
3306 int anc_size_remaining;
3307 u32 *anc_ptr;
3308 u16 reg;
3309 u8 mask, val, old_val;
3310
3311
3312 if (taiko->anc_func == 0)
3313 return 0;
3314
3315 switch (event) {
3316 case SND_SOC_DAPM_PRE_PMU:
3317 filename = "wcd9320/wcd9320_anc.bin";
3318
3319 ret = request_firmware(&fw, filename, codec->dev);
3320 if (ret != 0) {
3321 dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
3322 ret);
3323 return -ENODEV;
3324 }
3325
Simmi Pateriyadf675e92013-04-05 01:15:54 +05303326 if (fw->size < sizeof(struct wcd9xxx_anc_header)) {
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003327 dev_err(codec->dev, "Not enough data\n");
3328 release_firmware(fw);
3329 return -ENOMEM;
3330 }
3331
3332 /* First number is the number of register writes */
Simmi Pateriyadf675e92013-04-05 01:15:54 +05303333 anc_head = (struct wcd9xxx_anc_header *)(fw->data);
3334 anc_ptr = (u32 *)((u32)fw->data +
3335 sizeof(struct wcd9xxx_anc_header));
3336 anc_size_remaining = fw->size -
3337 sizeof(struct wcd9xxx_anc_header);
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003338 num_anc_slots = anc_head->num_anc_slots;
3339
3340 if (taiko->anc_slot >= num_anc_slots) {
3341 dev_err(codec->dev, "Invalid ANC slot selected\n");
3342 release_firmware(fw);
3343 return -EINVAL;
3344 }
3345 for (i = 0; i < num_anc_slots; i++) {
3346 if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
3347 dev_err(codec->dev, "Invalid register format\n");
3348 release_firmware(fw);
3349 return -EINVAL;
3350 }
3351 anc_writes_size = (u32)(*anc_ptr);
3352 anc_size_remaining -= sizeof(u32);
3353 anc_ptr += 1;
3354
3355 if (anc_writes_size * TAIKO_PACKED_REG_SIZE
3356 > anc_size_remaining) {
3357 dev_err(codec->dev, "Invalid register format\n");
3358 release_firmware(fw);
3359 return -ENOMEM;
3360 }
3361
3362 if (taiko->anc_slot == i)
3363 break;
3364
3365 anc_size_remaining -= (anc_writes_size *
3366 TAIKO_PACKED_REG_SIZE);
3367 anc_ptr += anc_writes_size;
3368 }
3369 if (i == num_anc_slots) {
3370 dev_err(codec->dev, "Selected ANC slot not present\n");
3371 release_firmware(fw);
3372 return -ENOMEM;
3373 }
3374 for (i = 0; i < anc_writes_size; i++) {
3375 TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
3376 mask, val);
3377 old_val = snd_soc_read(codec, reg);
3378 snd_soc_write(codec, reg, (old_val & ~mask) |
3379 (val & mask));
3380 }
3381 release_firmware(fw);
3382 break;
Damir Didjustoaf0085c2013-05-02 17:47:45 -07003383 case SND_SOC_DAPM_PRE_PMD:
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003384 msleep(40);
3385 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B1_CTL, 0x01, 0x00);
3386 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC2_B1_CTL, 0x02, 0x00);
3387 msleep(20);
3388 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0x0F);
3389 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
3390 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
3391 break;
3392 }
3393 return 0;
3394}
3395
Kiran Kandic3b24402012-06-11 00:05:59 -07003396static int taiko_hph_pa_event(struct snd_soc_dapm_widget *w,
Joonwoo Parka8890262012-10-15 12:04:27 -07003397 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07003398{
3399 struct snd_soc_codec *codec = w->codec;
3400 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07003401 enum wcd9xxx_notify_event e_pre_on, e_post_off;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003402 u8 req_clsh_state;
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07003403 u32 pa_settle_time = TAIKO_HPH_PA_SETTLE_COMP_OFF;
Joonwoo Parka8890262012-10-15 12:04:27 -07003404
Kiran Kandi4c56c592012-07-25 11:04:55 -07003405 pr_debug("%s: %s event = %d\n", __func__, w->name, event);
Joonwoo Parka8890262012-10-15 12:04:27 -07003406 if (w->shift == 5) {
Joonwoo Parka8890262012-10-15 12:04:27 -07003407 e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
3408 e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
Patrick Lai453cd742013-03-02 16:51:27 -08003409 req_clsh_state = WCD9XXX_CLSH_STATE_HPHL;
3410 } else if (w->shift == 4) {
3411 e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
3412 e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003413 req_clsh_state = WCD9XXX_CLSH_STATE_HPHR;
Joonwoo Parka8890262012-10-15 12:04:27 -07003414 } else {
3415 pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
3416 return -EINVAL;
3417 }
Kiran Kandic3b24402012-06-11 00:05:59 -07003418
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07003419 if (taiko->comp_enabled[COMPANDER_1])
3420 pa_settle_time = TAIKO_HPH_PA_SETTLE_COMP_ON;
3421
Kiran Kandic3b24402012-06-11 00:05:59 -07003422 switch (event) {
3423 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07003424 /* Let MBHC module know PA is turning on */
3425 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07003426 break;
3427
Kiran Kandi4c56c592012-07-25 11:04:55 -07003428 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07003429 usleep_range(pa_settle_time, pa_settle_time + 1000);
3430 pr_debug("%s: sleep %d us after %s PA enable\n", __func__,
3431 pa_settle_time, w->name);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003432 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
3433 req_clsh_state,
3434 WCD9XXX_CLSH_REQ_ENABLE,
3435 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandi4c56c592012-07-25 11:04:55 -07003436
Kiran Kandi4c56c592012-07-25 11:04:55 -07003437 break;
3438
Kiran Kandic3b24402012-06-11 00:05:59 -07003439 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07003440 usleep_range(pa_settle_time, pa_settle_time + 1000);
3441 pr_debug("%s: sleep %d us after %s PA disable\n", __func__,
3442 pa_settle_time, w->name);
3443
Joonwoo Parka8890262012-10-15 12:04:27 -07003444 /* Let MBHC module know PA turned off */
3445 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
3446
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003447 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
3448 req_clsh_state,
3449 WCD9XXX_CLSH_REQ_DISABLE,
3450 WCD9XXX_CLSH_EVENT_POST_PA);
3451
Kiran Kandic3b24402012-06-11 00:05:59 -07003452 break;
3453 }
3454 return 0;
3455}
3456
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003457static int taiko_codec_enable_anc_hph(struct snd_soc_dapm_widget *w,
3458 struct snd_kcontrol *kcontrol, int event)
3459{
3460 struct snd_soc_codec *codec = w->codec;
3461 int ret = 0;
3462
3463 switch (event) {
3464 case SND_SOC_DAPM_PRE_PMU:
3465 ret = taiko_hph_pa_event(w, kcontrol, event);
3466 if (w->shift == 4) {
3467 ret |= taiko_codec_enable_anc(w, kcontrol, event);
3468 msleep(50);
3469 }
3470 break;
3471 case SND_SOC_DAPM_POST_PMU:
3472 if (w->shift == 4) {
3473 snd_soc_update_bits(codec,
3474 TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x30);
3475 msleep(30);
3476 }
3477 ret = taiko_hph_pa_event(w, kcontrol, event);
3478 break;
3479 case SND_SOC_DAPM_PRE_PMD:
3480 if (w->shift == 5) {
3481 snd_soc_update_bits(codec,
3482 TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x00);
3483 msleep(40);
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003484 snd_soc_update_bits(codec,
3485 TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
3486 ret |= taiko_codec_enable_anc(w, kcontrol, event);
3487 }
Damir Didjusto340f6f32013-06-28 17:24:13 -07003488 break;
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003489 case SND_SOC_DAPM_POST_PMD:
3490 ret = taiko_hph_pa_event(w, kcontrol, event);
3491 break;
3492 }
3493 return ret;
3494}
3495
Kiran Kandic3b24402012-06-11 00:05:59 -07003496static const struct snd_soc_dapm_widget taiko_dapm_i2s_widgets[] = {
3497 SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", TAIKO_A_CDC_CLK_RX_I2S_CTL,
3498 4, 0, NULL, 0),
3499 SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", TAIKO_A_CDC_CLK_TX_I2S_CTL, 4,
3500 0, NULL, 0),
3501};
3502
3503static int taiko_lineout_dac_event(struct snd_soc_dapm_widget *w,
3504 struct snd_kcontrol *kcontrol, int event)
3505{
3506 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003507 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003508
3509 pr_debug("%s %s %d\n", __func__, w->name, event);
3510
3511 switch (event) {
3512 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003513 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
3514 WCD9XXX_CLSH_STATE_LO,
3515 WCD9XXX_CLSH_REQ_ENABLE,
3516 WCD9XXX_CLSH_EVENT_PRE_DAC);
Kiran Kandic3b24402012-06-11 00:05:59 -07003517 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
3518 break;
3519
3520 case SND_SOC_DAPM_POST_PMD:
3521 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
3522 break;
3523 }
3524 return 0;
3525}
3526
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003527static int taiko_spk_dac_event(struct snd_soc_dapm_widget *w,
3528 struct snd_kcontrol *kcontrol, int event)
3529{
3530 pr_debug("%s %s %d\n", __func__, w->name, event);
3531 return 0;
3532}
3533
Kiran Kandic3b24402012-06-11 00:05:59 -07003534static const struct snd_soc_dapm_route audio_i2s_map[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07003535 {"SLIM RX1", NULL, "RX_I2S_CLK"},
3536 {"SLIM RX2", NULL, "RX_I2S_CLK"},
3537 {"SLIM RX3", NULL, "RX_I2S_CLK"},
3538 {"SLIM RX4", NULL, "RX_I2S_CLK"},
3539
Venkat Sudhira41630a2012-10-27 00:57:31 -07003540 {"SLIM TX7 MUX", NULL, "TX_I2S_CLK"},
3541 {"SLIM TX8 MUX", NULL, "TX_I2S_CLK"},
3542 {"SLIM TX9 MUX", NULL, "TX_I2S_CLK"},
3543 {"SLIM TX10 MUX", NULL, "TX_I2S_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003544};
3545
Joonwoo Park559a5bf2013-02-15 14:46:36 -08003546static const struct snd_soc_dapm_route audio_i2s_map_1_0[] = {
3547 {"RX_I2S_CLK", NULL, "CDC_CONN"},
3548};
3549
3550static const struct snd_soc_dapm_route audio_i2s_map_2_0[] = {
3551 {"RX_I2S_CLK", NULL, "CDC_I2S_RX_CONN"},
3552};
3553
Kiran Kandic3b24402012-06-11 00:05:59 -07003554static const struct snd_soc_dapm_route audio_map[] = {
3555 /* SLIMBUS Connections */
Kuirong Wang906ac472012-07-09 12:54:44 -07003556 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
3557 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
3558 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003559 {"AIF4 VI", NULL, "SPK_OUT"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003560
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003561 /* MAD */
3562 {"AIF4 MAD", NULL, "CDC_CONN"},
Joonwoo Park9ead0e92013-03-18 11:33:33 -07003563 {"MADONOFF", "Switch", "MADINPUT"},
3564 {"AIF4 MAD", NULL, "MADONOFF"},
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003565
Kuirong Wang906ac472012-07-09 12:54:44 -07003566 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
3567 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3568 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3569 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3570 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3571 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3572 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3573 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3574 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3575 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3576 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3577 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
3578 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3579 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3580 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3581 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3582 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3583 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3584 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3585 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3586 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3587 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3588 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
3589 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3590 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3591 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3592 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3593 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3594 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3595 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3596 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3597 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3598 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3599
Kiran Kandic3b24402012-06-11 00:05:59 -07003600 {"SLIM TX1 MUX", "DEC1", "DEC1 MUX"},
3601
Kiran Kandic3b24402012-06-11 00:05:59 -07003602 {"SLIM TX2 MUX", "DEC2", "DEC2 MUX"},
3603
Kiran Kandic3b24402012-06-11 00:05:59 -07003604 {"SLIM TX3 MUX", "DEC3", "DEC3 MUX"},
3605 {"SLIM TX3 MUX", "RMIX1", "RX1 MIX1"},
3606 {"SLIM TX3 MUX", "RMIX2", "RX2 MIX1"},
3607 {"SLIM TX3 MUX", "RMIX3", "RX3 MIX1"},
3608 {"SLIM TX3 MUX", "RMIX4", "RX4 MIX1"},
3609 {"SLIM TX3 MUX", "RMIX5", "RX5 MIX1"},
3610 {"SLIM TX3 MUX", "RMIX6", "RX6 MIX1"},
3611 {"SLIM TX3 MUX", "RMIX7", "RX7 MIX1"},
3612
Kiran Kandic3b24402012-06-11 00:05:59 -07003613 {"SLIM TX4 MUX", "DEC4", "DEC4 MUX"},
3614
Kiran Kandic3b24402012-06-11 00:05:59 -07003615 {"SLIM TX5 MUX", "DEC5", "DEC5 MUX"},
3616 {"SLIM TX5 MUX", "RMIX1", "RX1 MIX1"},
3617 {"SLIM TX5 MUX", "RMIX2", "RX2 MIX1"},
3618 {"SLIM TX5 MUX", "RMIX3", "RX3 MIX1"},
3619 {"SLIM TX5 MUX", "RMIX4", "RX4 MIX1"},
3620 {"SLIM TX5 MUX", "RMIX5", "RX5 MIX1"},
3621 {"SLIM TX5 MUX", "RMIX6", "RX6 MIX1"},
3622 {"SLIM TX5 MUX", "RMIX7", "RX7 MIX1"},
3623
Kiran Kandic3b24402012-06-11 00:05:59 -07003624 {"SLIM TX6 MUX", "DEC6", "DEC6 MUX"},
3625
Kiran Kandic3b24402012-06-11 00:05:59 -07003626 {"SLIM TX7 MUX", "DEC1", "DEC1 MUX"},
3627 {"SLIM TX7 MUX", "DEC2", "DEC2 MUX"},
3628 {"SLIM TX7 MUX", "DEC3", "DEC3 MUX"},
3629 {"SLIM TX7 MUX", "DEC4", "DEC4 MUX"},
3630 {"SLIM TX7 MUX", "DEC5", "DEC5 MUX"},
3631 {"SLIM TX7 MUX", "DEC6", "DEC6 MUX"},
3632 {"SLIM TX7 MUX", "DEC7", "DEC7 MUX"},
3633 {"SLIM TX7 MUX", "DEC8", "DEC8 MUX"},
3634 {"SLIM TX7 MUX", "DEC9", "DEC9 MUX"},
3635 {"SLIM TX7 MUX", "DEC10", "DEC10 MUX"},
3636 {"SLIM TX7 MUX", "RMIX1", "RX1 MIX1"},
3637 {"SLIM TX7 MUX", "RMIX2", "RX2 MIX1"},
3638 {"SLIM TX7 MUX", "RMIX3", "RX3 MIX1"},
3639 {"SLIM TX7 MUX", "RMIX4", "RX4 MIX1"},
3640 {"SLIM TX7 MUX", "RMIX5", "RX5 MIX1"},
3641 {"SLIM TX7 MUX", "RMIX6", "RX6 MIX1"},
3642 {"SLIM TX7 MUX", "RMIX7", "RX7 MIX1"},
3643
Kiran Kandic3b24402012-06-11 00:05:59 -07003644 {"SLIM TX8 MUX", "DEC1", "DEC1 MUX"},
3645 {"SLIM TX8 MUX", "DEC2", "DEC2 MUX"},
3646 {"SLIM TX8 MUX", "DEC3", "DEC3 MUX"},
3647 {"SLIM TX8 MUX", "DEC4", "DEC4 MUX"},
3648 {"SLIM TX8 MUX", "DEC5", "DEC5 MUX"},
3649 {"SLIM TX8 MUX", "DEC6", "DEC6 MUX"},
3650 {"SLIM TX8 MUX", "DEC7", "DEC7 MUX"},
3651 {"SLIM TX8 MUX", "DEC8", "DEC8 MUX"},
3652 {"SLIM TX8 MUX", "DEC9", "DEC9 MUX"},
3653 {"SLIM TX8 MUX", "DEC10", "DEC10 MUX"},
3654
Kiran Kandic3b24402012-06-11 00:05:59 -07003655 {"SLIM TX9 MUX", "DEC1", "DEC1 MUX"},
3656 {"SLIM TX9 MUX", "DEC2", "DEC2 MUX"},
3657 {"SLIM TX9 MUX", "DEC3", "DEC3 MUX"},
3658 {"SLIM TX9 MUX", "DEC4", "DEC4 MUX"},
3659 {"SLIM TX9 MUX", "DEC5", "DEC5 MUX"},
3660 {"SLIM TX9 MUX", "DEC6", "DEC6 MUX"},
3661 {"SLIM TX9 MUX", "DEC7", "DEC7 MUX"},
3662 {"SLIM TX9 MUX", "DEC8", "DEC8 MUX"},
3663 {"SLIM TX9 MUX", "DEC9", "DEC9 MUX"},
3664 {"SLIM TX9 MUX", "DEC10", "DEC10 MUX"},
3665
Kiran Kandic3b24402012-06-11 00:05:59 -07003666 {"SLIM TX10 MUX", "DEC1", "DEC1 MUX"},
3667 {"SLIM TX10 MUX", "DEC2", "DEC2 MUX"},
3668 {"SLIM TX10 MUX", "DEC3", "DEC3 MUX"},
3669 {"SLIM TX10 MUX", "DEC4", "DEC4 MUX"},
3670 {"SLIM TX10 MUX", "DEC5", "DEC5 MUX"},
3671 {"SLIM TX10 MUX", "DEC6", "DEC6 MUX"},
3672 {"SLIM TX10 MUX", "DEC7", "DEC7 MUX"},
3673 {"SLIM TX10 MUX", "DEC8", "DEC8 MUX"},
3674 {"SLIM TX10 MUX", "DEC9", "DEC9 MUX"},
3675 {"SLIM TX10 MUX", "DEC10", "DEC10 MUX"},
3676
3677 /* Earpiece (RX MIX1) */
3678 {"EAR", NULL, "EAR PA"},
3679 {"EAR PA", NULL, "EAR_PA_MIXER"},
3680 {"EAR_PA_MIXER", NULL, "DAC1"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003681 {"DAC1", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003682
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003683 {"ANC EAR", NULL, "ANC EAR PA"},
3684 {"ANC EAR PA", NULL, "EAR_PA_MIXER"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003685 {"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
3686 {"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003687
3688 /* Headset (RX MIX1 and RX MIX2) */
3689 {"HEADPHONE", NULL, "HPHL"},
3690 {"HEADPHONE", NULL, "HPHR"},
3691
3692 {"HPHL", NULL, "HPHL_PA_MIXER"},
3693 {"HPHL_PA_MIXER", NULL, "HPHL DAC"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003694 {"HPHL DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003695
3696 {"HPHR", NULL, "HPHR_PA_MIXER"},
3697 {"HPHR_PA_MIXER", NULL, "HPHR DAC"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003698 {"HPHR DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003699
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003700 {"ANC HEADPHONE", NULL, "ANC HPHL"},
3701 {"ANC HEADPHONE", NULL, "ANC HPHR"},
3702
3703 {"ANC HPHL", NULL, "HPHL_PA_MIXER"},
3704 {"ANC HPHR", NULL, "HPHR_PA_MIXER"},
3705
Kiran Kandic3b24402012-06-11 00:05:59 -07003706 {"ANC1 MUX", "ADC1", "ADC1"},
3707 {"ANC1 MUX", "ADC2", "ADC2"},
3708 {"ANC1 MUX", "ADC3", "ADC3"},
3709 {"ANC1 MUX", "ADC4", "ADC4"},
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003710 {"ANC1 MUX", "DMIC1", "DMIC1"},
3711 {"ANC1 MUX", "DMIC2", "DMIC2"},
3712 {"ANC1 MUX", "DMIC3", "DMIC3"},
3713 {"ANC1 MUX", "DMIC4", "DMIC4"},
3714 {"ANC1 MUX", "DMIC5", "DMIC5"},
3715 {"ANC1 MUX", "DMIC6", "DMIC6"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003716 {"ANC2 MUX", "ADC1", "ADC1"},
3717 {"ANC2 MUX", "ADC2", "ADC2"},
3718 {"ANC2 MUX", "ADC3", "ADC3"},
3719 {"ANC2 MUX", "ADC4", "ADC4"},
3720
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003721 {"ANC HPHR", NULL, "CDC_CONN"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003722
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003723 {"DAC1", "Switch", "CLASS_H_DSM MUX"},
3724 {"HPHL DAC", "Switch", "CLASS_H_DSM MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003725 {"HPHR DAC", NULL, "RX2 CHAIN"},
3726
3727 {"LINEOUT1", NULL, "LINEOUT1 PA"},
3728 {"LINEOUT2", NULL, "LINEOUT2 PA"},
3729 {"LINEOUT3", NULL, "LINEOUT3 PA"},
3730 {"LINEOUT4", NULL, "LINEOUT4 PA"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003731 {"SPK_OUT", NULL, "SPK PA"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003732
3733 {"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
3734 {"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003735
Kiran Kandic3b24402012-06-11 00:05:59 -07003736 {"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
3737 {"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003738
Kiran Kandic3b24402012-06-11 00:05:59 -07003739 {"LINEOUT3 PA", NULL, "LINEOUT3_PA_MIXER"},
3740 {"LINEOUT3_PA_MIXER", NULL, "LINEOUT3 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003741
Kiran Kandic3b24402012-06-11 00:05:59 -07003742 {"LINEOUT4 PA", NULL, "LINEOUT4_PA_MIXER"},
3743 {"LINEOUT4_PA_MIXER", NULL, "LINEOUT4 DAC"},
3744
3745 {"LINEOUT1 DAC", NULL, "RX3 MIX1"},
3746
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02003747 {"RDAC5 MUX", "DEM3_INV", "RX3 MIX1"},
3748 {"RDAC5 MUX", "DEM4", "RX4 MIX1"},
3749
3750 {"LINEOUT3 DAC", NULL, "RDAC5 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003751
3752 {"LINEOUT2 DAC", NULL, "RX5 MIX1"},
3753
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02003754 {"RDAC7 MUX", "DEM5_INV", "RX5 MIX1"},
3755 {"RDAC7 MUX", "DEM6", "RX6 MIX1"},
3756
3757 {"LINEOUT4 DAC", NULL, "RDAC7 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003758
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003759 {"SPK PA", NULL, "SPK DAC"},
Kiran Kandid2b46332012-10-05 12:04:00 -07003760 {"SPK DAC", NULL, "RX7 MIX2"},
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003761 {"SPK DAC", NULL, "VDD_SPKDRV"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003762
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003763 {"CLASS_H_DSM MUX", "DSM_HPHL_RX1", "RX1 CHAIN"},
3764
Sudheer Papothia26a6672014-03-22 00:03:34 +05303765 {"RX1 INTERP", NULL, "RX1 MIX2"},
3766 {"RX1 CHAIN", NULL, "RX1 INTERP"},
3767 {"RX2 INTERP", NULL, "RX2 MIX2"},
3768 {"RX2 CHAIN", NULL, "RX2 INTERP"},
3769
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003770 {"RX1 MIX2", NULL, "ANC1 MUX"},
3771 {"RX2 MIX2", NULL, "ANC2 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003772
Kiran Kandic3b24402012-06-11 00:05:59 -07003773 {"LINEOUT1 DAC", NULL, "RX_BIAS"},
3774 {"LINEOUT2 DAC", NULL, "RX_BIAS"},
3775 {"LINEOUT3 DAC", NULL, "RX_BIAS"},
3776 {"LINEOUT4 DAC", NULL, "RX_BIAS"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003777 {"SPK DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003778
Joonwoo Parkc7731432012-10-17 12:41:44 -07003779 {"RX7 MIX1", NULL, "COMP0_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003780 {"RX1 MIX1", NULL, "COMP1_CLK"},
3781 {"RX2 MIX1", NULL, "COMP1_CLK"},
3782 {"RX3 MIX1", NULL, "COMP2_CLK"},
3783 {"RX5 MIX1", NULL, "COMP2_CLK"},
3784
Kiran Kandic3b24402012-06-11 00:05:59 -07003785 {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
3786 {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
3787 {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
3788 {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
3789 {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
3790 {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
3791 {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
3792 {"RX4 MIX1", NULL, "RX4 MIX1 INP1"},
3793 {"RX4 MIX1", NULL, "RX4 MIX1 INP2"},
3794 {"RX5 MIX1", NULL, "RX5 MIX1 INP1"},
3795 {"RX5 MIX1", NULL, "RX5 MIX1 INP2"},
3796 {"RX6 MIX1", NULL, "RX6 MIX1 INP1"},
3797 {"RX6 MIX1", NULL, "RX6 MIX1 INP2"},
3798 {"RX7 MIX1", NULL, "RX7 MIX1 INP1"},
3799 {"RX7 MIX1", NULL, "RX7 MIX1 INP2"},
3800 {"RX1 MIX2", NULL, "RX1 MIX1"},
3801 {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
3802 {"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
3803 {"RX2 MIX2", NULL, "RX2 MIX1"},
3804 {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
3805 {"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
3806 {"RX7 MIX2", NULL, "RX7 MIX1"},
3807 {"RX7 MIX2", NULL, "RX7 MIX2 INP1"},
3808 {"RX7 MIX2", NULL, "RX7 MIX2 INP2"},
3809
Kuirong Wang906ac472012-07-09 12:54:44 -07003810 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
3811 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
3812 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
3813 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
3814 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
3815 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
3816 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
3817 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
3818 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
3819 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
3820 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
3821 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
3822 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
3823 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
3824 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
3825 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
3826 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
3827 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
3828 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
3829 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
3830 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
3831 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
3832 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
3833 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
3834
3835 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
3836 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
3837 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
3838 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
3839 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
3840 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
3841 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
3842
Kiran Kandic3b24402012-06-11 00:05:59 -07003843 {"RX1 MIX1 INP1", "RX1", "SLIM RX1"},
3844 {"RX1 MIX1 INP1", "RX2", "SLIM RX2"},
3845 {"RX1 MIX1 INP1", "RX3", "SLIM RX3"},
3846 {"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
3847 {"RX1 MIX1 INP1", "RX5", "SLIM RX5"},
3848 {"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
3849 {"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
3850 {"RX1 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003851 {"RX1 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003852 {"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
3853 {"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
3854 {"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
3855 {"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
3856 {"RX1 MIX1 INP2", "RX5", "SLIM RX5"},
3857 {"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
3858 {"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
3859 {"RX1 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003860 {"RX1 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003861 {"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
3862 {"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
3863 {"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
3864 {"RX1 MIX1 INP3", "RX4", "SLIM RX4"},
3865 {"RX1 MIX1 INP3", "RX5", "SLIM RX5"},
3866 {"RX1 MIX1 INP3", "RX6", "SLIM RX6"},
3867 {"RX1 MIX1 INP3", "RX7", "SLIM RX7"},
3868 {"RX2 MIX1 INP1", "RX1", "SLIM RX1"},
3869 {"RX2 MIX1 INP1", "RX2", "SLIM RX2"},
3870 {"RX2 MIX1 INP1", "RX3", "SLIM RX3"},
3871 {"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
3872 {"RX2 MIX1 INP1", "RX5", "SLIM RX5"},
3873 {"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
3874 {"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
3875 {"RX2 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003876 {"RX2 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003877 {"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
3878 {"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
3879 {"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
3880 {"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
3881 {"RX2 MIX1 INP2", "RX5", "SLIM RX5"},
3882 {"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
3883 {"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
3884 {"RX2 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003885 {"RX2 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003886 {"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
3887 {"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
3888 {"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
3889 {"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
3890 {"RX3 MIX1 INP1", "RX5", "SLIM RX5"},
3891 {"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
3892 {"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
3893 {"RX3 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003894 {"RX3 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003895 {"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
3896 {"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
3897 {"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
3898 {"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
3899 {"RX3 MIX1 INP2", "RX5", "SLIM RX5"},
3900 {"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
3901 {"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
3902 {"RX3 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003903 {"RX3 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003904 {"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
3905 {"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
3906 {"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
3907 {"RX4 MIX1 INP1", "RX4", "SLIM RX4"},
3908 {"RX4 MIX1 INP1", "RX5", "SLIM RX5"},
3909 {"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
3910 {"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
3911 {"RX4 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003912 {"RX4 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003913 {"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
3914 {"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
3915 {"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
3916 {"RX4 MIX1 INP2", "RX5", "SLIM RX5"},
3917 {"RX4 MIX1 INP2", "RX4", "SLIM RX4"},
3918 {"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
3919 {"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
3920 {"RX4 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003921 {"RX4 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003922 {"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
3923 {"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
3924 {"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
3925 {"RX5 MIX1 INP1", "RX4", "SLIM RX4"},
3926 {"RX5 MIX1 INP1", "RX5", "SLIM RX5"},
3927 {"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
3928 {"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
3929 {"RX5 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003930 {"RX5 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003931 {"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
3932 {"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
3933 {"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
3934 {"RX5 MIX1 INP2", "RX4", "SLIM RX4"},
3935 {"RX5 MIX1 INP2", "RX5", "SLIM RX5"},
3936 {"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
3937 {"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
3938 {"RX5 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003939 {"RX5 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003940 {"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
3941 {"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
3942 {"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
3943 {"RX6 MIX1 INP1", "RX4", "SLIM RX4"},
3944 {"RX6 MIX1 INP1", "RX5", "SLIM RX5"},
3945 {"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
3946 {"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
3947 {"RX6 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003948 {"RX6 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003949 {"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
3950 {"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
3951 {"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
3952 {"RX6 MIX1 INP2", "RX4", "SLIM RX4"},
3953 {"RX6 MIX1 INP2", "RX5", "SLIM RX5"},
3954 {"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
3955 {"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
3956 {"RX6 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003957 {"RX6 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003958 {"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
3959 {"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
3960 {"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
3961 {"RX7 MIX1 INP1", "RX4", "SLIM RX4"},
3962 {"RX7 MIX1 INP1", "RX5", "SLIM RX5"},
3963 {"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
3964 {"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
3965 {"RX7 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003966 {"RX7 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003967 {"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
3968 {"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
3969 {"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
3970 {"RX7 MIX1 INP2", "RX4", "SLIM RX4"},
3971 {"RX7 MIX1 INP2", "RX5", "SLIM RX5"},
3972 {"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
3973 {"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
3974 {"RX7 MIX1 INP2", "IIR1", "IIR1"},
Kiran Kandibd85d772013-05-19 19:03:43 -07003975 {"RX7 MIX1 INP2", "IIR2", "IIR2"},
3976
3977 /* IIR1, IIR2 inputs to Second RX Mixer on RX1, RX2 and RX7 chains. */
Kiran Kandic3b24402012-06-11 00:05:59 -07003978 {"RX1 MIX2 INP1", "IIR1", "IIR1"},
3979 {"RX1 MIX2 INP2", "IIR1", "IIR1"},
3980 {"RX2 MIX2 INP1", "IIR1", "IIR1"},
3981 {"RX2 MIX2 INP2", "IIR1", "IIR1"},
3982 {"RX7 MIX2 INP1", "IIR1", "IIR1"},
3983 {"RX7 MIX2 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003984 {"RX1 MIX2 INP1", "IIR2", "IIR2"},
3985 {"RX1 MIX2 INP2", "IIR2", "IIR2"},
3986 {"RX2 MIX2 INP1", "IIR2", "IIR2"},
3987 {"RX2 MIX2 INP2", "IIR2", "IIR2"},
3988 {"RX7 MIX2 INP1", "IIR2", "IIR2"},
3989 {"RX7 MIX2 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003990
3991 /* Decimator Inputs */
3992 {"DEC1 MUX", "DMIC1", "DMIC1"},
3993 {"DEC1 MUX", "ADC6", "ADC6"},
3994 {"DEC1 MUX", NULL, "CDC_CONN"},
3995 {"DEC2 MUX", "DMIC2", "DMIC2"},
3996 {"DEC2 MUX", "ADC5", "ADC5"},
3997 {"DEC2 MUX", NULL, "CDC_CONN"},
3998 {"DEC3 MUX", "DMIC3", "DMIC3"},
3999 {"DEC3 MUX", "ADC4", "ADC4"},
4000 {"DEC3 MUX", NULL, "CDC_CONN"},
4001 {"DEC4 MUX", "DMIC4", "DMIC4"},
4002 {"DEC4 MUX", "ADC3", "ADC3"},
4003 {"DEC4 MUX", NULL, "CDC_CONN"},
4004 {"DEC5 MUX", "DMIC5", "DMIC5"},
4005 {"DEC5 MUX", "ADC2", "ADC2"},
4006 {"DEC5 MUX", NULL, "CDC_CONN"},
4007 {"DEC6 MUX", "DMIC6", "DMIC6"},
4008 {"DEC6 MUX", "ADC1", "ADC1"},
4009 {"DEC6 MUX", NULL, "CDC_CONN"},
4010 {"DEC7 MUX", "DMIC1", "DMIC1"},
4011 {"DEC7 MUX", "DMIC6", "DMIC6"},
4012 {"DEC7 MUX", "ADC1", "ADC1"},
4013 {"DEC7 MUX", "ADC6", "ADC6"},
4014 {"DEC7 MUX", NULL, "CDC_CONN"},
4015 {"DEC8 MUX", "DMIC2", "DMIC2"},
4016 {"DEC8 MUX", "DMIC5", "DMIC5"},
4017 {"DEC8 MUX", "ADC2", "ADC2"},
4018 {"DEC8 MUX", "ADC5", "ADC5"},
4019 {"DEC8 MUX", NULL, "CDC_CONN"},
4020 {"DEC9 MUX", "DMIC4", "DMIC4"},
4021 {"DEC9 MUX", "DMIC5", "DMIC5"},
4022 {"DEC9 MUX", "ADC2", "ADC2"},
4023 {"DEC9 MUX", "ADC3", "ADC3"},
4024 {"DEC9 MUX", NULL, "CDC_CONN"},
4025 {"DEC10 MUX", "DMIC3", "DMIC3"},
4026 {"DEC10 MUX", "DMIC6", "DMIC6"},
4027 {"DEC10 MUX", "ADC1", "ADC1"},
4028 {"DEC10 MUX", "ADC4", "ADC4"},
4029 {"DEC10 MUX", NULL, "CDC_CONN"},
4030
4031 /* ADC Connections */
4032 {"ADC1", NULL, "AMIC1"},
4033 {"ADC2", NULL, "AMIC2"},
4034 {"ADC3", NULL, "AMIC3"},
4035 {"ADC4", NULL, "AMIC4"},
4036 {"ADC5", NULL, "AMIC5"},
4037 {"ADC6", NULL, "AMIC6"},
4038
4039 /* AUX PGA Connections */
Kiran Kandic3b24402012-06-11 00:05:59 -07004040 {"EAR_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07004041 {"HPHL_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
4042 {"HPHR_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
4043 {"LINEOUT1_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
4044 {"LINEOUT2_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
4045 {"LINEOUT3_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
4046 {"LINEOUT4_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
Kiran Kandic3b24402012-06-11 00:05:59 -07004047 {"AUX_PGA_Left", NULL, "AMIC5"},
4048 {"AUX_PGA_Right", NULL, "AMIC6"},
4049
Kiran Kandic3b24402012-06-11 00:05:59 -07004050 {"IIR1", NULL, "IIR1 INP1 MUX"},
4051 {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
4052 {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
4053 {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
4054 {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
4055 {"IIR1 INP1 MUX", "DEC5", "DEC5 MUX"},
4056 {"IIR1 INP1 MUX", "DEC6", "DEC6 MUX"},
4057 {"IIR1 INP1 MUX", "DEC7", "DEC7 MUX"},
4058 {"IIR1 INP1 MUX", "DEC8", "DEC8 MUX"},
4059 {"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
4060 {"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
Kiran Kandibd85d772013-05-19 19:03:43 -07004061 {"IIR1 INP1 MUX", "RX1", "SLIM RX1"},
4062 {"IIR1 INP1 MUX", "RX2", "SLIM RX2"},
4063 {"IIR1 INP1 MUX", "RX3", "SLIM RX3"},
4064 {"IIR1 INP1 MUX", "RX4", "SLIM RX4"},
4065 {"IIR1 INP1 MUX", "RX5", "SLIM RX5"},
4066 {"IIR1 INP1 MUX", "RX6", "SLIM RX6"},
4067 {"IIR1 INP1 MUX", "RX7", "SLIM RX7"},
Kiran Kandic3b24402012-06-11 00:05:59 -07004068
Fred Oh456fcb52013-02-28 19:08:15 -08004069 {"IIR2", NULL, "IIR2 INP1 MUX"},
4070 {"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
4071 {"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
4072 {"IIR2 INP1 MUX", "DEC3", "DEC3 MUX"},
4073 {"IIR2 INP1 MUX", "DEC4", "DEC4 MUX"},
4074 {"IIR2 INP1 MUX", "DEC5", "DEC5 MUX"},
4075 {"IIR2 INP1 MUX", "DEC6", "DEC6 MUX"},
4076 {"IIR2 INP1 MUX", "DEC7", "DEC7 MUX"},
4077 {"IIR2 INP1 MUX", "DEC8", "DEC8 MUX"},
4078 {"IIR2 INP1 MUX", "DEC9", "DEC9 MUX"},
4079 {"IIR2 INP1 MUX", "DEC10", "DEC10 MUX"},
Kiran Kandibd85d772013-05-19 19:03:43 -07004080 {"IIR2 INP1 MUX", "RX1", "SLIM RX1"},
4081 {"IIR2 INP1 MUX", "RX2", "SLIM RX2"},
4082 {"IIR2 INP1 MUX", "RX3", "SLIM RX3"},
4083 {"IIR2 INP1 MUX", "RX4", "SLIM RX4"},
4084 {"IIR2 INP1 MUX", "RX5", "SLIM RX5"},
4085 {"IIR2 INP1 MUX", "RX6", "SLIM RX6"},
4086 {"IIR2 INP1 MUX", "RX7", "SLIM RX7"},
Fred Oh456fcb52013-02-28 19:08:15 -08004087
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05304088 {"IIR1", NULL, "IIR1 INP2 MUX"},
4089 {"IIR1 INP2 MUX", "DEC1", "DEC1 MUX"},
4090 {"IIR1 INP2 MUX", "DEC2", "DEC2 MUX"},
4091 {"IIR1 INP2 MUX", "DEC3", "DEC3 MUX"},
4092 {"IIR1 INP2 MUX", "DEC4", "DEC4 MUX"},
4093 {"IIR1 INP2 MUX", "DEC5", "DEC5 MUX"},
4094 {"IIR1 INP2 MUX", "DEC6", "DEC6 MUX"},
4095 {"IIR1 INP2 MUX", "DEC7", "DEC7 MUX"},
4096 {"IIR1 INP2 MUX", "DEC8", "DEC8 MUX"},
4097 {"IIR1 INP2 MUX", "DEC9", "DEC9 MUX"},
4098 {"IIR1 INP2 MUX", "DEC10", "DEC10 MUX"},
4099 {"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
4100 {"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
4101 {"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
4102 {"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
4103 {"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
4104 {"IIR1 INP2 MUX", "RX6", "SLIM RX6"},
4105 {"IIR1 INP2 MUX", "RX7", "SLIM RX7"},
4106
4107 {"IIR2", NULL, "IIR2 INP2 MUX"},
4108 {"IIR2 INP2 MUX", "DEC1", "DEC1 MUX"},
4109 {"IIR2 INP2 MUX", "DEC2", "DEC2 MUX"},
4110 {"IIR2 INP2 MUX", "DEC3", "DEC3 MUX"},
4111 {"IIR2 INP2 MUX", "DEC4", "DEC4 MUX"},
4112 {"IIR2 INP2 MUX", "DEC5", "DEC5 MUX"},
4113 {"IIR2 INP2 MUX", "DEC6", "DEC6 MUX"},
4114 {"IIR2 INP2 MUX", "DEC7", "DEC7 MUX"},
4115 {"IIR2 INP2 MUX", "DEC8", "DEC8 MUX"},
4116 {"IIR2 INP2 MUX", "DEC9", "DEC9 MUX"},
4117 {"IIR2 INP2 MUX", "DEC10", "DEC10 MUX"},
4118 {"IIR2 INP2 MUX", "RX1", "SLIM RX1"},
4119 {"IIR2 INP2 MUX", "RX2", "SLIM RX2"},
4120 {"IIR2 INP2 MUX", "RX3", "SLIM RX3"},
4121 {"IIR2 INP2 MUX", "RX4", "SLIM RX4"},
4122 {"IIR2 INP2 MUX", "RX5", "SLIM RX5"},
4123 {"IIR2 INP2 MUX", "RX6", "SLIM RX6"},
4124 {"IIR2 INP2 MUX", "RX7", "SLIM RX7"},
4125
4126 {"IIR1", NULL, "IIR1 INP3 MUX"},
4127 {"IIR1 INP3 MUX", "DEC1", "DEC1 MUX"},
4128 {"IIR1 INP3 MUX", "DEC2", "DEC2 MUX"},
4129 {"IIR1 INP3 MUX", "DEC3", "DEC3 MUX"},
4130 {"IIR1 INP3 MUX", "DEC4", "DEC4 MUX"},
4131 {"IIR1 INP3 MUX", "DEC5", "DEC5 MUX"},
4132 {"IIR1 INP3 MUX", "DEC6", "DEC6 MUX"},
4133 {"IIR1 INP3 MUX", "DEC7", "DEC7 MUX"},
4134 {"IIR1 INP3 MUX", "DEC8", "DEC8 MUX"},
4135 {"IIR1 INP3 MUX", "DEC9", "DEC9 MUX"},
4136 {"IIR1 INP3 MUX", "DEC10", "DEC10 MUX"},
4137 {"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
4138 {"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
4139 {"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
4140 {"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
4141 {"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
4142 {"IIR1 INP3 MUX", "RX6", "SLIM RX6"},
4143 {"IIR1 INP3 MUX", "RX7", "SLIM RX7"},
4144
4145 {"IIR2", NULL, "IIR2 INP3 MUX"},
4146 {"IIR2 INP3 MUX", "DEC1", "DEC1 MUX"},
4147 {"IIR2 INP3 MUX", "DEC2", "DEC2 MUX"},
4148 {"IIR2 INP3 MUX", "DEC3", "DEC3 MUX"},
4149 {"IIR2 INP3 MUX", "DEC4", "DEC4 MUX"},
4150 {"IIR2 INP3 MUX", "DEC5", "DEC5 MUX"},
4151 {"IIR2 INP3 MUX", "DEC6", "DEC6 MUX"},
4152 {"IIR2 INP3 MUX", "DEC7", "DEC7 MUX"},
4153 {"IIR2 INP3 MUX", "DEC8", "DEC8 MUX"},
4154 {"IIR2 INP3 MUX", "DEC9", "DEC9 MUX"},
4155 {"IIR2 INP3 MUX", "DEC10", "DEC10 MUX"},
4156 {"IIR2 INP3 MUX", "RX1", "SLIM RX1"},
4157 {"IIR2 INP3 MUX", "RX2", "SLIM RX2"},
4158 {"IIR2 INP3 MUX", "RX3", "SLIM RX3"},
4159 {"IIR2 INP3 MUX", "RX4", "SLIM RX4"},
4160 {"IIR2 INP3 MUX", "RX5", "SLIM RX5"},
4161 {"IIR2 INP3 MUX", "RX6", "SLIM RX6"},
4162 {"IIR2 INP3 MUX", "RX7", "SLIM RX7"},
4163
4164 {"IIR1", NULL, "IIR1 INP4 MUX"},
4165 {"IIR1 INP4 MUX", "DEC1", "DEC1 MUX"},
4166 {"IIR1 INP4 MUX", "DEC2", "DEC2 MUX"},
4167 {"IIR1 INP4 MUX", "DEC3", "DEC3 MUX"},
4168 {"IIR1 INP4 MUX", "DEC4", "DEC4 MUX"},
4169 {"IIR1 INP4 MUX", "DEC5", "DEC5 MUX"},
4170 {"IIR1 INP4 MUX", "DEC6", "DEC6 MUX"},
4171 {"IIR1 INP4 MUX", "DEC7", "DEC7 MUX"},
4172 {"IIR1 INP4 MUX", "DEC8", "DEC8 MUX"},
4173 {"IIR1 INP4 MUX", "DEC9", "DEC9 MUX"},
4174 {"IIR1 INP4 MUX", "DEC10", "DEC10 MUX"},
4175 {"IIR1 INP4 MUX", "RX1", "SLIM RX1"},
4176 {"IIR1 INP4 MUX", "RX2", "SLIM RX2"},
4177 {"IIR1 INP4 MUX", "RX3", "SLIM RX3"},
4178 {"IIR1 INP4 MUX", "RX4", "SLIM RX4"},
4179 {"IIR1 INP4 MUX", "RX5", "SLIM RX5"},
4180 {"IIR1 INP4 MUX", "RX6", "SLIM RX6"},
4181 {"IIR1 INP4 MUX", "RX7", "SLIM RX7"},
4182
4183 {"IIR2", NULL, "IIR2 INP4 MUX"},
4184 {"IIR2 INP4 MUX", "DEC1", "DEC1 MUX"},
4185 {"IIR2 INP4 MUX", "DEC2", "DEC2 MUX"},
4186 {"IIR2 INP4 MUX", "DEC3", "DEC3 MUX"},
4187 {"IIR2 INP4 MUX", "DEC4", "DEC4 MUX"},
4188 {"IIR2 INP4 MUX", "DEC5", "DEC5 MUX"},
4189 {"IIR2 INP4 MUX", "DEC6", "DEC6 MUX"},
4190 {"IIR2 INP4 MUX", "DEC7", "DEC7 MUX"},
4191 {"IIR2 INP4 MUX", "DEC8", "DEC8 MUX"},
4192 {"IIR2 INP4 MUX", "DEC9", "DEC9 MUX"},
4193 {"IIR2 INP4 MUX", "DEC10", "DEC10 MUX"},
4194 {"IIR2 INP4 MUX", "RX1", "SLIM RX1"},
4195 {"IIR2 INP4 MUX", "RX2", "SLIM RX2"},
4196 {"IIR2 INP4 MUX", "RX3", "SLIM RX3"},
4197 {"IIR2 INP4 MUX", "RX4", "SLIM RX4"},
4198 {"IIR2 INP4 MUX", "RX5", "SLIM RX5"},
4199 {"IIR2 INP4 MUX", "RX6", "SLIM RX6"},
4200 {"IIR2 INP4 MUX", "RX7", "SLIM RX7"},
4201
Kiran Kandic3b24402012-06-11 00:05:59 -07004202 {"MIC BIAS1 Internal1", NULL, "LDO_H"},
4203 {"MIC BIAS1 Internal2", NULL, "LDO_H"},
4204 {"MIC BIAS1 External", NULL, "LDO_H"},
4205 {"MIC BIAS2 Internal1", NULL, "LDO_H"},
4206 {"MIC BIAS2 Internal2", NULL, "LDO_H"},
4207 {"MIC BIAS2 Internal3", NULL, "LDO_H"},
4208 {"MIC BIAS2 External", NULL, "LDO_H"},
4209 {"MIC BIAS3 Internal1", NULL, "LDO_H"},
4210 {"MIC BIAS3 Internal2", NULL, "LDO_H"},
4211 {"MIC BIAS3 External", NULL, "LDO_H"},
4212 {"MIC BIAS4 External", NULL, "LDO_H"},
Joonwoo Parkccccba72013-04-26 11:19:46 -07004213 {DAPM_MICBIAS2_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07004214 {DAPM_MICBIAS3_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
Kiran Kandic3b24402012-06-11 00:05:59 -07004215};
4216
4217static int taiko_readable(struct snd_soc_codec *ssc, unsigned int reg)
4218{
4219 return taiko_reg_readable[reg];
4220}
4221
4222static bool taiko_is_digital_gain_register(unsigned int reg)
4223{
4224 bool rtn = false;
4225 switch (reg) {
4226 case TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL:
4227 case TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL:
4228 case TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL:
4229 case TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL:
4230 case TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL:
4231 case TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL:
4232 case TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL:
4233 case TAIKO_A_CDC_TX1_VOL_CTL_GAIN:
4234 case TAIKO_A_CDC_TX2_VOL_CTL_GAIN:
4235 case TAIKO_A_CDC_TX3_VOL_CTL_GAIN:
4236 case TAIKO_A_CDC_TX4_VOL_CTL_GAIN:
4237 case TAIKO_A_CDC_TX5_VOL_CTL_GAIN:
4238 case TAIKO_A_CDC_TX6_VOL_CTL_GAIN:
4239 case TAIKO_A_CDC_TX7_VOL_CTL_GAIN:
4240 case TAIKO_A_CDC_TX8_VOL_CTL_GAIN:
4241 case TAIKO_A_CDC_TX9_VOL_CTL_GAIN:
4242 case TAIKO_A_CDC_TX10_VOL_CTL_GAIN:
4243 rtn = true;
4244 break;
4245 default:
4246 break;
4247 }
4248 return rtn;
4249}
4250
4251static int taiko_volatile(struct snd_soc_codec *ssc, unsigned int reg)
4252{
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004253 int i;
4254
Kiran Kandic3b24402012-06-11 00:05:59 -07004255 /* Registers lower than 0x100 are top level registers which can be
4256 * written by the Taiko core driver.
4257 */
4258
4259 if ((reg >= TAIKO_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
4260 return 1;
4261
4262 /* IIR Coeff registers are not cacheable */
4263 if ((reg >= TAIKO_A_CDC_IIR1_COEF_B1_CTL) &&
4264 (reg <= TAIKO_A_CDC_IIR2_COEF_B2_CTL))
4265 return 1;
4266
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08004267 /* ANC filter registers are not cacheable */
4268 if ((reg >= TAIKO_A_CDC_ANC1_IIR_B1_CTL) &&
4269 (reg <= TAIKO_A_CDC_ANC1_LPF_B2_CTL))
4270 return 1;
4271 if ((reg >= TAIKO_A_CDC_ANC2_IIR_B1_CTL) &&
4272 (reg <= TAIKO_A_CDC_ANC2_LPF_B2_CTL))
4273 return 1;
4274
Kiran Kandic3b24402012-06-11 00:05:59 -07004275 /* Digital gain register is not cacheable so we have to write
4276 * the setting even it is the same
4277 */
4278 if (taiko_is_digital_gain_register(reg))
4279 return 1;
4280
4281 /* HPH status registers */
4282 if (reg == TAIKO_A_RX_HPH_L_STATUS || reg == TAIKO_A_RX_HPH_R_STATUS)
4283 return 1;
4284
Sudheer Papothifb0ec9d2014-03-15 00:12:33 +05304285 /* HPH PA Enable */
4286 if (reg == TAIKO_A_RX_HPH_CNP_EN)
4287 return 1;
4288
Joonwoo Parka8890262012-10-15 12:04:27 -07004289 if (reg == TAIKO_A_MBHC_INSERT_DET_STATUS)
4290 return 1;
4291
Joonwoo Park559a5bf2013-02-15 14:46:36 -08004292 switch (reg) {
4293 case TAIKO_A_CDC_SPKR_CLIPDET_VAL0:
4294 case TAIKO_A_CDC_SPKR_CLIPDET_VAL1:
4295 case TAIKO_A_CDC_SPKR_CLIPDET_VAL2:
4296 case TAIKO_A_CDC_SPKR_CLIPDET_VAL3:
4297 case TAIKO_A_CDC_SPKR_CLIPDET_VAL4:
4298 case TAIKO_A_CDC_SPKR_CLIPDET_VAL5:
4299 case TAIKO_A_CDC_SPKR_CLIPDET_VAL6:
4300 case TAIKO_A_CDC_SPKR_CLIPDET_VAL7:
4301 case TAIKO_A_CDC_VBAT_GAIN_MON_VAL:
4302 return 1;
4303 }
4304
Damir Didjustodcfdff82013-03-21 23:26:41 -07004305 for (i = 0; i < ARRAY_SIZE(audio_reg_cfg); i++)
4306 if (audio_reg_cfg[i].reg_logical_addr -
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004307 TAIKO_REGISTER_START_OFFSET == reg)
4308 return 1;
4309
Kiran Kandic3b24402012-06-11 00:05:59 -07004310 return 0;
4311}
4312
Kiran Kandic3b24402012-06-11 00:05:59 -07004313static int taiko_write(struct snd_soc_codec *codec, unsigned int reg,
4314 unsigned int value)
4315{
4316 int ret;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07004317 struct wcd9xxx *wcd9xxx = codec->control_data;
Kuirong Wang906ac472012-07-09 12:54:44 -07004318
4319 if (reg == SND_SOC_NOPM)
4320 return 0;
4321
Kiran Kandic3b24402012-06-11 00:05:59 -07004322 BUG_ON(reg > TAIKO_MAX_REGISTER);
4323
4324 if (!taiko_volatile(codec, reg)) {
4325 ret = snd_soc_cache_write(codec, reg, value);
4326 if (ret != 0)
4327 dev_err(codec->dev, "Cache write to %x failed: %d\n",
4328 reg, ret);
4329 }
4330
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07004331 return wcd9xxx_reg_write(&wcd9xxx->core_res, reg, value);
Kiran Kandic3b24402012-06-11 00:05:59 -07004332}
4333static unsigned int taiko_read(struct snd_soc_codec *codec,
4334 unsigned int reg)
4335{
4336 unsigned int val;
4337 int ret;
4338
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07004339 struct wcd9xxx *wcd9xxx = codec->control_data;
4340
Kuirong Wang906ac472012-07-09 12:54:44 -07004341 if (reg == SND_SOC_NOPM)
4342 return 0;
4343
Kiran Kandic3b24402012-06-11 00:05:59 -07004344 BUG_ON(reg > TAIKO_MAX_REGISTER);
4345
4346 if (!taiko_volatile(codec, reg) && taiko_readable(codec, reg) &&
4347 reg < codec->driver->reg_cache_size) {
4348 ret = snd_soc_cache_read(codec, reg, &val);
4349 if (ret >= 0) {
4350 return val;
4351 } else
4352 dev_err(codec->dev, "Cache read from %x failed: %d\n",
4353 reg, ret);
4354 }
4355
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07004356 val = wcd9xxx_reg_read(&wcd9xxx->core_res, reg);
Kiran Kandic3b24402012-06-11 00:05:59 -07004357 return val;
4358}
4359
Kiran Kandic3b24402012-06-11 00:05:59 -07004360static int taiko_startup(struct snd_pcm_substream *substream,
4361 struct snd_soc_dai *dai)
4362{
Kiran Kandic3b24402012-06-11 00:05:59 -07004363 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
4364 substream->name, substream->stream);
Kiran Kandic3b24402012-06-11 00:05:59 -07004365
4366 return 0;
4367}
4368
4369static void taiko_shutdown(struct snd_pcm_substream *substream,
4370 struct snd_soc_dai *dai)
4371{
Kiran Kandic3b24402012-06-11 00:05:59 -07004372 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
4373 substream->name, substream->stream);
Kiran Kandic3b24402012-06-11 00:05:59 -07004374}
4375
4376int taiko_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm)
4377{
4378 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
4379
4380 pr_debug("%s: mclk_enable = %u, dapm = %d\n", __func__, mclk_enable,
4381 dapm);
Joonwoo Parka8890262012-10-15 12:04:27 -07004382
Joonwoo Park533b3682013-06-13 11:41:21 -07004383 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07004384 if (mclk_enable) {
Joonwoo Parka8890262012-10-15 12:04:27 -07004385 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
4386 WCD9XXX_BANDGAP_AUDIO_MODE);
4387 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
Kiran Kandic3b24402012-06-11 00:05:59 -07004388 } else {
Joonwoo Parka8890262012-10-15 12:04:27 -07004389 /* Put clock and BG */
4390 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
4391 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
4392 WCD9XXX_BANDGAP_AUDIO_MODE);
Kiran Kandic3b24402012-06-11 00:05:59 -07004393 }
Joonwoo Park533b3682013-06-13 11:41:21 -07004394 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Joonwoo Parka8890262012-10-15 12:04:27 -07004395
Kiran Kandic3b24402012-06-11 00:05:59 -07004396 return 0;
4397}
4398
4399static int taiko_set_dai_sysclk(struct snd_soc_dai *dai,
4400 int clk_id, unsigned int freq, int dir)
4401{
Venkat Sudhira50a3762012-11-26 12:12:15 -08004402 pr_debug("%s\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07004403 return 0;
4404}
4405
4406static int taiko_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
4407{
4408 u8 val = 0;
4409 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
4410
4411 pr_debug("%s\n", __func__);
4412 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
4413 case SND_SOC_DAIFMT_CBS_CFS:
4414 /* CPU is master */
4415 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4416 if (dai->id == AIF1_CAP)
4417 snd_soc_update_bits(dai->codec,
4418 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4419 TAIKO_I2S_MASTER_MODE_MASK, 0);
4420 else if (dai->id == AIF1_PB)
4421 snd_soc_update_bits(dai->codec,
4422 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4423 TAIKO_I2S_MASTER_MODE_MASK, 0);
4424 }
4425 break;
4426 case SND_SOC_DAIFMT_CBM_CFM:
4427 /* CPU is slave */
4428 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4429 val = TAIKO_I2S_MASTER_MODE_MASK;
4430 if (dai->id == AIF1_CAP)
4431 snd_soc_update_bits(dai->codec,
4432 TAIKO_A_CDC_CLK_TX_I2S_CTL, val, val);
4433 else if (dai->id == AIF1_PB)
4434 snd_soc_update_bits(dai->codec,
4435 TAIKO_A_CDC_CLK_RX_I2S_CTL, val, val);
4436 }
4437 break;
4438 default:
4439 return -EINVAL;
4440 }
4441 return 0;
4442}
4443
4444static int taiko_set_channel_map(struct snd_soc_dai *dai,
4445 unsigned int tx_num, unsigned int *tx_slot,
4446 unsigned int rx_num, unsigned int *rx_slot)
4447
4448{
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004449 struct wcd9xxx_codec_dai_data *dai_data = NULL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004450 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07004451 struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07004452 if (!tx_slot && !rx_slot) {
4453 pr_err("%s: Invalid\n", __func__);
4454 return -EINVAL;
4455 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004456 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
4457 "taiko->intf_type %d\n",
4458 __func__, dai->name, dai->id, tx_num, rx_num,
4459 taiko->intf_type);
Kiran Kandic3b24402012-06-11 00:05:59 -07004460
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004461 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Kuirong Wang906ac472012-07-09 12:54:44 -07004462 wcd9xxx_init_slimslave(core, core->slim->laddr,
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004463 tx_num, tx_slot, rx_num, rx_slot);
4464 /*Reserve tx11 and tx12 for VI feedback path*/
4465 dai_data = &taiko->dai[AIF4_VIFEED];
4466 if (dai_data) {
4467 list_add_tail(&core->tx_chs[TAIKO_TX11].list,
4468 &dai_data->wcd9xxx_ch_list);
4469 list_add_tail(&core->tx_chs[TAIKO_TX12].list,
4470 &dai_data->wcd9xxx_ch_list);
4471 }
4472 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004473 return 0;
4474}
4475
4476static int taiko_get_channel_map(struct snd_soc_dai *dai,
4477 unsigned int *tx_num, unsigned int *tx_slot,
4478 unsigned int *rx_num, unsigned int *rx_slot)
4479
4480{
4481 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(dai->codec);
4482 u32 i = 0;
4483 struct wcd9xxx_ch *ch;
4484
4485 switch (dai->id) {
4486 case AIF1_PB:
4487 case AIF2_PB:
4488 case AIF3_PB:
4489 if (!rx_slot || !rx_num) {
4490 pr_err("%s: Invalid rx_slot %d or rx_num %d\n",
4491 __func__, (u32) rx_slot, (u32) rx_num);
4492 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004493 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004494 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
4495 list) {
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05004496 pr_debug("%s: slot_num %u ch->ch_num %d\n",
4497 __func__, i, ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07004498 rx_slot[i++] = ch->ch_num;
4499 }
4500 pr_debug("%s: rx_num %d\n", __func__, i);
4501 *rx_num = i;
4502 break;
4503 case AIF1_CAP:
4504 case AIF2_CAP:
4505 case AIF3_CAP:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004506 case AIF4_VIFEED:
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004507 case AIF4_MAD_TX:
Kuirong Wang906ac472012-07-09 12:54:44 -07004508 if (!tx_slot || !tx_num) {
4509 pr_err("%s: Invalid tx_slot %d or tx_num %d\n",
4510 __func__, (u32) tx_slot, (u32) tx_num);
4511 return -EINVAL;
4512 }
4513 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
4514 list) {
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05004515 pr_debug("%s: slot_num %u ch->ch_num %d\n",
4516 __func__, i, ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07004517 tx_slot[i++] = ch->ch_num;
4518 }
4519 pr_debug("%s: tx_num %d\n", __func__, i);
4520 *tx_num = i;
4521 break;
4522
4523 default:
4524 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
4525 break;
4526 }
4527
4528 return 0;
4529}
4530
4531static int taiko_set_interpolator_rate(struct snd_soc_dai *dai,
4532 u8 rx_fs_rate_reg_val, u32 compander_fs, u32 sample_rate)
4533{
4534 u32 j;
4535 u8 rx_mix1_inp;
4536 u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
4537 u16 rx_fs_reg;
4538 u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
4539 struct snd_soc_codec *codec = dai->codec;
4540 struct wcd9xxx_ch *ch;
4541 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
4542
4543 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
4544 /* for RX port starting from 16 instead of 10 like tabla */
4545 rx_mix1_inp = ch->port + RX_MIX1_INP_SEL_RX1 -
4546 TAIKO_TX_PORT_NUMBER;
4547 if ((rx_mix1_inp < RX_MIX1_INP_SEL_RX1) ||
4548 (rx_mix1_inp > RX_MIX1_INP_SEL_RX7)) {
4549 pr_err("%s: Invalid TAIKO_RX%u port. Dai ID is %d\n",
4550 __func__, rx_mix1_inp - 5 , dai->id);
4551 return -EINVAL;
4552 }
4553
4554 rx_mix_1_reg_1 = TAIKO_A_CDC_CONN_RX1_B1_CTL;
4555
4556 for (j = 0; j < NUM_INTERPOLATORS; j++) {
4557 rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
4558
4559 rx_mix_1_reg_1_val = snd_soc_read(codec,
4560 rx_mix_1_reg_1);
4561 rx_mix_1_reg_2_val = snd_soc_read(codec,
4562 rx_mix_1_reg_2);
4563
4564 if (((rx_mix_1_reg_1_val & 0x0F) == rx_mix1_inp) ||
4565 (((rx_mix_1_reg_1_val >> 4) & 0x0F)
4566 == rx_mix1_inp) ||
4567 ((rx_mix_1_reg_2_val & 0x0F) == rx_mix1_inp)) {
4568
4569 rx_fs_reg = TAIKO_A_CDC_RX1_B5_CTL + 8 * j;
4570
4571 pr_debug("%s: AIF_PB DAI(%d) connected to RX%u\n",
4572 __func__, dai->id, j + 1);
4573
4574 pr_debug("%s: set RX%u sample rate to %u\n",
4575 __func__, j + 1, sample_rate);
4576
4577 snd_soc_update_bits(codec, rx_fs_reg,
4578 0xE0, rx_fs_rate_reg_val);
4579
4580 if (comp_rx_path[j] < COMPANDER_MAX)
4581 taiko->comp_fs[comp_rx_path[j]]
4582 = compander_fs;
4583 }
Kuirong Wang94761952013-03-07 16:19:35 -08004584 if (j < 2)
Kuirong Wang906ac472012-07-09 12:54:44 -07004585 rx_mix_1_reg_1 += 3;
4586 else
4587 rx_mix_1_reg_1 += 2;
Kiran Kandic3b24402012-06-11 00:05:59 -07004588 }
4589 }
4590 return 0;
4591}
4592
Kuirong Wang906ac472012-07-09 12:54:44 -07004593static int taiko_set_decimator_rate(struct snd_soc_dai *dai,
4594 u8 tx_fs_rate_reg_val, u32 sample_rate)
Kiran Kandic3b24402012-06-11 00:05:59 -07004595{
Kuirong Wang906ac472012-07-09 12:54:44 -07004596 struct snd_soc_codec *codec = dai->codec;
4597 struct wcd9xxx_ch *ch;
4598 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
4599 u32 tx_port;
4600 u16 tx_port_reg, tx_fs_reg;
4601 u8 tx_port_reg_val;
4602 s8 decimator;
Kiran Kandic3b24402012-06-11 00:05:59 -07004603
Kuirong Wang906ac472012-07-09 12:54:44 -07004604 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
Kiran Kandic3b24402012-06-11 00:05:59 -07004605
Kuirong Wang906ac472012-07-09 12:54:44 -07004606 tx_port = ch->port + 1;
4607 pr_debug("%s: dai->id = %d, tx_port = %d",
4608 __func__, dai->id, tx_port);
4609
4610 if ((tx_port < 1) || (tx_port > NUM_DECIMATORS)) {
4611 pr_err("%s: Invalid SLIM TX%u port. DAI ID is %d\n",
4612 __func__, tx_port, dai->id);
4613 return -EINVAL;
4614 }
4615
4616 tx_port_reg = TAIKO_A_CDC_CONN_TX_SB_B1_CTL + (tx_port - 1);
4617 tx_port_reg_val = snd_soc_read(codec, tx_port_reg);
4618
4619 decimator = 0;
4620
4621 if ((tx_port >= 1) && (tx_port <= 6)) {
4622
4623 tx_port_reg_val = tx_port_reg_val & 0x0F;
4624 if (tx_port_reg_val == 0x8)
4625 decimator = tx_port;
4626
4627 } else if ((tx_port >= 7) && (tx_port <= NUM_DECIMATORS)) {
4628
4629 tx_port_reg_val = tx_port_reg_val & 0x1F;
4630
4631 if ((tx_port_reg_val >= 0x8) &&
4632 (tx_port_reg_val <= 0x11)) {
4633
4634 decimator = (tx_port_reg_val - 0x8) + 1;
4635 }
4636 }
4637
4638 if (decimator) { /* SLIM_TX port has a DEC as input */
4639
4640 tx_fs_reg = TAIKO_A_CDC_TX1_CLK_FS_CTL +
4641 8 * (decimator - 1);
4642
4643 pr_debug("%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
4644 __func__, decimator, tx_port, sample_rate);
4645
4646 snd_soc_update_bits(codec, tx_fs_reg, 0x07,
4647 tx_fs_rate_reg_val);
4648
4649 } else {
4650 if ((tx_port_reg_val >= 0x1) &&
4651 (tx_port_reg_val <= 0x7)) {
4652
4653 pr_debug("%s: RMIX%u going to SLIM TX%u\n",
4654 __func__, tx_port_reg_val, tx_port);
4655
4656 } else if ((tx_port_reg_val >= 0x8) &&
4657 (tx_port_reg_val <= 0x11)) {
4658
4659 pr_err("%s: ERROR: Should not be here\n",
4660 __func__);
4661 pr_err("%s: ERROR: DEC connected to SLIM TX%u\n",
4662 __func__, tx_port);
4663 return -EINVAL;
4664
4665 } else if (tx_port_reg_val == 0) {
4666 pr_debug("%s: no signal to SLIM TX%u\n",
4667 __func__, tx_port);
4668 } else {
4669 pr_err("%s: ERROR: wrong signal to SLIM TX%u\n",
4670 __func__, tx_port);
4671 pr_err("%s: ERROR: wrong signal = %u\n",
4672 __func__, tx_port_reg_val);
4673 return -EINVAL;
4674 }
4675 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004676 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004677 return 0;
4678}
4679
Patrick Laiff5a5782013-05-05 00:13:00 -07004680static void taiko_set_rxsb_port_format(struct snd_pcm_hw_params *params,
4681 struct snd_soc_dai *dai)
4682{
4683 struct snd_soc_codec *codec = dai->codec;
4684 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
4685 struct wcd9xxx_codec_dai_data *cdc_dai;
4686 struct wcd9xxx_ch *ch;
4687 int port;
4688 u8 bit_sel;
4689 u16 sb_ctl_reg, field_shift;
4690
4691 switch (params_format(params)) {
4692 case SNDRV_PCM_FORMAT_S16_LE:
4693 bit_sel = 0x2;
4694 taiko_p->dai[dai->id].bit_width = 16;
4695 break;
4696 case SNDRV_PCM_FORMAT_S24_LE:
4697 bit_sel = 0x0;
4698 taiko_p->dai[dai->id].bit_width = 24;
4699 break;
4700 default:
4701 dev_err(codec->dev, "Invalid format\n");
4702 return;
4703 }
4704
4705 cdc_dai = &taiko_p->dai[dai->id];
4706
4707 list_for_each_entry(ch, &cdc_dai->wcd9xxx_ch_list, list) {
4708 port = wcd9xxx_get_slave_port(ch->ch_num);
4709
4710 if (IS_ERR_VALUE(port) ||
4711 !TAIKO_VALIDATE_RX_SBPORT_RANGE(port)) {
4712 dev_warn(codec->dev,
4713 "%s: invalid port ID %d returned for RX DAI\n",
4714 __func__, port);
4715 return;
4716 }
4717
4718 port = TAIKO_CONVERT_RX_SBPORT_ID(port);
4719
4720 if (port <= 3) {
4721 sb_ctl_reg = TAIKO_A_CDC_CONN_RX_SB_B1_CTL;
4722 field_shift = port << 1;
4723 } else if (port <= 6) {
4724 sb_ctl_reg = TAIKO_A_CDC_CONN_RX_SB_B2_CTL;
4725 field_shift = (port - 4) << 1;
4726 } else { /* should not happen */
4727 dev_warn(codec->dev,
4728 "%s: bad port ID %d\n", __func__, port);
4729 return;
4730 }
4731
4732 dev_dbg(codec->dev, "%s: sb_ctl_reg %x field_shift %x\n",
4733 __func__, sb_ctl_reg, field_shift);
4734 snd_soc_update_bits(codec, sb_ctl_reg, 0x3 << field_shift,
4735 bit_sel << field_shift);
4736 }
4737}
4738
Kiran Kandic3b24402012-06-11 00:05:59 -07004739static int taiko_hw_params(struct snd_pcm_substream *substream,
4740 struct snd_pcm_hw_params *params,
4741 struct snd_soc_dai *dai)
4742{
4743 struct snd_soc_codec *codec = dai->codec;
4744 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07004745 u8 tx_fs_rate, rx_fs_rate;
Kiran Kandic3b24402012-06-11 00:05:59 -07004746 u32 compander_fs;
Kuirong Wang906ac472012-07-09 12:54:44 -07004747 int ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07004748
4749 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
4750 dai->name, dai->id, params_rate(params),
4751 params_channels(params));
4752
4753 switch (params_rate(params)) {
4754 case 8000:
4755 tx_fs_rate = 0x00;
4756 rx_fs_rate = 0x00;
4757 compander_fs = COMPANDER_FS_8KHZ;
4758 break;
4759 case 16000:
4760 tx_fs_rate = 0x01;
4761 rx_fs_rate = 0x20;
4762 compander_fs = COMPANDER_FS_16KHZ;
4763 break;
4764 case 32000:
4765 tx_fs_rate = 0x02;
4766 rx_fs_rate = 0x40;
4767 compander_fs = COMPANDER_FS_32KHZ;
4768 break;
4769 case 48000:
4770 tx_fs_rate = 0x03;
4771 rx_fs_rate = 0x60;
4772 compander_fs = COMPANDER_FS_48KHZ;
4773 break;
4774 case 96000:
4775 tx_fs_rate = 0x04;
4776 rx_fs_rate = 0x80;
4777 compander_fs = COMPANDER_FS_96KHZ;
4778 break;
4779 case 192000:
4780 tx_fs_rate = 0x05;
4781 rx_fs_rate = 0xA0;
4782 compander_fs = COMPANDER_FS_192KHZ;
4783 break;
4784 default:
4785 pr_err("%s: Invalid sampling rate %d\n", __func__,
Kuirong Wang906ac472012-07-09 12:54:44 -07004786 params_rate(params));
Kiran Kandic3b24402012-06-11 00:05:59 -07004787 return -EINVAL;
4788 }
4789
Kuirong Wang906ac472012-07-09 12:54:44 -07004790 switch (substream->stream) {
4791 case SNDRV_PCM_STREAM_CAPTURE:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004792 if (dai->id != AIF4_VIFEED) {
4793 ret = taiko_set_decimator_rate(dai, tx_fs_rate,
4794 params_rate(params));
4795 if (ret < 0) {
4796 pr_err("%s: set decimator rate failed %d\n",
4797 __func__, ret);
4798 return ret;
4799 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004800 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004801
Kiran Kandic3b24402012-06-11 00:05:59 -07004802 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4803 switch (params_format(params)) {
4804 case SNDRV_PCM_FORMAT_S16_LE:
4805 snd_soc_update_bits(codec,
4806 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4807 0x20, 0x20);
4808 break;
4809 case SNDRV_PCM_FORMAT_S32_LE:
4810 snd_soc_update_bits(codec,
4811 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4812 0x20, 0x00);
4813 break;
4814 default:
4815 pr_err("invalid format\n");
4816 break;
4817 }
4818 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07004819 0x07, tx_fs_rate);
Kiran Kandic3b24402012-06-11 00:05:59 -07004820 } else {
Kuirong Wang906ac472012-07-09 12:54:44 -07004821 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07004822 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004823 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07004824
Kuirong Wang906ac472012-07-09 12:54:44 -07004825 case SNDRV_PCM_STREAM_PLAYBACK:
4826 ret = taiko_set_interpolator_rate(dai, rx_fs_rate,
4827 compander_fs,
4828 params_rate(params));
4829 if (ret < 0) {
4830 pr_err("%s: set decimator rate failed %d\n", __func__,
4831 ret);
4832 return ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07004833 }
4834 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4835 switch (params_format(params)) {
4836 case SNDRV_PCM_FORMAT_S16_LE:
4837 snd_soc_update_bits(codec,
4838 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4839 0x20, 0x20);
4840 break;
4841 case SNDRV_PCM_FORMAT_S32_LE:
4842 snd_soc_update_bits(codec,
4843 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4844 0x20, 0x00);
4845 break;
4846 default:
4847 pr_err("invalid format\n");
4848 break;
4849 }
4850 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07004851 0x03, (rx_fs_rate >> 0x05));
Kiran Kandic3b24402012-06-11 00:05:59 -07004852 } else {
Patrick Laiff5a5782013-05-05 00:13:00 -07004853 taiko_set_rxsb_port_format(params, dai);
Kuirong Wang906ac472012-07-09 12:54:44 -07004854 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07004855 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004856 break;
4857 default:
4858 pr_err("%s: Invalid stream type %d\n", __func__,
4859 substream->stream);
4860 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004861 }
4862
4863 return 0;
4864}
4865
4866static struct snd_soc_dai_ops taiko_dai_ops = {
4867 .startup = taiko_startup,
4868 .shutdown = taiko_shutdown,
4869 .hw_params = taiko_hw_params,
4870 .set_sysclk = taiko_set_dai_sysclk,
4871 .set_fmt = taiko_set_dai_fmt,
4872 .set_channel_map = taiko_set_channel_map,
4873 .get_channel_map = taiko_get_channel_map,
4874};
4875
4876static struct snd_soc_dai_driver taiko_dai[] = {
4877 {
4878 .name = "taiko_rx1",
4879 .id = AIF1_PB,
4880 .playback = {
4881 .stream_name = "AIF1 Playback",
4882 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004883 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004884 .rate_max = 192000,
4885 .rate_min = 8000,
4886 .channels_min = 1,
4887 .channels_max = 2,
4888 },
4889 .ops = &taiko_dai_ops,
4890 },
4891 {
4892 .name = "taiko_tx1",
4893 .id = AIF1_CAP,
4894 .capture = {
4895 .stream_name = "AIF1 Capture",
4896 .rates = WCD9320_RATES,
4897 .formats = TAIKO_FORMATS,
4898 .rate_max = 192000,
4899 .rate_min = 8000,
4900 .channels_min = 1,
4901 .channels_max = 4,
4902 },
4903 .ops = &taiko_dai_ops,
4904 },
4905 {
4906 .name = "taiko_rx2",
4907 .id = AIF2_PB,
4908 .playback = {
4909 .stream_name = "AIF2 Playback",
4910 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004911 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004912 .rate_min = 8000,
4913 .rate_max = 192000,
4914 .channels_min = 1,
4915 .channels_max = 2,
4916 },
4917 .ops = &taiko_dai_ops,
4918 },
4919 {
4920 .name = "taiko_tx2",
4921 .id = AIF2_CAP,
4922 .capture = {
4923 .stream_name = "AIF2 Capture",
4924 .rates = WCD9320_RATES,
4925 .formats = TAIKO_FORMATS,
4926 .rate_max = 192000,
4927 .rate_min = 8000,
4928 .channels_min = 1,
Ravit Dennis895a5572013-06-05 16:34:42 +03004929 .channels_max = 8,
Kiran Kandic3b24402012-06-11 00:05:59 -07004930 },
4931 .ops = &taiko_dai_ops,
4932 },
4933 {
4934 .name = "taiko_tx3",
4935 .id = AIF3_CAP,
4936 .capture = {
4937 .stream_name = "AIF3 Capture",
4938 .rates = WCD9320_RATES,
4939 .formats = TAIKO_FORMATS,
4940 .rate_max = 48000,
4941 .rate_min = 8000,
4942 .channels_min = 1,
4943 .channels_max = 2,
4944 },
4945 .ops = &taiko_dai_ops,
4946 },
4947 {
4948 .name = "taiko_rx3",
4949 .id = AIF3_PB,
4950 .playback = {
4951 .stream_name = "AIF3 Playback",
4952 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004953 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004954 .rate_min = 8000,
4955 .rate_max = 192000,
4956 .channels_min = 1,
4957 .channels_max = 2,
4958 },
4959 .ops = &taiko_dai_ops,
4960 },
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004961 {
4962 .name = "taiko_vifeedback",
4963 .id = AIF4_VIFEED,
4964 .capture = {
4965 .stream_name = "VIfeed",
4966 .rates = SNDRV_PCM_RATE_48000,
4967 .formats = TAIKO_FORMATS,
4968 .rate_max = 48000,
4969 .rate_min = 48000,
4970 .channels_min = 2,
4971 .channels_max = 2,
4972 },
4973 .ops = &taiko_dai_ops,
4974 },
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004975 {
4976 .name = "taiko_mad1",
4977 .id = AIF4_MAD_TX,
4978 .capture = {
4979 .stream_name = "AIF4 MAD TX",
4980 .rates = SNDRV_PCM_RATE_16000,
4981 .formats = TAIKO_FORMATS,
4982 .rate_min = 16000,
4983 .rate_max = 16000,
4984 .channels_min = 1,
4985 .channels_max = 1,
4986 },
4987 .ops = &taiko_dai_ops,
4988 },
Kiran Kandic3b24402012-06-11 00:05:59 -07004989};
4990
4991static struct snd_soc_dai_driver taiko_i2s_dai[] = {
4992 {
4993 .name = "taiko_i2s_rx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07004994 .id = AIF1_PB,
Kiran Kandic3b24402012-06-11 00:05:59 -07004995 .playback = {
4996 .stream_name = "AIF1 Playback",
4997 .rates = WCD9320_RATES,
4998 .formats = TAIKO_FORMATS,
4999 .rate_max = 192000,
5000 .rate_min = 8000,
5001 .channels_min = 1,
5002 .channels_max = 4,
5003 },
5004 .ops = &taiko_dai_ops,
5005 },
5006 {
5007 .name = "taiko_i2s_tx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07005008 .id = AIF1_CAP,
Kiran Kandic3b24402012-06-11 00:05:59 -07005009 .capture = {
5010 .stream_name = "AIF1 Capture",
5011 .rates = WCD9320_RATES,
5012 .formats = TAIKO_FORMATS,
5013 .rate_max = 192000,
5014 .rate_min = 8000,
5015 .channels_min = 1,
5016 .channels_max = 4,
5017 },
5018 .ops = &taiko_dai_ops,
5019 },
Venkat Sudhir994193b2012-12-17 17:30:51 -08005020 {
5021 .name = "taiko_i2s_rx2",
5022 .id = AIF1_PB,
5023 .playback = {
5024 .stream_name = "AIF2 Playback",
5025 .rates = WCD9320_RATES,
5026 .formats = TAIKO_FORMATS,
5027 .rate_max = 192000,
5028 .rate_min = 8000,
5029 .channels_min = 1,
5030 .channels_max = 4,
5031 },
5032 .ops = &taiko_dai_ops,
5033 },
5034 {
5035 .name = "taiko_i2s_tx2",
5036 .id = AIF1_CAP,
5037 .capture = {
5038 .stream_name = "AIF2 Capture",
5039 .rates = WCD9320_RATES,
5040 .formats = TAIKO_FORMATS,
5041 .rate_max = 192000,
5042 .rate_min = 8000,
5043 .channels_min = 1,
5044 .channels_max = 4,
5045 },
5046 .ops = &taiko_dai_ops,
5047 },
Kiran Kandic3b24402012-06-11 00:05:59 -07005048};
5049
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005050static int taiko_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
5051 bool up)
5052{
5053 int ret = 0;
5054 struct wcd9xxx_ch *ch;
5055
5056 if (up) {
5057 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
5058 ret = wcd9xxx_get_slave_port(ch->ch_num);
5059 if (ret < 0) {
5060 pr_err("%s: Invalid slave port ID: %d\n",
5061 __func__, ret);
5062 ret = -EINVAL;
5063 } else {
5064 set_bit(ret, &dai->ch_mask);
5065 }
5066 }
5067 } else {
5068 ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
5069 msecs_to_jiffies(
5070 TAIKO_SLIM_CLOSE_TIMEOUT));
5071 if (!ret) {
5072 pr_err("%s: Slim close tx/rx wait timeout\n", __func__);
5073 ret = -ETIMEDOUT;
5074 } else {
5075 ret = 0;
5076 }
5077 }
5078 return ret;
5079}
5080
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005081static void taiko_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai,
5082 struct snd_soc_codec *codec)
5083{
5084 struct wcd9xxx_ch *ch;
5085 int port_num = 0;
5086 unsigned short reg = 0;
5087 u8 val = 0;
5088 if (!dai || !codec) {
5089 pr_err("%s: Invalid params\n", __func__);
5090 return;
5091 }
5092 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
5093 if (ch->port >= TAIKO_RX_PORT_START_NUMBER) {
5094 port_num = ch->port - TAIKO_RX_PORT_START_NUMBER;
5095 reg = TAIKO_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
5096 val = wcd9xxx_interface_reg_read(codec->control_data,
5097 reg);
5098 if (!(val & (1 << (port_num % 8)))) {
5099 val |= (1 << (port_num % 8));
5100 wcd9xxx_interface_reg_write(
5101 codec->control_data, reg, val);
5102 val = wcd9xxx_interface_reg_read(
5103 codec->control_data, reg);
5104 }
5105 } else {
5106 port_num = ch->port;
5107 reg = TAIKO_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
5108 val = wcd9xxx_interface_reg_read(codec->control_data,
5109 reg);
5110 if (!(val & (1 << (port_num % 8)))) {
5111 val |= (1 << (port_num % 8));
5112 wcd9xxx_interface_reg_write(codec->control_data,
5113 reg, val);
5114 val = wcd9xxx_interface_reg_read(
5115 codec->control_data, reg);
5116 }
5117 }
5118 }
5119}
5120
Kiran Kandic3b24402012-06-11 00:05:59 -07005121static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07005122 struct snd_kcontrol *kcontrol,
5123 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07005124{
Kuirong Wang906ac472012-07-09 12:54:44 -07005125 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07005126 struct snd_soc_codec *codec = w->codec;
5127 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005128 int ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07005129 struct wcd9xxx_codec_dai_data *dai;
5130
5131 core = dev_get_drvdata(codec->dev->parent);
5132
5133 pr_debug("%s: event called! codec name %s num_dai %d\n"
5134 "stream name %s event %d\n",
5135 __func__, w->codec->name, w->codec->num_dai, w->sname, event);
5136
Kiran Kandic3b24402012-06-11 00:05:59 -07005137 /* Execute the callback only if interface type is slimbus */
5138 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
5139 return 0;
5140
Kuirong Wang906ac472012-07-09 12:54:44 -07005141 dai = &taiko_p->dai[w->shift];
5142 pr_debug("%s: w->name %s w->shift %d event %d\n",
5143 __func__, w->name, w->shift, event);
Kiran Kandic3b24402012-06-11 00:05:59 -07005144
5145 switch (event) {
5146 case SND_SOC_DAPM_POST_PMU:
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005147 taiko_codec_enable_int_port(dai, codec);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005148 (void) taiko_codec_enable_slim_chmask(dai, true);
Kuirong Wang906ac472012-07-09 12:54:44 -07005149 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
5150 dai->rate, dai->bit_width,
5151 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07005152 break;
5153 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07005154 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
5155 dai->grph);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005156 ret = taiko_codec_enable_slim_chmask(dai, false);
5157 if (ret < 0) {
5158 ret = wcd9xxx_disconnect_port(core,
5159 &dai->wcd9xxx_ch_list,
5160 dai->grph);
5161 pr_debug("%s: Disconnect RX port, ret = %d\n",
5162 __func__, ret);
5163 }
Kuirong Wang906ac472012-07-09 12:54:44 -07005164 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07005165 }
5166 return ret;
5167}
5168
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005169static int taiko_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
5170 struct snd_kcontrol *kcontrol,
5171 int event)
5172{
5173 struct wcd9xxx *core = NULL;
5174 struct snd_soc_codec *codec = NULL;
5175 struct taiko_priv *taiko_p = NULL;
5176 u32 ret = 0;
5177 struct wcd9xxx_codec_dai_data *dai = NULL;
5178
5179 if (!w || !w->codec) {
5180 pr_err("%s invalid params\n", __func__);
5181 return -EINVAL;
5182 }
5183 codec = w->codec;
5184 taiko_p = snd_soc_codec_get_drvdata(codec);
5185 core = dev_get_drvdata(codec->dev->parent);
5186
5187 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
5188 __func__, w->codec->name, w->codec->num_dai, w->sname);
5189
5190 /* Execute the callback only if interface type is slimbus */
5191 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
5192 pr_err("%s Interface is not correct", __func__);
5193 return 0;
5194 }
5195
5196 pr_debug("%s(): w->name %s event %d w->shift %d\n",
5197 __func__, w->name, event, w->shift);
5198 if (w->shift != AIF4_VIFEED) {
5199 pr_err("%s Error in enabling the tx path\n", __func__);
5200 ret = -EINVAL;
5201 goto out_vi;
5202 }
5203 dai = &taiko_p->dai[w->shift];
5204 switch (event) {
5205 case SND_SOC_DAPM_POST_PMU:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005206 /*Enable V&I sensing*/
5207 snd_soc_update_bits(codec, TAIKO_A_SPKR_PROT_EN,
5208 0x88, 0x88);
5209 /*Enable spkr VI clocks*/
5210 snd_soc_update_bits(codec,
5211 TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0xC, 0xC);
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005212 taiko_codec_enable_int_port(dai, codec);
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -04005213 (void) taiko_codec_enable_slim_chmask(dai, true);
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005214 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
5215 dai->rate, dai->bit_width,
5216 &dai->grph);
5217 break;
5218 case SND_SOC_DAPM_POST_PMD:
5219 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
5220 dai->grph);
5221 if (ret)
5222 pr_err("%s error in close_slim_sch_tx %d\n",
5223 __func__, ret);
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005224 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL,
5225 0xC, 0x0);
5226 /*Disable V&I sensing*/
5227 snd_soc_update_bits(codec, TAIKO_A_SPKR_PROT_EN,
5228 0x88, 0x00);
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005229 break;
5230 }
5231out_vi:
5232 return ret;
5233}
5234
Kiran Kandic3b24402012-06-11 00:05:59 -07005235static int taiko_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07005236 struct snd_kcontrol *kcontrol,
5237 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07005238{
Kuirong Wang906ac472012-07-09 12:54:44 -07005239 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07005240 struct snd_soc_codec *codec = w->codec;
5241 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07005242 u32 ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07005243 struct wcd9xxx_codec_dai_data *dai;
Kiran Kandic3b24402012-06-11 00:05:59 -07005244
Kuirong Wang906ac472012-07-09 12:54:44 -07005245 core = dev_get_drvdata(codec->dev->parent);
5246
5247 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
5248 __func__, w->codec->name, w->codec->num_dai, w->sname);
Kiran Kandic3b24402012-06-11 00:05:59 -07005249
5250 /* Execute the callback only if interface type is slimbus */
5251 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
5252 return 0;
5253
Kuirong Wang906ac472012-07-09 12:54:44 -07005254 pr_debug("%s(): w->name %s event %d w->shift %d\n",
5255 __func__, w->name, event, w->shift);
Kiran Kandic3b24402012-06-11 00:05:59 -07005256
Kuirong Wang906ac472012-07-09 12:54:44 -07005257 dai = &taiko_p->dai[w->shift];
Kiran Kandic3b24402012-06-11 00:05:59 -07005258 switch (event) {
5259 case SND_SOC_DAPM_POST_PMU:
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005260 taiko_codec_enable_int_port(dai, codec);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005261 (void) taiko_codec_enable_slim_chmask(dai, true);
Kuirong Wang906ac472012-07-09 12:54:44 -07005262 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
5263 dai->rate, dai->bit_width,
5264 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07005265 break;
5266 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07005267 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
5268 dai->grph);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005269 ret = taiko_codec_enable_slim_chmask(dai, false);
5270 if (ret < 0) {
5271 ret = wcd9xxx_disconnect_port(core,
5272 &dai->wcd9xxx_ch_list,
5273 dai->grph);
5274 pr_debug("%s: Disconnect RX port, ret = %d\n",
5275 __func__, ret);
5276 }
Kuirong Wang906ac472012-07-09 12:54:44 -07005277 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07005278 }
5279 return ret;
5280}
5281
Kiran Kandi4c56c592012-07-25 11:04:55 -07005282static int taiko_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
5283 struct snd_kcontrol *kcontrol, int event)
5284{
5285 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005286 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandi4c56c592012-07-25 11:04:55 -07005287
5288 pr_debug("%s %s %d\n", __func__, w->name, event);
5289
5290 switch (event) {
Kiran Kandi4c56c592012-07-25 11:04:55 -07005291 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005292 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
5293 WCD9XXX_CLSH_STATE_EAR,
5294 WCD9XXX_CLSH_REQ_ENABLE,
5295 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandi4c56c592012-07-25 11:04:55 -07005296
5297 usleep_range(5000, 5000);
5298 break;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005299 case SND_SOC_DAPM_POST_PMD:
5300 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
5301 WCD9XXX_CLSH_STATE_EAR,
5302 WCD9XXX_CLSH_REQ_DISABLE,
5303 WCD9XXX_CLSH_EVENT_POST_PA);
5304 usleep_range(5000, 5000);
5305 }
5306 return 0;
5307}
5308
5309static int taiko_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
5310 struct snd_kcontrol *kcontrol, int event)
5311{
5312 struct snd_soc_codec *codec = w->codec;
5313 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
5314
5315 pr_debug("%s %s %d\n", __func__, w->name, event);
5316
5317 switch (event) {
5318 case SND_SOC_DAPM_PRE_PMU:
5319 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
5320 WCD9XXX_CLSH_STATE_EAR,
5321 WCD9XXX_CLSH_REQ_ENABLE,
5322 WCD9XXX_CLSH_EVENT_PRE_DAC);
5323 break;
5324 }
5325
5326 return 0;
5327}
5328
Sudheer Papothi0ef366f2014-01-28 05:56:59 +05305329static int taiko_codec_iir_mux_event(struct snd_soc_dapm_widget *w,
5330 struct snd_kcontrol *kcontrol, int event)
5331{
5332 struct snd_soc_codec *codec = w->codec;
5333
5334 pr_debug("%s: event = %d\n", __func__, event);
5335
5336 switch (event) {
5337 case SND_SOC_DAPM_POST_PMU:
5338 snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
5339 break;
5340 case SND_SOC_DAPM_POST_PMD:
5341 snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
5342 break;
5343 }
5344 return 0;
5345}
5346
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005347static int taiko_codec_dsm_mux_event(struct snd_soc_dapm_widget *w,
5348 struct snd_kcontrol *kcontrol, int event)
5349{
5350 struct snd_soc_codec *codec = w->codec;
5351 u8 reg_val, zoh_mux_val = 0x00;
5352
5353 pr_debug("%s: event = %d\n", __func__, event);
5354
5355 switch (event) {
5356 case SND_SOC_DAPM_POST_PMU:
5357 reg_val = snd_soc_read(codec, TAIKO_A_CDC_CONN_CLSH_CTL);
5358
5359 if ((reg_val & 0x30) == 0x10)
5360 zoh_mux_val = 0x04;
5361 else if ((reg_val & 0x30) == 0x20)
5362 zoh_mux_val = 0x08;
5363
5364 if (zoh_mux_val != 0x00)
5365 snd_soc_update_bits(codec,
5366 TAIKO_A_CDC_CONN_CLSH_CTL,
5367 0x0C, zoh_mux_val);
5368 break;
5369
5370 case SND_SOC_DAPM_POST_PMD:
5371 snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_CLSH_CTL,
5372 0x0C, 0x00);
5373 break;
Kiran Kandi4c56c592012-07-25 11:04:55 -07005374 }
5375 return 0;
5376}
5377
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08005378static int taiko_codec_enable_anc_ear(struct snd_soc_dapm_widget *w,
5379 struct snd_kcontrol *kcontrol, int event)
5380{
5381 struct snd_soc_codec *codec = w->codec;
5382 int ret = 0;
5383
5384 switch (event) {
5385 case SND_SOC_DAPM_PRE_PMU:
5386 ret = taiko_codec_enable_anc(w, kcontrol, event);
5387 msleep(50);
5388 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x10);
5389 break;
5390 case SND_SOC_DAPM_POST_PMU:
5391 ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
5392 break;
5393 case SND_SOC_DAPM_PRE_PMD:
5394 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x00);
5395 msleep(40);
5396 ret |= taiko_codec_enable_anc(w, kcontrol, event);
5397 break;
5398 case SND_SOC_DAPM_POST_PMD:
5399 ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
5400 break;
5401 }
5402 return ret;
5403}
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005404
Kiran Kandic3b24402012-06-11 00:05:59 -07005405/* Todo: Have seperate dapm widgets for I2S and Slimbus.
5406 * Might Need to have callbacks registered only for slimbus
5407 */
5408static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
5409 /*RX stuff */
5410 SND_SOC_DAPM_OUTPUT("EAR"),
5411
Kiran Kandi4c56c592012-07-25 11:04:55 -07005412 SND_SOC_DAPM_PGA_E("EAR PA", TAIKO_A_RX_EAR_EN, 4, 0, NULL, 0,
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005413 taiko_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU |
5414 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005415
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005416 SND_SOC_DAPM_MIXER_E("DAC1", TAIKO_A_RX_EAR_EN, 6, 0, dac1_switch,
5417 ARRAY_SIZE(dac1_switch), taiko_codec_ear_dac_event,
5418 SND_SOC_DAPM_PRE_PMU),
Kiran Kandic3b24402012-06-11 00:05:59 -07005419
Kuirong Wang906ac472012-07-09 12:54:44 -07005420 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
5421 AIF1_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07005422 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07005423 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
5424 AIF2_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07005425 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07005426 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
5427 AIF3_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07005428 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5429
Kuirong Wang906ac472012-07-09 12:54:44 -07005430 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TAIKO_RX1, 0,
5431 &slim_rx_mux[TAIKO_RX1]),
5432 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TAIKO_RX2, 0,
5433 &slim_rx_mux[TAIKO_RX2]),
5434 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TAIKO_RX3, 0,
5435 &slim_rx_mux[TAIKO_RX3]),
5436 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TAIKO_RX4, 0,
5437 &slim_rx_mux[TAIKO_RX4]),
5438 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TAIKO_RX5, 0,
5439 &slim_rx_mux[TAIKO_RX5]),
5440 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TAIKO_RX6, 0,
5441 &slim_rx_mux[TAIKO_RX6]),
5442 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TAIKO_RX7, 0,
5443 &slim_rx_mux[TAIKO_RX7]),
Kiran Kandic3b24402012-06-11 00:05:59 -07005444
Kuirong Wang906ac472012-07-09 12:54:44 -07005445 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
5446 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
5447 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
5448 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
5449 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
5450 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
5451 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
Kiran Kandic3b24402012-06-11 00:05:59 -07005452
5453 /* Headphone */
5454 SND_SOC_DAPM_OUTPUT("HEADPHONE"),
5455 SND_SOC_DAPM_PGA_E("HPHL", TAIKO_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
5456 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07005457 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005458 SND_SOC_DAPM_MIXER_E("HPHL DAC", TAIKO_A_RX_HPH_L_DAC_CTL, 7, 0,
5459 hphl_switch, ARRAY_SIZE(hphl_switch), taiko_hphl_dac_event,
5460 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005461
5462 SND_SOC_DAPM_PGA_E("HPHR", TAIKO_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
5463 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07005464 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005465
5466 SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TAIKO_A_RX_HPH_R_DAC_CTL, 7, 0,
5467 taiko_hphr_dac_event,
5468 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5469
5470 /* Speaker */
5471 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
5472 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
5473 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
5474 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005475 SND_SOC_DAPM_OUTPUT("SPK_OUT"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005476
5477 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TAIKO_A_RX_LINE_CNP_EN, 0, 0, NULL,
5478 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
5479 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5480 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TAIKO_A_RX_LINE_CNP_EN, 1, 0, NULL,
5481 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
5482 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5483 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TAIKO_A_RX_LINE_CNP_EN, 2, 0, NULL,
5484 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
5485 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5486 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TAIKO_A_RX_LINE_CNP_EN, 3, 0, NULL,
5487 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
5488 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005489 SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0 , NULL,
5490 0, taiko_codec_enable_spk_pa,
5491 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005492
5493 SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAIKO_A_RX_LINE_1_DAC_CTL, 7, 0
5494 , taiko_lineout_dac_event,
5495 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5496 SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TAIKO_A_RX_LINE_2_DAC_CTL, 7, 0
5497 , taiko_lineout_dac_event,
5498 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5499 SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TAIKO_A_RX_LINE_3_DAC_CTL, 7, 0
5500 , taiko_lineout_dac_event,
5501 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5502 SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
5503 &lineout3_ground_switch),
5504 SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TAIKO_A_RX_LINE_4_DAC_CTL, 7, 0
5505 , taiko_lineout_dac_event,
5506 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5507 SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
5508 &lineout4_ground_switch),
5509
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005510 SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
5511 taiko_spk_dac_event,
5512 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5513
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005514 SND_SOC_DAPM_SUPPLY("VDD_SPKDRV", SND_SOC_NOPM, 0, 0,
5515 taiko_codec_enable_vdd_spkr,
5516 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5517
Kiran Kandid2b46332012-10-05 12:04:00 -07005518 SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
5519 SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
5520 SND_SOC_DAPM_MIXER("RX7 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
5521
Sudheer Papothia26a6672014-03-22 00:03:34 +05305522 SND_SOC_DAPM_MIXER("RX1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
5523 SND_SOC_DAPM_MIXER("RX2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
5524
Kiran Kandid2b46332012-10-05 12:04:00 -07005525 SND_SOC_DAPM_MIXER_E("RX3 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005526 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005527 SND_SOC_DAPM_POST_PMU),
5528 SND_SOC_DAPM_MIXER_E("RX4 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005529 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005530 SND_SOC_DAPM_POST_PMU),
5531 SND_SOC_DAPM_MIXER_E("RX5 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005532 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005533 SND_SOC_DAPM_POST_PMU),
5534 SND_SOC_DAPM_MIXER_E("RX6 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005535 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005536 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07005537 SND_SOC_DAPM_MIXER_E("RX7 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005538 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005539 SND_SOC_DAPM_POST_PMU),
5540
Sudheer Papothia26a6672014-03-22 00:03:34 +05305541 SND_SOC_DAPM_MUX_E("RX1 INTERP", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0,
5542 &rx1_interpolator, taiko_codec_enable_interpolator,
5543 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
5544 SND_SOC_DAPM_MUX_E("RX2 INTERP", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0,
5545 &rx2_interpolator, taiko_codec_enable_interpolator,
5546 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
Kiran Kandic3b24402012-06-11 00:05:59 -07005547
5548 SND_SOC_DAPM_MIXER("RX1 CHAIN", TAIKO_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
5549 SND_SOC_DAPM_MIXER("RX2 CHAIN", TAIKO_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
5550
5551 SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5552 &rx_mix1_inp1_mux),
5553 SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5554 &rx_mix1_inp2_mux),
5555 SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
5556 &rx_mix1_inp3_mux),
5557 SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5558 &rx2_mix1_inp1_mux),
5559 SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5560 &rx2_mix1_inp2_mux),
5561 SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5562 &rx3_mix1_inp1_mux),
5563 SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5564 &rx3_mix1_inp2_mux),
5565 SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5566 &rx4_mix1_inp1_mux),
5567 SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5568 &rx4_mix1_inp2_mux),
5569 SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5570 &rx5_mix1_inp1_mux),
5571 SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5572 &rx5_mix1_inp2_mux),
5573 SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5574 &rx6_mix1_inp1_mux),
5575 SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5576 &rx6_mix1_inp2_mux),
5577 SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5578 &rx7_mix1_inp1_mux),
5579 SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5580 &rx7_mix1_inp2_mux),
5581 SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
5582 &rx1_mix2_inp1_mux),
5583 SND_SOC_DAPM_MUX("RX1 MIX2 INP2", SND_SOC_NOPM, 0, 0,
5584 &rx1_mix2_inp2_mux),
5585 SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
5586 &rx2_mix2_inp1_mux),
5587 SND_SOC_DAPM_MUX("RX2 MIX2 INP2", SND_SOC_NOPM, 0, 0,
5588 &rx2_mix2_inp2_mux),
5589 SND_SOC_DAPM_MUX("RX7 MIX2 INP1", SND_SOC_NOPM, 0, 0,
5590 &rx7_mix2_inp1_mux),
5591 SND_SOC_DAPM_MUX("RX7 MIX2 INP2", SND_SOC_NOPM, 0, 0,
5592 &rx7_mix2_inp2_mux),
5593
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02005594 SND_SOC_DAPM_MUX("RDAC5 MUX", SND_SOC_NOPM, 0, 0,
5595 &rx_dac5_mux),
5596 SND_SOC_DAPM_MUX("RDAC7 MUX", SND_SOC_NOPM, 0, 0,
5597 &rx_dac7_mux),
5598
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005599 SND_SOC_DAPM_MUX_E("CLASS_H_DSM MUX", SND_SOC_NOPM, 0, 0,
5600 &class_h_dsm_mux, taiko_codec_dsm_mux_event,
5601 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandi4c56c592012-07-25 11:04:55 -07005602
Kiran Kandic3b24402012-06-11 00:05:59 -07005603 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
5604 taiko_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
5605 SND_SOC_DAPM_POST_PMD),
5606
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005607 SND_SOC_DAPM_SUPPLY("CDC_I2S_RX_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 5, 0,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005608 NULL, 0),
5609
Kiran Kandic3b24402012-06-11 00:05:59 -07005610 /* TX */
5611
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005612 SND_SOC_DAPM_SUPPLY("CDC_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
Kiran Kandic3b24402012-06-11 00:05:59 -07005613 0),
5614
Joonwoo Parkccccba72013-04-26 11:19:46 -07005615 SND_SOC_DAPM_SUPPLY("LDO_H", SND_SOC_NOPM, 7, 0,
5616 taiko_codec_enable_ldo_h,
5617 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5618 /*
5619 * DAPM 'LDO_H Standalone' is to be powered by mbhc driver after
5620 * acquring codec_resource lock.
5621 * So call __taiko_codec_enable_ldo_h instead and avoid deadlock.
5622 */
5623 SND_SOC_DAPM_SUPPLY("LDO_H Standalone", SND_SOC_NOPM, 7, 0,
5624 __taiko_codec_enable_ldo_h,
5625 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005626
Joonwoo Parkc7731432012-10-17 12:41:44 -07005627 SND_SOC_DAPM_SUPPLY("COMP0_CLK", SND_SOC_NOPM, 0, 0,
Kiran Kandic3b24402012-06-11 00:05:59 -07005628 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07005629 SND_SOC_DAPM_PRE_PMD),
Joonwoo Parkc7731432012-10-17 12:41:44 -07005630 SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 1, 0,
5631 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07005632 SND_SOC_DAPM_PRE_PMD),
Joonwoo Parkc7731432012-10-17 12:41:44 -07005633 SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 2, 0,
Kiran Kandic3b24402012-06-11 00:05:59 -07005634 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07005635 SND_SOC_DAPM_PRE_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005636
5637
5638 SND_SOC_DAPM_INPUT("AMIC1"),
Joonwoo Park3699ca32013-02-08 12:06:15 -08005639 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", SND_SOC_NOPM, 7, 0,
5640 taiko_codec_enable_micbias,
5641 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5642 SND_SOC_DAPM_POST_PMD),
5643 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", SND_SOC_NOPM, 7, 0,
5644 taiko_codec_enable_micbias,
5645 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5646 SND_SOC_DAPM_POST_PMD),
5647 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", SND_SOC_NOPM, 7, 0,
5648 taiko_codec_enable_micbias,
5649 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5650 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005651
5652 SND_SOC_DAPM_INPUT("AMIC3"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005653
5654 SND_SOC_DAPM_INPUT("AMIC4"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005655
5656 SND_SOC_DAPM_INPUT("AMIC5"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005657
5658 SND_SOC_DAPM_INPUT("AMIC6"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005659
5660 SND_SOC_DAPM_MUX_E("DEC1 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
5661 &dec1_mux, taiko_codec_enable_dec,
5662 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5663 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5664
5665 SND_SOC_DAPM_MUX_E("DEC2 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
5666 &dec2_mux, taiko_codec_enable_dec,
5667 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5668 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5669
5670 SND_SOC_DAPM_MUX_E("DEC3 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
5671 &dec3_mux, taiko_codec_enable_dec,
5672 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5673 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5674
5675 SND_SOC_DAPM_MUX_E("DEC4 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
5676 &dec4_mux, taiko_codec_enable_dec,
5677 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5678 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5679
5680 SND_SOC_DAPM_MUX_E("DEC5 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
5681 &dec5_mux, taiko_codec_enable_dec,
5682 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5683 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5684
5685 SND_SOC_DAPM_MUX_E("DEC6 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
5686 &dec6_mux, taiko_codec_enable_dec,
5687 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5688 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5689
5690 SND_SOC_DAPM_MUX_E("DEC7 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
5691 &dec7_mux, taiko_codec_enable_dec,
5692 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5693 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5694
5695 SND_SOC_DAPM_MUX_E("DEC8 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
5696 &dec8_mux, taiko_codec_enable_dec,
5697 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5698 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5699
5700 SND_SOC_DAPM_MUX_E("DEC9 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
5701 &dec9_mux, taiko_codec_enable_dec,
5702 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5703 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5704
5705 SND_SOC_DAPM_MUX_E("DEC10 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
5706 &dec10_mux, taiko_codec_enable_dec,
5707 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5708 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5709
5710 SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
5711 SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
5712
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08005713 SND_SOC_DAPM_OUTPUT("ANC HEADPHONE"),
5714 SND_SOC_DAPM_PGA_E("ANC HPHL", SND_SOC_NOPM, 5, 0, NULL, 0,
5715 taiko_codec_enable_anc_hph,
5716 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
5717 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
5718 SND_SOC_DAPM_PGA_E("ANC HPHR", SND_SOC_NOPM, 4, 0, NULL, 0,
5719 taiko_codec_enable_anc_hph, SND_SOC_DAPM_PRE_PMU |
5720 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
5721 SND_SOC_DAPM_POST_PMU),
5722 SND_SOC_DAPM_OUTPUT("ANC EAR"),
5723 SND_SOC_DAPM_PGA_E("ANC EAR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
5724 taiko_codec_enable_anc_ear,
5725 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
5726 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005727 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
5728
5729 SND_SOC_DAPM_INPUT("AMIC2"),
Joonwoo Parkccccba72013-04-26 11:19:46 -07005730 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_EXTERNAL_STANDALONE, SND_SOC_NOPM,
5731 7, 0, taiko_codec_enable_micbias,
5732 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5733 SND_SOC_DAPM_POST_PMD),
Joonwoo Park3699ca32013-02-08 12:06:15 -08005734 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 7, 0,
5735 taiko_codec_enable_micbias,
5736 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5737 SND_SOC_DAPM_POST_PMD),
5738 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 7, 0,
5739 taiko_codec_enable_micbias,
5740 SND_SOC_DAPM_PRE_PMU |
5741 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5742 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 7, 0,
5743 taiko_codec_enable_micbias,
5744 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5745 SND_SOC_DAPM_POST_PMD),
5746 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 7, 0,
5747 taiko_codec_enable_micbias,
5748 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5749 SND_SOC_DAPM_POST_PMD),
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07005750 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_EXTERNAL_STANDALONE, SND_SOC_NOPM,
5751 7, 0, taiko_codec_enable_micbias,
5752 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5753 SND_SOC_DAPM_POST_PMD),
Joonwoo Park3699ca32013-02-08 12:06:15 -08005754 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 7, 0,
5755 taiko_codec_enable_micbias,
5756 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5757 SND_SOC_DAPM_POST_PMD),
5758 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 7, 0,
5759 taiko_codec_enable_micbias,
5760 SND_SOC_DAPM_PRE_PMU |
5761 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5762 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 7, 0,
5763 taiko_codec_enable_micbias,
5764 SND_SOC_DAPM_PRE_PMU |
5765 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5766 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", SND_SOC_NOPM, 7,
5767 0, taiko_codec_enable_micbias,
5768 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5769 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005770
Kuirong Wang906ac472012-07-09 12:54:44 -07005771 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
5772 AIF1_CAP, 0, taiko_codec_enable_slimtx,
5773 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005774
Kuirong Wang906ac472012-07-09 12:54:44 -07005775 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
5776 AIF2_CAP, 0, taiko_codec_enable_slimtx,
5777 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005778
Kuirong Wang906ac472012-07-09 12:54:44 -07005779 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
5780 AIF3_CAP, 0, taiko_codec_enable_slimtx,
5781 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005782
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005783 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
5784 AIF4_VIFEED, 0, taiko_codec_enable_slimvi_feedback,
5785 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005786 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
Joonwoo Park9ead0e92013-03-18 11:33:33 -07005787 SND_SOC_NOPM, 0, 0,
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005788 taiko_codec_enable_mad, SND_SOC_DAPM_PRE_PMU),
Joonwoo Park9ead0e92013-03-18 11:33:33 -07005789 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
5790 &aif4_mad_switch),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005791 SND_SOC_DAPM_INPUT("MADINPUT"),
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005792
Kuirong Wang906ac472012-07-09 12:54:44 -07005793 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
5794 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005795
Kuirong Wang906ac472012-07-09 12:54:44 -07005796 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
5797 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005798
Kuirong Wang906ac472012-07-09 12:54:44 -07005799 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
5800 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005801
Kuirong Wang906ac472012-07-09 12:54:44 -07005802 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TAIKO_TX1, 0,
5803 &sb_tx1_mux),
5804 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TAIKO_TX2, 0,
5805 &sb_tx2_mux),
5806 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TAIKO_TX3, 0,
5807 &sb_tx3_mux),
5808 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TAIKO_TX4, 0,
5809 &sb_tx4_mux),
5810 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TAIKO_TX5, 0,
5811 &sb_tx5_mux),
5812 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TAIKO_TX6, 0,
5813 &sb_tx6_mux),
5814 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TAIKO_TX7, 0,
5815 &sb_tx7_mux),
5816 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TAIKO_TX8, 0,
5817 &sb_tx8_mux),
5818 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TAIKO_TX9, 0,
5819 &sb_tx9_mux),
5820 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TAIKO_TX10, 0,
5821 &sb_tx10_mux),
Kiran Kandic3b24402012-06-11 00:05:59 -07005822
5823 /* Digital Mic Inputs */
5824 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
5825 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5826 SND_SOC_DAPM_POST_PMD),
5827
5828 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
5829 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5830 SND_SOC_DAPM_POST_PMD),
5831
5832 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
5833 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5834 SND_SOC_DAPM_POST_PMD),
5835
5836 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
5837 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5838 SND_SOC_DAPM_POST_PMD),
5839
5840 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
5841 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5842 SND_SOC_DAPM_POST_PMD),
5843 SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
5844 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5845 SND_SOC_DAPM_POST_PMD),
5846
5847 /* Sidetone */
Sudheer Papothi0ef366f2014-01-28 05:56:59 +05305848 SND_SOC_DAPM_MUX_E("IIR1 INP1 MUX", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, 0, 0,
5849 &iir1_inp1_mux, taiko_codec_iir_mux_event,
5850 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5851
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05305852 SND_SOC_DAPM_MUX_E("IIR1 INP2 MUX", TAIKO_A_CDC_IIR1_GAIN_B2_CTL, 0, 0,
5853 &iir1_inp2_mux, taiko_codec_iir_mux_event,
5854 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5855
5856 SND_SOC_DAPM_MUX_E("IIR1 INP3 MUX", TAIKO_A_CDC_IIR1_GAIN_B3_CTL, 0, 0,
5857 &iir1_inp3_mux, taiko_codec_iir_mux_event,
5858 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5859
5860 SND_SOC_DAPM_MUX_E("IIR1 INP4 MUX", TAIKO_A_CDC_IIR1_GAIN_B4_CTL, 0, 0,
5861 &iir1_inp4_mux, taiko_codec_iir_mux_event,
5862 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5863
Kiran Kandibd85d772013-05-19 19:03:43 -07005864 SND_SOC_DAPM_MIXER("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
Kiran Kandic3b24402012-06-11 00:05:59 -07005865
Sudheer Papothi0ef366f2014-01-28 05:56:59 +05305866 SND_SOC_DAPM_MUX_E("IIR2 INP1 MUX", TAIKO_A_CDC_IIR2_GAIN_B1_CTL, 0, 0,
5867 &iir2_inp1_mux, taiko_codec_iir_mux_event,
5868 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5869
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05305870 SND_SOC_DAPM_MUX_E("IIR2 INP2 MUX", TAIKO_A_CDC_IIR2_GAIN_B2_CTL, 0, 0,
5871 &iir2_inp2_mux, taiko_codec_iir_mux_event,
5872 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5873
5874 SND_SOC_DAPM_MUX_E("IIR2 INP3 MUX", TAIKO_A_CDC_IIR2_GAIN_B3_CTL, 0, 0,
5875 &iir2_inp3_mux, taiko_codec_iir_mux_event,
5876 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5877
5878 SND_SOC_DAPM_MUX_E("IIR2 INP4 MUX", TAIKO_A_CDC_IIR2_GAIN_B4_CTL, 0, 0,
5879 &iir2_inp4_mux, taiko_codec_iir_mux_event,
5880 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5881
Kiran Kandibd85d772013-05-19 19:03:43 -07005882 SND_SOC_DAPM_MIXER("IIR2", TAIKO_A_CDC_CLK_SD_CTL, 1, 0, NULL, 0),
Fred Oh456fcb52013-02-28 19:08:15 -08005883
Kiran Kandic3b24402012-06-11 00:05:59 -07005884 /* AUX PGA */
5885 SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TAIKO_A_RX_AUX_SW_CTL, 7, 0,
5886 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
5887 SND_SOC_DAPM_POST_PMD),
5888
5889 SND_SOC_DAPM_ADC_E("AUX_PGA_Right", NULL, TAIKO_A_RX_AUX_SW_CTL, 6, 0,
5890 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
5891 SND_SOC_DAPM_POST_PMD),
5892
5893 /* Lineout, ear and HPH PA Mixers */
5894
5895 SND_SOC_DAPM_MIXER("EAR_PA_MIXER", SND_SOC_NOPM, 0, 0,
5896 ear_pa_mix, ARRAY_SIZE(ear_pa_mix)),
5897
5898 SND_SOC_DAPM_MIXER("HPHL_PA_MIXER", SND_SOC_NOPM, 0, 0,
5899 hphl_pa_mix, ARRAY_SIZE(hphl_pa_mix)),
5900
5901 SND_SOC_DAPM_MIXER("HPHR_PA_MIXER", SND_SOC_NOPM, 0, 0,
5902 hphr_pa_mix, ARRAY_SIZE(hphr_pa_mix)),
5903
5904 SND_SOC_DAPM_MIXER("LINEOUT1_PA_MIXER", SND_SOC_NOPM, 0, 0,
5905 lineout1_pa_mix, ARRAY_SIZE(lineout1_pa_mix)),
5906
5907 SND_SOC_DAPM_MIXER("LINEOUT2_PA_MIXER", SND_SOC_NOPM, 0, 0,
5908 lineout2_pa_mix, ARRAY_SIZE(lineout2_pa_mix)),
5909
5910 SND_SOC_DAPM_MIXER("LINEOUT3_PA_MIXER", SND_SOC_NOPM, 0, 0,
5911 lineout3_pa_mix, ARRAY_SIZE(lineout3_pa_mix)),
5912
5913 SND_SOC_DAPM_MIXER("LINEOUT4_PA_MIXER", SND_SOC_NOPM, 0, 0,
5914 lineout4_pa_mix, ARRAY_SIZE(lineout4_pa_mix)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005915};
5916
Kiran Kandic3b24402012-06-11 00:05:59 -07005917static irqreturn_t taiko_slimbus_irq(int irq, void *data)
5918{
5919 struct taiko_priv *priv = data;
5920 struct snd_soc_codec *codec = priv->codec;
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005921 unsigned long status = 0;
5922 int i, j, port_id, k;
5923 u32 bit;
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005924 u8 val, int_val = 0;
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005925 bool tx, cleared;
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005926 unsigned short reg = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07005927
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005928 for (i = TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
5929 i <= TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
5930 val = wcd9xxx_interface_reg_read(codec->control_data, i);
5931 status |= ((u32)val << (8 * j));
5932 }
5933
5934 for_each_set_bit(j, &status, 32) {
5935 tx = (j >= 16 ? true : false);
5936 port_id = (tx ? j - 16 : j);
5937 val = wcd9xxx_interface_reg_read(codec->control_data,
5938 TAIKO_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
5939 if (val & TAIKO_SLIM_IRQ_OVERFLOW)
5940 pr_err_ratelimited(
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005941 "%s: overflow error on %s port %d, value %x\n",
5942 __func__, (tx ? "TX" : "RX"), port_id, val);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005943 if (val & TAIKO_SLIM_IRQ_UNDERFLOW)
5944 pr_err_ratelimited(
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005945 "%s: underflow error on %s port %d, value %x\n",
5946 __func__, (tx ? "TX" : "RX"), port_id, val);
5947 if ((val & TAIKO_SLIM_IRQ_OVERFLOW) ||
5948 (val & TAIKO_SLIM_IRQ_UNDERFLOW)) {
5949 if (!tx)
5950 reg = TAIKO_SLIM_PGD_PORT_INT_EN0 +
5951 (port_id / 8);
5952 else
5953 reg = TAIKO_SLIM_PGD_PORT_INT_TX_EN0 +
5954 (port_id / 8);
5955 int_val = wcd9xxx_interface_reg_read(
5956 codec->control_data, reg);
5957 if (int_val & (1 << (port_id % 8))) {
5958 int_val = int_val ^ (1 << (port_id % 8));
5959 wcd9xxx_interface_reg_write(codec->control_data,
5960 reg, int_val);
5961 }
5962 }
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005963 if (val & TAIKO_SLIM_IRQ_PORT_CLOSED) {
5964 /*
5965 * INT SOURCE register starts from RX to TX
5966 * but port number in the ch_mask is in opposite way
5967 */
5968 bit = (tx ? j - 16 : j + 16);
5969 pr_debug("%s: %s port %d closed value %x, bit %u\n",
5970 __func__, (tx ? "TX" : "RX"), port_id, val,
5971 bit);
5972 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
5973 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
5974 __func__, k, priv->dai[k].ch_mask);
5975 if (test_and_clear_bit(bit,
5976 &priv->dai[k].ch_mask)) {
5977 cleared = true;
5978 if (!priv->dai[k].ch_mask)
5979 wake_up(&priv->dai[k].dai_wait);
5980 /*
5981 * There are cases when multiple DAIs
5982 * might be using the same slimbus
5983 * channel. Hence don't break here.
5984 */
5985 }
5986 }
5987 WARN(!cleared,
5988 "Couldn't find slimbus %s port %d for closing\n",
5989 (tx ? "TX" : "RX"), port_id);
Kiran Kandic3b24402012-06-11 00:05:59 -07005990 }
5991 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005992 TAIKO_SLIM_PGD_PORT_INT_CLR_RX_0 +
5993 (j / 8),
5994 1 << (j % 8));
Joonwoo Parka8890262012-10-15 12:04:27 -07005995 }
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005996
Kiran Kandic3b24402012-06-11 00:05:59 -07005997 return IRQ_HANDLED;
5998}
5999
6000static int taiko_handle_pdata(struct taiko_priv *taiko)
6001{
6002 struct snd_soc_codec *codec = taiko->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07006003 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
Kiran Kandic3b24402012-06-11 00:05:59 -07006004 int k1, k2, k3, rc = 0;
Kiran Kandi725f8492012-08-06 13:45:16 -07006005 u8 leg_mode, txfe_bypass, txfe_buff, flag;
Kiran Kandic3b24402012-06-11 00:05:59 -07006006 u8 i = 0, j = 0;
6007 u8 val_txfe = 0, value = 0;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006008 u8 dmic_sample_rate_value = 0;
6009 u8 dmic_b1_ctl_value = 0, dmic_b2_ctl_value = 0;
6010 u8 anc_ctl_value = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07006011
6012 if (!pdata) {
Kiran Kandi725f8492012-08-06 13:45:16 -07006013 pr_err("%s: NULL pdata\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07006014 rc = -ENODEV;
6015 goto done;
6016 }
6017
Kiran Kandi725f8492012-08-06 13:45:16 -07006018 leg_mode = pdata->amic_settings.legacy_mode;
6019 txfe_bypass = pdata->amic_settings.txfe_enable;
6020 txfe_buff = pdata->amic_settings.txfe_buff;
6021 flag = pdata->amic_settings.use_pdata;
6022
Kiran Kandic3b24402012-06-11 00:05:59 -07006023 /* Make sure settings are correct */
Joonwoo Parka8890262012-10-15 12:04:27 -07006024 if ((pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V) ||
6025 (pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
6026 (pdata->micbias.bias2_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
6027 (pdata->micbias.bias3_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
6028 (pdata->micbias.bias4_cfilt_sel > WCD9XXX_CFILT3_SEL)) {
Kiran Kandic3b24402012-06-11 00:05:59 -07006029 rc = -EINVAL;
6030 goto done;
6031 }
Kiran Kandic3b24402012-06-11 00:05:59 -07006032 /* figure out k value */
Joonwoo Parka8890262012-10-15 12:04:27 -07006033 k1 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt1_mv);
6034 k2 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt2_mv);
6035 k3 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt3_mv);
Kiran Kandic3b24402012-06-11 00:05:59 -07006036
6037 if (IS_ERR_VALUE(k1) || IS_ERR_VALUE(k2) || IS_ERR_VALUE(k3)) {
6038 rc = -EINVAL;
6039 goto done;
6040 }
Kiran Kandic3b24402012-06-11 00:05:59 -07006041 /* Set voltage level and always use LDO */
6042 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 0x0C,
Joonwoo Parka8890262012-10-15 12:04:27 -07006043 (pdata->micbias.ldoh_v << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07006044
Joonwoo Parka8890262012-10-15 12:04:27 -07006045 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_1_VAL, 0xFC, (k1 << 2));
6046 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_2_VAL, 0xFC, (k2 << 2));
6047 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_3_VAL, 0xFC, (k3 << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07006048
6049 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07006050 (pdata->micbias.bias1_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07006051 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07006052 (pdata->micbias.bias2_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07006053 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07006054 (pdata->micbias.bias3_cfilt_sel << 5));
6055 snd_soc_update_bits(codec, taiko->resmgr.reg_addr->micb_4_ctl, 0x60,
Kiran Kandic3b24402012-06-11 00:05:59 -07006056 (pdata->micbias.bias4_cfilt_sel << 5));
6057
6058 for (i = 0; i < 6; j++, i += 2) {
6059 if (flag & (0x01 << i)) {
6060 value = (leg_mode & (0x01 << i)) ? 0x10 : 0x00;
6061 val_txfe = (txfe_bypass & (0x01 << i)) ? 0x20 : 0x00;
6062 val_txfe = val_txfe |
6063 ((txfe_buff & (0x01 << i)) ? 0x10 : 0x00);
6064 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
6065 0x10, value);
6066 snd_soc_update_bits(codec,
6067 TAIKO_A_TX_1_2_TEST_EN + j * 10,
6068 0x30, val_txfe);
6069 }
6070 if (flag & (0x01 << (i + 1))) {
6071 value = (leg_mode & (0x01 << (i + 1))) ? 0x01 : 0x00;
6072 val_txfe = (txfe_bypass &
6073 (0x01 << (i + 1))) ? 0x02 : 0x00;
6074 val_txfe |= (txfe_buff &
6075 (0x01 << (i + 1))) ? 0x01 : 0x00;
6076 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
6077 0x01, value);
6078 snd_soc_update_bits(codec,
6079 TAIKO_A_TX_1_2_TEST_EN + j * 10,
6080 0x03, val_txfe);
6081 }
6082 }
6083 if (flag & 0x40) {
6084 value = (leg_mode & 0x40) ? 0x10 : 0x00;
6085 value = value | ((txfe_bypass & 0x40) ? 0x02 : 0x00);
6086 value = value | ((txfe_buff & 0x40) ? 0x01 : 0x00);
6087 snd_soc_update_bits(codec, TAIKO_A_TX_7_MBHC_EN,
6088 0x13, value);
6089 }
6090
6091 if (pdata->ocp.use_pdata) {
6092 /* not defined in CODEC specification */
6093 if (pdata->ocp.hph_ocp_limit == 1 ||
6094 pdata->ocp.hph_ocp_limit == 5) {
6095 rc = -EINVAL;
6096 goto done;
6097 }
6098 snd_soc_update_bits(codec, TAIKO_A_RX_COM_OCP_CTL,
6099 0x0F, pdata->ocp.num_attempts);
6100 snd_soc_write(codec, TAIKO_A_RX_COM_OCP_COUNT,
6101 ((pdata->ocp.run_time << 4) | pdata->ocp.wait_time));
6102 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_OCP_CTL,
6103 0xE0, (pdata->ocp.hph_ocp_limit << 5));
6104 }
6105
6106 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
Joonwoo Park448a8fc2013-04-10 15:25:58 -07006107 if (pdata->regulator[i].name &&
6108 !strncmp(pdata->regulator[i].name, "CDC_VDDA_RX", 11)) {
Kiran Kandic3b24402012-06-11 00:05:59 -07006109 if (pdata->regulator[i].min_uV == 1800000 &&
6110 pdata->regulator[i].max_uV == 1800000) {
6111 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
6112 0x1C);
6113 } else if (pdata->regulator[i].min_uV == 2200000 &&
6114 pdata->regulator[i].max_uV == 2200000) {
6115 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
6116 0x1E);
6117 } else {
6118 pr_err("%s: unsupported CDC_VDDA_RX voltage\n"
6119 "min %d, max %d\n", __func__,
6120 pdata->regulator[i].min_uV,
6121 pdata->regulator[i].max_uV);
6122 rc = -EINVAL;
6123 }
6124 break;
6125 }
6126 }
Kiran Kandi4c56c592012-07-25 11:04:55 -07006127
Joonwoo Park1848c762012-10-18 13:16:01 -07006128 /* Set micbias capless mode with tail current */
6129 value = (pdata->micbias.bias1_cap_mode == MICBIAS_EXT_BYP_CAP ?
6130 0x00 : 0x16);
6131 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x1E, value);
6132 value = (pdata->micbias.bias2_cap_mode == MICBIAS_EXT_BYP_CAP ?
6133 0x00 : 0x16);
6134 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x1E, value);
6135 value = (pdata->micbias.bias3_cap_mode == MICBIAS_EXT_BYP_CAP ?
6136 0x00 : 0x16);
6137 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x1E, value);
6138 value = (pdata->micbias.bias4_cap_mode == MICBIAS_EXT_BYP_CAP ?
6139 0x00 : 0x16);
6140 snd_soc_update_bits(codec, TAIKO_A_MICB_4_CTL, 0x1E, value);
6141
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006142 /* Set the DMIC sample rate */
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07006143 if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6MHZ) {
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006144 switch (pdata->dmic_sample_rate) {
Damir Didjusto5f553e92013-10-02 14:54:31 -07006145 case WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ:
6146 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
6147 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
6148 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_4;
6149 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006150 break;
Damir Didjusto5f553e92013-10-02 14:54:31 -07006151 case WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ:
6152 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
6153 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
6154 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_2;
6155 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006156 break;
Damir Didjusto5f553e92013-10-02 14:54:31 -07006157 case WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ:
6158 case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
6159 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
6160 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
6161 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_3;
6162 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006163 break;
6164 default:
6165 pr_err("%s Invalid sample rate %d for mclk %d\n",
6166 __func__, pdata->dmic_sample_rate, pdata->mclk_rate);
6167 rc = -EINVAL;
6168 goto done;
6169 break;
6170 }
6171 } else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
6172 switch (pdata->dmic_sample_rate) {
Damir Didjusto5f553e92013-10-02 14:54:31 -07006173 case WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ:
6174 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
6175 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
6176 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_4;
6177 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006178 break;
Damir Didjusto5f553e92013-10-02 14:54:31 -07006179 case WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ:
6180 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
6181 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
6182 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_2;
6183 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006184 break;
Damir Didjusto5f553e92013-10-02 14:54:31 -07006185 case WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ:
6186 case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
6187 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
6188 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
6189 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_3;
6190 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006191 break;
6192 default:
6193 pr_err("%s Invalid sample rate %d for mclk %d\n",
6194 __func__, pdata->dmic_sample_rate, pdata->mclk_rate);
6195 rc = -EINVAL;
6196 goto done;
6197 break;
6198 }
6199 } else {
6200 pr_err("%s MCLK is not set!\n", __func__);
6201 rc = -EINVAL;
6202 goto done;
6203 }
6204
6205 snd_soc_update_bits(codec, TAIKO_A_CDC_TX1_DMIC_CTL,
6206 0x7, dmic_sample_rate_value);
6207 snd_soc_update_bits(codec, TAIKO_A_CDC_TX2_DMIC_CTL,
6208 0x7, dmic_sample_rate_value);
6209 snd_soc_update_bits(codec, TAIKO_A_CDC_TX3_DMIC_CTL,
6210 0x7, dmic_sample_rate_value);
6211 snd_soc_update_bits(codec, TAIKO_A_CDC_TX4_DMIC_CTL,
6212 0x7, dmic_sample_rate_value);
6213 snd_soc_update_bits(codec, TAIKO_A_CDC_TX5_DMIC_CTL,
6214 0x7, dmic_sample_rate_value);
6215 snd_soc_update_bits(codec, TAIKO_A_CDC_TX6_DMIC_CTL,
6216 0x7, dmic_sample_rate_value);
6217 snd_soc_update_bits(codec, TAIKO_A_CDC_TX7_DMIC_CTL,
6218 0x7, dmic_sample_rate_value);
6219 snd_soc_update_bits(codec, TAIKO_A_CDC_TX8_DMIC_CTL,
6220 0x7, dmic_sample_rate_value);
6221 snd_soc_update_bits(codec, TAIKO_A_CDC_TX9_DMIC_CTL,
6222 0x7, dmic_sample_rate_value);
6223 snd_soc_update_bits(codec, TAIKO_A_CDC_TX10_DMIC_CTL,
6224 0x7, dmic_sample_rate_value);
6225 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_DMIC_B1_CTL,
6226 0xEE, dmic_b1_ctl_value);
6227 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_DMIC_B2_CTL,
6228 0xE, dmic_b2_ctl_value);
6229 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B2_CTL,
6230 0x1, anc_ctl_value);
6231
Kiran Kandic3b24402012-06-11 00:05:59 -07006232done:
6233 return rc;
6234}
6235
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006236static const struct wcd9xxx_reg_mask_val taiko_reg_defaults[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07006237
Kiran Kandi4c56c592012-07-25 11:04:55 -07006238 /* set MCLk to 9.6 */
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05006239 TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x02),
Kiran Kandi4c56c592012-07-25 11:04:55 -07006240 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_POWER_CTL, 0x03),
Kiran Kandic3b24402012-06-11 00:05:59 -07006241
Kiran Kandi4c56c592012-07-25 11:04:55 -07006242 /* EAR PA deafults */
6243 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CMBUFF, 0x05),
Kiran Kandic3b24402012-06-11 00:05:59 -07006244
Kiran Kandi4c56c592012-07-25 11:04:55 -07006245 /* RX deafults */
Kiran Kandic3b24402012-06-11 00:05:59 -07006246 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B5_CTL, 0x78),
6247 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B5_CTL, 0x78),
6248 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B5_CTL, 0x78),
6249 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B5_CTL, 0x78),
6250 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B5_CTL, 0x78),
6251 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B5_CTL, 0x78),
6252 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B5_CTL, 0x78),
6253
Kiran Kandi4c56c592012-07-25 11:04:55 -07006254 /* RX1 and RX2 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07006255 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B6_CTL, 0xA0),
6256 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B6_CTL, 0xA0),
6257
Kiran Kandi4c56c592012-07-25 11:04:55 -07006258 /* RX3 to RX7 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07006259 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B6_CTL, 0x80),
6260 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B6_CTL, 0x80),
6261 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B6_CTL, 0x80),
6262 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B6_CTL, 0x80),
6263 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006264
6265 /* MAD registers */
6266 TAIKO_REG_VAL(TAIKO_A_MAD_ANA_CTRL, 0xF1),
6267 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_MAIN_CTL_1, 0x00),
6268 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_MAIN_CTL_2, 0x00),
6269 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_1, 0x00),
6270 /* Set SAMPLE_TX_EN bit */
6271 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_2, 0x03),
6272 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_3, 0x00),
6273 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_4, 0x00),
6274 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_5, 0x00),
6275 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_6, 0x00),
6276 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_7, 0x00),
6277 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_8, 0x00),
6278 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_PTR, 0x00),
6279 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_VAL, 0x40),
6280 TAIKO_REG_VAL(TAIKO_A_CDC_DEBUG_B7_CTL, 0x00),
6281 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL, 0x00),
6282 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_CTL, 0x00),
6283 TAIKO_REG_VAL(TAIKO_A_CDC_CONN_MAD, 0x01),
Bhalchandra Gajareafdb1b12013-06-10 13:45:28 -07006284
6285 /* Set HPH Path to low power mode */
6286 TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x55),
Joonwoo Park58d4a162013-07-23 16:19:37 -07006287
6288 /* BUCK default */
6289 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x51),
6290 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
Kiran Kandic3b24402012-06-11 00:05:59 -07006291};
6292
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006293static const struct wcd9xxx_reg_mask_val taiko_1_0_reg_defaults[] = {
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006294 /*
6295 * The following only need to be written for Taiko 1.0 parts.
6296 * Taiko 2.0 will have appropriate defaults for these registers.
6297 */
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006298
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006299 /* Required defaults for class H operation */
6300 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xF4),
6301 TAIKO_REG_VAL(TAIKO_A_BIAS_CURR_CTL_2, 0x08),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006302 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_3, 0x60),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006303
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006304 /* Choose max non-overlap time for NCP */
6305 TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
6306 /* Use 25mV/50mV for deltap/m to reduce ripple */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006307 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x08),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006308 /*
6309 * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
6310 * Note that the other bits of this register will be changed during
6311 * Rx PA bring up.
6312 */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006313 TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006314 /*Reduce EAR DAC bias to 70% */
6315 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
6316 /* Reduce LINE DAC bias to 70% */
6317 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
Joonwoo Parkd87ec4c2012-10-30 15:44:18 -07006318
6319 /*
6320 * There is a diode to pull down the micbias while doing
6321 * insertion detection. This diode can cause leakage.
6322 * Set bit 0 to 1 to prevent leakage.
6323 * Setting this bit of micbias 2 prevents leakage for all other micbias.
6324 */
6325 TAIKO_REG_VAL(TAIKO_A_MICB_2_MBHC, 0x41),
Joonwoo Park3c7bca62012-10-31 12:44:23 -07006326
6327 /* Disable TX7 internal biasing path which can cause leakage */
6328 TAIKO_REG_VAL(TAIKO_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
Joonwoo Park03604052012-11-06 18:40:25 -08006329 /* Enable MICB 4 VDDIO switch to prevent leakage */
6330 TAIKO_REG_VAL(TAIKO_A_MICB_4_MBHC, 0x81),
Joonwoo Park125cd4e2012-12-11 15:16:11 -08006331
6332 /* Close leakage on the spkdrv */
6333 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_DBG_PWRSTG, 0x24),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006334};
6335
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006336/*
6337 * Don't update TAIKO_A_CHIP_CTL, TAIKO_A_BUCK_CTRL_CCL_1 and
6338 * TAIKO_A_RX_EAR_CMBUFF as those are updated in taiko_reg_defaults
6339 */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006340static const struct wcd9xxx_reg_mask_val taiko_2_0_reg_defaults[] = {
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006341 TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_GAIN, 0x2),
6342 TAIKO_REG_VAL(TAIKO_A_CDC_TX_2_GAIN, 0x2),
6343 TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_2_ADC_IB, 0x44),
6344 TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_GAIN, 0x2),
6345 TAIKO_REG_VAL(TAIKO_A_CDC_TX_4_GAIN, 0x2),
6346 TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_4_ADC_IB, 0x44),
6347 TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_GAIN, 0x2),
6348 TAIKO_REG_VAL(TAIKO_A_CDC_TX_6_GAIN, 0x2),
6349 TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_6_ADC_IB, 0x44),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006350 TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
6351 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x8),
Joonwoo Parkd535b8a2013-08-01 18:44:56 -07006352 TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_4, 0x51),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006353 TAIKO_REG_VAL(TAIKO_A_NCP_DTEST, 0x10),
6354 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xA4),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006355 TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x69),
6356 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_CTL, 0xDA),
6357 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_TIME, 0x15),
6358 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
6359 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CNP, 0xC0),
6360 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
6361 TAIKO_REG_VAL(TAIKO_A_RX_LINE_1_TEST, 0x2),
6362 TAIKO_REG_VAL(TAIKO_A_RX_LINE_2_TEST, 0x2),
6363 TAIKO_REG_VAL(TAIKO_A_RX_LINE_3_TEST, 0x2),
6364 TAIKO_REG_VAL(TAIKO_A_RX_LINE_4_TEST, 0x2),
6365 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_OCP_CTL, 0x97),
6366 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_CLIP_DET, 0x1),
6367 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_IEC, 0x0),
6368 TAIKO_REG_VAL(TAIKO_A_CDC_TX1_MUX_CTL, 0x48),
6369 TAIKO_REG_VAL(TAIKO_A_CDC_TX2_MUX_CTL, 0x48),
6370 TAIKO_REG_VAL(TAIKO_A_CDC_TX3_MUX_CTL, 0x48),
6371 TAIKO_REG_VAL(TAIKO_A_CDC_TX4_MUX_CTL, 0x48),
6372 TAIKO_REG_VAL(TAIKO_A_CDC_TX5_MUX_CTL, 0x48),
6373 TAIKO_REG_VAL(TAIKO_A_CDC_TX6_MUX_CTL, 0x48),
6374 TAIKO_REG_VAL(TAIKO_A_CDC_TX7_MUX_CTL, 0x48),
6375 TAIKO_REG_VAL(TAIKO_A_CDC_TX8_MUX_CTL, 0x48),
6376 TAIKO_REG_VAL(TAIKO_A_CDC_TX9_MUX_CTL, 0x48),
6377 TAIKO_REG_VAL(TAIKO_A_CDC_TX10_MUX_CTL, 0x48),
6378 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B4_CTL, 0x8),
Joonwoo Parkdbbdac02013-03-21 19:24:31 -07006379 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B4_CTL, 0x8),
6380 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B4_CTL, 0x8),
6381 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B4_CTL, 0x8),
6382 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B4_CTL, 0x8),
6383 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B4_CTL, 0x8),
6384 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B4_CTL, 0x8),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006385 TAIKO_REG_VAL(TAIKO_A_CDC_VBAT_GAIN_UPD_MON, 0x0),
6386 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B1_CTL, 0x0),
6387 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B2_CTL, 0x0),
6388 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B3_CTL, 0x0),
6389 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B4_CTL, 0x0),
6390 TAIKO_REG_VAL(TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL, 0x0),
6391 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B4_CTL, 0x37),
6392 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
Joonwoo Park58d4a162013-07-23 16:19:37 -07006393 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006394};
6395
Kiran Kandic3b24402012-06-11 00:05:59 -07006396static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
6397{
6398 u32 i;
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006399 struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07006400
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006401 for (i = 0; i < ARRAY_SIZE(taiko_reg_defaults); i++)
6402 snd_soc_write(codec, taiko_reg_defaults[i].reg,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006403 taiko_reg_defaults[i].val);
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006404
6405 if (TAIKO_IS_1_0(taiko_core->version)) {
6406 for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
6407 snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006408 taiko_1_0_reg_defaults[i].val);
6409 if (spkr_drv_wrnd == 1)
6410 snd_soc_write(codec, TAIKO_A_SPKR_DRV_EN, 0xEF);
6411 } else {
6412 for (i = 0; i < ARRAY_SIZE(taiko_2_0_reg_defaults); i++)
6413 snd_soc_write(codec, taiko_2_0_reg_defaults[i].reg,
6414 taiko_2_0_reg_defaults[i].val);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08006415 spkr_drv_wrnd = -1;
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006416 }
Kiran Kandic3b24402012-06-11 00:05:59 -07006417}
6418
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006419static const struct wcd9xxx_reg_mask_val taiko_codec_reg_init_val[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07006420 /* Initialize current threshold to 350MA
6421 * number of wait and run cycles to 4096
6422 */
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006423 {TAIKO_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
Kiran Kandic3b24402012-06-11 00:05:59 -07006424 {TAIKO_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
Patrick Lai92833bf2012-12-01 10:31:35 -08006425 {TAIKO_A_RX_HPH_L_TEST, 0x01, 0x01},
6426 {TAIKO_A_RX_HPH_R_TEST, 0x01, 0x01},
Kiran Kandic3b24402012-06-11 00:05:59 -07006427
Kiran Kandic3b24402012-06-11 00:05:59 -07006428 /* Initialize gain registers to use register gain */
Kiran Kandi4c56c592012-07-25 11:04:55 -07006429 {TAIKO_A_RX_HPH_L_GAIN, 0x20, 0x20},
6430 {TAIKO_A_RX_HPH_R_GAIN, 0x20, 0x20},
6431 {TAIKO_A_RX_LINE_1_GAIN, 0x20, 0x20},
6432 {TAIKO_A_RX_LINE_2_GAIN, 0x20, 0x20},
6433 {TAIKO_A_RX_LINE_3_GAIN, 0x20, 0x20},
6434 {TAIKO_A_RX_LINE_4_GAIN, 0x20, 0x20},
Joonwoo Parkc7731432012-10-17 12:41:44 -07006435 {TAIKO_A_SPKR_DRV_GAIN, 0x04, 0x04},
Kiran Kandic3b24402012-06-11 00:05:59 -07006436
Kiran Kandic3b24402012-06-11 00:05:59 -07006437 /* Use 16 bit sample size for TX1 to TX6 */
6438 {TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0x30, 0x20},
6439 {TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0x30, 0x20},
6440 {TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0x30, 0x20},
6441 {TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0x30, 0x20},
6442 {TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0x30, 0x20},
6443 {TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0x30, 0x20},
6444
6445 /* Use 16 bit sample size for TX7 to TX10 */
6446 {TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0x60, 0x40},
6447 {TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0x60, 0x40},
6448 {TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x60, 0x40},
6449 {TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x60, 0x40},
6450
Kiran Kandic3b24402012-06-11 00:05:59 -07006451 /*enable HPF filter for TX paths */
6452 {TAIKO_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
6453 {TAIKO_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
6454 {TAIKO_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
6455 {TAIKO_A_CDC_TX4_MUX_CTL, 0x8, 0x0},
6456 {TAIKO_A_CDC_TX5_MUX_CTL, 0x8, 0x0},
6457 {TAIKO_A_CDC_TX6_MUX_CTL, 0x8, 0x0},
6458 {TAIKO_A_CDC_TX7_MUX_CTL, 0x8, 0x0},
6459 {TAIKO_A_CDC_TX8_MUX_CTL, 0x8, 0x0},
6460 {TAIKO_A_CDC_TX9_MUX_CTL, 0x8, 0x0},
6461 {TAIKO_A_CDC_TX10_MUX_CTL, 0x8, 0x0},
6462
Joonwoo Parkc7731432012-10-17 12:41:44 -07006463 /* Compander zone selection */
6464 {TAIKO_A_CDC_COMP0_B4_CTL, 0x3F, 0x37},
6465 {TAIKO_A_CDC_COMP1_B4_CTL, 0x3F, 0x37},
6466 {TAIKO_A_CDC_COMP2_B4_CTL, 0x3F, 0x37},
6467 {TAIKO_A_CDC_COMP0_B5_CTL, 0x7F, 0x7F},
6468 {TAIKO_A_CDC_COMP1_B5_CTL, 0x7F, 0x7F},
6469 {TAIKO_A_CDC_COMP2_B5_CTL, 0x7F, 0x7F},
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07006470
6471 /*
6472 * Setup wavegen timer to 20msec and disable chopper
6473 * as default. This corresponds to Compander OFF
6474 */
6475 {TAIKO_A_RX_HPH_CNP_WG_CTL, 0xFF, 0xDB},
6476 {TAIKO_A_RX_HPH_CNP_WG_TIME, 0xFF, 0x58},
6477 {TAIKO_A_RX_HPH_BIAS_WG_OCP, 0xFF, 0x1A},
6478 {TAIKO_A_RX_HPH_CHOP_CTL, 0xFF, 0x24},
Bhalchandra Gajare9581aed2013-03-29 17:06:10 -07006479
6480 /* Choose max non-overlap time for NCP */
6481 {TAIKO_A_NCP_CLK, 0xFF, 0xFC},
6482
6483 /* Program the 0.85 volt VBG_REFERENCE */
6484 {TAIKO_A_BIAS_CURR_CTL_2, 0xFF, 0x04},
Kiran Kandiddbeaa32013-10-06 14:40:11 -07006485
6486 /* set MAD input MIC to DMIC1 */
6487 {TAIKO_A_CDC_CONN_MAD, 0x0F, 0x08},
Kiran Kandic3b24402012-06-11 00:05:59 -07006488};
6489
6490static void taiko_codec_init_reg(struct snd_soc_codec *codec)
6491{
6492 u32 i;
6493
6494 for (i = 0; i < ARRAY_SIZE(taiko_codec_reg_init_val); i++)
6495 snd_soc_update_bits(codec, taiko_codec_reg_init_val[i].reg,
6496 taiko_codec_reg_init_val[i].mask,
6497 taiko_codec_reg_init_val[i].val);
6498}
6499
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006500static void taiko_slim_interface_init_reg(struct snd_soc_codec *codec)
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006501{
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006502 int i;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006503
6504 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
6505 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Parka8890262012-10-15 12:04:27 -07006506 TAIKO_SLIM_PGD_PORT_INT_EN0 + i,
6507 0xFF);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006508}
6509
6510static int taiko_setup_irqs(struct taiko_priv *taiko)
6511{
6512 int ret = 0;
6513 struct snd_soc_codec *codec = taiko->codec;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006514 struct wcd9xxx *wcd9xxx = codec->control_data;
6515 struct wcd9xxx_core_resource *core_res =
6516 &wcd9xxx->core_res;
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006517
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006518 ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS,
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006519 taiko_slimbus_irq, "SLIMBUS Slave", taiko);
6520 if (ret)
6521 pr_err("%s: Failed to request irq %d\n", __func__,
6522 WCD9XXX_IRQ_SLIMBUS);
6523 else
6524 taiko_slim_interface_init_reg(codec);
6525
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006526 return ret;
6527}
6528
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006529static void taiko_cleanup_irqs(struct taiko_priv *taiko)
6530{
6531 struct snd_soc_codec *codec = taiko->codec;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006532 struct wcd9xxx *wcd9xxx = codec->control_data;
6533 struct wcd9xxx_core_resource *core_res =
6534 &wcd9xxx->core_res;
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006535
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006536 wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, taiko);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006537}
6538
Joonwoo Parka8890262012-10-15 12:04:27 -07006539int taiko_hs_detect(struct snd_soc_codec *codec,
6540 struct wcd9xxx_mbhc_config *mbhc_cfg)
6541{
Joonwoo Park88bfa842013-04-15 16:59:21 -07006542 int rc;
Joonwoo Parka8890262012-10-15 12:04:27 -07006543 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Park88bfa842013-04-15 16:59:21 -07006544 rc = wcd9xxx_mbhc_start(&taiko->mbhc, mbhc_cfg);
6545 if (!rc)
6546 taiko->mbhc_started = true;
6547 return rc;
Joonwoo Parka8890262012-10-15 12:04:27 -07006548}
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006549EXPORT_SYMBOL(taiko_hs_detect);
Joonwoo Parka8890262012-10-15 12:04:27 -07006550
Joonwoo Parke7d724e2013-08-19 15:51:01 -07006551void taiko_hs_detect_exit(struct snd_soc_codec *codec)
6552{
6553 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
6554 wcd9xxx_mbhc_stop(&taiko->mbhc);
6555 taiko->mbhc_started = false;
6556}
6557EXPORT_SYMBOL(taiko_hs_detect_exit);
6558
Kiran Kandia1bed422013-05-28 18:29:12 -07006559void taiko_event_register(
6560 int (*machine_event_cb)(struct snd_soc_codec *codec,
6561 enum wcd9xxx_codec_event),
6562 struct snd_soc_codec *codec)
6563{
6564 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
6565 taiko->machine_codec_event_cb = machine_event_cb;
6566}
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006567EXPORT_SYMBOL(taiko_event_register);
Kiran Kandia1bed422013-05-28 18:29:12 -07006568
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006569static void taiko_init_slim_slave_cfg(struct snd_soc_codec *codec)
6570{
6571 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
6572 struct afe_param_cdc_slimbus_slave_cfg *cfg;
6573 struct wcd9xxx *wcd9xxx = codec->control_data;
6574 uint64_t eaddr = 0;
6575
6576 cfg = &priv->slimbus_slave_cfg;
6577 cfg->minor_version = 1;
6578 cfg->tx_slave_port_offset = 0;
6579 cfg->rx_slave_port_offset = 16;
6580
6581 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
6582 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
6583 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
6584 cfg->device_enum_addr_msw = eaddr >> 32;
6585
6586 pr_debug("%s: slimbus logical address 0x%llx\n", __func__, eaddr);
6587}
6588
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006589static int taiko_device_down(struct wcd9xxx *wcd9xxx)
6590{
6591 struct snd_soc_codec *codec;
6592
6593 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
6594 snd_soc_card_change_online_state(codec->card, 0);
6595
6596 return 0;
6597}
6598
Phani Kumar Uppalapati01a77e12013-08-08 15:31:35 -07006599static int wcd9xxx_prepare_static_pa(struct wcd9xxx_mbhc *mbhc,
6600 struct list_head *lh)
6601{
6602 int i;
6603 struct snd_soc_codec *codec = mbhc->codec;
6604
6605 const struct wcd9xxx_reg_mask_val reg_set_paon[] = {
6606 {WCD9XXX_A_RX_HPH_OCP_CTL, 0x18, 0x00},
6607 {WCD9XXX_A_RX_HPH_L_TEST, 0x1, 0x0},
6608 {WCD9XXX_A_RX_HPH_R_TEST, 0x1, 0x0},
6609 {WCD9XXX_A_RX_HPH_BIAS_WG_OCP, 0xff, 0x1A},
6610 {WCD9XXX_A_RX_HPH_CNP_WG_CTL, 0xff, 0xDB},
6611 {WCD9XXX_A_RX_HPH_CNP_WG_TIME, 0xff, 0x15},
6612 {WCD9XXX_A_CDC_RX1_B6_CTL, 0xff, 0x81},
6613 {WCD9XXX_A_CDC_CLK_RX_B1_CTL, 0x01, 0x01},
6614 {WCD9XXX_A_RX_HPH_CHOP_CTL, 0xff, 0xA4},
6615 {WCD9XXX_A_RX_HPH_L_GAIN, 0xff, 0x2C},
6616 {WCD9XXX_A_CDC_RX2_B6_CTL, 0xff, 0x81},
6617 {WCD9XXX_A_CDC_CLK_RX_B1_CTL, 0x02, 0x02},
6618 {WCD9XXX_A_RX_HPH_R_GAIN, 0xff, 0x2C},
6619 {WCD9XXX_A_NCP_CLK, 0xff, 0xFC},
6620 {WCD9XXX_A_BUCK_CTRL_CCL_3, 0xff, 0x60},
6621 {WCD9XXX_A_RX_COM_BIAS, 0xff, 0x80},
6622 {WCD9XXX_A_BUCK_MODE_3, 0xff, 0xC6},
6623 {WCD9XXX_A_BUCK_MODE_4, 0xff, 0xE6},
6624 {WCD9XXX_A_BUCK_MODE_5, 0xff, 0x02},
6625 {WCD9XXX_A_BUCK_MODE_1, 0xff, 0xA1},
6626 {WCD9XXX_A_NCP_EN, 0xff, 0xFF},
6627 {WCD9XXX_A_BUCK_MODE_5, 0xff, 0x7B},
6628 {WCD9XXX_A_CDC_CLSH_B1_CTL, 0xff, 0xE6},
6629 {WCD9XXX_A_RX_HPH_L_DAC_CTL, 0xff, 0xC0},
6630 {WCD9XXX_A_RX_HPH_R_DAC_CTL, 0xff, 0xC0},
6631 };
6632
6633 for (i = 0; i < ARRAY_SIZE(reg_set_paon); i++)
6634 wcd9xxx_soc_update_bits_push(codec, lh,
6635 reg_set_paon[i].reg,
6636 reg_set_paon[i].mask,
6637 reg_set_paon[i].val, 0);
6638 pr_debug("%s: PAs are prepared\n", __func__);
6639
6640 return 0;
6641}
6642
6643static int wcd9xxx_enable_static_pa(struct wcd9xxx_mbhc *mbhc, bool enable)
6644{
6645 struct snd_soc_codec *codec = mbhc->codec;
6646 const int wg_time = snd_soc_read(codec, WCD9XXX_A_RX_HPH_CNP_WG_TIME) *
6647 TAIKO_WG_TIME_FACTOR_US;
6648
6649 snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_CNP_EN, 0x30,
6650 enable ? 0x30 : 0x0);
6651 /* Wait for wave gen time to avoid pop noise */
6652 usleep_range(wg_time, wg_time + WCD9XXX_USLEEP_RANGE_MARGIN_US);
6653 pr_debug("%s: PAs are %s as static mode (wg_time %d)\n", __func__,
6654 enable ? "enabled" : "disabled", wg_time);
6655 return 0;
6656}
6657
6658static int taiko_setup_zdet(struct wcd9xxx_mbhc *mbhc,
6659 enum mbhc_impedance_detect_stages stage)
6660{
6661 int ret = 0;
6662 struct snd_soc_codec *codec = mbhc->codec;
6663 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
6664 const int ramp_wait_us = 18 * 1000;
6665
6666#define __wr(reg, mask, value) \
6667 do { \
6668 ret = wcd9xxx_soc_update_bits_push(codec, \
6669 &taiko->reg_save_restore, \
6670 reg, mask, value, 0); \
6671 if (ret < 0) \
6672 return ret; \
6673 } while (0)
6674
6675 switch (stage) {
6676
6677 case PRE_MEAS:
6678 INIT_LIST_HEAD(&taiko->reg_save_restore);
6679 wcd9xxx_prepare_static_pa(mbhc, &taiko->reg_save_restore);
6680 wcd9xxx_enable_static_pa(mbhc, true);
6681
6682 /*
6683 * save old value of registers and write the new value to
6684 * restore old value back, WCD9XXX_A_CDC_PA_RAMP_B{1,2,3,4}_CTL
6685 * registers don't need to be restored as those are solely used
6686 * by impedance detection.
6687 */
6688 /* Phase 1 */
6689 /* Reset the PA Ramp */
6690 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x1C);
6691 /*
6692 * Connect the PA Ramp to PA chain and release reset with
6693 * keep it connected.
6694 */
6695 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x1F);
6696 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x03);
6697 /*
6698 * Program the PA Ramp to FS_48K, L shift 1 and sample
6699 * num to 24
6700 */
6701 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B3_CTL,
6702 0x3 << 4 | 0x6);
6703 /* 0x56 for 10mv. 0xC0 is for 50mv */
6704 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B4_CTL, 0xC0);
6705 /* Enable MBHC MUX, Set MUX current to 37.5uA and ADC7 */
6706 __wr(WCD9XXX_A_MBHC_SCALING_MUX_1, 0xFF, 0xC0);
6707 __wr(WCD9XXX_A_MBHC_SCALING_MUX_2, 0xFF, 0xF0);
6708 __wr(WCD9XXX_A_TX_7_MBHC_TEST_CTL, 0xFF, 0x78);
6709 __wr(WCD9XXX_A_TX_7_MBHC_EN, 0xFF, 0x8C);
6710 /* Change NSA and NAVG */
6711 __wr(WCD9XXX_A_CDC_MBHC_TIMER_B4_CTL, 0x4 << 4, 0x4 << 4);
6712 __wr(WCD9XXX_A_CDC_MBHC_TIMER_B5_CTL, 0xFF, 0x10);
6713 /* Reset MBHC and set it up for STA */
6714 __wr(WCD9XXX_A_CDC_MBHC_CLK_CTL, 0xFF, 0x0A);
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07006715 snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x2);
Phani Kumar Uppalapati01a77e12013-08-08 15:31:35 -07006716 __wr(WCD9XXX_A_CDC_MBHC_CLK_CTL, 0xFF, 0x02);
6717
6718 /* Set HPH_MBHC for zdet */
6719 __wr(WCD9XXX_A_MBHC_HPH, 0xB3, 0x80);
6720 break;
6721 case POST_MEAS:
6722 /* Phase 2 */
6723 /* Start the PA ramp on HPH L and R */
6724 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B2_CTL, 0x05);
6725 /* Ramp generator takes ~17ms */
6726 usleep_range(ramp_wait_us,
6727 ramp_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
6728
6729 /* Disable Ical */
6730 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B2_CTL, 0x00);
6731 /* Ramp generator takes ~17ms */
6732 usleep_range(ramp_wait_us,
6733 ramp_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
6734 break;
6735 case PA_DISABLE:
6736 /* Ramp HPH L & R back to Zero */
6737 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B2_CTL, 0x0A);
6738 /* Ramp generator takes ~17ms */
6739 usleep_range(ramp_wait_us,
6740 ramp_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
6741 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B2_CTL, 0x00);
6742
6743 /* Clean up starts */
6744 /* Turn off PA ramp generator */
6745 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x0);
Sudheer Papothi3fb420b2013-12-05 05:30:15 +05306746 if (!mbhc->hph_pa_dac_state)
6747 wcd9xxx_enable_static_pa(mbhc, false);
Phani Kumar Uppalapati01a77e12013-08-08 15:31:35 -07006748 wcd9xxx_restore_registers(codec, &taiko->reg_save_restore);
6749 break;
6750 }
6751#undef __wr
6752
6753 return ret;
6754}
6755
6756static void taiko_compute_impedance(s16 *l, s16 *r, uint32_t *zl, uint32_t *zr)
6757{
6758
6759 int64_t rl, rr = 0; /* milliohm */
6760 const int alphal = 364; /* 0.005555 * 65536 = 364.05 */
6761 const int alphar = 364; /* 0.005555 * 65536 = 364.05 */
6762 const int beta = 3855; /* 0.011765 * 5 * 65536 = 3855.15 */
6763 const int rref = 11333; /* not scaled up */
6764 const int shift = 16;
6765
6766 rl = (int)(l[0] - l[1]) * 1000 / (l[0] - l[2]);
6767 rl = rl * rref * alphal;
6768 rl = rl >> shift;
6769 rl = rl * beta;
6770 rl = rl >> shift;
6771 *zl = rl;
6772
6773 rr = (int)(r[0] - r[1]) * 1000 / (r[0] - r[2]);
6774 rr = rr * rref * alphar;
6775 rr = rr >> shift;
6776 rr = rr * beta;
6777 rr = rr >> shift;
6778 *zr = rr;
6779}
6780
6781static enum wcd9xxx_cdc_type taiko_get_cdc_type(void)
6782{
6783 return WCD9XXX_CDC_TYPE_TAIKO;
6784}
6785
6786static const struct wcd9xxx_mbhc_cb mbhc_cb = {
6787 .get_cdc_type = taiko_get_cdc_type,
6788 .setup_zdet = taiko_setup_zdet,
6789 .compute_impedance = taiko_compute_impedance,
6790};
6791
Bhalchandra Gajare16748932013-10-01 18:16:05 -07006792static const struct wcd9xxx_mbhc_intr cdc_intr_ids = {
6793 .poll_plug_rem = WCD9XXX_IRQ_MBHC_REMOVAL,
6794 .shortavg_complete = WCD9XXX_IRQ_MBHC_SHORT_TERM,
6795 .potential_button_press = WCD9XXX_IRQ_MBHC_PRESS,
6796 .button_release = WCD9XXX_IRQ_MBHC_RELEASE,
6797 .dce_est_complete = WCD9XXX_IRQ_MBHC_POTENTIAL,
6798 .insertion = WCD9XXX_IRQ_MBHC_INSERTION,
6799 .hph_left_ocp = WCD9XXX_IRQ_HPH_PA_OCPL_FAULT,
6800 .hph_right_ocp = WCD9XXX_IRQ_HPH_PA_OCPR_FAULT,
6801 .hs_jack_switch = WCD9320_IRQ_MBHC_JACK_SWITCH,
6802};
6803
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006804static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
6805{
6806 int ret = 0;
6807 struct snd_soc_codec *codec;
6808 struct taiko_priv *taiko;
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07006809 int rco_clk_rate;
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006810
6811 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
6812 taiko = snd_soc_codec_get_drvdata(codec);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006813
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006814 snd_soc_card_change_online_state(codec->card, 1);
6815
6816 mutex_lock(&codec->mutex);
Anish Kumar9b461b42014-01-29 13:57:06 -08006817
6818 taiko_update_reg_defaults(codec);
6819 if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ)
6820 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x0);
6821 else if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_9P6MHZ)
6822 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x2);
6823 taiko_codec_init_reg(codec);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006824
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08006825 if (spkr_drv_wrnd == 1)
6826 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08006827
Anish Kumar9b461b42014-01-29 13:57:06 -08006828 codec->cache_sync = true;
6829 snd_soc_cache_sync(codec);
6830 codec->cache_sync = false;
6831
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006832 ret = taiko_handle_pdata(taiko);
6833 if (IS_ERR_VALUE(ret))
6834 pr_err("%s: bad pdata\n", __func__);
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08006835
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006836 taiko_init_slim_slave_cfg(codec);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006837 taiko_slim_interface_init_reg(codec);
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006838
Joonwoo Park865bcf02013-07-15 14:05:32 -07006839 wcd9xxx_resmgr_post_ssr(&taiko->resmgr);
6840
Joonwoo Park88bfa842013-04-15 16:59:21 -07006841 if (taiko->mbhc_started) {
6842 wcd9xxx_mbhc_deinit(&taiko->mbhc);
6843 taiko->mbhc_started = false;
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07006844
6845 if (TAIKO_IS_1_0(wcd9xxx->version))
6846 rco_clk_rate = TAIKO_MCLK_CLK_12P288MHZ;
6847 else
6848 rco_clk_rate = TAIKO_MCLK_CLK_9P6MHZ;
6849
Joonwoo Park88bfa842013-04-15 16:59:21 -07006850 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
Joonwoo Parkccccba72013-04-26 11:19:46 -07006851 taiko_enable_mbhc_micbias,
Bhalchandra Gajare16748932013-10-01 18:16:05 -07006852 &mbhc_cb, &cdc_intr_ids,
6853 rco_clk_rate, true);
Joonwoo Parke7d724e2013-08-19 15:51:01 -07006854 if (ret)
Joonwoo Park88bfa842013-04-15 16:59:21 -07006855 pr_err("%s: mbhc init failed %d\n", __func__, ret);
Joonwoo Parke7d724e2013-08-19 15:51:01 -07006856 else
6857 taiko_hs_detect(codec, taiko->mbhc.mbhc_cfg);
Joonwoo Park88bfa842013-04-15 16:59:21 -07006858 }
Kiran Kandia1bed422013-05-28 18:29:12 -07006859 taiko->machine_codec_event_cb(codec, WCD9XXX_CODEC_EVENT_CODEC_UP);
6860
Joonwoo Parkc98049a2013-07-30 16:43:34 -07006861 taiko_cleanup_irqs(taiko);
6862 ret = taiko_setup_irqs(taiko);
6863 if (ret)
6864 pr_err("%s: Failed to setup irq: %d\n", __func__, ret);
6865
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006866 mutex_unlock(&codec->mutex);
6867 return ret;
6868}
6869
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006870void *taiko_get_afe_config(struct snd_soc_codec *codec,
6871 enum afe_config_type config_type)
6872{
6873 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -04006874 struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006875
6876 switch (config_type) {
6877 case AFE_SLIMBUS_SLAVE_CONFIG:
6878 return &priv->slimbus_slave_cfg;
6879 case AFE_CDC_REGISTERS_CONFIG:
Damir Didjustodcfdff82013-03-21 23:26:41 -07006880 return &taiko_audio_reg_cfg;
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006881 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
6882 return &taiko_slimbus_slave_port_cfg;
Damir Didjustodcfdff82013-03-21 23:26:41 -07006883 case AFE_AANC_VERSION:
6884 return &taiko_cdc_aanc_version;
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -04006885 case AFE_CLIP_BANK_SEL:
6886 if (!TAIKO_IS_1_0(taiko_core->version))
6887 return &clip_bank_sel;
6888 else
6889 return NULL;
6890 case AFE_CDC_CLIP_REGISTERS_CONFIG:
6891 if (!TAIKO_IS_1_0(taiko_core->version))
6892 return &taiko_clip_reg_cfg;
6893 else
6894 return NULL;
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006895 default:
6896 pr_err("%s: Unknown config_type 0x%x\n", __func__, config_type);
6897 return NULL;
6898 }
6899}
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006900
Joonwoo Parka8890262012-10-15 12:04:27 -07006901static struct wcd9xxx_reg_address taiko_reg_address = {
6902 .micb_4_mbhc = TAIKO_A_MICB_4_MBHC,
6903 .micb_4_int_rbias = TAIKO_A_MICB_4_INT_RBIAS,
6904 .micb_4_ctl = TAIKO_A_MICB_4_CTL,
6905};
6906
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006907static int wcd9xxx_ssr_register(struct wcd9xxx *control,
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006908 int (*device_down_cb)(struct wcd9xxx *wcd9xxx),
6909 int (*device_up_cb)(struct wcd9xxx *wcd9xxx),
6910 void *priv)
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006911{
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006912 control->dev_down = device_down_cb;
6913 control->post_reset = device_up_cb;
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006914 control->ssr_priv = priv;
6915 return 0;
6916}
6917
Joonwoo Park2a9170a2013-03-04 17:05:57 -08006918static const struct snd_soc_dapm_widget taiko_1_dapm_widgets[] = {
6919 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_TX_1_2_EN, 7, 0,
6920 taiko_codec_enable_adc,
6921 SND_SOC_DAPM_PRE_PMU |
6922 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
6923 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_TX_1_2_EN, 3, 0,
6924 taiko_codec_enable_adc,
6925 SND_SOC_DAPM_PRE_PMU |
6926 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
6927 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_TX_3_4_EN, 7, 0,
6928 taiko_codec_enable_adc,
6929 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
6930 SND_SOC_DAPM_POST_PMD),
6931 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_TX_3_4_EN, 3, 0,
6932 taiko_codec_enable_adc,
6933 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
6934 SND_SOC_DAPM_POST_PMD),
6935 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_TX_5_6_EN, 7, 0,
6936 taiko_codec_enable_adc,
6937 SND_SOC_DAPM_POST_PMU),
6938 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_TX_5_6_EN, 3, 0,
6939 taiko_codec_enable_adc,
6940 SND_SOC_DAPM_POST_PMU),
6941};
6942
6943static const struct snd_soc_dapm_widget taiko_2_dapm_widgets[] = {
6944 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_CDC_TX_1_GAIN, 7, 0,
6945 taiko_codec_enable_adc,
6946 SND_SOC_DAPM_PRE_PMU |
6947 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
6948 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_CDC_TX_2_GAIN, 7, 0,
6949 taiko_codec_enable_adc,
6950 SND_SOC_DAPM_PRE_PMU |
6951 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
6952 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_CDC_TX_3_GAIN, 7, 0,
6953 taiko_codec_enable_adc,
6954 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
6955 SND_SOC_DAPM_POST_PMD),
6956 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_CDC_TX_4_GAIN, 7, 0,
6957 taiko_codec_enable_adc,
6958 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
6959 SND_SOC_DAPM_POST_PMD),
6960 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_CDC_TX_5_GAIN, 7, 0,
6961 taiko_codec_enable_adc,
6962 SND_SOC_DAPM_POST_PMU),
6963 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_CDC_TX_6_GAIN, 7, 0,
6964 taiko_codec_enable_adc,
6965 SND_SOC_DAPM_POST_PMU),
6966};
6967
Joonwoo Park448a8fc2013-04-10 15:25:58 -07006968static struct regulator *taiko_codec_find_regulator(struct snd_soc_codec *codec,
6969 const char *name)
6970{
6971 int i;
6972 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
6973
6974 for (i = 0; i < core->num_of_supplies; i++) {
6975 if (core->supplies[i].supply &&
6976 !strcmp(core->supplies[i].supply, name))
6977 return core->supplies[i].consumer;
6978 }
6979
6980 return NULL;
6981}
6982
Kiran Kandic3b24402012-06-11 00:05:59 -07006983static int taiko_codec_probe(struct snd_soc_codec *codec)
6984{
6985 struct wcd9xxx *control;
6986 struct taiko_priv *taiko;
Joonwoo Parka8890262012-10-15 12:04:27 -07006987 struct wcd9xxx_pdata *pdata;
6988 struct wcd9xxx *wcd9xxx;
Kiran Kandic3b24402012-06-11 00:05:59 -07006989 struct snd_soc_dapm_context *dapm = &codec->dapm;
6990 int ret = 0;
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07006991 int i, rco_clk_rate;
Kuirong Wang906ac472012-07-09 12:54:44 -07006992 void *ptr = NULL;
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006993 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006994 struct wcd9xxx_core_resource *core_res;
Kiran Kandic3b24402012-06-11 00:05:59 -07006995
6996 codec->control_data = dev_get_drvdata(codec->dev->parent);
6997 control = codec->control_data;
6998
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006999 wcd9xxx_ssr_register(control, taiko_device_down,
7000 taiko_post_reset_cb, (void *)codec);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08007001
Kiran Kandi4c56c592012-07-25 11:04:55 -07007002 dev_info(codec->dev, "%s()\n", __func__);
7003
Kiran Kandic3b24402012-06-11 00:05:59 -07007004 taiko = kzalloc(sizeof(struct taiko_priv), GFP_KERNEL);
7005 if (!taiko) {
7006 dev_err(codec->dev, "Failed to allocate private data\n");
7007 return -ENOMEM;
7008 }
7009 for (i = 0 ; i < NUM_DECIMATORS; i++) {
7010 tx_hpf_work[i].taiko = taiko;
7011 tx_hpf_work[i].decimator = i + 1;
7012 INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
7013 tx_hpf_corner_freq_callback);
7014 }
7015
Kiran Kandic3b24402012-06-11 00:05:59 -07007016 snd_soc_codec_set_drvdata(codec, taiko);
7017
Joonwoo Parka8890262012-10-15 12:04:27 -07007018 /* codec resmgr module init */
7019 wcd9xxx = codec->control_data;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07007020 core_res = &wcd9xxx->core_res;
Joonwoo Parka8890262012-10-15 12:04:27 -07007021 pdata = dev_get_platdata(codec->dev->parent);
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07007022 ret = wcd9xxx_resmgr_init(&taiko->resmgr, codec, core_res, pdata,
Bhalchandra Gajare9943aa62013-10-09 18:40:11 -07007023 &pdata->micbias, &taiko_reg_address,
7024 WCD9XXX_CDC_TYPE_TAIKO);
Joonwoo Parka8890262012-10-15 12:04:27 -07007025 if (ret) {
7026 pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007027 goto err_init;
Joonwoo Parka8890262012-10-15 12:04:27 -07007028 }
7029
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08007030 taiko->clsh_d.buck_mv = taiko_codec_get_buck_mv(codec);
Bhalchandra Gajare7c739522013-06-20 15:31:02 -07007031 /* Taiko does not support dynamic switching of vdd_cp */
7032 taiko->clsh_d.is_dynamic_vdd_cp = false;
Joonwoo Parka08e0552013-03-05 18:28:23 -08007033 wcd9xxx_clsh_init(&taiko->clsh_d, &taiko->resmgr);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08007034
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07007035 if (TAIKO_IS_1_0(core->version))
7036 rco_clk_rate = TAIKO_MCLK_CLK_12P288MHZ;
7037 else
7038 rco_clk_rate = TAIKO_MCLK_CLK_9P6MHZ;
7039
Joonwoo Parka8890262012-10-15 12:04:27 -07007040 /* init and start mbhc */
Simmi Pateriya0a44d842013-04-03 01:12:42 +05307041 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
Joonwoo Parkccccba72013-04-26 11:19:46 -07007042 taiko_enable_mbhc_micbias,
Bhalchandra Gajare16748932013-10-01 18:16:05 -07007043 &mbhc_cb, &cdc_intr_ids,
7044 rco_clk_rate, true);
Joonwoo Parka8890262012-10-15 12:04:27 -07007045 if (ret) {
7046 pr_err("%s: mbhc init failed %d\n", __func__, ret);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007047 goto err_init;
Joonwoo Parka8890262012-10-15 12:04:27 -07007048 }
7049
Kiran Kandic3b24402012-06-11 00:05:59 -07007050 taiko->codec = codec;
Kiran Kandic3b24402012-06-11 00:05:59 -07007051 for (i = 0; i < COMPANDER_MAX; i++) {
7052 taiko->comp_enabled[i] = 0;
7053 taiko->comp_fs[i] = COMPANDER_FS_48KHZ;
7054 }
Kiran Kandic3b24402012-06-11 00:05:59 -07007055 taiko->intf_type = wcd9xxx_get_intf_type();
7056 taiko->aux_pga_cnt = 0;
7057 taiko->aux_l_gain = 0x1F;
7058 taiko->aux_r_gain = 0x1F;
Joonwoo Parkccccba72013-04-26 11:19:46 -07007059 taiko->ldo_h_users = 0;
7060 taiko->micb_2_users = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07007061 taiko_update_reg_defaults(codec);
Venkat Sudhira50a3762012-11-26 12:12:15 -08007062 pr_debug("%s: MCLK Rate = %x\n", __func__, wcd9xxx->mclk_rate);
7063 if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ)
Venkat Sudhir16d95e62013-02-04 16:57:33 -08007064 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x0);
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07007065 else if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_9P6MHZ)
Venkat Sudhir16d95e62013-02-04 16:57:33 -08007066 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x2);
Kiran Kandic3b24402012-06-11 00:05:59 -07007067 taiko_codec_init_reg(codec);
7068 ret = taiko_handle_pdata(taiko);
7069 if (IS_ERR_VALUE(ret)) {
7070 pr_err("%s: bad pdata\n", __func__);
7071 goto err_pdata;
7072 }
7073
Joonwoo Park448a8fc2013-04-10 15:25:58 -07007074 taiko->spkdrv_reg = taiko_codec_find_regulator(codec,
7075 WCD9XXX_VDD_SPKDRV_NAME);
7076
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007077 if (spkr_drv_wrnd > 0) {
Joonwoo Park533b3682013-06-13 11:41:21 -07007078 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007079 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
7080 WCD9XXX_BANDGAP_AUDIO_MODE);
Joonwoo Park533b3682013-06-13 11:41:21 -07007081 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007082 }
7083
Kuirong Wang906ac472012-07-09 12:54:44 -07007084 ptr = kmalloc((sizeof(taiko_rx_chs) +
7085 sizeof(taiko_tx_chs)), GFP_KERNEL);
7086 if (!ptr) {
7087 pr_err("%s: no mem for slim chan ctl data\n", __func__);
7088 ret = -ENOMEM;
7089 goto err_nomem_slimch;
7090 }
7091
Kiran Kandic3b24402012-06-11 00:05:59 -07007092 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
7093 snd_soc_dapm_new_controls(dapm, taiko_dapm_i2s_widgets,
7094 ARRAY_SIZE(taiko_dapm_i2s_widgets));
7095 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
7096 ARRAY_SIZE(audio_i2s_map));
Joonwoo Park559a5bf2013-02-15 14:46:36 -08007097 if (TAIKO_IS_1_0(core->version))
7098 snd_soc_dapm_add_routes(dapm, audio_i2s_map_1_0,
7099 ARRAY_SIZE(audio_i2s_map_1_0));
7100 else
7101 snd_soc_dapm_add_routes(dapm, audio_i2s_map_2_0,
7102 ARRAY_SIZE(audio_i2s_map_2_0));
Kuirong Wang906ac472012-07-09 12:54:44 -07007103 for (i = 0; i < ARRAY_SIZE(taiko_i2s_dai); i++)
7104 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
7105 } else if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
7106 for (i = 0; i < NUM_CODEC_DAIS; i++) {
7107 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
7108 init_waitqueue_head(&taiko->dai[i].dai_wait);
7109 }
Joonwoo Park1d05bb92013-03-07 16:55:06 -08007110 taiko_slimbus_slave_port_cfg.slave_dev_intfdev_la =
7111 control->slim_slave->laddr;
7112 taiko_slimbus_slave_port_cfg.slave_dev_pgd_la =
7113 control->slim->laddr;
7114 taiko_slimbus_slave_port_cfg.slave_port_mapping[0] =
7115 TAIKO_MAD_SLIMBUS_TX_PORT;
7116
7117 taiko_init_slim_slave_cfg(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07007118 }
7119
Kiran Kandiec0db5c2013-03-08 16:03:58 -08007120 if (TAIKO_IS_1_0(control->version)) {
Joonwoo Park2a9170a2013-03-04 17:05:57 -08007121 snd_soc_dapm_new_controls(dapm, taiko_1_dapm_widgets,
7122 ARRAY_SIZE(taiko_1_dapm_widgets));
Kiran Kandiec0db5c2013-03-08 16:03:58 -08007123 snd_soc_add_codec_controls(codec,
7124 taiko_1_x_analog_gain_controls,
7125 ARRAY_SIZE(taiko_1_x_analog_gain_controls));
7126 } else {
Joonwoo Park2a9170a2013-03-04 17:05:57 -08007127 snd_soc_dapm_new_controls(dapm, taiko_2_dapm_widgets,
7128 ARRAY_SIZE(taiko_2_dapm_widgets));
Kiran Kandiec0db5c2013-03-08 16:03:58 -08007129 snd_soc_add_codec_controls(codec,
7130 taiko_2_x_analog_gain_controls,
7131 ARRAY_SIZE(taiko_2_x_analog_gain_controls));
7132 }
Joonwoo Park2a9170a2013-03-04 17:05:57 -08007133
Joonwoo Parkb755e9e2013-05-28 13:14:05 -07007134 snd_soc_add_codec_controls(codec, impedance_detect_controls,
7135 ARRAY_SIZE(impedance_detect_controls));
7136
Kuirong Wang906ac472012-07-09 12:54:44 -07007137 control->num_rx_port = TAIKO_RX_MAX;
7138 control->rx_chs = ptr;
7139 memcpy(control->rx_chs, taiko_rx_chs, sizeof(taiko_rx_chs));
7140 control->num_tx_port = TAIKO_TX_MAX;
7141 control->tx_chs = ptr + sizeof(taiko_rx_chs);
7142 memcpy(control->tx_chs, taiko_tx_chs, sizeof(taiko_tx_chs));
7143
Kiran Kandic3b24402012-06-11 00:05:59 -07007144 snd_soc_dapm_sync(dapm);
7145
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007146 ret = taiko_setup_irqs(taiko);
7147 if (ret) {
7148 pr_err("%s: taiko irq setup failed %d\n", __func__, ret);
7149 goto err_irq;
7150 }
Kiran Kandic3b24402012-06-11 00:05:59 -07007151
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007152 atomic_set(&kp_taiko_priv, (unsigned long)taiko);
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08007153 mutex_lock(&dapm->codec->mutex);
7154 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
7155 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
7156 snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
7157 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
7158 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
7159 snd_soc_dapm_sync(dapm);
7160 mutex_unlock(&dapm->codec->mutex);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007161
Kiran Kandic3b24402012-06-11 00:05:59 -07007162 codec->ignore_pmdown_time = 1;
7163 return ret;
7164
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007165err_irq:
7166 taiko_cleanup_irqs(taiko);
Kiran Kandic3b24402012-06-11 00:05:59 -07007167err_pdata:
Kuirong Wang906ac472012-07-09 12:54:44 -07007168 kfree(ptr);
7169err_nomem_slimch:
Kiran Kandic3b24402012-06-11 00:05:59 -07007170 kfree(taiko);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007171err_init:
Kiran Kandic3b24402012-06-11 00:05:59 -07007172 return ret;
7173}
7174static int taiko_codec_remove(struct snd_soc_codec *codec)
7175{
Kiran Kandic3b24402012-06-11 00:05:59 -07007176 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07007177
Joonwoo Park533b3682013-06-13 11:41:21 -07007178 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007179 atomic_set(&kp_taiko_priv, 0);
7180
7181 if (spkr_drv_wrnd > 0)
7182 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
7183 WCD9XXX_BANDGAP_AUDIO_MODE);
Joonwoo Park533b3682013-06-13 11:41:21 -07007184 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007185
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007186 taiko_cleanup_irqs(taiko);
7187
Joonwoo Parka8890262012-10-15 12:04:27 -07007188 /* cleanup MBHC */
7189 wcd9xxx_mbhc_deinit(&taiko->mbhc);
7190 /* cleanup resmgr */
7191 wcd9xxx_resmgr_deinit(&taiko->resmgr);
7192
Joonwoo Park448a8fc2013-04-10 15:25:58 -07007193 taiko->spkdrv_reg = NULL;
7194
Kiran Kandic3b24402012-06-11 00:05:59 -07007195 kfree(taiko);
7196 return 0;
7197}
7198static struct snd_soc_codec_driver soc_codec_dev_taiko = {
7199 .probe = taiko_codec_probe,
7200 .remove = taiko_codec_remove,
7201
7202 .read = taiko_read,
7203 .write = taiko_write,
7204
7205 .readable_register = taiko_readable,
7206 .volatile_register = taiko_volatile,
7207
7208 .reg_cache_size = TAIKO_CACHE_SIZE,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07007209 .reg_cache_default = taiko_reset_reg_defaults,
Kiran Kandic3b24402012-06-11 00:05:59 -07007210 .reg_word_size = 1,
7211
7212 .controls = taiko_snd_controls,
7213 .num_controls = ARRAY_SIZE(taiko_snd_controls),
7214 .dapm_widgets = taiko_dapm_widgets,
7215 .num_dapm_widgets = ARRAY_SIZE(taiko_dapm_widgets),
7216 .dapm_routes = audio_map,
7217 .num_dapm_routes = ARRAY_SIZE(audio_map),
7218};
7219
7220#ifdef CONFIG_PM
7221static int taiko_suspend(struct device *dev)
7222{
7223 dev_dbg(dev, "%s: system suspend\n", __func__);
7224 return 0;
7225}
7226
7227static int taiko_resume(struct device *dev)
7228{
7229 struct platform_device *pdev = to_platform_device(dev);
7230 struct taiko_priv *taiko = platform_get_drvdata(pdev);
Phani Kumar Uppalapatia32fcd02014-03-24 22:11:41 -07007231
7232 if (!taiko) {
7233 dev_err(dev, "%s: taiko private data is NULL\n", __func__);
7234 return -EINVAL;
7235 }
Kiran Kandic3b24402012-06-11 00:05:59 -07007236 dev_dbg(dev, "%s: system resume\n", __func__);
Joonwoo Parka8890262012-10-15 12:04:27 -07007237 /* Notify */
7238 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, WCD9XXX_EVENT_POST_RESUME);
Kiran Kandic3b24402012-06-11 00:05:59 -07007239 return 0;
7240}
7241
7242static const struct dev_pm_ops taiko_pm_ops = {
7243 .suspend = taiko_suspend,
7244 .resume = taiko_resume,
7245};
7246#endif
7247
7248static int __devinit taiko_probe(struct platform_device *pdev)
7249{
7250 int ret = 0;
7251 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
7252 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
7253 taiko_dai, ARRAY_SIZE(taiko_dai));
7254 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
7255 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
7256 taiko_i2s_dai, ARRAY_SIZE(taiko_i2s_dai));
7257 return ret;
7258}
7259static int __devexit taiko_remove(struct platform_device *pdev)
7260{
7261 snd_soc_unregister_codec(&pdev->dev);
7262 return 0;
7263}
7264static struct platform_driver taiko_codec_driver = {
7265 .probe = taiko_probe,
7266 .remove = taiko_remove,
7267 .driver = {
7268 .name = "taiko_codec",
7269 .owner = THIS_MODULE,
7270#ifdef CONFIG_PM
7271 .pm = &taiko_pm_ops,
7272#endif
7273 },
7274};
7275
7276static int __init taiko_codec_init(void)
7277{
7278 return platform_driver_register(&taiko_codec_driver);
7279}
7280
7281static void __exit taiko_codec_exit(void)
7282{
7283 platform_driver_unregister(&taiko_codec_driver);
7284}
7285
7286module_init(taiko_codec_init);
7287module_exit(taiko_codec_exit);
7288
7289MODULE_DESCRIPTION("Taiko codec driver");
7290MODULE_LICENSE("GPL v2");