blob: b72590f663d87313738a831872b490884e8303d8 [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
Kiran Kandiddbeaa32013-10-06 14:40:11 -07001133static const char *const taiko_conn_mad_text[] = {
1134 "ADC_MB", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "NOTUSED1",
1135 "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6", "NOTUSED2",
1136 "NOTUSED3"};
1137
1138static const struct soc_enum taiko_conn_mad_enum =
1139 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(taiko_conn_mad_text),
1140 taiko_conn_mad_text);
1141
1142
1143static int taiko_mad_input_get(struct snd_kcontrol *kcontrol,
1144 struct snd_ctl_elem_value *ucontrol)
1145{
1146 u8 taiko_mad_input;
1147 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1148
1149 taiko_mad_input = snd_soc_read(codec, TAIKO_A_CDC_CONN_MAD);
1150
1151 taiko_mad_input = taiko_mad_input & 0x0F;
1152
1153 ucontrol->value.integer.value[0] = taiko_mad_input;
1154
1155 pr_debug("%s: taiko_mad_input = %s\n", __func__,
1156 taiko_conn_mad_text[taiko_mad_input]);
1157
1158 return 0;
1159}
1160
1161static int taiko_mad_input_put(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 struct snd_soc_card *card = codec->card;
1167 char mad_amic_input_widget[6];
1168 u32 adc;
1169 const char *mad_input_widget;
1170 u32 mic_bias_found = 0;
1171 u32 i;
1172 int ret = 0;
1173
1174 taiko_mad_input = ucontrol->value.integer.value[0];
1175
1176 pr_debug("%s: taiko_mad_input = %s\n", __func__,
1177 taiko_conn_mad_text[taiko_mad_input]);
1178
1179 if (!strcmp(taiko_conn_mad_text[taiko_mad_input], "NOTUSED1") ||
1180 !strcmp(taiko_conn_mad_text[taiko_mad_input], "NOTUSED2") ||
1181 !strcmp(taiko_conn_mad_text[taiko_mad_input], "NOTUSED3") ||
1182 !strcmp(taiko_conn_mad_text[taiko_mad_input], "ADC_MB")) {
1183 pr_info("%s: taiko mad input is set to unsupported input = %s\n",
1184 __func__, taiko_conn_mad_text[taiko_mad_input]);
1185 return -EINVAL;
1186 }
1187
1188 if (strnstr(taiko_conn_mad_text[taiko_mad_input],
1189 "ADC", sizeof("ADC"))) {
1190 ret = kstrtouint(strpbrk(taiko_conn_mad_text[taiko_mad_input]
1191 , "123456"), 10, &adc);
1192 if ((ret < 0) || (adc > 6)) {
1193 pr_err("%s: Invalid ADC = %s\n", __func__,
1194 taiko_conn_mad_text[taiko_mad_input]);
1195 ret = -EINVAL;
1196 }
1197
1198 snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc);
1199
1200 mad_input_widget = mad_amic_input_widget;
1201 pr_debug("%s: taiko amic input widget = %s\n", __func__,
1202 mad_amic_input_widget);
1203 } else {
1204 /* DMIC type input widget*/
1205 mad_input_widget = taiko_conn_mad_text[taiko_mad_input];
1206 }
1207
1208 pr_debug("%s: taiko input widget = %s\n", __func__, mad_input_widget);
1209
1210 for (i = 0; i < card->num_dapm_routes; i++) {
1211
1212 if (!strncmp(card->dapm_routes[i].sink,
1213 mad_input_widget, strlen(mad_input_widget))) {
1214
1215 if (strnstr(card->dapm_routes[i].source,
1216 "MIC BIAS1", sizeof("MIC BIAS1"))) {
1217 mic_bias_found = 1;
1218 break;
1219 } else if (strnstr(card->dapm_routes[i].source,
1220 "MIC BIAS2", sizeof("MIC BIAS2"))) {
1221 mic_bias_found = 2;
1222 break;
1223 } else if (strnstr(card->dapm_routes[i].source,
1224 "MIC BIAS3", sizeof("MIC BIAS3"))) {
1225 mic_bias_found = 3;
1226 break;
1227 } else if (strnstr(card->dapm_routes[i].source,
1228 "MIC BIAS4", sizeof("MIC BIAS4"))) {
1229 mic_bias_found = 4;
1230 break;
1231 }
1232 }
1233 }
1234
1235 if (mic_bias_found) {
1236 pr_debug("%s: source mic bias = %s. sink = %s\n", __func__,
1237 card->dapm_routes[i].source,
1238 card->dapm_routes[i].sink);
1239
1240 snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_MAD,
1241 0x0F, taiko_mad_input);
1242 snd_soc_update_bits(codec, TAIKO_A_MAD_ANA_CTRL,
1243 0x07, mic_bias_found);
1244 return 0;
1245 } else {
1246 pr_err("%s: mic bias source not found for input = %s\n",
1247 __func__, mad_input_widget);
1248 return -EINVAL;
1249 }
1250}
1251
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08001252
Kiran Kandic3b24402012-06-11 00:05:59 -07001253static const struct snd_kcontrol_new taiko_snd_controls[] = {
1254
Kiran Kandic3b24402012-06-11 00:05:59 -07001255 SOC_SINGLE_S8_TLV("RX1 Digital Volume", TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
1256 -84, 40, digital_gain),
1257 SOC_SINGLE_S8_TLV("RX2 Digital Volume", TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
1258 -84, 40, digital_gain),
1259 SOC_SINGLE_S8_TLV("RX3 Digital Volume", TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
1260 -84, 40, digital_gain),
1261 SOC_SINGLE_S8_TLV("RX4 Digital Volume", TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
1262 -84, 40, digital_gain),
1263 SOC_SINGLE_S8_TLV("RX5 Digital Volume", TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
1264 -84, 40, digital_gain),
1265 SOC_SINGLE_S8_TLV("RX6 Digital Volume", TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
1266 -84, 40, digital_gain),
1267 SOC_SINGLE_S8_TLV("RX7 Digital Volume", TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
1268 -84, 40, digital_gain),
1269
1270 SOC_SINGLE_S8_TLV("DEC1 Volume", TAIKO_A_CDC_TX1_VOL_CTL_GAIN, -84, 40,
1271 digital_gain),
1272 SOC_SINGLE_S8_TLV("DEC2 Volume", TAIKO_A_CDC_TX2_VOL_CTL_GAIN, -84, 40,
1273 digital_gain),
1274 SOC_SINGLE_S8_TLV("DEC3 Volume", TAIKO_A_CDC_TX3_VOL_CTL_GAIN, -84, 40,
1275 digital_gain),
1276 SOC_SINGLE_S8_TLV("DEC4 Volume", TAIKO_A_CDC_TX4_VOL_CTL_GAIN, -84, 40,
1277 digital_gain),
1278 SOC_SINGLE_S8_TLV("DEC5 Volume", TAIKO_A_CDC_TX5_VOL_CTL_GAIN, -84, 40,
1279 digital_gain),
1280 SOC_SINGLE_S8_TLV("DEC6 Volume", TAIKO_A_CDC_TX6_VOL_CTL_GAIN, -84, 40,
1281 digital_gain),
1282 SOC_SINGLE_S8_TLV("DEC7 Volume", TAIKO_A_CDC_TX7_VOL_CTL_GAIN, -84, 40,
1283 digital_gain),
1284 SOC_SINGLE_S8_TLV("DEC8 Volume", TAIKO_A_CDC_TX8_VOL_CTL_GAIN, -84, 40,
1285 digital_gain),
1286 SOC_SINGLE_S8_TLV("DEC9 Volume", TAIKO_A_CDC_TX9_VOL_CTL_GAIN, -84, 40,
1287 digital_gain),
1288 SOC_SINGLE_S8_TLV("DEC10 Volume", TAIKO_A_CDC_TX10_VOL_CTL_GAIN, -84,
1289 40, digital_gain),
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001290
Kiran Kandic3b24402012-06-11 00:05:59 -07001291 SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, -84,
1292 40, digital_gain),
1293 SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", TAIKO_A_CDC_IIR1_GAIN_B2_CTL, -84,
1294 40, digital_gain),
1295 SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", TAIKO_A_CDC_IIR1_GAIN_B3_CTL, -84,
1296 40, digital_gain),
1297 SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", TAIKO_A_CDC_IIR1_GAIN_B4_CTL, -84,
1298 40, digital_gain),
Fred Oh456fcb52013-02-28 19:08:15 -08001299 SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", TAIKO_A_CDC_IIR2_GAIN_B1_CTL, -84,
1300 40, digital_gain),
1301 SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", TAIKO_A_CDC_IIR2_GAIN_B2_CTL, -84,
1302 40, digital_gain),
1303 SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", TAIKO_A_CDC_IIR2_GAIN_B3_CTL, -84,
1304 40, digital_gain),
1305 SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", TAIKO_A_CDC_IIR2_GAIN_B4_CTL, -84,
1306 40, digital_gain),
Kiran Kandic3b24402012-06-11 00:05:59 -07001307
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001308 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, taiko_get_anc_slot,
Kiran Kandic3b24402012-06-11 00:05:59 -07001309 taiko_put_anc_slot),
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001310 SOC_ENUM_EXT("ANC Function", taiko_anc_func_enum, taiko_get_anc_func,
1311 taiko_put_anc_func),
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001312
Kiran Kandic3b24402012-06-11 00:05:59 -07001313 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
1314 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
1315 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
1316 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
1317 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
1318 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
1319 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
1320 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
1321 SOC_ENUM("TX9 HPF cut off", cf_dec9_enum),
1322 SOC_ENUM("TX10 HPF cut off", cf_dec10_enum),
1323
1324 SOC_SINGLE("TX1 HPF Switch", TAIKO_A_CDC_TX1_MUX_CTL, 3, 1, 0),
1325 SOC_SINGLE("TX2 HPF Switch", TAIKO_A_CDC_TX2_MUX_CTL, 3, 1, 0),
1326 SOC_SINGLE("TX3 HPF Switch", TAIKO_A_CDC_TX3_MUX_CTL, 3, 1, 0),
1327 SOC_SINGLE("TX4 HPF Switch", TAIKO_A_CDC_TX4_MUX_CTL, 3, 1, 0),
1328 SOC_SINGLE("TX5 HPF Switch", TAIKO_A_CDC_TX5_MUX_CTL, 3, 1, 0),
1329 SOC_SINGLE("TX6 HPF Switch", TAIKO_A_CDC_TX6_MUX_CTL, 3, 1, 0),
1330 SOC_SINGLE("TX7 HPF Switch", TAIKO_A_CDC_TX7_MUX_CTL, 3, 1, 0),
1331 SOC_SINGLE("TX8 HPF Switch", TAIKO_A_CDC_TX8_MUX_CTL, 3, 1, 0),
1332 SOC_SINGLE("TX9 HPF Switch", TAIKO_A_CDC_TX9_MUX_CTL, 3, 1, 0),
1333 SOC_SINGLE("TX10 HPF Switch", TAIKO_A_CDC_TX10_MUX_CTL, 3, 1, 0),
1334
1335 SOC_SINGLE("RX1 HPF Switch", TAIKO_A_CDC_RX1_B5_CTL, 2, 1, 0),
1336 SOC_SINGLE("RX2 HPF Switch", TAIKO_A_CDC_RX2_B5_CTL, 2, 1, 0),
1337 SOC_SINGLE("RX3 HPF Switch", TAIKO_A_CDC_RX3_B5_CTL, 2, 1, 0),
1338 SOC_SINGLE("RX4 HPF Switch", TAIKO_A_CDC_RX4_B5_CTL, 2, 1, 0),
1339 SOC_SINGLE("RX5 HPF Switch", TAIKO_A_CDC_RX5_B5_CTL, 2, 1, 0),
1340 SOC_SINGLE("RX6 HPF Switch", TAIKO_A_CDC_RX6_B5_CTL, 2, 1, 0),
1341 SOC_SINGLE("RX7 HPF Switch", TAIKO_A_CDC_RX7_B5_CTL, 2, 1, 0),
1342
1343 SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
1344 SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
1345 SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
1346 SOC_ENUM("RX4 HPF cut off", cf_rxmix4_enum),
1347 SOC_ENUM("RX5 HPF cut off", cf_rxmix5_enum),
1348 SOC_ENUM("RX6 HPF cut off", cf_rxmix6_enum),
1349 SOC_ENUM("RX7 HPF cut off", cf_rxmix7_enum),
1350
1351 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
1352 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1353 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
1354 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1355 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
1356 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1357 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
1358 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1359 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
1360 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1361 SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
1362 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1363 SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
1364 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1365 SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
1366 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1367 SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
1368 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1369 SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
1370 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1371
1372 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
1373 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1374 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
1375 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1376 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
1377 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1378 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
1379 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1380 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
1381 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1382 SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
1383 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1384 SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
1385 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1386 SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
1387 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1388 SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
1389 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1390 SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
1391 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1392
Joonwoo Parkc7731432012-10-17 12:41:44 -07001393 SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_0, 1, 0,
1394 taiko_get_compander, taiko_set_compander),
1395 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
1396 taiko_get_compander, taiko_set_compander),
1397 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
1398 taiko_get_compander, taiko_set_compander),
Kiran Kandic3b24402012-06-11 00:05:59 -07001399
Kiran Kandiddbeaa32013-10-06 14:40:11 -07001400 SOC_ENUM_EXT("MAD Input", taiko_conn_mad_enum,
1401 taiko_mad_input_get, taiko_mad_input_put),
1402
Kiran Kandic3b24402012-06-11 00:05:59 -07001403};
1404
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001405static int taiko_pa_gain_get(struct snd_kcontrol *kcontrol,
1406 struct snd_ctl_elem_value *ucontrol)
1407{
1408 u8 ear_pa_gain;
1409 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1410
1411 ear_pa_gain = snd_soc_read(codec, TAIKO_A_RX_EAR_GAIN);
1412
1413 ear_pa_gain = ear_pa_gain >> 5;
1414
1415 ucontrol->value.integer.value[0] = ear_pa_gain;
1416
1417 pr_debug("%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
1418
1419 return 0;
1420}
1421
1422static int taiko_pa_gain_put(struct snd_kcontrol *kcontrol,
1423 struct snd_ctl_elem_value *ucontrol)
1424{
1425 u8 ear_pa_gain;
1426 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1427
1428 pr_debug("%s: ucontrol->value.integer.value[0] = %ld\n", __func__,
1429 ucontrol->value.integer.value[0]);
1430
1431 ear_pa_gain = ucontrol->value.integer.value[0] << 5;
1432
1433 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_GAIN, 0xE0, ear_pa_gain);
1434 return 0;
1435}
1436
1437static const char * const taiko_1_x_ear_pa_gain_text[] = {
1438 "POS_6_DB", "UNDEFINED_1", "UNDEFINED_2", "UNDEFINED_3", "POS_2_DB",
1439 "NEG_2P5_DB", "UNDEFINED_4", "NEG_12_DB"
1440};
1441
1442static const struct soc_enum taiko_1_x_ear_pa_gain_enum =
1443 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(taiko_1_x_ear_pa_gain_text),
1444 taiko_1_x_ear_pa_gain_text);
1445
1446static const struct snd_kcontrol_new taiko_1_x_analog_gain_controls[] = {
1447
1448 SOC_ENUM_EXT("EAR PA Gain", taiko_1_x_ear_pa_gain_enum,
1449 taiko_pa_gain_get, taiko_pa_gain_put),
1450
1451 SOC_SINGLE_TLV("HPHL Volume", TAIKO_A_RX_HPH_L_GAIN, 0, 20, 1,
1452 line_gain),
1453 SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 20, 1,
1454 line_gain),
1455
1456 SOC_SINGLE_TLV("LINEOUT1 Volume", TAIKO_A_RX_LINE_1_GAIN, 0, 20, 1,
1457 line_gain),
1458 SOC_SINGLE_TLV("LINEOUT2 Volume", TAIKO_A_RX_LINE_2_GAIN, 0, 20, 1,
1459 line_gain),
1460 SOC_SINGLE_TLV("LINEOUT3 Volume", TAIKO_A_RX_LINE_3_GAIN, 0, 20, 1,
1461 line_gain),
1462 SOC_SINGLE_TLV("LINEOUT4 Volume", TAIKO_A_RX_LINE_4_GAIN, 0, 20, 1,
1463 line_gain),
1464
1465 SOC_SINGLE_TLV("SPK DRV Volume", TAIKO_A_SPKR_DRV_GAIN, 3, 7, 1,
1466 line_gain),
1467
1468 SOC_SINGLE_TLV("ADC1 Volume", TAIKO_A_TX_1_2_EN, 5, 3, 0, analog_gain),
1469 SOC_SINGLE_TLV("ADC2 Volume", TAIKO_A_TX_1_2_EN, 1, 3, 0, analog_gain),
1470 SOC_SINGLE_TLV("ADC3 Volume", TAIKO_A_TX_3_4_EN, 5, 3, 0, analog_gain),
1471 SOC_SINGLE_TLV("ADC4 Volume", TAIKO_A_TX_3_4_EN, 1, 3, 0, analog_gain),
1472 SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_TX_5_6_EN, 5, 3, 0, analog_gain),
1473 SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_TX_5_6_EN, 1, 3, 0, analog_gain),
1474};
1475
1476static const char * const taiko_2_x_ear_pa_gain_text[] = {
1477 "POS_6_DB", "POS_4P5_DB", "POS_3_DB", "POS_1P5_DB",
1478 "POS_0_DB", "NEG_2P5_DB", "UNDEFINED", "NEG_12_DB"
1479};
1480
1481static const struct soc_enum taiko_2_x_ear_pa_gain_enum =
1482 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(taiko_2_x_ear_pa_gain_text),
1483 taiko_2_x_ear_pa_gain_text);
1484
1485static const struct snd_kcontrol_new taiko_2_x_analog_gain_controls[] = {
1486
1487 SOC_ENUM_EXT("EAR PA Gain", taiko_2_x_ear_pa_gain_enum,
1488 taiko_pa_gain_get, taiko_pa_gain_put),
1489
1490 SOC_SINGLE_TLV("HPHL Volume", TAIKO_A_RX_HPH_L_GAIN, 0, 20, 1,
1491 line_gain),
1492 SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 20, 1,
1493 line_gain),
1494
1495 SOC_SINGLE_TLV("LINEOUT1 Volume", TAIKO_A_RX_LINE_1_GAIN, 0, 20, 1,
1496 line_gain),
1497 SOC_SINGLE_TLV("LINEOUT2 Volume", TAIKO_A_RX_LINE_2_GAIN, 0, 20, 1,
1498 line_gain),
1499 SOC_SINGLE_TLV("LINEOUT3 Volume", TAIKO_A_RX_LINE_3_GAIN, 0, 20, 1,
1500 line_gain),
1501 SOC_SINGLE_TLV("LINEOUT4 Volume", TAIKO_A_RX_LINE_4_GAIN, 0, 20, 1,
1502 line_gain),
1503
1504 SOC_SINGLE_TLV("SPK DRV Volume", TAIKO_A_SPKR_DRV_GAIN, 3, 8, 1,
1505 line_gain),
1506
1507 SOC_SINGLE_TLV("ADC1 Volume", TAIKO_A_CDC_TX_1_GAIN, 2, 19, 0,
1508 analog_gain),
1509 SOC_SINGLE_TLV("ADC2 Volume", TAIKO_A_CDC_TX_2_GAIN, 2, 19, 0,
1510 analog_gain),
1511 SOC_SINGLE_TLV("ADC3 Volume", TAIKO_A_CDC_TX_3_GAIN, 2, 19, 0,
1512 analog_gain),
1513 SOC_SINGLE_TLV("ADC4 Volume", TAIKO_A_CDC_TX_4_GAIN, 2, 19, 0,
1514 analog_gain),
1515 SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_CDC_TX_5_GAIN, 2, 19, 0,
1516 analog_gain),
1517 SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_CDC_TX_6_GAIN, 2, 19, 0,
1518 analog_gain),
1519};
1520
Joonwoo Parkb755e9e2013-05-28 13:14:05 -07001521static int taiko_hph_impedance_get(struct snd_kcontrol *kcontrol,
1522 struct snd_ctl_elem_value *ucontrol)
1523{
1524 uint32_t zl, zr;
1525 bool hphr;
1526 struct soc_multi_mixer_control *mc;
1527 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1528 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
1529
1530 mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
1531
1532 hphr = mc->shift;
1533 wcd9xxx_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
1534 pr_debug("%s: zl %u, zr %u\n", __func__, zl, zr);
1535 ucontrol->value.integer.value[0] = hphr ? zr : zl;
1536
1537 return 0;
1538}
1539
1540static const struct snd_kcontrol_new impedance_detect_controls[] = {
1541 SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
1542 taiko_hph_impedance_get, NULL),
1543 SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
1544 taiko_hph_impedance_get, NULL),
1545};
1546
Kiran Kandic3b24402012-06-11 00:05:59 -07001547static const char * const rx_mix1_text[] = {
1548 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2", "RX1", "RX2", "RX3", "RX4",
1549 "RX5", "RX6", "RX7"
1550};
1551
1552static const char * const rx_mix2_text[] = {
1553 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2"
1554};
1555
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001556static const char * const rx_rdac5_text[] = {
1557 "DEM4", "DEM3_INV"
Kiran Kandic3b24402012-06-11 00:05:59 -07001558};
1559
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001560static const char * const rx_rdac7_text[] = {
1561 "DEM6", "DEM5_INV"
1562};
1563
1564
Kiran Kandic3b24402012-06-11 00:05:59 -07001565static const char * const sb_tx1_mux_text[] = {
1566 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1567 "DEC1"
1568};
1569
1570static const char * const sb_tx2_mux_text[] = {
1571 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1572 "DEC2"
1573};
1574
1575static const char * const sb_tx3_mux_text[] = {
1576 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1577 "DEC3"
1578};
1579
1580static const char * const sb_tx4_mux_text[] = {
1581 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1582 "DEC4"
1583};
1584
1585static const char * const sb_tx5_mux_text[] = {
1586 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1587 "DEC5"
1588};
1589
1590static const char * const sb_tx6_mux_text[] = {
1591 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1592 "DEC6"
1593};
1594
1595static const char * const sb_tx7_to_tx10_mux_text[] = {
1596 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1597 "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1598 "DEC9", "DEC10"
1599};
1600
1601static const char * const dec1_mux_text[] = {
1602 "ZERO", "DMIC1", "ADC6",
1603};
1604
1605static const char * const dec2_mux_text[] = {
1606 "ZERO", "DMIC2", "ADC5",
1607};
1608
1609static const char * const dec3_mux_text[] = {
1610 "ZERO", "DMIC3", "ADC4",
1611};
1612
1613static const char * const dec4_mux_text[] = {
1614 "ZERO", "DMIC4", "ADC3",
1615};
1616
1617static const char * const dec5_mux_text[] = {
1618 "ZERO", "DMIC5", "ADC2",
1619};
1620
1621static const char * const dec6_mux_text[] = {
1622 "ZERO", "DMIC6", "ADC1",
1623};
1624
1625static const char * const dec7_mux_text[] = {
1626 "ZERO", "DMIC1", "DMIC6", "ADC1", "ADC6", "ANC1_FB", "ANC2_FB",
1627};
1628
1629static const char * const dec8_mux_text[] = {
1630 "ZERO", "DMIC2", "DMIC5", "ADC2", "ADC5",
1631};
1632
1633static const char * const dec9_mux_text[] = {
1634 "ZERO", "DMIC4", "DMIC5", "ADC2", "ADC3", "ADCMB", "ANC1_FB", "ANC2_FB",
1635};
1636
1637static const char * const dec10_mux_text[] = {
1638 "ZERO", "DMIC3", "DMIC6", "ADC1", "ADC4", "ADCMB", "ANC1_FB", "ANC2_FB",
1639};
1640
1641static const char * const anc_mux_text[] = {
1642 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC_MB",
1643 "RSVD_1", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6"
1644};
1645
1646static const char * const anc1_fb_mux_text[] = {
1647 "ZERO", "EAR_HPH_L", "EAR_LINE_1",
1648};
1649
Fred Oh456fcb52013-02-28 19:08:15 -08001650static const char * const iir_inp1_text[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07001651 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1652 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1653};
1654
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05301655static const char * const iir_inp2_text[] = {
1656 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1657 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1658};
1659
1660static const char * const iir_inp3_text[] = {
1661 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1662 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1663};
1664
1665static const char * const iir_inp4_text[] = {
1666 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1667 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1668};
1669
Kiran Kandic3b24402012-06-11 00:05:59 -07001670static const struct soc_enum rx_mix1_inp1_chain_enum =
1671 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 0, 12, rx_mix1_text);
1672
1673static const struct soc_enum rx_mix1_inp2_chain_enum =
1674 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 4, 12, rx_mix1_text);
1675
1676static const struct soc_enum rx_mix1_inp3_chain_enum =
1677 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B2_CTL, 0, 12, rx_mix1_text);
1678
1679static const struct soc_enum rx2_mix1_inp1_chain_enum =
1680 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 0, 12, rx_mix1_text);
1681
1682static const struct soc_enum rx2_mix1_inp2_chain_enum =
1683 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 4, 12, rx_mix1_text);
1684
1685static const struct soc_enum rx3_mix1_inp1_chain_enum =
1686 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 0, 12, rx_mix1_text);
1687
1688static const struct soc_enum rx3_mix1_inp2_chain_enum =
1689 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 4, 12, rx_mix1_text);
1690
1691static const struct soc_enum rx4_mix1_inp1_chain_enum =
1692 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 0, 12, rx_mix1_text);
1693
1694static const struct soc_enum rx4_mix1_inp2_chain_enum =
1695 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 4, 12, rx_mix1_text);
1696
1697static const struct soc_enum rx5_mix1_inp1_chain_enum =
1698 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 0, 12, rx_mix1_text);
1699
1700static const struct soc_enum rx5_mix1_inp2_chain_enum =
1701 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 4, 12, rx_mix1_text);
1702
1703static const struct soc_enum rx6_mix1_inp1_chain_enum =
1704 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 0, 12, rx_mix1_text);
1705
1706static const struct soc_enum rx6_mix1_inp2_chain_enum =
1707 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 4, 12, rx_mix1_text);
1708
1709static const struct soc_enum rx7_mix1_inp1_chain_enum =
1710 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 0, 12, rx_mix1_text);
1711
1712static const struct soc_enum rx7_mix1_inp2_chain_enum =
1713 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 4, 12, rx_mix1_text);
1714
1715static const struct soc_enum rx1_mix2_inp1_chain_enum =
1716 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 0, 5, rx_mix2_text);
1717
1718static const struct soc_enum rx1_mix2_inp2_chain_enum =
1719 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 3, 5, rx_mix2_text);
1720
1721static const struct soc_enum rx2_mix2_inp1_chain_enum =
1722 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 0, 5, rx_mix2_text);
1723
1724static const struct soc_enum rx2_mix2_inp2_chain_enum =
1725 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 3, 5, rx_mix2_text);
1726
1727static const struct soc_enum rx7_mix2_inp1_chain_enum =
1728 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 0, 5, rx_mix2_text);
1729
1730static const struct soc_enum rx7_mix2_inp2_chain_enum =
1731 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 3, 5, rx_mix2_text);
1732
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001733static const struct soc_enum rx_rdac5_enum =
1734 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_MISC, 2, 2, rx_rdac5_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001735
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001736static const struct soc_enum rx_rdac7_enum =
1737 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_MISC, 1, 2, rx_rdac7_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001738
1739static const struct soc_enum sb_tx1_mux_enum =
1740 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0, 9, sb_tx1_mux_text);
1741
1742static const struct soc_enum sb_tx2_mux_enum =
1743 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0, 9, sb_tx2_mux_text);
1744
1745static const struct soc_enum sb_tx3_mux_enum =
1746 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0, 9, sb_tx3_mux_text);
1747
1748static const struct soc_enum sb_tx4_mux_enum =
1749 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0, 9, sb_tx4_mux_text);
1750
1751static const struct soc_enum sb_tx5_mux_enum =
1752 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0, 9, sb_tx5_mux_text);
1753
1754static const struct soc_enum sb_tx6_mux_enum =
1755 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0, 9, sb_tx6_mux_text);
1756
1757static const struct soc_enum sb_tx7_mux_enum =
1758 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0, 18,
1759 sb_tx7_to_tx10_mux_text);
1760
1761static const struct soc_enum sb_tx8_mux_enum =
1762 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0, 18,
1763 sb_tx7_to_tx10_mux_text);
1764
1765static const struct soc_enum sb_tx9_mux_enum =
1766 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0, 18,
1767 sb_tx7_to_tx10_mux_text);
1768
1769static const struct soc_enum sb_tx10_mux_enum =
1770 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0, 18,
1771 sb_tx7_to_tx10_mux_text);
1772
1773static const struct soc_enum dec1_mux_enum =
1774 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 0, 3, dec1_mux_text);
1775
1776static const struct soc_enum dec2_mux_enum =
1777 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 2, 3, dec2_mux_text);
1778
1779static const struct soc_enum dec3_mux_enum =
1780 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 4, 3, dec3_mux_text);
1781
1782static const struct soc_enum dec4_mux_enum =
1783 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 6, 3, dec4_mux_text);
1784
1785static const struct soc_enum dec5_mux_enum =
1786 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 0, 3, dec5_mux_text);
1787
1788static const struct soc_enum dec6_mux_enum =
1789 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 2, 3, dec6_mux_text);
1790
1791static const struct soc_enum dec7_mux_enum =
1792 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 4, 7, dec7_mux_text);
1793
1794static const struct soc_enum dec8_mux_enum =
1795 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 0, 7, dec8_mux_text);
1796
1797static const struct soc_enum dec9_mux_enum =
1798 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 3, 8, dec9_mux_text);
1799
1800static const struct soc_enum dec10_mux_enum =
1801 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B4_CTL, 0, 8, dec10_mux_text);
1802
1803static const struct soc_enum anc1_mux_enum =
1804 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 0, 16, anc_mux_text);
1805
1806static const struct soc_enum anc2_mux_enum =
1807 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 4, 16, anc_mux_text);
1808
1809static const struct soc_enum anc1_fb_mux_enum =
1810 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B2_CTL, 0, 3, anc1_fb_mux_text);
1811
1812static const struct soc_enum iir1_inp1_mux_enum =
Fred Oh456fcb52013-02-28 19:08:15 -08001813 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir_inp1_text);
1814
1815static const struct soc_enum iir2_inp1_mux_enum =
1816 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B1_CTL, 0, 18, iir_inp1_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001817
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05301818static const struct soc_enum iir1_inp2_mux_enum =
1819 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B2_CTL, 0, 18, iir_inp2_text);
1820
1821static const struct soc_enum iir2_inp2_mux_enum =
1822 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B2_CTL, 0, 18, iir_inp2_text);
1823
1824static const struct soc_enum iir1_inp3_mux_enum =
1825 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B3_CTL, 0, 18, iir_inp3_text);
1826
1827static const struct soc_enum iir2_inp3_mux_enum =
1828 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B3_CTL, 0, 18, iir_inp3_text);
1829
1830static const struct soc_enum iir1_inp4_mux_enum =
1831 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B4_CTL, 0, 18, iir_inp4_text);
1832
1833static const struct soc_enum iir2_inp4_mux_enum =
1834 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B4_CTL, 0, 18, iir_inp4_text);
1835
Kiran Kandic3b24402012-06-11 00:05:59 -07001836static const struct snd_kcontrol_new rx_mix1_inp1_mux =
1837 SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
1838
1839static const struct snd_kcontrol_new rx_mix1_inp2_mux =
1840 SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
1841
1842static const struct snd_kcontrol_new rx_mix1_inp3_mux =
1843 SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
1844
1845static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
1846 SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
1847
1848static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
1849 SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
1850
1851static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
1852 SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
1853
1854static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
1855 SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
1856
1857static const struct snd_kcontrol_new rx4_mix1_inp1_mux =
1858 SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum);
1859
1860static const struct snd_kcontrol_new rx4_mix1_inp2_mux =
1861 SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum);
1862
1863static const struct snd_kcontrol_new rx5_mix1_inp1_mux =
1864 SOC_DAPM_ENUM("RX5 MIX1 INP1 Mux", rx5_mix1_inp1_chain_enum);
1865
1866static const struct snd_kcontrol_new rx5_mix1_inp2_mux =
1867 SOC_DAPM_ENUM("RX5 MIX1 INP2 Mux", rx5_mix1_inp2_chain_enum);
1868
1869static const struct snd_kcontrol_new rx6_mix1_inp1_mux =
1870 SOC_DAPM_ENUM("RX6 MIX1 INP1 Mux", rx6_mix1_inp1_chain_enum);
1871
1872static const struct snd_kcontrol_new rx6_mix1_inp2_mux =
1873 SOC_DAPM_ENUM("RX6 MIX1 INP2 Mux", rx6_mix1_inp2_chain_enum);
1874
1875static const struct snd_kcontrol_new rx7_mix1_inp1_mux =
1876 SOC_DAPM_ENUM("RX7 MIX1 INP1 Mux", rx7_mix1_inp1_chain_enum);
1877
1878static const struct snd_kcontrol_new rx7_mix1_inp2_mux =
1879 SOC_DAPM_ENUM("RX7 MIX1 INP2 Mux", rx7_mix1_inp2_chain_enum);
1880
1881static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
1882 SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_mix2_inp1_chain_enum);
1883
1884static const struct snd_kcontrol_new rx1_mix2_inp2_mux =
1885 SOC_DAPM_ENUM("RX1 MIX2 INP2 Mux", rx1_mix2_inp2_chain_enum);
1886
1887static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
1888 SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
1889
1890static const struct snd_kcontrol_new rx2_mix2_inp2_mux =
1891 SOC_DAPM_ENUM("RX2 MIX2 INP2 Mux", rx2_mix2_inp2_chain_enum);
1892
1893static const struct snd_kcontrol_new rx7_mix2_inp1_mux =
1894 SOC_DAPM_ENUM("RX7 MIX2 INP1 Mux", rx7_mix2_inp1_chain_enum);
1895
1896static const struct snd_kcontrol_new rx7_mix2_inp2_mux =
1897 SOC_DAPM_ENUM("RX7 MIX2 INP2 Mux", rx7_mix2_inp2_chain_enum);
1898
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001899static const struct snd_kcontrol_new rx_dac5_mux =
1900 SOC_DAPM_ENUM("RDAC5 MUX Mux", rx_rdac5_enum);
Kiran Kandic3b24402012-06-11 00:05:59 -07001901
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001902static const struct snd_kcontrol_new rx_dac7_mux =
1903 SOC_DAPM_ENUM("RDAC7 MUX Mux", rx_rdac7_enum);
Kiran Kandic3b24402012-06-11 00:05:59 -07001904
1905static const struct snd_kcontrol_new sb_tx1_mux =
1906 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
1907
1908static const struct snd_kcontrol_new sb_tx2_mux =
1909 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
1910
1911static const struct snd_kcontrol_new sb_tx3_mux =
1912 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
1913
1914static const struct snd_kcontrol_new sb_tx4_mux =
1915 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
1916
1917static const struct snd_kcontrol_new sb_tx5_mux =
1918 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
1919
1920static const struct snd_kcontrol_new sb_tx6_mux =
1921 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
1922
1923static const struct snd_kcontrol_new sb_tx7_mux =
1924 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
1925
1926static const struct snd_kcontrol_new sb_tx8_mux =
1927 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
1928
1929static const struct snd_kcontrol_new sb_tx9_mux =
1930 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
1931
1932static const struct snd_kcontrol_new sb_tx10_mux =
1933 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
1934
1935
1936static int wcd9320_put_dec_enum(struct snd_kcontrol *kcontrol,
1937 struct snd_ctl_elem_value *ucontrol)
1938{
1939 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1940 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1941 struct snd_soc_codec *codec = w->codec;
1942 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1943 unsigned int dec_mux, decimator;
1944 char *dec_name = NULL;
1945 char *widget_name = NULL;
1946 char *temp;
1947 u16 tx_mux_ctl_reg;
1948 u8 adc_dmic_sel = 0x0;
1949 int ret = 0;
1950
1951 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1952 return -EINVAL;
1953
1954 dec_mux = ucontrol->value.enumerated.item[0];
1955
1956 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
1957 if (!widget_name)
1958 return -ENOMEM;
1959 temp = widget_name;
1960
1961 dec_name = strsep(&widget_name, " ");
1962 widget_name = temp;
1963 if (!dec_name) {
1964 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
1965 ret = -EINVAL;
1966 goto out;
1967 }
1968
1969 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
1970 if (ret < 0) {
1971 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
1972 ret = -EINVAL;
1973 goto out;
1974 }
1975
1976 dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
1977 , __func__, w->name, decimator, dec_mux);
1978
1979
1980 switch (decimator) {
1981 case 1:
1982 case 2:
1983 case 3:
1984 case 4:
1985 case 5:
1986 case 6:
1987 if (dec_mux == 1)
1988 adc_dmic_sel = 0x1;
1989 else
1990 adc_dmic_sel = 0x0;
1991 break;
1992 case 7:
1993 case 8:
1994 case 9:
1995 case 10:
1996 if ((dec_mux == 1) || (dec_mux == 2))
1997 adc_dmic_sel = 0x1;
1998 else
1999 adc_dmic_sel = 0x0;
2000 break;
2001 default:
2002 pr_err("%s: Invalid Decimator = %u\n", __func__, decimator);
2003 ret = -EINVAL;
2004 goto out;
2005 }
2006
2007 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
2008
2009 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
2010
2011 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
2012
2013out:
2014 kfree(widget_name);
2015 return ret;
2016}
2017
2018#define WCD9320_DEC_ENUM(xname, xenum) \
2019{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2020 .info = snd_soc_info_enum_double, \
2021 .get = snd_soc_dapm_get_enum_double, \
2022 .put = wcd9320_put_dec_enum, \
2023 .private_value = (unsigned long)&xenum }
2024
2025static const struct snd_kcontrol_new dec1_mux =
2026 WCD9320_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
2027
2028static const struct snd_kcontrol_new dec2_mux =
2029 WCD9320_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
2030
2031static const struct snd_kcontrol_new dec3_mux =
2032 WCD9320_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum);
2033
2034static const struct snd_kcontrol_new dec4_mux =
2035 WCD9320_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum);
2036
2037static const struct snd_kcontrol_new dec5_mux =
2038 WCD9320_DEC_ENUM("DEC5 MUX Mux", dec5_mux_enum);
2039
2040static const struct snd_kcontrol_new dec6_mux =
2041 WCD9320_DEC_ENUM("DEC6 MUX Mux", dec6_mux_enum);
2042
2043static const struct snd_kcontrol_new dec7_mux =
2044 WCD9320_DEC_ENUM("DEC7 MUX Mux", dec7_mux_enum);
2045
2046static const struct snd_kcontrol_new dec8_mux =
2047 WCD9320_DEC_ENUM("DEC8 MUX Mux", dec8_mux_enum);
2048
2049static const struct snd_kcontrol_new dec9_mux =
2050 WCD9320_DEC_ENUM("DEC9 MUX Mux", dec9_mux_enum);
2051
2052static const struct snd_kcontrol_new dec10_mux =
2053 WCD9320_DEC_ENUM("DEC10 MUX Mux", dec10_mux_enum);
2054
2055static const struct snd_kcontrol_new iir1_inp1_mux =
2056 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
2057
Fred Oh456fcb52013-02-28 19:08:15 -08002058static const struct snd_kcontrol_new iir2_inp1_mux =
2059 SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
2060
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05302061static const struct snd_kcontrol_new iir1_inp2_mux =
2062 SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
2063
2064static const struct snd_kcontrol_new iir2_inp2_mux =
2065 SOC_DAPM_ENUM("IIR2 INP2 Mux", iir2_inp2_mux_enum);
2066
2067static const struct snd_kcontrol_new iir1_inp3_mux =
2068 SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
2069
2070static const struct snd_kcontrol_new iir2_inp3_mux =
2071 SOC_DAPM_ENUM("IIR2 INP3 Mux", iir2_inp3_mux_enum);
2072
2073static const struct snd_kcontrol_new iir1_inp4_mux =
2074 SOC_DAPM_ENUM("IIR1 INP4 Mux", iir1_inp4_mux_enum);
2075
2076static const struct snd_kcontrol_new iir2_inp4_mux =
2077 SOC_DAPM_ENUM("IIR2 INP4 Mux", iir2_inp4_mux_enum);
2078
Kiran Kandic3b24402012-06-11 00:05:59 -07002079static const struct snd_kcontrol_new anc1_mux =
2080 SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
2081
2082static const struct snd_kcontrol_new anc2_mux =
2083 SOC_DAPM_ENUM("ANC2 MUX Mux", anc2_mux_enum);
2084
2085static const struct snd_kcontrol_new anc1_fb_mux =
2086 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
2087
2088static const struct snd_kcontrol_new dac1_switch[] = {
2089 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_EAR_EN, 5, 1, 0)
2090};
2091static const struct snd_kcontrol_new hphl_switch[] = {
2092 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
2093};
2094
2095static const struct snd_kcontrol_new hphl_pa_mix[] = {
2096 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2097 7, 1, 0),
2098};
2099
2100static const struct snd_kcontrol_new hphr_pa_mix[] = {
2101 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2102 6, 1, 0),
2103};
2104
2105static const struct snd_kcontrol_new ear_pa_mix[] = {
2106 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2107 5, 1, 0),
2108};
2109static const struct snd_kcontrol_new lineout1_pa_mix[] = {
2110 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2111 4, 1, 0),
2112};
2113
2114static const struct snd_kcontrol_new lineout2_pa_mix[] = {
2115 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2116 3, 1, 0),
2117};
2118
2119static const struct snd_kcontrol_new lineout3_pa_mix[] = {
2120 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2121 2, 1, 0),
2122};
2123
2124static const struct snd_kcontrol_new lineout4_pa_mix[] = {
2125 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
2126 1, 1, 0),
2127};
2128
2129static const struct snd_kcontrol_new lineout3_ground_switch =
2130 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_3_DAC_CTL, 6, 1, 0);
2131
2132static const struct snd_kcontrol_new lineout4_ground_switch =
2133 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_4_DAC_CTL, 6, 1, 0);
2134
Joonwoo Park9ead0e92013-03-18 11:33:33 -07002135static const struct snd_kcontrol_new aif4_mad_switch =
2136 SOC_DAPM_SINGLE("Switch", TAIKO_A_CDC_CLK_OTHR_CTL, 4, 1, 0);
2137
Kuirong Wang906ac472012-07-09 12:54:44 -07002138/* virtual port entries */
2139static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
2140 struct snd_ctl_elem_value *ucontrol)
2141{
2142 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2143 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2144
2145 ucontrol->value.integer.value[0] = widget->value;
2146 return 0;
2147}
2148
2149static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
2150 struct snd_ctl_elem_value *ucontrol)
2151{
2152 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2153 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2154 struct snd_soc_codec *codec = widget->codec;
2155 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
2156 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2157 struct soc_multi_mixer_control *mixer =
2158 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2159 u32 dai_id = widget->shift;
2160 u32 port_id = mixer->shift;
2161 u32 enable = ucontrol->value.integer.value[0];
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08002162 u32 vtable = vport_check_table[dai_id];
Kuirong Wang906ac472012-07-09 12:54:44 -07002163
2164
2165 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
2166 widget->name, ucontrol->id.name, widget->value, widget->shift,
2167 ucontrol->value.integer.value[0]);
2168
2169 mutex_lock(&codec->mutex);
2170
2171 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
2172 if (dai_id != AIF1_CAP) {
2173 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2174 __func__);
2175 mutex_unlock(&codec->mutex);
2176 return -EINVAL;
2177 }
2178 }
Venkat Sudhira41630a2012-10-27 00:57:31 -07002179 switch (dai_id) {
2180 case AIF1_CAP:
2181 case AIF2_CAP:
2182 case AIF3_CAP:
2183 /* only add to the list if value not set
2184 */
2185 if (enable && !(widget->value & 1 << port_id)) {
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08002186
2187 if (taiko_p->intf_type ==
2188 WCD9XXX_INTERFACE_TYPE_SLIMBUS)
2189 vtable = vport_check_table[dai_id];
2190 if (taiko_p->intf_type ==
2191 WCD9XXX_INTERFACE_TYPE_I2C)
2192 vtable = vport_i2s_check_table[dai_id];
2193
Venkat Sudhira41630a2012-10-27 00:57:31 -07002194 if (wcd9xxx_tx_vport_validation(
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08002195 vtable,
Kuirong Wangdcc392e2012-10-19 00:33:38 -07002196 port_id,
2197 taiko_p->dai)) {
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002198 dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n",
Venkat Sudhira41630a2012-10-27 00:57:31 -07002199 __func__, port_id + 1);
2200 mutex_unlock(&codec->mutex);
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002201 return 0;
Venkat Sudhira41630a2012-10-27 00:57:31 -07002202 }
2203 widget->value |= 1 << port_id;
2204 list_add_tail(&core->tx_chs[port_id].list,
Kuirong Wang906ac472012-07-09 12:54:44 -07002205 &taiko_p->dai[dai_id].wcd9xxx_ch_list
Venkat Sudhira41630a2012-10-27 00:57:31 -07002206 );
2207 } else if (!enable && (widget->value & 1 << port_id)) {
2208 widget->value &= ~(1 << port_id);
2209 list_del_init(&core->tx_chs[port_id].list);
2210 } else {
2211 if (enable)
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002212 dev_dbg(codec->dev, "%s: TX%u port is used by\n"
Venkat Sudhira41630a2012-10-27 00:57:31 -07002213 "this virtual port\n",
2214 __func__, port_id + 1);
2215 else
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002216 dev_dbg(codec->dev, "%s: TX%u port is not used by\n"
Venkat Sudhira41630a2012-10-27 00:57:31 -07002217 "this virtual port\n",
2218 __func__, port_id + 1);
2219 /* avoid update power function */
2220 mutex_unlock(&codec->mutex);
2221 return 0;
2222 }
2223 break;
2224 default:
2225 pr_err("Unknown AIF %d\n", dai_id);
Kuirong Wang906ac472012-07-09 12:54:44 -07002226 mutex_unlock(&codec->mutex);
Venkat Sudhira41630a2012-10-27 00:57:31 -07002227 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07002228 }
Kuirong Wang906ac472012-07-09 12:54:44 -07002229 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
2230 widget->name, widget->sname, widget->value, widget->shift);
2231
2232 snd_soc_dapm_mixer_update_power(widget, kcontrol, enable);
2233
2234 mutex_unlock(&codec->mutex);
2235 return 0;
2236}
2237
2238static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
2239 struct snd_ctl_elem_value *ucontrol)
2240{
2241 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2242 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2243
2244 ucontrol->value.enumerated.item[0] = widget->value;
2245 return 0;
2246}
2247
2248static const char *const slim_rx_mux_text[] = {
2249 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
2250};
2251
2252static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
2253 struct snd_ctl_elem_value *ucontrol)
2254{
2255 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2256 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2257 struct snd_soc_codec *codec = widget->codec;
2258 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
2259 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2260 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2261 u32 port_id = widget->shift;
2262
2263 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
2264 widget->name, ucontrol->id.name, widget->value, widget->shift,
2265 ucontrol->value.integer.value[0]);
2266
2267 widget->value = ucontrol->value.enumerated.item[0];
2268
2269 mutex_lock(&codec->mutex);
2270
2271 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Venkat Sudhir994193b2012-12-17 17:30:51 -08002272 if (widget->value > 2) {
Kuirong Wang906ac472012-07-09 12:54:44 -07002273 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2274 __func__);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07002275 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07002276 }
2277 }
2278 /* value need to match the Virtual port and AIF number
2279 */
2280 switch (widget->value) {
2281 case 0:
2282 list_del_init(&core->rx_chs[port_id].list);
2283 break;
2284 case 1:
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002285 if (wcd9xxx_rx_vport_validation(port_id +
2286 TAIKO_RX_PORT_START_NUMBER,
2287 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list)) {
2288 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2289 __func__, port_id + 1);
2290 goto rtn;
2291 }
Kuirong Wang906ac472012-07-09 12:54:44 -07002292 list_add_tail(&core->rx_chs[port_id].list,
2293 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list);
2294 break;
2295 case 2:
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002296 if (wcd9xxx_rx_vport_validation(port_id +
2297 TAIKO_RX_PORT_START_NUMBER,
2298 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list)) {
2299 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2300 __func__, port_id + 1);
2301 goto rtn;
2302 }
Kuirong Wang906ac472012-07-09 12:54:44 -07002303 list_add_tail(&core->rx_chs[port_id].list,
2304 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list);
2305 break;
2306 case 3:
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002307 if (wcd9xxx_rx_vport_validation(port_id +
2308 TAIKO_RX_PORT_START_NUMBER,
2309 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list)) {
2310 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2311 __func__, port_id + 1);
2312 goto rtn;
2313 }
Kuirong Wang906ac472012-07-09 12:54:44 -07002314 list_add_tail(&core->rx_chs[port_id].list,
2315 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list);
2316 break;
2317 default:
2318 pr_err("Unknown AIF %d\n", widget->value);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07002319 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07002320 }
Kuirong Wang80aca0d2013-05-09 14:51:09 -07002321rtn:
Kuirong Wang906ac472012-07-09 12:54:44 -07002322 snd_soc_dapm_mux_update_power(widget, kcontrol, 1, widget->value, e);
2323
2324 mutex_unlock(&codec->mutex);
2325 return 0;
Kuirong Wangdcc392e2012-10-19 00:33:38 -07002326err:
2327 mutex_unlock(&codec->mutex);
2328 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07002329}
2330
2331static const struct soc_enum slim_rx_mux_enum =
2332 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
2333
2334static const struct snd_kcontrol_new slim_rx_mux[TAIKO_RX_MAX] = {
2335 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
2336 slim_rx_mux_get, slim_rx_mux_put),
2337 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
2338 slim_rx_mux_get, slim_rx_mux_put),
2339 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
2340 slim_rx_mux_get, slim_rx_mux_put),
2341 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
2342 slim_rx_mux_get, slim_rx_mux_put),
2343 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
2344 slim_rx_mux_get, slim_rx_mux_put),
2345 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
2346 slim_rx_mux_get, slim_rx_mux_put),
2347 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
2348 slim_rx_mux_get, slim_rx_mux_put),
2349};
2350
2351static const struct snd_kcontrol_new aif_cap_mixer[] = {
2352 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TAIKO_TX1, 1, 0,
2353 slim_tx_mixer_get, slim_tx_mixer_put),
2354 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TAIKO_TX2, 1, 0,
2355 slim_tx_mixer_get, slim_tx_mixer_put),
2356 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TAIKO_TX3, 1, 0,
2357 slim_tx_mixer_get, slim_tx_mixer_put),
2358 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TAIKO_TX4, 1, 0,
2359 slim_tx_mixer_get, slim_tx_mixer_put),
2360 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TAIKO_TX5, 1, 0,
2361 slim_tx_mixer_get, slim_tx_mixer_put),
2362 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TAIKO_TX6, 1, 0,
2363 slim_tx_mixer_get, slim_tx_mixer_put),
2364 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TAIKO_TX7, 1, 0,
2365 slim_tx_mixer_get, slim_tx_mixer_put),
2366 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TAIKO_TX8, 1, 0,
2367 slim_tx_mixer_get, slim_tx_mixer_put),
2368 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TAIKO_TX9, 1, 0,
2369 slim_tx_mixer_get, slim_tx_mixer_put),
2370 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TAIKO_TX10, 1, 0,
2371 slim_tx_mixer_get, slim_tx_mixer_put),
2372};
2373
Kiran Kandic3b24402012-06-11 00:05:59 -07002374static void taiko_codec_enable_adc_block(struct snd_soc_codec *codec,
2375 int enable)
2376{
2377 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2378
2379 pr_debug("%s %d\n", __func__, enable);
2380
2381 if (enable) {
2382 taiko->adc_count++;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002383 snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
2384 0x2, 0x2);
Kiran Kandic3b24402012-06-11 00:05:59 -07002385 } else {
2386 taiko->adc_count--;
2387 if (!taiko->adc_count)
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002388 snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
Kiran Kandic3b24402012-06-11 00:05:59 -07002389 0x2, 0x0);
2390 }
2391}
2392
2393static int taiko_codec_enable_adc(struct snd_soc_dapm_widget *w,
2394 struct snd_kcontrol *kcontrol, int event)
2395{
2396 struct snd_soc_codec *codec = w->codec;
2397 u16 adc_reg;
2398 u8 init_bit_shift;
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002399 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07002400
2401 pr_debug("%s %d\n", __func__, event);
2402
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002403 if (TAIKO_IS_1_0(core->version)) {
2404 if (w->reg == TAIKO_A_TX_1_2_EN) {
2405 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2406 } else if (w->reg == TAIKO_A_TX_3_4_EN) {
2407 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2408 } else if (w->reg == TAIKO_A_TX_5_6_EN) {
2409 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2410 } else {
2411 pr_err("%s: Error, invalid adc register\n", __func__);
2412 return -EINVAL;
2413 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002414
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002415 if (w->shift == 3) {
2416 init_bit_shift = 6;
2417 } else if (w->shift == 7) {
2418 init_bit_shift = 7;
2419 } else {
2420 pr_err("%s: Error, invalid init bit postion adc register\n",
2421 __func__);
2422 return -EINVAL;
2423 }
2424 } else {
2425 switch (w->reg) {
2426 case TAIKO_A_CDC_TX_1_GAIN:
2427 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2428 init_bit_shift = 7;
2429 break;
2430 case TAIKO_A_CDC_TX_2_GAIN:
2431 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2432 init_bit_shift = 6;
2433 break;
2434 case TAIKO_A_CDC_TX_3_GAIN:
2435 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2436 init_bit_shift = 7;
2437 break;
2438 case TAIKO_A_CDC_TX_4_GAIN:
2439 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2440 init_bit_shift = 6;
2441 break;
2442 case TAIKO_A_CDC_TX_5_GAIN:
2443 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2444 init_bit_shift = 7;
2445 break;
2446 case TAIKO_A_CDC_TX_6_GAIN:
2447 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2448 init_bit_shift = 6;
2449 break;
2450 default:
2451 pr_err("%s: Error, invalid adc register\n", __func__);
2452 return -EINVAL;
2453 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002454 }
2455
2456 switch (event) {
2457 case SND_SOC_DAPM_PRE_PMU:
2458 taiko_codec_enable_adc_block(codec, 1);
2459 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
2460 1 << init_bit_shift);
2461 break;
2462 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002463 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -07002464 break;
2465 case SND_SOC_DAPM_POST_PMD:
2466 taiko_codec_enable_adc_block(codec, 0);
2467 break;
2468 }
2469 return 0;
2470}
2471
Kiran Kandic3b24402012-06-11 00:05:59 -07002472static int taiko_codec_enable_aux_pga(struct snd_soc_dapm_widget *w,
2473 struct snd_kcontrol *kcontrol, int event)
2474{
2475 struct snd_soc_codec *codec = w->codec;
2476 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2477
2478 pr_debug("%s: %d\n", __func__, event);
2479
2480 switch (event) {
2481 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Park533b3682013-06-13 11:41:21 -07002482 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Joonwoo Parka8890262012-10-15 12:04:27 -07002483 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
2484 WCD9XXX_BANDGAP_AUDIO_MODE);
2485 /* AUX PGA requires RCO or MCLK */
2486 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
2487 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
Joonwoo Park533b3682013-06-13 11:41:21 -07002488 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07002489 break;
2490
2491 case SND_SOC_DAPM_POST_PMD:
Joonwoo Park533b3682013-06-13 11:41:21 -07002492 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Joonwoo Parka8890262012-10-15 12:04:27 -07002493 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
2494 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
2495 WCD9XXX_BANDGAP_AUDIO_MODE);
2496 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
Joonwoo Park533b3682013-06-13 11:41:21 -07002497 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07002498 break;
2499 }
2500 return 0;
2501}
2502
2503static int taiko_codec_enable_lineout(struct snd_soc_dapm_widget *w,
2504 struct snd_kcontrol *kcontrol, int event)
2505{
2506 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002507 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002508 u16 lineout_gain_reg;
2509
2510 pr_debug("%s %d %s\n", __func__, event, w->name);
2511
2512 switch (w->shift) {
2513 case 0:
2514 lineout_gain_reg = TAIKO_A_RX_LINE_1_GAIN;
2515 break;
2516 case 1:
2517 lineout_gain_reg = TAIKO_A_RX_LINE_2_GAIN;
2518 break;
2519 case 2:
2520 lineout_gain_reg = TAIKO_A_RX_LINE_3_GAIN;
2521 break;
2522 case 3:
2523 lineout_gain_reg = TAIKO_A_RX_LINE_4_GAIN;
2524 break;
2525 default:
2526 pr_err("%s: Error, incorrect lineout register value\n",
2527 __func__);
2528 return -EINVAL;
2529 }
2530
2531 switch (event) {
2532 case SND_SOC_DAPM_PRE_PMU:
2533 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
2534 break;
2535 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002536 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2537 WCD9XXX_CLSH_STATE_LO,
2538 WCD9XXX_CLSH_REQ_ENABLE,
2539 WCD9XXX_CLSH_EVENT_POST_PA);
2540 pr_debug("%s: sleeping 3 ms after %s PA turn on\n",
Kiran Kandic3b24402012-06-11 00:05:59 -07002541 __func__, w->name);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002542 usleep_range(3000, 3000);
Kiran Kandic3b24402012-06-11 00:05:59 -07002543 break;
2544 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002545 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2546 WCD9XXX_CLSH_STATE_LO,
2547 WCD9XXX_CLSH_REQ_DISABLE,
2548 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandic3b24402012-06-11 00:05:59 -07002549 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
2550 break;
2551 }
2552 return 0;
2553}
2554
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002555static int taiko_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
2556 struct snd_kcontrol *kcontrol, int event)
2557{
Joonwoo Park125cd4e2012-12-11 15:16:11 -08002558 struct snd_soc_codec *codec = w->codec;
2559 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2560
2561 pr_debug("%s: %d %s\n", __func__, event, w->name);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08002562 switch (event) {
2563 case SND_SOC_DAPM_PRE_PMU:
2564 taiko->spkr_pa_widget_on = true;
2565 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
2566 break;
2567 case SND_SOC_DAPM_POST_PMD:
2568 taiko->spkr_pa_widget_on = false;
2569 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x00);
2570 break;
2571 }
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002572 return 0;
2573}
Kiran Kandic3b24402012-06-11 00:05:59 -07002574
2575static int taiko_codec_enable_dmic(struct snd_soc_dapm_widget *w,
2576 struct snd_kcontrol *kcontrol, int event)
2577{
2578 struct snd_soc_codec *codec = w->codec;
2579 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2580 u8 dmic_clk_en;
2581 u16 dmic_clk_reg;
2582 s32 *dmic_clk_cnt;
2583 unsigned int dmic;
2584 int ret;
2585
2586 ret = kstrtouint(strpbrk(w->name, "123456"), 10, &dmic);
2587 if (ret < 0) {
2588 pr_err("%s: Invalid DMIC line on the codec\n", __func__);
2589 return -EINVAL;
2590 }
2591
2592 switch (dmic) {
2593 case 1:
2594 case 2:
2595 dmic_clk_en = 0x01;
2596 dmic_clk_cnt = &(taiko->dmic_1_2_clk_cnt);
2597 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
2598 pr_debug("%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
2599 __func__, event, dmic, *dmic_clk_cnt);
2600
2601 break;
2602
2603 case 3:
2604 case 4:
2605 dmic_clk_en = 0x10;
2606 dmic_clk_cnt = &(taiko->dmic_3_4_clk_cnt);
2607 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
2608
2609 pr_debug("%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n",
2610 __func__, event, dmic, *dmic_clk_cnt);
2611 break;
2612
2613 case 5:
2614 case 6:
2615 dmic_clk_en = 0x01;
2616 dmic_clk_cnt = &(taiko->dmic_5_6_clk_cnt);
2617 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B2_CTL;
2618
2619 pr_debug("%s() event %d DMIC%d dmic_5_6_clk_cnt %d\n",
2620 __func__, event, dmic, *dmic_clk_cnt);
2621
2622 break;
2623
2624 default:
2625 pr_err("%s: Invalid DMIC Selection\n", __func__);
2626 return -EINVAL;
2627 }
2628
2629 switch (event) {
2630 case SND_SOC_DAPM_PRE_PMU:
2631
2632 (*dmic_clk_cnt)++;
2633 if (*dmic_clk_cnt == 1)
2634 snd_soc_update_bits(codec, dmic_clk_reg,
2635 dmic_clk_en, dmic_clk_en);
2636
2637 break;
2638 case SND_SOC_DAPM_POST_PMD:
2639
2640 (*dmic_clk_cnt)--;
2641 if (*dmic_clk_cnt == 0)
2642 snd_soc_update_bits(codec, dmic_clk_reg,
2643 dmic_clk_en, 0);
2644 break;
2645 }
2646 return 0;
2647}
2648
Joonwoo Park1d05bb92013-03-07 16:55:06 -08002649static int taiko_codec_config_mad(struct snd_soc_codec *codec)
2650{
2651 int ret;
2652 const struct firmware *fw;
2653 struct mad_audio_cal *mad_cal;
2654 const char *filename = TAIKO_MAD_AUDIO_FIRMWARE_PATH;
2655
2656 pr_debug("%s: enter\n", __func__);
2657 ret = request_firmware(&fw, filename, codec->dev);
2658 if (ret != 0) {
2659 pr_err("Failed to acquire MAD firwmare data %s: %d\n", filename,
2660 ret);
2661 return -ENODEV;
2662 }
2663
2664 if (fw->size < sizeof(struct mad_audio_cal)) {
2665 pr_err("%s: incorrect firmware size %u\n", __func__, fw->size);
2666 release_firmware(fw);
2667 return -ENOMEM;
2668 }
2669
2670 mad_cal = (struct mad_audio_cal *)(fw->data);
2671 if (!mad_cal) {
2672 pr_err("%s: Invalid calibration data\n", __func__);
2673 release_firmware(fw);
2674 return -EINVAL;
2675 }
2676
Joonwoo Park1d05bb92013-03-07 16:55:06 -08002677 snd_soc_write(codec, TAIKO_A_CDC_MAD_MAIN_CTL_2,
2678 mad_cal->microphone_info.cycle_time);
2679 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_MAIN_CTL_1, 0xFF << 3,
2680 ((uint16_t)mad_cal->microphone_info.settle_time)
2681 << 3);
2682
2683 /* Audio */
2684 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_8,
2685 mad_cal->audio_info.rms_omit_samples);
2686 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_1,
2687 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
2688 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_2, 0x03 << 2,
2689 mad_cal->audio_info.detection_mechanism << 2);
2690 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_7,
2691 mad_cal->audio_info.rms_diff_threshold & 0x3F);
2692 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_5,
2693 mad_cal->audio_info.rms_threshold_lsb);
2694 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_6,
2695 mad_cal->audio_info.rms_threshold_msb);
2696
2697
2698 /* Beacon */
2699 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_8,
2700 mad_cal->beacon_info.rms_omit_samples);
2701 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_1,
2702 0x07 << 4, mad_cal->beacon_info.rms_comp_time);
2703 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_2, 0x03 << 2,
2704 mad_cal->beacon_info.detection_mechanism << 2);
2705 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_7,
2706 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
2707 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_5,
2708 mad_cal->beacon_info.rms_threshold_lsb);
2709 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_6,
2710 mad_cal->beacon_info.rms_threshold_msb);
2711
2712 /* Ultrasound */
2713 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_1,
2714 0x07 << 4, mad_cal->beacon_info.rms_comp_time);
2715 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_ULTR_CTL_2, 0x03 << 2,
2716 mad_cal->ultrasound_info.detection_mechanism);
2717 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_7,
2718 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
2719 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_5,
2720 mad_cal->ultrasound_info.rms_threshold_lsb);
2721 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_6,
2722 mad_cal->ultrasound_info.rms_threshold_msb);
2723
2724 release_firmware(fw);
2725 pr_debug("%s: leave ret %d\n", __func__, ret);
2726
2727 return ret;
2728}
2729
2730static int taiko_codec_enable_mad(struct snd_soc_dapm_widget *w,
2731 struct snd_kcontrol *kcontrol, int event)
2732{
2733 struct snd_soc_codec *codec = w->codec;
2734 int ret = 0;
2735
2736 pr_debug("%s %d\n", __func__, event);
2737 switch (event) {
2738 case SND_SOC_DAPM_PRE_PMU:
2739 ret = taiko_codec_config_mad(codec);
2740 if (ret) {
2741 pr_err("%s: Failed to config MAD\n", __func__);
2742 break;
2743 }
2744 break;
2745 }
2746 return ret;
2747}
2748
Kiran Kandic3b24402012-06-11 00:05:59 -07002749static int taiko_codec_enable_micbias(struct snd_soc_dapm_widget *w,
2750 struct snd_kcontrol *kcontrol, int event)
2751{
2752 struct snd_soc_codec *codec = w->codec;
2753 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Park3699ca32013-02-08 12:06:15 -08002754 u16 micb_int_reg = 0, micb_ctl_reg = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07002755 u8 cfilt_sel_val = 0;
2756 char *internal1_text = "Internal1";
2757 char *internal2_text = "Internal2";
2758 char *internal3_text = "Internal3";
Joonwoo Parka8890262012-10-15 12:04:27 -07002759 enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
Kiran Kandic3b24402012-06-11 00:05:59 -07002760
Joonwoo Park3699ca32013-02-08 12:06:15 -08002761 pr_debug("%s: w->name %s event %d\n", __func__, w->name, event);
2762 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) {
2763 micb_ctl_reg = TAIKO_A_MICB_1_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002764 micb_int_reg = TAIKO_A_MICB_1_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002765 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias1_cfilt_sel;
2766 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
2767 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
2768 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002769 } else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) {
2770 micb_ctl_reg = TAIKO_A_MICB_2_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002771 micb_int_reg = TAIKO_A_MICB_2_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002772 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias2_cfilt_sel;
2773 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
2774 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
2775 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002776 } else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) {
Damir Didjusto6e4f9d22013-03-07 10:10:57 -08002777 micb_ctl_reg = TAIKO_A_MICB_3_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002778 micb_int_reg = TAIKO_A_MICB_3_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002779 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias3_cfilt_sel;
2780 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
2781 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
2782 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002783 } else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) {
Damir Didjusto6e4f9d22013-03-07 10:10:57 -08002784 micb_ctl_reg = TAIKO_A_MICB_4_CTL;
Joonwoo Parka8890262012-10-15 12:04:27 -07002785 micb_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
2786 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias4_cfilt_sel;
2787 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_4_ON;
2788 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_4_ON;
2789 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_4_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002790 } else {
2791 pr_err("%s: Error, invalid micbias %s\n", __func__, w->name);
Kiran Kandic3b24402012-06-11 00:05:59 -07002792 return -EINVAL;
2793 }
2794
2795 switch (event) {
2796 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002797 /* Let MBHC module know so micbias switch to be off */
2798 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002799
Joonwoo Parka8890262012-10-15 12:04:27 -07002800 /* Get cfilt */
2801 wcd9xxx_resmgr_cfilt_get(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002802
2803 if (strnstr(w->name, internal1_text, 30))
2804 snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
2805 else if (strnstr(w->name, internal2_text, 30))
2806 snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
2807 else if (strnstr(w->name, internal3_text, 30))
2808 snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
2809
Joonwoo Parkccccba72013-04-26 11:19:46 -07002810 if (taiko->mbhc_started && micb_ctl_reg == TAIKO_A_MICB_2_CTL) {
2811 if (++taiko->micb_2_users == 1) {
2812 if (taiko->resmgr.pdata->
2813 micbias.bias2_is_headset_only)
2814 wcd9xxx_resmgr_add_cond_update_bits(
2815 &taiko->resmgr,
2816 WCD9XXX_COND_HPH_MIC,
2817 micb_ctl_reg, w->shift,
2818 false);
2819 else
2820 snd_soc_update_bits(codec, micb_ctl_reg,
2821 1 << w->shift,
2822 1 << w->shift);
2823 }
2824 pr_debug("%s: micb_2_users %d\n", __func__,
2825 taiko->micb_2_users);
2826 } else {
Joonwoo Park3699ca32013-02-08 12:06:15 -08002827 snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
2828 1 << w->shift);
Joonwoo Parkccccba72013-04-26 11:19:46 -07002829 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002830 break;
2831 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002832 usleep_range(20000, 20000);
Joonwoo Parka8890262012-10-15 12:04:27 -07002833 /* Let MBHC module know so micbias is on */
2834 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002835 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07002836 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parkccccba72013-04-26 11:19:46 -07002837 if (taiko->mbhc_started && micb_ctl_reg == TAIKO_A_MICB_2_CTL) {
2838 if (--taiko->micb_2_users == 0) {
2839 if (taiko->resmgr.pdata->
2840 micbias.bias2_is_headset_only)
2841 wcd9xxx_resmgr_rm_cond_update_bits(
2842 &taiko->resmgr,
2843 WCD9XXX_COND_HPH_MIC,
2844 micb_ctl_reg, 7, false);
2845 else
2846 snd_soc_update_bits(codec, micb_ctl_reg,
2847 1 << w->shift, 0);
2848 }
2849 pr_debug("%s: micb_2_users %d\n", __func__,
2850 taiko->micb_2_users);
2851 WARN(taiko->micb_2_users < 0,
2852 "Unexpected micbias users %d\n",
2853 taiko->micb_2_users);
2854 } else {
Joonwoo Park3699ca32013-02-08 12:06:15 -08002855 snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
2856 0);
Joonwoo Parkccccba72013-04-26 11:19:46 -07002857 }
Joonwoo Park3699ca32013-02-08 12:06:15 -08002858
Joonwoo Parka8890262012-10-15 12:04:27 -07002859 /* Let MBHC module know so micbias switch to be off */
2860 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
Kiran Kandic3b24402012-06-11 00:05:59 -07002861
2862 if (strnstr(w->name, internal1_text, 30))
2863 snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
2864 else if (strnstr(w->name, internal2_text, 30))
2865 snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
2866 else if (strnstr(w->name, internal3_text, 30))
2867 snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
2868
Joonwoo Parka8890262012-10-15 12:04:27 -07002869 /* Put cfilt */
2870 wcd9xxx_resmgr_cfilt_put(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002871 break;
2872 }
2873
2874 return 0;
2875}
2876
Joonwoo Parkccccba72013-04-26 11:19:46 -07002877/* called under codec_resource_lock acquisition */
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07002878static int taiko_enable_mbhc_micbias(struct snd_soc_codec *codec, bool enable,
2879 enum wcd9xxx_micbias_num micb_num)
Joonwoo Parkccccba72013-04-26 11:19:46 -07002880{
2881 int rc;
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07002882 const char *micbias;
2883
2884 if (micb_num != MBHC_MICBIAS3 &&
2885 micb_num != MBHC_MICBIAS2)
2886 return -EINVAL;
2887
2888 micbias = (micb_num == MBHC_MICBIAS3) ?
2889 DAPM_MICBIAS3_EXTERNAL_STANDALONE :
2890 DAPM_MICBIAS2_EXTERNAL_STANDALONE;
Joonwoo Parkccccba72013-04-26 11:19:46 -07002891
2892 if (enable)
2893 rc = snd_soc_dapm_force_enable_pin(&codec->dapm,
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07002894 micbias);
Joonwoo Parkccccba72013-04-26 11:19:46 -07002895 else
2896 rc = snd_soc_dapm_disable_pin(&codec->dapm,
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07002897 micbias);
Joonwoo Parkccccba72013-04-26 11:19:46 -07002898 if (!rc)
2899 snd_soc_dapm_sync(&codec->dapm);
2900 pr_debug("%s: leave ret %d\n", __func__, rc);
2901 return rc;
2902}
Kiran Kandic3b24402012-06-11 00:05:59 -07002903
2904static void tx_hpf_corner_freq_callback(struct work_struct *work)
2905{
2906 struct delayed_work *hpf_delayed_work;
2907 struct hpf_work *hpf_work;
2908 struct taiko_priv *taiko;
2909 struct snd_soc_codec *codec;
2910 u16 tx_mux_ctl_reg;
2911 u8 hpf_cut_of_freq;
2912
2913 hpf_delayed_work = to_delayed_work(work);
2914 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
2915 taiko = hpf_work->taiko;
2916 codec = hpf_work->taiko->codec;
2917 hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
2918
2919 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL +
2920 (hpf_work->decimator - 1) * 8;
2921
2922 pr_debug("%s(): decimator %u hpf_cut_of_freq 0x%x\n", __func__,
2923 hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
2924
2925 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
2926}
2927
2928#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30
2929#define CF_MIN_3DB_4HZ 0x0
2930#define CF_MIN_3DB_75HZ 0x1
2931#define CF_MIN_3DB_150HZ 0x2
2932
2933static int taiko_codec_enable_dec(struct snd_soc_dapm_widget *w,
2934 struct snd_kcontrol *kcontrol, int event)
2935{
2936 struct snd_soc_codec *codec = w->codec;
2937 unsigned int decimator;
2938 char *dec_name = NULL;
2939 char *widget_name = NULL;
2940 char *temp;
2941 int ret = 0;
2942 u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
2943 u8 dec_hpf_cut_of_freq;
2944 int offset;
2945
2946
2947 pr_debug("%s %d\n", __func__, event);
2948
2949 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
2950 if (!widget_name)
2951 return -ENOMEM;
2952 temp = widget_name;
2953
2954 dec_name = strsep(&widget_name, " ");
2955 widget_name = temp;
2956 if (!dec_name) {
2957 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
2958 ret = -EINVAL;
2959 goto out;
2960 }
2961
2962 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
2963 if (ret < 0) {
2964 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
2965 ret = -EINVAL;
2966 goto out;
2967 }
2968
2969 pr_debug("%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
2970 w->name, dec_name, decimator);
2971
2972 if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
2973 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B1_CTL;
2974 offset = 0;
2975 } else if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL) {
2976 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B2_CTL;
2977 offset = 8;
2978 } else {
2979 pr_err("%s: Error, incorrect dec\n", __func__);
2980 return -EINVAL;
2981 }
2982
2983 tx_vol_ctl_reg = TAIKO_A_CDC_TX1_VOL_CTL_CFG + 8 * (decimator - 1);
2984 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
2985
2986 switch (event) {
2987 case SND_SOC_DAPM_PRE_PMU:
2988
2989 /* Enableable TX digital mute */
2990 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2991
2992 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
2993 1 << w->shift);
2994 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
2995
2996 dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
2997
2998 dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
2999
3000 tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
3001 dec_hpf_cut_of_freq;
3002
3003 if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
3004
3005 /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
3006 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
3007 CF_MIN_3DB_150HZ << 4);
3008 }
3009
3010 /* enable HPF */
3011 snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
3012
3013 break;
3014
3015 case SND_SOC_DAPM_POST_PMU:
3016
3017 /* Disable TX digital mute */
3018 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
3019
3020 if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
3021 CF_MIN_3DB_150HZ) {
3022
3023 schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
3024 msecs_to_jiffies(300));
3025 }
3026 /* apply the digital gain after the decimator is enabled*/
Damir Didjustoed406e22012-11-16 15:44:57 -08003027 if ((w->shift + offset) < ARRAY_SIZE(tx_digital_gain_reg))
Kiran Kandic3b24402012-06-11 00:05:59 -07003028 snd_soc_write(codec,
3029 tx_digital_gain_reg[w->shift + offset],
3030 snd_soc_read(codec,
3031 tx_digital_gain_reg[w->shift + offset])
3032 );
3033
3034 break;
3035
3036 case SND_SOC_DAPM_PRE_PMD:
3037
3038 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
3039 cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
3040 break;
3041
3042 case SND_SOC_DAPM_POST_PMD:
3043
3044 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
3045 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
3046 (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
3047
3048 break;
3049 }
3050out:
3051 kfree(widget_name);
3052 return ret;
3053}
3054
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003055static int taiko_codec_enable_vdd_spkr(struct snd_soc_dapm_widget *w,
3056 struct snd_kcontrol *kcontrol, int event)
3057{
3058 int ret = 0;
3059 struct snd_soc_codec *codec = w->codec;
3060 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Joonwoo Park448a8fc2013-04-10 15:25:58 -07003061 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003062
3063 pr_debug("%s: %d %s\n", __func__, event, w->name);
Joonwoo Park448a8fc2013-04-10 15:25:58 -07003064
3065 WARN_ONCE(!priv->spkdrv_reg, "SPKDRV supply %s isn't defined\n",
3066 WCD9XXX_VDD_SPKDRV_NAME);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003067 switch (event) {
3068 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Park448a8fc2013-04-10 15:25:58 -07003069 if (priv->spkdrv_reg) {
3070 ret = regulator_enable(priv->spkdrv_reg);
3071 if (ret)
3072 pr_err("%s: Failed to enable spkdrv_reg %s\n",
3073 __func__, WCD9XXX_VDD_SPKDRV_NAME);
3074 }
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003075 if (spkr_drv_wrnd > 0) {
3076 WARN_ON(!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
3077 0x80));
3078 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
3079 0x00);
3080 }
3081 if (TAIKO_IS_1_0(core->version))
3082 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
3083 0x24, 0x00);
3084 break;
3085 case SND_SOC_DAPM_POST_PMD:
3086 if (TAIKO_IS_1_0(core->version))
3087 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
3088 0x24, 0x24);
3089 if (spkr_drv_wrnd > 0) {
3090 WARN_ON(!!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
3091 0x80));
3092 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
3093 0x80);
3094 }
Joonwoo Park448a8fc2013-04-10 15:25:58 -07003095 if (priv->spkdrv_reg) {
3096 ret = regulator_disable(priv->spkdrv_reg);
3097 if (ret)
3098 pr_err("%s: Failed to disable spkdrv_reg %s\n",
3099 __func__, WCD9XXX_VDD_SPKDRV_NAME);
3100 }
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003101 break;
3102 }
3103
3104 return ret;
3105}
3106
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003107static int taiko_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07003108 struct snd_kcontrol *kcontrol, int event)
3109{
3110 struct snd_soc_codec *codec = w->codec;
3111
3112 pr_debug("%s %d %s\n", __func__, event, w->name);
3113
3114 switch (event) {
3115 case SND_SOC_DAPM_PRE_PMU:
3116 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
3117 1 << w->shift, 1 << w->shift);
3118 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
3119 1 << w->shift, 0x0);
3120 break;
3121 case SND_SOC_DAPM_POST_PMU:
3122 /* apply the digital gain after the interpolator is enabled*/
3123 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
3124 snd_soc_write(codec,
3125 rx_digital_gain_reg[w->shift],
3126 snd_soc_read(codec,
3127 rx_digital_gain_reg[w->shift])
3128 );
3129 break;
3130 }
3131 return 0;
3132}
3133
Joonwoo Parkccccba72013-04-26 11:19:46 -07003134/* called under codec_resource_lock acquisition */
3135static int __taiko_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
3136 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07003137{
Joonwoo Parkccccba72013-04-26 11:19:46 -07003138 struct snd_soc_codec *codec = w->codec;
3139 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
3140
3141 pr_debug("%s: enter\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07003142 switch (event) {
Joonwoo Parkccccba72013-04-26 11:19:46 -07003143 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Park533b3682013-06-13 11:41:21 -07003144 /*
3145 * ldo_h_users is protected by codec->mutex, don't need
3146 * additional mutex
3147 */
Joonwoo Parkccccba72013-04-26 11:19:46 -07003148 if (++priv->ldo_h_users == 1) {
Joonwoo Park533b3682013-06-13 11:41:21 -07003149 WCD9XXX_BG_CLK_LOCK(&priv->resmgr);
Joonwoo Parkccccba72013-04-26 11:19:46 -07003150 wcd9xxx_resmgr_get_bandgap(&priv->resmgr,
3151 WCD9XXX_BANDGAP_AUDIO_MODE);
3152 wcd9xxx_resmgr_get_clk_block(&priv->resmgr,
3153 WCD9XXX_CLK_RCO);
3154 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 1 << 7,
3155 1 << 7);
3156 wcd9xxx_resmgr_put_clk_block(&priv->resmgr,
3157 WCD9XXX_CLK_RCO);
Joonwoo Park533b3682013-06-13 11:41:21 -07003158 WCD9XXX_BG_CLK_UNLOCK(&priv->resmgr);
Joonwoo Parkccccba72013-04-26 11:19:46 -07003159 pr_debug("%s: ldo_h_users %d\n", __func__,
3160 priv->ldo_h_users);
3161 /* LDO enable requires 1ms to settle down */
3162 usleep_range(1000, 1000);
3163 }
3164 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07003165 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parkccccba72013-04-26 11:19:46 -07003166 if (--priv->ldo_h_users == 0) {
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_clk_block(&priv->resmgr,
3169 WCD9XXX_CLK_RCO);
3170 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 1 << 7,
3171 0);
3172 wcd9xxx_resmgr_put_clk_block(&priv->resmgr,
3173 WCD9XXX_CLK_RCO);
3174 wcd9xxx_resmgr_put_bandgap(&priv->resmgr,
3175 WCD9XXX_BANDGAP_AUDIO_MODE);
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 }
3180 WARN(priv->ldo_h_users < 0, "Unexpected ldo_h users %d\n",
3181 priv->ldo_h_users);
Kiran Kandic3b24402012-06-11 00:05:59 -07003182 break;
3183 }
Joonwoo Parkccccba72013-04-26 11:19:46 -07003184 pr_debug("%s: leave\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07003185 return 0;
3186}
3187
Joonwoo Parkccccba72013-04-26 11:19:46 -07003188static int taiko_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
3189 struct snd_kcontrol *kcontrol, int event)
3190{
3191 int rc;
Joonwoo Parkccccba72013-04-26 11:19:46 -07003192 rc = __taiko_codec_enable_ldo_h(w, kcontrol, event);
Joonwoo Parkccccba72013-04-26 11:19:46 -07003193 return rc;
3194}
3195
Kiran Kandic3b24402012-06-11 00:05:59 -07003196static int taiko_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
3197 struct snd_kcontrol *kcontrol, int event)
3198{
3199 struct snd_soc_codec *codec = w->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07003200 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003201
3202 pr_debug("%s %d\n", __func__, event);
3203
3204 switch (event) {
3205 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07003206 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
Kiran Kandic3b24402012-06-11 00:05:59 -07003207 break;
3208 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07003209 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
Kiran Kandic3b24402012-06-11 00:05:59 -07003210 break;
3211 }
3212 return 0;
3213}
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003214
3215static int taiko_hphl_dac_event(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07003216 struct snd_kcontrol *kcontrol, int event)
3217{
3218 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003219 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Santosh Mardi93a69192013-07-03 23:37:29 +05303220 uint32_t impedl, impedr;
3221 int ret = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07003222
3223 pr_debug("%s %s %d\n", __func__, w->name, event);
3224
3225 switch (event) {
3226 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003227 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
3228 0x02, 0x02);
3229 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
3230 WCD9XXX_CLSH_STATE_HPHL,
3231 WCD9XXX_CLSH_REQ_ENABLE,
3232 WCD9XXX_CLSH_EVENT_PRE_DAC);
Santosh Mardi93a69192013-07-03 23:37:29 +05303233 ret = wcd9xxx_mbhc_get_impedance(&taiko_p->mbhc,
3234 &impedl, &impedr);
3235 if (!ret)
3236 wcd9xxx_clsh_imped_config(codec, impedl);
3237 else
3238 dev_err(codec->dev, "Failed to get mbhc impedance %d\n",
3239 ret);
Kiran Kandic3b24402012-06-11 00:05:59 -07003240 break;
3241 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003242 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
3243 0x02, 0x00);
3244 }
3245 return 0;
3246}
3247
3248static int taiko_hphr_dac_event(struct snd_soc_dapm_widget *w,
3249 struct snd_kcontrol *kcontrol, int event)
3250{
3251 struct snd_soc_codec *codec = w->codec;
3252 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
3253
3254 pr_debug("%s %s %d\n", __func__, w->name, event);
3255
3256 switch (event) {
3257 case SND_SOC_DAPM_PRE_PMU:
3258 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
3259 0x04, 0x04);
3260 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
3261 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
3262 WCD9XXX_CLSH_STATE_HPHR,
3263 WCD9XXX_CLSH_REQ_ENABLE,
3264 WCD9XXX_CLSH_EVENT_PRE_DAC);
3265 break;
3266 case SND_SOC_DAPM_POST_PMD:
3267 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
3268 0x04, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -07003269 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
3270 break;
3271 }
3272 return 0;
3273}
3274
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003275static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
3276 struct snd_kcontrol *kcontrol, int event)
3277{
3278 struct snd_soc_codec *codec = w->codec;
3279 const char *filename;
3280 const struct firmware *fw;
3281 int i;
3282 int ret;
3283 int num_anc_slots;
Simmi Pateriyadf675e92013-04-05 01:15:54 +05303284 struct wcd9xxx_anc_header *anc_head;
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003285 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3286 u32 anc_writes_size = 0;
3287 int anc_size_remaining;
3288 u32 *anc_ptr;
3289 u16 reg;
3290 u8 mask, val, old_val;
3291
3292
3293 if (taiko->anc_func == 0)
3294 return 0;
3295
3296 switch (event) {
3297 case SND_SOC_DAPM_PRE_PMU:
3298 filename = "wcd9320/wcd9320_anc.bin";
3299
3300 ret = request_firmware(&fw, filename, codec->dev);
3301 if (ret != 0) {
3302 dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
3303 ret);
3304 return -ENODEV;
3305 }
3306
Simmi Pateriyadf675e92013-04-05 01:15:54 +05303307 if (fw->size < sizeof(struct wcd9xxx_anc_header)) {
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003308 dev_err(codec->dev, "Not enough data\n");
3309 release_firmware(fw);
3310 return -ENOMEM;
3311 }
3312
3313 /* First number is the number of register writes */
Simmi Pateriyadf675e92013-04-05 01:15:54 +05303314 anc_head = (struct wcd9xxx_anc_header *)(fw->data);
3315 anc_ptr = (u32 *)((u32)fw->data +
3316 sizeof(struct wcd9xxx_anc_header));
3317 anc_size_remaining = fw->size -
3318 sizeof(struct wcd9xxx_anc_header);
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003319 num_anc_slots = anc_head->num_anc_slots;
3320
3321 if (taiko->anc_slot >= num_anc_slots) {
3322 dev_err(codec->dev, "Invalid ANC slot selected\n");
3323 release_firmware(fw);
3324 return -EINVAL;
3325 }
3326 for (i = 0; i < num_anc_slots; i++) {
3327 if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
3328 dev_err(codec->dev, "Invalid register format\n");
3329 release_firmware(fw);
3330 return -EINVAL;
3331 }
3332 anc_writes_size = (u32)(*anc_ptr);
3333 anc_size_remaining -= sizeof(u32);
3334 anc_ptr += 1;
3335
3336 if (anc_writes_size * TAIKO_PACKED_REG_SIZE
3337 > anc_size_remaining) {
3338 dev_err(codec->dev, "Invalid register format\n");
3339 release_firmware(fw);
3340 return -ENOMEM;
3341 }
3342
3343 if (taiko->anc_slot == i)
3344 break;
3345
3346 anc_size_remaining -= (anc_writes_size *
3347 TAIKO_PACKED_REG_SIZE);
3348 anc_ptr += anc_writes_size;
3349 }
3350 if (i == num_anc_slots) {
3351 dev_err(codec->dev, "Selected ANC slot not present\n");
3352 release_firmware(fw);
3353 return -ENOMEM;
3354 }
3355 for (i = 0; i < anc_writes_size; i++) {
3356 TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
3357 mask, val);
3358 old_val = snd_soc_read(codec, reg);
3359 snd_soc_write(codec, reg, (old_val & ~mask) |
3360 (val & mask));
3361 }
3362 release_firmware(fw);
3363 break;
Damir Didjustoaf0085c2013-05-02 17:47:45 -07003364 case SND_SOC_DAPM_PRE_PMD:
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003365 msleep(40);
3366 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B1_CTL, 0x01, 0x00);
3367 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC2_B1_CTL, 0x02, 0x00);
3368 msleep(20);
3369 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0x0F);
3370 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
3371 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
3372 break;
3373 }
3374 return 0;
3375}
3376
Kiran Kandic3b24402012-06-11 00:05:59 -07003377static int taiko_hph_pa_event(struct snd_soc_dapm_widget *w,
Joonwoo Parka8890262012-10-15 12:04:27 -07003378 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07003379{
3380 struct snd_soc_codec *codec = w->codec;
3381 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07003382 enum wcd9xxx_notify_event e_pre_on, e_post_off;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003383 u8 req_clsh_state;
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07003384 u32 pa_settle_time = TAIKO_HPH_PA_SETTLE_COMP_OFF;
Joonwoo Parka8890262012-10-15 12:04:27 -07003385
Kiran Kandi4c56c592012-07-25 11:04:55 -07003386 pr_debug("%s: %s event = %d\n", __func__, w->name, event);
Joonwoo Parka8890262012-10-15 12:04:27 -07003387 if (w->shift == 5) {
Joonwoo Parka8890262012-10-15 12:04:27 -07003388 e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
3389 e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
Patrick Lai453cd742013-03-02 16:51:27 -08003390 req_clsh_state = WCD9XXX_CLSH_STATE_HPHL;
3391 } else if (w->shift == 4) {
3392 e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
3393 e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003394 req_clsh_state = WCD9XXX_CLSH_STATE_HPHR;
Joonwoo Parka8890262012-10-15 12:04:27 -07003395 } else {
3396 pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
3397 return -EINVAL;
3398 }
Kiran Kandic3b24402012-06-11 00:05:59 -07003399
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07003400 if (taiko->comp_enabled[COMPANDER_1])
3401 pa_settle_time = TAIKO_HPH_PA_SETTLE_COMP_ON;
3402
Kiran Kandic3b24402012-06-11 00:05:59 -07003403 switch (event) {
3404 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07003405 /* Let MBHC module know PA is turning on */
3406 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07003407 break;
3408
Kiran Kandi4c56c592012-07-25 11:04:55 -07003409 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07003410 usleep_range(pa_settle_time, pa_settle_time + 1000);
3411 pr_debug("%s: sleep %d us after %s PA enable\n", __func__,
3412 pa_settle_time, w->name);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003413 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
3414 req_clsh_state,
3415 WCD9XXX_CLSH_REQ_ENABLE,
3416 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandi4c56c592012-07-25 11:04:55 -07003417
Kiran Kandi4c56c592012-07-25 11:04:55 -07003418 break;
3419
Kiran Kandic3b24402012-06-11 00:05:59 -07003420 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07003421 usleep_range(pa_settle_time, pa_settle_time + 1000);
3422 pr_debug("%s: sleep %d us after %s PA disable\n", __func__,
3423 pa_settle_time, w->name);
3424
Joonwoo Parka8890262012-10-15 12:04:27 -07003425 /* Let MBHC module know PA turned off */
3426 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
3427
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003428 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
3429 req_clsh_state,
3430 WCD9XXX_CLSH_REQ_DISABLE,
3431 WCD9XXX_CLSH_EVENT_POST_PA);
3432
Kiran Kandic3b24402012-06-11 00:05:59 -07003433 break;
3434 }
3435 return 0;
3436}
3437
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003438static int taiko_codec_enable_anc_hph(struct snd_soc_dapm_widget *w,
3439 struct snd_kcontrol *kcontrol, int event)
3440{
3441 struct snd_soc_codec *codec = w->codec;
3442 int ret = 0;
3443
3444 switch (event) {
3445 case SND_SOC_DAPM_PRE_PMU:
3446 ret = taiko_hph_pa_event(w, kcontrol, event);
3447 if (w->shift == 4) {
3448 ret |= taiko_codec_enable_anc(w, kcontrol, event);
3449 msleep(50);
3450 }
3451 break;
3452 case SND_SOC_DAPM_POST_PMU:
3453 if (w->shift == 4) {
3454 snd_soc_update_bits(codec,
3455 TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x30);
3456 msleep(30);
3457 }
3458 ret = taiko_hph_pa_event(w, kcontrol, event);
3459 break;
3460 case SND_SOC_DAPM_PRE_PMD:
3461 if (w->shift == 5) {
3462 snd_soc_update_bits(codec,
3463 TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x00);
3464 msleep(40);
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003465 snd_soc_update_bits(codec,
3466 TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
3467 ret |= taiko_codec_enable_anc(w, kcontrol, event);
3468 }
Damir Didjusto340f6f32013-06-28 17:24:13 -07003469 break;
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003470 case SND_SOC_DAPM_POST_PMD:
3471 ret = taiko_hph_pa_event(w, kcontrol, event);
3472 break;
3473 }
3474 return ret;
3475}
3476
Kiran Kandic3b24402012-06-11 00:05:59 -07003477static const struct snd_soc_dapm_widget taiko_dapm_i2s_widgets[] = {
3478 SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", TAIKO_A_CDC_CLK_RX_I2S_CTL,
3479 4, 0, NULL, 0),
3480 SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", TAIKO_A_CDC_CLK_TX_I2S_CTL, 4,
3481 0, NULL, 0),
3482};
3483
3484static int taiko_lineout_dac_event(struct snd_soc_dapm_widget *w,
3485 struct snd_kcontrol *kcontrol, int event)
3486{
3487 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003488 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003489
3490 pr_debug("%s %s %d\n", __func__, w->name, event);
3491
3492 switch (event) {
3493 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003494 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
3495 WCD9XXX_CLSH_STATE_LO,
3496 WCD9XXX_CLSH_REQ_ENABLE,
3497 WCD9XXX_CLSH_EVENT_PRE_DAC);
Kiran Kandic3b24402012-06-11 00:05:59 -07003498 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
3499 break;
3500
3501 case SND_SOC_DAPM_POST_PMD:
3502 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
3503 break;
3504 }
3505 return 0;
3506}
3507
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003508static int taiko_spk_dac_event(struct snd_soc_dapm_widget *w,
3509 struct snd_kcontrol *kcontrol, int event)
3510{
3511 pr_debug("%s %s %d\n", __func__, w->name, event);
3512 return 0;
3513}
3514
Kiran Kandic3b24402012-06-11 00:05:59 -07003515static const struct snd_soc_dapm_route audio_i2s_map[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07003516 {"SLIM RX1", NULL, "RX_I2S_CLK"},
3517 {"SLIM RX2", NULL, "RX_I2S_CLK"},
3518 {"SLIM RX3", NULL, "RX_I2S_CLK"},
3519 {"SLIM RX4", NULL, "RX_I2S_CLK"},
3520
Venkat Sudhira41630a2012-10-27 00:57:31 -07003521 {"SLIM TX7 MUX", NULL, "TX_I2S_CLK"},
3522 {"SLIM TX8 MUX", NULL, "TX_I2S_CLK"},
3523 {"SLIM TX9 MUX", NULL, "TX_I2S_CLK"},
3524 {"SLIM TX10 MUX", NULL, "TX_I2S_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003525};
3526
Joonwoo Park559a5bf2013-02-15 14:46:36 -08003527static const struct snd_soc_dapm_route audio_i2s_map_1_0[] = {
3528 {"RX_I2S_CLK", NULL, "CDC_CONN"},
3529};
3530
3531static const struct snd_soc_dapm_route audio_i2s_map_2_0[] = {
3532 {"RX_I2S_CLK", NULL, "CDC_I2S_RX_CONN"},
3533};
3534
Kiran Kandic3b24402012-06-11 00:05:59 -07003535static const struct snd_soc_dapm_route audio_map[] = {
3536 /* SLIMBUS Connections */
Kuirong Wang906ac472012-07-09 12:54:44 -07003537 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
3538 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
3539 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003540 {"AIF4 VI", NULL, "SPK_OUT"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003541
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003542 /* MAD */
3543 {"AIF4 MAD", NULL, "CDC_CONN"},
Joonwoo Park9ead0e92013-03-18 11:33:33 -07003544 {"MADONOFF", "Switch", "MADINPUT"},
3545 {"AIF4 MAD", NULL, "MADONOFF"},
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003546
Kuirong Wang906ac472012-07-09 12:54:44 -07003547 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
3548 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3549 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3550 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3551 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3552 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3553 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3554 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3555 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3556 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3557 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3558 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
3559 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3560 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3561 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3562 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3563 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3564 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3565 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3566 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3567 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3568 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3569 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
3570 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3571 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3572 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3573 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3574 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3575 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3576 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3577 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3578 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3579 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3580
Kiran Kandic3b24402012-06-11 00:05:59 -07003581 {"SLIM TX1 MUX", "DEC1", "DEC1 MUX"},
3582
Kiran Kandic3b24402012-06-11 00:05:59 -07003583 {"SLIM TX2 MUX", "DEC2", "DEC2 MUX"},
3584
Kiran Kandic3b24402012-06-11 00:05:59 -07003585 {"SLIM TX3 MUX", "DEC3", "DEC3 MUX"},
3586 {"SLIM TX3 MUX", "RMIX1", "RX1 MIX1"},
3587 {"SLIM TX3 MUX", "RMIX2", "RX2 MIX1"},
3588 {"SLIM TX3 MUX", "RMIX3", "RX3 MIX1"},
3589 {"SLIM TX3 MUX", "RMIX4", "RX4 MIX1"},
3590 {"SLIM TX3 MUX", "RMIX5", "RX5 MIX1"},
3591 {"SLIM TX3 MUX", "RMIX6", "RX6 MIX1"},
3592 {"SLIM TX3 MUX", "RMIX7", "RX7 MIX1"},
3593
Kiran Kandic3b24402012-06-11 00:05:59 -07003594 {"SLIM TX4 MUX", "DEC4", "DEC4 MUX"},
3595
Kiran Kandic3b24402012-06-11 00:05:59 -07003596 {"SLIM TX5 MUX", "DEC5", "DEC5 MUX"},
3597 {"SLIM TX5 MUX", "RMIX1", "RX1 MIX1"},
3598 {"SLIM TX5 MUX", "RMIX2", "RX2 MIX1"},
3599 {"SLIM TX5 MUX", "RMIX3", "RX3 MIX1"},
3600 {"SLIM TX5 MUX", "RMIX4", "RX4 MIX1"},
3601 {"SLIM TX5 MUX", "RMIX5", "RX5 MIX1"},
3602 {"SLIM TX5 MUX", "RMIX6", "RX6 MIX1"},
3603 {"SLIM TX5 MUX", "RMIX7", "RX7 MIX1"},
3604
Kiran Kandic3b24402012-06-11 00:05:59 -07003605 {"SLIM TX6 MUX", "DEC6", "DEC6 MUX"},
3606
Kiran Kandic3b24402012-06-11 00:05:59 -07003607 {"SLIM TX7 MUX", "DEC1", "DEC1 MUX"},
3608 {"SLIM TX7 MUX", "DEC2", "DEC2 MUX"},
3609 {"SLIM TX7 MUX", "DEC3", "DEC3 MUX"},
3610 {"SLIM TX7 MUX", "DEC4", "DEC4 MUX"},
3611 {"SLIM TX7 MUX", "DEC5", "DEC5 MUX"},
3612 {"SLIM TX7 MUX", "DEC6", "DEC6 MUX"},
3613 {"SLIM TX7 MUX", "DEC7", "DEC7 MUX"},
3614 {"SLIM TX7 MUX", "DEC8", "DEC8 MUX"},
3615 {"SLIM TX7 MUX", "DEC9", "DEC9 MUX"},
3616 {"SLIM TX7 MUX", "DEC10", "DEC10 MUX"},
3617 {"SLIM TX7 MUX", "RMIX1", "RX1 MIX1"},
3618 {"SLIM TX7 MUX", "RMIX2", "RX2 MIX1"},
3619 {"SLIM TX7 MUX", "RMIX3", "RX3 MIX1"},
3620 {"SLIM TX7 MUX", "RMIX4", "RX4 MIX1"},
3621 {"SLIM TX7 MUX", "RMIX5", "RX5 MIX1"},
3622 {"SLIM TX7 MUX", "RMIX6", "RX6 MIX1"},
3623 {"SLIM TX7 MUX", "RMIX7", "RX7 MIX1"},
3624
Kiran Kandic3b24402012-06-11 00:05:59 -07003625 {"SLIM TX8 MUX", "DEC1", "DEC1 MUX"},
3626 {"SLIM TX8 MUX", "DEC2", "DEC2 MUX"},
3627 {"SLIM TX8 MUX", "DEC3", "DEC3 MUX"},
3628 {"SLIM TX8 MUX", "DEC4", "DEC4 MUX"},
3629 {"SLIM TX8 MUX", "DEC5", "DEC5 MUX"},
3630 {"SLIM TX8 MUX", "DEC6", "DEC6 MUX"},
3631 {"SLIM TX8 MUX", "DEC7", "DEC7 MUX"},
3632 {"SLIM TX8 MUX", "DEC8", "DEC8 MUX"},
3633 {"SLIM TX8 MUX", "DEC9", "DEC9 MUX"},
3634 {"SLIM TX8 MUX", "DEC10", "DEC10 MUX"},
3635
Kiran Kandic3b24402012-06-11 00:05:59 -07003636 {"SLIM TX9 MUX", "DEC1", "DEC1 MUX"},
3637 {"SLIM TX9 MUX", "DEC2", "DEC2 MUX"},
3638 {"SLIM TX9 MUX", "DEC3", "DEC3 MUX"},
3639 {"SLIM TX9 MUX", "DEC4", "DEC4 MUX"},
3640 {"SLIM TX9 MUX", "DEC5", "DEC5 MUX"},
3641 {"SLIM TX9 MUX", "DEC6", "DEC6 MUX"},
3642 {"SLIM TX9 MUX", "DEC7", "DEC7 MUX"},
3643 {"SLIM TX9 MUX", "DEC8", "DEC8 MUX"},
3644 {"SLIM TX9 MUX", "DEC9", "DEC9 MUX"},
3645 {"SLIM TX9 MUX", "DEC10", "DEC10 MUX"},
3646
Kiran Kandic3b24402012-06-11 00:05:59 -07003647 {"SLIM TX10 MUX", "DEC1", "DEC1 MUX"},
3648 {"SLIM TX10 MUX", "DEC2", "DEC2 MUX"},
3649 {"SLIM TX10 MUX", "DEC3", "DEC3 MUX"},
3650 {"SLIM TX10 MUX", "DEC4", "DEC4 MUX"},
3651 {"SLIM TX10 MUX", "DEC5", "DEC5 MUX"},
3652 {"SLIM TX10 MUX", "DEC6", "DEC6 MUX"},
3653 {"SLIM TX10 MUX", "DEC7", "DEC7 MUX"},
3654 {"SLIM TX10 MUX", "DEC8", "DEC8 MUX"},
3655 {"SLIM TX10 MUX", "DEC9", "DEC9 MUX"},
3656 {"SLIM TX10 MUX", "DEC10", "DEC10 MUX"},
3657
3658 /* Earpiece (RX MIX1) */
3659 {"EAR", NULL, "EAR PA"},
3660 {"EAR PA", NULL, "EAR_PA_MIXER"},
3661 {"EAR_PA_MIXER", NULL, "DAC1"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003662 {"DAC1", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003663
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003664 {"ANC EAR", NULL, "ANC EAR PA"},
3665 {"ANC EAR PA", NULL, "EAR_PA_MIXER"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003666 {"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
3667 {"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003668
3669 /* Headset (RX MIX1 and RX MIX2) */
3670 {"HEADPHONE", NULL, "HPHL"},
3671 {"HEADPHONE", NULL, "HPHR"},
3672
3673 {"HPHL", NULL, "HPHL_PA_MIXER"},
3674 {"HPHL_PA_MIXER", NULL, "HPHL DAC"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003675 {"HPHL DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003676
3677 {"HPHR", NULL, "HPHR_PA_MIXER"},
3678 {"HPHR_PA_MIXER", NULL, "HPHR DAC"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003679 {"HPHR DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003680
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003681 {"ANC HEADPHONE", NULL, "ANC HPHL"},
3682 {"ANC HEADPHONE", NULL, "ANC HPHR"},
3683
3684 {"ANC HPHL", NULL, "HPHL_PA_MIXER"},
3685 {"ANC HPHR", NULL, "HPHR_PA_MIXER"},
3686
Kiran Kandic3b24402012-06-11 00:05:59 -07003687 {"ANC1 MUX", "ADC1", "ADC1"},
3688 {"ANC1 MUX", "ADC2", "ADC2"},
3689 {"ANC1 MUX", "ADC3", "ADC3"},
3690 {"ANC1 MUX", "ADC4", "ADC4"},
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003691 {"ANC1 MUX", "DMIC1", "DMIC1"},
3692 {"ANC1 MUX", "DMIC2", "DMIC2"},
3693 {"ANC1 MUX", "DMIC3", "DMIC3"},
3694 {"ANC1 MUX", "DMIC4", "DMIC4"},
3695 {"ANC1 MUX", "DMIC5", "DMIC5"},
3696 {"ANC1 MUX", "DMIC6", "DMIC6"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003697 {"ANC2 MUX", "ADC1", "ADC1"},
3698 {"ANC2 MUX", "ADC2", "ADC2"},
3699 {"ANC2 MUX", "ADC3", "ADC3"},
3700 {"ANC2 MUX", "ADC4", "ADC4"},
3701
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003702 {"ANC HPHR", NULL, "CDC_CONN"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003703
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003704 {"DAC1", "Switch", "CLASS_H_DSM MUX"},
3705 {"HPHL DAC", "Switch", "CLASS_H_DSM MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003706 {"HPHR DAC", NULL, "RX2 CHAIN"},
3707
3708 {"LINEOUT1", NULL, "LINEOUT1 PA"},
3709 {"LINEOUT2", NULL, "LINEOUT2 PA"},
3710 {"LINEOUT3", NULL, "LINEOUT3 PA"},
3711 {"LINEOUT4", NULL, "LINEOUT4 PA"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003712 {"SPK_OUT", NULL, "SPK PA"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003713
3714 {"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
3715 {"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003716
Kiran Kandic3b24402012-06-11 00:05:59 -07003717 {"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
3718 {"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003719
Kiran Kandic3b24402012-06-11 00:05:59 -07003720 {"LINEOUT3 PA", NULL, "LINEOUT3_PA_MIXER"},
3721 {"LINEOUT3_PA_MIXER", NULL, "LINEOUT3 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003722
Kiran Kandic3b24402012-06-11 00:05:59 -07003723 {"LINEOUT4 PA", NULL, "LINEOUT4_PA_MIXER"},
3724 {"LINEOUT4_PA_MIXER", NULL, "LINEOUT4 DAC"},
3725
3726 {"LINEOUT1 DAC", NULL, "RX3 MIX1"},
3727
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02003728 {"RDAC5 MUX", "DEM3_INV", "RX3 MIX1"},
3729 {"RDAC5 MUX", "DEM4", "RX4 MIX1"},
3730
3731 {"LINEOUT3 DAC", NULL, "RDAC5 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003732
3733 {"LINEOUT2 DAC", NULL, "RX5 MIX1"},
3734
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02003735 {"RDAC7 MUX", "DEM5_INV", "RX5 MIX1"},
3736 {"RDAC7 MUX", "DEM6", "RX6 MIX1"},
3737
3738 {"LINEOUT4 DAC", NULL, "RDAC7 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003739
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003740 {"SPK PA", NULL, "SPK DAC"},
Kiran Kandid2b46332012-10-05 12:04:00 -07003741 {"SPK DAC", NULL, "RX7 MIX2"},
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003742 {"SPK DAC", NULL, "VDD_SPKDRV"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003743
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003744 {"CLASS_H_DSM MUX", "DSM_HPHL_RX1", "RX1 CHAIN"},
3745
Kiran Kandic3b24402012-06-11 00:05:59 -07003746 {"RX1 CHAIN", NULL, "RX1 MIX2"},
3747 {"RX2 CHAIN", NULL, "RX2 MIX2"},
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003748 {"RX1 MIX2", NULL, "ANC1 MUX"},
3749 {"RX2 MIX2", NULL, "ANC2 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003750
Kiran Kandic3b24402012-06-11 00:05:59 -07003751 {"LINEOUT1 DAC", NULL, "RX_BIAS"},
3752 {"LINEOUT2 DAC", NULL, "RX_BIAS"},
3753 {"LINEOUT3 DAC", NULL, "RX_BIAS"},
3754 {"LINEOUT4 DAC", NULL, "RX_BIAS"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003755 {"SPK DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003756
Joonwoo Parkc7731432012-10-17 12:41:44 -07003757 {"RX7 MIX1", NULL, "COMP0_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003758 {"RX1 MIX1", NULL, "COMP1_CLK"},
3759 {"RX2 MIX1", NULL, "COMP1_CLK"},
3760 {"RX3 MIX1", NULL, "COMP2_CLK"},
3761 {"RX5 MIX1", NULL, "COMP2_CLK"},
3762
Kiran Kandic3b24402012-06-11 00:05:59 -07003763 {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
3764 {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
3765 {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
3766 {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
3767 {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
3768 {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
3769 {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
3770 {"RX4 MIX1", NULL, "RX4 MIX1 INP1"},
3771 {"RX4 MIX1", NULL, "RX4 MIX1 INP2"},
3772 {"RX5 MIX1", NULL, "RX5 MIX1 INP1"},
3773 {"RX5 MIX1", NULL, "RX5 MIX1 INP2"},
3774 {"RX6 MIX1", NULL, "RX6 MIX1 INP1"},
3775 {"RX6 MIX1", NULL, "RX6 MIX1 INP2"},
3776 {"RX7 MIX1", NULL, "RX7 MIX1 INP1"},
3777 {"RX7 MIX1", NULL, "RX7 MIX1 INP2"},
3778 {"RX1 MIX2", NULL, "RX1 MIX1"},
3779 {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
3780 {"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
3781 {"RX2 MIX2", NULL, "RX2 MIX1"},
3782 {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
3783 {"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
3784 {"RX7 MIX2", NULL, "RX7 MIX1"},
3785 {"RX7 MIX2", NULL, "RX7 MIX2 INP1"},
3786 {"RX7 MIX2", NULL, "RX7 MIX2 INP2"},
3787
Kuirong Wang906ac472012-07-09 12:54:44 -07003788 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
3789 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
3790 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
3791 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
3792 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
3793 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
3794 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
3795 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
3796 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
3797 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
3798 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
3799 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
3800 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
3801 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
3802 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
3803 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
3804 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
3805 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
3806 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
3807 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
3808 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
3809 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
3810 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
3811 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
3812
3813 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
3814 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
3815 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
3816 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
3817 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
3818 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
3819 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
3820
Kiran Kandic3b24402012-06-11 00:05:59 -07003821 {"RX1 MIX1 INP1", "RX1", "SLIM RX1"},
3822 {"RX1 MIX1 INP1", "RX2", "SLIM RX2"},
3823 {"RX1 MIX1 INP1", "RX3", "SLIM RX3"},
3824 {"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
3825 {"RX1 MIX1 INP1", "RX5", "SLIM RX5"},
3826 {"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
3827 {"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
3828 {"RX1 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003829 {"RX1 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003830 {"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
3831 {"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
3832 {"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
3833 {"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
3834 {"RX1 MIX1 INP2", "RX5", "SLIM RX5"},
3835 {"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
3836 {"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
3837 {"RX1 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003838 {"RX1 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003839 {"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
3840 {"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
3841 {"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
3842 {"RX1 MIX1 INP3", "RX4", "SLIM RX4"},
3843 {"RX1 MIX1 INP3", "RX5", "SLIM RX5"},
3844 {"RX1 MIX1 INP3", "RX6", "SLIM RX6"},
3845 {"RX1 MIX1 INP3", "RX7", "SLIM RX7"},
3846 {"RX2 MIX1 INP1", "RX1", "SLIM RX1"},
3847 {"RX2 MIX1 INP1", "RX2", "SLIM RX2"},
3848 {"RX2 MIX1 INP1", "RX3", "SLIM RX3"},
3849 {"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
3850 {"RX2 MIX1 INP1", "RX5", "SLIM RX5"},
3851 {"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
3852 {"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
3853 {"RX2 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003854 {"RX2 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003855 {"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
3856 {"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
3857 {"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
3858 {"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
3859 {"RX2 MIX1 INP2", "RX5", "SLIM RX5"},
3860 {"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
3861 {"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
3862 {"RX2 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003863 {"RX2 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003864 {"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
3865 {"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
3866 {"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
3867 {"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
3868 {"RX3 MIX1 INP1", "RX5", "SLIM RX5"},
3869 {"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
3870 {"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
3871 {"RX3 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003872 {"RX3 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003873 {"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
3874 {"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
3875 {"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
3876 {"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
3877 {"RX3 MIX1 INP2", "RX5", "SLIM RX5"},
3878 {"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
3879 {"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
3880 {"RX3 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003881 {"RX3 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003882 {"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
3883 {"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
3884 {"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
3885 {"RX4 MIX1 INP1", "RX4", "SLIM RX4"},
3886 {"RX4 MIX1 INP1", "RX5", "SLIM RX5"},
3887 {"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
3888 {"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
3889 {"RX4 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003890 {"RX4 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003891 {"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
3892 {"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
3893 {"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
3894 {"RX4 MIX1 INP2", "RX5", "SLIM RX5"},
3895 {"RX4 MIX1 INP2", "RX4", "SLIM RX4"},
3896 {"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
3897 {"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
3898 {"RX4 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003899 {"RX4 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003900 {"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
3901 {"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
3902 {"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
3903 {"RX5 MIX1 INP1", "RX4", "SLIM RX4"},
3904 {"RX5 MIX1 INP1", "RX5", "SLIM RX5"},
3905 {"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
3906 {"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
3907 {"RX5 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003908 {"RX5 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003909 {"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
3910 {"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
3911 {"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
3912 {"RX5 MIX1 INP2", "RX4", "SLIM RX4"},
3913 {"RX5 MIX1 INP2", "RX5", "SLIM RX5"},
3914 {"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
3915 {"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
3916 {"RX5 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003917 {"RX5 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003918 {"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
3919 {"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
3920 {"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
3921 {"RX6 MIX1 INP1", "RX4", "SLIM RX4"},
3922 {"RX6 MIX1 INP1", "RX5", "SLIM RX5"},
3923 {"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
3924 {"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
3925 {"RX6 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003926 {"RX6 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003927 {"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
3928 {"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
3929 {"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
3930 {"RX6 MIX1 INP2", "RX4", "SLIM RX4"},
3931 {"RX6 MIX1 INP2", "RX5", "SLIM RX5"},
3932 {"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
3933 {"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
3934 {"RX6 MIX1 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003935 {"RX6 MIX1 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003936 {"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
3937 {"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
3938 {"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
3939 {"RX7 MIX1 INP1", "RX4", "SLIM RX4"},
3940 {"RX7 MIX1 INP1", "RX5", "SLIM RX5"},
3941 {"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
3942 {"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
3943 {"RX7 MIX1 INP1", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003944 {"RX7 MIX1 INP1", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003945 {"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
3946 {"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
3947 {"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
3948 {"RX7 MIX1 INP2", "RX4", "SLIM RX4"},
3949 {"RX7 MIX1 INP2", "RX5", "SLIM RX5"},
3950 {"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
3951 {"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
3952 {"RX7 MIX1 INP2", "IIR1", "IIR1"},
Kiran Kandibd85d772013-05-19 19:03:43 -07003953 {"RX7 MIX1 INP2", "IIR2", "IIR2"},
3954
3955 /* IIR1, IIR2 inputs to Second RX Mixer on RX1, RX2 and RX7 chains. */
Kiran Kandic3b24402012-06-11 00:05:59 -07003956 {"RX1 MIX2 INP1", "IIR1", "IIR1"},
3957 {"RX1 MIX2 INP2", "IIR1", "IIR1"},
3958 {"RX2 MIX2 INP1", "IIR1", "IIR1"},
3959 {"RX2 MIX2 INP2", "IIR1", "IIR1"},
3960 {"RX7 MIX2 INP1", "IIR1", "IIR1"},
3961 {"RX7 MIX2 INP2", "IIR1", "IIR1"},
Fred Oh456fcb52013-02-28 19:08:15 -08003962 {"RX1 MIX2 INP1", "IIR2", "IIR2"},
3963 {"RX1 MIX2 INP2", "IIR2", "IIR2"},
3964 {"RX2 MIX2 INP1", "IIR2", "IIR2"},
3965 {"RX2 MIX2 INP2", "IIR2", "IIR2"},
3966 {"RX7 MIX2 INP1", "IIR2", "IIR2"},
3967 {"RX7 MIX2 INP2", "IIR2", "IIR2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003968
3969 /* Decimator Inputs */
3970 {"DEC1 MUX", "DMIC1", "DMIC1"},
3971 {"DEC1 MUX", "ADC6", "ADC6"},
3972 {"DEC1 MUX", NULL, "CDC_CONN"},
3973 {"DEC2 MUX", "DMIC2", "DMIC2"},
3974 {"DEC2 MUX", "ADC5", "ADC5"},
3975 {"DEC2 MUX", NULL, "CDC_CONN"},
3976 {"DEC3 MUX", "DMIC3", "DMIC3"},
3977 {"DEC3 MUX", "ADC4", "ADC4"},
3978 {"DEC3 MUX", NULL, "CDC_CONN"},
3979 {"DEC4 MUX", "DMIC4", "DMIC4"},
3980 {"DEC4 MUX", "ADC3", "ADC3"},
3981 {"DEC4 MUX", NULL, "CDC_CONN"},
3982 {"DEC5 MUX", "DMIC5", "DMIC5"},
3983 {"DEC5 MUX", "ADC2", "ADC2"},
3984 {"DEC5 MUX", NULL, "CDC_CONN"},
3985 {"DEC6 MUX", "DMIC6", "DMIC6"},
3986 {"DEC6 MUX", "ADC1", "ADC1"},
3987 {"DEC6 MUX", NULL, "CDC_CONN"},
3988 {"DEC7 MUX", "DMIC1", "DMIC1"},
3989 {"DEC7 MUX", "DMIC6", "DMIC6"},
3990 {"DEC7 MUX", "ADC1", "ADC1"},
3991 {"DEC7 MUX", "ADC6", "ADC6"},
3992 {"DEC7 MUX", NULL, "CDC_CONN"},
3993 {"DEC8 MUX", "DMIC2", "DMIC2"},
3994 {"DEC8 MUX", "DMIC5", "DMIC5"},
3995 {"DEC8 MUX", "ADC2", "ADC2"},
3996 {"DEC8 MUX", "ADC5", "ADC5"},
3997 {"DEC8 MUX", NULL, "CDC_CONN"},
3998 {"DEC9 MUX", "DMIC4", "DMIC4"},
3999 {"DEC9 MUX", "DMIC5", "DMIC5"},
4000 {"DEC9 MUX", "ADC2", "ADC2"},
4001 {"DEC9 MUX", "ADC3", "ADC3"},
4002 {"DEC9 MUX", NULL, "CDC_CONN"},
4003 {"DEC10 MUX", "DMIC3", "DMIC3"},
4004 {"DEC10 MUX", "DMIC6", "DMIC6"},
4005 {"DEC10 MUX", "ADC1", "ADC1"},
4006 {"DEC10 MUX", "ADC4", "ADC4"},
4007 {"DEC10 MUX", NULL, "CDC_CONN"},
4008
4009 /* ADC Connections */
4010 {"ADC1", NULL, "AMIC1"},
4011 {"ADC2", NULL, "AMIC2"},
4012 {"ADC3", NULL, "AMIC3"},
4013 {"ADC4", NULL, "AMIC4"},
4014 {"ADC5", NULL, "AMIC5"},
4015 {"ADC6", NULL, "AMIC6"},
4016
4017 /* AUX PGA Connections */
Kiran Kandic3b24402012-06-11 00:05:59 -07004018 {"EAR_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07004019 {"HPHL_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
4020 {"HPHR_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
4021 {"LINEOUT1_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
4022 {"LINEOUT2_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
4023 {"LINEOUT3_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
4024 {"LINEOUT4_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
Kiran Kandic3b24402012-06-11 00:05:59 -07004025 {"AUX_PGA_Left", NULL, "AMIC5"},
4026 {"AUX_PGA_Right", NULL, "AMIC6"},
4027
Kiran Kandic3b24402012-06-11 00:05:59 -07004028 {"IIR1", NULL, "IIR1 INP1 MUX"},
4029 {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
4030 {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
4031 {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
4032 {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
4033 {"IIR1 INP1 MUX", "DEC5", "DEC5 MUX"},
4034 {"IIR1 INP1 MUX", "DEC6", "DEC6 MUX"},
4035 {"IIR1 INP1 MUX", "DEC7", "DEC7 MUX"},
4036 {"IIR1 INP1 MUX", "DEC8", "DEC8 MUX"},
4037 {"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
4038 {"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
Kiran Kandibd85d772013-05-19 19:03:43 -07004039 {"IIR1 INP1 MUX", "RX1", "SLIM RX1"},
4040 {"IIR1 INP1 MUX", "RX2", "SLIM RX2"},
4041 {"IIR1 INP1 MUX", "RX3", "SLIM RX3"},
4042 {"IIR1 INP1 MUX", "RX4", "SLIM RX4"},
4043 {"IIR1 INP1 MUX", "RX5", "SLIM RX5"},
4044 {"IIR1 INP1 MUX", "RX6", "SLIM RX6"},
4045 {"IIR1 INP1 MUX", "RX7", "SLIM RX7"},
Kiran Kandic3b24402012-06-11 00:05:59 -07004046
Fred Oh456fcb52013-02-28 19:08:15 -08004047 {"IIR2", NULL, "IIR2 INP1 MUX"},
4048 {"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
4049 {"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
4050 {"IIR2 INP1 MUX", "DEC3", "DEC3 MUX"},
4051 {"IIR2 INP1 MUX", "DEC4", "DEC4 MUX"},
4052 {"IIR2 INP1 MUX", "DEC5", "DEC5 MUX"},
4053 {"IIR2 INP1 MUX", "DEC6", "DEC6 MUX"},
4054 {"IIR2 INP1 MUX", "DEC7", "DEC7 MUX"},
4055 {"IIR2 INP1 MUX", "DEC8", "DEC8 MUX"},
4056 {"IIR2 INP1 MUX", "DEC9", "DEC9 MUX"},
4057 {"IIR2 INP1 MUX", "DEC10", "DEC10 MUX"},
Kiran Kandibd85d772013-05-19 19:03:43 -07004058 {"IIR2 INP1 MUX", "RX1", "SLIM RX1"},
4059 {"IIR2 INP1 MUX", "RX2", "SLIM RX2"},
4060 {"IIR2 INP1 MUX", "RX3", "SLIM RX3"},
4061 {"IIR2 INP1 MUX", "RX4", "SLIM RX4"},
4062 {"IIR2 INP1 MUX", "RX5", "SLIM RX5"},
4063 {"IIR2 INP1 MUX", "RX6", "SLIM RX6"},
4064 {"IIR2 INP1 MUX", "RX7", "SLIM RX7"},
Fred Oh456fcb52013-02-28 19:08:15 -08004065
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05304066 {"IIR1", NULL, "IIR1 INP2 MUX"},
4067 {"IIR1 INP2 MUX", "DEC1", "DEC1 MUX"},
4068 {"IIR1 INP2 MUX", "DEC2", "DEC2 MUX"},
4069 {"IIR1 INP2 MUX", "DEC3", "DEC3 MUX"},
4070 {"IIR1 INP2 MUX", "DEC4", "DEC4 MUX"},
4071 {"IIR1 INP2 MUX", "DEC5", "DEC5 MUX"},
4072 {"IIR1 INP2 MUX", "DEC6", "DEC6 MUX"},
4073 {"IIR1 INP2 MUX", "DEC7", "DEC7 MUX"},
4074 {"IIR1 INP2 MUX", "DEC8", "DEC8 MUX"},
4075 {"IIR1 INP2 MUX", "DEC9", "DEC9 MUX"},
4076 {"IIR1 INP2 MUX", "DEC10", "DEC10 MUX"},
4077 {"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
4078 {"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
4079 {"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
4080 {"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
4081 {"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
4082 {"IIR1 INP2 MUX", "RX6", "SLIM RX6"},
4083 {"IIR1 INP2 MUX", "RX7", "SLIM RX7"},
4084
4085 {"IIR2", NULL, "IIR2 INP2 MUX"},
4086 {"IIR2 INP2 MUX", "DEC1", "DEC1 MUX"},
4087 {"IIR2 INP2 MUX", "DEC2", "DEC2 MUX"},
4088 {"IIR2 INP2 MUX", "DEC3", "DEC3 MUX"},
4089 {"IIR2 INP2 MUX", "DEC4", "DEC4 MUX"},
4090 {"IIR2 INP2 MUX", "DEC5", "DEC5 MUX"},
4091 {"IIR2 INP2 MUX", "DEC6", "DEC6 MUX"},
4092 {"IIR2 INP2 MUX", "DEC7", "DEC7 MUX"},
4093 {"IIR2 INP2 MUX", "DEC8", "DEC8 MUX"},
4094 {"IIR2 INP2 MUX", "DEC9", "DEC9 MUX"},
4095 {"IIR2 INP2 MUX", "DEC10", "DEC10 MUX"},
4096 {"IIR2 INP2 MUX", "RX1", "SLIM RX1"},
4097 {"IIR2 INP2 MUX", "RX2", "SLIM RX2"},
4098 {"IIR2 INP2 MUX", "RX3", "SLIM RX3"},
4099 {"IIR2 INP2 MUX", "RX4", "SLIM RX4"},
4100 {"IIR2 INP2 MUX", "RX5", "SLIM RX5"},
4101 {"IIR2 INP2 MUX", "RX6", "SLIM RX6"},
4102 {"IIR2 INP2 MUX", "RX7", "SLIM RX7"},
4103
4104 {"IIR1", NULL, "IIR1 INP3 MUX"},
4105 {"IIR1 INP3 MUX", "DEC1", "DEC1 MUX"},
4106 {"IIR1 INP3 MUX", "DEC2", "DEC2 MUX"},
4107 {"IIR1 INP3 MUX", "DEC3", "DEC3 MUX"},
4108 {"IIR1 INP3 MUX", "DEC4", "DEC4 MUX"},
4109 {"IIR1 INP3 MUX", "DEC5", "DEC5 MUX"},
4110 {"IIR1 INP3 MUX", "DEC6", "DEC6 MUX"},
4111 {"IIR1 INP3 MUX", "DEC7", "DEC7 MUX"},
4112 {"IIR1 INP3 MUX", "DEC8", "DEC8 MUX"},
4113 {"IIR1 INP3 MUX", "DEC9", "DEC9 MUX"},
4114 {"IIR1 INP3 MUX", "DEC10", "DEC10 MUX"},
4115 {"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
4116 {"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
4117 {"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
4118 {"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
4119 {"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
4120 {"IIR1 INP3 MUX", "RX6", "SLIM RX6"},
4121 {"IIR1 INP3 MUX", "RX7", "SLIM RX7"},
4122
4123 {"IIR2", NULL, "IIR2 INP3 MUX"},
4124 {"IIR2 INP3 MUX", "DEC1", "DEC1 MUX"},
4125 {"IIR2 INP3 MUX", "DEC2", "DEC2 MUX"},
4126 {"IIR2 INP3 MUX", "DEC3", "DEC3 MUX"},
4127 {"IIR2 INP3 MUX", "DEC4", "DEC4 MUX"},
4128 {"IIR2 INP3 MUX", "DEC5", "DEC5 MUX"},
4129 {"IIR2 INP3 MUX", "DEC6", "DEC6 MUX"},
4130 {"IIR2 INP3 MUX", "DEC7", "DEC7 MUX"},
4131 {"IIR2 INP3 MUX", "DEC8", "DEC8 MUX"},
4132 {"IIR2 INP3 MUX", "DEC9", "DEC9 MUX"},
4133 {"IIR2 INP3 MUX", "DEC10", "DEC10 MUX"},
4134 {"IIR2 INP3 MUX", "RX1", "SLIM RX1"},
4135 {"IIR2 INP3 MUX", "RX2", "SLIM RX2"},
4136 {"IIR2 INP3 MUX", "RX3", "SLIM RX3"},
4137 {"IIR2 INP3 MUX", "RX4", "SLIM RX4"},
4138 {"IIR2 INP3 MUX", "RX5", "SLIM RX5"},
4139 {"IIR2 INP3 MUX", "RX6", "SLIM RX6"},
4140 {"IIR2 INP3 MUX", "RX7", "SLIM RX7"},
4141
4142 {"IIR1", NULL, "IIR1 INP4 MUX"},
4143 {"IIR1 INP4 MUX", "DEC1", "DEC1 MUX"},
4144 {"IIR1 INP4 MUX", "DEC2", "DEC2 MUX"},
4145 {"IIR1 INP4 MUX", "DEC3", "DEC3 MUX"},
4146 {"IIR1 INP4 MUX", "DEC4", "DEC4 MUX"},
4147 {"IIR1 INP4 MUX", "DEC5", "DEC5 MUX"},
4148 {"IIR1 INP4 MUX", "DEC6", "DEC6 MUX"},
4149 {"IIR1 INP4 MUX", "DEC7", "DEC7 MUX"},
4150 {"IIR1 INP4 MUX", "DEC8", "DEC8 MUX"},
4151 {"IIR1 INP4 MUX", "DEC9", "DEC9 MUX"},
4152 {"IIR1 INP4 MUX", "DEC10", "DEC10 MUX"},
4153 {"IIR1 INP4 MUX", "RX1", "SLIM RX1"},
4154 {"IIR1 INP4 MUX", "RX2", "SLIM RX2"},
4155 {"IIR1 INP4 MUX", "RX3", "SLIM RX3"},
4156 {"IIR1 INP4 MUX", "RX4", "SLIM RX4"},
4157 {"IIR1 INP4 MUX", "RX5", "SLIM RX5"},
4158 {"IIR1 INP4 MUX", "RX6", "SLIM RX6"},
4159 {"IIR1 INP4 MUX", "RX7", "SLIM RX7"},
4160
4161 {"IIR2", NULL, "IIR2 INP4 MUX"},
4162 {"IIR2 INP4 MUX", "DEC1", "DEC1 MUX"},
4163 {"IIR2 INP4 MUX", "DEC2", "DEC2 MUX"},
4164 {"IIR2 INP4 MUX", "DEC3", "DEC3 MUX"},
4165 {"IIR2 INP4 MUX", "DEC4", "DEC4 MUX"},
4166 {"IIR2 INP4 MUX", "DEC5", "DEC5 MUX"},
4167 {"IIR2 INP4 MUX", "DEC6", "DEC6 MUX"},
4168 {"IIR2 INP4 MUX", "DEC7", "DEC7 MUX"},
4169 {"IIR2 INP4 MUX", "DEC8", "DEC8 MUX"},
4170 {"IIR2 INP4 MUX", "DEC9", "DEC9 MUX"},
4171 {"IIR2 INP4 MUX", "DEC10", "DEC10 MUX"},
4172 {"IIR2 INP4 MUX", "RX1", "SLIM RX1"},
4173 {"IIR2 INP4 MUX", "RX2", "SLIM RX2"},
4174 {"IIR2 INP4 MUX", "RX3", "SLIM RX3"},
4175 {"IIR2 INP4 MUX", "RX4", "SLIM RX4"},
4176 {"IIR2 INP4 MUX", "RX5", "SLIM RX5"},
4177 {"IIR2 INP4 MUX", "RX6", "SLIM RX6"},
4178 {"IIR2 INP4 MUX", "RX7", "SLIM RX7"},
4179
Kiran Kandic3b24402012-06-11 00:05:59 -07004180 {"MIC BIAS1 Internal1", NULL, "LDO_H"},
4181 {"MIC BIAS1 Internal2", NULL, "LDO_H"},
4182 {"MIC BIAS1 External", NULL, "LDO_H"},
4183 {"MIC BIAS2 Internal1", NULL, "LDO_H"},
4184 {"MIC BIAS2 Internal2", NULL, "LDO_H"},
4185 {"MIC BIAS2 Internal3", NULL, "LDO_H"},
4186 {"MIC BIAS2 External", NULL, "LDO_H"},
4187 {"MIC BIAS3 Internal1", NULL, "LDO_H"},
4188 {"MIC BIAS3 Internal2", NULL, "LDO_H"},
4189 {"MIC BIAS3 External", NULL, "LDO_H"},
4190 {"MIC BIAS4 External", NULL, "LDO_H"},
Joonwoo Parkccccba72013-04-26 11:19:46 -07004191 {DAPM_MICBIAS2_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07004192 {DAPM_MICBIAS3_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
Kiran Kandic3b24402012-06-11 00:05:59 -07004193};
4194
4195static int taiko_readable(struct snd_soc_codec *ssc, unsigned int reg)
4196{
4197 return taiko_reg_readable[reg];
4198}
4199
4200static bool taiko_is_digital_gain_register(unsigned int reg)
4201{
4202 bool rtn = false;
4203 switch (reg) {
4204 case TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL:
4205 case TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL:
4206 case TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL:
4207 case TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL:
4208 case TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL:
4209 case TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL:
4210 case TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL:
4211 case TAIKO_A_CDC_TX1_VOL_CTL_GAIN:
4212 case TAIKO_A_CDC_TX2_VOL_CTL_GAIN:
4213 case TAIKO_A_CDC_TX3_VOL_CTL_GAIN:
4214 case TAIKO_A_CDC_TX4_VOL_CTL_GAIN:
4215 case TAIKO_A_CDC_TX5_VOL_CTL_GAIN:
4216 case TAIKO_A_CDC_TX6_VOL_CTL_GAIN:
4217 case TAIKO_A_CDC_TX7_VOL_CTL_GAIN:
4218 case TAIKO_A_CDC_TX8_VOL_CTL_GAIN:
4219 case TAIKO_A_CDC_TX9_VOL_CTL_GAIN:
4220 case TAIKO_A_CDC_TX10_VOL_CTL_GAIN:
4221 rtn = true;
4222 break;
4223 default:
4224 break;
4225 }
4226 return rtn;
4227}
4228
4229static int taiko_volatile(struct snd_soc_codec *ssc, unsigned int reg)
4230{
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004231 int i;
4232
Kiran Kandic3b24402012-06-11 00:05:59 -07004233 /* Registers lower than 0x100 are top level registers which can be
4234 * written by the Taiko core driver.
4235 */
4236
4237 if ((reg >= TAIKO_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
4238 return 1;
4239
4240 /* IIR Coeff registers are not cacheable */
4241 if ((reg >= TAIKO_A_CDC_IIR1_COEF_B1_CTL) &&
4242 (reg <= TAIKO_A_CDC_IIR2_COEF_B2_CTL))
4243 return 1;
4244
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08004245 /* ANC filter registers are not cacheable */
4246 if ((reg >= TAIKO_A_CDC_ANC1_IIR_B1_CTL) &&
4247 (reg <= TAIKO_A_CDC_ANC1_LPF_B2_CTL))
4248 return 1;
4249 if ((reg >= TAIKO_A_CDC_ANC2_IIR_B1_CTL) &&
4250 (reg <= TAIKO_A_CDC_ANC2_LPF_B2_CTL))
4251 return 1;
4252
Kiran Kandic3b24402012-06-11 00:05:59 -07004253 /* Digital gain register is not cacheable so we have to write
4254 * the setting even it is the same
4255 */
4256 if (taiko_is_digital_gain_register(reg))
4257 return 1;
4258
4259 /* HPH status registers */
4260 if (reg == TAIKO_A_RX_HPH_L_STATUS || reg == TAIKO_A_RX_HPH_R_STATUS)
4261 return 1;
4262
Joonwoo Parka8890262012-10-15 12:04:27 -07004263 if (reg == TAIKO_A_MBHC_INSERT_DET_STATUS)
4264 return 1;
4265
Joonwoo Park559a5bf2013-02-15 14:46:36 -08004266 switch (reg) {
4267 case TAIKO_A_CDC_SPKR_CLIPDET_VAL0:
4268 case TAIKO_A_CDC_SPKR_CLIPDET_VAL1:
4269 case TAIKO_A_CDC_SPKR_CLIPDET_VAL2:
4270 case TAIKO_A_CDC_SPKR_CLIPDET_VAL3:
4271 case TAIKO_A_CDC_SPKR_CLIPDET_VAL4:
4272 case TAIKO_A_CDC_SPKR_CLIPDET_VAL5:
4273 case TAIKO_A_CDC_SPKR_CLIPDET_VAL6:
4274 case TAIKO_A_CDC_SPKR_CLIPDET_VAL7:
4275 case TAIKO_A_CDC_VBAT_GAIN_MON_VAL:
4276 return 1;
4277 }
4278
Damir Didjustodcfdff82013-03-21 23:26:41 -07004279 for (i = 0; i < ARRAY_SIZE(audio_reg_cfg); i++)
4280 if (audio_reg_cfg[i].reg_logical_addr -
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004281 TAIKO_REGISTER_START_OFFSET == reg)
4282 return 1;
4283
Kiran Kandic3b24402012-06-11 00:05:59 -07004284 return 0;
4285}
4286
Kiran Kandic3b24402012-06-11 00:05:59 -07004287static int taiko_write(struct snd_soc_codec *codec, unsigned int reg,
4288 unsigned int value)
4289{
4290 int ret;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07004291 struct wcd9xxx *wcd9xxx = codec->control_data;
Kuirong Wang906ac472012-07-09 12:54:44 -07004292
4293 if (reg == SND_SOC_NOPM)
4294 return 0;
4295
Kiran Kandic3b24402012-06-11 00:05:59 -07004296 BUG_ON(reg > TAIKO_MAX_REGISTER);
4297
4298 if (!taiko_volatile(codec, reg)) {
4299 ret = snd_soc_cache_write(codec, reg, value);
4300 if (ret != 0)
4301 dev_err(codec->dev, "Cache write to %x failed: %d\n",
4302 reg, ret);
4303 }
4304
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07004305 return wcd9xxx_reg_write(&wcd9xxx->core_res, reg, value);
Kiran Kandic3b24402012-06-11 00:05:59 -07004306}
4307static unsigned int taiko_read(struct snd_soc_codec *codec,
4308 unsigned int reg)
4309{
4310 unsigned int val;
4311 int ret;
4312
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07004313 struct wcd9xxx *wcd9xxx = codec->control_data;
4314
Kuirong Wang906ac472012-07-09 12:54:44 -07004315 if (reg == SND_SOC_NOPM)
4316 return 0;
4317
Kiran Kandic3b24402012-06-11 00:05:59 -07004318 BUG_ON(reg > TAIKO_MAX_REGISTER);
4319
4320 if (!taiko_volatile(codec, reg) && taiko_readable(codec, reg) &&
4321 reg < codec->driver->reg_cache_size) {
4322 ret = snd_soc_cache_read(codec, reg, &val);
4323 if (ret >= 0) {
4324 return val;
4325 } else
4326 dev_err(codec->dev, "Cache read from %x failed: %d\n",
4327 reg, ret);
4328 }
4329
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07004330 val = wcd9xxx_reg_read(&wcd9xxx->core_res, reg);
Kiran Kandic3b24402012-06-11 00:05:59 -07004331 return val;
4332}
4333
Kiran Kandic3b24402012-06-11 00:05:59 -07004334static int taiko_startup(struct snd_pcm_substream *substream,
4335 struct snd_soc_dai *dai)
4336{
4337 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
4338 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
4339 substream->name, substream->stream);
4340 if ((taiko_core != NULL) &&
4341 (taiko_core->dev != NULL) &&
4342 (taiko_core->dev->parent != NULL))
4343 pm_runtime_get_sync(taiko_core->dev->parent);
4344
4345 return 0;
4346}
4347
4348static void taiko_shutdown(struct snd_pcm_substream *substream,
4349 struct snd_soc_dai *dai)
4350{
4351 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
4352 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
4353 substream->name, substream->stream);
4354 if ((taiko_core != NULL) &&
4355 (taiko_core->dev != NULL) &&
4356 (taiko_core->dev->parent != NULL)) {
4357 pm_runtime_mark_last_busy(taiko_core->dev->parent);
4358 pm_runtime_put(taiko_core->dev->parent);
4359 }
4360}
4361
4362int taiko_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm)
4363{
4364 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
4365
4366 pr_debug("%s: mclk_enable = %u, dapm = %d\n", __func__, mclk_enable,
4367 dapm);
Joonwoo Parka8890262012-10-15 12:04:27 -07004368
Joonwoo Park533b3682013-06-13 11:41:21 -07004369 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07004370 if (mclk_enable) {
Joonwoo Parka8890262012-10-15 12:04:27 -07004371 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
4372 WCD9XXX_BANDGAP_AUDIO_MODE);
4373 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
Kiran Kandic3b24402012-06-11 00:05:59 -07004374 } else {
Joonwoo Parka8890262012-10-15 12:04:27 -07004375 /* Put clock and BG */
4376 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
4377 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
4378 WCD9XXX_BANDGAP_AUDIO_MODE);
Kiran Kandic3b24402012-06-11 00:05:59 -07004379 }
Joonwoo Park533b3682013-06-13 11:41:21 -07004380 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Joonwoo Parka8890262012-10-15 12:04:27 -07004381
Kiran Kandic3b24402012-06-11 00:05:59 -07004382 return 0;
4383}
4384
4385static int taiko_set_dai_sysclk(struct snd_soc_dai *dai,
4386 int clk_id, unsigned int freq, int dir)
4387{
Venkat Sudhira50a3762012-11-26 12:12:15 -08004388 pr_debug("%s\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07004389 return 0;
4390}
4391
4392static int taiko_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
4393{
4394 u8 val = 0;
4395 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
4396
4397 pr_debug("%s\n", __func__);
4398 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
4399 case SND_SOC_DAIFMT_CBS_CFS:
4400 /* CPU is master */
4401 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4402 if (dai->id == AIF1_CAP)
4403 snd_soc_update_bits(dai->codec,
4404 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4405 TAIKO_I2S_MASTER_MODE_MASK, 0);
4406 else if (dai->id == AIF1_PB)
4407 snd_soc_update_bits(dai->codec,
4408 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4409 TAIKO_I2S_MASTER_MODE_MASK, 0);
4410 }
4411 break;
4412 case SND_SOC_DAIFMT_CBM_CFM:
4413 /* CPU is slave */
4414 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4415 val = TAIKO_I2S_MASTER_MODE_MASK;
4416 if (dai->id == AIF1_CAP)
4417 snd_soc_update_bits(dai->codec,
4418 TAIKO_A_CDC_CLK_TX_I2S_CTL, val, val);
4419 else if (dai->id == AIF1_PB)
4420 snd_soc_update_bits(dai->codec,
4421 TAIKO_A_CDC_CLK_RX_I2S_CTL, val, val);
4422 }
4423 break;
4424 default:
4425 return -EINVAL;
4426 }
4427 return 0;
4428}
4429
4430static int taiko_set_channel_map(struct snd_soc_dai *dai,
4431 unsigned int tx_num, unsigned int *tx_slot,
4432 unsigned int rx_num, unsigned int *rx_slot)
4433
4434{
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004435 struct wcd9xxx_codec_dai_data *dai_data = NULL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004436 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07004437 struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07004438 if (!tx_slot && !rx_slot) {
4439 pr_err("%s: Invalid\n", __func__);
4440 return -EINVAL;
4441 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004442 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
4443 "taiko->intf_type %d\n",
4444 __func__, dai->name, dai->id, tx_num, rx_num,
4445 taiko->intf_type);
Kiran Kandic3b24402012-06-11 00:05:59 -07004446
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004447 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Kuirong Wang906ac472012-07-09 12:54:44 -07004448 wcd9xxx_init_slimslave(core, core->slim->laddr,
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004449 tx_num, tx_slot, rx_num, rx_slot);
4450 /*Reserve tx11 and tx12 for VI feedback path*/
4451 dai_data = &taiko->dai[AIF4_VIFEED];
4452 if (dai_data) {
4453 list_add_tail(&core->tx_chs[TAIKO_TX11].list,
4454 &dai_data->wcd9xxx_ch_list);
4455 list_add_tail(&core->tx_chs[TAIKO_TX12].list,
4456 &dai_data->wcd9xxx_ch_list);
4457 }
4458 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004459 return 0;
4460}
4461
4462static int taiko_get_channel_map(struct snd_soc_dai *dai,
4463 unsigned int *tx_num, unsigned int *tx_slot,
4464 unsigned int *rx_num, unsigned int *rx_slot)
4465
4466{
4467 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(dai->codec);
4468 u32 i = 0;
4469 struct wcd9xxx_ch *ch;
4470
4471 switch (dai->id) {
4472 case AIF1_PB:
4473 case AIF2_PB:
4474 case AIF3_PB:
4475 if (!rx_slot || !rx_num) {
4476 pr_err("%s: Invalid rx_slot %d or rx_num %d\n",
4477 __func__, (u32) rx_slot, (u32) rx_num);
4478 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004479 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004480 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
4481 list) {
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05004482 pr_debug("%s: slot_num %u ch->ch_num %d\n",
4483 __func__, i, ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07004484 rx_slot[i++] = ch->ch_num;
4485 }
4486 pr_debug("%s: rx_num %d\n", __func__, i);
4487 *rx_num = i;
4488 break;
4489 case AIF1_CAP:
4490 case AIF2_CAP:
4491 case AIF3_CAP:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004492 case AIF4_VIFEED:
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004493 case AIF4_MAD_TX:
Kuirong Wang906ac472012-07-09 12:54:44 -07004494 if (!tx_slot || !tx_num) {
4495 pr_err("%s: Invalid tx_slot %d or tx_num %d\n",
4496 __func__, (u32) tx_slot, (u32) tx_num);
4497 return -EINVAL;
4498 }
4499 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
4500 list) {
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05004501 pr_debug("%s: slot_num %u ch->ch_num %d\n",
4502 __func__, i, ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07004503 tx_slot[i++] = ch->ch_num;
4504 }
4505 pr_debug("%s: tx_num %d\n", __func__, i);
4506 *tx_num = i;
4507 break;
4508
4509 default:
4510 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
4511 break;
4512 }
4513
4514 return 0;
4515}
4516
4517static int taiko_set_interpolator_rate(struct snd_soc_dai *dai,
4518 u8 rx_fs_rate_reg_val, u32 compander_fs, u32 sample_rate)
4519{
4520 u32 j;
4521 u8 rx_mix1_inp;
4522 u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
4523 u16 rx_fs_reg;
4524 u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
4525 struct snd_soc_codec *codec = dai->codec;
4526 struct wcd9xxx_ch *ch;
4527 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
4528
4529 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
4530 /* for RX port starting from 16 instead of 10 like tabla */
4531 rx_mix1_inp = ch->port + RX_MIX1_INP_SEL_RX1 -
4532 TAIKO_TX_PORT_NUMBER;
4533 if ((rx_mix1_inp < RX_MIX1_INP_SEL_RX1) ||
4534 (rx_mix1_inp > RX_MIX1_INP_SEL_RX7)) {
4535 pr_err("%s: Invalid TAIKO_RX%u port. Dai ID is %d\n",
4536 __func__, rx_mix1_inp - 5 , dai->id);
4537 return -EINVAL;
4538 }
4539
4540 rx_mix_1_reg_1 = TAIKO_A_CDC_CONN_RX1_B1_CTL;
4541
4542 for (j = 0; j < NUM_INTERPOLATORS; j++) {
4543 rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
4544
4545 rx_mix_1_reg_1_val = snd_soc_read(codec,
4546 rx_mix_1_reg_1);
4547 rx_mix_1_reg_2_val = snd_soc_read(codec,
4548 rx_mix_1_reg_2);
4549
4550 if (((rx_mix_1_reg_1_val & 0x0F) == rx_mix1_inp) ||
4551 (((rx_mix_1_reg_1_val >> 4) & 0x0F)
4552 == rx_mix1_inp) ||
4553 ((rx_mix_1_reg_2_val & 0x0F) == rx_mix1_inp)) {
4554
4555 rx_fs_reg = TAIKO_A_CDC_RX1_B5_CTL + 8 * j;
4556
4557 pr_debug("%s: AIF_PB DAI(%d) connected to RX%u\n",
4558 __func__, dai->id, j + 1);
4559
4560 pr_debug("%s: set RX%u sample rate to %u\n",
4561 __func__, j + 1, sample_rate);
4562
4563 snd_soc_update_bits(codec, rx_fs_reg,
4564 0xE0, rx_fs_rate_reg_val);
4565
4566 if (comp_rx_path[j] < COMPANDER_MAX)
4567 taiko->comp_fs[comp_rx_path[j]]
4568 = compander_fs;
4569 }
Kuirong Wang94761952013-03-07 16:19:35 -08004570 if (j < 2)
Kuirong Wang906ac472012-07-09 12:54:44 -07004571 rx_mix_1_reg_1 += 3;
4572 else
4573 rx_mix_1_reg_1 += 2;
Kiran Kandic3b24402012-06-11 00:05:59 -07004574 }
4575 }
4576 return 0;
4577}
4578
Kuirong Wang906ac472012-07-09 12:54:44 -07004579static int taiko_set_decimator_rate(struct snd_soc_dai *dai,
4580 u8 tx_fs_rate_reg_val, u32 sample_rate)
Kiran Kandic3b24402012-06-11 00:05:59 -07004581{
Kuirong Wang906ac472012-07-09 12:54:44 -07004582 struct snd_soc_codec *codec = dai->codec;
4583 struct wcd9xxx_ch *ch;
4584 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
4585 u32 tx_port;
4586 u16 tx_port_reg, tx_fs_reg;
4587 u8 tx_port_reg_val;
4588 s8 decimator;
Kiran Kandic3b24402012-06-11 00:05:59 -07004589
Kuirong Wang906ac472012-07-09 12:54:44 -07004590 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
Kiran Kandic3b24402012-06-11 00:05:59 -07004591
Kuirong Wang906ac472012-07-09 12:54:44 -07004592 tx_port = ch->port + 1;
4593 pr_debug("%s: dai->id = %d, tx_port = %d",
4594 __func__, dai->id, tx_port);
4595
4596 if ((tx_port < 1) || (tx_port > NUM_DECIMATORS)) {
4597 pr_err("%s: Invalid SLIM TX%u port. DAI ID is %d\n",
4598 __func__, tx_port, dai->id);
4599 return -EINVAL;
4600 }
4601
4602 tx_port_reg = TAIKO_A_CDC_CONN_TX_SB_B1_CTL + (tx_port - 1);
4603 tx_port_reg_val = snd_soc_read(codec, tx_port_reg);
4604
4605 decimator = 0;
4606
4607 if ((tx_port >= 1) && (tx_port <= 6)) {
4608
4609 tx_port_reg_val = tx_port_reg_val & 0x0F;
4610 if (tx_port_reg_val == 0x8)
4611 decimator = tx_port;
4612
4613 } else if ((tx_port >= 7) && (tx_port <= NUM_DECIMATORS)) {
4614
4615 tx_port_reg_val = tx_port_reg_val & 0x1F;
4616
4617 if ((tx_port_reg_val >= 0x8) &&
4618 (tx_port_reg_val <= 0x11)) {
4619
4620 decimator = (tx_port_reg_val - 0x8) + 1;
4621 }
4622 }
4623
4624 if (decimator) { /* SLIM_TX port has a DEC as input */
4625
4626 tx_fs_reg = TAIKO_A_CDC_TX1_CLK_FS_CTL +
4627 8 * (decimator - 1);
4628
4629 pr_debug("%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
4630 __func__, decimator, tx_port, sample_rate);
4631
4632 snd_soc_update_bits(codec, tx_fs_reg, 0x07,
4633 tx_fs_rate_reg_val);
4634
4635 } else {
4636 if ((tx_port_reg_val >= 0x1) &&
4637 (tx_port_reg_val <= 0x7)) {
4638
4639 pr_debug("%s: RMIX%u going to SLIM TX%u\n",
4640 __func__, tx_port_reg_val, tx_port);
4641
4642 } else if ((tx_port_reg_val >= 0x8) &&
4643 (tx_port_reg_val <= 0x11)) {
4644
4645 pr_err("%s: ERROR: Should not be here\n",
4646 __func__);
4647 pr_err("%s: ERROR: DEC connected to SLIM TX%u\n",
4648 __func__, tx_port);
4649 return -EINVAL;
4650
4651 } else if (tx_port_reg_val == 0) {
4652 pr_debug("%s: no signal to SLIM TX%u\n",
4653 __func__, tx_port);
4654 } else {
4655 pr_err("%s: ERROR: wrong signal to SLIM TX%u\n",
4656 __func__, tx_port);
4657 pr_err("%s: ERROR: wrong signal = %u\n",
4658 __func__, tx_port_reg_val);
4659 return -EINVAL;
4660 }
4661 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004662 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004663 return 0;
4664}
4665
Patrick Laiff5a5782013-05-05 00:13:00 -07004666static void taiko_set_rxsb_port_format(struct snd_pcm_hw_params *params,
4667 struct snd_soc_dai *dai)
4668{
4669 struct snd_soc_codec *codec = dai->codec;
4670 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
4671 struct wcd9xxx_codec_dai_data *cdc_dai;
4672 struct wcd9xxx_ch *ch;
4673 int port;
4674 u8 bit_sel;
4675 u16 sb_ctl_reg, field_shift;
4676
4677 switch (params_format(params)) {
4678 case SNDRV_PCM_FORMAT_S16_LE:
4679 bit_sel = 0x2;
4680 taiko_p->dai[dai->id].bit_width = 16;
4681 break;
4682 case SNDRV_PCM_FORMAT_S24_LE:
4683 bit_sel = 0x0;
4684 taiko_p->dai[dai->id].bit_width = 24;
4685 break;
4686 default:
4687 dev_err(codec->dev, "Invalid format\n");
4688 return;
4689 }
4690
4691 cdc_dai = &taiko_p->dai[dai->id];
4692
4693 list_for_each_entry(ch, &cdc_dai->wcd9xxx_ch_list, list) {
4694 port = wcd9xxx_get_slave_port(ch->ch_num);
4695
4696 if (IS_ERR_VALUE(port) ||
4697 !TAIKO_VALIDATE_RX_SBPORT_RANGE(port)) {
4698 dev_warn(codec->dev,
4699 "%s: invalid port ID %d returned for RX DAI\n",
4700 __func__, port);
4701 return;
4702 }
4703
4704 port = TAIKO_CONVERT_RX_SBPORT_ID(port);
4705
4706 if (port <= 3) {
4707 sb_ctl_reg = TAIKO_A_CDC_CONN_RX_SB_B1_CTL;
4708 field_shift = port << 1;
4709 } else if (port <= 6) {
4710 sb_ctl_reg = TAIKO_A_CDC_CONN_RX_SB_B2_CTL;
4711 field_shift = (port - 4) << 1;
4712 } else { /* should not happen */
4713 dev_warn(codec->dev,
4714 "%s: bad port ID %d\n", __func__, port);
4715 return;
4716 }
4717
4718 dev_dbg(codec->dev, "%s: sb_ctl_reg %x field_shift %x\n",
4719 __func__, sb_ctl_reg, field_shift);
4720 snd_soc_update_bits(codec, sb_ctl_reg, 0x3 << field_shift,
4721 bit_sel << field_shift);
4722 }
4723}
4724
Kiran Kandic3b24402012-06-11 00:05:59 -07004725static int taiko_hw_params(struct snd_pcm_substream *substream,
4726 struct snd_pcm_hw_params *params,
4727 struct snd_soc_dai *dai)
4728{
4729 struct snd_soc_codec *codec = dai->codec;
4730 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07004731 u8 tx_fs_rate, rx_fs_rate;
Kiran Kandic3b24402012-06-11 00:05:59 -07004732 u32 compander_fs;
Kuirong Wang906ac472012-07-09 12:54:44 -07004733 int ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07004734
4735 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
4736 dai->name, dai->id, params_rate(params),
4737 params_channels(params));
4738
4739 switch (params_rate(params)) {
4740 case 8000:
4741 tx_fs_rate = 0x00;
4742 rx_fs_rate = 0x00;
4743 compander_fs = COMPANDER_FS_8KHZ;
4744 break;
4745 case 16000:
4746 tx_fs_rate = 0x01;
4747 rx_fs_rate = 0x20;
4748 compander_fs = COMPANDER_FS_16KHZ;
4749 break;
4750 case 32000:
4751 tx_fs_rate = 0x02;
4752 rx_fs_rate = 0x40;
4753 compander_fs = COMPANDER_FS_32KHZ;
4754 break;
4755 case 48000:
4756 tx_fs_rate = 0x03;
4757 rx_fs_rate = 0x60;
4758 compander_fs = COMPANDER_FS_48KHZ;
4759 break;
4760 case 96000:
4761 tx_fs_rate = 0x04;
4762 rx_fs_rate = 0x80;
4763 compander_fs = COMPANDER_FS_96KHZ;
4764 break;
4765 case 192000:
4766 tx_fs_rate = 0x05;
4767 rx_fs_rate = 0xA0;
4768 compander_fs = COMPANDER_FS_192KHZ;
4769 break;
4770 default:
4771 pr_err("%s: Invalid sampling rate %d\n", __func__,
Kuirong Wang906ac472012-07-09 12:54:44 -07004772 params_rate(params));
Kiran Kandic3b24402012-06-11 00:05:59 -07004773 return -EINVAL;
4774 }
4775
Kuirong Wang906ac472012-07-09 12:54:44 -07004776 switch (substream->stream) {
4777 case SNDRV_PCM_STREAM_CAPTURE:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004778 if (dai->id != AIF4_VIFEED) {
4779 ret = taiko_set_decimator_rate(dai, tx_fs_rate,
4780 params_rate(params));
4781 if (ret < 0) {
4782 pr_err("%s: set decimator rate failed %d\n",
4783 __func__, ret);
4784 return ret;
4785 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004786 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004787
Kiran Kandic3b24402012-06-11 00:05:59 -07004788 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4789 switch (params_format(params)) {
4790 case SNDRV_PCM_FORMAT_S16_LE:
4791 snd_soc_update_bits(codec,
4792 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4793 0x20, 0x20);
4794 break;
4795 case SNDRV_PCM_FORMAT_S32_LE:
4796 snd_soc_update_bits(codec,
4797 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4798 0x20, 0x00);
4799 break;
4800 default:
4801 pr_err("invalid format\n");
4802 break;
4803 }
4804 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07004805 0x07, tx_fs_rate);
Kiran Kandic3b24402012-06-11 00:05:59 -07004806 } else {
Kuirong Wang906ac472012-07-09 12:54:44 -07004807 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07004808 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004809 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07004810
Kuirong Wang906ac472012-07-09 12:54:44 -07004811 case SNDRV_PCM_STREAM_PLAYBACK:
4812 ret = taiko_set_interpolator_rate(dai, rx_fs_rate,
4813 compander_fs,
4814 params_rate(params));
4815 if (ret < 0) {
4816 pr_err("%s: set decimator rate failed %d\n", __func__,
4817 ret);
4818 return ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07004819 }
4820 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4821 switch (params_format(params)) {
4822 case SNDRV_PCM_FORMAT_S16_LE:
4823 snd_soc_update_bits(codec,
4824 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4825 0x20, 0x20);
4826 break;
4827 case SNDRV_PCM_FORMAT_S32_LE:
4828 snd_soc_update_bits(codec,
4829 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4830 0x20, 0x00);
4831 break;
4832 default:
4833 pr_err("invalid format\n");
4834 break;
4835 }
4836 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07004837 0x03, (rx_fs_rate >> 0x05));
Kiran Kandic3b24402012-06-11 00:05:59 -07004838 } else {
Patrick Laiff5a5782013-05-05 00:13:00 -07004839 taiko_set_rxsb_port_format(params, dai);
Kuirong Wang906ac472012-07-09 12:54:44 -07004840 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07004841 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004842 break;
4843 default:
4844 pr_err("%s: Invalid stream type %d\n", __func__,
4845 substream->stream);
4846 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004847 }
4848
4849 return 0;
4850}
4851
4852static struct snd_soc_dai_ops taiko_dai_ops = {
4853 .startup = taiko_startup,
4854 .shutdown = taiko_shutdown,
4855 .hw_params = taiko_hw_params,
4856 .set_sysclk = taiko_set_dai_sysclk,
4857 .set_fmt = taiko_set_dai_fmt,
4858 .set_channel_map = taiko_set_channel_map,
4859 .get_channel_map = taiko_get_channel_map,
4860};
4861
4862static struct snd_soc_dai_driver taiko_dai[] = {
4863 {
4864 .name = "taiko_rx1",
4865 .id = AIF1_PB,
4866 .playback = {
4867 .stream_name = "AIF1 Playback",
4868 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004869 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004870 .rate_max = 192000,
4871 .rate_min = 8000,
4872 .channels_min = 1,
4873 .channels_max = 2,
4874 },
4875 .ops = &taiko_dai_ops,
4876 },
4877 {
4878 .name = "taiko_tx1",
4879 .id = AIF1_CAP,
4880 .capture = {
4881 .stream_name = "AIF1 Capture",
4882 .rates = WCD9320_RATES,
4883 .formats = TAIKO_FORMATS,
4884 .rate_max = 192000,
4885 .rate_min = 8000,
4886 .channels_min = 1,
4887 .channels_max = 4,
4888 },
4889 .ops = &taiko_dai_ops,
4890 },
4891 {
4892 .name = "taiko_rx2",
4893 .id = AIF2_PB,
4894 .playback = {
4895 .stream_name = "AIF2 Playback",
4896 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004897 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004898 .rate_min = 8000,
4899 .rate_max = 192000,
4900 .channels_min = 1,
4901 .channels_max = 2,
4902 },
4903 .ops = &taiko_dai_ops,
4904 },
4905 {
4906 .name = "taiko_tx2",
4907 .id = AIF2_CAP,
4908 .capture = {
4909 .stream_name = "AIF2 Capture",
4910 .rates = WCD9320_RATES,
4911 .formats = TAIKO_FORMATS,
4912 .rate_max = 192000,
4913 .rate_min = 8000,
4914 .channels_min = 1,
Ravit Dennis895a5572013-06-05 16:34:42 +03004915 .channels_max = 8,
Kiran Kandic3b24402012-06-11 00:05:59 -07004916 },
4917 .ops = &taiko_dai_ops,
4918 },
4919 {
4920 .name = "taiko_tx3",
4921 .id = AIF3_CAP,
4922 .capture = {
4923 .stream_name = "AIF3 Capture",
4924 .rates = WCD9320_RATES,
4925 .formats = TAIKO_FORMATS,
4926 .rate_max = 48000,
4927 .rate_min = 8000,
4928 .channels_min = 1,
4929 .channels_max = 2,
4930 },
4931 .ops = &taiko_dai_ops,
4932 },
4933 {
4934 .name = "taiko_rx3",
4935 .id = AIF3_PB,
4936 .playback = {
4937 .stream_name = "AIF3 Playback",
4938 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004939 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004940 .rate_min = 8000,
4941 .rate_max = 192000,
4942 .channels_min = 1,
4943 .channels_max = 2,
4944 },
4945 .ops = &taiko_dai_ops,
4946 },
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004947 {
4948 .name = "taiko_vifeedback",
4949 .id = AIF4_VIFEED,
4950 .capture = {
4951 .stream_name = "VIfeed",
4952 .rates = SNDRV_PCM_RATE_48000,
4953 .formats = TAIKO_FORMATS,
4954 .rate_max = 48000,
4955 .rate_min = 48000,
4956 .channels_min = 2,
4957 .channels_max = 2,
4958 },
4959 .ops = &taiko_dai_ops,
4960 },
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004961 {
4962 .name = "taiko_mad1",
4963 .id = AIF4_MAD_TX,
4964 .capture = {
4965 .stream_name = "AIF4 MAD TX",
4966 .rates = SNDRV_PCM_RATE_16000,
4967 .formats = TAIKO_FORMATS,
4968 .rate_min = 16000,
4969 .rate_max = 16000,
4970 .channels_min = 1,
4971 .channels_max = 1,
4972 },
4973 .ops = &taiko_dai_ops,
4974 },
Kiran Kandic3b24402012-06-11 00:05:59 -07004975};
4976
4977static struct snd_soc_dai_driver taiko_i2s_dai[] = {
4978 {
4979 .name = "taiko_i2s_rx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07004980 .id = AIF1_PB,
Kiran Kandic3b24402012-06-11 00:05:59 -07004981 .playback = {
4982 .stream_name = "AIF1 Playback",
4983 .rates = WCD9320_RATES,
4984 .formats = TAIKO_FORMATS,
4985 .rate_max = 192000,
4986 .rate_min = 8000,
4987 .channels_min = 1,
4988 .channels_max = 4,
4989 },
4990 .ops = &taiko_dai_ops,
4991 },
4992 {
4993 .name = "taiko_i2s_tx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07004994 .id = AIF1_CAP,
Kiran Kandic3b24402012-06-11 00:05:59 -07004995 .capture = {
4996 .stream_name = "AIF1 Capture",
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 },
Venkat Sudhir994193b2012-12-17 17:30:51 -08005006 {
5007 .name = "taiko_i2s_rx2",
5008 .id = AIF1_PB,
5009 .playback = {
5010 .stream_name = "AIF2 Playback",
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 },
5020 {
5021 .name = "taiko_i2s_tx2",
5022 .id = AIF1_CAP,
5023 .capture = {
5024 .stream_name = "AIF2 Capture",
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 },
Kiran Kandic3b24402012-06-11 00:05:59 -07005034};
5035
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005036static int taiko_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
5037 bool up)
5038{
5039 int ret = 0;
5040 struct wcd9xxx_ch *ch;
5041
5042 if (up) {
5043 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
5044 ret = wcd9xxx_get_slave_port(ch->ch_num);
5045 if (ret < 0) {
5046 pr_err("%s: Invalid slave port ID: %d\n",
5047 __func__, ret);
5048 ret = -EINVAL;
5049 } else {
5050 set_bit(ret, &dai->ch_mask);
5051 }
5052 }
5053 } else {
5054 ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
5055 msecs_to_jiffies(
5056 TAIKO_SLIM_CLOSE_TIMEOUT));
5057 if (!ret) {
5058 pr_err("%s: Slim close tx/rx wait timeout\n", __func__);
5059 ret = -ETIMEDOUT;
5060 } else {
5061 ret = 0;
5062 }
5063 }
5064 return ret;
5065}
5066
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005067static void taiko_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai,
5068 struct snd_soc_codec *codec)
5069{
5070 struct wcd9xxx_ch *ch;
5071 int port_num = 0;
5072 unsigned short reg = 0;
5073 u8 val = 0;
5074 if (!dai || !codec) {
5075 pr_err("%s: Invalid params\n", __func__);
5076 return;
5077 }
5078 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
5079 if (ch->port >= TAIKO_RX_PORT_START_NUMBER) {
5080 port_num = ch->port - TAIKO_RX_PORT_START_NUMBER;
5081 reg = TAIKO_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
5082 val = wcd9xxx_interface_reg_read(codec->control_data,
5083 reg);
5084 if (!(val & (1 << (port_num % 8)))) {
5085 val |= (1 << (port_num % 8));
5086 wcd9xxx_interface_reg_write(
5087 codec->control_data, reg, val);
5088 val = wcd9xxx_interface_reg_read(
5089 codec->control_data, reg);
5090 }
5091 } else {
5092 port_num = ch->port;
5093 reg = TAIKO_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
5094 val = wcd9xxx_interface_reg_read(codec->control_data,
5095 reg);
5096 if (!(val & (1 << (port_num % 8)))) {
5097 val |= (1 << (port_num % 8));
5098 wcd9xxx_interface_reg_write(codec->control_data,
5099 reg, val);
5100 val = wcd9xxx_interface_reg_read(
5101 codec->control_data, reg);
5102 }
5103 }
5104 }
5105}
5106
Kiran Kandic3b24402012-06-11 00:05:59 -07005107static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07005108 struct snd_kcontrol *kcontrol,
5109 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07005110{
Kuirong Wang906ac472012-07-09 12:54:44 -07005111 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07005112 struct snd_soc_codec *codec = w->codec;
5113 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005114 int ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07005115 struct wcd9xxx_codec_dai_data *dai;
5116
5117 core = dev_get_drvdata(codec->dev->parent);
5118
5119 pr_debug("%s: event called! codec name %s num_dai %d\n"
5120 "stream name %s event %d\n",
5121 __func__, w->codec->name, w->codec->num_dai, w->sname, event);
5122
Kiran Kandic3b24402012-06-11 00:05:59 -07005123 /* Execute the callback only if interface type is slimbus */
5124 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
5125 return 0;
5126
Kuirong Wang906ac472012-07-09 12:54:44 -07005127 dai = &taiko_p->dai[w->shift];
5128 pr_debug("%s: w->name %s w->shift %d event %d\n",
5129 __func__, w->name, w->shift, event);
Kiran Kandic3b24402012-06-11 00:05:59 -07005130
5131 switch (event) {
5132 case SND_SOC_DAPM_POST_PMU:
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005133 taiko_codec_enable_int_port(dai, codec);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005134 (void) taiko_codec_enable_slim_chmask(dai, true);
Kuirong Wang906ac472012-07-09 12:54:44 -07005135 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
5136 dai->rate, dai->bit_width,
5137 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07005138 break;
5139 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07005140 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
5141 dai->grph);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005142 ret = taiko_codec_enable_slim_chmask(dai, false);
5143 if (ret < 0) {
5144 ret = wcd9xxx_disconnect_port(core,
5145 &dai->wcd9xxx_ch_list,
5146 dai->grph);
5147 pr_debug("%s: Disconnect RX port, ret = %d\n",
5148 __func__, ret);
5149 }
Kuirong Wang906ac472012-07-09 12:54:44 -07005150 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07005151 }
5152 return ret;
5153}
5154
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005155static int taiko_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
5156 struct snd_kcontrol *kcontrol,
5157 int event)
5158{
5159 struct wcd9xxx *core = NULL;
5160 struct snd_soc_codec *codec = NULL;
5161 struct taiko_priv *taiko_p = NULL;
5162 u32 ret = 0;
5163 struct wcd9xxx_codec_dai_data *dai = NULL;
5164
5165 if (!w || !w->codec) {
5166 pr_err("%s invalid params\n", __func__);
5167 return -EINVAL;
5168 }
5169 codec = w->codec;
5170 taiko_p = snd_soc_codec_get_drvdata(codec);
5171 core = dev_get_drvdata(codec->dev->parent);
5172
5173 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
5174 __func__, w->codec->name, w->codec->num_dai, w->sname);
5175
5176 /* Execute the callback only if interface type is slimbus */
5177 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
5178 pr_err("%s Interface is not correct", __func__);
5179 return 0;
5180 }
5181
5182 pr_debug("%s(): w->name %s event %d w->shift %d\n",
5183 __func__, w->name, event, w->shift);
5184 if (w->shift != AIF4_VIFEED) {
5185 pr_err("%s Error in enabling the tx path\n", __func__);
5186 ret = -EINVAL;
5187 goto out_vi;
5188 }
5189 dai = &taiko_p->dai[w->shift];
5190 switch (event) {
5191 case SND_SOC_DAPM_POST_PMU:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005192 /*Enable V&I sensing*/
5193 snd_soc_update_bits(codec, TAIKO_A_SPKR_PROT_EN,
5194 0x88, 0x88);
5195 /*Enable spkr VI clocks*/
5196 snd_soc_update_bits(codec,
5197 TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0xC, 0xC);
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005198 taiko_codec_enable_int_port(dai, codec);
Gopikrishnaiah Anandand3b89c02013-04-16 11:22:15 -04005199 (void) taiko_codec_enable_slim_chmask(dai, true);
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005200 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
5201 dai->rate, dai->bit_width,
5202 &dai->grph);
5203 break;
5204 case SND_SOC_DAPM_POST_PMD:
5205 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
5206 dai->grph);
5207 if (ret)
5208 pr_err("%s error in close_slim_sch_tx %d\n",
5209 __func__, ret);
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005210 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL,
5211 0xC, 0x0);
5212 /*Disable V&I sensing*/
5213 snd_soc_update_bits(codec, TAIKO_A_SPKR_PROT_EN,
5214 0x88, 0x00);
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005215 break;
5216 }
5217out_vi:
5218 return ret;
5219}
5220
Kiran Kandic3b24402012-06-11 00:05:59 -07005221static int taiko_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07005222 struct snd_kcontrol *kcontrol,
5223 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07005224{
Kuirong Wang906ac472012-07-09 12:54:44 -07005225 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07005226 struct snd_soc_codec *codec = w->codec;
5227 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07005228 u32 ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07005229 struct wcd9xxx_codec_dai_data *dai;
Kiran Kandic3b24402012-06-11 00:05:59 -07005230
Kuirong Wang906ac472012-07-09 12:54:44 -07005231 core = dev_get_drvdata(codec->dev->parent);
5232
5233 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
5234 __func__, w->codec->name, w->codec->num_dai, w->sname);
Kiran Kandic3b24402012-06-11 00:05:59 -07005235
5236 /* Execute the callback only if interface type is slimbus */
5237 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
5238 return 0;
5239
Kuirong Wang906ac472012-07-09 12:54:44 -07005240 pr_debug("%s(): w->name %s event %d w->shift %d\n",
5241 __func__, w->name, event, w->shift);
Kiran Kandic3b24402012-06-11 00:05:59 -07005242
Kuirong Wang906ac472012-07-09 12:54:44 -07005243 dai = &taiko_p->dai[w->shift];
Kiran Kandic3b24402012-06-11 00:05:59 -07005244 switch (event) {
5245 case SND_SOC_DAPM_POST_PMU:
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005246 taiko_codec_enable_int_port(dai, codec);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005247 (void) taiko_codec_enable_slim_chmask(dai, true);
Kuirong Wang906ac472012-07-09 12:54:44 -07005248 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
5249 dai->rate, dai->bit_width,
5250 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07005251 break;
5252 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07005253 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
5254 dai->grph);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005255 ret = taiko_codec_enable_slim_chmask(dai, false);
5256 if (ret < 0) {
5257 ret = wcd9xxx_disconnect_port(core,
5258 &dai->wcd9xxx_ch_list,
5259 dai->grph);
5260 pr_debug("%s: Disconnect RX port, ret = %d\n",
5261 __func__, ret);
5262 }
Kuirong Wang906ac472012-07-09 12:54:44 -07005263 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07005264 }
5265 return ret;
5266}
5267
Kiran Kandi4c56c592012-07-25 11:04:55 -07005268static int taiko_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
5269 struct snd_kcontrol *kcontrol, int event)
5270{
5271 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005272 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandi4c56c592012-07-25 11:04:55 -07005273
5274 pr_debug("%s %s %d\n", __func__, w->name, event);
5275
5276 switch (event) {
Kiran Kandi4c56c592012-07-25 11:04:55 -07005277 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005278 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
5279 WCD9XXX_CLSH_STATE_EAR,
5280 WCD9XXX_CLSH_REQ_ENABLE,
5281 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandi4c56c592012-07-25 11:04:55 -07005282
5283 usleep_range(5000, 5000);
5284 break;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005285 case SND_SOC_DAPM_POST_PMD:
5286 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
5287 WCD9XXX_CLSH_STATE_EAR,
5288 WCD9XXX_CLSH_REQ_DISABLE,
5289 WCD9XXX_CLSH_EVENT_POST_PA);
5290 usleep_range(5000, 5000);
5291 }
5292 return 0;
5293}
5294
5295static int taiko_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
5296 struct snd_kcontrol *kcontrol, int event)
5297{
5298 struct snd_soc_codec *codec = w->codec;
5299 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
5300
5301 pr_debug("%s %s %d\n", __func__, w->name, event);
5302
5303 switch (event) {
5304 case SND_SOC_DAPM_PRE_PMU:
5305 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
5306 WCD9XXX_CLSH_STATE_EAR,
5307 WCD9XXX_CLSH_REQ_ENABLE,
5308 WCD9XXX_CLSH_EVENT_PRE_DAC);
5309 break;
5310 }
5311
5312 return 0;
5313}
5314
Sudheer Papothi0ef366f2014-01-28 05:56:59 +05305315static int taiko_codec_iir_mux_event(struct snd_soc_dapm_widget *w,
5316 struct snd_kcontrol *kcontrol, int event)
5317{
5318 struct snd_soc_codec *codec = w->codec;
5319
5320 pr_debug("%s: event = %d\n", __func__, event);
5321
5322 switch (event) {
5323 case SND_SOC_DAPM_POST_PMU:
5324 snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
5325 break;
5326 case SND_SOC_DAPM_POST_PMD:
5327 snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
5328 break;
5329 }
5330 return 0;
5331}
5332
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005333static int taiko_codec_dsm_mux_event(struct snd_soc_dapm_widget *w,
5334 struct snd_kcontrol *kcontrol, int event)
5335{
5336 struct snd_soc_codec *codec = w->codec;
5337 u8 reg_val, zoh_mux_val = 0x00;
5338
5339 pr_debug("%s: event = %d\n", __func__, event);
5340
5341 switch (event) {
5342 case SND_SOC_DAPM_POST_PMU:
5343 reg_val = snd_soc_read(codec, TAIKO_A_CDC_CONN_CLSH_CTL);
5344
5345 if ((reg_val & 0x30) == 0x10)
5346 zoh_mux_val = 0x04;
5347 else if ((reg_val & 0x30) == 0x20)
5348 zoh_mux_val = 0x08;
5349
5350 if (zoh_mux_val != 0x00)
5351 snd_soc_update_bits(codec,
5352 TAIKO_A_CDC_CONN_CLSH_CTL,
5353 0x0C, zoh_mux_val);
5354 break;
5355
5356 case SND_SOC_DAPM_POST_PMD:
5357 snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_CLSH_CTL,
5358 0x0C, 0x00);
5359 break;
Kiran Kandi4c56c592012-07-25 11:04:55 -07005360 }
5361 return 0;
5362}
5363
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08005364static int taiko_codec_enable_anc_ear(struct snd_soc_dapm_widget *w,
5365 struct snd_kcontrol *kcontrol, int event)
5366{
5367 struct snd_soc_codec *codec = w->codec;
5368 int ret = 0;
5369
5370 switch (event) {
5371 case SND_SOC_DAPM_PRE_PMU:
5372 ret = taiko_codec_enable_anc(w, kcontrol, event);
5373 msleep(50);
5374 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x10);
5375 break;
5376 case SND_SOC_DAPM_POST_PMU:
5377 ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
5378 break;
5379 case SND_SOC_DAPM_PRE_PMD:
5380 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x00);
5381 msleep(40);
5382 ret |= taiko_codec_enable_anc(w, kcontrol, event);
5383 break;
5384 case SND_SOC_DAPM_POST_PMD:
5385 ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
5386 break;
5387 }
5388 return ret;
5389}
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005390
Kiran Kandic3b24402012-06-11 00:05:59 -07005391/* Todo: Have seperate dapm widgets for I2S and Slimbus.
5392 * Might Need to have callbacks registered only for slimbus
5393 */
5394static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
5395 /*RX stuff */
5396 SND_SOC_DAPM_OUTPUT("EAR"),
5397
Kiran Kandi4c56c592012-07-25 11:04:55 -07005398 SND_SOC_DAPM_PGA_E("EAR PA", TAIKO_A_RX_EAR_EN, 4, 0, NULL, 0,
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005399 taiko_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU |
5400 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005401
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005402 SND_SOC_DAPM_MIXER_E("DAC1", TAIKO_A_RX_EAR_EN, 6, 0, dac1_switch,
5403 ARRAY_SIZE(dac1_switch), taiko_codec_ear_dac_event,
5404 SND_SOC_DAPM_PRE_PMU),
Kiran Kandic3b24402012-06-11 00:05:59 -07005405
Kuirong Wang906ac472012-07-09 12:54:44 -07005406 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
5407 AIF1_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07005408 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07005409 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
5410 AIF2_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07005411 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07005412 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
5413 AIF3_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07005414 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5415
Kuirong Wang906ac472012-07-09 12:54:44 -07005416 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TAIKO_RX1, 0,
5417 &slim_rx_mux[TAIKO_RX1]),
5418 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TAIKO_RX2, 0,
5419 &slim_rx_mux[TAIKO_RX2]),
5420 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TAIKO_RX3, 0,
5421 &slim_rx_mux[TAIKO_RX3]),
5422 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TAIKO_RX4, 0,
5423 &slim_rx_mux[TAIKO_RX4]),
5424 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TAIKO_RX5, 0,
5425 &slim_rx_mux[TAIKO_RX5]),
5426 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TAIKO_RX6, 0,
5427 &slim_rx_mux[TAIKO_RX6]),
5428 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TAIKO_RX7, 0,
5429 &slim_rx_mux[TAIKO_RX7]),
Kiran Kandic3b24402012-06-11 00:05:59 -07005430
Kuirong Wang906ac472012-07-09 12:54:44 -07005431 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
5432 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
5433 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
5434 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
5435 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
5436 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
5437 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
Kiran Kandic3b24402012-06-11 00:05:59 -07005438
5439 /* Headphone */
5440 SND_SOC_DAPM_OUTPUT("HEADPHONE"),
5441 SND_SOC_DAPM_PGA_E("HPHL", TAIKO_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
5442 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07005443 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005444 SND_SOC_DAPM_MIXER_E("HPHL DAC", TAIKO_A_RX_HPH_L_DAC_CTL, 7, 0,
5445 hphl_switch, ARRAY_SIZE(hphl_switch), taiko_hphl_dac_event,
5446 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005447
5448 SND_SOC_DAPM_PGA_E("HPHR", TAIKO_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
5449 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07005450 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005451
5452 SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TAIKO_A_RX_HPH_R_DAC_CTL, 7, 0,
5453 taiko_hphr_dac_event,
5454 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5455
5456 /* Speaker */
5457 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
5458 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
5459 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
5460 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005461 SND_SOC_DAPM_OUTPUT("SPK_OUT"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005462
5463 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TAIKO_A_RX_LINE_CNP_EN, 0, 0, NULL,
5464 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
5465 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5466 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TAIKO_A_RX_LINE_CNP_EN, 1, 0, NULL,
5467 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
5468 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5469 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TAIKO_A_RX_LINE_CNP_EN, 2, 0, NULL,
5470 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
5471 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5472 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TAIKO_A_RX_LINE_CNP_EN, 3, 0, NULL,
5473 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
5474 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005475 SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0 , NULL,
5476 0, taiko_codec_enable_spk_pa,
5477 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005478
5479 SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAIKO_A_RX_LINE_1_DAC_CTL, 7, 0
5480 , taiko_lineout_dac_event,
5481 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5482 SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TAIKO_A_RX_LINE_2_DAC_CTL, 7, 0
5483 , taiko_lineout_dac_event,
5484 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5485 SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TAIKO_A_RX_LINE_3_DAC_CTL, 7, 0
5486 , taiko_lineout_dac_event,
5487 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5488 SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
5489 &lineout3_ground_switch),
5490 SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TAIKO_A_RX_LINE_4_DAC_CTL, 7, 0
5491 , taiko_lineout_dac_event,
5492 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5493 SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
5494 &lineout4_ground_switch),
5495
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005496 SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
5497 taiko_spk_dac_event,
5498 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5499
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005500 SND_SOC_DAPM_SUPPLY("VDD_SPKDRV", SND_SOC_NOPM, 0, 0,
5501 taiko_codec_enable_vdd_spkr,
5502 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5503
Kiran Kandid2b46332012-10-05 12:04:00 -07005504 SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
5505 SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
5506 SND_SOC_DAPM_MIXER("RX7 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
5507
Kiran Kandic3b24402012-06-11 00:05:59 -07005508 SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005509 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005510 SND_SOC_DAPM_POST_PMU),
5511 SND_SOC_DAPM_MIXER_E("RX2 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005512 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005513 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07005514 SND_SOC_DAPM_MIXER_E("RX3 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005515 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005516 SND_SOC_DAPM_POST_PMU),
5517 SND_SOC_DAPM_MIXER_E("RX4 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005518 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005519 SND_SOC_DAPM_POST_PMU),
5520 SND_SOC_DAPM_MIXER_E("RX5 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005521 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005522 SND_SOC_DAPM_POST_PMU),
5523 SND_SOC_DAPM_MIXER_E("RX6 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005524 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005525 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07005526 SND_SOC_DAPM_MIXER_E("RX7 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005527 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07005528 SND_SOC_DAPM_POST_PMU),
5529
Kiran Kandic3b24402012-06-11 00:05:59 -07005530
5531 SND_SOC_DAPM_MIXER("RX1 CHAIN", TAIKO_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
5532 SND_SOC_DAPM_MIXER("RX2 CHAIN", TAIKO_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
5533
5534 SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5535 &rx_mix1_inp1_mux),
5536 SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5537 &rx_mix1_inp2_mux),
5538 SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
5539 &rx_mix1_inp3_mux),
5540 SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5541 &rx2_mix1_inp1_mux),
5542 SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5543 &rx2_mix1_inp2_mux),
5544 SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5545 &rx3_mix1_inp1_mux),
5546 SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5547 &rx3_mix1_inp2_mux),
5548 SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5549 &rx4_mix1_inp1_mux),
5550 SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5551 &rx4_mix1_inp2_mux),
5552 SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5553 &rx5_mix1_inp1_mux),
5554 SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5555 &rx5_mix1_inp2_mux),
5556 SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5557 &rx6_mix1_inp1_mux),
5558 SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5559 &rx6_mix1_inp2_mux),
5560 SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
5561 &rx7_mix1_inp1_mux),
5562 SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
5563 &rx7_mix1_inp2_mux),
5564 SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
5565 &rx1_mix2_inp1_mux),
5566 SND_SOC_DAPM_MUX("RX1 MIX2 INP2", SND_SOC_NOPM, 0, 0,
5567 &rx1_mix2_inp2_mux),
5568 SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
5569 &rx2_mix2_inp1_mux),
5570 SND_SOC_DAPM_MUX("RX2 MIX2 INP2", SND_SOC_NOPM, 0, 0,
5571 &rx2_mix2_inp2_mux),
5572 SND_SOC_DAPM_MUX("RX7 MIX2 INP1", SND_SOC_NOPM, 0, 0,
5573 &rx7_mix2_inp1_mux),
5574 SND_SOC_DAPM_MUX("RX7 MIX2 INP2", SND_SOC_NOPM, 0, 0,
5575 &rx7_mix2_inp2_mux),
5576
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02005577 SND_SOC_DAPM_MUX("RDAC5 MUX", SND_SOC_NOPM, 0, 0,
5578 &rx_dac5_mux),
5579 SND_SOC_DAPM_MUX("RDAC7 MUX", SND_SOC_NOPM, 0, 0,
5580 &rx_dac7_mux),
5581
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005582 SND_SOC_DAPM_MUX_E("CLASS_H_DSM MUX", SND_SOC_NOPM, 0, 0,
5583 &class_h_dsm_mux, taiko_codec_dsm_mux_event,
5584 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandi4c56c592012-07-25 11:04:55 -07005585
Kiran Kandic3b24402012-06-11 00:05:59 -07005586 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
5587 taiko_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
5588 SND_SOC_DAPM_POST_PMD),
5589
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005590 SND_SOC_DAPM_SUPPLY("CDC_I2S_RX_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 5, 0,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005591 NULL, 0),
5592
Kiran Kandic3b24402012-06-11 00:05:59 -07005593 /* TX */
5594
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005595 SND_SOC_DAPM_SUPPLY("CDC_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
Kiran Kandic3b24402012-06-11 00:05:59 -07005596 0),
5597
Joonwoo Parkccccba72013-04-26 11:19:46 -07005598 SND_SOC_DAPM_SUPPLY("LDO_H", SND_SOC_NOPM, 7, 0,
5599 taiko_codec_enable_ldo_h,
5600 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
5601 /*
5602 * DAPM 'LDO_H Standalone' is to be powered by mbhc driver after
5603 * acquring codec_resource lock.
5604 * So call __taiko_codec_enable_ldo_h instead and avoid deadlock.
5605 */
5606 SND_SOC_DAPM_SUPPLY("LDO_H Standalone", SND_SOC_NOPM, 7, 0,
5607 __taiko_codec_enable_ldo_h,
5608 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005609
Joonwoo Parkc7731432012-10-17 12:41:44 -07005610 SND_SOC_DAPM_SUPPLY("COMP0_CLK", SND_SOC_NOPM, 0, 0,
Kiran Kandic3b24402012-06-11 00:05:59 -07005611 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07005612 SND_SOC_DAPM_PRE_PMD),
Joonwoo Parkc7731432012-10-17 12:41:44 -07005613 SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 1, 0,
5614 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07005615 SND_SOC_DAPM_PRE_PMD),
Joonwoo Parkc7731432012-10-17 12:41:44 -07005616 SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 2, 0,
Kiran Kandic3b24402012-06-11 00:05:59 -07005617 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
Bhalchandra Gajareed090e62013-03-29 16:11:49 -07005618 SND_SOC_DAPM_PRE_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005619
5620
5621 SND_SOC_DAPM_INPUT("AMIC1"),
Joonwoo Park3699ca32013-02-08 12:06:15 -08005622 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", SND_SOC_NOPM, 7, 0,
5623 taiko_codec_enable_micbias,
5624 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5625 SND_SOC_DAPM_POST_PMD),
5626 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", SND_SOC_NOPM, 7, 0,
5627 taiko_codec_enable_micbias,
5628 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5629 SND_SOC_DAPM_POST_PMD),
5630 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", SND_SOC_NOPM, 7, 0,
5631 taiko_codec_enable_micbias,
5632 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5633 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005634
5635 SND_SOC_DAPM_INPUT("AMIC3"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005636
5637 SND_SOC_DAPM_INPUT("AMIC4"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005638
5639 SND_SOC_DAPM_INPUT("AMIC5"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005640
5641 SND_SOC_DAPM_INPUT("AMIC6"),
Kiran Kandic3b24402012-06-11 00:05:59 -07005642
5643 SND_SOC_DAPM_MUX_E("DEC1 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
5644 &dec1_mux, taiko_codec_enable_dec,
5645 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5646 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5647
5648 SND_SOC_DAPM_MUX_E("DEC2 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
5649 &dec2_mux, taiko_codec_enable_dec,
5650 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5651 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5652
5653 SND_SOC_DAPM_MUX_E("DEC3 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
5654 &dec3_mux, taiko_codec_enable_dec,
5655 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5656 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5657
5658 SND_SOC_DAPM_MUX_E("DEC4 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
5659 &dec4_mux, taiko_codec_enable_dec,
5660 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5661 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5662
5663 SND_SOC_DAPM_MUX_E("DEC5 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
5664 &dec5_mux, taiko_codec_enable_dec,
5665 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5666 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5667
5668 SND_SOC_DAPM_MUX_E("DEC6 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
5669 &dec6_mux, taiko_codec_enable_dec,
5670 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5671 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5672
5673 SND_SOC_DAPM_MUX_E("DEC7 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
5674 &dec7_mux, taiko_codec_enable_dec,
5675 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5676 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5677
5678 SND_SOC_DAPM_MUX_E("DEC8 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
5679 &dec8_mux, taiko_codec_enable_dec,
5680 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5681 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5682
5683 SND_SOC_DAPM_MUX_E("DEC9 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
5684 &dec9_mux, taiko_codec_enable_dec,
5685 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5686 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5687
5688 SND_SOC_DAPM_MUX_E("DEC10 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
5689 &dec10_mux, taiko_codec_enable_dec,
5690 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5691 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
5692
5693 SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
5694 SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
5695
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08005696 SND_SOC_DAPM_OUTPUT("ANC HEADPHONE"),
5697 SND_SOC_DAPM_PGA_E("ANC HPHL", SND_SOC_NOPM, 5, 0, NULL, 0,
5698 taiko_codec_enable_anc_hph,
5699 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
5700 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
5701 SND_SOC_DAPM_PGA_E("ANC HPHR", SND_SOC_NOPM, 4, 0, NULL, 0,
5702 taiko_codec_enable_anc_hph, SND_SOC_DAPM_PRE_PMU |
5703 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
5704 SND_SOC_DAPM_POST_PMU),
5705 SND_SOC_DAPM_OUTPUT("ANC EAR"),
5706 SND_SOC_DAPM_PGA_E("ANC EAR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
5707 taiko_codec_enable_anc_ear,
5708 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
5709 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005710 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
5711
5712 SND_SOC_DAPM_INPUT("AMIC2"),
Joonwoo Parkccccba72013-04-26 11:19:46 -07005713 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_EXTERNAL_STANDALONE, SND_SOC_NOPM,
5714 7, 0, taiko_codec_enable_micbias,
5715 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5716 SND_SOC_DAPM_POST_PMD),
Joonwoo Park3699ca32013-02-08 12:06:15 -08005717 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 7, 0,
5718 taiko_codec_enable_micbias,
5719 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5720 SND_SOC_DAPM_POST_PMD),
5721 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 7, 0,
5722 taiko_codec_enable_micbias,
5723 SND_SOC_DAPM_PRE_PMU |
5724 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5725 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 7, 0,
5726 taiko_codec_enable_micbias,
5727 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5728 SND_SOC_DAPM_POST_PMD),
5729 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 7, 0,
5730 taiko_codec_enable_micbias,
5731 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5732 SND_SOC_DAPM_POST_PMD),
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07005733 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_EXTERNAL_STANDALONE, SND_SOC_NOPM,
5734 7, 0, taiko_codec_enable_micbias,
5735 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5736 SND_SOC_DAPM_POST_PMD),
Joonwoo Park3699ca32013-02-08 12:06:15 -08005737 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 7, 0,
5738 taiko_codec_enable_micbias,
5739 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5740 SND_SOC_DAPM_POST_PMD),
5741 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 7, 0,
5742 taiko_codec_enable_micbias,
5743 SND_SOC_DAPM_PRE_PMU |
5744 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5745 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 7, 0,
5746 taiko_codec_enable_micbias,
5747 SND_SOC_DAPM_PRE_PMU |
5748 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5749 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", SND_SOC_NOPM, 7,
5750 0, taiko_codec_enable_micbias,
5751 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5752 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005753
Kuirong Wang906ac472012-07-09 12:54:44 -07005754 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
5755 AIF1_CAP, 0, taiko_codec_enable_slimtx,
5756 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005757
Kuirong Wang906ac472012-07-09 12:54:44 -07005758 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
5759 AIF2_CAP, 0, taiko_codec_enable_slimtx,
5760 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005761
Kuirong Wang906ac472012-07-09 12:54:44 -07005762 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
5763 AIF3_CAP, 0, taiko_codec_enable_slimtx,
5764 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005765
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005766 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
5767 AIF4_VIFEED, 0, taiko_codec_enable_slimvi_feedback,
5768 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005769 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
Joonwoo Park9ead0e92013-03-18 11:33:33 -07005770 SND_SOC_NOPM, 0, 0,
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005771 taiko_codec_enable_mad, SND_SOC_DAPM_PRE_PMU),
Joonwoo Park9ead0e92013-03-18 11:33:33 -07005772 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
5773 &aif4_mad_switch),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005774 SND_SOC_DAPM_INPUT("MADINPUT"),
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005775
Kuirong Wang906ac472012-07-09 12:54:44 -07005776 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
5777 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005778
Kuirong Wang906ac472012-07-09 12:54:44 -07005779 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
5780 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005781
Kuirong Wang906ac472012-07-09 12:54:44 -07005782 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
5783 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005784
Kuirong Wang906ac472012-07-09 12:54:44 -07005785 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TAIKO_TX1, 0,
5786 &sb_tx1_mux),
5787 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TAIKO_TX2, 0,
5788 &sb_tx2_mux),
5789 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TAIKO_TX3, 0,
5790 &sb_tx3_mux),
5791 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TAIKO_TX4, 0,
5792 &sb_tx4_mux),
5793 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TAIKO_TX5, 0,
5794 &sb_tx5_mux),
5795 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TAIKO_TX6, 0,
5796 &sb_tx6_mux),
5797 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TAIKO_TX7, 0,
5798 &sb_tx7_mux),
5799 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TAIKO_TX8, 0,
5800 &sb_tx8_mux),
5801 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TAIKO_TX9, 0,
5802 &sb_tx9_mux),
5803 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TAIKO_TX10, 0,
5804 &sb_tx10_mux),
Kiran Kandic3b24402012-06-11 00:05:59 -07005805
5806 /* Digital Mic Inputs */
5807 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
5808 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5809 SND_SOC_DAPM_POST_PMD),
5810
5811 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
5812 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5813 SND_SOC_DAPM_POST_PMD),
5814
5815 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
5816 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5817 SND_SOC_DAPM_POST_PMD),
5818
5819 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
5820 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5821 SND_SOC_DAPM_POST_PMD),
5822
5823 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
5824 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5825 SND_SOC_DAPM_POST_PMD),
5826 SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
5827 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5828 SND_SOC_DAPM_POST_PMD),
5829
5830 /* Sidetone */
Sudheer Papothi0ef366f2014-01-28 05:56:59 +05305831 SND_SOC_DAPM_MUX_E("IIR1 INP1 MUX", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, 0, 0,
5832 &iir1_inp1_mux, taiko_codec_iir_mux_event,
5833 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5834
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05305835 SND_SOC_DAPM_MUX_E("IIR1 INP2 MUX", TAIKO_A_CDC_IIR1_GAIN_B2_CTL, 0, 0,
5836 &iir1_inp2_mux, taiko_codec_iir_mux_event,
5837 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5838
5839 SND_SOC_DAPM_MUX_E("IIR1 INP3 MUX", TAIKO_A_CDC_IIR1_GAIN_B3_CTL, 0, 0,
5840 &iir1_inp3_mux, taiko_codec_iir_mux_event,
5841 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5842
5843 SND_SOC_DAPM_MUX_E("IIR1 INP4 MUX", TAIKO_A_CDC_IIR1_GAIN_B4_CTL, 0, 0,
5844 &iir1_inp4_mux, taiko_codec_iir_mux_event,
5845 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5846
Kiran Kandibd85d772013-05-19 19:03:43 -07005847 SND_SOC_DAPM_MIXER("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
Kiran Kandic3b24402012-06-11 00:05:59 -07005848
Sudheer Papothi0ef366f2014-01-28 05:56:59 +05305849 SND_SOC_DAPM_MUX_E("IIR2 INP1 MUX", TAIKO_A_CDC_IIR2_GAIN_B1_CTL, 0, 0,
5850 &iir2_inp1_mux, taiko_codec_iir_mux_event,
5851 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5852
Sudheer Papothi8368d4f2014-02-12 07:15:08 +05305853 SND_SOC_DAPM_MUX_E("IIR2 INP2 MUX", TAIKO_A_CDC_IIR2_GAIN_B2_CTL, 0, 0,
5854 &iir2_inp2_mux, taiko_codec_iir_mux_event,
5855 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5856
5857 SND_SOC_DAPM_MUX_E("IIR2 INP3 MUX", TAIKO_A_CDC_IIR2_GAIN_B3_CTL, 0, 0,
5858 &iir2_inp3_mux, taiko_codec_iir_mux_event,
5859 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5860
5861 SND_SOC_DAPM_MUX_E("IIR2 INP4 MUX", TAIKO_A_CDC_IIR2_GAIN_B4_CTL, 0, 0,
5862 &iir2_inp4_mux, taiko_codec_iir_mux_event,
5863 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5864
Kiran Kandibd85d772013-05-19 19:03:43 -07005865 SND_SOC_DAPM_MIXER("IIR2", TAIKO_A_CDC_CLK_SD_CTL, 1, 0, NULL, 0),
Fred Oh456fcb52013-02-28 19:08:15 -08005866
Kiran Kandic3b24402012-06-11 00:05:59 -07005867 /* AUX PGA */
5868 SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TAIKO_A_RX_AUX_SW_CTL, 7, 0,
5869 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
5870 SND_SOC_DAPM_POST_PMD),
5871
5872 SND_SOC_DAPM_ADC_E("AUX_PGA_Right", NULL, TAIKO_A_RX_AUX_SW_CTL, 6, 0,
5873 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
5874 SND_SOC_DAPM_POST_PMD),
5875
5876 /* Lineout, ear and HPH PA Mixers */
5877
5878 SND_SOC_DAPM_MIXER("EAR_PA_MIXER", SND_SOC_NOPM, 0, 0,
5879 ear_pa_mix, ARRAY_SIZE(ear_pa_mix)),
5880
5881 SND_SOC_DAPM_MIXER("HPHL_PA_MIXER", SND_SOC_NOPM, 0, 0,
5882 hphl_pa_mix, ARRAY_SIZE(hphl_pa_mix)),
5883
5884 SND_SOC_DAPM_MIXER("HPHR_PA_MIXER", SND_SOC_NOPM, 0, 0,
5885 hphr_pa_mix, ARRAY_SIZE(hphr_pa_mix)),
5886
5887 SND_SOC_DAPM_MIXER("LINEOUT1_PA_MIXER", SND_SOC_NOPM, 0, 0,
5888 lineout1_pa_mix, ARRAY_SIZE(lineout1_pa_mix)),
5889
5890 SND_SOC_DAPM_MIXER("LINEOUT2_PA_MIXER", SND_SOC_NOPM, 0, 0,
5891 lineout2_pa_mix, ARRAY_SIZE(lineout2_pa_mix)),
5892
5893 SND_SOC_DAPM_MIXER("LINEOUT3_PA_MIXER", SND_SOC_NOPM, 0, 0,
5894 lineout3_pa_mix, ARRAY_SIZE(lineout3_pa_mix)),
5895
5896 SND_SOC_DAPM_MIXER("LINEOUT4_PA_MIXER", SND_SOC_NOPM, 0, 0,
5897 lineout4_pa_mix, ARRAY_SIZE(lineout4_pa_mix)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005898};
5899
Kiran Kandic3b24402012-06-11 00:05:59 -07005900static irqreturn_t taiko_slimbus_irq(int irq, void *data)
5901{
5902 struct taiko_priv *priv = data;
5903 struct snd_soc_codec *codec = priv->codec;
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005904 unsigned long status = 0;
5905 int i, j, port_id, k;
5906 u32 bit;
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005907 u8 val, int_val = 0;
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005908 bool tx, cleared;
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005909 unsigned short reg = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07005910
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005911 for (i = TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
5912 i <= TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
5913 val = wcd9xxx_interface_reg_read(codec->control_data, i);
5914 status |= ((u32)val << (8 * j));
5915 }
5916
5917 for_each_set_bit(j, &status, 32) {
5918 tx = (j >= 16 ? true : false);
5919 port_id = (tx ? j - 16 : j);
5920 val = wcd9xxx_interface_reg_read(codec->control_data,
5921 TAIKO_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
5922 if (val & TAIKO_SLIM_IRQ_OVERFLOW)
5923 pr_err_ratelimited(
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005924 "%s: overflow error on %s port %d, value %x\n",
5925 __func__, (tx ? "TX" : "RX"), port_id, val);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005926 if (val & TAIKO_SLIM_IRQ_UNDERFLOW)
5927 pr_err_ratelimited(
Gopikrishnaiah Anandanf8756272013-08-09 13:24:23 -04005928 "%s: underflow error on %s port %d, value %x\n",
5929 __func__, (tx ? "TX" : "RX"), port_id, val);
5930 if ((val & TAIKO_SLIM_IRQ_OVERFLOW) ||
5931 (val & TAIKO_SLIM_IRQ_UNDERFLOW)) {
5932 if (!tx)
5933 reg = TAIKO_SLIM_PGD_PORT_INT_EN0 +
5934 (port_id / 8);
5935 else
5936 reg = TAIKO_SLIM_PGD_PORT_INT_TX_EN0 +
5937 (port_id / 8);
5938 int_val = wcd9xxx_interface_reg_read(
5939 codec->control_data, reg);
5940 if (int_val & (1 << (port_id % 8))) {
5941 int_val = int_val ^ (1 << (port_id % 8));
5942 wcd9xxx_interface_reg_write(codec->control_data,
5943 reg, int_val);
5944 }
5945 }
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005946 if (val & TAIKO_SLIM_IRQ_PORT_CLOSED) {
5947 /*
5948 * INT SOURCE register starts from RX to TX
5949 * but port number in the ch_mask is in opposite way
5950 */
5951 bit = (tx ? j - 16 : j + 16);
5952 pr_debug("%s: %s port %d closed value %x, bit %u\n",
5953 __func__, (tx ? "TX" : "RX"), port_id, val,
5954 bit);
5955 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
5956 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
5957 __func__, k, priv->dai[k].ch_mask);
5958 if (test_and_clear_bit(bit,
5959 &priv->dai[k].ch_mask)) {
5960 cleared = true;
5961 if (!priv->dai[k].ch_mask)
5962 wake_up(&priv->dai[k].dai_wait);
5963 /*
5964 * There are cases when multiple DAIs
5965 * might be using the same slimbus
5966 * channel. Hence don't break here.
5967 */
5968 }
5969 }
5970 WARN(!cleared,
5971 "Couldn't find slimbus %s port %d for closing\n",
5972 (tx ? "TX" : "RX"), port_id);
Kiran Kandic3b24402012-06-11 00:05:59 -07005973 }
5974 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005975 TAIKO_SLIM_PGD_PORT_INT_CLR_RX_0 +
5976 (j / 8),
5977 1 << (j % 8));
Joonwoo Parka8890262012-10-15 12:04:27 -07005978 }
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005979
Kiran Kandic3b24402012-06-11 00:05:59 -07005980 return IRQ_HANDLED;
5981}
5982
5983static int taiko_handle_pdata(struct taiko_priv *taiko)
5984{
5985 struct snd_soc_codec *codec = taiko->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07005986 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
Kiran Kandic3b24402012-06-11 00:05:59 -07005987 int k1, k2, k3, rc = 0;
Kiran Kandi725f8492012-08-06 13:45:16 -07005988 u8 leg_mode, txfe_bypass, txfe_buff, flag;
Kiran Kandic3b24402012-06-11 00:05:59 -07005989 u8 i = 0, j = 0;
5990 u8 val_txfe = 0, value = 0;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07005991 u8 dmic_sample_rate_value = 0;
5992 u8 dmic_b1_ctl_value = 0, dmic_b2_ctl_value = 0;
5993 u8 anc_ctl_value = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07005994
5995 if (!pdata) {
Kiran Kandi725f8492012-08-06 13:45:16 -07005996 pr_err("%s: NULL pdata\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07005997 rc = -ENODEV;
5998 goto done;
5999 }
6000
Kiran Kandi725f8492012-08-06 13:45:16 -07006001 leg_mode = pdata->amic_settings.legacy_mode;
6002 txfe_bypass = pdata->amic_settings.txfe_enable;
6003 txfe_buff = pdata->amic_settings.txfe_buff;
6004 flag = pdata->amic_settings.use_pdata;
6005
Kiran Kandic3b24402012-06-11 00:05:59 -07006006 /* Make sure settings are correct */
Joonwoo Parka8890262012-10-15 12:04:27 -07006007 if ((pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V) ||
6008 (pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
6009 (pdata->micbias.bias2_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
6010 (pdata->micbias.bias3_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
6011 (pdata->micbias.bias4_cfilt_sel > WCD9XXX_CFILT3_SEL)) {
Kiran Kandic3b24402012-06-11 00:05:59 -07006012 rc = -EINVAL;
6013 goto done;
6014 }
Kiran Kandic3b24402012-06-11 00:05:59 -07006015 /* figure out k value */
Joonwoo Parka8890262012-10-15 12:04:27 -07006016 k1 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt1_mv);
6017 k2 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt2_mv);
6018 k3 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt3_mv);
Kiran Kandic3b24402012-06-11 00:05:59 -07006019
6020 if (IS_ERR_VALUE(k1) || IS_ERR_VALUE(k2) || IS_ERR_VALUE(k3)) {
6021 rc = -EINVAL;
6022 goto done;
6023 }
Kiran Kandic3b24402012-06-11 00:05:59 -07006024 /* Set voltage level and always use LDO */
6025 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 0x0C,
Joonwoo Parka8890262012-10-15 12:04:27 -07006026 (pdata->micbias.ldoh_v << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07006027
Joonwoo Parka8890262012-10-15 12:04:27 -07006028 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_1_VAL, 0xFC, (k1 << 2));
6029 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_2_VAL, 0xFC, (k2 << 2));
6030 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_3_VAL, 0xFC, (k3 << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07006031
6032 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07006033 (pdata->micbias.bias1_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07006034 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07006035 (pdata->micbias.bias2_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07006036 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07006037 (pdata->micbias.bias3_cfilt_sel << 5));
6038 snd_soc_update_bits(codec, taiko->resmgr.reg_addr->micb_4_ctl, 0x60,
Kiran Kandic3b24402012-06-11 00:05:59 -07006039 (pdata->micbias.bias4_cfilt_sel << 5));
6040
6041 for (i = 0; i < 6; j++, i += 2) {
6042 if (flag & (0x01 << i)) {
6043 value = (leg_mode & (0x01 << i)) ? 0x10 : 0x00;
6044 val_txfe = (txfe_bypass & (0x01 << i)) ? 0x20 : 0x00;
6045 val_txfe = val_txfe |
6046 ((txfe_buff & (0x01 << i)) ? 0x10 : 0x00);
6047 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
6048 0x10, value);
6049 snd_soc_update_bits(codec,
6050 TAIKO_A_TX_1_2_TEST_EN + j * 10,
6051 0x30, val_txfe);
6052 }
6053 if (flag & (0x01 << (i + 1))) {
6054 value = (leg_mode & (0x01 << (i + 1))) ? 0x01 : 0x00;
6055 val_txfe = (txfe_bypass &
6056 (0x01 << (i + 1))) ? 0x02 : 0x00;
6057 val_txfe |= (txfe_buff &
6058 (0x01 << (i + 1))) ? 0x01 : 0x00;
6059 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
6060 0x01, value);
6061 snd_soc_update_bits(codec,
6062 TAIKO_A_TX_1_2_TEST_EN + j * 10,
6063 0x03, val_txfe);
6064 }
6065 }
6066 if (flag & 0x40) {
6067 value = (leg_mode & 0x40) ? 0x10 : 0x00;
6068 value = value | ((txfe_bypass & 0x40) ? 0x02 : 0x00);
6069 value = value | ((txfe_buff & 0x40) ? 0x01 : 0x00);
6070 snd_soc_update_bits(codec, TAIKO_A_TX_7_MBHC_EN,
6071 0x13, value);
6072 }
6073
6074 if (pdata->ocp.use_pdata) {
6075 /* not defined in CODEC specification */
6076 if (pdata->ocp.hph_ocp_limit == 1 ||
6077 pdata->ocp.hph_ocp_limit == 5) {
6078 rc = -EINVAL;
6079 goto done;
6080 }
6081 snd_soc_update_bits(codec, TAIKO_A_RX_COM_OCP_CTL,
6082 0x0F, pdata->ocp.num_attempts);
6083 snd_soc_write(codec, TAIKO_A_RX_COM_OCP_COUNT,
6084 ((pdata->ocp.run_time << 4) | pdata->ocp.wait_time));
6085 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_OCP_CTL,
6086 0xE0, (pdata->ocp.hph_ocp_limit << 5));
6087 }
6088
6089 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
Joonwoo Park448a8fc2013-04-10 15:25:58 -07006090 if (pdata->regulator[i].name &&
6091 !strncmp(pdata->regulator[i].name, "CDC_VDDA_RX", 11)) {
Kiran Kandic3b24402012-06-11 00:05:59 -07006092 if (pdata->regulator[i].min_uV == 1800000 &&
6093 pdata->regulator[i].max_uV == 1800000) {
6094 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
6095 0x1C);
6096 } else if (pdata->regulator[i].min_uV == 2200000 &&
6097 pdata->regulator[i].max_uV == 2200000) {
6098 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
6099 0x1E);
6100 } else {
6101 pr_err("%s: unsupported CDC_VDDA_RX voltage\n"
6102 "min %d, max %d\n", __func__,
6103 pdata->regulator[i].min_uV,
6104 pdata->regulator[i].max_uV);
6105 rc = -EINVAL;
6106 }
6107 break;
6108 }
6109 }
Kiran Kandi4c56c592012-07-25 11:04:55 -07006110
Joonwoo Park1848c762012-10-18 13:16:01 -07006111 /* Set micbias capless mode with tail current */
6112 value = (pdata->micbias.bias1_cap_mode == MICBIAS_EXT_BYP_CAP ?
6113 0x00 : 0x16);
6114 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x1E, value);
6115 value = (pdata->micbias.bias2_cap_mode == MICBIAS_EXT_BYP_CAP ?
6116 0x00 : 0x16);
6117 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x1E, value);
6118 value = (pdata->micbias.bias3_cap_mode == MICBIAS_EXT_BYP_CAP ?
6119 0x00 : 0x16);
6120 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x1E, value);
6121 value = (pdata->micbias.bias4_cap_mode == MICBIAS_EXT_BYP_CAP ?
6122 0x00 : 0x16);
6123 snd_soc_update_bits(codec, TAIKO_A_MICB_4_CTL, 0x1E, value);
6124
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006125 /* Set the DMIC sample rate */
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07006126 if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6MHZ) {
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006127 switch (pdata->dmic_sample_rate) {
Damir Didjusto5f553e92013-10-02 14:54:31 -07006128 case WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ:
6129 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
6130 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
6131 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_4;
6132 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006133 break;
Damir Didjusto5f553e92013-10-02 14:54:31 -07006134 case WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ:
6135 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
6136 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
6137 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_2;
6138 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006139 break;
Damir Didjusto5f553e92013-10-02 14:54:31 -07006140 case WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ:
6141 case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
6142 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
6143 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
6144 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_3;
6145 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006146 break;
6147 default:
6148 pr_err("%s Invalid sample rate %d for mclk %d\n",
6149 __func__, pdata->dmic_sample_rate, pdata->mclk_rate);
6150 rc = -EINVAL;
6151 goto done;
6152 break;
6153 }
6154 } else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
6155 switch (pdata->dmic_sample_rate) {
Damir Didjusto5f553e92013-10-02 14:54:31 -07006156 case WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ:
6157 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
6158 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
6159 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_4;
6160 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006161 break;
Damir Didjusto5f553e92013-10-02 14:54:31 -07006162 case WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ:
6163 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
6164 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
6165 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_2;
6166 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006167 break;
Damir Didjusto5f553e92013-10-02 14:54:31 -07006168 case WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ:
6169 case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
6170 dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
6171 dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
6172 dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_3;
6173 anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07006174 break;
6175 default:
6176 pr_err("%s Invalid sample rate %d for mclk %d\n",
6177 __func__, pdata->dmic_sample_rate, pdata->mclk_rate);
6178 rc = -EINVAL;
6179 goto done;
6180 break;
6181 }
6182 } else {
6183 pr_err("%s MCLK is not set!\n", __func__);
6184 rc = -EINVAL;
6185 goto done;
6186 }
6187
6188 snd_soc_update_bits(codec, TAIKO_A_CDC_TX1_DMIC_CTL,
6189 0x7, dmic_sample_rate_value);
6190 snd_soc_update_bits(codec, TAIKO_A_CDC_TX2_DMIC_CTL,
6191 0x7, dmic_sample_rate_value);
6192 snd_soc_update_bits(codec, TAIKO_A_CDC_TX3_DMIC_CTL,
6193 0x7, dmic_sample_rate_value);
6194 snd_soc_update_bits(codec, TAIKO_A_CDC_TX4_DMIC_CTL,
6195 0x7, dmic_sample_rate_value);
6196 snd_soc_update_bits(codec, TAIKO_A_CDC_TX5_DMIC_CTL,
6197 0x7, dmic_sample_rate_value);
6198 snd_soc_update_bits(codec, TAIKO_A_CDC_TX6_DMIC_CTL,
6199 0x7, dmic_sample_rate_value);
6200 snd_soc_update_bits(codec, TAIKO_A_CDC_TX7_DMIC_CTL,
6201 0x7, dmic_sample_rate_value);
6202 snd_soc_update_bits(codec, TAIKO_A_CDC_TX8_DMIC_CTL,
6203 0x7, dmic_sample_rate_value);
6204 snd_soc_update_bits(codec, TAIKO_A_CDC_TX9_DMIC_CTL,
6205 0x7, dmic_sample_rate_value);
6206 snd_soc_update_bits(codec, TAIKO_A_CDC_TX10_DMIC_CTL,
6207 0x7, dmic_sample_rate_value);
6208 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_DMIC_B1_CTL,
6209 0xEE, dmic_b1_ctl_value);
6210 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_DMIC_B2_CTL,
6211 0xE, dmic_b2_ctl_value);
6212 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B2_CTL,
6213 0x1, anc_ctl_value);
6214
Kiran Kandic3b24402012-06-11 00:05:59 -07006215done:
6216 return rc;
6217}
6218
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006219static const struct wcd9xxx_reg_mask_val taiko_reg_defaults[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07006220
Kiran Kandi4c56c592012-07-25 11:04:55 -07006221 /* set MCLk to 9.6 */
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05006222 TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x02),
Kiran Kandi4c56c592012-07-25 11:04:55 -07006223 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_POWER_CTL, 0x03),
Kiran Kandic3b24402012-06-11 00:05:59 -07006224
Kiran Kandi4c56c592012-07-25 11:04:55 -07006225 /* EAR PA deafults */
6226 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CMBUFF, 0x05),
Kiran Kandic3b24402012-06-11 00:05:59 -07006227
Kiran Kandi4c56c592012-07-25 11:04:55 -07006228 /* RX deafults */
Kiran Kandic3b24402012-06-11 00:05:59 -07006229 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B5_CTL, 0x78),
6230 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B5_CTL, 0x78),
6231 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B5_CTL, 0x78),
6232 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B5_CTL, 0x78),
6233 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B5_CTL, 0x78),
6234 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B5_CTL, 0x78),
6235 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B5_CTL, 0x78),
6236
Kiran Kandi4c56c592012-07-25 11:04:55 -07006237 /* RX1 and RX2 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07006238 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B6_CTL, 0xA0),
6239 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B6_CTL, 0xA0),
6240
Kiran Kandi4c56c592012-07-25 11:04:55 -07006241 /* RX3 to RX7 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07006242 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B6_CTL, 0x80),
6243 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B6_CTL, 0x80),
6244 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B6_CTL, 0x80),
6245 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B6_CTL, 0x80),
6246 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006247
6248 /* MAD registers */
6249 TAIKO_REG_VAL(TAIKO_A_MAD_ANA_CTRL, 0xF1),
6250 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_MAIN_CTL_1, 0x00),
6251 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_MAIN_CTL_2, 0x00),
6252 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_1, 0x00),
6253 /* Set SAMPLE_TX_EN bit */
6254 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_2, 0x03),
6255 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_3, 0x00),
6256 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_4, 0x00),
6257 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_5, 0x00),
6258 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_6, 0x00),
6259 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_7, 0x00),
6260 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_8, 0x00),
6261 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_PTR, 0x00),
6262 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_VAL, 0x40),
6263 TAIKO_REG_VAL(TAIKO_A_CDC_DEBUG_B7_CTL, 0x00),
6264 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL, 0x00),
6265 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_CTL, 0x00),
6266 TAIKO_REG_VAL(TAIKO_A_CDC_CONN_MAD, 0x01),
Bhalchandra Gajareafdb1b12013-06-10 13:45:28 -07006267
6268 /* Set HPH Path to low power mode */
6269 TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x55),
Joonwoo Park58d4a162013-07-23 16:19:37 -07006270
6271 /* BUCK default */
6272 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x51),
6273 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
Kiran Kandic3b24402012-06-11 00:05:59 -07006274};
6275
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006276static const struct wcd9xxx_reg_mask_val taiko_1_0_reg_defaults[] = {
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006277 /*
6278 * The following only need to be written for Taiko 1.0 parts.
6279 * Taiko 2.0 will have appropriate defaults for these registers.
6280 */
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006281
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006282 /* Required defaults for class H operation */
6283 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xF4),
6284 TAIKO_REG_VAL(TAIKO_A_BIAS_CURR_CTL_2, 0x08),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006285 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_3, 0x60),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006286
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006287 /* Choose max non-overlap time for NCP */
6288 TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
6289 /* Use 25mV/50mV for deltap/m to reduce ripple */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006290 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x08),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006291 /*
6292 * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
6293 * Note that the other bits of this register will be changed during
6294 * Rx PA bring up.
6295 */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006296 TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006297 /*Reduce EAR DAC bias to 70% */
6298 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
6299 /* Reduce LINE DAC bias to 70% */
6300 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
Joonwoo Parkd87ec4c2012-10-30 15:44:18 -07006301
6302 /*
6303 * There is a diode to pull down the micbias while doing
6304 * insertion detection. This diode can cause leakage.
6305 * Set bit 0 to 1 to prevent leakage.
6306 * Setting this bit of micbias 2 prevents leakage for all other micbias.
6307 */
6308 TAIKO_REG_VAL(TAIKO_A_MICB_2_MBHC, 0x41),
Joonwoo Park3c7bca62012-10-31 12:44:23 -07006309
6310 /* Disable TX7 internal biasing path which can cause leakage */
6311 TAIKO_REG_VAL(TAIKO_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
Joonwoo Park03604052012-11-06 18:40:25 -08006312 /* Enable MICB 4 VDDIO switch to prevent leakage */
6313 TAIKO_REG_VAL(TAIKO_A_MICB_4_MBHC, 0x81),
Joonwoo Park125cd4e2012-12-11 15:16:11 -08006314
6315 /* Close leakage on the spkdrv */
6316 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_DBG_PWRSTG, 0x24),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006317};
6318
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006319/*
6320 * Don't update TAIKO_A_CHIP_CTL, TAIKO_A_BUCK_CTRL_CCL_1 and
6321 * TAIKO_A_RX_EAR_CMBUFF as those are updated in taiko_reg_defaults
6322 */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006323static const struct wcd9xxx_reg_mask_val taiko_2_0_reg_defaults[] = {
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006324 TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_GAIN, 0x2),
6325 TAIKO_REG_VAL(TAIKO_A_CDC_TX_2_GAIN, 0x2),
6326 TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_2_ADC_IB, 0x44),
6327 TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_GAIN, 0x2),
6328 TAIKO_REG_VAL(TAIKO_A_CDC_TX_4_GAIN, 0x2),
6329 TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_4_ADC_IB, 0x44),
6330 TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_GAIN, 0x2),
6331 TAIKO_REG_VAL(TAIKO_A_CDC_TX_6_GAIN, 0x2),
6332 TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_6_ADC_IB, 0x44),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006333 TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
6334 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x8),
Joonwoo Parkd535b8a2013-08-01 18:44:56 -07006335 TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_4, 0x51),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006336 TAIKO_REG_VAL(TAIKO_A_NCP_DTEST, 0x10),
6337 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xA4),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006338 TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x69),
6339 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_CTL, 0xDA),
6340 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_TIME, 0x15),
6341 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
6342 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CNP, 0xC0),
6343 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
6344 TAIKO_REG_VAL(TAIKO_A_RX_LINE_1_TEST, 0x2),
6345 TAIKO_REG_VAL(TAIKO_A_RX_LINE_2_TEST, 0x2),
6346 TAIKO_REG_VAL(TAIKO_A_RX_LINE_3_TEST, 0x2),
6347 TAIKO_REG_VAL(TAIKO_A_RX_LINE_4_TEST, 0x2),
6348 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_OCP_CTL, 0x97),
6349 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_CLIP_DET, 0x1),
6350 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_IEC, 0x0),
6351 TAIKO_REG_VAL(TAIKO_A_CDC_TX1_MUX_CTL, 0x48),
6352 TAIKO_REG_VAL(TAIKO_A_CDC_TX2_MUX_CTL, 0x48),
6353 TAIKO_REG_VAL(TAIKO_A_CDC_TX3_MUX_CTL, 0x48),
6354 TAIKO_REG_VAL(TAIKO_A_CDC_TX4_MUX_CTL, 0x48),
6355 TAIKO_REG_VAL(TAIKO_A_CDC_TX5_MUX_CTL, 0x48),
6356 TAIKO_REG_VAL(TAIKO_A_CDC_TX6_MUX_CTL, 0x48),
6357 TAIKO_REG_VAL(TAIKO_A_CDC_TX7_MUX_CTL, 0x48),
6358 TAIKO_REG_VAL(TAIKO_A_CDC_TX8_MUX_CTL, 0x48),
6359 TAIKO_REG_VAL(TAIKO_A_CDC_TX9_MUX_CTL, 0x48),
6360 TAIKO_REG_VAL(TAIKO_A_CDC_TX10_MUX_CTL, 0x48),
6361 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B4_CTL, 0x8),
Joonwoo Parkdbbdac02013-03-21 19:24:31 -07006362 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B4_CTL, 0x8),
6363 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B4_CTL, 0x8),
6364 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B4_CTL, 0x8),
6365 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B4_CTL, 0x8),
6366 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B4_CTL, 0x8),
6367 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B4_CTL, 0x8),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006368 TAIKO_REG_VAL(TAIKO_A_CDC_VBAT_GAIN_UPD_MON, 0x0),
6369 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B1_CTL, 0x0),
6370 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B2_CTL, 0x0),
6371 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B3_CTL, 0x0),
6372 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B4_CTL, 0x0),
6373 TAIKO_REG_VAL(TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL, 0x0),
6374 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B4_CTL, 0x37),
6375 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
Joonwoo Park58d4a162013-07-23 16:19:37 -07006376 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006377};
6378
Kiran Kandic3b24402012-06-11 00:05:59 -07006379static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
6380{
6381 u32 i;
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006382 struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07006383
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006384 for (i = 0; i < ARRAY_SIZE(taiko_reg_defaults); i++)
6385 snd_soc_write(codec, taiko_reg_defaults[i].reg,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006386 taiko_reg_defaults[i].val);
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006387
6388 if (TAIKO_IS_1_0(taiko_core->version)) {
6389 for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
6390 snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006391 taiko_1_0_reg_defaults[i].val);
6392 if (spkr_drv_wrnd == 1)
6393 snd_soc_write(codec, TAIKO_A_SPKR_DRV_EN, 0xEF);
6394 } else {
6395 for (i = 0; i < ARRAY_SIZE(taiko_2_0_reg_defaults); i++)
6396 snd_soc_write(codec, taiko_2_0_reg_defaults[i].reg,
6397 taiko_2_0_reg_defaults[i].val);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08006398 spkr_drv_wrnd = -1;
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006399 }
Kiran Kandic3b24402012-06-11 00:05:59 -07006400}
6401
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08006402static const struct wcd9xxx_reg_mask_val taiko_codec_reg_init_val[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07006403 /* Initialize current threshold to 350MA
6404 * number of wait and run cycles to 4096
6405 */
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006406 {TAIKO_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
Kiran Kandic3b24402012-06-11 00:05:59 -07006407 {TAIKO_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
Patrick Lai92833bf2012-12-01 10:31:35 -08006408 {TAIKO_A_RX_HPH_L_TEST, 0x01, 0x01},
6409 {TAIKO_A_RX_HPH_R_TEST, 0x01, 0x01},
Kiran Kandic3b24402012-06-11 00:05:59 -07006410
Kiran Kandic3b24402012-06-11 00:05:59 -07006411 /* Initialize gain registers to use register gain */
Kiran Kandi4c56c592012-07-25 11:04:55 -07006412 {TAIKO_A_RX_HPH_L_GAIN, 0x20, 0x20},
6413 {TAIKO_A_RX_HPH_R_GAIN, 0x20, 0x20},
6414 {TAIKO_A_RX_LINE_1_GAIN, 0x20, 0x20},
6415 {TAIKO_A_RX_LINE_2_GAIN, 0x20, 0x20},
6416 {TAIKO_A_RX_LINE_3_GAIN, 0x20, 0x20},
6417 {TAIKO_A_RX_LINE_4_GAIN, 0x20, 0x20},
Joonwoo Parkc7731432012-10-17 12:41:44 -07006418 {TAIKO_A_SPKR_DRV_GAIN, 0x04, 0x04},
Kiran Kandic3b24402012-06-11 00:05:59 -07006419
Kiran Kandic3b24402012-06-11 00:05:59 -07006420 /* Use 16 bit sample size for TX1 to TX6 */
6421 {TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0x30, 0x20},
6422 {TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0x30, 0x20},
6423 {TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0x30, 0x20},
6424 {TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0x30, 0x20},
6425 {TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0x30, 0x20},
6426 {TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0x30, 0x20},
6427
6428 /* Use 16 bit sample size for TX7 to TX10 */
6429 {TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0x60, 0x40},
6430 {TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0x60, 0x40},
6431 {TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x60, 0x40},
6432 {TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x60, 0x40},
6433
Kiran Kandic3b24402012-06-11 00:05:59 -07006434 /*enable HPF filter for TX paths */
6435 {TAIKO_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
6436 {TAIKO_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
6437 {TAIKO_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
6438 {TAIKO_A_CDC_TX4_MUX_CTL, 0x8, 0x0},
6439 {TAIKO_A_CDC_TX5_MUX_CTL, 0x8, 0x0},
6440 {TAIKO_A_CDC_TX6_MUX_CTL, 0x8, 0x0},
6441 {TAIKO_A_CDC_TX7_MUX_CTL, 0x8, 0x0},
6442 {TAIKO_A_CDC_TX8_MUX_CTL, 0x8, 0x0},
6443 {TAIKO_A_CDC_TX9_MUX_CTL, 0x8, 0x0},
6444 {TAIKO_A_CDC_TX10_MUX_CTL, 0x8, 0x0},
6445
Joonwoo Parkc7731432012-10-17 12:41:44 -07006446 /* Compander zone selection */
6447 {TAIKO_A_CDC_COMP0_B4_CTL, 0x3F, 0x37},
6448 {TAIKO_A_CDC_COMP1_B4_CTL, 0x3F, 0x37},
6449 {TAIKO_A_CDC_COMP2_B4_CTL, 0x3F, 0x37},
6450 {TAIKO_A_CDC_COMP0_B5_CTL, 0x7F, 0x7F},
6451 {TAIKO_A_CDC_COMP1_B5_CTL, 0x7F, 0x7F},
6452 {TAIKO_A_CDC_COMP2_B5_CTL, 0x7F, 0x7F},
Bhalchandra Gajareef7810e2013-03-29 16:50:37 -07006453
6454 /*
6455 * Setup wavegen timer to 20msec and disable chopper
6456 * as default. This corresponds to Compander OFF
6457 */
6458 {TAIKO_A_RX_HPH_CNP_WG_CTL, 0xFF, 0xDB},
6459 {TAIKO_A_RX_HPH_CNP_WG_TIME, 0xFF, 0x58},
6460 {TAIKO_A_RX_HPH_BIAS_WG_OCP, 0xFF, 0x1A},
6461 {TAIKO_A_RX_HPH_CHOP_CTL, 0xFF, 0x24},
Bhalchandra Gajare9581aed2013-03-29 17:06:10 -07006462
6463 /* Choose max non-overlap time for NCP */
6464 {TAIKO_A_NCP_CLK, 0xFF, 0xFC},
6465
6466 /* Program the 0.85 volt VBG_REFERENCE */
6467 {TAIKO_A_BIAS_CURR_CTL_2, 0xFF, 0x04},
Kiran Kandiddbeaa32013-10-06 14:40:11 -07006468
6469 /* set MAD input MIC to DMIC1 */
6470 {TAIKO_A_CDC_CONN_MAD, 0x0F, 0x08},
Kiran Kandic3b24402012-06-11 00:05:59 -07006471};
6472
6473static void taiko_codec_init_reg(struct snd_soc_codec *codec)
6474{
6475 u32 i;
6476
6477 for (i = 0; i < ARRAY_SIZE(taiko_codec_reg_init_val); i++)
6478 snd_soc_update_bits(codec, taiko_codec_reg_init_val[i].reg,
6479 taiko_codec_reg_init_val[i].mask,
6480 taiko_codec_reg_init_val[i].val);
6481}
6482
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006483static void taiko_slim_interface_init_reg(struct snd_soc_codec *codec)
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006484{
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006485 int i;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006486
6487 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
6488 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Parka8890262012-10-15 12:04:27 -07006489 TAIKO_SLIM_PGD_PORT_INT_EN0 + i,
6490 0xFF);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006491}
6492
6493static int taiko_setup_irqs(struct taiko_priv *taiko)
6494{
6495 int ret = 0;
6496 struct snd_soc_codec *codec = taiko->codec;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006497 struct wcd9xxx *wcd9xxx = codec->control_data;
6498 struct wcd9xxx_core_resource *core_res =
6499 &wcd9xxx->core_res;
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006500
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006501 ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS,
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006502 taiko_slimbus_irq, "SLIMBUS Slave", taiko);
6503 if (ret)
6504 pr_err("%s: Failed to request irq %d\n", __func__,
6505 WCD9XXX_IRQ_SLIMBUS);
6506 else
6507 taiko_slim_interface_init_reg(codec);
6508
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006509 return ret;
6510}
6511
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006512static void taiko_cleanup_irqs(struct taiko_priv *taiko)
6513{
6514 struct snd_soc_codec *codec = taiko->codec;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006515 struct wcd9xxx *wcd9xxx = codec->control_data;
6516 struct wcd9xxx_core_resource *core_res =
6517 &wcd9xxx->core_res;
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006518
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006519 wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, taiko);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006520}
6521
Joonwoo Parka8890262012-10-15 12:04:27 -07006522int taiko_hs_detect(struct snd_soc_codec *codec,
6523 struct wcd9xxx_mbhc_config *mbhc_cfg)
6524{
Joonwoo Park88bfa842013-04-15 16:59:21 -07006525 int rc;
Joonwoo Parka8890262012-10-15 12:04:27 -07006526 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Park88bfa842013-04-15 16:59:21 -07006527 rc = wcd9xxx_mbhc_start(&taiko->mbhc, mbhc_cfg);
6528 if (!rc)
6529 taiko->mbhc_started = true;
6530 return rc;
Joonwoo Parka8890262012-10-15 12:04:27 -07006531}
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006532EXPORT_SYMBOL(taiko_hs_detect);
Joonwoo Parka8890262012-10-15 12:04:27 -07006533
Joonwoo Parke7d724e2013-08-19 15:51:01 -07006534void taiko_hs_detect_exit(struct snd_soc_codec *codec)
6535{
6536 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
6537 wcd9xxx_mbhc_stop(&taiko->mbhc);
6538 taiko->mbhc_started = false;
6539}
6540EXPORT_SYMBOL(taiko_hs_detect_exit);
6541
Kiran Kandia1bed422013-05-28 18:29:12 -07006542void taiko_event_register(
6543 int (*machine_event_cb)(struct snd_soc_codec *codec,
6544 enum wcd9xxx_codec_event),
6545 struct snd_soc_codec *codec)
6546{
6547 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
6548 taiko->machine_codec_event_cb = machine_event_cb;
6549}
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006550EXPORT_SYMBOL(taiko_event_register);
Kiran Kandia1bed422013-05-28 18:29:12 -07006551
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006552static void taiko_init_slim_slave_cfg(struct snd_soc_codec *codec)
6553{
6554 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
6555 struct afe_param_cdc_slimbus_slave_cfg *cfg;
6556 struct wcd9xxx *wcd9xxx = codec->control_data;
6557 uint64_t eaddr = 0;
6558
6559 cfg = &priv->slimbus_slave_cfg;
6560 cfg->minor_version = 1;
6561 cfg->tx_slave_port_offset = 0;
6562 cfg->rx_slave_port_offset = 16;
6563
6564 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
6565 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
6566 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
6567 cfg->device_enum_addr_msw = eaddr >> 32;
6568
6569 pr_debug("%s: slimbus logical address 0x%llx\n", __func__, eaddr);
6570}
6571
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006572static int taiko_device_down(struct wcd9xxx *wcd9xxx)
6573{
6574 struct snd_soc_codec *codec;
6575
6576 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
6577 snd_soc_card_change_online_state(codec->card, 0);
6578
6579 return 0;
6580}
6581
Phani Kumar Uppalapati01a77e12013-08-08 15:31:35 -07006582static int wcd9xxx_prepare_static_pa(struct wcd9xxx_mbhc *mbhc,
6583 struct list_head *lh)
6584{
6585 int i;
6586 struct snd_soc_codec *codec = mbhc->codec;
6587
6588 const struct wcd9xxx_reg_mask_val reg_set_paon[] = {
6589 {WCD9XXX_A_RX_HPH_OCP_CTL, 0x18, 0x00},
6590 {WCD9XXX_A_RX_HPH_L_TEST, 0x1, 0x0},
6591 {WCD9XXX_A_RX_HPH_R_TEST, 0x1, 0x0},
6592 {WCD9XXX_A_RX_HPH_BIAS_WG_OCP, 0xff, 0x1A},
6593 {WCD9XXX_A_RX_HPH_CNP_WG_CTL, 0xff, 0xDB},
6594 {WCD9XXX_A_RX_HPH_CNP_WG_TIME, 0xff, 0x15},
6595 {WCD9XXX_A_CDC_RX1_B6_CTL, 0xff, 0x81},
6596 {WCD9XXX_A_CDC_CLK_RX_B1_CTL, 0x01, 0x01},
6597 {WCD9XXX_A_RX_HPH_CHOP_CTL, 0xff, 0xA4},
6598 {WCD9XXX_A_RX_HPH_L_GAIN, 0xff, 0x2C},
6599 {WCD9XXX_A_CDC_RX2_B6_CTL, 0xff, 0x81},
6600 {WCD9XXX_A_CDC_CLK_RX_B1_CTL, 0x02, 0x02},
6601 {WCD9XXX_A_RX_HPH_R_GAIN, 0xff, 0x2C},
6602 {WCD9XXX_A_NCP_CLK, 0xff, 0xFC},
6603 {WCD9XXX_A_BUCK_CTRL_CCL_3, 0xff, 0x60},
6604 {WCD9XXX_A_RX_COM_BIAS, 0xff, 0x80},
6605 {WCD9XXX_A_BUCK_MODE_3, 0xff, 0xC6},
6606 {WCD9XXX_A_BUCK_MODE_4, 0xff, 0xE6},
6607 {WCD9XXX_A_BUCK_MODE_5, 0xff, 0x02},
6608 {WCD9XXX_A_BUCK_MODE_1, 0xff, 0xA1},
6609 {WCD9XXX_A_NCP_EN, 0xff, 0xFF},
6610 {WCD9XXX_A_BUCK_MODE_5, 0xff, 0x7B},
6611 {WCD9XXX_A_CDC_CLSH_B1_CTL, 0xff, 0xE6},
6612 {WCD9XXX_A_RX_HPH_L_DAC_CTL, 0xff, 0xC0},
6613 {WCD9XXX_A_RX_HPH_R_DAC_CTL, 0xff, 0xC0},
6614 };
6615
6616 for (i = 0; i < ARRAY_SIZE(reg_set_paon); i++)
6617 wcd9xxx_soc_update_bits_push(codec, lh,
6618 reg_set_paon[i].reg,
6619 reg_set_paon[i].mask,
6620 reg_set_paon[i].val, 0);
6621 pr_debug("%s: PAs are prepared\n", __func__);
6622
6623 return 0;
6624}
6625
6626static int wcd9xxx_enable_static_pa(struct wcd9xxx_mbhc *mbhc, bool enable)
6627{
6628 struct snd_soc_codec *codec = mbhc->codec;
6629 const int wg_time = snd_soc_read(codec, WCD9XXX_A_RX_HPH_CNP_WG_TIME) *
6630 TAIKO_WG_TIME_FACTOR_US;
6631
6632 snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_CNP_EN, 0x30,
6633 enable ? 0x30 : 0x0);
6634 /* Wait for wave gen time to avoid pop noise */
6635 usleep_range(wg_time, wg_time + WCD9XXX_USLEEP_RANGE_MARGIN_US);
6636 pr_debug("%s: PAs are %s as static mode (wg_time %d)\n", __func__,
6637 enable ? "enabled" : "disabled", wg_time);
6638 return 0;
6639}
6640
6641static int taiko_setup_zdet(struct wcd9xxx_mbhc *mbhc,
6642 enum mbhc_impedance_detect_stages stage)
6643{
6644 int ret = 0;
6645 struct snd_soc_codec *codec = mbhc->codec;
6646 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
6647 const int ramp_wait_us = 18 * 1000;
6648
6649#define __wr(reg, mask, value) \
6650 do { \
6651 ret = wcd9xxx_soc_update_bits_push(codec, \
6652 &taiko->reg_save_restore, \
6653 reg, mask, value, 0); \
6654 if (ret < 0) \
6655 return ret; \
6656 } while (0)
6657
6658 switch (stage) {
6659
6660 case PRE_MEAS:
6661 INIT_LIST_HEAD(&taiko->reg_save_restore);
6662 wcd9xxx_prepare_static_pa(mbhc, &taiko->reg_save_restore);
6663 wcd9xxx_enable_static_pa(mbhc, true);
6664
6665 /*
6666 * save old value of registers and write the new value to
6667 * restore old value back, WCD9XXX_A_CDC_PA_RAMP_B{1,2,3,4}_CTL
6668 * registers don't need to be restored as those are solely used
6669 * by impedance detection.
6670 */
6671 /* Phase 1 */
6672 /* Reset the PA Ramp */
6673 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x1C);
6674 /*
6675 * Connect the PA Ramp to PA chain and release reset with
6676 * keep it connected.
6677 */
6678 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x1F);
6679 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x03);
6680 /*
6681 * Program the PA Ramp to FS_48K, L shift 1 and sample
6682 * num to 24
6683 */
6684 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B3_CTL,
6685 0x3 << 4 | 0x6);
6686 /* 0x56 for 10mv. 0xC0 is for 50mv */
6687 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B4_CTL, 0xC0);
6688 /* Enable MBHC MUX, Set MUX current to 37.5uA and ADC7 */
6689 __wr(WCD9XXX_A_MBHC_SCALING_MUX_1, 0xFF, 0xC0);
6690 __wr(WCD9XXX_A_MBHC_SCALING_MUX_2, 0xFF, 0xF0);
6691 __wr(WCD9XXX_A_TX_7_MBHC_TEST_CTL, 0xFF, 0x78);
6692 __wr(WCD9XXX_A_TX_7_MBHC_EN, 0xFF, 0x8C);
6693 /* Change NSA and NAVG */
6694 __wr(WCD9XXX_A_CDC_MBHC_TIMER_B4_CTL, 0x4 << 4, 0x4 << 4);
6695 __wr(WCD9XXX_A_CDC_MBHC_TIMER_B5_CTL, 0xFF, 0x10);
6696 /* Reset MBHC and set it up for STA */
6697 __wr(WCD9XXX_A_CDC_MBHC_CLK_CTL, 0xFF, 0x0A);
Phani Kumar Uppalapatib7266bd2013-10-21 14:26:10 -07006698 snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x2);
Phani Kumar Uppalapati01a77e12013-08-08 15:31:35 -07006699 __wr(WCD9XXX_A_CDC_MBHC_CLK_CTL, 0xFF, 0x02);
6700
6701 /* Set HPH_MBHC for zdet */
6702 __wr(WCD9XXX_A_MBHC_HPH, 0xB3, 0x80);
6703 break;
6704 case POST_MEAS:
6705 /* Phase 2 */
6706 /* Start the PA ramp on HPH L and R */
6707 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B2_CTL, 0x05);
6708 /* Ramp generator takes ~17ms */
6709 usleep_range(ramp_wait_us,
6710 ramp_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
6711
6712 /* Disable Ical */
6713 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B2_CTL, 0x00);
6714 /* Ramp generator takes ~17ms */
6715 usleep_range(ramp_wait_us,
6716 ramp_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
6717 break;
6718 case PA_DISABLE:
6719 /* Ramp HPH L & R back to Zero */
6720 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B2_CTL, 0x0A);
6721 /* Ramp generator takes ~17ms */
6722 usleep_range(ramp_wait_us,
6723 ramp_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
6724 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B2_CTL, 0x00);
6725
6726 /* Clean up starts */
6727 /* Turn off PA ramp generator */
6728 snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x0);
Sudheer Papothi3fb420b2013-12-05 05:30:15 +05306729 if (!mbhc->hph_pa_dac_state)
6730 wcd9xxx_enable_static_pa(mbhc, false);
Phani Kumar Uppalapati01a77e12013-08-08 15:31:35 -07006731 wcd9xxx_restore_registers(codec, &taiko->reg_save_restore);
6732 break;
6733 }
6734#undef __wr
6735
6736 return ret;
6737}
6738
6739static void taiko_compute_impedance(s16 *l, s16 *r, uint32_t *zl, uint32_t *zr)
6740{
6741
6742 int64_t rl, rr = 0; /* milliohm */
6743 const int alphal = 364; /* 0.005555 * 65536 = 364.05 */
6744 const int alphar = 364; /* 0.005555 * 65536 = 364.05 */
6745 const int beta = 3855; /* 0.011765 * 5 * 65536 = 3855.15 */
6746 const int rref = 11333; /* not scaled up */
6747 const int shift = 16;
6748
6749 rl = (int)(l[0] - l[1]) * 1000 / (l[0] - l[2]);
6750 rl = rl * rref * alphal;
6751 rl = rl >> shift;
6752 rl = rl * beta;
6753 rl = rl >> shift;
6754 *zl = rl;
6755
6756 rr = (int)(r[0] - r[1]) * 1000 / (r[0] - r[2]);
6757 rr = rr * rref * alphar;
6758 rr = rr >> shift;
6759 rr = rr * beta;
6760 rr = rr >> shift;
6761 *zr = rr;
6762}
6763
6764static enum wcd9xxx_cdc_type taiko_get_cdc_type(void)
6765{
6766 return WCD9XXX_CDC_TYPE_TAIKO;
6767}
6768
6769static const struct wcd9xxx_mbhc_cb mbhc_cb = {
6770 .get_cdc_type = taiko_get_cdc_type,
6771 .setup_zdet = taiko_setup_zdet,
6772 .compute_impedance = taiko_compute_impedance,
6773};
6774
Bhalchandra Gajare16748932013-10-01 18:16:05 -07006775static const struct wcd9xxx_mbhc_intr cdc_intr_ids = {
6776 .poll_plug_rem = WCD9XXX_IRQ_MBHC_REMOVAL,
6777 .shortavg_complete = WCD9XXX_IRQ_MBHC_SHORT_TERM,
6778 .potential_button_press = WCD9XXX_IRQ_MBHC_PRESS,
6779 .button_release = WCD9XXX_IRQ_MBHC_RELEASE,
6780 .dce_est_complete = WCD9XXX_IRQ_MBHC_POTENTIAL,
6781 .insertion = WCD9XXX_IRQ_MBHC_INSERTION,
6782 .hph_left_ocp = WCD9XXX_IRQ_HPH_PA_OCPL_FAULT,
6783 .hph_right_ocp = WCD9XXX_IRQ_HPH_PA_OCPR_FAULT,
6784 .hs_jack_switch = WCD9320_IRQ_MBHC_JACK_SWITCH,
6785};
6786
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006787static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
6788{
6789 int ret = 0;
6790 struct snd_soc_codec *codec;
6791 struct taiko_priv *taiko;
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07006792 int rco_clk_rate;
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006793
6794 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
6795 taiko = snd_soc_codec_get_drvdata(codec);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006796
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006797 snd_soc_card_change_online_state(codec->card, 1);
6798
6799 mutex_lock(&codec->mutex);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006800 if (codec->reg_def_copy) {
6801 pr_debug("%s: Update ASOC cache", __func__);
6802 kfree(codec->reg_cache);
6803 codec->reg_cache = kmemdup(codec->reg_def_copy,
6804 codec->reg_size, GFP_KERNEL);
6805 }
6806
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08006807 if (spkr_drv_wrnd == 1)
6808 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08006809
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006810 taiko_update_reg_defaults(codec);
6811 taiko_codec_init_reg(codec);
6812 ret = taiko_handle_pdata(taiko);
6813 if (IS_ERR_VALUE(ret))
6814 pr_err("%s: bad pdata\n", __func__);
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08006815
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006816 taiko_init_slim_slave_cfg(codec);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07006817 taiko_slim_interface_init_reg(codec);
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006818
Joonwoo Park865bcf02013-07-15 14:05:32 -07006819 wcd9xxx_resmgr_post_ssr(&taiko->resmgr);
6820
Joonwoo Park88bfa842013-04-15 16:59:21 -07006821 if (taiko->mbhc_started) {
6822 wcd9xxx_mbhc_deinit(&taiko->mbhc);
6823 taiko->mbhc_started = false;
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07006824
6825 if (TAIKO_IS_1_0(wcd9xxx->version))
6826 rco_clk_rate = TAIKO_MCLK_CLK_12P288MHZ;
6827 else
6828 rco_clk_rate = TAIKO_MCLK_CLK_9P6MHZ;
6829
Joonwoo Park88bfa842013-04-15 16:59:21 -07006830 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
Joonwoo Parkccccba72013-04-26 11:19:46 -07006831 taiko_enable_mbhc_micbias,
Bhalchandra Gajare16748932013-10-01 18:16:05 -07006832 &mbhc_cb, &cdc_intr_ids,
6833 rco_clk_rate, true);
Joonwoo Parke7d724e2013-08-19 15:51:01 -07006834 if (ret)
Joonwoo Park88bfa842013-04-15 16:59:21 -07006835 pr_err("%s: mbhc init failed %d\n", __func__, ret);
Joonwoo Parke7d724e2013-08-19 15:51:01 -07006836 else
6837 taiko_hs_detect(codec, taiko->mbhc.mbhc_cfg);
Joonwoo Park88bfa842013-04-15 16:59:21 -07006838 }
Kiran Kandia1bed422013-05-28 18:29:12 -07006839 taiko->machine_codec_event_cb(codec, WCD9XXX_CODEC_EVENT_CODEC_UP);
6840
Joonwoo Parkc98049a2013-07-30 16:43:34 -07006841 taiko_cleanup_irqs(taiko);
6842 ret = taiko_setup_irqs(taiko);
6843 if (ret)
6844 pr_err("%s: Failed to setup irq: %d\n", __func__, ret);
6845
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006846 mutex_unlock(&codec->mutex);
6847 return ret;
6848}
6849
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006850void *taiko_get_afe_config(struct snd_soc_codec *codec,
6851 enum afe_config_type config_type)
6852{
6853 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -04006854 struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006855
6856 switch (config_type) {
6857 case AFE_SLIMBUS_SLAVE_CONFIG:
6858 return &priv->slimbus_slave_cfg;
6859 case AFE_CDC_REGISTERS_CONFIG:
Damir Didjustodcfdff82013-03-21 23:26:41 -07006860 return &taiko_audio_reg_cfg;
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006861 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
6862 return &taiko_slimbus_slave_port_cfg;
Damir Didjustodcfdff82013-03-21 23:26:41 -07006863 case AFE_AANC_VERSION:
6864 return &taiko_cdc_aanc_version;
Gopikrishnaiah Anandaneb51dd72013-04-09 11:39:55 -04006865 case AFE_CLIP_BANK_SEL:
6866 if (!TAIKO_IS_1_0(taiko_core->version))
6867 return &clip_bank_sel;
6868 else
6869 return NULL;
6870 case AFE_CDC_CLIP_REGISTERS_CONFIG:
6871 if (!TAIKO_IS_1_0(taiko_core->version))
6872 return &taiko_clip_reg_cfg;
6873 else
6874 return NULL;
Joonwoo Park1d05bb92013-03-07 16:55:06 -08006875 default:
6876 pr_err("%s: Unknown config_type 0x%x\n", __func__, config_type);
6877 return NULL;
6878 }
6879}
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006880
Joonwoo Parka8890262012-10-15 12:04:27 -07006881static struct wcd9xxx_reg_address taiko_reg_address = {
6882 .micb_4_mbhc = TAIKO_A_MICB_4_MBHC,
6883 .micb_4_int_rbias = TAIKO_A_MICB_4_INT_RBIAS,
6884 .micb_4_ctl = TAIKO_A_MICB_4_CTL,
6885};
6886
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006887static int wcd9xxx_ssr_register(struct wcd9xxx *control,
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006888 int (*device_down_cb)(struct wcd9xxx *wcd9xxx),
6889 int (*device_up_cb)(struct wcd9xxx *wcd9xxx),
6890 void *priv)
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006891{
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006892 control->dev_down = device_down_cb;
6893 control->post_reset = device_up_cb;
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006894 control->ssr_priv = priv;
6895 return 0;
6896}
6897
Joonwoo Park2a9170a2013-03-04 17:05:57 -08006898static const struct snd_soc_dapm_widget taiko_1_dapm_widgets[] = {
6899 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_TX_1_2_EN, 7, 0,
6900 taiko_codec_enable_adc,
6901 SND_SOC_DAPM_PRE_PMU |
6902 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
6903 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_TX_1_2_EN, 3, 0,
6904 taiko_codec_enable_adc,
6905 SND_SOC_DAPM_PRE_PMU |
6906 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
6907 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_TX_3_4_EN, 7, 0,
6908 taiko_codec_enable_adc,
6909 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
6910 SND_SOC_DAPM_POST_PMD),
6911 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_TX_3_4_EN, 3, 0,
6912 taiko_codec_enable_adc,
6913 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
6914 SND_SOC_DAPM_POST_PMD),
6915 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_TX_5_6_EN, 7, 0,
6916 taiko_codec_enable_adc,
6917 SND_SOC_DAPM_POST_PMU),
6918 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_TX_5_6_EN, 3, 0,
6919 taiko_codec_enable_adc,
6920 SND_SOC_DAPM_POST_PMU),
6921};
6922
6923static const struct snd_soc_dapm_widget taiko_2_dapm_widgets[] = {
6924 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_CDC_TX_1_GAIN, 7, 0,
6925 taiko_codec_enable_adc,
6926 SND_SOC_DAPM_PRE_PMU |
6927 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
6928 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_CDC_TX_2_GAIN, 7, 0,
6929 taiko_codec_enable_adc,
6930 SND_SOC_DAPM_PRE_PMU |
6931 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
6932 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_CDC_TX_3_GAIN, 7, 0,
6933 taiko_codec_enable_adc,
6934 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
6935 SND_SOC_DAPM_POST_PMD),
6936 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_CDC_TX_4_GAIN, 7, 0,
6937 taiko_codec_enable_adc,
6938 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
6939 SND_SOC_DAPM_POST_PMD),
6940 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_CDC_TX_5_GAIN, 7, 0,
6941 taiko_codec_enable_adc,
6942 SND_SOC_DAPM_POST_PMU),
6943 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_CDC_TX_6_GAIN, 7, 0,
6944 taiko_codec_enable_adc,
6945 SND_SOC_DAPM_POST_PMU),
6946};
6947
Joonwoo Park448a8fc2013-04-10 15:25:58 -07006948static struct regulator *taiko_codec_find_regulator(struct snd_soc_codec *codec,
6949 const char *name)
6950{
6951 int i;
6952 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
6953
6954 for (i = 0; i < core->num_of_supplies; i++) {
6955 if (core->supplies[i].supply &&
6956 !strcmp(core->supplies[i].supply, name))
6957 return core->supplies[i].consumer;
6958 }
6959
6960 return NULL;
6961}
6962
Kiran Kandic3b24402012-06-11 00:05:59 -07006963static int taiko_codec_probe(struct snd_soc_codec *codec)
6964{
6965 struct wcd9xxx *control;
6966 struct taiko_priv *taiko;
Joonwoo Parka8890262012-10-15 12:04:27 -07006967 struct wcd9xxx_pdata *pdata;
6968 struct wcd9xxx *wcd9xxx;
Kiran Kandic3b24402012-06-11 00:05:59 -07006969 struct snd_soc_dapm_context *dapm = &codec->dapm;
6970 int ret = 0;
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07006971 int i, rco_clk_rate;
Kuirong Wang906ac472012-07-09 12:54:44 -07006972 void *ptr = NULL;
Joonwoo Park559a5bf2013-02-15 14:46:36 -08006973 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07006974 struct wcd9xxx_core_resource *core_res;
Kiran Kandic3b24402012-06-11 00:05:59 -07006975
6976 codec->control_data = dev_get_drvdata(codec->dev->parent);
6977 control = codec->control_data;
6978
Joonwoo Park8ffa2812013-08-07 19:01:30 -07006979 wcd9xxx_ssr_register(control, taiko_device_down,
6980 taiko_post_reset_cb, (void *)codec);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08006981
Kiran Kandi4c56c592012-07-25 11:04:55 -07006982 dev_info(codec->dev, "%s()\n", __func__);
6983
Kiran Kandic3b24402012-06-11 00:05:59 -07006984 taiko = kzalloc(sizeof(struct taiko_priv), GFP_KERNEL);
6985 if (!taiko) {
6986 dev_err(codec->dev, "Failed to allocate private data\n");
6987 return -ENOMEM;
6988 }
6989 for (i = 0 ; i < NUM_DECIMATORS; i++) {
6990 tx_hpf_work[i].taiko = taiko;
6991 tx_hpf_work[i].decimator = i + 1;
6992 INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
6993 tx_hpf_corner_freq_callback);
6994 }
6995
Kiran Kandic3b24402012-06-11 00:05:59 -07006996 snd_soc_codec_set_drvdata(codec, taiko);
6997
Joonwoo Parka8890262012-10-15 12:04:27 -07006998 /* codec resmgr module init */
6999 wcd9xxx = codec->control_data;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07007000 core_res = &wcd9xxx->core_res;
Joonwoo Parka8890262012-10-15 12:04:27 -07007001 pdata = dev_get_platdata(codec->dev->parent);
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -07007002 ret = wcd9xxx_resmgr_init(&taiko->resmgr, codec, core_res, pdata,
Bhalchandra Gajare9943aa62013-10-09 18:40:11 -07007003 &pdata->micbias, &taiko_reg_address,
7004 WCD9XXX_CDC_TYPE_TAIKO);
Joonwoo Parka8890262012-10-15 12:04:27 -07007005 if (ret) {
7006 pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007007 goto err_init;
Joonwoo Parka8890262012-10-15 12:04:27 -07007008 }
7009
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08007010 taiko->clsh_d.buck_mv = taiko_codec_get_buck_mv(codec);
Bhalchandra Gajare7c739522013-06-20 15:31:02 -07007011 /* Taiko does not support dynamic switching of vdd_cp */
7012 taiko->clsh_d.is_dynamic_vdd_cp = false;
Joonwoo Parka08e0552013-03-05 18:28:23 -08007013 wcd9xxx_clsh_init(&taiko->clsh_d, &taiko->resmgr);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08007014
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07007015 if (TAIKO_IS_1_0(core->version))
7016 rco_clk_rate = TAIKO_MCLK_CLK_12P288MHZ;
7017 else
7018 rco_clk_rate = TAIKO_MCLK_CLK_9P6MHZ;
7019
Joonwoo Parka8890262012-10-15 12:04:27 -07007020 /* init and start mbhc */
Simmi Pateriya0a44d842013-04-03 01:12:42 +05307021 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
Joonwoo Parkccccba72013-04-26 11:19:46 -07007022 taiko_enable_mbhc_micbias,
Bhalchandra Gajare16748932013-10-01 18:16:05 -07007023 &mbhc_cb, &cdc_intr_ids,
7024 rco_clk_rate, true);
Joonwoo Parka8890262012-10-15 12:04:27 -07007025 if (ret) {
7026 pr_err("%s: mbhc 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
Kiran Kandic3b24402012-06-11 00:05:59 -07007030 taiko->codec = codec;
Kiran Kandic3b24402012-06-11 00:05:59 -07007031 for (i = 0; i < COMPANDER_MAX; i++) {
7032 taiko->comp_enabled[i] = 0;
7033 taiko->comp_fs[i] = COMPANDER_FS_48KHZ;
7034 }
Kiran Kandic3b24402012-06-11 00:05:59 -07007035 taiko->intf_type = wcd9xxx_get_intf_type();
7036 taiko->aux_pga_cnt = 0;
7037 taiko->aux_l_gain = 0x1F;
7038 taiko->aux_r_gain = 0x1F;
Joonwoo Parkccccba72013-04-26 11:19:46 -07007039 taiko->ldo_h_users = 0;
7040 taiko->micb_2_users = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07007041 taiko_update_reg_defaults(codec);
Venkat Sudhira50a3762012-11-26 12:12:15 -08007042 pr_debug("%s: MCLK Rate = %x\n", __func__, wcd9xxx->mclk_rate);
7043 if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ)
Venkat Sudhir16d95e62013-02-04 16:57:33 -08007044 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x0);
Phani Kumar Uppalapati43bc4152013-05-24 00:44:20 -07007045 else if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_9P6MHZ)
Venkat Sudhir16d95e62013-02-04 16:57:33 -08007046 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x2);
Kiran Kandic3b24402012-06-11 00:05:59 -07007047 taiko_codec_init_reg(codec);
7048 ret = taiko_handle_pdata(taiko);
7049 if (IS_ERR_VALUE(ret)) {
7050 pr_err("%s: bad pdata\n", __func__);
7051 goto err_pdata;
7052 }
7053
Joonwoo Park448a8fc2013-04-10 15:25:58 -07007054 taiko->spkdrv_reg = taiko_codec_find_regulator(codec,
7055 WCD9XXX_VDD_SPKDRV_NAME);
7056
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007057 if (spkr_drv_wrnd > 0) {
Joonwoo Park533b3682013-06-13 11:41:21 -07007058 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007059 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
7060 WCD9XXX_BANDGAP_AUDIO_MODE);
Joonwoo Park533b3682013-06-13 11:41:21 -07007061 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007062 }
7063
Kuirong Wang906ac472012-07-09 12:54:44 -07007064 ptr = kmalloc((sizeof(taiko_rx_chs) +
7065 sizeof(taiko_tx_chs)), GFP_KERNEL);
7066 if (!ptr) {
7067 pr_err("%s: no mem for slim chan ctl data\n", __func__);
7068 ret = -ENOMEM;
7069 goto err_nomem_slimch;
7070 }
7071
Kiran Kandic3b24402012-06-11 00:05:59 -07007072 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
7073 snd_soc_dapm_new_controls(dapm, taiko_dapm_i2s_widgets,
7074 ARRAY_SIZE(taiko_dapm_i2s_widgets));
7075 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
7076 ARRAY_SIZE(audio_i2s_map));
Joonwoo Park559a5bf2013-02-15 14:46:36 -08007077 if (TAIKO_IS_1_0(core->version))
7078 snd_soc_dapm_add_routes(dapm, audio_i2s_map_1_0,
7079 ARRAY_SIZE(audio_i2s_map_1_0));
7080 else
7081 snd_soc_dapm_add_routes(dapm, audio_i2s_map_2_0,
7082 ARRAY_SIZE(audio_i2s_map_2_0));
Kuirong Wang906ac472012-07-09 12:54:44 -07007083 for (i = 0; i < ARRAY_SIZE(taiko_i2s_dai); i++)
7084 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
7085 } else if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
7086 for (i = 0; i < NUM_CODEC_DAIS; i++) {
7087 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
7088 init_waitqueue_head(&taiko->dai[i].dai_wait);
7089 }
Joonwoo Park1d05bb92013-03-07 16:55:06 -08007090 taiko_slimbus_slave_port_cfg.slave_dev_intfdev_la =
7091 control->slim_slave->laddr;
7092 taiko_slimbus_slave_port_cfg.slave_dev_pgd_la =
7093 control->slim->laddr;
7094 taiko_slimbus_slave_port_cfg.slave_port_mapping[0] =
7095 TAIKO_MAD_SLIMBUS_TX_PORT;
7096
7097 taiko_init_slim_slave_cfg(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07007098 }
7099
Kiran Kandiec0db5c2013-03-08 16:03:58 -08007100 if (TAIKO_IS_1_0(control->version)) {
Joonwoo Park2a9170a2013-03-04 17:05:57 -08007101 snd_soc_dapm_new_controls(dapm, taiko_1_dapm_widgets,
7102 ARRAY_SIZE(taiko_1_dapm_widgets));
Kiran Kandiec0db5c2013-03-08 16:03:58 -08007103 snd_soc_add_codec_controls(codec,
7104 taiko_1_x_analog_gain_controls,
7105 ARRAY_SIZE(taiko_1_x_analog_gain_controls));
7106 } else {
Joonwoo Park2a9170a2013-03-04 17:05:57 -08007107 snd_soc_dapm_new_controls(dapm, taiko_2_dapm_widgets,
7108 ARRAY_SIZE(taiko_2_dapm_widgets));
Kiran Kandiec0db5c2013-03-08 16:03:58 -08007109 snd_soc_add_codec_controls(codec,
7110 taiko_2_x_analog_gain_controls,
7111 ARRAY_SIZE(taiko_2_x_analog_gain_controls));
7112 }
Joonwoo Park2a9170a2013-03-04 17:05:57 -08007113
Joonwoo Parkb755e9e2013-05-28 13:14:05 -07007114 snd_soc_add_codec_controls(codec, impedance_detect_controls,
7115 ARRAY_SIZE(impedance_detect_controls));
7116
Kuirong Wang906ac472012-07-09 12:54:44 -07007117 control->num_rx_port = TAIKO_RX_MAX;
7118 control->rx_chs = ptr;
7119 memcpy(control->rx_chs, taiko_rx_chs, sizeof(taiko_rx_chs));
7120 control->num_tx_port = TAIKO_TX_MAX;
7121 control->tx_chs = ptr + sizeof(taiko_rx_chs);
7122 memcpy(control->tx_chs, taiko_tx_chs, sizeof(taiko_tx_chs));
7123
Kiran Kandic3b24402012-06-11 00:05:59 -07007124 snd_soc_dapm_sync(dapm);
7125
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007126 ret = taiko_setup_irqs(taiko);
7127 if (ret) {
7128 pr_err("%s: taiko irq setup failed %d\n", __func__, ret);
7129 goto err_irq;
7130 }
Kiran Kandic3b24402012-06-11 00:05:59 -07007131
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007132 atomic_set(&kp_taiko_priv, (unsigned long)taiko);
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08007133 mutex_lock(&dapm->codec->mutex);
7134 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
7135 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
7136 snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
7137 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
7138 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
7139 snd_soc_dapm_sync(dapm);
7140 mutex_unlock(&dapm->codec->mutex);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007141
Kiran Kandic3b24402012-06-11 00:05:59 -07007142 codec->ignore_pmdown_time = 1;
7143 return ret;
7144
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007145err_irq:
7146 taiko_cleanup_irqs(taiko);
Kiran Kandic3b24402012-06-11 00:05:59 -07007147err_pdata:
Kuirong Wang906ac472012-07-09 12:54:44 -07007148 kfree(ptr);
7149err_nomem_slimch:
Kiran Kandic3b24402012-06-11 00:05:59 -07007150 kfree(taiko);
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007151err_init:
Kiran Kandic3b24402012-06-11 00:05:59 -07007152 return ret;
7153}
7154static int taiko_codec_remove(struct snd_soc_codec *codec)
7155{
Kiran Kandic3b24402012-06-11 00:05:59 -07007156 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07007157
Joonwoo Park533b3682013-06-13 11:41:21 -07007158 WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007159 atomic_set(&kp_taiko_priv, 0);
7160
7161 if (spkr_drv_wrnd > 0)
7162 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
7163 WCD9XXX_BANDGAP_AUDIO_MODE);
Joonwoo Park533b3682013-06-13 11:41:21 -07007164 WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08007165
Ravishankar Sarawadi7b700362013-04-18 15:56:02 -07007166 taiko_cleanup_irqs(taiko);
7167
Joonwoo Parka8890262012-10-15 12:04:27 -07007168 /* cleanup MBHC */
7169 wcd9xxx_mbhc_deinit(&taiko->mbhc);
7170 /* cleanup resmgr */
7171 wcd9xxx_resmgr_deinit(&taiko->resmgr);
7172
Joonwoo Park448a8fc2013-04-10 15:25:58 -07007173 taiko->spkdrv_reg = NULL;
7174
Kiran Kandic3b24402012-06-11 00:05:59 -07007175 kfree(taiko);
7176 return 0;
7177}
7178static struct snd_soc_codec_driver soc_codec_dev_taiko = {
7179 .probe = taiko_codec_probe,
7180 .remove = taiko_codec_remove,
7181
7182 .read = taiko_read,
7183 .write = taiko_write,
7184
7185 .readable_register = taiko_readable,
7186 .volatile_register = taiko_volatile,
7187
7188 .reg_cache_size = TAIKO_CACHE_SIZE,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07007189 .reg_cache_default = taiko_reset_reg_defaults,
Kiran Kandic3b24402012-06-11 00:05:59 -07007190 .reg_word_size = 1,
7191
7192 .controls = taiko_snd_controls,
7193 .num_controls = ARRAY_SIZE(taiko_snd_controls),
7194 .dapm_widgets = taiko_dapm_widgets,
7195 .num_dapm_widgets = ARRAY_SIZE(taiko_dapm_widgets),
7196 .dapm_routes = audio_map,
7197 .num_dapm_routes = ARRAY_SIZE(audio_map),
7198};
7199
7200#ifdef CONFIG_PM
7201static int taiko_suspend(struct device *dev)
7202{
7203 dev_dbg(dev, "%s: system suspend\n", __func__);
7204 return 0;
7205}
7206
7207static int taiko_resume(struct device *dev)
7208{
7209 struct platform_device *pdev = to_platform_device(dev);
7210 struct taiko_priv *taiko = platform_get_drvdata(pdev);
7211 dev_dbg(dev, "%s: system resume\n", __func__);
Joonwoo Parka8890262012-10-15 12:04:27 -07007212 /* Notify */
7213 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, WCD9XXX_EVENT_POST_RESUME);
Kiran Kandic3b24402012-06-11 00:05:59 -07007214 return 0;
7215}
7216
7217static const struct dev_pm_ops taiko_pm_ops = {
7218 .suspend = taiko_suspend,
7219 .resume = taiko_resume,
7220};
7221#endif
7222
7223static int __devinit taiko_probe(struct platform_device *pdev)
7224{
7225 int ret = 0;
7226 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
7227 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
7228 taiko_dai, ARRAY_SIZE(taiko_dai));
7229 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
7230 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
7231 taiko_i2s_dai, ARRAY_SIZE(taiko_i2s_dai));
7232 return ret;
7233}
7234static int __devexit taiko_remove(struct platform_device *pdev)
7235{
7236 snd_soc_unregister_codec(&pdev->dev);
7237 return 0;
7238}
7239static struct platform_driver taiko_codec_driver = {
7240 .probe = taiko_probe,
7241 .remove = taiko_remove,
7242 .driver = {
7243 .name = "taiko_codec",
7244 .owner = THIS_MODULE,
7245#ifdef CONFIG_PM
7246 .pm = &taiko_pm_ops,
7247#endif
7248 },
7249};
7250
7251static int __init taiko_codec_init(void)
7252{
7253 return platform_driver_register(&taiko_codec_driver);
7254}
7255
7256static void __exit taiko_codec_exit(void)
7257{
7258 platform_driver_unregister(&taiko_codec_driver);
7259}
7260
7261module_init(taiko_codec_init);
7262module_exit(taiko_codec_exit);
7263
7264MODULE_DESCRIPTION("Taiko codec driver");
7265MODULE_LICENSE("GPL v2");