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