blob: 08167cae8d6c094ca5b96f2bee649081c332b071 [file] [log] [blame]
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08001/* Copyright (c) 2012-2013, 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>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h>
32#include <linux/bitops.h>
33#include <linux/delay.h>
34#include <linux/pm_runtime.h>
35#include <linux/kernel.h>
36#include <linux/gpio.h>
37#include "wcd9320.h"
Joonwoo Parka8890262012-10-15 12:04:27 -070038#include "wcd9xxx-resmgr.h"
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -080039#include "wcd9xxx-common.h"
Kiran Kandic3b24402012-06-11 00:05:59 -070040
Joonwoo Park1d05bb92013-03-07 16:55:06 -080041#define TAIKO_MAD_SLIMBUS_TX_PORT 12
42#define TAIKO_MAD_AUDIO_FIRMWARE_PATH "wcd9320/wcd9320_mad_audio.bin"
43
Joonwoo Park125cd4e2012-12-11 15:16:11 -080044static atomic_t kp_taiko_priv;
45static int spkr_drv_wrnd_param_set(const char *val,
46 const struct kernel_param *kp);
47static int spkr_drv_wrnd = 1;
48
49static struct kernel_param_ops spkr_drv_wrnd_param_ops = {
50 .set = spkr_drv_wrnd_param_set,
51 .get = param_get_int,
52};
Joonwoo Park1d05bb92013-03-07 16:55:06 -080053
54static struct afe_param_slimbus_slave_port_cfg taiko_slimbus_slave_port_cfg = {
55 .minor_version = 1,
56 .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1,
57 .slave_dev_pgd_la = 0,
58 .slave_dev_intfdev_la = 0,
59 .bit_width = 16,
60 .data_format = 0,
61 .num_channels = 1
62};
63
64enum {
65 RESERVED = 0,
66 AANC_LPF_FF_FB = 1,
67 AANC_LPF_COEFF_MSB,
68 AANC_LPF_COEFF_LSB,
69 HW_MAD_AUDIO_ENABLE,
70 HW_MAD_ULTR_ENABLE,
71 HW_MAD_BEACON_ENABLE,
72 HW_MAD_AUDIO_SLEEP_TIME,
73 HW_MAD_ULTR_SLEEP_TIME,
74 HW_MAD_BEACON_SLEEP_TIME,
75 HW_MAD_TX_AUDIO_SWITCH_OFF,
76 HW_MAD_TX_ULTR_SWITCH_OFF,
77 HW_MAD_TX_BEACON_SWITCH_OFF,
78 MAD_AUDIO_INT_DEST_SELECT_REG,
79 MAD_ULT_INT_DEST_SELECT_REG,
80 MAD_BEACON_INT_DEST_SELECT_REG,
81 MAD_CLIP_INT_DEST_SELECT_REG,
82 MAD_VBAT_INT_DEST_SELECT_REG,
83 MAD_AUDIO_INT_MASK_REG,
84 MAD_ULT_INT_MASK_REG,
85 MAD_BEACON_INT_MASK_REG,
86 MAD_CLIP_INT_MASK_REG,
87 MAD_VBAT_INT_MASK_REG,
88 MAD_AUDIO_INT_STATUS_REG,
89 MAD_ULT_INT_STATUS_REG,
90 MAD_BEACON_INT_STATUS_REG,
91 MAD_CLIP_INT_STATUS_REG,
92 MAD_VBAT_INT_STATUS_REG,
93 MAD_AUDIO_INT_CLEAR_REG,
94 MAD_ULT_INT_CLEAR_REG,
95 MAD_BEACON_INT_CLEAR_REG,
96 MAD_CLIP_INT_CLEAR_REG,
97 MAD_VBAT_INT_CLEAR_REG,
98 SB_PGD_PORT_TX_WATERMARK_n,
99 SB_PGD_PORT_TX_ENABLE_n,
100 SB_PGD_PORT_RX_WATERMARK_n,
101 SB_PGD_PORT_RX_ENABLE_n,
Damir Didjustodcfdff82013-03-21 23:26:41 -0700102 SB_PGD_TX_PORTn_MULTI_CHNL_0,
103 SB_PGD_TX_PORTn_MULTI_CHNL_1,
104 SB_PGD_RX_PORTn_MULTI_CHNL_0,
105 SB_PGD_RX_PORTn_MULTI_CHNL_1,
106 AANC_FF_GAIN_ADAPTIVE,
107 AANC_FFGAIN_ADAPTIVE_EN,
108 AANC_GAIN_CONTROL,
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800109 MAX_CFG_REGISTERS,
110};
111
Damir Didjustodcfdff82013-03-21 23:26:41 -0700112static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800113 {
114 1,
115 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_MAIN_CTL_1),
116 HW_MAD_AUDIO_ENABLE, 0x1, 8, 0
117 },
118 {
119 1,
120 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_AUDIO_CTL_3),
121 HW_MAD_AUDIO_SLEEP_TIME, 0xF, 8, 0
122 },
123 {
124 1,
125 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_AUDIO_CTL_4),
126 HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, 8, 0
127 },
128 {
129 1,
130 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_DESTN3),
131 MAD_AUDIO_INT_DEST_SELECT_REG, 0x1, 8, 0
132 },
133 {
134 1,
135 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_MASK3),
136 MAD_AUDIO_INT_MASK_REG, 0x1, 8, 0
137 },
138 {
139 1,
140 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_STATUS3),
141 MAD_AUDIO_INT_STATUS_REG, 0x1, 8, 0
142 },
143 {
144 1,
145 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_CLEAR3),
146 MAD_AUDIO_INT_CLEAR_REG, 0x1, 8, 0
147 },
148 {
149 1,
150 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_TX_BASE),
151 SB_PGD_PORT_TX_WATERMARK_n, 0x1E, 8, 0x1
152 },
153 {
154 1,
155 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_TX_BASE),
156 SB_PGD_PORT_TX_ENABLE_n, 0x1, 8, 0x1
157 },
158 {
159 1,
160 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_RX_BASE),
161 SB_PGD_PORT_RX_WATERMARK_n, 0x1E, 8, 0x1
162 },
163 {
164 1,
165 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_RX_BASE),
166 SB_PGD_PORT_RX_ENABLE_n, 0x1, 8, 0x1
Damir Didjustodcfdff82013-03-21 23:26:41 -0700167 },
168 { 1,
169 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_ANC1_IIR_B1_CTL),
170 AANC_FF_GAIN_ADAPTIVE, 0x4, 8, 0
171 },
172 { 1,
173 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_ANC1_IIR_B1_CTL),
174 AANC_FFGAIN_ADAPTIVE_EN, 0x8, 8, 0
175 },
176 {
177 1,
178 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_ANC1_GAIN_CTL),
179 AANC_GAIN_CONTROL, 0xFF, 8, 0
180 },
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800181};
182
Damir Didjustodcfdff82013-03-21 23:26:41 -0700183static struct afe_param_cdc_reg_cfg_data taiko_audio_reg_cfg = {
184 .num_registers = ARRAY_SIZE(audio_reg_cfg),
185 .reg_data = audio_reg_cfg,
186};
187
188static struct afe_param_id_cdc_aanc_version taiko_cdc_aanc_version = {
189 .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
190 .aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800191};
192
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800193module_param_cb(spkr_drv_wrnd, &spkr_drv_wrnd_param_ops, &spkr_drv_wrnd, 0644);
194MODULE_PARM_DESC(spkr_drv_wrnd,
195 "Run software workaround to avoid leakage on the speaker drive");
196
Kiran Kandic3b24402012-06-11 00:05:59 -0700197#define WCD9320_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
198 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
199 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
200
Kiran Kandic3b24402012-06-11 00:05:59 -0700201#define NUM_DECIMATORS 10
202#define NUM_INTERPOLATORS 7
203#define BITS_PER_REG 8
Kuirong Wang906ac472012-07-09 12:54:44 -0700204#define TAIKO_TX_PORT_NUMBER 16
Kiran Kandic3b24402012-06-11 00:05:59 -0700205
Kiran Kandic3b24402012-06-11 00:05:59 -0700206#define TAIKO_I2S_MASTER_MODE_MASK 0x08
Damir Didjusto1a353ce2013-04-02 11:45:47 -0700207
208#define TAIKO_DMIC_SAMPLE_RATE_DIV_2 0x0
209#define TAIKO_DMIC_SAMPLE_RATE_DIV_3 0x1
210#define TAIKO_DMIC_SAMPLE_RATE_DIV_4 0x2
211
212#define TAIKO_DMIC_B1_CTL_DIV_2 0x00
213#define TAIKO_DMIC_B1_CTL_DIV_3 0x22
214#define TAIKO_DMIC_B1_CTL_DIV_4 0x44
215
216#define TAIKO_DMIC_B2_CTL_DIV_2 0x00
217#define TAIKO_DMIC_B2_CTL_DIV_3 0x02
218#define TAIKO_DMIC_B2_CTL_DIV_4 0x04
219
220#define TAIKO_ANC_DMIC_X2_ON 0x1
221#define TAIKO_ANC_DMIC_X2_OFF 0x0
Joonwoo Park9bbb4d12012-11-09 19:58:11 -0800222
223#define TAIKO_SLIM_CLOSE_TIMEOUT 1000
224#define TAIKO_SLIM_IRQ_OVERFLOW (1 << 0)
225#define TAIKO_SLIM_IRQ_UNDERFLOW (1 << 1)
226#define TAIKO_SLIM_IRQ_PORT_CLOSED (1 << 2)
Venkat Sudhira50a3762012-11-26 12:12:15 -0800227#define TAIKO_MCLK_CLK_12P288MHZ 12288000
228#define TAIKO_MCLK_CLK_9P6HZ 9600000
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -0800229
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -0800230#define TAIKO_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
231 SNDRV_PCM_FORMAT_S24_LE)
232
233#define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
234
Kuirong Wang906ac472012-07-09 12:54:44 -0700235enum {
236 AIF1_PB = 0,
237 AIF1_CAP,
238 AIF2_PB,
239 AIF2_CAP,
240 AIF3_PB,
241 AIF3_CAP,
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -0500242 AIF4_VIFEED,
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800243 AIF4_MAD_TX,
Kuirong Wang906ac472012-07-09 12:54:44 -0700244 NUM_CODEC_DAIS,
Kiran Kandic3b24402012-06-11 00:05:59 -0700245};
246
Kuirong Wang906ac472012-07-09 12:54:44 -0700247enum {
248 RX_MIX1_INP_SEL_ZERO = 0,
249 RX_MIX1_INP_SEL_SRC1,
250 RX_MIX1_INP_SEL_SRC2,
251 RX_MIX1_INP_SEL_IIR1,
252 RX_MIX1_INP_SEL_IIR2,
253 RX_MIX1_INP_SEL_RX1,
254 RX_MIX1_INP_SEL_RX2,
255 RX_MIX1_INP_SEL_RX3,
256 RX_MIX1_INP_SEL_RX4,
257 RX_MIX1_INP_SEL_RX5,
258 RX_MIX1_INP_SEL_RX6,
259 RX_MIX1_INP_SEL_RX7,
260 RX_MIX1_INP_SEL_AUXRX,
261};
262
263#define TAIKO_COMP_DIGITAL_GAIN_OFFSET 3
264
Kiran Kandic3b24402012-06-11 00:05:59 -0700265static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
266static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
267static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
268static struct snd_soc_dai_driver taiko_dai[];
269static const DECLARE_TLV_DB_SCALE(aux_pga_gain, 0, 2, 0);
270
Kiran Kandic3b24402012-06-11 00:05:59 -0700271/* Codec supports 2 IIR filters */
272enum {
273 IIR1 = 0,
274 IIR2,
275 IIR_MAX,
276};
277/* Codec supports 5 bands */
278enum {
279 BAND1 = 0,
280 BAND2,
281 BAND3,
282 BAND4,
283 BAND5,
284 BAND_MAX,
285};
286
287enum {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700288 COMPANDER_0,
289 COMPANDER_1,
Kiran Kandic3b24402012-06-11 00:05:59 -0700290 COMPANDER_2,
291 COMPANDER_MAX,
292};
293
294enum {
295 COMPANDER_FS_8KHZ = 0,
296 COMPANDER_FS_16KHZ,
297 COMPANDER_FS_32KHZ,
298 COMPANDER_FS_48KHZ,
299 COMPANDER_FS_96KHZ,
300 COMPANDER_FS_192KHZ,
301 COMPANDER_FS_MAX,
302};
303
Kiran Kandic3b24402012-06-11 00:05:59 -0700304struct comp_sample_dependent_params {
305 u32 peak_det_timeout;
306 u32 rms_meter_div_fact;
307 u32 rms_meter_resamp_fact;
308};
309
Kiran Kandic3b24402012-06-11 00:05:59 -0700310struct hpf_work {
311 struct taiko_priv *taiko;
312 u32 decimator;
313 u8 tx_hpf_cut_of_freq;
314 struct delayed_work dwork;
315};
316
317static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
318
Kuirong Wang906ac472012-07-09 12:54:44 -0700319static const struct wcd9xxx_ch taiko_rx_chs[TAIKO_RX_MAX] = {
320 WCD9XXX_CH(16, 0),
321 WCD9XXX_CH(17, 1),
322 WCD9XXX_CH(18, 2),
323 WCD9XXX_CH(19, 3),
324 WCD9XXX_CH(20, 4),
325 WCD9XXX_CH(21, 5),
326 WCD9XXX_CH(22, 6),
327 WCD9XXX_CH(23, 7),
328 WCD9XXX_CH(24, 8),
329 WCD9XXX_CH(25, 9),
330 WCD9XXX_CH(26, 10),
331 WCD9XXX_CH(27, 11),
332 WCD9XXX_CH(28, 12),
333};
334
335static const struct wcd9xxx_ch taiko_tx_chs[TAIKO_TX_MAX] = {
336 WCD9XXX_CH(0, 0),
337 WCD9XXX_CH(1, 1),
338 WCD9XXX_CH(2, 2),
339 WCD9XXX_CH(3, 3),
340 WCD9XXX_CH(4, 4),
341 WCD9XXX_CH(5, 5),
342 WCD9XXX_CH(6, 6),
343 WCD9XXX_CH(7, 7),
344 WCD9XXX_CH(8, 8),
345 WCD9XXX_CH(9, 9),
346 WCD9XXX_CH(10, 10),
347 WCD9XXX_CH(11, 11),
348 WCD9XXX_CH(12, 12),
349 WCD9XXX_CH(13, 13),
350 WCD9XXX_CH(14, 14),
351 WCD9XXX_CH(15, 15),
352};
353
354static const u32 vport_check_table[NUM_CODEC_DAIS] = {
355 0, /* AIF1_PB */
356 (1 << AIF2_CAP) | (1 << AIF3_CAP), /* AIF1_CAP */
357 0, /* AIF2_PB */
358 (1 << AIF1_CAP) | (1 << AIF3_CAP), /* AIF2_CAP */
359 0, /* AIF2_PB */
360 (1 << AIF1_CAP) | (1 << AIF2_CAP), /* AIF2_CAP */
361};
362
Venkat Sudhir96dd28c2012-12-04 17:00:19 -0800363static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
364 0, /* AIF1_PB */
365 0, /* AIF1_CAP */
Venkat Sudhir994193b2012-12-17 17:30:51 -0800366 0, /* AIF2_PB */
367 0, /* AIF2_CAP */
Venkat Sudhir96dd28c2012-12-04 17:00:19 -0800368};
369
Kiran Kandic3b24402012-06-11 00:05:59 -0700370struct taiko_priv {
371 struct snd_soc_codec *codec;
Kiran Kandic3b24402012-06-11 00:05:59 -0700372 u32 adc_count;
Kiran Kandic3b24402012-06-11 00:05:59 -0700373 u32 rx_bias_count;
374 s32 dmic_1_2_clk_cnt;
375 s32 dmic_3_4_clk_cnt;
376 s32 dmic_5_6_clk_cnt;
377
Kiran Kandic3b24402012-06-11 00:05:59 -0700378 u32 anc_slot;
Damir Didjusto2cb06bd2013-01-30 23:14:55 -0800379 bool anc_func;
Kiran Kandic3b24402012-06-11 00:05:59 -0700380
Kiran Kandic3b24402012-06-11 00:05:59 -0700381 /*track taiko interface type*/
382 u8 intf_type;
383
Kiran Kandic3b24402012-06-11 00:05:59 -0700384 /* num of slim ports required */
Kuirong Wang906ac472012-07-09 12:54:44 -0700385 struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
Kiran Kandic3b24402012-06-11 00:05:59 -0700386
387 /*compander*/
388 int comp_enabled[COMPANDER_MAX];
389 u32 comp_fs[COMPANDER_MAX];
390
391 /* Maintain the status of AUX PGA */
392 int aux_pga_cnt;
393 u8 aux_l_gain;
394 u8 aux_r_gain;
395
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800396 bool spkr_pa_widget_on;
397
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800398 struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
399
Joonwoo Parka8890262012-10-15 12:04:27 -0700400 /* resmgr module */
401 struct wcd9xxx_resmgr resmgr;
402 /* mbhc module */
403 struct wcd9xxx_mbhc mbhc;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -0800404
405 /* class h specific data */
406 struct wcd9xxx_clsh_cdc_data clsh_d;
407
Kiran Kandic3b24402012-06-11 00:05:59 -0700408};
409
Kiran Kandic3b24402012-06-11 00:05:59 -0700410static const u32 comp_shift[] = {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700411 4, /* Compander 0's clock source is on interpolator 7 */
Kiran Kandic3b24402012-06-11 00:05:59 -0700412 0,
413 2,
414};
415
416static const int comp_rx_path[] = {
417 COMPANDER_1,
418 COMPANDER_1,
419 COMPANDER_2,
420 COMPANDER_2,
421 COMPANDER_2,
422 COMPANDER_2,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700423 COMPANDER_0,
Kiran Kandic3b24402012-06-11 00:05:59 -0700424 COMPANDER_MAX,
425};
426
427static const struct comp_sample_dependent_params comp_samp_params[] = {
428 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700429 /* 8 Khz */
430 .peak_det_timeout = 0x02,
431 .rms_meter_div_fact = 0x09,
432 .rms_meter_resamp_fact = 0x06,
Kiran Kandic3b24402012-06-11 00:05:59 -0700433 },
434 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700435 /* 16 Khz */
436 .peak_det_timeout = 0x03,
437 .rms_meter_div_fact = 0x0A,
438 .rms_meter_resamp_fact = 0x0C,
439 },
440 {
441 /* 32 Khz */
442 .peak_det_timeout = 0x05,
443 .rms_meter_div_fact = 0x0B,
444 .rms_meter_resamp_fact = 0x1E,
445 },
446 {
447 /* 48 Khz */
448 .peak_det_timeout = 0x05,
449 .rms_meter_div_fact = 0x0B,
Kiran Kandic3b24402012-06-11 00:05:59 -0700450 .rms_meter_resamp_fact = 0x28,
451 },
Kiran Kandic3b24402012-06-11 00:05:59 -0700452 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700453 /* 96 Khz */
454 .peak_det_timeout = 0x06,
455 .rms_meter_div_fact = 0x0C,
456 .rms_meter_resamp_fact = 0x50,
Kiran Kandic3b24402012-06-11 00:05:59 -0700457 },
Kiran Kandic3b24402012-06-11 00:05:59 -0700458 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700459 /* 192 Khz */
460 .peak_det_timeout = 0x07,
461 .rms_meter_div_fact = 0xD,
462 .rms_meter_resamp_fact = 0xA0,
Kiran Kandic3b24402012-06-11 00:05:59 -0700463 },
464};
465
466static unsigned short rx_digital_gain_reg[] = {
467 TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
468 TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
469 TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
470 TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
471 TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
472 TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
473 TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
474};
475
476
477static unsigned short tx_digital_gain_reg[] = {
478 TAIKO_A_CDC_TX1_VOL_CTL_GAIN,
479 TAIKO_A_CDC_TX2_VOL_CTL_GAIN,
480 TAIKO_A_CDC_TX3_VOL_CTL_GAIN,
481 TAIKO_A_CDC_TX4_VOL_CTL_GAIN,
482 TAIKO_A_CDC_TX5_VOL_CTL_GAIN,
483 TAIKO_A_CDC_TX6_VOL_CTL_GAIN,
484 TAIKO_A_CDC_TX7_VOL_CTL_GAIN,
485 TAIKO_A_CDC_TX8_VOL_CTL_GAIN,
486 TAIKO_A_CDC_TX9_VOL_CTL_GAIN,
487 TAIKO_A_CDC_TX10_VOL_CTL_GAIN,
488};
489
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800490static int spkr_drv_wrnd_param_set(const char *val,
491 const struct kernel_param *kp)
492{
493 struct snd_soc_codec *codec;
494 int ret, old;
495 struct taiko_priv *priv;
496
497 priv = (struct taiko_priv *)atomic_read(&kp_taiko_priv);
498 if (!priv) {
499 pr_debug("%s: codec isn't yet registered\n", __func__);
500 return 0;
501 }
502
503 WCD9XXX_BCL_LOCK(&priv->resmgr);
504 old = spkr_drv_wrnd;
505 ret = param_set_int(val, kp);
506 if (ret) {
507 WCD9XXX_BCL_UNLOCK(&priv->resmgr);
508 return ret;
509 }
510
511 pr_debug("%s: spkr_drv_wrnd %d -> %d\n", __func__, old, spkr_drv_wrnd);
512 codec = priv->codec;
513 if (old == 0 && spkr_drv_wrnd == 1) {
514 wcd9xxx_resmgr_get_bandgap(&priv->resmgr,
515 WCD9XXX_BANDGAP_AUDIO_MODE);
516 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
517 } else if (old == 1 && spkr_drv_wrnd == 0) {
518 wcd9xxx_resmgr_put_bandgap(&priv->resmgr,
519 WCD9XXX_BANDGAP_AUDIO_MODE);
520 if (!priv->spkr_pa_widget_on)
521 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
522 0x00);
523 }
524
525 WCD9XXX_BCL_UNLOCK(&priv->resmgr);
526 return 0;
527}
528
Kiran Kandic3b24402012-06-11 00:05:59 -0700529static int taiko_get_anc_slot(struct snd_kcontrol *kcontrol,
530 struct snd_ctl_elem_value *ucontrol)
531{
532 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
533 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
534 ucontrol->value.integer.value[0] = taiko->anc_slot;
535 return 0;
536}
537
538static int taiko_put_anc_slot(struct snd_kcontrol *kcontrol,
539 struct snd_ctl_elem_value *ucontrol)
540{
541 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
542 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
543 taiko->anc_slot = ucontrol->value.integer.value[0];
544 return 0;
545}
546
Damir Didjusto2cb06bd2013-01-30 23:14:55 -0800547static int taiko_get_anc_func(struct snd_kcontrol *kcontrol,
548 struct snd_ctl_elem_value *ucontrol)
549{
550 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
551 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
552
553 ucontrol->value.integer.value[0] = (taiko->anc_func == true ? 1 : 0);
554 return 0;
555}
556
557static int taiko_put_anc_func(struct snd_kcontrol *kcontrol,
558 struct snd_ctl_elem_value *ucontrol)
559{
560 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
561 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
562 struct snd_soc_dapm_context *dapm = &codec->dapm;
563
564 mutex_lock(&dapm->codec->mutex);
565 taiko->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
566
567 dev_dbg(codec->dev, "%s: anc_func %x", __func__, taiko->anc_func);
568
569 if (taiko->anc_func == true) {
570 snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
571 snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
572 snd_soc_dapm_enable_pin(dapm, "ANC HEADPHONE");
573 snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
574 snd_soc_dapm_enable_pin(dapm, "ANC EAR");
575 snd_soc_dapm_disable_pin(dapm, "HPHR");
576 snd_soc_dapm_disable_pin(dapm, "HPHL");
577 snd_soc_dapm_disable_pin(dapm, "HEADPHONE");
578 snd_soc_dapm_disable_pin(dapm, "EAR PA");
579 snd_soc_dapm_disable_pin(dapm, "EAR");
580 } else {
581 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
582 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
583 snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
584 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
585 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
586 snd_soc_dapm_enable_pin(dapm, "HPHR");
587 snd_soc_dapm_enable_pin(dapm, "HPHL");
588 snd_soc_dapm_enable_pin(dapm, "HEADPHONE");
589 snd_soc_dapm_enable_pin(dapm, "EAR PA");
590 snd_soc_dapm_enable_pin(dapm, "EAR");
591 }
592 snd_soc_dapm_sync(dapm);
593 mutex_unlock(&dapm->codec->mutex);
594 return 0;
595}
596
Kiran Kandic3b24402012-06-11 00:05:59 -0700597static int taiko_get_iir_enable_audio_mixer(
598 struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_value *ucontrol)
600{
601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
602 int iir_idx = ((struct soc_multi_mixer_control *)
603 kcontrol->private_value)->reg;
604 int band_idx = ((struct soc_multi_mixer_control *)
605 kcontrol->private_value)->shift;
606
607 ucontrol->value.integer.value[0] =
Ben Romberger205e14d2013-02-06 12:31:53 -0800608 (snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
609 (1 << band_idx)) != 0;
Kiran Kandic3b24402012-06-11 00:05:59 -0700610
611 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
612 iir_idx, band_idx,
613 (uint32_t)ucontrol->value.integer.value[0]);
614 return 0;
615}
616
617static int taiko_put_iir_enable_audio_mixer(
618 struct snd_kcontrol *kcontrol,
619 struct snd_ctl_elem_value *ucontrol)
620{
621 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
622 int iir_idx = ((struct soc_multi_mixer_control *)
623 kcontrol->private_value)->reg;
624 int band_idx = ((struct soc_multi_mixer_control *)
625 kcontrol->private_value)->shift;
626 int value = ucontrol->value.integer.value[0];
627
628 /* Mask first 5 bits, 6-8 are reserved */
629 snd_soc_update_bits(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx),
630 (1 << band_idx), (value << band_idx));
631
632 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
Ben Romberger205e14d2013-02-06 12:31:53 -0800633 iir_idx, band_idx,
634 ((snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
635 (1 << band_idx)) != 0));
Kiran Kandic3b24402012-06-11 00:05:59 -0700636 return 0;
637}
638static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
639 int iir_idx, int band_idx,
640 int coeff_idx)
641{
Ben Romberger205e14d2013-02-06 12:31:53 -0800642 uint32_t value = 0;
643
Kiran Kandic3b24402012-06-11 00:05:59 -0700644 /* Address does not automatically update if reading */
645 snd_soc_write(codec,
646 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
Ben Romberger205e14d2013-02-06 12:31:53 -0800647 ((band_idx * BAND_MAX + coeff_idx)
648 * sizeof(uint32_t)) & 0x7F);
649
650 value |= snd_soc_read(codec,
651 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx));
652
653 snd_soc_write(codec,
654 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
655 ((band_idx * BAND_MAX + coeff_idx)
656 * sizeof(uint32_t) + 1) & 0x7F);
657
658 value |= (snd_soc_read(codec,
659 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 8);
660
661 snd_soc_write(codec,
662 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
663 ((band_idx * BAND_MAX + coeff_idx)
664 * sizeof(uint32_t) + 2) & 0x7F);
665
666 value |= (snd_soc_read(codec,
667 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 16);
668
669 snd_soc_write(codec,
670 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
671 ((band_idx * BAND_MAX + coeff_idx)
672 * sizeof(uint32_t) + 3) & 0x7F);
Kiran Kandic3b24402012-06-11 00:05:59 -0700673
674 /* Mask bits top 2 bits since they are reserved */
Ben Romberger205e14d2013-02-06 12:31:53 -0800675 value |= ((snd_soc_read(codec,
676 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) & 0x3F) << 24);
677
678 return value;
Kiran Kandic3b24402012-06-11 00:05:59 -0700679}
680
681static int taiko_get_iir_band_audio_mixer(
682 struct snd_kcontrol *kcontrol,
683 struct snd_ctl_elem_value *ucontrol)
684{
685 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
686 int iir_idx = ((struct soc_multi_mixer_control *)
687 kcontrol->private_value)->reg;
688 int band_idx = ((struct soc_multi_mixer_control *)
689 kcontrol->private_value)->shift;
690
691 ucontrol->value.integer.value[0] =
692 get_iir_band_coeff(codec, iir_idx, band_idx, 0);
693 ucontrol->value.integer.value[1] =
694 get_iir_band_coeff(codec, iir_idx, band_idx, 1);
695 ucontrol->value.integer.value[2] =
696 get_iir_band_coeff(codec, iir_idx, band_idx, 2);
697 ucontrol->value.integer.value[3] =
698 get_iir_band_coeff(codec, iir_idx, band_idx, 3);
699 ucontrol->value.integer.value[4] =
700 get_iir_band_coeff(codec, iir_idx, band_idx, 4);
701
702 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
703 "%s: IIR #%d band #%d b1 = 0x%x\n"
704 "%s: IIR #%d band #%d b2 = 0x%x\n"
705 "%s: IIR #%d band #%d a1 = 0x%x\n"
706 "%s: IIR #%d band #%d a2 = 0x%x\n",
707 __func__, iir_idx, band_idx,
708 (uint32_t)ucontrol->value.integer.value[0],
709 __func__, iir_idx, band_idx,
710 (uint32_t)ucontrol->value.integer.value[1],
711 __func__, iir_idx, band_idx,
712 (uint32_t)ucontrol->value.integer.value[2],
713 __func__, iir_idx, band_idx,
714 (uint32_t)ucontrol->value.integer.value[3],
715 __func__, iir_idx, band_idx,
716 (uint32_t)ucontrol->value.integer.value[4]);
717 return 0;
718}
719
720static void set_iir_band_coeff(struct snd_soc_codec *codec,
721 int iir_idx, int band_idx,
Ben Romberger205e14d2013-02-06 12:31:53 -0800722 uint32_t value)
Kiran Kandic3b24402012-06-11 00:05:59 -0700723{
Kiran Kandic3b24402012-06-11 00:05:59 -0700724 snd_soc_write(codec,
Ben Romberger205e14d2013-02-06 12:31:53 -0800725 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
726 (value & 0xFF));
727
728 snd_soc_write(codec,
729 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
730 (value >> 8) & 0xFF);
731
732 snd_soc_write(codec,
733 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
734 (value >> 16) & 0xFF);
Kiran Kandic3b24402012-06-11 00:05:59 -0700735
736 /* Mask top 2 bits, 7-8 are reserved */
737 snd_soc_write(codec,
738 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
739 (value >> 24) & 0x3F);
Kiran Kandic3b24402012-06-11 00:05:59 -0700740}
741
742static int taiko_put_iir_band_audio_mixer(
743 struct snd_kcontrol *kcontrol,
744 struct snd_ctl_elem_value *ucontrol)
745{
746 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
747 int iir_idx = ((struct soc_multi_mixer_control *)
748 kcontrol->private_value)->reg;
749 int band_idx = ((struct soc_multi_mixer_control *)
750 kcontrol->private_value)->shift;
751
Ben Romberger205e14d2013-02-06 12:31:53 -0800752 /* Mask top bit it is reserved */
753 /* Updates addr automatically for each B2 write */
754 snd_soc_write(codec,
755 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
756 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
757
758 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700759 ucontrol->value.integer.value[0]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800760 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700761 ucontrol->value.integer.value[1]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800762 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700763 ucontrol->value.integer.value[2]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800764 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700765 ucontrol->value.integer.value[3]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800766 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700767 ucontrol->value.integer.value[4]);
768
769 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
770 "%s: IIR #%d band #%d b1 = 0x%x\n"
771 "%s: IIR #%d band #%d b2 = 0x%x\n"
772 "%s: IIR #%d band #%d a1 = 0x%x\n"
773 "%s: IIR #%d band #%d a2 = 0x%x\n",
774 __func__, iir_idx, band_idx,
775 get_iir_band_coeff(codec, iir_idx, band_idx, 0),
776 __func__, iir_idx, band_idx,
777 get_iir_band_coeff(codec, iir_idx, band_idx, 1),
778 __func__, iir_idx, band_idx,
779 get_iir_band_coeff(codec, iir_idx, band_idx, 2),
780 __func__, iir_idx, band_idx,
781 get_iir_band_coeff(codec, iir_idx, band_idx, 3),
782 __func__, iir_idx, band_idx,
783 get_iir_band_coeff(codec, iir_idx, band_idx, 4));
784 return 0;
785}
786
Kiran Kandic3b24402012-06-11 00:05:59 -0700787static int taiko_get_compander(struct snd_kcontrol *kcontrol,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700788 struct snd_ctl_elem_value *ucontrol)
Kiran Kandic3b24402012-06-11 00:05:59 -0700789{
790
791 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
792 int comp = ((struct soc_multi_mixer_control *)
Joonwoo Parkc7731432012-10-17 12:41:44 -0700793 kcontrol->private_value)->shift;
Kiran Kandic3b24402012-06-11 00:05:59 -0700794 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
795
796 ucontrol->value.integer.value[0] = taiko->comp_enabled[comp];
Kiran Kandic3b24402012-06-11 00:05:59 -0700797 return 0;
798}
799
800static int taiko_set_compander(struct snd_kcontrol *kcontrol,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700801 struct snd_ctl_elem_value *ucontrol)
Kiran Kandic3b24402012-06-11 00:05:59 -0700802{
803 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
804 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
805 int comp = ((struct soc_multi_mixer_control *)
Joonwoo Parkc7731432012-10-17 12:41:44 -0700806 kcontrol->private_value)->shift;
Kiran Kandic3b24402012-06-11 00:05:59 -0700807 int value = ucontrol->value.integer.value[0];
808
Joonwoo Parkc7731432012-10-17 12:41:44 -0700809 pr_debug("%s: Compander %d enable current %d, new %d\n",
810 __func__, comp, taiko->comp_enabled[comp], value);
Kiran Kandic3b24402012-06-11 00:05:59 -0700811 taiko->comp_enabled[comp] = value;
812 return 0;
813}
814
Joonwoo Parkc7731432012-10-17 12:41:44 -0700815static int taiko_config_gain_compander(struct snd_soc_codec *codec,
816 int comp, bool enable)
817{
818 int ret = 0;
819
820 switch (comp) {
821 case COMPANDER_0:
822 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_GAIN,
823 1 << 2, !enable << 2);
824 break;
825 case COMPANDER_1:
826 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_L_GAIN,
827 1 << 5, !enable << 5);
828 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_R_GAIN,
829 1 << 5, !enable << 5);
830 break;
831 case COMPANDER_2:
832 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_1_GAIN,
833 1 << 5, !enable << 5);
834 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_3_GAIN,
835 1 << 5, !enable << 5);
836 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_2_GAIN,
837 1 << 5, !enable << 5);
838 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_4_GAIN,
839 1 << 5, !enable << 5);
840 break;
841 default:
842 WARN_ON(1);
843 ret = -EINVAL;
844 }
845
846 return ret;
847}
848
849static void taiko_discharge_comp(struct snd_soc_codec *codec, int comp)
850{
851 /* Update RSM to 1, DIVF to 5 */
852 snd_soc_write(codec, TAIKO_A_CDC_COMP0_B3_CTL + (comp * 8), 1);
853 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8), 0xF0,
854 1 << 5);
855 /* Wait for 1ms */
856 usleep_range(1000, 1000);
857}
Kiran Kandic3b24402012-06-11 00:05:59 -0700858
859static int taiko_config_compander(struct snd_soc_dapm_widget *w,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700860 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -0700861{
Joonwoo Parkc7731432012-10-17 12:41:44 -0700862 int mask, emask;
863 bool timedout;
864 unsigned long timeout;
Kiran Kandic3b24402012-06-11 00:05:59 -0700865 struct snd_soc_codec *codec = w->codec;
866 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parkc7731432012-10-17 12:41:44 -0700867 const int comp = w->shift;
868 const u32 rate = taiko->comp_fs[comp];
869 const struct comp_sample_dependent_params *comp_params =
870 &comp_samp_params[rate];
Kiran Kandic3b24402012-06-11 00:05:59 -0700871
Joonwoo Parkc7731432012-10-17 12:41:44 -0700872 pr_debug("%s: %s event %d compander %d, enabled %d", __func__,
873 w->name, event, comp, taiko->comp_enabled[comp]);
874
875 if (!taiko->comp_enabled[comp])
876 return 0;
877
878 /* Compander 0 has single channel */
879 mask = (comp == COMPANDER_0 ? 0x01 : 0x03);
880 emask = (comp == COMPANDER_0 ? 0x02 : 0x03);
Kiran Kandid2b46332012-10-05 12:04:00 -0700881
Kiran Kandic3b24402012-06-11 00:05:59 -0700882 switch (event) {
883 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parkc7731432012-10-17 12:41:44 -0700884 /* Set gain source to compander */
885 taiko_config_gain_compander(codec, comp, true);
886 /* Enable RX interpolation path clocks */
887 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
888 mask << comp_shift[comp],
889 mask << comp_shift[comp]);
890
891 taiko_discharge_comp(codec, comp);
892
893 /* Clear compander halt */
894 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP0_B1_CTL +
895 (comp * 8),
896 1 << 2, 0);
897 /* Toggle compander reset bits */
898 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
899 mask << comp_shift[comp],
900 mask << comp_shift[comp]);
901 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
902 mask << comp_shift[comp], 0);
Kiran Kandic3b24402012-06-11 00:05:59 -0700903 break;
904 case SND_SOC_DAPM_POST_PMU:
Joonwoo Parkc7731432012-10-17 12:41:44 -0700905 /* Set sample rate dependent paramater */
906 snd_soc_update_bits(codec,
907 TAIKO_A_CDC_COMP0_FS_CFG + (comp * 8),
908 0x07, rate);
909 snd_soc_write(codec, TAIKO_A_CDC_COMP0_B3_CTL + (comp * 8),
910 comp_params->rms_meter_resamp_fact);
911 snd_soc_update_bits(codec,
912 TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8),
913 0x0F, comp_params->peak_det_timeout);
914 snd_soc_update_bits(codec,
915 TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8),
916 0xF0, comp_params->rms_meter_div_fact << 4);
917 /* Compander enable */
918 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP0_B1_CTL +
919 (comp * 8), emask, emask);
Kiran Kandic3b24402012-06-11 00:05:59 -0700920 break;
921 case SND_SOC_DAPM_PRE_PMD:
Joonwoo Parkc7731432012-10-17 12:41:44 -0700922 /* Halt compander */
923 snd_soc_update_bits(codec,
924 TAIKO_A_CDC_COMP0_B1_CTL + (comp * 8),
925 1 << 2, 1 << 2);
926 /* Wait up to a second for shutdown complete */
927 timeout = jiffies + HZ;
928 do {
929 if ((snd_soc_read(codec,
930 TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS +
931 (comp * 8)) & mask) == mask)
932 break;
933 } while (!(timedout = time_after(jiffies, timeout)));
934 pr_debug("%s: Compander %d shutdown %s in %dms\n", __func__,
935 comp, timedout ? "timedout" : "completed",
936 jiffies_to_msecs(timeout - HZ - jiffies));
Kiran Kandic3b24402012-06-11 00:05:59 -0700937 break;
938 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parkc7731432012-10-17 12:41:44 -0700939 /* Disable compander */
940 snd_soc_update_bits(codec,
941 TAIKO_A_CDC_COMP0_B1_CTL + (comp * 8),
942 emask, 0x00);
943 /* Turn off the clock for compander in pair */
944 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
945 mask << comp_shift[comp], 0);
946 /* Set gain source to register */
947 taiko_config_gain_compander(codec, comp, false);
Kiran Kandic3b24402012-06-11 00:05:59 -0700948 break;
949 }
950 return 0;
951}
952
Kiran Kandiec0db5c2013-03-08 16:03:58 -0800953
Kiran Kandic3b24402012-06-11 00:05:59 -0700954
Damir Didjusto2cb06bd2013-01-30 23:14:55 -0800955static const char *const taiko_anc_func_text[] = {"OFF", "ON"};
956static const struct soc_enum taiko_anc_func_enum =
957 SOC_ENUM_SINGLE_EXT(2, taiko_anc_func_text);
958
959static const char *const tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
960static const struct soc_enum tabla_ear_pa_gain_enum[] = {
961 SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
962};
963
Kiran Kandic3b24402012-06-11 00:05:59 -0700964/*cut of frequency for high pass filter*/
965static const char * const cf_text[] = {
966 "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
967};
968
969static const struct soc_enum cf_dec1_enum =
970 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX1_MUX_CTL, 4, 3, cf_text);
971
972static const struct soc_enum cf_dec2_enum =
973 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX2_MUX_CTL, 4, 3, cf_text);
974
975static const struct soc_enum cf_dec3_enum =
976 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX3_MUX_CTL, 4, 3, cf_text);
977
978static const struct soc_enum cf_dec4_enum =
979 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX4_MUX_CTL, 4, 3, cf_text);
980
981static const struct soc_enum cf_dec5_enum =
982 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX5_MUX_CTL, 4, 3, cf_text);
983
984static const struct soc_enum cf_dec6_enum =
985 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX6_MUX_CTL, 4, 3, cf_text);
986
987static const struct soc_enum cf_dec7_enum =
988 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX7_MUX_CTL, 4, 3, cf_text);
989
990static const struct soc_enum cf_dec8_enum =
991 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX8_MUX_CTL, 4, 3, cf_text);
992
993static const struct soc_enum cf_dec9_enum =
994 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX9_MUX_CTL, 4, 3, cf_text);
995
996static const struct soc_enum cf_dec10_enum =
997 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX10_MUX_CTL, 4, 3, cf_text);
998
999static const struct soc_enum cf_rxmix1_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001000 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX1_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001001
1002static const struct soc_enum cf_rxmix2_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001003 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX2_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001004
1005static const struct soc_enum cf_rxmix3_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001006 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX3_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001007
1008static const struct soc_enum cf_rxmix4_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001009 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX4_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001010
1011static const struct soc_enum cf_rxmix5_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001012 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX5_B4_CTL, 0, 3, cf_text)
Kiran Kandic3b24402012-06-11 00:05:59 -07001013;
1014static const struct soc_enum cf_rxmix6_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001015 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX6_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001016
1017static const struct soc_enum cf_rxmix7_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001018 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX7_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001019
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08001020static const char * const class_h_dsm_text[] = {
1021 "ZERO", "DSM_HPHL_RX1", "DSM_SPKR_RX7"
1022};
1023
1024static const struct soc_enum class_h_dsm_enum =
1025 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_CLSH_CTL, 4, 3, class_h_dsm_text);
1026
1027static const struct snd_kcontrol_new class_h_dsm_mux =
1028 SOC_DAPM_ENUM("CLASS_H_DSM MUX Mux", class_h_dsm_enum);
1029
1030
Kiran Kandic3b24402012-06-11 00:05:59 -07001031static const struct snd_kcontrol_new taiko_snd_controls[] = {
1032
Kiran Kandic3b24402012-06-11 00:05:59 -07001033 SOC_SINGLE_S8_TLV("RX1 Digital Volume", TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
1034 -84, 40, digital_gain),
1035 SOC_SINGLE_S8_TLV("RX2 Digital Volume", TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
1036 -84, 40, digital_gain),
1037 SOC_SINGLE_S8_TLV("RX3 Digital Volume", TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
1038 -84, 40, digital_gain),
1039 SOC_SINGLE_S8_TLV("RX4 Digital Volume", TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
1040 -84, 40, digital_gain),
1041 SOC_SINGLE_S8_TLV("RX5 Digital Volume", TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
1042 -84, 40, digital_gain),
1043 SOC_SINGLE_S8_TLV("RX6 Digital Volume", TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
1044 -84, 40, digital_gain),
1045 SOC_SINGLE_S8_TLV("RX7 Digital Volume", TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
1046 -84, 40, digital_gain),
1047
1048 SOC_SINGLE_S8_TLV("DEC1 Volume", TAIKO_A_CDC_TX1_VOL_CTL_GAIN, -84, 40,
1049 digital_gain),
1050 SOC_SINGLE_S8_TLV("DEC2 Volume", TAIKO_A_CDC_TX2_VOL_CTL_GAIN, -84, 40,
1051 digital_gain),
1052 SOC_SINGLE_S8_TLV("DEC3 Volume", TAIKO_A_CDC_TX3_VOL_CTL_GAIN, -84, 40,
1053 digital_gain),
1054 SOC_SINGLE_S8_TLV("DEC4 Volume", TAIKO_A_CDC_TX4_VOL_CTL_GAIN, -84, 40,
1055 digital_gain),
1056 SOC_SINGLE_S8_TLV("DEC5 Volume", TAIKO_A_CDC_TX5_VOL_CTL_GAIN, -84, 40,
1057 digital_gain),
1058 SOC_SINGLE_S8_TLV("DEC6 Volume", TAIKO_A_CDC_TX6_VOL_CTL_GAIN, -84, 40,
1059 digital_gain),
1060 SOC_SINGLE_S8_TLV("DEC7 Volume", TAIKO_A_CDC_TX7_VOL_CTL_GAIN, -84, 40,
1061 digital_gain),
1062 SOC_SINGLE_S8_TLV("DEC8 Volume", TAIKO_A_CDC_TX8_VOL_CTL_GAIN, -84, 40,
1063 digital_gain),
1064 SOC_SINGLE_S8_TLV("DEC9 Volume", TAIKO_A_CDC_TX9_VOL_CTL_GAIN, -84, 40,
1065 digital_gain),
1066 SOC_SINGLE_S8_TLV("DEC10 Volume", TAIKO_A_CDC_TX10_VOL_CTL_GAIN, -84,
1067 40, digital_gain),
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001068
Kiran Kandic3b24402012-06-11 00:05:59 -07001069 SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, -84,
1070 40, digital_gain),
1071 SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", TAIKO_A_CDC_IIR1_GAIN_B2_CTL, -84,
1072 40, digital_gain),
1073 SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", TAIKO_A_CDC_IIR1_GAIN_B3_CTL, -84,
1074 40, digital_gain),
1075 SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", TAIKO_A_CDC_IIR1_GAIN_B4_CTL, -84,
1076 40, digital_gain),
Kiran Kandic3b24402012-06-11 00:05:59 -07001077
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001078 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, taiko_get_anc_slot,
Kiran Kandic3b24402012-06-11 00:05:59 -07001079 taiko_put_anc_slot),
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001080 SOC_ENUM_EXT("ANC Function", taiko_anc_func_enum, taiko_get_anc_func,
1081 taiko_put_anc_func),
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001082
Kiran Kandic3b24402012-06-11 00:05:59 -07001083 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
1084 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
1085 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
1086 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
1087 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
1088 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
1089 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
1090 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
1091 SOC_ENUM("TX9 HPF cut off", cf_dec9_enum),
1092 SOC_ENUM("TX10 HPF cut off", cf_dec10_enum),
1093
1094 SOC_SINGLE("TX1 HPF Switch", TAIKO_A_CDC_TX1_MUX_CTL, 3, 1, 0),
1095 SOC_SINGLE("TX2 HPF Switch", TAIKO_A_CDC_TX2_MUX_CTL, 3, 1, 0),
1096 SOC_SINGLE("TX3 HPF Switch", TAIKO_A_CDC_TX3_MUX_CTL, 3, 1, 0),
1097 SOC_SINGLE("TX4 HPF Switch", TAIKO_A_CDC_TX4_MUX_CTL, 3, 1, 0),
1098 SOC_SINGLE("TX5 HPF Switch", TAIKO_A_CDC_TX5_MUX_CTL, 3, 1, 0),
1099 SOC_SINGLE("TX6 HPF Switch", TAIKO_A_CDC_TX6_MUX_CTL, 3, 1, 0),
1100 SOC_SINGLE("TX7 HPF Switch", TAIKO_A_CDC_TX7_MUX_CTL, 3, 1, 0),
1101 SOC_SINGLE("TX8 HPF Switch", TAIKO_A_CDC_TX8_MUX_CTL, 3, 1, 0),
1102 SOC_SINGLE("TX9 HPF Switch", TAIKO_A_CDC_TX9_MUX_CTL, 3, 1, 0),
1103 SOC_SINGLE("TX10 HPF Switch", TAIKO_A_CDC_TX10_MUX_CTL, 3, 1, 0),
1104
1105 SOC_SINGLE("RX1 HPF Switch", TAIKO_A_CDC_RX1_B5_CTL, 2, 1, 0),
1106 SOC_SINGLE("RX2 HPF Switch", TAIKO_A_CDC_RX2_B5_CTL, 2, 1, 0),
1107 SOC_SINGLE("RX3 HPF Switch", TAIKO_A_CDC_RX3_B5_CTL, 2, 1, 0),
1108 SOC_SINGLE("RX4 HPF Switch", TAIKO_A_CDC_RX4_B5_CTL, 2, 1, 0),
1109 SOC_SINGLE("RX5 HPF Switch", TAIKO_A_CDC_RX5_B5_CTL, 2, 1, 0),
1110 SOC_SINGLE("RX6 HPF Switch", TAIKO_A_CDC_RX6_B5_CTL, 2, 1, 0),
1111 SOC_SINGLE("RX7 HPF Switch", TAIKO_A_CDC_RX7_B5_CTL, 2, 1, 0),
1112
1113 SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
1114 SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
1115 SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
1116 SOC_ENUM("RX4 HPF cut off", cf_rxmix4_enum),
1117 SOC_ENUM("RX5 HPF cut off", cf_rxmix5_enum),
1118 SOC_ENUM("RX6 HPF cut off", cf_rxmix6_enum),
1119 SOC_ENUM("RX7 HPF cut off", cf_rxmix7_enum),
1120
1121 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
1122 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1123 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
1124 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1125 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
1126 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1127 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
1128 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1129 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
1130 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1131 SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
1132 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1133 SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
1134 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1135 SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
1136 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1137 SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
1138 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1139 SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
1140 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1141
1142 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
1143 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1144 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
1145 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1146 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
1147 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1148 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
1149 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1150 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
1151 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1152 SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
1153 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1154 SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
1155 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1156 SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
1157 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1158 SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
1159 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1160 SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
1161 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1162
Joonwoo Parkc7731432012-10-17 12:41:44 -07001163 SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_0, 1, 0,
1164 taiko_get_compander, taiko_set_compander),
1165 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
1166 taiko_get_compander, taiko_set_compander),
1167 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
1168 taiko_get_compander, taiko_set_compander),
Kiran Kandic3b24402012-06-11 00:05:59 -07001169
1170};
1171
Kiran Kandiec0db5c2013-03-08 16:03:58 -08001172static int taiko_pa_gain_get(struct snd_kcontrol *kcontrol,
1173 struct snd_ctl_elem_value *ucontrol)
1174{
1175 u8 ear_pa_gain;
1176 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1177
1178 ear_pa_gain = snd_soc_read(codec, TAIKO_A_RX_EAR_GAIN);
1179
1180 ear_pa_gain = ear_pa_gain >> 5;
1181
1182 ucontrol->value.integer.value[0] = ear_pa_gain;
1183
1184 pr_debug("%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
1185
1186 return 0;
1187}
1188
1189static int taiko_pa_gain_put(struct snd_kcontrol *kcontrol,
1190 struct snd_ctl_elem_value *ucontrol)
1191{
1192 u8 ear_pa_gain;
1193 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1194
1195 pr_debug("%s: ucontrol->value.integer.value[0] = %ld\n", __func__,
1196 ucontrol->value.integer.value[0]);
1197
1198 ear_pa_gain = ucontrol->value.integer.value[0] << 5;
1199
1200 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_GAIN, 0xE0, ear_pa_gain);
1201 return 0;
1202}
1203
1204static const char * const taiko_1_x_ear_pa_gain_text[] = {
1205 "POS_6_DB", "UNDEFINED_1", "UNDEFINED_2", "UNDEFINED_3", "POS_2_DB",
1206 "NEG_2P5_DB", "UNDEFINED_4", "NEG_12_DB"
1207};
1208
1209static const struct soc_enum taiko_1_x_ear_pa_gain_enum =
1210 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(taiko_1_x_ear_pa_gain_text),
1211 taiko_1_x_ear_pa_gain_text);
1212
1213static const struct snd_kcontrol_new taiko_1_x_analog_gain_controls[] = {
1214
1215 SOC_ENUM_EXT("EAR PA Gain", taiko_1_x_ear_pa_gain_enum,
1216 taiko_pa_gain_get, taiko_pa_gain_put),
1217
1218 SOC_SINGLE_TLV("HPHL Volume", TAIKO_A_RX_HPH_L_GAIN, 0, 20, 1,
1219 line_gain),
1220 SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 20, 1,
1221 line_gain),
1222
1223 SOC_SINGLE_TLV("LINEOUT1 Volume", TAIKO_A_RX_LINE_1_GAIN, 0, 20, 1,
1224 line_gain),
1225 SOC_SINGLE_TLV("LINEOUT2 Volume", TAIKO_A_RX_LINE_2_GAIN, 0, 20, 1,
1226 line_gain),
1227 SOC_SINGLE_TLV("LINEOUT3 Volume", TAIKO_A_RX_LINE_3_GAIN, 0, 20, 1,
1228 line_gain),
1229 SOC_SINGLE_TLV("LINEOUT4 Volume", TAIKO_A_RX_LINE_4_GAIN, 0, 20, 1,
1230 line_gain),
1231
1232 SOC_SINGLE_TLV("SPK DRV Volume", TAIKO_A_SPKR_DRV_GAIN, 3, 7, 1,
1233 line_gain),
1234
1235 SOC_SINGLE_TLV("ADC1 Volume", TAIKO_A_TX_1_2_EN, 5, 3, 0, analog_gain),
1236 SOC_SINGLE_TLV("ADC2 Volume", TAIKO_A_TX_1_2_EN, 1, 3, 0, analog_gain),
1237 SOC_SINGLE_TLV("ADC3 Volume", TAIKO_A_TX_3_4_EN, 5, 3, 0, analog_gain),
1238 SOC_SINGLE_TLV("ADC4 Volume", TAIKO_A_TX_3_4_EN, 1, 3, 0, analog_gain),
1239 SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_TX_5_6_EN, 5, 3, 0, analog_gain),
1240 SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_TX_5_6_EN, 1, 3, 0, analog_gain),
1241};
1242
1243static const char * const taiko_2_x_ear_pa_gain_text[] = {
1244 "POS_6_DB", "POS_4P5_DB", "POS_3_DB", "POS_1P5_DB",
1245 "POS_0_DB", "NEG_2P5_DB", "UNDEFINED", "NEG_12_DB"
1246};
1247
1248static const struct soc_enum taiko_2_x_ear_pa_gain_enum =
1249 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(taiko_2_x_ear_pa_gain_text),
1250 taiko_2_x_ear_pa_gain_text);
1251
1252static const struct snd_kcontrol_new taiko_2_x_analog_gain_controls[] = {
1253
1254 SOC_ENUM_EXT("EAR PA Gain", taiko_2_x_ear_pa_gain_enum,
1255 taiko_pa_gain_get, taiko_pa_gain_put),
1256
1257 SOC_SINGLE_TLV("HPHL Volume", TAIKO_A_RX_HPH_L_GAIN, 0, 20, 1,
1258 line_gain),
1259 SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 20, 1,
1260 line_gain),
1261
1262 SOC_SINGLE_TLV("LINEOUT1 Volume", TAIKO_A_RX_LINE_1_GAIN, 0, 20, 1,
1263 line_gain),
1264 SOC_SINGLE_TLV("LINEOUT2 Volume", TAIKO_A_RX_LINE_2_GAIN, 0, 20, 1,
1265 line_gain),
1266 SOC_SINGLE_TLV("LINEOUT3 Volume", TAIKO_A_RX_LINE_3_GAIN, 0, 20, 1,
1267 line_gain),
1268 SOC_SINGLE_TLV("LINEOUT4 Volume", TAIKO_A_RX_LINE_4_GAIN, 0, 20, 1,
1269 line_gain),
1270
1271 SOC_SINGLE_TLV("SPK DRV Volume", TAIKO_A_SPKR_DRV_GAIN, 3, 8, 1,
1272 line_gain),
1273
1274 SOC_SINGLE_TLV("ADC1 Volume", TAIKO_A_CDC_TX_1_GAIN, 2, 19, 0,
1275 analog_gain),
1276 SOC_SINGLE_TLV("ADC2 Volume", TAIKO_A_CDC_TX_2_GAIN, 2, 19, 0,
1277 analog_gain),
1278 SOC_SINGLE_TLV("ADC3 Volume", TAIKO_A_CDC_TX_3_GAIN, 2, 19, 0,
1279 analog_gain),
1280 SOC_SINGLE_TLV("ADC4 Volume", TAIKO_A_CDC_TX_4_GAIN, 2, 19, 0,
1281 analog_gain),
1282 SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_CDC_TX_5_GAIN, 2, 19, 0,
1283 analog_gain),
1284 SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_CDC_TX_6_GAIN, 2, 19, 0,
1285 analog_gain),
1286};
1287
Kiran Kandic3b24402012-06-11 00:05:59 -07001288static const char * const rx_mix1_text[] = {
1289 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2", "RX1", "RX2", "RX3", "RX4",
1290 "RX5", "RX6", "RX7"
1291};
1292
1293static const char * const rx_mix2_text[] = {
1294 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2"
1295};
1296
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001297static const char * const rx_rdac5_text[] = {
1298 "DEM4", "DEM3_INV"
Kiran Kandic3b24402012-06-11 00:05:59 -07001299};
1300
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001301static const char * const rx_rdac7_text[] = {
1302 "DEM6", "DEM5_INV"
1303};
1304
1305
Kiran Kandic3b24402012-06-11 00:05:59 -07001306static const char * const sb_tx1_mux_text[] = {
1307 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1308 "DEC1"
1309};
1310
1311static const char * const sb_tx2_mux_text[] = {
1312 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1313 "DEC2"
1314};
1315
1316static const char * const sb_tx3_mux_text[] = {
1317 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1318 "DEC3"
1319};
1320
1321static const char * const sb_tx4_mux_text[] = {
1322 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1323 "DEC4"
1324};
1325
1326static const char * const sb_tx5_mux_text[] = {
1327 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1328 "DEC5"
1329};
1330
1331static const char * const sb_tx6_mux_text[] = {
1332 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1333 "DEC6"
1334};
1335
1336static const char * const sb_tx7_to_tx10_mux_text[] = {
1337 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1338 "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1339 "DEC9", "DEC10"
1340};
1341
1342static const char * const dec1_mux_text[] = {
1343 "ZERO", "DMIC1", "ADC6",
1344};
1345
1346static const char * const dec2_mux_text[] = {
1347 "ZERO", "DMIC2", "ADC5",
1348};
1349
1350static const char * const dec3_mux_text[] = {
1351 "ZERO", "DMIC3", "ADC4",
1352};
1353
1354static const char * const dec4_mux_text[] = {
1355 "ZERO", "DMIC4", "ADC3",
1356};
1357
1358static const char * const dec5_mux_text[] = {
1359 "ZERO", "DMIC5", "ADC2",
1360};
1361
1362static const char * const dec6_mux_text[] = {
1363 "ZERO", "DMIC6", "ADC1",
1364};
1365
1366static const char * const dec7_mux_text[] = {
1367 "ZERO", "DMIC1", "DMIC6", "ADC1", "ADC6", "ANC1_FB", "ANC2_FB",
1368};
1369
1370static const char * const dec8_mux_text[] = {
1371 "ZERO", "DMIC2", "DMIC5", "ADC2", "ADC5",
1372};
1373
1374static const char * const dec9_mux_text[] = {
1375 "ZERO", "DMIC4", "DMIC5", "ADC2", "ADC3", "ADCMB", "ANC1_FB", "ANC2_FB",
1376};
1377
1378static const char * const dec10_mux_text[] = {
1379 "ZERO", "DMIC3", "DMIC6", "ADC1", "ADC4", "ADCMB", "ANC1_FB", "ANC2_FB",
1380};
1381
1382static const char * const anc_mux_text[] = {
1383 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC_MB",
1384 "RSVD_1", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6"
1385};
1386
1387static const char * const anc1_fb_mux_text[] = {
1388 "ZERO", "EAR_HPH_L", "EAR_LINE_1",
1389};
1390
1391static const char * const iir1_inp1_text[] = {
1392 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1393 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1394};
1395
1396static const struct soc_enum rx_mix1_inp1_chain_enum =
1397 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 0, 12, rx_mix1_text);
1398
1399static const struct soc_enum rx_mix1_inp2_chain_enum =
1400 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 4, 12, rx_mix1_text);
1401
1402static const struct soc_enum rx_mix1_inp3_chain_enum =
1403 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B2_CTL, 0, 12, rx_mix1_text);
1404
1405static const struct soc_enum rx2_mix1_inp1_chain_enum =
1406 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 0, 12, rx_mix1_text);
1407
1408static const struct soc_enum rx2_mix1_inp2_chain_enum =
1409 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 4, 12, rx_mix1_text);
1410
1411static const struct soc_enum rx3_mix1_inp1_chain_enum =
1412 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 0, 12, rx_mix1_text);
1413
1414static const struct soc_enum rx3_mix1_inp2_chain_enum =
1415 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 4, 12, rx_mix1_text);
1416
1417static const struct soc_enum rx4_mix1_inp1_chain_enum =
1418 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 0, 12, rx_mix1_text);
1419
1420static const struct soc_enum rx4_mix1_inp2_chain_enum =
1421 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 4, 12, rx_mix1_text);
1422
1423static const struct soc_enum rx5_mix1_inp1_chain_enum =
1424 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 0, 12, rx_mix1_text);
1425
1426static const struct soc_enum rx5_mix1_inp2_chain_enum =
1427 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 4, 12, rx_mix1_text);
1428
1429static const struct soc_enum rx6_mix1_inp1_chain_enum =
1430 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 0, 12, rx_mix1_text);
1431
1432static const struct soc_enum rx6_mix1_inp2_chain_enum =
1433 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 4, 12, rx_mix1_text);
1434
1435static const struct soc_enum rx7_mix1_inp1_chain_enum =
1436 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 0, 12, rx_mix1_text);
1437
1438static const struct soc_enum rx7_mix1_inp2_chain_enum =
1439 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 4, 12, rx_mix1_text);
1440
1441static const struct soc_enum rx1_mix2_inp1_chain_enum =
1442 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 0, 5, rx_mix2_text);
1443
1444static const struct soc_enum rx1_mix2_inp2_chain_enum =
1445 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 3, 5, rx_mix2_text);
1446
1447static const struct soc_enum rx2_mix2_inp1_chain_enum =
1448 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 0, 5, rx_mix2_text);
1449
1450static const struct soc_enum rx2_mix2_inp2_chain_enum =
1451 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 3, 5, rx_mix2_text);
1452
1453static const struct soc_enum rx7_mix2_inp1_chain_enum =
1454 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 0, 5, rx_mix2_text);
1455
1456static const struct soc_enum rx7_mix2_inp2_chain_enum =
1457 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 3, 5, rx_mix2_text);
1458
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001459static const struct soc_enum rx_rdac5_enum =
1460 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_MISC, 2, 2, rx_rdac5_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001461
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001462static const struct soc_enum rx_rdac7_enum =
1463 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_MISC, 1, 2, rx_rdac7_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001464
1465static const struct soc_enum sb_tx1_mux_enum =
1466 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0, 9, sb_tx1_mux_text);
1467
1468static const struct soc_enum sb_tx2_mux_enum =
1469 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0, 9, sb_tx2_mux_text);
1470
1471static const struct soc_enum sb_tx3_mux_enum =
1472 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0, 9, sb_tx3_mux_text);
1473
1474static const struct soc_enum sb_tx4_mux_enum =
1475 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0, 9, sb_tx4_mux_text);
1476
1477static const struct soc_enum sb_tx5_mux_enum =
1478 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0, 9, sb_tx5_mux_text);
1479
1480static const struct soc_enum sb_tx6_mux_enum =
1481 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0, 9, sb_tx6_mux_text);
1482
1483static const struct soc_enum sb_tx7_mux_enum =
1484 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0, 18,
1485 sb_tx7_to_tx10_mux_text);
1486
1487static const struct soc_enum sb_tx8_mux_enum =
1488 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0, 18,
1489 sb_tx7_to_tx10_mux_text);
1490
1491static const struct soc_enum sb_tx9_mux_enum =
1492 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0, 18,
1493 sb_tx7_to_tx10_mux_text);
1494
1495static const struct soc_enum sb_tx10_mux_enum =
1496 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0, 18,
1497 sb_tx7_to_tx10_mux_text);
1498
1499static const struct soc_enum dec1_mux_enum =
1500 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 0, 3, dec1_mux_text);
1501
1502static const struct soc_enum dec2_mux_enum =
1503 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 2, 3, dec2_mux_text);
1504
1505static const struct soc_enum dec3_mux_enum =
1506 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 4, 3, dec3_mux_text);
1507
1508static const struct soc_enum dec4_mux_enum =
1509 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 6, 3, dec4_mux_text);
1510
1511static const struct soc_enum dec5_mux_enum =
1512 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 0, 3, dec5_mux_text);
1513
1514static const struct soc_enum dec6_mux_enum =
1515 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 2, 3, dec6_mux_text);
1516
1517static const struct soc_enum dec7_mux_enum =
1518 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 4, 7, dec7_mux_text);
1519
1520static const struct soc_enum dec8_mux_enum =
1521 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 0, 7, dec8_mux_text);
1522
1523static const struct soc_enum dec9_mux_enum =
1524 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 3, 8, dec9_mux_text);
1525
1526static const struct soc_enum dec10_mux_enum =
1527 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B4_CTL, 0, 8, dec10_mux_text);
1528
1529static const struct soc_enum anc1_mux_enum =
1530 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 0, 16, anc_mux_text);
1531
1532static const struct soc_enum anc2_mux_enum =
1533 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 4, 16, anc_mux_text);
1534
1535static const struct soc_enum anc1_fb_mux_enum =
1536 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B2_CTL, 0, 3, anc1_fb_mux_text);
1537
1538static const struct soc_enum iir1_inp1_mux_enum =
1539 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir1_inp1_text);
1540
1541static const struct snd_kcontrol_new rx_mix1_inp1_mux =
1542 SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
1543
1544static const struct snd_kcontrol_new rx_mix1_inp2_mux =
1545 SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
1546
1547static const struct snd_kcontrol_new rx_mix1_inp3_mux =
1548 SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
1549
1550static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
1551 SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
1552
1553static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
1554 SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
1555
1556static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
1557 SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
1558
1559static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
1560 SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
1561
1562static const struct snd_kcontrol_new rx4_mix1_inp1_mux =
1563 SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum);
1564
1565static const struct snd_kcontrol_new rx4_mix1_inp2_mux =
1566 SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum);
1567
1568static const struct snd_kcontrol_new rx5_mix1_inp1_mux =
1569 SOC_DAPM_ENUM("RX5 MIX1 INP1 Mux", rx5_mix1_inp1_chain_enum);
1570
1571static const struct snd_kcontrol_new rx5_mix1_inp2_mux =
1572 SOC_DAPM_ENUM("RX5 MIX1 INP2 Mux", rx5_mix1_inp2_chain_enum);
1573
1574static const struct snd_kcontrol_new rx6_mix1_inp1_mux =
1575 SOC_DAPM_ENUM("RX6 MIX1 INP1 Mux", rx6_mix1_inp1_chain_enum);
1576
1577static const struct snd_kcontrol_new rx6_mix1_inp2_mux =
1578 SOC_DAPM_ENUM("RX6 MIX1 INP2 Mux", rx6_mix1_inp2_chain_enum);
1579
1580static const struct snd_kcontrol_new rx7_mix1_inp1_mux =
1581 SOC_DAPM_ENUM("RX7 MIX1 INP1 Mux", rx7_mix1_inp1_chain_enum);
1582
1583static const struct snd_kcontrol_new rx7_mix1_inp2_mux =
1584 SOC_DAPM_ENUM("RX7 MIX1 INP2 Mux", rx7_mix1_inp2_chain_enum);
1585
1586static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
1587 SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_mix2_inp1_chain_enum);
1588
1589static const struct snd_kcontrol_new rx1_mix2_inp2_mux =
1590 SOC_DAPM_ENUM("RX1 MIX2 INP2 Mux", rx1_mix2_inp2_chain_enum);
1591
1592static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
1593 SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
1594
1595static const struct snd_kcontrol_new rx2_mix2_inp2_mux =
1596 SOC_DAPM_ENUM("RX2 MIX2 INP2 Mux", rx2_mix2_inp2_chain_enum);
1597
1598static const struct snd_kcontrol_new rx7_mix2_inp1_mux =
1599 SOC_DAPM_ENUM("RX7 MIX2 INP1 Mux", rx7_mix2_inp1_chain_enum);
1600
1601static const struct snd_kcontrol_new rx7_mix2_inp2_mux =
1602 SOC_DAPM_ENUM("RX7 MIX2 INP2 Mux", rx7_mix2_inp2_chain_enum);
1603
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001604static const struct snd_kcontrol_new rx_dac5_mux =
1605 SOC_DAPM_ENUM("RDAC5 MUX Mux", rx_rdac5_enum);
Kiran Kandic3b24402012-06-11 00:05:59 -07001606
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001607static const struct snd_kcontrol_new rx_dac7_mux =
1608 SOC_DAPM_ENUM("RDAC7 MUX Mux", rx_rdac7_enum);
Kiran Kandic3b24402012-06-11 00:05:59 -07001609
1610static const struct snd_kcontrol_new sb_tx1_mux =
1611 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
1612
1613static const struct snd_kcontrol_new sb_tx2_mux =
1614 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
1615
1616static const struct snd_kcontrol_new sb_tx3_mux =
1617 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
1618
1619static const struct snd_kcontrol_new sb_tx4_mux =
1620 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
1621
1622static const struct snd_kcontrol_new sb_tx5_mux =
1623 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
1624
1625static const struct snd_kcontrol_new sb_tx6_mux =
1626 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
1627
1628static const struct snd_kcontrol_new sb_tx7_mux =
1629 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
1630
1631static const struct snd_kcontrol_new sb_tx8_mux =
1632 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
1633
1634static const struct snd_kcontrol_new sb_tx9_mux =
1635 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
1636
1637static const struct snd_kcontrol_new sb_tx10_mux =
1638 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
1639
1640
1641static int wcd9320_put_dec_enum(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_value *ucontrol)
1643{
1644 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1645 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1646 struct snd_soc_codec *codec = w->codec;
1647 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1648 unsigned int dec_mux, decimator;
1649 char *dec_name = NULL;
1650 char *widget_name = NULL;
1651 char *temp;
1652 u16 tx_mux_ctl_reg;
1653 u8 adc_dmic_sel = 0x0;
1654 int ret = 0;
1655
1656 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1657 return -EINVAL;
1658
1659 dec_mux = ucontrol->value.enumerated.item[0];
1660
1661 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
1662 if (!widget_name)
1663 return -ENOMEM;
1664 temp = widget_name;
1665
1666 dec_name = strsep(&widget_name, " ");
1667 widget_name = temp;
1668 if (!dec_name) {
1669 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
1670 ret = -EINVAL;
1671 goto out;
1672 }
1673
1674 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
1675 if (ret < 0) {
1676 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
1677 ret = -EINVAL;
1678 goto out;
1679 }
1680
1681 dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
1682 , __func__, w->name, decimator, dec_mux);
1683
1684
1685 switch (decimator) {
1686 case 1:
1687 case 2:
1688 case 3:
1689 case 4:
1690 case 5:
1691 case 6:
1692 if (dec_mux == 1)
1693 adc_dmic_sel = 0x1;
1694 else
1695 adc_dmic_sel = 0x0;
1696 break;
1697 case 7:
1698 case 8:
1699 case 9:
1700 case 10:
1701 if ((dec_mux == 1) || (dec_mux == 2))
1702 adc_dmic_sel = 0x1;
1703 else
1704 adc_dmic_sel = 0x0;
1705 break;
1706 default:
1707 pr_err("%s: Invalid Decimator = %u\n", __func__, decimator);
1708 ret = -EINVAL;
1709 goto out;
1710 }
1711
1712 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
1713
1714 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
1715
1716 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
1717
1718out:
1719 kfree(widget_name);
1720 return ret;
1721}
1722
1723#define WCD9320_DEC_ENUM(xname, xenum) \
1724{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1725 .info = snd_soc_info_enum_double, \
1726 .get = snd_soc_dapm_get_enum_double, \
1727 .put = wcd9320_put_dec_enum, \
1728 .private_value = (unsigned long)&xenum }
1729
1730static const struct snd_kcontrol_new dec1_mux =
1731 WCD9320_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
1732
1733static const struct snd_kcontrol_new dec2_mux =
1734 WCD9320_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
1735
1736static const struct snd_kcontrol_new dec3_mux =
1737 WCD9320_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum);
1738
1739static const struct snd_kcontrol_new dec4_mux =
1740 WCD9320_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum);
1741
1742static const struct snd_kcontrol_new dec5_mux =
1743 WCD9320_DEC_ENUM("DEC5 MUX Mux", dec5_mux_enum);
1744
1745static const struct snd_kcontrol_new dec6_mux =
1746 WCD9320_DEC_ENUM("DEC6 MUX Mux", dec6_mux_enum);
1747
1748static const struct snd_kcontrol_new dec7_mux =
1749 WCD9320_DEC_ENUM("DEC7 MUX Mux", dec7_mux_enum);
1750
1751static const struct snd_kcontrol_new dec8_mux =
1752 WCD9320_DEC_ENUM("DEC8 MUX Mux", dec8_mux_enum);
1753
1754static const struct snd_kcontrol_new dec9_mux =
1755 WCD9320_DEC_ENUM("DEC9 MUX Mux", dec9_mux_enum);
1756
1757static const struct snd_kcontrol_new dec10_mux =
1758 WCD9320_DEC_ENUM("DEC10 MUX Mux", dec10_mux_enum);
1759
1760static const struct snd_kcontrol_new iir1_inp1_mux =
1761 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
1762
1763static const struct snd_kcontrol_new anc1_mux =
1764 SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
1765
1766static const struct snd_kcontrol_new anc2_mux =
1767 SOC_DAPM_ENUM("ANC2 MUX Mux", anc2_mux_enum);
1768
1769static const struct snd_kcontrol_new anc1_fb_mux =
1770 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
1771
1772static const struct snd_kcontrol_new dac1_switch[] = {
1773 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_EAR_EN, 5, 1, 0)
1774};
1775static const struct snd_kcontrol_new hphl_switch[] = {
1776 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
1777};
1778
1779static const struct snd_kcontrol_new hphl_pa_mix[] = {
1780 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1781 7, 1, 0),
1782};
1783
1784static const struct snd_kcontrol_new hphr_pa_mix[] = {
1785 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1786 6, 1, 0),
1787};
1788
1789static const struct snd_kcontrol_new ear_pa_mix[] = {
1790 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1791 5, 1, 0),
1792};
1793static const struct snd_kcontrol_new lineout1_pa_mix[] = {
1794 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1795 4, 1, 0),
1796};
1797
1798static const struct snd_kcontrol_new lineout2_pa_mix[] = {
1799 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1800 3, 1, 0),
1801};
1802
1803static const struct snd_kcontrol_new lineout3_pa_mix[] = {
1804 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1805 2, 1, 0),
1806};
1807
1808static const struct snd_kcontrol_new lineout4_pa_mix[] = {
1809 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1810 1, 1, 0),
1811};
1812
1813static const struct snd_kcontrol_new lineout3_ground_switch =
1814 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_3_DAC_CTL, 6, 1, 0);
1815
1816static const struct snd_kcontrol_new lineout4_ground_switch =
1817 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_4_DAC_CTL, 6, 1, 0);
1818
Joonwoo Park9ead0e92013-03-18 11:33:33 -07001819static const struct snd_kcontrol_new aif4_mad_switch =
1820 SOC_DAPM_SINGLE("Switch", TAIKO_A_CDC_CLK_OTHR_CTL, 4, 1, 0);
1821
Kuirong Wang906ac472012-07-09 12:54:44 -07001822/* virtual port entries */
1823static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
1824 struct snd_ctl_elem_value *ucontrol)
1825{
1826 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1827 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1828
1829 ucontrol->value.integer.value[0] = widget->value;
1830 return 0;
1831}
1832
1833static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
1834 struct snd_ctl_elem_value *ucontrol)
1835{
1836 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1837 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1838 struct snd_soc_codec *codec = widget->codec;
1839 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
1840 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
1841 struct soc_multi_mixer_control *mixer =
1842 ((struct soc_multi_mixer_control *)kcontrol->private_value);
1843 u32 dai_id = widget->shift;
1844 u32 port_id = mixer->shift;
1845 u32 enable = ucontrol->value.integer.value[0];
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08001846 u32 vtable = vport_check_table[dai_id];
Kuirong Wang906ac472012-07-09 12:54:44 -07001847
1848
1849 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
1850 widget->name, ucontrol->id.name, widget->value, widget->shift,
1851 ucontrol->value.integer.value[0]);
1852
1853 mutex_lock(&codec->mutex);
1854
1855 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
1856 if (dai_id != AIF1_CAP) {
1857 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
1858 __func__);
1859 mutex_unlock(&codec->mutex);
1860 return -EINVAL;
1861 }
1862 }
Venkat Sudhira41630a2012-10-27 00:57:31 -07001863 switch (dai_id) {
1864 case AIF1_CAP:
1865 case AIF2_CAP:
1866 case AIF3_CAP:
1867 /* only add to the list if value not set
1868 */
1869 if (enable && !(widget->value & 1 << port_id)) {
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08001870
1871 if (taiko_p->intf_type ==
1872 WCD9XXX_INTERFACE_TYPE_SLIMBUS)
1873 vtable = vport_check_table[dai_id];
1874 if (taiko_p->intf_type ==
1875 WCD9XXX_INTERFACE_TYPE_I2C)
1876 vtable = vport_i2s_check_table[dai_id];
1877
Venkat Sudhira41630a2012-10-27 00:57:31 -07001878 if (wcd9xxx_tx_vport_validation(
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08001879 vtable,
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001880 port_id,
1881 taiko_p->dai)) {
Venkat Sudhira41630a2012-10-27 00:57:31 -07001882 pr_debug("%s: TX%u is used by other\n"
1883 "virtual port\n",
1884 __func__, port_id + 1);
1885 mutex_unlock(&codec->mutex);
1886 return -EINVAL;
1887 }
1888 widget->value |= 1 << port_id;
1889 list_add_tail(&core->tx_chs[port_id].list,
Kuirong Wang906ac472012-07-09 12:54:44 -07001890 &taiko_p->dai[dai_id].wcd9xxx_ch_list
Venkat Sudhira41630a2012-10-27 00:57:31 -07001891 );
1892 } else if (!enable && (widget->value & 1 << port_id)) {
1893 widget->value &= ~(1 << port_id);
1894 list_del_init(&core->tx_chs[port_id].list);
1895 } else {
1896 if (enable)
1897 pr_debug("%s: TX%u port is used by\n"
1898 "this virtual port\n",
1899 __func__, port_id + 1);
1900 else
1901 pr_debug("%s: TX%u port is not used by\n"
1902 "this virtual port\n",
1903 __func__, port_id + 1);
1904 /* avoid update power function */
1905 mutex_unlock(&codec->mutex);
1906 return 0;
1907 }
1908 break;
1909 default:
1910 pr_err("Unknown AIF %d\n", dai_id);
Kuirong Wang906ac472012-07-09 12:54:44 -07001911 mutex_unlock(&codec->mutex);
Venkat Sudhira41630a2012-10-27 00:57:31 -07001912 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07001913 }
Kuirong Wang906ac472012-07-09 12:54:44 -07001914 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
1915 widget->name, widget->sname, widget->value, widget->shift);
1916
1917 snd_soc_dapm_mixer_update_power(widget, kcontrol, enable);
1918
1919 mutex_unlock(&codec->mutex);
1920 return 0;
1921}
1922
1923static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
1924 struct snd_ctl_elem_value *ucontrol)
1925{
1926 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1927 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1928
1929 ucontrol->value.enumerated.item[0] = widget->value;
1930 return 0;
1931}
1932
1933static const char *const slim_rx_mux_text[] = {
1934 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
1935};
1936
1937static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
1938 struct snd_ctl_elem_value *ucontrol)
1939{
1940 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1941 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1942 struct snd_soc_codec *codec = widget->codec;
1943 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
1944 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
1945 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1946 u32 port_id = widget->shift;
1947
1948 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
1949 widget->name, ucontrol->id.name, widget->value, widget->shift,
1950 ucontrol->value.integer.value[0]);
1951
1952 widget->value = ucontrol->value.enumerated.item[0];
1953
1954 mutex_lock(&codec->mutex);
1955
1956 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Venkat Sudhir994193b2012-12-17 17:30:51 -08001957 if (widget->value > 2) {
Kuirong Wang906ac472012-07-09 12:54:44 -07001958 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
1959 __func__);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001960 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001961 }
1962 }
1963 /* value need to match the Virtual port and AIF number
1964 */
1965 switch (widget->value) {
1966 case 0:
1967 list_del_init(&core->rx_chs[port_id].list);
1968 break;
1969 case 1:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001970 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
1971 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list))
1972 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001973 list_add_tail(&core->rx_chs[port_id].list,
1974 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list);
1975 break;
1976 case 2:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001977 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05001978 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list))
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001979 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001980 list_add_tail(&core->rx_chs[port_id].list,
1981 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list);
1982 break;
1983 case 3:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001984 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05001985 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list))
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001986 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001987 list_add_tail(&core->rx_chs[port_id].list,
1988 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list);
1989 break;
1990 default:
1991 pr_err("Unknown AIF %d\n", widget->value);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001992 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001993 }
1994
1995 snd_soc_dapm_mux_update_power(widget, kcontrol, 1, widget->value, e);
1996
1997 mutex_unlock(&codec->mutex);
1998 return 0;
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001999pr_err:
2000 pr_err("%s: RX%u is used by current requesting AIF_PB itself\n",
2001 __func__, port_id + 1);
2002err:
2003 mutex_unlock(&codec->mutex);
2004 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07002005}
2006
2007static const struct soc_enum slim_rx_mux_enum =
2008 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
2009
2010static const struct snd_kcontrol_new slim_rx_mux[TAIKO_RX_MAX] = {
2011 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
2012 slim_rx_mux_get, slim_rx_mux_put),
2013 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
2014 slim_rx_mux_get, slim_rx_mux_put),
2015 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
2016 slim_rx_mux_get, slim_rx_mux_put),
2017 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
2018 slim_rx_mux_get, slim_rx_mux_put),
2019 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
2020 slim_rx_mux_get, slim_rx_mux_put),
2021 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
2022 slim_rx_mux_get, slim_rx_mux_put),
2023 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
2024 slim_rx_mux_get, slim_rx_mux_put),
2025};
2026
2027static const struct snd_kcontrol_new aif_cap_mixer[] = {
2028 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TAIKO_TX1, 1, 0,
2029 slim_tx_mixer_get, slim_tx_mixer_put),
2030 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TAIKO_TX2, 1, 0,
2031 slim_tx_mixer_get, slim_tx_mixer_put),
2032 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TAIKO_TX3, 1, 0,
2033 slim_tx_mixer_get, slim_tx_mixer_put),
2034 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TAIKO_TX4, 1, 0,
2035 slim_tx_mixer_get, slim_tx_mixer_put),
2036 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TAIKO_TX5, 1, 0,
2037 slim_tx_mixer_get, slim_tx_mixer_put),
2038 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TAIKO_TX6, 1, 0,
2039 slim_tx_mixer_get, slim_tx_mixer_put),
2040 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TAIKO_TX7, 1, 0,
2041 slim_tx_mixer_get, slim_tx_mixer_put),
2042 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TAIKO_TX8, 1, 0,
2043 slim_tx_mixer_get, slim_tx_mixer_put),
2044 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TAIKO_TX9, 1, 0,
2045 slim_tx_mixer_get, slim_tx_mixer_put),
2046 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TAIKO_TX10, 1, 0,
2047 slim_tx_mixer_get, slim_tx_mixer_put),
2048};
2049
Kiran Kandic3b24402012-06-11 00:05:59 -07002050static void taiko_codec_enable_adc_block(struct snd_soc_codec *codec,
2051 int enable)
2052{
2053 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2054
2055 pr_debug("%s %d\n", __func__, enable);
2056
2057 if (enable) {
2058 taiko->adc_count++;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002059 snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
2060 0x2, 0x2);
Kiran Kandic3b24402012-06-11 00:05:59 -07002061 } else {
2062 taiko->adc_count--;
2063 if (!taiko->adc_count)
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002064 snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
Kiran Kandic3b24402012-06-11 00:05:59 -07002065 0x2, 0x0);
2066 }
2067}
2068
2069static int taiko_codec_enable_adc(struct snd_soc_dapm_widget *w,
2070 struct snd_kcontrol *kcontrol, int event)
2071{
2072 struct snd_soc_codec *codec = w->codec;
2073 u16 adc_reg;
2074 u8 init_bit_shift;
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002075 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07002076
2077 pr_debug("%s %d\n", __func__, event);
2078
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002079 if (TAIKO_IS_1_0(core->version)) {
2080 if (w->reg == TAIKO_A_TX_1_2_EN) {
2081 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2082 } else if (w->reg == TAIKO_A_TX_3_4_EN) {
2083 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2084 } else if (w->reg == TAIKO_A_TX_5_6_EN) {
2085 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2086 } else {
2087 pr_err("%s: Error, invalid adc register\n", __func__);
2088 return -EINVAL;
2089 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002090
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002091 if (w->shift == 3) {
2092 init_bit_shift = 6;
2093 } else if (w->shift == 7) {
2094 init_bit_shift = 7;
2095 } else {
2096 pr_err("%s: Error, invalid init bit postion adc register\n",
2097 __func__);
2098 return -EINVAL;
2099 }
2100 } else {
2101 switch (w->reg) {
2102 case TAIKO_A_CDC_TX_1_GAIN:
2103 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2104 init_bit_shift = 7;
2105 break;
2106 case TAIKO_A_CDC_TX_2_GAIN:
2107 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2108 init_bit_shift = 6;
2109 break;
2110 case TAIKO_A_CDC_TX_3_GAIN:
2111 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2112 init_bit_shift = 7;
2113 break;
2114 case TAIKO_A_CDC_TX_4_GAIN:
2115 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2116 init_bit_shift = 6;
2117 break;
2118 case TAIKO_A_CDC_TX_5_GAIN:
2119 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2120 init_bit_shift = 7;
2121 break;
2122 case TAIKO_A_CDC_TX_6_GAIN:
2123 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2124 init_bit_shift = 6;
2125 break;
2126 default:
2127 pr_err("%s: Error, invalid adc register\n", __func__);
2128 return -EINVAL;
2129 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002130 }
2131
2132 switch (event) {
2133 case SND_SOC_DAPM_PRE_PMU:
2134 taiko_codec_enable_adc_block(codec, 1);
2135 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
2136 1 << init_bit_shift);
2137 break;
2138 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002139 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -07002140 break;
2141 case SND_SOC_DAPM_POST_PMD:
2142 taiko_codec_enable_adc_block(codec, 0);
2143 break;
2144 }
2145 return 0;
2146}
2147
Kiran Kandic3b24402012-06-11 00:05:59 -07002148static int taiko_codec_enable_aux_pga(struct snd_soc_dapm_widget *w,
2149 struct snd_kcontrol *kcontrol, int event)
2150{
2151 struct snd_soc_codec *codec = w->codec;
2152 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2153
2154 pr_debug("%s: %d\n", __func__, event);
2155
2156 switch (event) {
2157 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002158 WCD9XXX_BCL_LOCK(&taiko->resmgr);
2159 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
2160 WCD9XXX_BANDGAP_AUDIO_MODE);
2161 /* AUX PGA requires RCO or MCLK */
2162 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
2163 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
2164 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07002165 break;
2166
2167 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002168 WCD9XXX_BCL_LOCK(&taiko->resmgr);
2169 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
2170 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
2171 WCD9XXX_BANDGAP_AUDIO_MODE);
2172 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
2173 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07002174 break;
2175 }
2176 return 0;
2177}
2178
2179static int taiko_codec_enable_lineout(struct snd_soc_dapm_widget *w,
2180 struct snd_kcontrol *kcontrol, int event)
2181{
2182 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002183 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002184 u16 lineout_gain_reg;
2185
2186 pr_debug("%s %d %s\n", __func__, event, w->name);
2187
2188 switch (w->shift) {
2189 case 0:
2190 lineout_gain_reg = TAIKO_A_RX_LINE_1_GAIN;
2191 break;
2192 case 1:
2193 lineout_gain_reg = TAIKO_A_RX_LINE_2_GAIN;
2194 break;
2195 case 2:
2196 lineout_gain_reg = TAIKO_A_RX_LINE_3_GAIN;
2197 break;
2198 case 3:
2199 lineout_gain_reg = TAIKO_A_RX_LINE_4_GAIN;
2200 break;
2201 default:
2202 pr_err("%s: Error, incorrect lineout register value\n",
2203 __func__);
2204 return -EINVAL;
2205 }
2206
2207 switch (event) {
2208 case SND_SOC_DAPM_PRE_PMU:
2209 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
2210 break;
2211 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002212 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2213 WCD9XXX_CLSH_STATE_LO,
2214 WCD9XXX_CLSH_REQ_ENABLE,
2215 WCD9XXX_CLSH_EVENT_POST_PA);
2216 pr_debug("%s: sleeping 3 ms after %s PA turn on\n",
Kiran Kandic3b24402012-06-11 00:05:59 -07002217 __func__, w->name);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002218 usleep_range(3000, 3000);
Kiran Kandic3b24402012-06-11 00:05:59 -07002219 break;
2220 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002221 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2222 WCD9XXX_CLSH_STATE_LO,
2223 WCD9XXX_CLSH_REQ_DISABLE,
2224 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandic3b24402012-06-11 00:05:59 -07002225 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
2226 break;
2227 }
2228 return 0;
2229}
2230
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002231static int taiko_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
2232 struct snd_kcontrol *kcontrol, int event)
2233{
Joonwoo Park125cd4e2012-12-11 15:16:11 -08002234 struct snd_soc_codec *codec = w->codec;
2235 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2236
2237 pr_debug("%s: %d %s\n", __func__, event, w->name);
2238 WCD9XXX_BCL_LOCK(&taiko->resmgr);
2239 switch (event) {
2240 case SND_SOC_DAPM_PRE_PMU:
2241 taiko->spkr_pa_widget_on = true;
2242 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
2243 break;
2244 case SND_SOC_DAPM_POST_PMD:
2245 taiko->spkr_pa_widget_on = false;
2246 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x00);
2247 break;
2248 }
2249 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002250 return 0;
2251}
Kiran Kandic3b24402012-06-11 00:05:59 -07002252
2253static int taiko_codec_enable_dmic(struct snd_soc_dapm_widget *w,
2254 struct snd_kcontrol *kcontrol, int event)
2255{
2256 struct snd_soc_codec *codec = w->codec;
2257 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2258 u8 dmic_clk_en;
2259 u16 dmic_clk_reg;
2260 s32 *dmic_clk_cnt;
2261 unsigned int dmic;
2262 int ret;
2263
2264 ret = kstrtouint(strpbrk(w->name, "123456"), 10, &dmic);
2265 if (ret < 0) {
2266 pr_err("%s: Invalid DMIC line on the codec\n", __func__);
2267 return -EINVAL;
2268 }
2269
2270 switch (dmic) {
2271 case 1:
2272 case 2:
2273 dmic_clk_en = 0x01;
2274 dmic_clk_cnt = &(taiko->dmic_1_2_clk_cnt);
2275 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
2276 pr_debug("%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
2277 __func__, event, dmic, *dmic_clk_cnt);
2278
2279 break;
2280
2281 case 3:
2282 case 4:
2283 dmic_clk_en = 0x10;
2284 dmic_clk_cnt = &(taiko->dmic_3_4_clk_cnt);
2285 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
2286
2287 pr_debug("%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n",
2288 __func__, event, dmic, *dmic_clk_cnt);
2289 break;
2290
2291 case 5:
2292 case 6:
2293 dmic_clk_en = 0x01;
2294 dmic_clk_cnt = &(taiko->dmic_5_6_clk_cnt);
2295 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B2_CTL;
2296
2297 pr_debug("%s() event %d DMIC%d dmic_5_6_clk_cnt %d\n",
2298 __func__, event, dmic, *dmic_clk_cnt);
2299
2300 break;
2301
2302 default:
2303 pr_err("%s: Invalid DMIC Selection\n", __func__);
2304 return -EINVAL;
2305 }
2306
2307 switch (event) {
2308 case SND_SOC_DAPM_PRE_PMU:
2309
2310 (*dmic_clk_cnt)++;
2311 if (*dmic_clk_cnt == 1)
2312 snd_soc_update_bits(codec, dmic_clk_reg,
2313 dmic_clk_en, dmic_clk_en);
2314
2315 break;
2316 case SND_SOC_DAPM_POST_PMD:
2317
2318 (*dmic_clk_cnt)--;
2319 if (*dmic_clk_cnt == 0)
2320 snd_soc_update_bits(codec, dmic_clk_reg,
2321 dmic_clk_en, 0);
2322 break;
2323 }
2324 return 0;
2325}
2326
Joonwoo Park1d05bb92013-03-07 16:55:06 -08002327static int taiko_codec_config_mad(struct snd_soc_codec *codec)
2328{
2329 int ret;
2330 const struct firmware *fw;
2331 struct mad_audio_cal *mad_cal;
2332 const char *filename = TAIKO_MAD_AUDIO_FIRMWARE_PATH;
2333
2334 pr_debug("%s: enter\n", __func__);
2335 ret = request_firmware(&fw, filename, codec->dev);
2336 if (ret != 0) {
2337 pr_err("Failed to acquire MAD firwmare data %s: %d\n", filename,
2338 ret);
2339 return -ENODEV;
2340 }
2341
2342 if (fw->size < sizeof(struct mad_audio_cal)) {
2343 pr_err("%s: incorrect firmware size %u\n", __func__, fw->size);
2344 release_firmware(fw);
2345 return -ENOMEM;
2346 }
2347
2348 mad_cal = (struct mad_audio_cal *)(fw->data);
2349 if (!mad_cal) {
2350 pr_err("%s: Invalid calibration data\n", __func__);
2351 release_firmware(fw);
2352 return -EINVAL;
2353 }
2354
2355 snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_MAD,
2356 0x0F, mad_cal->microphone_info.input_microphone);
2357 snd_soc_write(codec, TAIKO_A_CDC_MAD_MAIN_CTL_2,
2358 mad_cal->microphone_info.cycle_time);
2359 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_MAIN_CTL_1, 0xFF << 3,
2360 ((uint16_t)mad_cal->microphone_info.settle_time)
2361 << 3);
2362
2363 /* Audio */
2364 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_8,
2365 mad_cal->audio_info.rms_omit_samples);
2366 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_1,
2367 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
2368 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_2, 0x03 << 2,
2369 mad_cal->audio_info.detection_mechanism << 2);
2370 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_7,
2371 mad_cal->audio_info.rms_diff_threshold & 0x3F);
2372 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_5,
2373 mad_cal->audio_info.rms_threshold_lsb);
2374 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_6,
2375 mad_cal->audio_info.rms_threshold_msb);
2376
2377
2378 /* Beacon */
2379 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_8,
2380 mad_cal->beacon_info.rms_omit_samples);
2381 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_1,
2382 0x07 << 4, mad_cal->beacon_info.rms_comp_time);
2383 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_2, 0x03 << 2,
2384 mad_cal->beacon_info.detection_mechanism << 2);
2385 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_7,
2386 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
2387 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_5,
2388 mad_cal->beacon_info.rms_threshold_lsb);
2389 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_6,
2390 mad_cal->beacon_info.rms_threshold_msb);
2391
2392 /* Ultrasound */
2393 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_1,
2394 0x07 << 4, mad_cal->beacon_info.rms_comp_time);
2395 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_ULTR_CTL_2, 0x03 << 2,
2396 mad_cal->ultrasound_info.detection_mechanism);
2397 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_7,
2398 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
2399 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_5,
2400 mad_cal->ultrasound_info.rms_threshold_lsb);
2401 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_6,
2402 mad_cal->ultrasound_info.rms_threshold_msb);
2403
2404 release_firmware(fw);
2405 pr_debug("%s: leave ret %d\n", __func__, ret);
2406
2407 return ret;
2408}
2409
2410static int taiko_codec_enable_mad(struct snd_soc_dapm_widget *w,
2411 struct snd_kcontrol *kcontrol, int event)
2412{
2413 struct snd_soc_codec *codec = w->codec;
2414 int ret = 0;
2415
2416 pr_debug("%s %d\n", __func__, event);
2417 switch (event) {
2418 case SND_SOC_DAPM_PRE_PMU:
2419 ret = taiko_codec_config_mad(codec);
2420 if (ret) {
2421 pr_err("%s: Failed to config MAD\n", __func__);
2422 break;
2423 }
2424 break;
2425 }
2426 return ret;
2427}
2428
Kiran Kandic3b24402012-06-11 00:05:59 -07002429static int taiko_codec_enable_micbias(struct snd_soc_dapm_widget *w,
2430 struct snd_kcontrol *kcontrol, int event)
2431{
2432 struct snd_soc_codec *codec = w->codec;
2433 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Park3699ca32013-02-08 12:06:15 -08002434 u16 micb_int_reg = 0, micb_ctl_reg = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07002435 u8 cfilt_sel_val = 0;
2436 char *internal1_text = "Internal1";
2437 char *internal2_text = "Internal2";
2438 char *internal3_text = "Internal3";
Joonwoo Parka8890262012-10-15 12:04:27 -07002439 enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
Kiran Kandic3b24402012-06-11 00:05:59 -07002440
Joonwoo Park3699ca32013-02-08 12:06:15 -08002441 pr_debug("%s: w->name %s event %d\n", __func__, w->name, event);
2442 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) {
2443 micb_ctl_reg = TAIKO_A_MICB_1_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002444 micb_int_reg = TAIKO_A_MICB_1_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002445 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias1_cfilt_sel;
2446 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
2447 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
2448 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002449 } else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) {
2450 micb_ctl_reg = TAIKO_A_MICB_2_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002451 micb_int_reg = TAIKO_A_MICB_2_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002452 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias2_cfilt_sel;
2453 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
2454 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
2455 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002456 } else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) {
Damir Didjusto6e4f9d22013-03-07 10:10:57 -08002457 micb_ctl_reg = TAIKO_A_MICB_3_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002458 micb_int_reg = TAIKO_A_MICB_3_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002459 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias3_cfilt_sel;
2460 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
2461 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
2462 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002463 } else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) {
Damir Didjusto6e4f9d22013-03-07 10:10:57 -08002464 micb_ctl_reg = TAIKO_A_MICB_4_CTL;
Joonwoo Parka8890262012-10-15 12:04:27 -07002465 micb_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
2466 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias4_cfilt_sel;
2467 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_4_ON;
2468 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_4_ON;
2469 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_4_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002470 } else {
2471 pr_err("%s: Error, invalid micbias %s\n", __func__, w->name);
Kiran Kandic3b24402012-06-11 00:05:59 -07002472 return -EINVAL;
2473 }
2474
2475 switch (event) {
2476 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002477 /* Let MBHC module know so micbias switch to be off */
2478 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002479
Joonwoo Parka8890262012-10-15 12:04:27 -07002480 /* Get cfilt */
2481 wcd9xxx_resmgr_cfilt_get(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002482
2483 if (strnstr(w->name, internal1_text, 30))
2484 snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
2485 else if (strnstr(w->name, internal2_text, 30))
2486 snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
2487 else if (strnstr(w->name, internal3_text, 30))
2488 snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
2489
Joonwoo Park3edb9892013-03-05 17:44:54 -08002490 if (micb_ctl_reg == TAIKO_A_MICB_2_CTL)
Joonwoo Park3699ca32013-02-08 12:06:15 -08002491 wcd9xxx_resmgr_add_cond_update_bits(&taiko->resmgr,
2492 WCD9XXX_COND_HPH_MIC,
2493 micb_ctl_reg, w->shift,
2494 false);
Joonwoo Park3edb9892013-03-05 17:44:54 -08002495 else
Joonwoo Park3699ca32013-02-08 12:06:15 -08002496 snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
2497 1 << w->shift);
Kiran Kandic3b24402012-06-11 00:05:59 -07002498 break;
2499 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002500 usleep_range(20000, 20000);
Joonwoo Parka8890262012-10-15 12:04:27 -07002501 /* Let MBHC module know so micbias is on */
2502 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002503 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07002504 case SND_SOC_DAPM_POST_PMD:
Joonwoo Park3edb9892013-03-05 17:44:54 -08002505 if (micb_ctl_reg == TAIKO_A_MICB_2_CTL)
Joonwoo Park3699ca32013-02-08 12:06:15 -08002506 wcd9xxx_resmgr_rm_cond_update_bits(&taiko->resmgr,
2507 WCD9XXX_COND_HPH_MIC,
2508 micb_ctl_reg, 7, false);
Joonwoo Park3edb9892013-03-05 17:44:54 -08002509 else
Joonwoo Park3699ca32013-02-08 12:06:15 -08002510 snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
2511 0);
2512
Joonwoo Parka8890262012-10-15 12:04:27 -07002513 /* Let MBHC module know so micbias switch to be off */
2514 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
Kiran Kandic3b24402012-06-11 00:05:59 -07002515
2516 if (strnstr(w->name, internal1_text, 30))
2517 snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
2518 else if (strnstr(w->name, internal2_text, 30))
2519 snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
2520 else if (strnstr(w->name, internal3_text, 30))
2521 snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
2522
Joonwoo Parka8890262012-10-15 12:04:27 -07002523 /* Put cfilt */
2524 wcd9xxx_resmgr_cfilt_put(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002525 break;
2526 }
2527
2528 return 0;
2529}
2530
2531
2532static void tx_hpf_corner_freq_callback(struct work_struct *work)
2533{
2534 struct delayed_work *hpf_delayed_work;
2535 struct hpf_work *hpf_work;
2536 struct taiko_priv *taiko;
2537 struct snd_soc_codec *codec;
2538 u16 tx_mux_ctl_reg;
2539 u8 hpf_cut_of_freq;
2540
2541 hpf_delayed_work = to_delayed_work(work);
2542 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
2543 taiko = hpf_work->taiko;
2544 codec = hpf_work->taiko->codec;
2545 hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
2546
2547 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL +
2548 (hpf_work->decimator - 1) * 8;
2549
2550 pr_debug("%s(): decimator %u hpf_cut_of_freq 0x%x\n", __func__,
2551 hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
2552
2553 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
2554}
2555
2556#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30
2557#define CF_MIN_3DB_4HZ 0x0
2558#define CF_MIN_3DB_75HZ 0x1
2559#define CF_MIN_3DB_150HZ 0x2
2560
2561static int taiko_codec_enable_dec(struct snd_soc_dapm_widget *w,
2562 struct snd_kcontrol *kcontrol, int event)
2563{
2564 struct snd_soc_codec *codec = w->codec;
2565 unsigned int decimator;
2566 char *dec_name = NULL;
2567 char *widget_name = NULL;
2568 char *temp;
2569 int ret = 0;
2570 u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
2571 u8 dec_hpf_cut_of_freq;
2572 int offset;
2573
2574
2575 pr_debug("%s %d\n", __func__, event);
2576
2577 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
2578 if (!widget_name)
2579 return -ENOMEM;
2580 temp = widget_name;
2581
2582 dec_name = strsep(&widget_name, " ");
2583 widget_name = temp;
2584 if (!dec_name) {
2585 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
2586 ret = -EINVAL;
2587 goto out;
2588 }
2589
2590 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
2591 if (ret < 0) {
2592 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
2593 ret = -EINVAL;
2594 goto out;
2595 }
2596
2597 pr_debug("%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
2598 w->name, dec_name, decimator);
2599
2600 if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
2601 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B1_CTL;
2602 offset = 0;
2603 } else if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL) {
2604 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B2_CTL;
2605 offset = 8;
2606 } else {
2607 pr_err("%s: Error, incorrect dec\n", __func__);
2608 return -EINVAL;
2609 }
2610
2611 tx_vol_ctl_reg = TAIKO_A_CDC_TX1_VOL_CTL_CFG + 8 * (decimator - 1);
2612 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
2613
2614 switch (event) {
2615 case SND_SOC_DAPM_PRE_PMU:
2616
2617 /* Enableable TX digital mute */
2618 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2619
2620 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
2621 1 << w->shift);
2622 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
2623
2624 dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
2625
2626 dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
2627
2628 tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
2629 dec_hpf_cut_of_freq;
2630
2631 if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
2632
2633 /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
2634 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
2635 CF_MIN_3DB_150HZ << 4);
2636 }
2637
2638 /* enable HPF */
2639 snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
2640
2641 break;
2642
2643 case SND_SOC_DAPM_POST_PMU:
2644
2645 /* Disable TX digital mute */
2646 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
2647
2648 if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
2649 CF_MIN_3DB_150HZ) {
2650
2651 schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
2652 msecs_to_jiffies(300));
2653 }
2654 /* apply the digital gain after the decimator is enabled*/
Damir Didjustoed406e22012-11-16 15:44:57 -08002655 if ((w->shift + offset) < ARRAY_SIZE(tx_digital_gain_reg))
Kiran Kandic3b24402012-06-11 00:05:59 -07002656 snd_soc_write(codec,
2657 tx_digital_gain_reg[w->shift + offset],
2658 snd_soc_read(codec,
2659 tx_digital_gain_reg[w->shift + offset])
2660 );
2661
2662 break;
2663
2664 case SND_SOC_DAPM_PRE_PMD:
2665
2666 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2667 cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
2668 break;
2669
2670 case SND_SOC_DAPM_POST_PMD:
2671
2672 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
2673 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
2674 (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
2675
2676 break;
2677 }
2678out:
2679 kfree(widget_name);
2680 return ret;
2681}
2682
Joonwoo Park125cd4e2012-12-11 15:16:11 -08002683static int taiko_codec_enable_vdd_spkr(struct snd_soc_dapm_widget *w,
2684 struct snd_kcontrol *kcontrol, int event)
2685{
2686 int ret = 0;
2687 struct snd_soc_codec *codec = w->codec;
2688 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2689
2690 pr_debug("%s: %d %s\n", __func__, event, w->name);
2691 switch (event) {
2692 case SND_SOC_DAPM_PRE_PMU:
2693 if (spkr_drv_wrnd > 0) {
2694 WARN_ON(!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
2695 0x80));
2696 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
2697 0x00);
2698 }
2699 if (TAIKO_IS_1_0(core->version))
2700 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
2701 0x24, 0x00);
2702 break;
2703 case SND_SOC_DAPM_POST_PMD:
2704 if (TAIKO_IS_1_0(core->version))
2705 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
2706 0x24, 0x24);
2707 if (spkr_drv_wrnd > 0) {
2708 WARN_ON(!!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
2709 0x80));
2710 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
2711 0x80);
2712 }
2713 break;
2714 }
2715
2716 return ret;
2717}
2718
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07002719static int taiko_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07002720 struct snd_kcontrol *kcontrol, int event)
2721{
2722 struct snd_soc_codec *codec = w->codec;
2723
2724 pr_debug("%s %d %s\n", __func__, event, w->name);
2725
2726 switch (event) {
2727 case SND_SOC_DAPM_PRE_PMU:
2728 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
2729 1 << w->shift, 1 << w->shift);
2730 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
2731 1 << w->shift, 0x0);
2732 break;
2733 case SND_SOC_DAPM_POST_PMU:
2734 /* apply the digital gain after the interpolator is enabled*/
2735 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
2736 snd_soc_write(codec,
2737 rx_digital_gain_reg[w->shift],
2738 snd_soc_read(codec,
2739 rx_digital_gain_reg[w->shift])
2740 );
2741 break;
2742 }
2743 return 0;
2744}
2745
2746static int taiko_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
2747 struct snd_kcontrol *kcontrol, int event)
2748{
2749 switch (event) {
2750 case SND_SOC_DAPM_POST_PMU:
2751 case SND_SOC_DAPM_POST_PMD:
2752 usleep_range(1000, 1000);
2753 break;
2754 }
2755 return 0;
2756}
2757
2758static int taiko_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
2759 struct snd_kcontrol *kcontrol, int event)
2760{
2761 struct snd_soc_codec *codec = w->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07002762 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002763
2764 pr_debug("%s %d\n", __func__, event);
2765
2766 switch (event) {
2767 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002768 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
Kiran Kandic3b24402012-06-11 00:05:59 -07002769 break;
2770 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002771 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
Kiran Kandic3b24402012-06-11 00:05:59 -07002772 break;
2773 }
2774 return 0;
2775}
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002776
2777static int taiko_hphl_dac_event(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07002778 struct snd_kcontrol *kcontrol, int event)
2779{
2780 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002781 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002782
2783 pr_debug("%s %s %d\n", __func__, w->name, event);
2784
2785 switch (event) {
2786 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002787 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
2788 0x02, 0x02);
2789 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
2790 WCD9XXX_CLSH_STATE_HPHL,
2791 WCD9XXX_CLSH_REQ_ENABLE,
2792 WCD9XXX_CLSH_EVENT_PRE_DAC);
Kiran Kandic3b24402012-06-11 00:05:59 -07002793 break;
2794 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002795 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
2796 0x02, 0x00);
2797 }
2798 return 0;
2799}
2800
2801static int taiko_hphr_dac_event(struct snd_soc_dapm_widget *w,
2802 struct snd_kcontrol *kcontrol, int event)
2803{
2804 struct snd_soc_codec *codec = w->codec;
2805 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
2806
2807 pr_debug("%s %s %d\n", __func__, w->name, event);
2808
2809 switch (event) {
2810 case SND_SOC_DAPM_PRE_PMU:
2811 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
2812 0x04, 0x04);
2813 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
2814 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
2815 WCD9XXX_CLSH_STATE_HPHR,
2816 WCD9XXX_CLSH_REQ_ENABLE,
2817 WCD9XXX_CLSH_EVENT_PRE_DAC);
2818 break;
2819 case SND_SOC_DAPM_POST_PMD:
2820 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
2821 0x04, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -07002822 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
2823 break;
2824 }
2825 return 0;
2826}
2827
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08002828static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
2829 struct snd_kcontrol *kcontrol, int event)
2830{
2831 struct snd_soc_codec *codec = w->codec;
2832 const char *filename;
2833 const struct firmware *fw;
2834 int i;
2835 int ret;
2836 int num_anc_slots;
2837 struct anc_header *anc_head;
2838 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2839 u32 anc_writes_size = 0;
2840 int anc_size_remaining;
2841 u32 *anc_ptr;
2842 u16 reg;
2843 u8 mask, val, old_val;
2844
2845
2846 if (taiko->anc_func == 0)
2847 return 0;
2848
2849 switch (event) {
2850 case SND_SOC_DAPM_PRE_PMU:
2851 filename = "wcd9320/wcd9320_anc.bin";
2852
2853 ret = request_firmware(&fw, filename, codec->dev);
2854 if (ret != 0) {
2855 dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
2856 ret);
2857 return -ENODEV;
2858 }
2859
2860 if (fw->size < sizeof(struct anc_header)) {
2861 dev_err(codec->dev, "Not enough data\n");
2862 release_firmware(fw);
2863 return -ENOMEM;
2864 }
2865
2866 /* First number is the number of register writes */
2867 anc_head = (struct anc_header *)(fw->data);
2868 anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
2869 anc_size_remaining = fw->size - sizeof(struct anc_header);
2870 num_anc_slots = anc_head->num_anc_slots;
2871
2872 if (taiko->anc_slot >= num_anc_slots) {
2873 dev_err(codec->dev, "Invalid ANC slot selected\n");
2874 release_firmware(fw);
2875 return -EINVAL;
2876 }
2877 for (i = 0; i < num_anc_slots; i++) {
2878 if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
2879 dev_err(codec->dev, "Invalid register format\n");
2880 release_firmware(fw);
2881 return -EINVAL;
2882 }
2883 anc_writes_size = (u32)(*anc_ptr);
2884 anc_size_remaining -= sizeof(u32);
2885 anc_ptr += 1;
2886
2887 if (anc_writes_size * TAIKO_PACKED_REG_SIZE
2888 > anc_size_remaining) {
2889 dev_err(codec->dev, "Invalid register format\n");
2890 release_firmware(fw);
2891 return -ENOMEM;
2892 }
2893
2894 if (taiko->anc_slot == i)
2895 break;
2896
2897 anc_size_remaining -= (anc_writes_size *
2898 TAIKO_PACKED_REG_SIZE);
2899 anc_ptr += anc_writes_size;
2900 }
2901 if (i == num_anc_slots) {
2902 dev_err(codec->dev, "Selected ANC slot not present\n");
2903 release_firmware(fw);
2904 return -ENOMEM;
2905 }
2906 for (i = 0; i < anc_writes_size; i++) {
2907 TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
2908 mask, val);
2909 old_val = snd_soc_read(codec, reg);
2910 snd_soc_write(codec, reg, (old_val & ~mask) |
2911 (val & mask));
2912 }
2913 release_firmware(fw);
2914 break;
2915 case SND_SOC_DAPM_POST_PMD:
2916 msleep(40);
2917 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B1_CTL, 0x01, 0x00);
2918 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC2_B1_CTL, 0x02, 0x00);
2919 msleep(20);
2920 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0x0F);
2921 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
2922 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
2923 break;
2924 }
2925 return 0;
2926}
2927
Kiran Kandic3b24402012-06-11 00:05:59 -07002928static int taiko_hph_pa_event(struct snd_soc_dapm_widget *w,
Joonwoo Parka8890262012-10-15 12:04:27 -07002929 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07002930{
2931 struct snd_soc_codec *codec = w->codec;
2932 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07002933 enum wcd9xxx_notify_event e_pre_on, e_post_off;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002934 u8 req_clsh_state;
Joonwoo Parka8890262012-10-15 12:04:27 -07002935
Kiran Kandi4c56c592012-07-25 11:04:55 -07002936 pr_debug("%s: %s event = %d\n", __func__, w->name, event);
Joonwoo Parka8890262012-10-15 12:04:27 -07002937 if (w->shift == 5) {
Joonwoo Parka8890262012-10-15 12:04:27 -07002938 e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
2939 e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
Patrick Lai453cd742013-03-02 16:51:27 -08002940 req_clsh_state = WCD9XXX_CLSH_STATE_HPHL;
2941 } else if (w->shift == 4) {
2942 e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
2943 e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002944 req_clsh_state = WCD9XXX_CLSH_STATE_HPHR;
Joonwoo Parka8890262012-10-15 12:04:27 -07002945 } else {
2946 pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
2947 return -EINVAL;
2948 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002949
2950 switch (event) {
2951 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002952 /* Let MBHC module know PA is turning on */
2953 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002954 break;
2955
Kiran Kandi4c56c592012-07-25 11:04:55 -07002956 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002957 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2958 req_clsh_state,
2959 WCD9XXX_CLSH_REQ_ENABLE,
2960 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandi4c56c592012-07-25 11:04:55 -07002961
Kiran Kandi4c56c592012-07-25 11:04:55 -07002962
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002963 usleep_range(5000, 5000);
Kiran Kandi4c56c592012-07-25 11:04:55 -07002964 break;
2965
Kiran Kandic3b24402012-06-11 00:05:59 -07002966 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002967 /* Let MBHC module know PA turned off */
2968 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
2969
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002970 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2971 req_clsh_state,
2972 WCD9XXX_CLSH_REQ_DISABLE,
2973 WCD9XXX_CLSH_EVENT_POST_PA);
2974
Kiran Kandic3b24402012-06-11 00:05:59 -07002975 pr_debug("%s: sleep 10 ms after %s PA disable.\n", __func__,
Joonwoo Parka8890262012-10-15 12:04:27 -07002976 w->name);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002977 usleep_range(5000, 5000);
Kiran Kandic3b24402012-06-11 00:05:59 -07002978 break;
2979 }
2980 return 0;
2981}
2982
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08002983static int taiko_codec_enable_anc_hph(struct snd_soc_dapm_widget *w,
2984 struct snd_kcontrol *kcontrol, int event)
2985{
2986 struct snd_soc_codec *codec = w->codec;
2987 int ret = 0;
2988
2989 switch (event) {
2990 case SND_SOC_DAPM_PRE_PMU:
2991 ret = taiko_hph_pa_event(w, kcontrol, event);
2992 if (w->shift == 4) {
2993 ret |= taiko_codec_enable_anc(w, kcontrol, event);
2994 msleep(50);
2995 }
2996 break;
2997 case SND_SOC_DAPM_POST_PMU:
2998 if (w->shift == 4) {
2999 snd_soc_update_bits(codec,
3000 TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x30);
3001 msleep(30);
3002 }
3003 ret = taiko_hph_pa_event(w, kcontrol, event);
3004 break;
3005 case SND_SOC_DAPM_PRE_PMD:
3006 if (w->shift == 5) {
3007 snd_soc_update_bits(codec,
3008 TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x00);
3009 msleep(40);
3010 }
3011 if (w->shift == 5) {
3012 snd_soc_update_bits(codec,
3013 TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
3014 ret |= taiko_codec_enable_anc(w, kcontrol, event);
3015 }
3016 case SND_SOC_DAPM_POST_PMD:
3017 ret = taiko_hph_pa_event(w, kcontrol, event);
3018 break;
3019 }
3020 return ret;
3021}
3022
Kiran Kandic3b24402012-06-11 00:05:59 -07003023static const struct snd_soc_dapm_widget taiko_dapm_i2s_widgets[] = {
3024 SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", TAIKO_A_CDC_CLK_RX_I2S_CTL,
3025 4, 0, NULL, 0),
3026 SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", TAIKO_A_CDC_CLK_TX_I2S_CTL, 4,
3027 0, NULL, 0),
3028};
3029
3030static int taiko_lineout_dac_event(struct snd_soc_dapm_widget *w,
3031 struct snd_kcontrol *kcontrol, int event)
3032{
3033 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003034 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003035
3036 pr_debug("%s %s %d\n", __func__, w->name, event);
3037
3038 switch (event) {
3039 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003040 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
3041 WCD9XXX_CLSH_STATE_LO,
3042 WCD9XXX_CLSH_REQ_ENABLE,
3043 WCD9XXX_CLSH_EVENT_PRE_DAC);
Kiran Kandic3b24402012-06-11 00:05:59 -07003044 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
3045 break;
3046
3047 case SND_SOC_DAPM_POST_PMD:
3048 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
3049 break;
3050 }
3051 return 0;
3052}
3053
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003054static int taiko_spk_dac_event(struct snd_soc_dapm_widget *w,
3055 struct snd_kcontrol *kcontrol, int event)
3056{
3057 pr_debug("%s %s %d\n", __func__, w->name, event);
3058 return 0;
3059}
3060
Kiran Kandic3b24402012-06-11 00:05:59 -07003061static const struct snd_soc_dapm_route audio_i2s_map[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07003062 {"SLIM RX1", NULL, "RX_I2S_CLK"},
3063 {"SLIM RX2", NULL, "RX_I2S_CLK"},
3064 {"SLIM RX3", NULL, "RX_I2S_CLK"},
3065 {"SLIM RX4", NULL, "RX_I2S_CLK"},
3066
Venkat Sudhira41630a2012-10-27 00:57:31 -07003067 {"SLIM TX7 MUX", NULL, "TX_I2S_CLK"},
3068 {"SLIM TX8 MUX", NULL, "TX_I2S_CLK"},
3069 {"SLIM TX9 MUX", NULL, "TX_I2S_CLK"},
3070 {"SLIM TX10 MUX", NULL, "TX_I2S_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003071};
3072
Joonwoo Park559a5bf2013-02-15 14:46:36 -08003073static const struct snd_soc_dapm_route audio_i2s_map_1_0[] = {
3074 {"RX_I2S_CLK", NULL, "CDC_CONN"},
3075};
3076
3077static const struct snd_soc_dapm_route audio_i2s_map_2_0[] = {
3078 {"RX_I2S_CLK", NULL, "CDC_I2S_RX_CONN"},
3079};
3080
Kiran Kandic3b24402012-06-11 00:05:59 -07003081static const struct snd_soc_dapm_route audio_map[] = {
3082 /* SLIMBUS Connections */
Kuirong Wang906ac472012-07-09 12:54:44 -07003083 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
3084 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
3085 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003086 {"AIF4 VI", NULL, "SPK_OUT"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003087
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003088 /* MAD */
3089 {"AIF4 MAD", NULL, "CDC_CONN"},
Joonwoo Park9ead0e92013-03-18 11:33:33 -07003090 {"MADONOFF", "Switch", "MADINPUT"},
3091 {"AIF4 MAD", NULL, "MADONOFF"},
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003092
Kuirong Wang906ac472012-07-09 12:54:44 -07003093 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
3094 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3095 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3096 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3097 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3098 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3099 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3100 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3101 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3102 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3103 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3104 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
3105 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3106 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3107 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3108 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3109 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3110 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3111 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3112 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3113 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3114 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3115 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
3116 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3117 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3118 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3119 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3120 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3121 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3122 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3123 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3124 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3125 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3126
Kiran Kandic3b24402012-06-11 00:05:59 -07003127 {"SLIM TX1 MUX", "DEC1", "DEC1 MUX"},
3128
Kiran Kandic3b24402012-06-11 00:05:59 -07003129 {"SLIM TX2 MUX", "DEC2", "DEC2 MUX"},
3130
Kiran Kandic3b24402012-06-11 00:05:59 -07003131 {"SLIM TX3 MUX", "DEC3", "DEC3 MUX"},
3132 {"SLIM TX3 MUX", "RMIX1", "RX1 MIX1"},
3133 {"SLIM TX3 MUX", "RMIX2", "RX2 MIX1"},
3134 {"SLIM TX3 MUX", "RMIX3", "RX3 MIX1"},
3135 {"SLIM TX3 MUX", "RMIX4", "RX4 MIX1"},
3136 {"SLIM TX3 MUX", "RMIX5", "RX5 MIX1"},
3137 {"SLIM TX3 MUX", "RMIX6", "RX6 MIX1"},
3138 {"SLIM TX3 MUX", "RMIX7", "RX7 MIX1"},
3139
Kiran Kandic3b24402012-06-11 00:05:59 -07003140 {"SLIM TX4 MUX", "DEC4", "DEC4 MUX"},
3141
Kiran Kandic3b24402012-06-11 00:05:59 -07003142 {"SLIM TX5 MUX", "DEC5", "DEC5 MUX"},
3143 {"SLIM TX5 MUX", "RMIX1", "RX1 MIX1"},
3144 {"SLIM TX5 MUX", "RMIX2", "RX2 MIX1"},
3145 {"SLIM TX5 MUX", "RMIX3", "RX3 MIX1"},
3146 {"SLIM TX5 MUX", "RMIX4", "RX4 MIX1"},
3147 {"SLIM TX5 MUX", "RMIX5", "RX5 MIX1"},
3148 {"SLIM TX5 MUX", "RMIX6", "RX6 MIX1"},
3149 {"SLIM TX5 MUX", "RMIX7", "RX7 MIX1"},
3150
Kiran Kandic3b24402012-06-11 00:05:59 -07003151 {"SLIM TX6 MUX", "DEC6", "DEC6 MUX"},
3152
Kiran Kandic3b24402012-06-11 00:05:59 -07003153 {"SLIM TX7 MUX", "DEC1", "DEC1 MUX"},
3154 {"SLIM TX7 MUX", "DEC2", "DEC2 MUX"},
3155 {"SLIM TX7 MUX", "DEC3", "DEC3 MUX"},
3156 {"SLIM TX7 MUX", "DEC4", "DEC4 MUX"},
3157 {"SLIM TX7 MUX", "DEC5", "DEC5 MUX"},
3158 {"SLIM TX7 MUX", "DEC6", "DEC6 MUX"},
3159 {"SLIM TX7 MUX", "DEC7", "DEC7 MUX"},
3160 {"SLIM TX7 MUX", "DEC8", "DEC8 MUX"},
3161 {"SLIM TX7 MUX", "DEC9", "DEC9 MUX"},
3162 {"SLIM TX7 MUX", "DEC10", "DEC10 MUX"},
3163 {"SLIM TX7 MUX", "RMIX1", "RX1 MIX1"},
3164 {"SLIM TX7 MUX", "RMIX2", "RX2 MIX1"},
3165 {"SLIM TX7 MUX", "RMIX3", "RX3 MIX1"},
3166 {"SLIM TX7 MUX", "RMIX4", "RX4 MIX1"},
3167 {"SLIM TX7 MUX", "RMIX5", "RX5 MIX1"},
3168 {"SLIM TX7 MUX", "RMIX6", "RX6 MIX1"},
3169 {"SLIM TX7 MUX", "RMIX7", "RX7 MIX1"},
3170
Kiran Kandic3b24402012-06-11 00:05:59 -07003171 {"SLIM TX8 MUX", "DEC1", "DEC1 MUX"},
3172 {"SLIM TX8 MUX", "DEC2", "DEC2 MUX"},
3173 {"SLIM TX8 MUX", "DEC3", "DEC3 MUX"},
3174 {"SLIM TX8 MUX", "DEC4", "DEC4 MUX"},
3175 {"SLIM TX8 MUX", "DEC5", "DEC5 MUX"},
3176 {"SLIM TX8 MUX", "DEC6", "DEC6 MUX"},
3177 {"SLIM TX8 MUX", "DEC7", "DEC7 MUX"},
3178 {"SLIM TX8 MUX", "DEC8", "DEC8 MUX"},
3179 {"SLIM TX8 MUX", "DEC9", "DEC9 MUX"},
3180 {"SLIM TX8 MUX", "DEC10", "DEC10 MUX"},
3181
Kiran Kandic3b24402012-06-11 00:05:59 -07003182 {"SLIM TX9 MUX", "DEC1", "DEC1 MUX"},
3183 {"SLIM TX9 MUX", "DEC2", "DEC2 MUX"},
3184 {"SLIM TX9 MUX", "DEC3", "DEC3 MUX"},
3185 {"SLIM TX9 MUX", "DEC4", "DEC4 MUX"},
3186 {"SLIM TX9 MUX", "DEC5", "DEC5 MUX"},
3187 {"SLIM TX9 MUX", "DEC6", "DEC6 MUX"},
3188 {"SLIM TX9 MUX", "DEC7", "DEC7 MUX"},
3189 {"SLIM TX9 MUX", "DEC8", "DEC8 MUX"},
3190 {"SLIM TX9 MUX", "DEC9", "DEC9 MUX"},
3191 {"SLIM TX9 MUX", "DEC10", "DEC10 MUX"},
3192
Kiran Kandic3b24402012-06-11 00:05:59 -07003193 {"SLIM TX10 MUX", "DEC1", "DEC1 MUX"},
3194 {"SLIM TX10 MUX", "DEC2", "DEC2 MUX"},
3195 {"SLIM TX10 MUX", "DEC3", "DEC3 MUX"},
3196 {"SLIM TX10 MUX", "DEC4", "DEC4 MUX"},
3197 {"SLIM TX10 MUX", "DEC5", "DEC5 MUX"},
3198 {"SLIM TX10 MUX", "DEC6", "DEC6 MUX"},
3199 {"SLIM TX10 MUX", "DEC7", "DEC7 MUX"},
3200 {"SLIM TX10 MUX", "DEC8", "DEC8 MUX"},
3201 {"SLIM TX10 MUX", "DEC9", "DEC9 MUX"},
3202 {"SLIM TX10 MUX", "DEC10", "DEC10 MUX"},
3203
3204 /* Earpiece (RX MIX1) */
3205 {"EAR", NULL, "EAR PA"},
3206 {"EAR PA", NULL, "EAR_PA_MIXER"},
3207 {"EAR_PA_MIXER", NULL, "DAC1"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003208 {"DAC1", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003209
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003210 {"ANC EAR", NULL, "ANC EAR PA"},
3211 {"ANC EAR PA", NULL, "EAR_PA_MIXER"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003212 {"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
3213 {"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003214
3215 /* Headset (RX MIX1 and RX MIX2) */
3216 {"HEADPHONE", NULL, "HPHL"},
3217 {"HEADPHONE", NULL, "HPHR"},
3218
3219 {"HPHL", NULL, "HPHL_PA_MIXER"},
3220 {"HPHL_PA_MIXER", NULL, "HPHL DAC"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003221 {"HPHL DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003222
3223 {"HPHR", NULL, "HPHR_PA_MIXER"},
3224 {"HPHR_PA_MIXER", NULL, "HPHR DAC"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003225 {"HPHR DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003226
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003227 {"ANC HEADPHONE", NULL, "ANC HPHL"},
3228 {"ANC HEADPHONE", NULL, "ANC HPHR"},
3229
3230 {"ANC HPHL", NULL, "HPHL_PA_MIXER"},
3231 {"ANC HPHR", NULL, "HPHR_PA_MIXER"},
3232
Kiran Kandic3b24402012-06-11 00:05:59 -07003233 {"ANC1 MUX", "ADC1", "ADC1"},
3234 {"ANC1 MUX", "ADC2", "ADC2"},
3235 {"ANC1 MUX", "ADC3", "ADC3"},
3236 {"ANC1 MUX", "ADC4", "ADC4"},
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003237 {"ANC1 MUX", "DMIC1", "DMIC1"},
3238 {"ANC1 MUX", "DMIC2", "DMIC2"},
3239 {"ANC1 MUX", "DMIC3", "DMIC3"},
3240 {"ANC1 MUX", "DMIC4", "DMIC4"},
3241 {"ANC1 MUX", "DMIC5", "DMIC5"},
3242 {"ANC1 MUX", "DMIC6", "DMIC6"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003243 {"ANC2 MUX", "ADC1", "ADC1"},
3244 {"ANC2 MUX", "ADC2", "ADC2"},
3245 {"ANC2 MUX", "ADC3", "ADC3"},
3246 {"ANC2 MUX", "ADC4", "ADC4"},
3247
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003248 {"ANC HPHR", NULL, "CDC_CONN"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003249
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003250 {"DAC1", "Switch", "CLASS_H_DSM MUX"},
3251 {"HPHL DAC", "Switch", "CLASS_H_DSM MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003252 {"HPHR DAC", NULL, "RX2 CHAIN"},
3253
3254 {"LINEOUT1", NULL, "LINEOUT1 PA"},
3255 {"LINEOUT2", NULL, "LINEOUT2 PA"},
3256 {"LINEOUT3", NULL, "LINEOUT3 PA"},
3257 {"LINEOUT4", NULL, "LINEOUT4 PA"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003258 {"SPK_OUT", NULL, "SPK PA"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003259
3260 {"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
3261 {"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003262
Kiran Kandic3b24402012-06-11 00:05:59 -07003263 {"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
3264 {"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003265
Kiran Kandic3b24402012-06-11 00:05:59 -07003266 {"LINEOUT3 PA", NULL, "LINEOUT3_PA_MIXER"},
3267 {"LINEOUT3_PA_MIXER", NULL, "LINEOUT3 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003268
Kiran Kandic3b24402012-06-11 00:05:59 -07003269 {"LINEOUT4 PA", NULL, "LINEOUT4_PA_MIXER"},
3270 {"LINEOUT4_PA_MIXER", NULL, "LINEOUT4 DAC"},
3271
3272 {"LINEOUT1 DAC", NULL, "RX3 MIX1"},
3273
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02003274 {"RDAC5 MUX", "DEM3_INV", "RX3 MIX1"},
3275 {"RDAC5 MUX", "DEM4", "RX4 MIX1"},
3276
3277 {"LINEOUT3 DAC", NULL, "RDAC5 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003278
3279 {"LINEOUT2 DAC", NULL, "RX5 MIX1"},
3280
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02003281 {"RDAC7 MUX", "DEM5_INV", "RX5 MIX1"},
3282 {"RDAC7 MUX", "DEM6", "RX6 MIX1"},
3283
3284 {"LINEOUT4 DAC", NULL, "RDAC7 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003285
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003286 {"SPK PA", NULL, "SPK DAC"},
Kiran Kandid2b46332012-10-05 12:04:00 -07003287 {"SPK DAC", NULL, "RX7 MIX2"},
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003288 {"SPK DAC", NULL, "VDD_SPKDRV"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003289
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003290 {"CLASS_H_DSM MUX", "DSM_HPHL_RX1", "RX1 CHAIN"},
3291
Kiran Kandic3b24402012-06-11 00:05:59 -07003292 {"RX1 CHAIN", NULL, "RX1 MIX2"},
3293 {"RX2 CHAIN", NULL, "RX2 MIX2"},
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003294 {"RX1 MIX2", NULL, "ANC1 MUX"},
3295 {"RX2 MIX2", NULL, "ANC2 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003296
Kiran Kandic3b24402012-06-11 00:05:59 -07003297 {"LINEOUT1 DAC", NULL, "RX_BIAS"},
3298 {"LINEOUT2 DAC", NULL, "RX_BIAS"},
3299 {"LINEOUT3 DAC", NULL, "RX_BIAS"},
3300 {"LINEOUT4 DAC", NULL, "RX_BIAS"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003301 {"SPK DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003302
Joonwoo Parkc7731432012-10-17 12:41:44 -07003303 {"RX7 MIX1", NULL, "COMP0_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003304 {"RX1 MIX1", NULL, "COMP1_CLK"},
3305 {"RX2 MIX1", NULL, "COMP1_CLK"},
3306 {"RX3 MIX1", NULL, "COMP2_CLK"},
3307 {"RX5 MIX1", NULL, "COMP2_CLK"},
3308
Kiran Kandic3b24402012-06-11 00:05:59 -07003309 {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
3310 {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
3311 {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
3312 {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
3313 {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
3314 {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
3315 {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
3316 {"RX4 MIX1", NULL, "RX4 MIX1 INP1"},
3317 {"RX4 MIX1", NULL, "RX4 MIX1 INP2"},
3318 {"RX5 MIX1", NULL, "RX5 MIX1 INP1"},
3319 {"RX5 MIX1", NULL, "RX5 MIX1 INP2"},
3320 {"RX6 MIX1", NULL, "RX6 MIX1 INP1"},
3321 {"RX6 MIX1", NULL, "RX6 MIX1 INP2"},
3322 {"RX7 MIX1", NULL, "RX7 MIX1 INP1"},
3323 {"RX7 MIX1", NULL, "RX7 MIX1 INP2"},
3324 {"RX1 MIX2", NULL, "RX1 MIX1"},
3325 {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
3326 {"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
3327 {"RX2 MIX2", NULL, "RX2 MIX1"},
3328 {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
3329 {"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
3330 {"RX7 MIX2", NULL, "RX7 MIX1"},
3331 {"RX7 MIX2", NULL, "RX7 MIX2 INP1"},
3332 {"RX7 MIX2", NULL, "RX7 MIX2 INP2"},
3333
Kuirong Wang906ac472012-07-09 12:54:44 -07003334 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
3335 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
3336 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
3337 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
3338 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
3339 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
3340 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
3341 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
3342 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
3343 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
3344 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
3345 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
3346 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
3347 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
3348 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
3349 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
3350 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
3351 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
3352 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
3353 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
3354 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
3355 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
3356 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
3357 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
3358
3359 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
3360 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
3361 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
3362 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
3363 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
3364 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
3365 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
3366
Kiran Kandic3b24402012-06-11 00:05:59 -07003367 {"RX1 MIX1 INP1", "RX1", "SLIM RX1"},
3368 {"RX1 MIX1 INP1", "RX2", "SLIM RX2"},
3369 {"RX1 MIX1 INP1", "RX3", "SLIM RX3"},
3370 {"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
3371 {"RX1 MIX1 INP1", "RX5", "SLIM RX5"},
3372 {"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
3373 {"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
3374 {"RX1 MIX1 INP1", "IIR1", "IIR1"},
3375 {"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
3376 {"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
3377 {"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
3378 {"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
3379 {"RX1 MIX1 INP2", "RX5", "SLIM RX5"},
3380 {"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
3381 {"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
3382 {"RX1 MIX1 INP2", "IIR1", "IIR1"},
3383 {"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
3384 {"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
3385 {"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
3386 {"RX1 MIX1 INP3", "RX4", "SLIM RX4"},
3387 {"RX1 MIX1 INP3", "RX5", "SLIM RX5"},
3388 {"RX1 MIX1 INP3", "RX6", "SLIM RX6"},
3389 {"RX1 MIX1 INP3", "RX7", "SLIM RX7"},
3390 {"RX2 MIX1 INP1", "RX1", "SLIM RX1"},
3391 {"RX2 MIX1 INP1", "RX2", "SLIM RX2"},
3392 {"RX2 MIX1 INP1", "RX3", "SLIM RX3"},
3393 {"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
3394 {"RX2 MIX1 INP1", "RX5", "SLIM RX5"},
3395 {"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
3396 {"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
3397 {"RX2 MIX1 INP1", "IIR1", "IIR1"},
3398 {"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
3399 {"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
3400 {"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
3401 {"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
3402 {"RX2 MIX1 INP2", "RX5", "SLIM RX5"},
3403 {"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
3404 {"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
3405 {"RX2 MIX1 INP2", "IIR1", "IIR1"},
3406 {"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
3407 {"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
3408 {"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
3409 {"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
3410 {"RX3 MIX1 INP1", "RX5", "SLIM RX5"},
3411 {"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
3412 {"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
3413 {"RX3 MIX1 INP1", "IIR1", "IIR1"},
3414 {"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
3415 {"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
3416 {"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
3417 {"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
3418 {"RX3 MIX1 INP2", "RX5", "SLIM RX5"},
3419 {"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
3420 {"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
3421 {"RX3 MIX1 INP2", "IIR1", "IIR1"},
3422 {"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
3423 {"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
3424 {"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
3425 {"RX4 MIX1 INP1", "RX4", "SLIM RX4"},
3426 {"RX4 MIX1 INP1", "RX5", "SLIM RX5"},
3427 {"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
3428 {"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
3429 {"RX4 MIX1 INP1", "IIR1", "IIR1"},
3430 {"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
3431 {"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
3432 {"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
3433 {"RX4 MIX1 INP2", "RX5", "SLIM RX5"},
3434 {"RX4 MIX1 INP2", "RX4", "SLIM RX4"},
3435 {"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
3436 {"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
3437 {"RX4 MIX1 INP2", "IIR1", "IIR1"},
3438 {"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
3439 {"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
3440 {"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
3441 {"RX5 MIX1 INP1", "RX4", "SLIM RX4"},
3442 {"RX5 MIX1 INP1", "RX5", "SLIM RX5"},
3443 {"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
3444 {"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
3445 {"RX5 MIX1 INP1", "IIR1", "IIR1"},
3446 {"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
3447 {"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
3448 {"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
3449 {"RX5 MIX1 INP2", "RX4", "SLIM RX4"},
3450 {"RX5 MIX1 INP2", "RX5", "SLIM RX5"},
3451 {"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
3452 {"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
3453 {"RX5 MIX1 INP2", "IIR1", "IIR1"},
3454 {"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
3455 {"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
3456 {"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
3457 {"RX6 MIX1 INP1", "RX4", "SLIM RX4"},
3458 {"RX6 MIX1 INP1", "RX5", "SLIM RX5"},
3459 {"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
3460 {"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
3461 {"RX6 MIX1 INP1", "IIR1", "IIR1"},
3462 {"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
3463 {"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
3464 {"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
3465 {"RX6 MIX1 INP2", "RX4", "SLIM RX4"},
3466 {"RX6 MIX1 INP2", "RX5", "SLIM RX5"},
3467 {"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
3468 {"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
3469 {"RX6 MIX1 INP2", "IIR1", "IIR1"},
3470 {"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
3471 {"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
3472 {"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
3473 {"RX7 MIX1 INP1", "RX4", "SLIM RX4"},
3474 {"RX7 MIX1 INP1", "RX5", "SLIM RX5"},
3475 {"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
3476 {"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
3477 {"RX7 MIX1 INP1", "IIR1", "IIR1"},
3478 {"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
3479 {"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
3480 {"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
3481 {"RX7 MIX1 INP2", "RX4", "SLIM RX4"},
3482 {"RX7 MIX1 INP2", "RX5", "SLIM RX5"},
3483 {"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
3484 {"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
3485 {"RX7 MIX1 INP2", "IIR1", "IIR1"},
3486 {"RX1 MIX2 INP1", "IIR1", "IIR1"},
3487 {"RX1 MIX2 INP2", "IIR1", "IIR1"},
3488 {"RX2 MIX2 INP1", "IIR1", "IIR1"},
3489 {"RX2 MIX2 INP2", "IIR1", "IIR1"},
3490 {"RX7 MIX2 INP1", "IIR1", "IIR1"},
3491 {"RX7 MIX2 INP2", "IIR1", "IIR1"},
3492
3493 /* Decimator Inputs */
3494 {"DEC1 MUX", "DMIC1", "DMIC1"},
3495 {"DEC1 MUX", "ADC6", "ADC6"},
3496 {"DEC1 MUX", NULL, "CDC_CONN"},
3497 {"DEC2 MUX", "DMIC2", "DMIC2"},
3498 {"DEC2 MUX", "ADC5", "ADC5"},
3499 {"DEC2 MUX", NULL, "CDC_CONN"},
3500 {"DEC3 MUX", "DMIC3", "DMIC3"},
3501 {"DEC3 MUX", "ADC4", "ADC4"},
3502 {"DEC3 MUX", NULL, "CDC_CONN"},
3503 {"DEC4 MUX", "DMIC4", "DMIC4"},
3504 {"DEC4 MUX", "ADC3", "ADC3"},
3505 {"DEC4 MUX", NULL, "CDC_CONN"},
3506 {"DEC5 MUX", "DMIC5", "DMIC5"},
3507 {"DEC5 MUX", "ADC2", "ADC2"},
3508 {"DEC5 MUX", NULL, "CDC_CONN"},
3509 {"DEC6 MUX", "DMIC6", "DMIC6"},
3510 {"DEC6 MUX", "ADC1", "ADC1"},
3511 {"DEC6 MUX", NULL, "CDC_CONN"},
3512 {"DEC7 MUX", "DMIC1", "DMIC1"},
3513 {"DEC7 MUX", "DMIC6", "DMIC6"},
3514 {"DEC7 MUX", "ADC1", "ADC1"},
3515 {"DEC7 MUX", "ADC6", "ADC6"},
3516 {"DEC7 MUX", NULL, "CDC_CONN"},
3517 {"DEC8 MUX", "DMIC2", "DMIC2"},
3518 {"DEC8 MUX", "DMIC5", "DMIC5"},
3519 {"DEC8 MUX", "ADC2", "ADC2"},
3520 {"DEC8 MUX", "ADC5", "ADC5"},
3521 {"DEC8 MUX", NULL, "CDC_CONN"},
3522 {"DEC9 MUX", "DMIC4", "DMIC4"},
3523 {"DEC9 MUX", "DMIC5", "DMIC5"},
3524 {"DEC9 MUX", "ADC2", "ADC2"},
3525 {"DEC9 MUX", "ADC3", "ADC3"},
3526 {"DEC9 MUX", NULL, "CDC_CONN"},
3527 {"DEC10 MUX", "DMIC3", "DMIC3"},
3528 {"DEC10 MUX", "DMIC6", "DMIC6"},
3529 {"DEC10 MUX", "ADC1", "ADC1"},
3530 {"DEC10 MUX", "ADC4", "ADC4"},
3531 {"DEC10 MUX", NULL, "CDC_CONN"},
3532
3533 /* ADC Connections */
3534 {"ADC1", NULL, "AMIC1"},
3535 {"ADC2", NULL, "AMIC2"},
3536 {"ADC3", NULL, "AMIC3"},
3537 {"ADC4", NULL, "AMIC4"},
3538 {"ADC5", NULL, "AMIC5"},
3539 {"ADC6", NULL, "AMIC6"},
3540
3541 /* AUX PGA Connections */
Kiran Kandic3b24402012-06-11 00:05:59 -07003542 {"EAR_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07003543 {"HPHL_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
3544 {"HPHR_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
3545 {"LINEOUT1_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
3546 {"LINEOUT2_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
3547 {"LINEOUT3_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
3548 {"LINEOUT4_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003549 {"AUX_PGA_Left", NULL, "AMIC5"},
3550 {"AUX_PGA_Right", NULL, "AMIC6"},
3551
Kiran Kandic3b24402012-06-11 00:05:59 -07003552 {"IIR1", NULL, "IIR1 INP1 MUX"},
3553 {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
3554 {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
3555 {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
3556 {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
3557 {"IIR1 INP1 MUX", "DEC5", "DEC5 MUX"},
3558 {"IIR1 INP1 MUX", "DEC6", "DEC6 MUX"},
3559 {"IIR1 INP1 MUX", "DEC7", "DEC7 MUX"},
3560 {"IIR1 INP1 MUX", "DEC8", "DEC8 MUX"},
3561 {"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
3562 {"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
3563
3564 {"MIC BIAS1 Internal1", NULL, "LDO_H"},
3565 {"MIC BIAS1 Internal2", NULL, "LDO_H"},
3566 {"MIC BIAS1 External", NULL, "LDO_H"},
3567 {"MIC BIAS2 Internal1", NULL, "LDO_H"},
3568 {"MIC BIAS2 Internal2", NULL, "LDO_H"},
3569 {"MIC BIAS2 Internal3", NULL, "LDO_H"},
3570 {"MIC BIAS2 External", NULL, "LDO_H"},
3571 {"MIC BIAS3 Internal1", NULL, "LDO_H"},
3572 {"MIC BIAS3 Internal2", NULL, "LDO_H"},
3573 {"MIC BIAS3 External", NULL, "LDO_H"},
3574 {"MIC BIAS4 External", NULL, "LDO_H"},
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003575
Kiran Kandic3b24402012-06-11 00:05:59 -07003576};
3577
3578static int taiko_readable(struct snd_soc_codec *ssc, unsigned int reg)
3579{
3580 return taiko_reg_readable[reg];
3581}
3582
3583static bool taiko_is_digital_gain_register(unsigned int reg)
3584{
3585 bool rtn = false;
3586 switch (reg) {
3587 case TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL:
3588 case TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL:
3589 case TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL:
3590 case TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL:
3591 case TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL:
3592 case TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL:
3593 case TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL:
3594 case TAIKO_A_CDC_TX1_VOL_CTL_GAIN:
3595 case TAIKO_A_CDC_TX2_VOL_CTL_GAIN:
3596 case TAIKO_A_CDC_TX3_VOL_CTL_GAIN:
3597 case TAIKO_A_CDC_TX4_VOL_CTL_GAIN:
3598 case TAIKO_A_CDC_TX5_VOL_CTL_GAIN:
3599 case TAIKO_A_CDC_TX6_VOL_CTL_GAIN:
3600 case TAIKO_A_CDC_TX7_VOL_CTL_GAIN:
3601 case TAIKO_A_CDC_TX8_VOL_CTL_GAIN:
3602 case TAIKO_A_CDC_TX9_VOL_CTL_GAIN:
3603 case TAIKO_A_CDC_TX10_VOL_CTL_GAIN:
3604 rtn = true;
3605 break;
3606 default:
3607 break;
3608 }
3609 return rtn;
3610}
3611
3612static int taiko_volatile(struct snd_soc_codec *ssc, unsigned int reg)
3613{
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003614 int i;
3615
Kiran Kandic3b24402012-06-11 00:05:59 -07003616 /* Registers lower than 0x100 are top level registers which can be
3617 * written by the Taiko core driver.
3618 */
3619
3620 if ((reg >= TAIKO_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
3621 return 1;
3622
3623 /* IIR Coeff registers are not cacheable */
3624 if ((reg >= TAIKO_A_CDC_IIR1_COEF_B1_CTL) &&
3625 (reg <= TAIKO_A_CDC_IIR2_COEF_B2_CTL))
3626 return 1;
3627
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003628 /* ANC filter registers are not cacheable */
3629 if ((reg >= TAIKO_A_CDC_ANC1_IIR_B1_CTL) &&
3630 (reg <= TAIKO_A_CDC_ANC1_LPF_B2_CTL))
3631 return 1;
3632 if ((reg >= TAIKO_A_CDC_ANC2_IIR_B1_CTL) &&
3633 (reg <= TAIKO_A_CDC_ANC2_LPF_B2_CTL))
3634 return 1;
3635
Kiran Kandic3b24402012-06-11 00:05:59 -07003636 /* Digital gain register is not cacheable so we have to write
3637 * the setting even it is the same
3638 */
3639 if (taiko_is_digital_gain_register(reg))
3640 return 1;
3641
3642 /* HPH status registers */
3643 if (reg == TAIKO_A_RX_HPH_L_STATUS || reg == TAIKO_A_RX_HPH_R_STATUS)
3644 return 1;
3645
Joonwoo Parka8890262012-10-15 12:04:27 -07003646 if (reg == TAIKO_A_MBHC_INSERT_DET_STATUS)
3647 return 1;
3648
Joonwoo Park559a5bf2013-02-15 14:46:36 -08003649 switch (reg) {
3650 case TAIKO_A_CDC_SPKR_CLIPDET_VAL0:
3651 case TAIKO_A_CDC_SPKR_CLIPDET_VAL1:
3652 case TAIKO_A_CDC_SPKR_CLIPDET_VAL2:
3653 case TAIKO_A_CDC_SPKR_CLIPDET_VAL3:
3654 case TAIKO_A_CDC_SPKR_CLIPDET_VAL4:
3655 case TAIKO_A_CDC_SPKR_CLIPDET_VAL5:
3656 case TAIKO_A_CDC_SPKR_CLIPDET_VAL6:
3657 case TAIKO_A_CDC_SPKR_CLIPDET_VAL7:
3658 case TAIKO_A_CDC_VBAT_GAIN_MON_VAL:
3659 return 1;
3660 }
3661
Damir Didjustodcfdff82013-03-21 23:26:41 -07003662 for (i = 0; i < ARRAY_SIZE(audio_reg_cfg); i++)
3663 if (audio_reg_cfg[i].reg_logical_addr -
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003664 TAIKO_REGISTER_START_OFFSET == reg)
3665 return 1;
3666
Kiran Kandic3b24402012-06-11 00:05:59 -07003667 return 0;
3668}
3669
Kiran Kandic3b24402012-06-11 00:05:59 -07003670static int taiko_write(struct snd_soc_codec *codec, unsigned int reg,
3671 unsigned int value)
3672{
3673 int ret;
Kuirong Wang906ac472012-07-09 12:54:44 -07003674
3675 if (reg == SND_SOC_NOPM)
3676 return 0;
3677
Kiran Kandic3b24402012-06-11 00:05:59 -07003678 BUG_ON(reg > TAIKO_MAX_REGISTER);
3679
3680 if (!taiko_volatile(codec, reg)) {
3681 ret = snd_soc_cache_write(codec, reg, value);
3682 if (ret != 0)
3683 dev_err(codec->dev, "Cache write to %x failed: %d\n",
3684 reg, ret);
3685 }
3686
3687 return wcd9xxx_reg_write(codec->control_data, reg, value);
3688}
3689static unsigned int taiko_read(struct snd_soc_codec *codec,
3690 unsigned int reg)
3691{
3692 unsigned int val;
3693 int ret;
3694
Kuirong Wang906ac472012-07-09 12:54:44 -07003695 if (reg == SND_SOC_NOPM)
3696 return 0;
3697
Kiran Kandic3b24402012-06-11 00:05:59 -07003698 BUG_ON(reg > TAIKO_MAX_REGISTER);
3699
3700 if (!taiko_volatile(codec, reg) && taiko_readable(codec, reg) &&
3701 reg < codec->driver->reg_cache_size) {
3702 ret = snd_soc_cache_read(codec, reg, &val);
3703 if (ret >= 0) {
3704 return val;
3705 } else
3706 dev_err(codec->dev, "Cache read from %x failed: %d\n",
3707 reg, ret);
3708 }
3709
3710 val = wcd9xxx_reg_read(codec->control_data, reg);
3711 return val;
3712}
3713
Kiran Kandic3b24402012-06-11 00:05:59 -07003714static int taiko_startup(struct snd_pcm_substream *substream,
3715 struct snd_soc_dai *dai)
3716{
3717 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
3718 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
3719 substream->name, substream->stream);
3720 if ((taiko_core != NULL) &&
3721 (taiko_core->dev != NULL) &&
3722 (taiko_core->dev->parent != NULL))
3723 pm_runtime_get_sync(taiko_core->dev->parent);
3724
3725 return 0;
3726}
3727
3728static void taiko_shutdown(struct snd_pcm_substream *substream,
3729 struct snd_soc_dai *dai)
3730{
3731 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
3732 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
3733 substream->name, substream->stream);
3734 if ((taiko_core != NULL) &&
3735 (taiko_core->dev != NULL) &&
3736 (taiko_core->dev->parent != NULL)) {
3737 pm_runtime_mark_last_busy(taiko_core->dev->parent);
3738 pm_runtime_put(taiko_core->dev->parent);
3739 }
3740}
3741
3742int taiko_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm)
3743{
3744 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3745
3746 pr_debug("%s: mclk_enable = %u, dapm = %d\n", __func__, mclk_enable,
3747 dapm);
Joonwoo Parka8890262012-10-15 12:04:27 -07003748
3749 WCD9XXX_BCL_LOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07003750 if (mclk_enable) {
Joonwoo Parka8890262012-10-15 12:04:27 -07003751 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
3752 WCD9XXX_BANDGAP_AUDIO_MODE);
3753 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
Kiran Kandic3b24402012-06-11 00:05:59 -07003754 } else {
Joonwoo Parka8890262012-10-15 12:04:27 -07003755 /* Put clock and BG */
3756 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
3757 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
3758 WCD9XXX_BANDGAP_AUDIO_MODE);
Kiran Kandic3b24402012-06-11 00:05:59 -07003759 }
Joonwoo Parka8890262012-10-15 12:04:27 -07003760 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
3761
Kiran Kandic3b24402012-06-11 00:05:59 -07003762 return 0;
3763}
3764
3765static int taiko_set_dai_sysclk(struct snd_soc_dai *dai,
3766 int clk_id, unsigned int freq, int dir)
3767{
Venkat Sudhira50a3762012-11-26 12:12:15 -08003768 pr_debug("%s\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07003769 return 0;
3770}
3771
3772static int taiko_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3773{
3774 u8 val = 0;
3775 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
3776
3777 pr_debug("%s\n", __func__);
3778 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3779 case SND_SOC_DAIFMT_CBS_CFS:
3780 /* CPU is master */
3781 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3782 if (dai->id == AIF1_CAP)
3783 snd_soc_update_bits(dai->codec,
3784 TAIKO_A_CDC_CLK_TX_I2S_CTL,
3785 TAIKO_I2S_MASTER_MODE_MASK, 0);
3786 else if (dai->id == AIF1_PB)
3787 snd_soc_update_bits(dai->codec,
3788 TAIKO_A_CDC_CLK_RX_I2S_CTL,
3789 TAIKO_I2S_MASTER_MODE_MASK, 0);
3790 }
3791 break;
3792 case SND_SOC_DAIFMT_CBM_CFM:
3793 /* CPU is slave */
3794 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3795 val = TAIKO_I2S_MASTER_MODE_MASK;
3796 if (dai->id == AIF1_CAP)
3797 snd_soc_update_bits(dai->codec,
3798 TAIKO_A_CDC_CLK_TX_I2S_CTL, val, val);
3799 else if (dai->id == AIF1_PB)
3800 snd_soc_update_bits(dai->codec,
3801 TAIKO_A_CDC_CLK_RX_I2S_CTL, val, val);
3802 }
3803 break;
3804 default:
3805 return -EINVAL;
3806 }
3807 return 0;
3808}
3809
3810static int taiko_set_channel_map(struct snd_soc_dai *dai,
3811 unsigned int tx_num, unsigned int *tx_slot,
3812 unsigned int rx_num, unsigned int *rx_slot)
3813
3814{
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003815 struct wcd9xxx_codec_dai_data *dai_data = NULL;
Kiran Kandic3b24402012-06-11 00:05:59 -07003816 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07003817 struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07003818 if (!tx_slot && !rx_slot) {
3819 pr_err("%s: Invalid\n", __func__);
3820 return -EINVAL;
3821 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003822 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
3823 "taiko->intf_type %d\n",
3824 __func__, dai->name, dai->id, tx_num, rx_num,
3825 taiko->intf_type);
Kiran Kandic3b24402012-06-11 00:05:59 -07003826
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003827 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Kuirong Wang906ac472012-07-09 12:54:44 -07003828 wcd9xxx_init_slimslave(core, core->slim->laddr,
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003829 tx_num, tx_slot, rx_num, rx_slot);
3830 /*Reserve tx11 and tx12 for VI feedback path*/
3831 dai_data = &taiko->dai[AIF4_VIFEED];
3832 if (dai_data) {
3833 list_add_tail(&core->tx_chs[TAIKO_TX11].list,
3834 &dai_data->wcd9xxx_ch_list);
3835 list_add_tail(&core->tx_chs[TAIKO_TX12].list,
3836 &dai_data->wcd9xxx_ch_list);
3837 }
3838 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003839 return 0;
3840}
3841
3842static int taiko_get_channel_map(struct snd_soc_dai *dai,
3843 unsigned int *tx_num, unsigned int *tx_slot,
3844 unsigned int *rx_num, unsigned int *rx_slot)
3845
3846{
3847 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(dai->codec);
3848 u32 i = 0;
3849 struct wcd9xxx_ch *ch;
3850
3851 switch (dai->id) {
3852 case AIF1_PB:
3853 case AIF2_PB:
3854 case AIF3_PB:
3855 if (!rx_slot || !rx_num) {
3856 pr_err("%s: Invalid rx_slot %d or rx_num %d\n",
3857 __func__, (u32) rx_slot, (u32) rx_num);
3858 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07003859 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003860 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
3861 list) {
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05003862 pr_debug("%s: slot_num %u ch->ch_num %d\n",
3863 __func__, i, ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07003864 rx_slot[i++] = ch->ch_num;
3865 }
3866 pr_debug("%s: rx_num %d\n", __func__, i);
3867 *rx_num = i;
3868 break;
3869 case AIF1_CAP:
3870 case AIF2_CAP:
3871 case AIF3_CAP:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003872 case AIF4_VIFEED:
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003873 case AIF4_MAD_TX:
Kuirong Wang906ac472012-07-09 12:54:44 -07003874 if (!tx_slot || !tx_num) {
3875 pr_err("%s: Invalid tx_slot %d or tx_num %d\n",
3876 __func__, (u32) tx_slot, (u32) tx_num);
3877 return -EINVAL;
3878 }
3879 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
3880 list) {
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05003881 pr_debug("%s: slot_num %u ch->ch_num %d\n",
3882 __func__, i, ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07003883 tx_slot[i++] = ch->ch_num;
3884 }
3885 pr_debug("%s: tx_num %d\n", __func__, i);
3886 *tx_num = i;
3887 break;
3888
3889 default:
3890 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
3891 break;
3892 }
3893
3894 return 0;
3895}
3896
3897static int taiko_set_interpolator_rate(struct snd_soc_dai *dai,
3898 u8 rx_fs_rate_reg_val, u32 compander_fs, u32 sample_rate)
3899{
3900 u32 j;
3901 u8 rx_mix1_inp;
3902 u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
3903 u16 rx_fs_reg;
3904 u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
3905 struct snd_soc_codec *codec = dai->codec;
3906 struct wcd9xxx_ch *ch;
3907 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3908
3909 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
3910 /* for RX port starting from 16 instead of 10 like tabla */
3911 rx_mix1_inp = ch->port + RX_MIX1_INP_SEL_RX1 -
3912 TAIKO_TX_PORT_NUMBER;
3913 if ((rx_mix1_inp < RX_MIX1_INP_SEL_RX1) ||
3914 (rx_mix1_inp > RX_MIX1_INP_SEL_RX7)) {
3915 pr_err("%s: Invalid TAIKO_RX%u port. Dai ID is %d\n",
3916 __func__, rx_mix1_inp - 5 , dai->id);
3917 return -EINVAL;
3918 }
3919
3920 rx_mix_1_reg_1 = TAIKO_A_CDC_CONN_RX1_B1_CTL;
3921
3922 for (j = 0; j < NUM_INTERPOLATORS; j++) {
3923 rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
3924
3925 rx_mix_1_reg_1_val = snd_soc_read(codec,
3926 rx_mix_1_reg_1);
3927 rx_mix_1_reg_2_val = snd_soc_read(codec,
3928 rx_mix_1_reg_2);
3929
3930 if (((rx_mix_1_reg_1_val & 0x0F) == rx_mix1_inp) ||
3931 (((rx_mix_1_reg_1_val >> 4) & 0x0F)
3932 == rx_mix1_inp) ||
3933 ((rx_mix_1_reg_2_val & 0x0F) == rx_mix1_inp)) {
3934
3935 rx_fs_reg = TAIKO_A_CDC_RX1_B5_CTL + 8 * j;
3936
3937 pr_debug("%s: AIF_PB DAI(%d) connected to RX%u\n",
3938 __func__, dai->id, j + 1);
3939
3940 pr_debug("%s: set RX%u sample rate to %u\n",
3941 __func__, j + 1, sample_rate);
3942
3943 snd_soc_update_bits(codec, rx_fs_reg,
3944 0xE0, rx_fs_rate_reg_val);
3945
3946 if (comp_rx_path[j] < COMPANDER_MAX)
3947 taiko->comp_fs[comp_rx_path[j]]
3948 = compander_fs;
3949 }
Kuirong Wang94761952013-03-07 16:19:35 -08003950 if (j < 2)
Kuirong Wang906ac472012-07-09 12:54:44 -07003951 rx_mix_1_reg_1 += 3;
3952 else
3953 rx_mix_1_reg_1 += 2;
Kiran Kandic3b24402012-06-11 00:05:59 -07003954 }
3955 }
3956 return 0;
3957}
3958
Kuirong Wang906ac472012-07-09 12:54:44 -07003959static int taiko_set_decimator_rate(struct snd_soc_dai *dai,
3960 u8 tx_fs_rate_reg_val, u32 sample_rate)
Kiran Kandic3b24402012-06-11 00:05:59 -07003961{
Kuirong Wang906ac472012-07-09 12:54:44 -07003962 struct snd_soc_codec *codec = dai->codec;
3963 struct wcd9xxx_ch *ch;
3964 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3965 u32 tx_port;
3966 u16 tx_port_reg, tx_fs_reg;
3967 u8 tx_port_reg_val;
3968 s8 decimator;
Kiran Kandic3b24402012-06-11 00:05:59 -07003969
Kuirong Wang906ac472012-07-09 12:54:44 -07003970 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
Kiran Kandic3b24402012-06-11 00:05:59 -07003971
Kuirong Wang906ac472012-07-09 12:54:44 -07003972 tx_port = ch->port + 1;
3973 pr_debug("%s: dai->id = %d, tx_port = %d",
3974 __func__, dai->id, tx_port);
3975
3976 if ((tx_port < 1) || (tx_port > NUM_DECIMATORS)) {
3977 pr_err("%s: Invalid SLIM TX%u port. DAI ID is %d\n",
3978 __func__, tx_port, dai->id);
3979 return -EINVAL;
3980 }
3981
3982 tx_port_reg = TAIKO_A_CDC_CONN_TX_SB_B1_CTL + (tx_port - 1);
3983 tx_port_reg_val = snd_soc_read(codec, tx_port_reg);
3984
3985 decimator = 0;
3986
3987 if ((tx_port >= 1) && (tx_port <= 6)) {
3988
3989 tx_port_reg_val = tx_port_reg_val & 0x0F;
3990 if (tx_port_reg_val == 0x8)
3991 decimator = tx_port;
3992
3993 } else if ((tx_port >= 7) && (tx_port <= NUM_DECIMATORS)) {
3994
3995 tx_port_reg_val = tx_port_reg_val & 0x1F;
3996
3997 if ((tx_port_reg_val >= 0x8) &&
3998 (tx_port_reg_val <= 0x11)) {
3999
4000 decimator = (tx_port_reg_val - 0x8) + 1;
4001 }
4002 }
4003
4004 if (decimator) { /* SLIM_TX port has a DEC as input */
4005
4006 tx_fs_reg = TAIKO_A_CDC_TX1_CLK_FS_CTL +
4007 8 * (decimator - 1);
4008
4009 pr_debug("%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
4010 __func__, decimator, tx_port, sample_rate);
4011
4012 snd_soc_update_bits(codec, tx_fs_reg, 0x07,
4013 tx_fs_rate_reg_val);
4014
4015 } else {
4016 if ((tx_port_reg_val >= 0x1) &&
4017 (tx_port_reg_val <= 0x7)) {
4018
4019 pr_debug("%s: RMIX%u going to SLIM TX%u\n",
4020 __func__, tx_port_reg_val, tx_port);
4021
4022 } else if ((tx_port_reg_val >= 0x8) &&
4023 (tx_port_reg_val <= 0x11)) {
4024
4025 pr_err("%s: ERROR: Should not be here\n",
4026 __func__);
4027 pr_err("%s: ERROR: DEC connected to SLIM TX%u\n",
4028 __func__, tx_port);
4029 return -EINVAL;
4030
4031 } else if (tx_port_reg_val == 0) {
4032 pr_debug("%s: no signal to SLIM TX%u\n",
4033 __func__, tx_port);
4034 } else {
4035 pr_err("%s: ERROR: wrong signal to SLIM TX%u\n",
4036 __func__, tx_port);
4037 pr_err("%s: ERROR: wrong signal = %u\n",
4038 __func__, tx_port_reg_val);
4039 return -EINVAL;
4040 }
4041 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004042 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004043 return 0;
4044}
4045
4046static int taiko_hw_params(struct snd_pcm_substream *substream,
4047 struct snd_pcm_hw_params *params,
4048 struct snd_soc_dai *dai)
4049{
4050 struct snd_soc_codec *codec = dai->codec;
4051 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07004052 u8 tx_fs_rate, rx_fs_rate;
Kiran Kandic3b24402012-06-11 00:05:59 -07004053 u32 compander_fs;
Kuirong Wang906ac472012-07-09 12:54:44 -07004054 int ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07004055
4056 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
4057 dai->name, dai->id, params_rate(params),
4058 params_channels(params));
4059
4060 switch (params_rate(params)) {
4061 case 8000:
4062 tx_fs_rate = 0x00;
4063 rx_fs_rate = 0x00;
4064 compander_fs = COMPANDER_FS_8KHZ;
4065 break;
4066 case 16000:
4067 tx_fs_rate = 0x01;
4068 rx_fs_rate = 0x20;
4069 compander_fs = COMPANDER_FS_16KHZ;
4070 break;
4071 case 32000:
4072 tx_fs_rate = 0x02;
4073 rx_fs_rate = 0x40;
4074 compander_fs = COMPANDER_FS_32KHZ;
4075 break;
4076 case 48000:
4077 tx_fs_rate = 0x03;
4078 rx_fs_rate = 0x60;
4079 compander_fs = COMPANDER_FS_48KHZ;
4080 break;
4081 case 96000:
4082 tx_fs_rate = 0x04;
4083 rx_fs_rate = 0x80;
4084 compander_fs = COMPANDER_FS_96KHZ;
4085 break;
4086 case 192000:
4087 tx_fs_rate = 0x05;
4088 rx_fs_rate = 0xA0;
4089 compander_fs = COMPANDER_FS_192KHZ;
4090 break;
4091 default:
4092 pr_err("%s: Invalid sampling rate %d\n", __func__,
Kuirong Wang906ac472012-07-09 12:54:44 -07004093 params_rate(params));
Kiran Kandic3b24402012-06-11 00:05:59 -07004094 return -EINVAL;
4095 }
4096
Kuirong Wang906ac472012-07-09 12:54:44 -07004097 switch (substream->stream) {
4098 case SNDRV_PCM_STREAM_CAPTURE:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004099 if (dai->id != AIF4_VIFEED) {
4100 ret = taiko_set_decimator_rate(dai, tx_fs_rate,
4101 params_rate(params));
4102 if (ret < 0) {
4103 pr_err("%s: set decimator rate failed %d\n",
4104 __func__, ret);
4105 return ret;
4106 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004107 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004108
Kiran Kandic3b24402012-06-11 00:05:59 -07004109 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4110 switch (params_format(params)) {
4111 case SNDRV_PCM_FORMAT_S16_LE:
4112 snd_soc_update_bits(codec,
4113 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4114 0x20, 0x20);
4115 break;
4116 case SNDRV_PCM_FORMAT_S32_LE:
4117 snd_soc_update_bits(codec,
4118 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4119 0x20, 0x00);
4120 break;
4121 default:
4122 pr_err("invalid format\n");
4123 break;
4124 }
4125 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07004126 0x07, tx_fs_rate);
Kiran Kandic3b24402012-06-11 00:05:59 -07004127 } else {
Kuirong Wang906ac472012-07-09 12:54:44 -07004128 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07004129 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004130 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07004131
Kuirong Wang906ac472012-07-09 12:54:44 -07004132 case SNDRV_PCM_STREAM_PLAYBACK:
4133 ret = taiko_set_interpolator_rate(dai, rx_fs_rate,
4134 compander_fs,
4135 params_rate(params));
4136 if (ret < 0) {
4137 pr_err("%s: set decimator rate failed %d\n", __func__,
4138 ret);
4139 return ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07004140 }
4141 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4142 switch (params_format(params)) {
4143 case SNDRV_PCM_FORMAT_S16_LE:
4144 snd_soc_update_bits(codec,
4145 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4146 0x20, 0x20);
4147 break;
4148 case SNDRV_PCM_FORMAT_S32_LE:
4149 snd_soc_update_bits(codec,
4150 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4151 0x20, 0x00);
4152 break;
4153 default:
4154 pr_err("invalid format\n");
4155 break;
4156 }
4157 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07004158 0x03, (rx_fs_rate >> 0x05));
Kiran Kandic3b24402012-06-11 00:05:59 -07004159 } else {
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004160 switch (params_format(params)) {
4161 case SNDRV_PCM_FORMAT_S16_LE:
4162 snd_soc_update_bits(codec,
4163 TAIKO_A_CDC_CONN_RX_SB_B1_CTL,
4164 0xFF, 0xAA);
4165 snd_soc_update_bits(codec,
4166 TAIKO_A_CDC_CONN_RX_SB_B2_CTL,
4167 0xFF, 0x2A);
4168 taiko->dai[dai->id].bit_width = 16;
4169 break;
4170 case SNDRV_PCM_FORMAT_S24_LE:
4171 snd_soc_update_bits(codec,
4172 TAIKO_A_CDC_CONN_RX_SB_B1_CTL,
4173 0xFF, 0x00);
4174 snd_soc_update_bits(codec,
4175 TAIKO_A_CDC_CONN_RX_SB_B2_CTL,
4176 0xFF, 0x00);
4177 taiko->dai[dai->id].bit_width = 24;
4178 break;
4179 default:
4180 dev_err(codec->dev, "Invalid format\n");
4181 break;
4182 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004183 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07004184 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004185 break;
4186 default:
4187 pr_err("%s: Invalid stream type %d\n", __func__,
4188 substream->stream);
4189 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004190 }
4191
4192 return 0;
4193}
4194
4195static struct snd_soc_dai_ops taiko_dai_ops = {
4196 .startup = taiko_startup,
4197 .shutdown = taiko_shutdown,
4198 .hw_params = taiko_hw_params,
4199 .set_sysclk = taiko_set_dai_sysclk,
4200 .set_fmt = taiko_set_dai_fmt,
4201 .set_channel_map = taiko_set_channel_map,
4202 .get_channel_map = taiko_get_channel_map,
4203};
4204
4205static struct snd_soc_dai_driver taiko_dai[] = {
4206 {
4207 .name = "taiko_rx1",
4208 .id = AIF1_PB,
4209 .playback = {
4210 .stream_name = "AIF1 Playback",
4211 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004212 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004213 .rate_max = 192000,
4214 .rate_min = 8000,
4215 .channels_min = 1,
4216 .channels_max = 2,
4217 },
4218 .ops = &taiko_dai_ops,
4219 },
4220 {
4221 .name = "taiko_tx1",
4222 .id = AIF1_CAP,
4223 .capture = {
4224 .stream_name = "AIF1 Capture",
4225 .rates = WCD9320_RATES,
4226 .formats = TAIKO_FORMATS,
4227 .rate_max = 192000,
4228 .rate_min = 8000,
4229 .channels_min = 1,
4230 .channels_max = 4,
4231 },
4232 .ops = &taiko_dai_ops,
4233 },
4234 {
4235 .name = "taiko_rx2",
4236 .id = AIF2_PB,
4237 .playback = {
4238 .stream_name = "AIF2 Playback",
4239 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004240 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004241 .rate_min = 8000,
4242 .rate_max = 192000,
4243 .channels_min = 1,
4244 .channels_max = 2,
4245 },
4246 .ops = &taiko_dai_ops,
4247 },
4248 {
4249 .name = "taiko_tx2",
4250 .id = AIF2_CAP,
4251 .capture = {
4252 .stream_name = "AIF2 Capture",
4253 .rates = WCD9320_RATES,
4254 .formats = TAIKO_FORMATS,
4255 .rate_max = 192000,
4256 .rate_min = 8000,
4257 .channels_min = 1,
4258 .channels_max = 4,
4259 },
4260 .ops = &taiko_dai_ops,
4261 },
4262 {
4263 .name = "taiko_tx3",
4264 .id = AIF3_CAP,
4265 .capture = {
4266 .stream_name = "AIF3 Capture",
4267 .rates = WCD9320_RATES,
4268 .formats = TAIKO_FORMATS,
4269 .rate_max = 48000,
4270 .rate_min = 8000,
4271 .channels_min = 1,
4272 .channels_max = 2,
4273 },
4274 .ops = &taiko_dai_ops,
4275 },
4276 {
4277 .name = "taiko_rx3",
4278 .id = AIF3_PB,
4279 .playback = {
4280 .stream_name = "AIF3 Playback",
4281 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004282 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004283 .rate_min = 8000,
4284 .rate_max = 192000,
4285 .channels_min = 1,
4286 .channels_max = 2,
4287 },
4288 .ops = &taiko_dai_ops,
4289 },
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004290 {
4291 .name = "taiko_vifeedback",
4292 .id = AIF4_VIFEED,
4293 .capture = {
4294 .stream_name = "VIfeed",
4295 .rates = SNDRV_PCM_RATE_48000,
4296 .formats = TAIKO_FORMATS,
4297 .rate_max = 48000,
4298 .rate_min = 48000,
4299 .channels_min = 2,
4300 .channels_max = 2,
4301 },
4302 .ops = &taiko_dai_ops,
4303 },
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004304 {
4305 .name = "taiko_mad1",
4306 .id = AIF4_MAD_TX,
4307 .capture = {
4308 .stream_name = "AIF4 MAD TX",
4309 .rates = SNDRV_PCM_RATE_16000,
4310 .formats = TAIKO_FORMATS,
4311 .rate_min = 16000,
4312 .rate_max = 16000,
4313 .channels_min = 1,
4314 .channels_max = 1,
4315 },
4316 .ops = &taiko_dai_ops,
4317 },
Kiran Kandic3b24402012-06-11 00:05:59 -07004318};
4319
4320static struct snd_soc_dai_driver taiko_i2s_dai[] = {
4321 {
4322 .name = "taiko_i2s_rx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07004323 .id = AIF1_PB,
Kiran Kandic3b24402012-06-11 00:05:59 -07004324 .playback = {
4325 .stream_name = "AIF1 Playback",
4326 .rates = WCD9320_RATES,
4327 .formats = TAIKO_FORMATS,
4328 .rate_max = 192000,
4329 .rate_min = 8000,
4330 .channels_min = 1,
4331 .channels_max = 4,
4332 },
4333 .ops = &taiko_dai_ops,
4334 },
4335 {
4336 .name = "taiko_i2s_tx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07004337 .id = AIF1_CAP,
Kiran Kandic3b24402012-06-11 00:05:59 -07004338 .capture = {
4339 .stream_name = "AIF1 Capture",
4340 .rates = WCD9320_RATES,
4341 .formats = TAIKO_FORMATS,
4342 .rate_max = 192000,
4343 .rate_min = 8000,
4344 .channels_min = 1,
4345 .channels_max = 4,
4346 },
4347 .ops = &taiko_dai_ops,
4348 },
Venkat Sudhir994193b2012-12-17 17:30:51 -08004349 {
4350 .name = "taiko_i2s_rx2",
4351 .id = AIF1_PB,
4352 .playback = {
4353 .stream_name = "AIF2 Playback",
4354 .rates = WCD9320_RATES,
4355 .formats = TAIKO_FORMATS,
4356 .rate_max = 192000,
4357 .rate_min = 8000,
4358 .channels_min = 1,
4359 .channels_max = 4,
4360 },
4361 .ops = &taiko_dai_ops,
4362 },
4363 {
4364 .name = "taiko_i2s_tx2",
4365 .id = AIF1_CAP,
4366 .capture = {
4367 .stream_name = "AIF2 Capture",
4368 .rates = WCD9320_RATES,
4369 .formats = TAIKO_FORMATS,
4370 .rate_max = 192000,
4371 .rate_min = 8000,
4372 .channels_min = 1,
4373 .channels_max = 4,
4374 },
4375 .ops = &taiko_dai_ops,
4376 },
Kiran Kandic3b24402012-06-11 00:05:59 -07004377};
4378
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004379static int taiko_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
4380 bool up)
4381{
4382 int ret = 0;
4383 struct wcd9xxx_ch *ch;
4384
4385 if (up) {
4386 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
4387 ret = wcd9xxx_get_slave_port(ch->ch_num);
4388 if (ret < 0) {
4389 pr_err("%s: Invalid slave port ID: %d\n",
4390 __func__, ret);
4391 ret = -EINVAL;
4392 } else {
4393 set_bit(ret, &dai->ch_mask);
4394 }
4395 }
4396 } else {
4397 ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
4398 msecs_to_jiffies(
4399 TAIKO_SLIM_CLOSE_TIMEOUT));
4400 if (!ret) {
4401 pr_err("%s: Slim close tx/rx wait timeout\n", __func__);
4402 ret = -ETIMEDOUT;
4403 } else {
4404 ret = 0;
4405 }
4406 }
4407 return ret;
4408}
4409
Kiran Kandic3b24402012-06-11 00:05:59 -07004410static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07004411 struct snd_kcontrol *kcontrol,
4412 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07004413{
Kuirong Wang906ac472012-07-09 12:54:44 -07004414 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07004415 struct snd_soc_codec *codec = w->codec;
4416 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004417 int ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07004418 struct wcd9xxx_codec_dai_data *dai;
4419
4420 core = dev_get_drvdata(codec->dev->parent);
4421
4422 pr_debug("%s: event called! codec name %s num_dai %d\n"
4423 "stream name %s event %d\n",
4424 __func__, w->codec->name, w->codec->num_dai, w->sname, event);
4425
Kiran Kandic3b24402012-06-11 00:05:59 -07004426 /* Execute the callback only if interface type is slimbus */
4427 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
4428 return 0;
4429
Kuirong Wang906ac472012-07-09 12:54:44 -07004430 dai = &taiko_p->dai[w->shift];
4431 pr_debug("%s: w->name %s w->shift %d event %d\n",
4432 __func__, w->name, w->shift, event);
Kiran Kandic3b24402012-06-11 00:05:59 -07004433
4434 switch (event) {
4435 case SND_SOC_DAPM_POST_PMU:
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004436 (void) taiko_codec_enable_slim_chmask(dai, true);
Kuirong Wang906ac472012-07-09 12:54:44 -07004437 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
4438 dai->rate, dai->bit_width,
4439 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07004440 break;
4441 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07004442 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
4443 dai->grph);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004444 ret = taiko_codec_enable_slim_chmask(dai, false);
4445 if (ret < 0) {
4446 ret = wcd9xxx_disconnect_port(core,
4447 &dai->wcd9xxx_ch_list,
4448 dai->grph);
4449 pr_debug("%s: Disconnect RX port, ret = %d\n",
4450 __func__, ret);
4451 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004452 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07004453 }
4454 return ret;
4455}
4456
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004457static int taiko_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
4458 struct snd_kcontrol *kcontrol,
4459 int event)
4460{
4461 struct wcd9xxx *core = NULL;
4462 struct snd_soc_codec *codec = NULL;
4463 struct taiko_priv *taiko_p = NULL;
4464 u32 ret = 0;
4465 struct wcd9xxx_codec_dai_data *dai = NULL;
4466
4467 if (!w || !w->codec) {
4468 pr_err("%s invalid params\n", __func__);
4469 return -EINVAL;
4470 }
4471 codec = w->codec;
4472 taiko_p = snd_soc_codec_get_drvdata(codec);
4473 core = dev_get_drvdata(codec->dev->parent);
4474
4475 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
4476 __func__, w->codec->name, w->codec->num_dai, w->sname);
4477
4478 /* Execute the callback only if interface type is slimbus */
4479 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
4480 pr_err("%s Interface is not correct", __func__);
4481 return 0;
4482 }
4483
4484 pr_debug("%s(): w->name %s event %d w->shift %d\n",
4485 __func__, w->name, event, w->shift);
4486 if (w->shift != AIF4_VIFEED) {
4487 pr_err("%s Error in enabling the tx path\n", __func__);
4488 ret = -EINVAL;
4489 goto out_vi;
4490 }
4491 dai = &taiko_p->dai[w->shift];
4492 switch (event) {
4493 case SND_SOC_DAPM_POST_PMU:
4494 /*Enable Clip Detection*/
4495 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_CLIP_DET,
4496 0x8, 0x8);
4497 /*Enable V&I sensing*/
4498 snd_soc_update_bits(codec, TAIKO_A_SPKR_PROT_EN,
4499 0x88, 0x88);
4500 /*Enable spkr VI clocks*/
4501 snd_soc_update_bits(codec,
4502 TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0xC, 0xC);
4503 /*Enable Voltage Decimator*/
4504 snd_soc_update_bits(codec,
4505 TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x1F, 0x12);
4506 /*Enable Current Decimator*/
4507 snd_soc_update_bits(codec,
4508 TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x1F, 0x13);
4509 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
4510 dai->rate, dai->bit_width,
4511 &dai->grph);
4512 break;
4513 case SND_SOC_DAPM_POST_PMD:
4514 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
4515 dai->grph);
4516 if (ret)
4517 pr_err("%s error in close_slim_sch_tx %d\n",
4518 __func__, ret);
4519 /*Disable Voltage decimator*/
4520 snd_soc_update_bits(codec,
4521 TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x1F, 0x0);
4522 /*Disable Current decimator*/
4523 snd_soc_update_bits(codec,
4524 TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x1F, 0x0);
4525 /*Disable spkr VI clocks*/
4526 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL,
4527 0xC, 0x0);
4528 /*Disable V&I sensing*/
4529 snd_soc_update_bits(codec, TAIKO_A_SPKR_PROT_EN,
4530 0x88, 0x00);
4531 /*Disable clip detection*/
4532 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_CLIP_DET,
4533 0x8, 0x0);
4534 break;
4535 }
4536out_vi:
4537 return ret;
4538}
4539
Kiran Kandic3b24402012-06-11 00:05:59 -07004540static int taiko_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07004541 struct snd_kcontrol *kcontrol,
4542 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07004543{
Kuirong Wang906ac472012-07-09 12:54:44 -07004544 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07004545 struct snd_soc_codec *codec = w->codec;
4546 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07004547 u32 ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07004548 struct wcd9xxx_codec_dai_data *dai;
Kiran Kandic3b24402012-06-11 00:05:59 -07004549
Kuirong Wang906ac472012-07-09 12:54:44 -07004550 core = dev_get_drvdata(codec->dev->parent);
4551
4552 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
4553 __func__, w->codec->name, w->codec->num_dai, w->sname);
Kiran Kandic3b24402012-06-11 00:05:59 -07004554
4555 /* Execute the callback only if interface type is slimbus */
4556 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
4557 return 0;
4558
Kuirong Wang906ac472012-07-09 12:54:44 -07004559 pr_debug("%s(): w->name %s event %d w->shift %d\n",
4560 __func__, w->name, event, w->shift);
Kiran Kandic3b24402012-06-11 00:05:59 -07004561
Kuirong Wang906ac472012-07-09 12:54:44 -07004562 dai = &taiko_p->dai[w->shift];
Kiran Kandic3b24402012-06-11 00:05:59 -07004563 switch (event) {
4564 case SND_SOC_DAPM_POST_PMU:
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004565 (void) taiko_codec_enable_slim_chmask(dai, true);
Kuirong Wang906ac472012-07-09 12:54:44 -07004566 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
4567 dai->rate, dai->bit_width,
4568 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07004569 break;
4570 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07004571 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
4572 dai->grph);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004573 ret = taiko_codec_enable_slim_chmask(dai, false);
4574 if (ret < 0) {
4575 ret = wcd9xxx_disconnect_port(core,
4576 &dai->wcd9xxx_ch_list,
4577 dai->grph);
4578 pr_debug("%s: Disconnect RX port, ret = %d\n",
4579 __func__, ret);
4580 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004581 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07004582 }
4583 return ret;
4584}
4585
Kiran Kandi4c56c592012-07-25 11:04:55 -07004586static int taiko_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
4587 struct snd_kcontrol *kcontrol, int event)
4588{
4589 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004590 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandi4c56c592012-07-25 11:04:55 -07004591
4592 pr_debug("%s %s %d\n", __func__, w->name, event);
4593
4594 switch (event) {
Kiran Kandi4c56c592012-07-25 11:04:55 -07004595 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004596 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
4597 WCD9XXX_CLSH_STATE_EAR,
4598 WCD9XXX_CLSH_REQ_ENABLE,
4599 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandi4c56c592012-07-25 11:04:55 -07004600
4601 usleep_range(5000, 5000);
4602 break;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004603 case SND_SOC_DAPM_POST_PMD:
4604 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
4605 WCD9XXX_CLSH_STATE_EAR,
4606 WCD9XXX_CLSH_REQ_DISABLE,
4607 WCD9XXX_CLSH_EVENT_POST_PA);
4608 usleep_range(5000, 5000);
4609 }
4610 return 0;
4611}
4612
4613static int taiko_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
4614 struct snd_kcontrol *kcontrol, int event)
4615{
4616 struct snd_soc_codec *codec = w->codec;
4617 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
4618
4619 pr_debug("%s %s %d\n", __func__, w->name, event);
4620
4621 switch (event) {
4622 case SND_SOC_DAPM_PRE_PMU:
4623 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
4624 WCD9XXX_CLSH_STATE_EAR,
4625 WCD9XXX_CLSH_REQ_ENABLE,
4626 WCD9XXX_CLSH_EVENT_PRE_DAC);
4627 break;
4628 }
4629
4630 return 0;
4631}
4632
4633static int taiko_codec_dsm_mux_event(struct snd_soc_dapm_widget *w,
4634 struct snd_kcontrol *kcontrol, int event)
4635{
4636 struct snd_soc_codec *codec = w->codec;
4637 u8 reg_val, zoh_mux_val = 0x00;
4638
4639 pr_debug("%s: event = %d\n", __func__, event);
4640
4641 switch (event) {
4642 case SND_SOC_DAPM_POST_PMU:
4643 reg_val = snd_soc_read(codec, TAIKO_A_CDC_CONN_CLSH_CTL);
4644
4645 if ((reg_val & 0x30) == 0x10)
4646 zoh_mux_val = 0x04;
4647 else if ((reg_val & 0x30) == 0x20)
4648 zoh_mux_val = 0x08;
4649
4650 if (zoh_mux_val != 0x00)
4651 snd_soc_update_bits(codec,
4652 TAIKO_A_CDC_CONN_CLSH_CTL,
4653 0x0C, zoh_mux_val);
4654 break;
4655
4656 case SND_SOC_DAPM_POST_PMD:
4657 snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_CLSH_CTL,
4658 0x0C, 0x00);
4659 break;
Kiran Kandi4c56c592012-07-25 11:04:55 -07004660 }
4661 return 0;
4662}
4663
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08004664static int taiko_codec_enable_anc_ear(struct snd_soc_dapm_widget *w,
4665 struct snd_kcontrol *kcontrol, int event)
4666{
4667 struct snd_soc_codec *codec = w->codec;
4668 int ret = 0;
4669
4670 switch (event) {
4671 case SND_SOC_DAPM_PRE_PMU:
4672 ret = taiko_codec_enable_anc(w, kcontrol, event);
4673 msleep(50);
4674 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x10);
4675 break;
4676 case SND_SOC_DAPM_POST_PMU:
4677 ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
4678 break;
4679 case SND_SOC_DAPM_PRE_PMD:
4680 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x00);
4681 msleep(40);
4682 ret |= taiko_codec_enable_anc(w, kcontrol, event);
4683 break;
4684 case SND_SOC_DAPM_POST_PMD:
4685 ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
4686 break;
4687 }
4688 return ret;
4689}
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004690
Kiran Kandic3b24402012-06-11 00:05:59 -07004691/* Todo: Have seperate dapm widgets for I2S and Slimbus.
4692 * Might Need to have callbacks registered only for slimbus
4693 */
4694static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
4695 /*RX stuff */
4696 SND_SOC_DAPM_OUTPUT("EAR"),
4697
Kiran Kandi4c56c592012-07-25 11:04:55 -07004698 SND_SOC_DAPM_PGA_E("EAR PA", TAIKO_A_RX_EAR_EN, 4, 0, NULL, 0,
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004699 taiko_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU |
4700 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004701
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004702 SND_SOC_DAPM_MIXER_E("DAC1", TAIKO_A_RX_EAR_EN, 6, 0, dac1_switch,
4703 ARRAY_SIZE(dac1_switch), taiko_codec_ear_dac_event,
4704 SND_SOC_DAPM_PRE_PMU),
Kiran Kandic3b24402012-06-11 00:05:59 -07004705
Kuirong Wang906ac472012-07-09 12:54:44 -07004706 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
4707 AIF1_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07004708 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07004709 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
4710 AIF2_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07004711 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07004712 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
4713 AIF3_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07004714 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4715
Kuirong Wang906ac472012-07-09 12:54:44 -07004716 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TAIKO_RX1, 0,
4717 &slim_rx_mux[TAIKO_RX1]),
4718 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TAIKO_RX2, 0,
4719 &slim_rx_mux[TAIKO_RX2]),
4720 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TAIKO_RX3, 0,
4721 &slim_rx_mux[TAIKO_RX3]),
4722 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TAIKO_RX4, 0,
4723 &slim_rx_mux[TAIKO_RX4]),
4724 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TAIKO_RX5, 0,
4725 &slim_rx_mux[TAIKO_RX5]),
4726 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TAIKO_RX6, 0,
4727 &slim_rx_mux[TAIKO_RX6]),
4728 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TAIKO_RX7, 0,
4729 &slim_rx_mux[TAIKO_RX7]),
Kiran Kandic3b24402012-06-11 00:05:59 -07004730
Kuirong Wang906ac472012-07-09 12:54:44 -07004731 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4732 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4733 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
4734 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
4735 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
4736 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
4737 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
Kiran Kandic3b24402012-06-11 00:05:59 -07004738
4739 /* Headphone */
4740 SND_SOC_DAPM_OUTPUT("HEADPHONE"),
4741 SND_SOC_DAPM_PGA_E("HPHL", TAIKO_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
4742 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07004743 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004744 SND_SOC_DAPM_MIXER_E("HPHL DAC", TAIKO_A_RX_HPH_L_DAC_CTL, 7, 0,
4745 hphl_switch, ARRAY_SIZE(hphl_switch), taiko_hphl_dac_event,
4746 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004747
4748 SND_SOC_DAPM_PGA_E("HPHR", TAIKO_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
4749 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07004750 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004751
4752 SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TAIKO_A_RX_HPH_R_DAC_CTL, 7, 0,
4753 taiko_hphr_dac_event,
4754 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4755
4756 /* Speaker */
4757 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
4758 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
4759 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
4760 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004761 SND_SOC_DAPM_OUTPUT("SPK_OUT"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004762
4763 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TAIKO_A_RX_LINE_CNP_EN, 0, 0, NULL,
4764 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
4765 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4766 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TAIKO_A_RX_LINE_CNP_EN, 1, 0, NULL,
4767 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
4768 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4769 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TAIKO_A_RX_LINE_CNP_EN, 2, 0, NULL,
4770 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
4771 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4772 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TAIKO_A_RX_LINE_CNP_EN, 3, 0, NULL,
4773 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
4774 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park125cd4e2012-12-11 15:16:11 -08004775 SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0 , NULL,
4776 0, taiko_codec_enable_spk_pa,
4777 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004778
4779 SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAIKO_A_RX_LINE_1_DAC_CTL, 7, 0
4780 , taiko_lineout_dac_event,
4781 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4782 SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TAIKO_A_RX_LINE_2_DAC_CTL, 7, 0
4783 , taiko_lineout_dac_event,
4784 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4785 SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TAIKO_A_RX_LINE_3_DAC_CTL, 7, 0
4786 , taiko_lineout_dac_event,
4787 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4788 SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
4789 &lineout3_ground_switch),
4790 SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TAIKO_A_RX_LINE_4_DAC_CTL, 7, 0
4791 , taiko_lineout_dac_event,
4792 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4793 SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
4794 &lineout4_ground_switch),
4795
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004796 SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
4797 taiko_spk_dac_event,
4798 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4799
Joonwoo Park125cd4e2012-12-11 15:16:11 -08004800 SND_SOC_DAPM_SUPPLY("VDD_SPKDRV", SND_SOC_NOPM, 0, 0,
4801 taiko_codec_enable_vdd_spkr,
4802 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4803
Kiran Kandid2b46332012-10-05 12:04:00 -07004804 SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4805 SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4806 SND_SOC_DAPM_MIXER("RX7 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4807
Kiran Kandic3b24402012-06-11 00:05:59 -07004808 SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004809 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004810 SND_SOC_DAPM_POST_PMU),
4811 SND_SOC_DAPM_MIXER_E("RX2 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004812 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004813 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07004814 SND_SOC_DAPM_MIXER_E("RX3 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004815 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004816 SND_SOC_DAPM_POST_PMU),
4817 SND_SOC_DAPM_MIXER_E("RX4 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004818 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004819 SND_SOC_DAPM_POST_PMU),
4820 SND_SOC_DAPM_MIXER_E("RX5 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004821 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004822 SND_SOC_DAPM_POST_PMU),
4823 SND_SOC_DAPM_MIXER_E("RX6 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004824 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004825 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07004826 SND_SOC_DAPM_MIXER_E("RX7 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004827 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004828 SND_SOC_DAPM_POST_PMU),
4829
Kiran Kandic3b24402012-06-11 00:05:59 -07004830
4831 SND_SOC_DAPM_MIXER("RX1 CHAIN", TAIKO_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
4832 SND_SOC_DAPM_MIXER("RX2 CHAIN", TAIKO_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
4833
4834 SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4835 &rx_mix1_inp1_mux),
4836 SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4837 &rx_mix1_inp2_mux),
4838 SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
4839 &rx_mix1_inp3_mux),
4840 SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4841 &rx2_mix1_inp1_mux),
4842 SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4843 &rx2_mix1_inp2_mux),
4844 SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4845 &rx3_mix1_inp1_mux),
4846 SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4847 &rx3_mix1_inp2_mux),
4848 SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4849 &rx4_mix1_inp1_mux),
4850 SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4851 &rx4_mix1_inp2_mux),
4852 SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4853 &rx5_mix1_inp1_mux),
4854 SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4855 &rx5_mix1_inp2_mux),
4856 SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4857 &rx6_mix1_inp1_mux),
4858 SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4859 &rx6_mix1_inp2_mux),
4860 SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4861 &rx7_mix1_inp1_mux),
4862 SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4863 &rx7_mix1_inp2_mux),
4864 SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
4865 &rx1_mix2_inp1_mux),
4866 SND_SOC_DAPM_MUX("RX1 MIX2 INP2", SND_SOC_NOPM, 0, 0,
4867 &rx1_mix2_inp2_mux),
4868 SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
4869 &rx2_mix2_inp1_mux),
4870 SND_SOC_DAPM_MUX("RX2 MIX2 INP2", SND_SOC_NOPM, 0, 0,
4871 &rx2_mix2_inp2_mux),
4872 SND_SOC_DAPM_MUX("RX7 MIX2 INP1", SND_SOC_NOPM, 0, 0,
4873 &rx7_mix2_inp1_mux),
4874 SND_SOC_DAPM_MUX("RX7 MIX2 INP2", SND_SOC_NOPM, 0, 0,
4875 &rx7_mix2_inp2_mux),
4876
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02004877 SND_SOC_DAPM_MUX("RDAC5 MUX", SND_SOC_NOPM, 0, 0,
4878 &rx_dac5_mux),
4879 SND_SOC_DAPM_MUX("RDAC7 MUX", SND_SOC_NOPM, 0, 0,
4880 &rx_dac7_mux),
4881
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004882 SND_SOC_DAPM_MUX_E("CLASS_H_DSM MUX", SND_SOC_NOPM, 0, 0,
4883 &class_h_dsm_mux, taiko_codec_dsm_mux_event,
4884 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandi4c56c592012-07-25 11:04:55 -07004885
Kiran Kandic3b24402012-06-11 00:05:59 -07004886 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
4887 taiko_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
4888 SND_SOC_DAPM_POST_PMD),
4889
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004890 SND_SOC_DAPM_SUPPLY("CDC_I2S_RX_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 5, 0,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08004891 NULL, 0),
4892
Kiran Kandic3b24402012-06-11 00:05:59 -07004893 /* TX */
4894
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004895 SND_SOC_DAPM_SUPPLY("CDC_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
Kiran Kandic3b24402012-06-11 00:05:59 -07004896 0),
4897
4898 SND_SOC_DAPM_SUPPLY("LDO_H", TAIKO_A_LDO_H_MODE_1, 7, 0,
4899 taiko_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
4900
Joonwoo Parkc7731432012-10-17 12:41:44 -07004901 SND_SOC_DAPM_SUPPLY("COMP0_CLK", SND_SOC_NOPM, 0, 0,
Kiran Kandic3b24402012-06-11 00:05:59 -07004902 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
4903 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
Joonwoo Parkc7731432012-10-17 12:41:44 -07004904 SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 1, 0,
4905 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
4906 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
4907 SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 2, 0,
Kiran Kandic3b24402012-06-11 00:05:59 -07004908 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
4909 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
4910
4911
4912 SND_SOC_DAPM_INPUT("AMIC1"),
Joonwoo Park3699ca32013-02-08 12:06:15 -08004913 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", SND_SOC_NOPM, 7, 0,
4914 taiko_codec_enable_micbias,
4915 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4916 SND_SOC_DAPM_POST_PMD),
4917 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", SND_SOC_NOPM, 7, 0,
4918 taiko_codec_enable_micbias,
4919 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4920 SND_SOC_DAPM_POST_PMD),
4921 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", SND_SOC_NOPM, 7, 0,
4922 taiko_codec_enable_micbias,
4923 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4924 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004925
4926 SND_SOC_DAPM_INPUT("AMIC3"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004927
4928 SND_SOC_DAPM_INPUT("AMIC4"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004929
4930 SND_SOC_DAPM_INPUT("AMIC5"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004931
4932 SND_SOC_DAPM_INPUT("AMIC6"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004933
4934 SND_SOC_DAPM_MUX_E("DEC1 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
4935 &dec1_mux, taiko_codec_enable_dec,
4936 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4937 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4938
4939 SND_SOC_DAPM_MUX_E("DEC2 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
4940 &dec2_mux, taiko_codec_enable_dec,
4941 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4942 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4943
4944 SND_SOC_DAPM_MUX_E("DEC3 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
4945 &dec3_mux, taiko_codec_enable_dec,
4946 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4947 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4948
4949 SND_SOC_DAPM_MUX_E("DEC4 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
4950 &dec4_mux, taiko_codec_enable_dec,
4951 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4952 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4953
4954 SND_SOC_DAPM_MUX_E("DEC5 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
4955 &dec5_mux, taiko_codec_enable_dec,
4956 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4957 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4958
4959 SND_SOC_DAPM_MUX_E("DEC6 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
4960 &dec6_mux, taiko_codec_enable_dec,
4961 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4962 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4963
4964 SND_SOC_DAPM_MUX_E("DEC7 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
4965 &dec7_mux, taiko_codec_enable_dec,
4966 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4967 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4968
4969 SND_SOC_DAPM_MUX_E("DEC8 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
4970 &dec8_mux, taiko_codec_enable_dec,
4971 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4972 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4973
4974 SND_SOC_DAPM_MUX_E("DEC9 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
4975 &dec9_mux, taiko_codec_enable_dec,
4976 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4977 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4978
4979 SND_SOC_DAPM_MUX_E("DEC10 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
4980 &dec10_mux, taiko_codec_enable_dec,
4981 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4982 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4983
4984 SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
4985 SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
4986
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08004987 SND_SOC_DAPM_OUTPUT("ANC HEADPHONE"),
4988 SND_SOC_DAPM_PGA_E("ANC HPHL", SND_SOC_NOPM, 5, 0, NULL, 0,
4989 taiko_codec_enable_anc_hph,
4990 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
4991 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
4992 SND_SOC_DAPM_PGA_E("ANC HPHR", SND_SOC_NOPM, 4, 0, NULL, 0,
4993 taiko_codec_enable_anc_hph, SND_SOC_DAPM_PRE_PMU |
4994 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
4995 SND_SOC_DAPM_POST_PMU),
4996 SND_SOC_DAPM_OUTPUT("ANC EAR"),
4997 SND_SOC_DAPM_PGA_E("ANC EAR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
4998 taiko_codec_enable_anc_ear,
4999 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
5000 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005001 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
5002
5003 SND_SOC_DAPM_INPUT("AMIC2"),
Joonwoo Park3699ca32013-02-08 12:06:15 -08005004 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 7, 0,
5005 taiko_codec_enable_micbias,
5006 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5007 SND_SOC_DAPM_POST_PMD),
5008 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 7, 0,
5009 taiko_codec_enable_micbias,
5010 SND_SOC_DAPM_PRE_PMU |
5011 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5012 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 7, 0,
5013 taiko_codec_enable_micbias,
5014 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5015 SND_SOC_DAPM_POST_PMD),
5016 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 7, 0,
5017 taiko_codec_enable_micbias,
5018 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5019 SND_SOC_DAPM_POST_PMD),
5020 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 7, 0,
5021 taiko_codec_enable_micbias,
5022 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5023 SND_SOC_DAPM_POST_PMD),
5024 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 7, 0,
5025 taiko_codec_enable_micbias,
5026 SND_SOC_DAPM_PRE_PMU |
5027 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5028 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 7, 0,
5029 taiko_codec_enable_micbias,
5030 SND_SOC_DAPM_PRE_PMU |
5031 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5032 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", SND_SOC_NOPM, 7,
5033 0, taiko_codec_enable_micbias,
5034 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5035 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005036
Kuirong Wang906ac472012-07-09 12:54:44 -07005037 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
5038 AIF1_CAP, 0, taiko_codec_enable_slimtx,
5039 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005040
Kuirong Wang906ac472012-07-09 12:54:44 -07005041 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
5042 AIF2_CAP, 0, taiko_codec_enable_slimtx,
5043 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005044
Kuirong Wang906ac472012-07-09 12:54:44 -07005045 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
5046 AIF3_CAP, 0, taiko_codec_enable_slimtx,
5047 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07005048
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005049 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
5050 AIF4_VIFEED, 0, taiko_codec_enable_slimvi_feedback,
5051 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005052 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
Joonwoo Park9ead0e92013-03-18 11:33:33 -07005053 SND_SOC_NOPM, 0, 0,
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005054 taiko_codec_enable_mad, SND_SOC_DAPM_PRE_PMU),
Joonwoo Park9ead0e92013-03-18 11:33:33 -07005055 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
5056 &aif4_mad_switch),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005057 SND_SOC_DAPM_INPUT("MADINPUT"),
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05005058
Kuirong Wang906ac472012-07-09 12:54:44 -07005059 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
5060 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005061
Kuirong Wang906ac472012-07-09 12:54:44 -07005062 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
5063 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005064
Kuirong Wang906ac472012-07-09 12:54:44 -07005065 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
5066 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005067
Kuirong Wang906ac472012-07-09 12:54:44 -07005068 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TAIKO_TX1, 0,
5069 &sb_tx1_mux),
5070 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TAIKO_TX2, 0,
5071 &sb_tx2_mux),
5072 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TAIKO_TX3, 0,
5073 &sb_tx3_mux),
5074 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TAIKO_TX4, 0,
5075 &sb_tx4_mux),
5076 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TAIKO_TX5, 0,
5077 &sb_tx5_mux),
5078 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TAIKO_TX6, 0,
5079 &sb_tx6_mux),
5080 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TAIKO_TX7, 0,
5081 &sb_tx7_mux),
5082 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TAIKO_TX8, 0,
5083 &sb_tx8_mux),
5084 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TAIKO_TX9, 0,
5085 &sb_tx9_mux),
5086 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TAIKO_TX10, 0,
5087 &sb_tx10_mux),
Kiran Kandic3b24402012-06-11 00:05:59 -07005088
5089 /* Digital Mic Inputs */
5090 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
5091 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5092 SND_SOC_DAPM_POST_PMD),
5093
5094 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
5095 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5096 SND_SOC_DAPM_POST_PMD),
5097
5098 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
5099 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5100 SND_SOC_DAPM_POST_PMD),
5101
5102 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
5103 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5104 SND_SOC_DAPM_POST_PMD),
5105
5106 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
5107 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5108 SND_SOC_DAPM_POST_PMD),
5109 SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
5110 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5111 SND_SOC_DAPM_POST_PMD),
5112
5113 /* Sidetone */
5114 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
5115 SND_SOC_DAPM_PGA("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
5116
5117 /* AUX PGA */
5118 SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TAIKO_A_RX_AUX_SW_CTL, 7, 0,
5119 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
5120 SND_SOC_DAPM_POST_PMD),
5121
5122 SND_SOC_DAPM_ADC_E("AUX_PGA_Right", NULL, TAIKO_A_RX_AUX_SW_CTL, 6, 0,
5123 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
5124 SND_SOC_DAPM_POST_PMD),
5125
5126 /* Lineout, ear and HPH PA Mixers */
5127
5128 SND_SOC_DAPM_MIXER("EAR_PA_MIXER", SND_SOC_NOPM, 0, 0,
5129 ear_pa_mix, ARRAY_SIZE(ear_pa_mix)),
5130
5131 SND_SOC_DAPM_MIXER("HPHL_PA_MIXER", SND_SOC_NOPM, 0, 0,
5132 hphl_pa_mix, ARRAY_SIZE(hphl_pa_mix)),
5133
5134 SND_SOC_DAPM_MIXER("HPHR_PA_MIXER", SND_SOC_NOPM, 0, 0,
5135 hphr_pa_mix, ARRAY_SIZE(hphr_pa_mix)),
5136
5137 SND_SOC_DAPM_MIXER("LINEOUT1_PA_MIXER", SND_SOC_NOPM, 0, 0,
5138 lineout1_pa_mix, ARRAY_SIZE(lineout1_pa_mix)),
5139
5140 SND_SOC_DAPM_MIXER("LINEOUT2_PA_MIXER", SND_SOC_NOPM, 0, 0,
5141 lineout2_pa_mix, ARRAY_SIZE(lineout2_pa_mix)),
5142
5143 SND_SOC_DAPM_MIXER("LINEOUT3_PA_MIXER", SND_SOC_NOPM, 0, 0,
5144 lineout3_pa_mix, ARRAY_SIZE(lineout3_pa_mix)),
5145
5146 SND_SOC_DAPM_MIXER("LINEOUT4_PA_MIXER", SND_SOC_NOPM, 0, 0,
5147 lineout4_pa_mix, ARRAY_SIZE(lineout4_pa_mix)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005148};
5149
Kiran Kandic3b24402012-06-11 00:05:59 -07005150static irqreturn_t taiko_slimbus_irq(int irq, void *data)
5151{
5152 struct taiko_priv *priv = data;
5153 struct snd_soc_codec *codec = priv->codec;
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005154 unsigned long status = 0;
5155 int i, j, port_id, k;
5156 u32 bit;
Kiran Kandic3b24402012-06-11 00:05:59 -07005157 u8 val;
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005158 bool tx, cleared;
Kiran Kandic3b24402012-06-11 00:05:59 -07005159
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005160 for (i = TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
5161 i <= TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
5162 val = wcd9xxx_interface_reg_read(codec->control_data, i);
5163 status |= ((u32)val << (8 * j));
5164 }
5165
5166 for_each_set_bit(j, &status, 32) {
5167 tx = (j >= 16 ? true : false);
5168 port_id = (tx ? j - 16 : j);
5169 val = wcd9xxx_interface_reg_read(codec->control_data,
5170 TAIKO_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
5171 if (val & TAIKO_SLIM_IRQ_OVERFLOW)
5172 pr_err_ratelimited(
5173 "%s: overflow error on %s port %d, value %x\n",
5174 __func__, (tx ? "TX" : "RX"), port_id, val);
5175 if (val & TAIKO_SLIM_IRQ_UNDERFLOW)
5176 pr_err_ratelimited(
5177 "%s: underflow error on %s port %d, value %x\n",
5178 __func__, (tx ? "TX" : "RX"), port_id, val);
5179 if (val & TAIKO_SLIM_IRQ_PORT_CLOSED) {
5180 /*
5181 * INT SOURCE register starts from RX to TX
5182 * but port number in the ch_mask is in opposite way
5183 */
5184 bit = (tx ? j - 16 : j + 16);
5185 pr_debug("%s: %s port %d closed value %x, bit %u\n",
5186 __func__, (tx ? "TX" : "RX"), port_id, val,
5187 bit);
5188 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
5189 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
5190 __func__, k, priv->dai[k].ch_mask);
5191 if (test_and_clear_bit(bit,
5192 &priv->dai[k].ch_mask)) {
5193 cleared = true;
5194 if (!priv->dai[k].ch_mask)
5195 wake_up(&priv->dai[k].dai_wait);
5196 /*
5197 * There are cases when multiple DAIs
5198 * might be using the same slimbus
5199 * channel. Hence don't break here.
5200 */
5201 }
5202 }
5203 WARN(!cleared,
5204 "Couldn't find slimbus %s port %d for closing\n",
5205 (tx ? "TX" : "RX"), port_id);
Kiran Kandic3b24402012-06-11 00:05:59 -07005206 }
5207 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005208 TAIKO_SLIM_PGD_PORT_INT_CLR_RX_0 +
5209 (j / 8),
5210 1 << (j % 8));
Joonwoo Parka8890262012-10-15 12:04:27 -07005211 }
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005212
Kiran Kandic3b24402012-06-11 00:05:59 -07005213 return IRQ_HANDLED;
5214}
5215
5216static int taiko_handle_pdata(struct taiko_priv *taiko)
5217{
5218 struct snd_soc_codec *codec = taiko->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07005219 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
Kiran Kandic3b24402012-06-11 00:05:59 -07005220 int k1, k2, k3, rc = 0;
Kiran Kandi725f8492012-08-06 13:45:16 -07005221 u8 leg_mode, txfe_bypass, txfe_buff, flag;
Kiran Kandic3b24402012-06-11 00:05:59 -07005222 u8 i = 0, j = 0;
5223 u8 val_txfe = 0, value = 0;
Damir Didjusto1a353ce2013-04-02 11:45:47 -07005224 u8 dmic_sample_rate_value = 0;
5225 u8 dmic_b1_ctl_value = 0, dmic_b2_ctl_value = 0;
5226 u8 anc_ctl_value = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07005227
5228 if (!pdata) {
Kiran Kandi725f8492012-08-06 13:45:16 -07005229 pr_err("%s: NULL pdata\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07005230 rc = -ENODEV;
5231 goto done;
5232 }
5233
Kiran Kandi725f8492012-08-06 13:45:16 -07005234 leg_mode = pdata->amic_settings.legacy_mode;
5235 txfe_bypass = pdata->amic_settings.txfe_enable;
5236 txfe_buff = pdata->amic_settings.txfe_buff;
5237 flag = pdata->amic_settings.use_pdata;
5238
Kiran Kandic3b24402012-06-11 00:05:59 -07005239 /* Make sure settings are correct */
Joonwoo Parka8890262012-10-15 12:04:27 -07005240 if ((pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V) ||
5241 (pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
5242 (pdata->micbias.bias2_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
5243 (pdata->micbias.bias3_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
5244 (pdata->micbias.bias4_cfilt_sel > WCD9XXX_CFILT3_SEL)) {
Kiran Kandic3b24402012-06-11 00:05:59 -07005245 rc = -EINVAL;
5246 goto done;
5247 }
Kiran Kandic3b24402012-06-11 00:05:59 -07005248 /* figure out k value */
Joonwoo Parka8890262012-10-15 12:04:27 -07005249 k1 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt1_mv);
5250 k2 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt2_mv);
5251 k3 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt3_mv);
Kiran Kandic3b24402012-06-11 00:05:59 -07005252
5253 if (IS_ERR_VALUE(k1) || IS_ERR_VALUE(k2) || IS_ERR_VALUE(k3)) {
5254 rc = -EINVAL;
5255 goto done;
5256 }
Kiran Kandic3b24402012-06-11 00:05:59 -07005257 /* Set voltage level and always use LDO */
5258 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 0x0C,
Joonwoo Parka8890262012-10-15 12:04:27 -07005259 (pdata->micbias.ldoh_v << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07005260
Joonwoo Parka8890262012-10-15 12:04:27 -07005261 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_1_VAL, 0xFC, (k1 << 2));
5262 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_2_VAL, 0xFC, (k2 << 2));
5263 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_3_VAL, 0xFC, (k3 << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07005264
5265 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07005266 (pdata->micbias.bias1_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07005267 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07005268 (pdata->micbias.bias2_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07005269 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07005270 (pdata->micbias.bias3_cfilt_sel << 5));
5271 snd_soc_update_bits(codec, taiko->resmgr.reg_addr->micb_4_ctl, 0x60,
Kiran Kandic3b24402012-06-11 00:05:59 -07005272 (pdata->micbias.bias4_cfilt_sel << 5));
5273
5274 for (i = 0; i < 6; j++, i += 2) {
5275 if (flag & (0x01 << i)) {
5276 value = (leg_mode & (0x01 << i)) ? 0x10 : 0x00;
5277 val_txfe = (txfe_bypass & (0x01 << i)) ? 0x20 : 0x00;
5278 val_txfe = val_txfe |
5279 ((txfe_buff & (0x01 << i)) ? 0x10 : 0x00);
5280 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
5281 0x10, value);
5282 snd_soc_update_bits(codec,
5283 TAIKO_A_TX_1_2_TEST_EN + j * 10,
5284 0x30, val_txfe);
5285 }
5286 if (flag & (0x01 << (i + 1))) {
5287 value = (leg_mode & (0x01 << (i + 1))) ? 0x01 : 0x00;
5288 val_txfe = (txfe_bypass &
5289 (0x01 << (i + 1))) ? 0x02 : 0x00;
5290 val_txfe |= (txfe_buff &
5291 (0x01 << (i + 1))) ? 0x01 : 0x00;
5292 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
5293 0x01, value);
5294 snd_soc_update_bits(codec,
5295 TAIKO_A_TX_1_2_TEST_EN + j * 10,
5296 0x03, val_txfe);
5297 }
5298 }
5299 if (flag & 0x40) {
5300 value = (leg_mode & 0x40) ? 0x10 : 0x00;
5301 value = value | ((txfe_bypass & 0x40) ? 0x02 : 0x00);
5302 value = value | ((txfe_buff & 0x40) ? 0x01 : 0x00);
5303 snd_soc_update_bits(codec, TAIKO_A_TX_7_MBHC_EN,
5304 0x13, value);
5305 }
5306
5307 if (pdata->ocp.use_pdata) {
5308 /* not defined in CODEC specification */
5309 if (pdata->ocp.hph_ocp_limit == 1 ||
5310 pdata->ocp.hph_ocp_limit == 5) {
5311 rc = -EINVAL;
5312 goto done;
5313 }
5314 snd_soc_update_bits(codec, TAIKO_A_RX_COM_OCP_CTL,
5315 0x0F, pdata->ocp.num_attempts);
5316 snd_soc_write(codec, TAIKO_A_RX_COM_OCP_COUNT,
5317 ((pdata->ocp.run_time << 4) | pdata->ocp.wait_time));
5318 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_OCP_CTL,
5319 0xE0, (pdata->ocp.hph_ocp_limit << 5));
5320 }
5321
5322 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
5323 if (!strncmp(pdata->regulator[i].name, "CDC_VDDA_RX", 11)) {
5324 if (pdata->regulator[i].min_uV == 1800000 &&
5325 pdata->regulator[i].max_uV == 1800000) {
5326 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
5327 0x1C);
5328 } else if (pdata->regulator[i].min_uV == 2200000 &&
5329 pdata->regulator[i].max_uV == 2200000) {
5330 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
5331 0x1E);
5332 } else {
5333 pr_err("%s: unsupported CDC_VDDA_RX voltage\n"
5334 "min %d, max %d\n", __func__,
5335 pdata->regulator[i].min_uV,
5336 pdata->regulator[i].max_uV);
5337 rc = -EINVAL;
5338 }
5339 break;
5340 }
5341 }
Kiran Kandi4c56c592012-07-25 11:04:55 -07005342
Joonwoo Park1848c762012-10-18 13:16:01 -07005343 /* Set micbias capless mode with tail current */
5344 value = (pdata->micbias.bias1_cap_mode == MICBIAS_EXT_BYP_CAP ?
5345 0x00 : 0x16);
5346 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x1E, value);
5347 value = (pdata->micbias.bias2_cap_mode == MICBIAS_EXT_BYP_CAP ?
5348 0x00 : 0x16);
5349 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x1E, value);
5350 value = (pdata->micbias.bias3_cap_mode == MICBIAS_EXT_BYP_CAP ?
5351 0x00 : 0x16);
5352 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x1E, value);
5353 value = (pdata->micbias.bias4_cap_mode == MICBIAS_EXT_BYP_CAP ?
5354 0x00 : 0x16);
5355 snd_soc_update_bits(codec, TAIKO_A_MICB_4_CTL, 0x1E, value);
5356
Damir Didjusto1a353ce2013-04-02 11:45:47 -07005357 /* Set the DMIC sample rate */
5358 if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6HZ) {
5359 switch (pdata->dmic_sample_rate) {
5360 case TAIKO_DMIC_SAMPLE_RATE_2P4MHZ:
5361 dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_4;
5362 dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_4;
5363 dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_4;
5364 anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
5365 break;
5366 case TAIKO_DMIC_SAMPLE_RATE_4P8MHZ:
5367 dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_2;
5368 dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_2;
5369 dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_2;
5370 anc_ctl_value = TAIKO_ANC_DMIC_X2_ON;
5371 break;
5372 case TAIKO_DMIC_SAMPLE_RATE_3P2MHZ:
5373 case TAIKO_DMIC_SAMPLE_RATE_UNDEFINED:
5374 dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_3;
5375 dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_3;
5376 dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_3;
5377 anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
5378 break;
5379 default:
5380 pr_err("%s Invalid sample rate %d for mclk %d\n",
5381 __func__, pdata->dmic_sample_rate, pdata->mclk_rate);
5382 rc = -EINVAL;
5383 goto done;
5384 break;
5385 }
5386 } else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
5387 switch (pdata->dmic_sample_rate) {
5388 case TAIKO_DMIC_SAMPLE_RATE_3P072MHZ:
5389 dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_4;
5390 dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_4;
5391 dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_4;
5392 anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
5393 break;
5394 case TAIKO_DMIC_SAMPLE_RATE_6P144MHZ:
5395 dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_2;
5396 dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_2;
5397 dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_2;
5398 anc_ctl_value = TAIKO_ANC_DMIC_X2_ON;
5399 break;
5400 case TAIKO_DMIC_SAMPLE_RATE_4P096MHZ:
5401 case TAIKO_DMIC_SAMPLE_RATE_UNDEFINED:
5402 dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_3;
5403 dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_3;
5404 dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_3;
5405 anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
5406 break;
5407 default:
5408 pr_err("%s Invalid sample rate %d for mclk %d\n",
5409 __func__, pdata->dmic_sample_rate, pdata->mclk_rate);
5410 rc = -EINVAL;
5411 goto done;
5412 break;
5413 }
5414 } else {
5415 pr_err("%s MCLK is not set!\n", __func__);
5416 rc = -EINVAL;
5417 goto done;
5418 }
5419
5420 snd_soc_update_bits(codec, TAIKO_A_CDC_TX1_DMIC_CTL,
5421 0x7, dmic_sample_rate_value);
5422 snd_soc_update_bits(codec, TAIKO_A_CDC_TX2_DMIC_CTL,
5423 0x7, dmic_sample_rate_value);
5424 snd_soc_update_bits(codec, TAIKO_A_CDC_TX3_DMIC_CTL,
5425 0x7, dmic_sample_rate_value);
5426 snd_soc_update_bits(codec, TAIKO_A_CDC_TX4_DMIC_CTL,
5427 0x7, dmic_sample_rate_value);
5428 snd_soc_update_bits(codec, TAIKO_A_CDC_TX5_DMIC_CTL,
5429 0x7, dmic_sample_rate_value);
5430 snd_soc_update_bits(codec, TAIKO_A_CDC_TX6_DMIC_CTL,
5431 0x7, dmic_sample_rate_value);
5432 snd_soc_update_bits(codec, TAIKO_A_CDC_TX7_DMIC_CTL,
5433 0x7, dmic_sample_rate_value);
5434 snd_soc_update_bits(codec, TAIKO_A_CDC_TX8_DMIC_CTL,
5435 0x7, dmic_sample_rate_value);
5436 snd_soc_update_bits(codec, TAIKO_A_CDC_TX9_DMIC_CTL,
5437 0x7, dmic_sample_rate_value);
5438 snd_soc_update_bits(codec, TAIKO_A_CDC_TX10_DMIC_CTL,
5439 0x7, dmic_sample_rate_value);
5440 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_DMIC_B1_CTL,
5441 0xEE, dmic_b1_ctl_value);
5442 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_DMIC_B2_CTL,
5443 0xE, dmic_b2_ctl_value);
5444 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B2_CTL,
5445 0x1, anc_ctl_value);
5446
Kiran Kandic3b24402012-06-11 00:05:59 -07005447done:
5448 return rc;
5449}
5450
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005451static const struct wcd9xxx_reg_mask_val taiko_reg_defaults[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07005452
Kiran Kandi4c56c592012-07-25 11:04:55 -07005453 /* set MCLk to 9.6 */
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05005454 TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x02),
Kiran Kandi4c56c592012-07-25 11:04:55 -07005455 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_POWER_CTL, 0x03),
Kiran Kandic3b24402012-06-11 00:05:59 -07005456
Kiran Kandi4c56c592012-07-25 11:04:55 -07005457 /* EAR PA deafults */
5458 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CMBUFF, 0x05),
Kiran Kandic3b24402012-06-11 00:05:59 -07005459
Kiran Kandi4c56c592012-07-25 11:04:55 -07005460 /* RX deafults */
Kiran Kandic3b24402012-06-11 00:05:59 -07005461 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B5_CTL, 0x78),
5462 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B5_CTL, 0x78),
5463 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B5_CTL, 0x78),
5464 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B5_CTL, 0x78),
5465 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B5_CTL, 0x78),
5466 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B5_CTL, 0x78),
5467 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B5_CTL, 0x78),
5468
Kiran Kandi4c56c592012-07-25 11:04:55 -07005469 /* RX1 and RX2 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07005470 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B6_CTL, 0xA0),
5471 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B6_CTL, 0xA0),
5472
Kiran Kandi4c56c592012-07-25 11:04:55 -07005473 /* RX3 to RX7 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07005474 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B6_CTL, 0x80),
5475 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B6_CTL, 0x80),
5476 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B6_CTL, 0x80),
5477 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B6_CTL, 0x80),
5478 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005479
5480 /* MAD registers */
5481 TAIKO_REG_VAL(TAIKO_A_MAD_ANA_CTRL, 0xF1),
5482 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_MAIN_CTL_1, 0x00),
5483 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_MAIN_CTL_2, 0x00),
5484 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_1, 0x00),
5485 /* Set SAMPLE_TX_EN bit */
5486 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_2, 0x03),
5487 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_3, 0x00),
5488 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_4, 0x00),
5489 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_5, 0x00),
5490 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_6, 0x00),
5491 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_7, 0x00),
5492 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_8, 0x00),
5493 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_PTR, 0x00),
5494 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_VAL, 0x40),
5495 TAIKO_REG_VAL(TAIKO_A_CDC_DEBUG_B7_CTL, 0x00),
5496 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL, 0x00),
5497 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_CTL, 0x00),
5498 TAIKO_REG_VAL(TAIKO_A_CDC_CONN_MAD, 0x01),
Kiran Kandic3b24402012-06-11 00:05:59 -07005499};
5500
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005501static const struct wcd9xxx_reg_mask_val taiko_1_0_reg_defaults[] = {
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005502 /*
5503 * The following only need to be written for Taiko 1.0 parts.
5504 * Taiko 2.0 will have appropriate defaults for these registers.
5505 */
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005506
5507 /* BUCK default */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005508 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x50),
5509
5510 /* Required defaults for class H operation */
5511 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xF4),
5512 TAIKO_REG_VAL(TAIKO_A_BIAS_CURR_CTL_2, 0x08),
5513 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
5514 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_3, 0x60),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005515
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005516 /* Choose max non-overlap time for NCP */
5517 TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
5518 /* Use 25mV/50mV for deltap/m to reduce ripple */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005519 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x08),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005520 /*
5521 * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
5522 * Note that the other bits of this register will be changed during
5523 * Rx PA bring up.
5524 */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005525 TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005526 /* Reduce HPH DAC bias to 70% */
5527 TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
5528 /*Reduce EAR DAC bias to 70% */
5529 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
5530 /* Reduce LINE DAC bias to 70% */
5531 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
Joonwoo Parkd87ec4c2012-10-30 15:44:18 -07005532
5533 /*
5534 * There is a diode to pull down the micbias while doing
5535 * insertion detection. This diode can cause leakage.
5536 * Set bit 0 to 1 to prevent leakage.
5537 * Setting this bit of micbias 2 prevents leakage for all other micbias.
5538 */
5539 TAIKO_REG_VAL(TAIKO_A_MICB_2_MBHC, 0x41),
Joonwoo Park3c7bca62012-10-31 12:44:23 -07005540
5541 /* Disable TX7 internal biasing path which can cause leakage */
5542 TAIKO_REG_VAL(TAIKO_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
Joonwoo Park03604052012-11-06 18:40:25 -08005543 /* Enable MICB 4 VDDIO switch to prevent leakage */
5544 TAIKO_REG_VAL(TAIKO_A_MICB_4_MBHC, 0x81),
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005545
5546 /* Close leakage on the spkdrv */
5547 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_DBG_PWRSTG, 0x24),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005548};
5549
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005550/*
5551 * Don't update TAIKO_A_CHIP_CTL, TAIKO_A_BUCK_CTRL_CCL_1 and
5552 * TAIKO_A_RX_EAR_CMBUFF as those are updated in taiko_reg_defaults
5553 */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005554static const struct wcd9xxx_reg_mask_val taiko_2_0_reg_defaults[] = {
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005555 TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_GAIN, 0x2),
5556 TAIKO_REG_VAL(TAIKO_A_CDC_TX_2_GAIN, 0x2),
5557 TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_2_ADC_IB, 0x44),
5558 TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_GAIN, 0x2),
5559 TAIKO_REG_VAL(TAIKO_A_CDC_TX_4_GAIN, 0x2),
5560 TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_4_ADC_IB, 0x44),
5561 TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_GAIN, 0x2),
5562 TAIKO_REG_VAL(TAIKO_A_CDC_TX_6_GAIN, 0x2),
5563 TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_6_ADC_IB, 0x44),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005564 TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
5565 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x8),
5566 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x51),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005567 TAIKO_REG_VAL(TAIKO_A_NCP_DTEST, 0x10),
5568 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xA4),
5569 TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
5570 TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x69),
5571 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_CTL, 0xDA),
5572 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_TIME, 0x15),
5573 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
5574 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CNP, 0xC0),
5575 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
5576 TAIKO_REG_VAL(TAIKO_A_RX_LINE_1_TEST, 0x2),
5577 TAIKO_REG_VAL(TAIKO_A_RX_LINE_2_TEST, 0x2),
5578 TAIKO_REG_VAL(TAIKO_A_RX_LINE_3_TEST, 0x2),
5579 TAIKO_REG_VAL(TAIKO_A_RX_LINE_4_TEST, 0x2),
5580 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_OCP_CTL, 0x97),
5581 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_CLIP_DET, 0x1),
5582 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_IEC, 0x0),
5583 TAIKO_REG_VAL(TAIKO_A_CDC_TX1_MUX_CTL, 0x48),
5584 TAIKO_REG_VAL(TAIKO_A_CDC_TX2_MUX_CTL, 0x48),
5585 TAIKO_REG_VAL(TAIKO_A_CDC_TX3_MUX_CTL, 0x48),
5586 TAIKO_REG_VAL(TAIKO_A_CDC_TX4_MUX_CTL, 0x48),
5587 TAIKO_REG_VAL(TAIKO_A_CDC_TX5_MUX_CTL, 0x48),
5588 TAIKO_REG_VAL(TAIKO_A_CDC_TX6_MUX_CTL, 0x48),
5589 TAIKO_REG_VAL(TAIKO_A_CDC_TX7_MUX_CTL, 0x48),
5590 TAIKO_REG_VAL(TAIKO_A_CDC_TX8_MUX_CTL, 0x48),
5591 TAIKO_REG_VAL(TAIKO_A_CDC_TX9_MUX_CTL, 0x48),
5592 TAIKO_REG_VAL(TAIKO_A_CDC_TX10_MUX_CTL, 0x48),
5593 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B4_CTL, 0x8),
Joonwoo Parkdbbdac02013-03-21 19:24:31 -07005594 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B4_CTL, 0x8),
5595 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B4_CTL, 0x8),
5596 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B4_CTL, 0x8),
5597 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B4_CTL, 0x8),
5598 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B4_CTL, 0x8),
5599 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B4_CTL, 0x8),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005600 TAIKO_REG_VAL(TAIKO_A_CDC_VBAT_GAIN_UPD_MON, 0x0),
5601 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B1_CTL, 0x0),
5602 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B2_CTL, 0x0),
5603 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B3_CTL, 0x0),
5604 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B4_CTL, 0x0),
5605 TAIKO_REG_VAL(TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL, 0x0),
5606 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B4_CTL, 0x37),
5607 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
5608};
5609
Kiran Kandic3b24402012-06-11 00:05:59 -07005610static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
5611{
5612 u32 i;
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005613 struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07005614
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005615 for (i = 0; i < ARRAY_SIZE(taiko_reg_defaults); i++)
5616 snd_soc_write(codec, taiko_reg_defaults[i].reg,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005617 taiko_reg_defaults[i].val);
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005618
5619 if (TAIKO_IS_1_0(taiko_core->version)) {
5620 for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
5621 snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005622 taiko_1_0_reg_defaults[i].val);
5623 if (spkr_drv_wrnd == 1)
5624 snd_soc_write(codec, TAIKO_A_SPKR_DRV_EN, 0xEF);
5625 } else {
5626 for (i = 0; i < ARRAY_SIZE(taiko_2_0_reg_defaults); i++)
5627 snd_soc_write(codec, taiko_2_0_reg_defaults[i].reg,
5628 taiko_2_0_reg_defaults[i].val);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005629 spkr_drv_wrnd = -1;
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005630 }
Kiran Kandic3b24402012-06-11 00:05:59 -07005631}
5632
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005633static const struct wcd9xxx_reg_mask_val taiko_codec_reg_init_val[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07005634 /* Initialize current threshold to 350MA
5635 * number of wait and run cycles to 4096
5636 */
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005637 {TAIKO_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
Kiran Kandic3b24402012-06-11 00:05:59 -07005638 {TAIKO_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
Patrick Lai92833bf2012-12-01 10:31:35 -08005639 {TAIKO_A_RX_HPH_L_TEST, 0x01, 0x01},
5640 {TAIKO_A_RX_HPH_R_TEST, 0x01, 0x01},
Kiran Kandic3b24402012-06-11 00:05:59 -07005641
Kiran Kandic3b24402012-06-11 00:05:59 -07005642 /* Initialize gain registers to use register gain */
Kiran Kandi4c56c592012-07-25 11:04:55 -07005643 {TAIKO_A_RX_HPH_L_GAIN, 0x20, 0x20},
5644 {TAIKO_A_RX_HPH_R_GAIN, 0x20, 0x20},
5645 {TAIKO_A_RX_LINE_1_GAIN, 0x20, 0x20},
5646 {TAIKO_A_RX_LINE_2_GAIN, 0x20, 0x20},
5647 {TAIKO_A_RX_LINE_3_GAIN, 0x20, 0x20},
5648 {TAIKO_A_RX_LINE_4_GAIN, 0x20, 0x20},
Joonwoo Parkc7731432012-10-17 12:41:44 -07005649 {TAIKO_A_SPKR_DRV_GAIN, 0x04, 0x04},
Kiran Kandic3b24402012-06-11 00:05:59 -07005650
Kiran Kandic3b24402012-06-11 00:05:59 -07005651 /* Use 16 bit sample size for TX1 to TX6 */
5652 {TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0x30, 0x20},
5653 {TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0x30, 0x20},
5654 {TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0x30, 0x20},
5655 {TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0x30, 0x20},
5656 {TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0x30, 0x20},
5657 {TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0x30, 0x20},
5658
5659 /* Use 16 bit sample size for TX7 to TX10 */
5660 {TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0x60, 0x40},
5661 {TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0x60, 0x40},
5662 {TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x60, 0x40},
5663 {TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x60, 0x40},
5664
Kiran Kandic3b24402012-06-11 00:05:59 -07005665 /*enable HPF filter for TX paths */
5666 {TAIKO_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
5667 {TAIKO_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
5668 {TAIKO_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
5669 {TAIKO_A_CDC_TX4_MUX_CTL, 0x8, 0x0},
5670 {TAIKO_A_CDC_TX5_MUX_CTL, 0x8, 0x0},
5671 {TAIKO_A_CDC_TX6_MUX_CTL, 0x8, 0x0},
5672 {TAIKO_A_CDC_TX7_MUX_CTL, 0x8, 0x0},
5673 {TAIKO_A_CDC_TX8_MUX_CTL, 0x8, 0x0},
5674 {TAIKO_A_CDC_TX9_MUX_CTL, 0x8, 0x0},
5675 {TAIKO_A_CDC_TX10_MUX_CTL, 0x8, 0x0},
5676
Joonwoo Parkc7731432012-10-17 12:41:44 -07005677 /* Compander zone selection */
5678 {TAIKO_A_CDC_COMP0_B4_CTL, 0x3F, 0x37},
5679 {TAIKO_A_CDC_COMP1_B4_CTL, 0x3F, 0x37},
5680 {TAIKO_A_CDC_COMP2_B4_CTL, 0x3F, 0x37},
5681 {TAIKO_A_CDC_COMP0_B5_CTL, 0x7F, 0x7F},
5682 {TAIKO_A_CDC_COMP1_B5_CTL, 0x7F, 0x7F},
5683 {TAIKO_A_CDC_COMP2_B5_CTL, 0x7F, 0x7F},
Kiran Kandic3b24402012-06-11 00:05:59 -07005684};
5685
5686static void taiko_codec_init_reg(struct snd_soc_codec *codec)
5687{
5688 u32 i;
5689
5690 for (i = 0; i < ARRAY_SIZE(taiko_codec_reg_init_val); i++)
5691 snd_soc_update_bits(codec, taiko_codec_reg_init_val[i].reg,
5692 taiko_codec_reg_init_val[i].mask,
5693 taiko_codec_reg_init_val[i].val);
5694}
5695
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005696static int taiko_setup_irqs(struct taiko_priv *taiko)
5697{
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005698 int i;
Joonwoo Parka8890262012-10-15 12:04:27 -07005699 int ret = 0;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005700 struct snd_soc_codec *codec = taiko->codec;
5701
Joonwoo Parkf6574c72012-10-10 17:29:57 -07005702 ret = wcd9xxx_request_irq(codec->control_data, WCD9XXX_IRQ_SLIMBUS,
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005703 taiko_slimbus_irq, "SLIMBUS Slave", taiko);
5704 if (ret) {
5705 pr_err("%s: Failed to request irq %d\n", __func__,
Joonwoo Parkf6574c72012-10-10 17:29:57 -07005706 WCD9XXX_IRQ_SLIMBUS);
Joonwoo Parka8890262012-10-15 12:04:27 -07005707 goto exit;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005708 }
5709
5710 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
5711 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Parka8890262012-10-15 12:04:27 -07005712 TAIKO_SLIM_PGD_PORT_INT_EN0 + i,
5713 0xFF);
5714exit:
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005715 return ret;
5716}
5717
Joonwoo Parka8890262012-10-15 12:04:27 -07005718int taiko_hs_detect(struct snd_soc_codec *codec,
5719 struct wcd9xxx_mbhc_config *mbhc_cfg)
5720{
5721 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
5722 return wcd9xxx_mbhc_start(&taiko->mbhc, mbhc_cfg);
5723}
5724EXPORT_SYMBOL_GPL(taiko_hs_detect);
5725
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005726static void taiko_init_slim_slave_cfg(struct snd_soc_codec *codec)
5727{
5728 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
5729 struct afe_param_cdc_slimbus_slave_cfg *cfg;
5730 struct wcd9xxx *wcd9xxx = codec->control_data;
5731 uint64_t eaddr = 0;
5732
5733 cfg = &priv->slimbus_slave_cfg;
5734 cfg->minor_version = 1;
5735 cfg->tx_slave_port_offset = 0;
5736 cfg->rx_slave_port_offset = 16;
5737
5738 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
5739 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
5740 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
5741 cfg->device_enum_addr_msw = eaddr >> 32;
5742
5743 pr_debug("%s: slimbus logical address 0x%llx\n", __func__, eaddr);
5744}
5745
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005746static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
5747{
5748 int ret = 0;
5749 struct snd_soc_codec *codec;
5750 struct taiko_priv *taiko;
5751
5752 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
5753 taiko = snd_soc_codec_get_drvdata(codec);
5754 mutex_lock(&codec->mutex);
5755 WCD9XXX_BCL_LOCK(&taiko->resmgr);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005756
5757 if (codec->reg_def_copy) {
5758 pr_debug("%s: Update ASOC cache", __func__);
5759 kfree(codec->reg_cache);
5760 codec->reg_cache = kmemdup(codec->reg_def_copy,
5761 codec->reg_size, GFP_KERNEL);
5762 }
5763
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08005764 wcd9xxx_resmgr_post_ssr(&taiko->resmgr);
5765 if (spkr_drv_wrnd == 1)
5766 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
5767 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
5768
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005769 taiko_update_reg_defaults(codec);
5770 taiko_codec_init_reg(codec);
5771 ret = taiko_handle_pdata(taiko);
5772 if (IS_ERR_VALUE(ret))
5773 pr_err("%s: bad pdata\n", __func__);
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08005774
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005775 taiko_init_slim_slave_cfg(codec);
5776
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08005777 wcd9xxx_mbhc_deinit(&taiko->mbhc);
5778 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
5779 if (ret)
5780 pr_err("%s: mbhc init failed %d\n", __func__, ret);
5781 else
5782 wcd9xxx_mbhc_start(&taiko->mbhc, taiko->mbhc.mbhc_cfg);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005783 mutex_unlock(&codec->mutex);
5784 return ret;
5785}
5786
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005787void *taiko_get_afe_config(struct snd_soc_codec *codec,
5788 enum afe_config_type config_type)
5789{
5790 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
5791
5792 switch (config_type) {
5793 case AFE_SLIMBUS_SLAVE_CONFIG:
5794 return &priv->slimbus_slave_cfg;
5795 case AFE_CDC_REGISTERS_CONFIG:
Damir Didjustodcfdff82013-03-21 23:26:41 -07005796 return &taiko_audio_reg_cfg;
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005797 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
5798 return &taiko_slimbus_slave_port_cfg;
Damir Didjustodcfdff82013-03-21 23:26:41 -07005799 case AFE_AANC_VERSION:
5800 return &taiko_cdc_aanc_version;
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005801 default:
5802 pr_err("%s: Unknown config_type 0x%x\n", __func__, config_type);
5803 return NULL;
5804 }
5805}
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005806
Joonwoo Parka8890262012-10-15 12:04:27 -07005807static struct wcd9xxx_reg_address taiko_reg_address = {
5808 .micb_4_mbhc = TAIKO_A_MICB_4_MBHC,
5809 .micb_4_int_rbias = TAIKO_A_MICB_4_INT_RBIAS,
5810 .micb_4_ctl = TAIKO_A_MICB_4_CTL,
5811};
5812
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005813static int wcd9xxx_ssr_register(struct wcd9xxx *control,
5814 int (*post_reset_cb)(struct wcd9xxx *wcd9xxx), void *priv)
5815{
5816 control->post_reset = post_reset_cb;
5817 control->ssr_priv = priv;
5818 return 0;
5819}
5820
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005821static int taiko_codec_get_buck_mv(struct snd_soc_codec *codec)
5822{
5823 int buck_volt = WCD9XXX_CDC_BUCK_UNSUPPORTED;
5824 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
5825 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
5826 int i;
5827
5828 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
5829 if (!strncmp(pdata->regulator[i].name,
5830 WCD9XXX_SUPPLY_BUCK_NAME,
5831 sizeof(WCD9XXX_SUPPLY_BUCK_NAME))) {
5832 buck_volt = pdata->regulator[i].min_uV;
5833 break;
5834 }
5835 }
5836 return buck_volt;
5837}
5838
Joonwoo Park2a9170a2013-03-04 17:05:57 -08005839static const struct snd_soc_dapm_widget taiko_1_dapm_widgets[] = {
5840 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_TX_1_2_EN, 7, 0,
5841 taiko_codec_enable_adc,
5842 SND_SOC_DAPM_PRE_PMU |
5843 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5844 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_TX_1_2_EN, 3, 0,
5845 taiko_codec_enable_adc,
5846 SND_SOC_DAPM_PRE_PMU |
5847 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5848 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_TX_3_4_EN, 7, 0,
5849 taiko_codec_enable_adc,
5850 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5851 SND_SOC_DAPM_POST_PMD),
5852 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_TX_3_4_EN, 3, 0,
5853 taiko_codec_enable_adc,
5854 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5855 SND_SOC_DAPM_POST_PMD),
5856 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_TX_5_6_EN, 7, 0,
5857 taiko_codec_enable_adc,
5858 SND_SOC_DAPM_POST_PMU),
5859 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_TX_5_6_EN, 3, 0,
5860 taiko_codec_enable_adc,
5861 SND_SOC_DAPM_POST_PMU),
5862};
5863
5864static const struct snd_soc_dapm_widget taiko_2_dapm_widgets[] = {
5865 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_CDC_TX_1_GAIN, 7, 0,
5866 taiko_codec_enable_adc,
5867 SND_SOC_DAPM_PRE_PMU |
5868 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5869 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_CDC_TX_2_GAIN, 7, 0,
5870 taiko_codec_enable_adc,
5871 SND_SOC_DAPM_PRE_PMU |
5872 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5873 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_CDC_TX_3_GAIN, 7, 0,
5874 taiko_codec_enable_adc,
5875 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5876 SND_SOC_DAPM_POST_PMD),
5877 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_CDC_TX_4_GAIN, 7, 0,
5878 taiko_codec_enable_adc,
5879 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5880 SND_SOC_DAPM_POST_PMD),
5881 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_CDC_TX_5_GAIN, 7, 0,
5882 taiko_codec_enable_adc,
5883 SND_SOC_DAPM_POST_PMU),
5884 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_CDC_TX_6_GAIN, 7, 0,
5885 taiko_codec_enable_adc,
5886 SND_SOC_DAPM_POST_PMU),
5887};
5888
Kiran Kandic3b24402012-06-11 00:05:59 -07005889static int taiko_codec_probe(struct snd_soc_codec *codec)
5890{
5891 struct wcd9xxx *control;
5892 struct taiko_priv *taiko;
Joonwoo Parka8890262012-10-15 12:04:27 -07005893 struct wcd9xxx_pdata *pdata;
5894 struct wcd9xxx *wcd9xxx;
Kiran Kandic3b24402012-06-11 00:05:59 -07005895 struct snd_soc_dapm_context *dapm = &codec->dapm;
5896 int ret = 0;
5897 int i;
Kuirong Wang906ac472012-07-09 12:54:44 -07005898 void *ptr = NULL;
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005899 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07005900
5901 codec->control_data = dev_get_drvdata(codec->dev->parent);
5902 control = codec->control_data;
5903
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005904 wcd9xxx_ssr_register(control, taiko_post_reset_cb, (void *)codec);
5905
Kiran Kandi4c56c592012-07-25 11:04:55 -07005906 dev_info(codec->dev, "%s()\n", __func__);
5907
Kiran Kandic3b24402012-06-11 00:05:59 -07005908 taiko = kzalloc(sizeof(struct taiko_priv), GFP_KERNEL);
5909 if (!taiko) {
5910 dev_err(codec->dev, "Failed to allocate private data\n");
5911 return -ENOMEM;
5912 }
5913 for (i = 0 ; i < NUM_DECIMATORS; i++) {
5914 tx_hpf_work[i].taiko = taiko;
5915 tx_hpf_work[i].decimator = i + 1;
5916 INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
5917 tx_hpf_corner_freq_callback);
5918 }
5919
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005920
Kiran Kandic3b24402012-06-11 00:05:59 -07005921 snd_soc_codec_set_drvdata(codec, taiko);
5922
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005923
Joonwoo Parka8890262012-10-15 12:04:27 -07005924 /* codec resmgr module init */
5925 wcd9xxx = codec->control_data;
5926 pdata = dev_get_platdata(codec->dev->parent);
5927 ret = wcd9xxx_resmgr_init(&taiko->resmgr, codec, wcd9xxx, pdata,
5928 &taiko_reg_address);
5929 if (ret) {
5930 pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
5931 return ret;
5932 }
5933
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005934 taiko->clsh_d.buck_mv = taiko_codec_get_buck_mv(codec);
Joonwoo Parka08e0552013-03-05 18:28:23 -08005935 wcd9xxx_clsh_init(&taiko->clsh_d, &taiko->resmgr);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005936
Joonwoo Parka8890262012-10-15 12:04:27 -07005937 /* init and start mbhc */
5938 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
5939 if (ret) {
5940 pr_err("%s: mbhc init failed %d\n", __func__, ret);
5941 return ret;
5942 }
5943
Kiran Kandic3b24402012-06-11 00:05:59 -07005944 taiko->codec = codec;
Kiran Kandic3b24402012-06-11 00:05:59 -07005945 for (i = 0; i < COMPANDER_MAX; i++) {
5946 taiko->comp_enabled[i] = 0;
5947 taiko->comp_fs[i] = COMPANDER_FS_48KHZ;
5948 }
Kiran Kandic3b24402012-06-11 00:05:59 -07005949 taiko->intf_type = wcd9xxx_get_intf_type();
5950 taiko->aux_pga_cnt = 0;
5951 taiko->aux_l_gain = 0x1F;
5952 taiko->aux_r_gain = 0x1F;
Kiran Kandic3b24402012-06-11 00:05:59 -07005953 taiko_update_reg_defaults(codec);
Venkat Sudhira50a3762012-11-26 12:12:15 -08005954 pr_debug("%s: MCLK Rate = %x\n", __func__, wcd9xxx->mclk_rate);
5955 if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ)
Venkat Sudhir16d95e62013-02-04 16:57:33 -08005956 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x0);
Venkat Sudhira50a3762012-11-26 12:12:15 -08005957 else if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_9P6HZ)
Venkat Sudhir16d95e62013-02-04 16:57:33 -08005958 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x2);
Kiran Kandic3b24402012-06-11 00:05:59 -07005959 taiko_codec_init_reg(codec);
5960 ret = taiko_handle_pdata(taiko);
5961 if (IS_ERR_VALUE(ret)) {
5962 pr_err("%s: bad pdata\n", __func__);
5963 goto err_pdata;
5964 }
5965
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005966 if (spkr_drv_wrnd > 0) {
5967 WCD9XXX_BCL_LOCK(&taiko->resmgr);
5968 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
5969 WCD9XXX_BANDGAP_AUDIO_MODE);
5970 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
5971 }
5972
Kuirong Wang906ac472012-07-09 12:54:44 -07005973 ptr = kmalloc((sizeof(taiko_rx_chs) +
5974 sizeof(taiko_tx_chs)), GFP_KERNEL);
5975 if (!ptr) {
5976 pr_err("%s: no mem for slim chan ctl data\n", __func__);
5977 ret = -ENOMEM;
5978 goto err_nomem_slimch;
5979 }
5980
Kiran Kandic3b24402012-06-11 00:05:59 -07005981 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
5982 snd_soc_dapm_new_controls(dapm, taiko_dapm_i2s_widgets,
5983 ARRAY_SIZE(taiko_dapm_i2s_widgets));
5984 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
5985 ARRAY_SIZE(audio_i2s_map));
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005986 if (TAIKO_IS_1_0(core->version))
5987 snd_soc_dapm_add_routes(dapm, audio_i2s_map_1_0,
5988 ARRAY_SIZE(audio_i2s_map_1_0));
5989 else
5990 snd_soc_dapm_add_routes(dapm, audio_i2s_map_2_0,
5991 ARRAY_SIZE(audio_i2s_map_2_0));
Kuirong Wang906ac472012-07-09 12:54:44 -07005992 for (i = 0; i < ARRAY_SIZE(taiko_i2s_dai); i++)
5993 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
5994 } else if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
5995 for (i = 0; i < NUM_CODEC_DAIS; i++) {
5996 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
5997 init_waitqueue_head(&taiko->dai[i].dai_wait);
5998 }
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005999 taiko_slimbus_slave_port_cfg.slave_dev_intfdev_la =
6000 control->slim_slave->laddr;
6001 taiko_slimbus_slave_port_cfg.slave_dev_pgd_la =
6002 control->slim->laddr;
6003 taiko_slimbus_slave_port_cfg.slave_port_mapping[0] =
6004 TAIKO_MAD_SLIMBUS_TX_PORT;
6005
6006 taiko_init_slim_slave_cfg(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07006007 }
6008
Kiran Kandiec0db5c2013-03-08 16:03:58 -08006009 if (TAIKO_IS_1_0(control->version)) {
Joonwoo Park2a9170a2013-03-04 17:05:57 -08006010 snd_soc_dapm_new_controls(dapm, taiko_1_dapm_widgets,
6011 ARRAY_SIZE(taiko_1_dapm_widgets));
Kiran Kandiec0db5c2013-03-08 16:03:58 -08006012 snd_soc_add_codec_controls(codec,
6013 taiko_1_x_analog_gain_controls,
6014 ARRAY_SIZE(taiko_1_x_analog_gain_controls));
6015 } else {
Joonwoo Park2a9170a2013-03-04 17:05:57 -08006016 snd_soc_dapm_new_controls(dapm, taiko_2_dapm_widgets,
6017 ARRAY_SIZE(taiko_2_dapm_widgets));
Kiran Kandiec0db5c2013-03-08 16:03:58 -08006018 snd_soc_add_codec_controls(codec,
6019 taiko_2_x_analog_gain_controls,
6020 ARRAY_SIZE(taiko_2_x_analog_gain_controls));
6021 }
Joonwoo Park2a9170a2013-03-04 17:05:57 -08006022
Kuirong Wang906ac472012-07-09 12:54:44 -07006023 control->num_rx_port = TAIKO_RX_MAX;
6024 control->rx_chs = ptr;
6025 memcpy(control->rx_chs, taiko_rx_chs, sizeof(taiko_rx_chs));
6026 control->num_tx_port = TAIKO_TX_MAX;
6027 control->tx_chs = ptr + sizeof(taiko_rx_chs);
6028 memcpy(control->tx_chs, taiko_tx_chs, sizeof(taiko_tx_chs));
6029
Kiran Kandic3b24402012-06-11 00:05:59 -07006030 snd_soc_dapm_sync(dapm);
6031
Joonwoo Park7680b9f2012-07-13 11:36:48 -07006032 (void) taiko_setup_irqs(taiko);
Kiran Kandic3b24402012-06-11 00:05:59 -07006033
Joonwoo Park125cd4e2012-12-11 15:16:11 -08006034 atomic_set(&kp_taiko_priv, (unsigned long)taiko);
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08006035 mutex_lock(&dapm->codec->mutex);
6036 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
6037 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
6038 snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
6039 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
6040 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
6041 snd_soc_dapm_sync(dapm);
6042 mutex_unlock(&dapm->codec->mutex);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08006043
Kiran Kandic3b24402012-06-11 00:05:59 -07006044 codec->ignore_pmdown_time = 1;
6045 return ret;
6046
Kiran Kandic3b24402012-06-11 00:05:59 -07006047err_pdata:
Kuirong Wang906ac472012-07-09 12:54:44 -07006048 kfree(ptr);
6049err_nomem_slimch:
Kiran Kandic3b24402012-06-11 00:05:59 -07006050 kfree(taiko);
6051 return ret;
6052}
6053static int taiko_codec_remove(struct snd_soc_codec *codec)
6054{
Kiran Kandic3b24402012-06-11 00:05:59 -07006055 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07006056
Joonwoo Park125cd4e2012-12-11 15:16:11 -08006057 WCD9XXX_BCL_LOCK(&taiko->resmgr);
6058 atomic_set(&kp_taiko_priv, 0);
6059
6060 if (spkr_drv_wrnd > 0)
6061 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
6062 WCD9XXX_BANDGAP_AUDIO_MODE);
6063 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
6064
Joonwoo Parka8890262012-10-15 12:04:27 -07006065 /* cleanup MBHC */
6066 wcd9xxx_mbhc_deinit(&taiko->mbhc);
6067 /* cleanup resmgr */
6068 wcd9xxx_resmgr_deinit(&taiko->resmgr);
6069
Kiran Kandic3b24402012-06-11 00:05:59 -07006070 kfree(taiko);
6071 return 0;
6072}
6073static struct snd_soc_codec_driver soc_codec_dev_taiko = {
6074 .probe = taiko_codec_probe,
6075 .remove = taiko_codec_remove,
6076
6077 .read = taiko_read,
6078 .write = taiko_write,
6079
6080 .readable_register = taiko_readable,
6081 .volatile_register = taiko_volatile,
6082
6083 .reg_cache_size = TAIKO_CACHE_SIZE,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07006084 .reg_cache_default = taiko_reset_reg_defaults,
Kiran Kandic3b24402012-06-11 00:05:59 -07006085 .reg_word_size = 1,
6086
6087 .controls = taiko_snd_controls,
6088 .num_controls = ARRAY_SIZE(taiko_snd_controls),
6089 .dapm_widgets = taiko_dapm_widgets,
6090 .num_dapm_widgets = ARRAY_SIZE(taiko_dapm_widgets),
6091 .dapm_routes = audio_map,
6092 .num_dapm_routes = ARRAY_SIZE(audio_map),
6093};
6094
6095#ifdef CONFIG_PM
6096static int taiko_suspend(struct device *dev)
6097{
6098 dev_dbg(dev, "%s: system suspend\n", __func__);
6099 return 0;
6100}
6101
6102static int taiko_resume(struct device *dev)
6103{
6104 struct platform_device *pdev = to_platform_device(dev);
6105 struct taiko_priv *taiko = platform_get_drvdata(pdev);
6106 dev_dbg(dev, "%s: system resume\n", __func__);
Joonwoo Parka8890262012-10-15 12:04:27 -07006107 /* Notify */
6108 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, WCD9XXX_EVENT_POST_RESUME);
Kiran Kandic3b24402012-06-11 00:05:59 -07006109 return 0;
6110}
6111
6112static const struct dev_pm_ops taiko_pm_ops = {
6113 .suspend = taiko_suspend,
6114 .resume = taiko_resume,
6115};
6116#endif
6117
6118static int __devinit taiko_probe(struct platform_device *pdev)
6119{
6120 int ret = 0;
6121 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
6122 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
6123 taiko_dai, ARRAY_SIZE(taiko_dai));
6124 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
6125 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
6126 taiko_i2s_dai, ARRAY_SIZE(taiko_i2s_dai));
6127 return ret;
6128}
6129static int __devexit taiko_remove(struct platform_device *pdev)
6130{
6131 snd_soc_unregister_codec(&pdev->dev);
6132 return 0;
6133}
6134static struct platform_driver taiko_codec_driver = {
6135 .probe = taiko_probe,
6136 .remove = taiko_remove,
6137 .driver = {
6138 .name = "taiko_codec",
6139 .owner = THIS_MODULE,
6140#ifdef CONFIG_PM
6141 .pm = &taiko_pm_ops,
6142#endif
6143 },
6144};
6145
6146static int __init taiko_codec_init(void)
6147{
6148 return platform_driver_register(&taiko_codec_driver);
6149}
6150
6151static void __exit taiko_codec_exit(void)
6152{
6153 platform_driver_unregister(&taiko_codec_driver);
6154}
6155
6156module_init(taiko_codec_init);
6157module_exit(taiko_codec_exit);
6158
6159MODULE_DESCRIPTION("Taiko codec driver");
6160MODULE_LICENSE("GPL v2");