blob: 80738ba22705022b34e9cdb53e0105f511e3fe8e [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,
102 MAX_CFG_REGISTERS,
103};
104
105static struct afe_param_cdc_reg_cfg mad_audio_reg_cfg[] = {
106 {
107 1,
108 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_MAIN_CTL_1),
109 HW_MAD_AUDIO_ENABLE, 0x1, 8, 0
110 },
111 {
112 1,
113 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_AUDIO_CTL_3),
114 HW_MAD_AUDIO_SLEEP_TIME, 0xF, 8, 0
115 },
116 {
117 1,
118 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_MAD_AUDIO_CTL_4),
119 HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, 8, 0
120 },
121 {
122 1,
123 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_DESTN3),
124 MAD_AUDIO_INT_DEST_SELECT_REG, 0x1, 8, 0
125 },
126 {
127 1,
128 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_MASK3),
129 MAD_AUDIO_INT_MASK_REG, 0x1, 8, 0
130 },
131 {
132 1,
133 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_STATUS3),
134 MAD_AUDIO_INT_STATUS_REG, 0x1, 8, 0
135 },
136 {
137 1,
138 (TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_CLEAR3),
139 MAD_AUDIO_INT_CLEAR_REG, 0x1, 8, 0
140 },
141 {
142 1,
143 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_TX_BASE),
144 SB_PGD_PORT_TX_WATERMARK_n, 0x1E, 8, 0x1
145 },
146 {
147 1,
148 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_TX_BASE),
149 SB_PGD_PORT_TX_ENABLE_n, 0x1, 8, 0x1
150 },
151 {
152 1,
153 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_RX_BASE),
154 SB_PGD_PORT_RX_WATERMARK_n, 0x1E, 8, 0x1
155 },
156 {
157 1,
158 (TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_RX_BASE),
159 SB_PGD_PORT_RX_ENABLE_n, 0x1, 8, 0x1
160 }
161};
162
163static struct afe_param_cdc_reg_cfg_data taiko_mad_audio_reg_cfg = {
164 .num_registers = ARRAY_SIZE(mad_audio_reg_cfg),
165 .reg_data = mad_audio_reg_cfg,
166};
167
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800168module_param_cb(spkr_drv_wrnd, &spkr_drv_wrnd_param_ops, &spkr_drv_wrnd, 0644);
169MODULE_PARM_DESC(spkr_drv_wrnd,
170 "Run software workaround to avoid leakage on the speaker drive");
171
Kiran Kandic3b24402012-06-11 00:05:59 -0700172#define WCD9320_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
173 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
174 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
175
Kiran Kandic3b24402012-06-11 00:05:59 -0700176#define NUM_DECIMATORS 10
177#define NUM_INTERPOLATORS 7
178#define BITS_PER_REG 8
Kuirong Wang906ac472012-07-09 12:54:44 -0700179#define TAIKO_TX_PORT_NUMBER 16
Kiran Kandic3b24402012-06-11 00:05:59 -0700180
Kiran Kandic3b24402012-06-11 00:05:59 -0700181#define TAIKO_I2S_MASTER_MODE_MASK 0x08
Venkat Sudhira41630a2012-10-27 00:57:31 -0700182#define TAIKO_MCLK_CLK_12P288MHZ 12288000
183#define TAIKO_MCLK_CLK_9P6HZ 9600000
Joonwoo Park9bbb4d12012-11-09 19:58:11 -0800184
185#define TAIKO_SLIM_CLOSE_TIMEOUT 1000
186#define TAIKO_SLIM_IRQ_OVERFLOW (1 << 0)
187#define TAIKO_SLIM_IRQ_UNDERFLOW (1 << 1)
188#define TAIKO_SLIM_IRQ_PORT_CLOSED (1 << 2)
Venkat Sudhira50a3762012-11-26 12:12:15 -0800189#define TAIKO_MCLK_CLK_12P288MHZ 12288000
190#define TAIKO_MCLK_CLK_9P6HZ 9600000
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -0800191
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -0800192#define TAIKO_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
193 SNDRV_PCM_FORMAT_S24_LE)
194
195#define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
196
Kuirong Wang906ac472012-07-09 12:54:44 -0700197enum {
198 AIF1_PB = 0,
199 AIF1_CAP,
200 AIF2_PB,
201 AIF2_CAP,
202 AIF3_PB,
203 AIF3_CAP,
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -0500204 AIF4_VIFEED,
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800205 AIF4_MAD_TX,
Kuirong Wang906ac472012-07-09 12:54:44 -0700206 NUM_CODEC_DAIS,
Kiran Kandic3b24402012-06-11 00:05:59 -0700207};
208
Kuirong Wang906ac472012-07-09 12:54:44 -0700209enum {
210 RX_MIX1_INP_SEL_ZERO = 0,
211 RX_MIX1_INP_SEL_SRC1,
212 RX_MIX1_INP_SEL_SRC2,
213 RX_MIX1_INP_SEL_IIR1,
214 RX_MIX1_INP_SEL_IIR2,
215 RX_MIX1_INP_SEL_RX1,
216 RX_MIX1_INP_SEL_RX2,
217 RX_MIX1_INP_SEL_RX3,
218 RX_MIX1_INP_SEL_RX4,
219 RX_MIX1_INP_SEL_RX5,
220 RX_MIX1_INP_SEL_RX6,
221 RX_MIX1_INP_SEL_RX7,
222 RX_MIX1_INP_SEL_AUXRX,
223};
224
225#define TAIKO_COMP_DIGITAL_GAIN_OFFSET 3
226
Kiran Kandic3b24402012-06-11 00:05:59 -0700227static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
228static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
229static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
230static struct snd_soc_dai_driver taiko_dai[];
231static const DECLARE_TLV_DB_SCALE(aux_pga_gain, 0, 2, 0);
232
Kiran Kandic3b24402012-06-11 00:05:59 -0700233/* Codec supports 2 IIR filters */
234enum {
235 IIR1 = 0,
236 IIR2,
237 IIR_MAX,
238};
239/* Codec supports 5 bands */
240enum {
241 BAND1 = 0,
242 BAND2,
243 BAND3,
244 BAND4,
245 BAND5,
246 BAND_MAX,
247};
248
249enum {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700250 COMPANDER_0,
251 COMPANDER_1,
Kiran Kandic3b24402012-06-11 00:05:59 -0700252 COMPANDER_2,
253 COMPANDER_MAX,
254};
255
256enum {
257 COMPANDER_FS_8KHZ = 0,
258 COMPANDER_FS_16KHZ,
259 COMPANDER_FS_32KHZ,
260 COMPANDER_FS_48KHZ,
261 COMPANDER_FS_96KHZ,
262 COMPANDER_FS_192KHZ,
263 COMPANDER_FS_MAX,
264};
265
Kiran Kandic3b24402012-06-11 00:05:59 -0700266struct comp_sample_dependent_params {
267 u32 peak_det_timeout;
268 u32 rms_meter_div_fact;
269 u32 rms_meter_resamp_fact;
270};
271
Kiran Kandic3b24402012-06-11 00:05:59 -0700272struct hpf_work {
273 struct taiko_priv *taiko;
274 u32 decimator;
275 u8 tx_hpf_cut_of_freq;
276 struct delayed_work dwork;
277};
278
279static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
280
Kuirong Wang906ac472012-07-09 12:54:44 -0700281static const struct wcd9xxx_ch taiko_rx_chs[TAIKO_RX_MAX] = {
282 WCD9XXX_CH(16, 0),
283 WCD9XXX_CH(17, 1),
284 WCD9XXX_CH(18, 2),
285 WCD9XXX_CH(19, 3),
286 WCD9XXX_CH(20, 4),
287 WCD9XXX_CH(21, 5),
288 WCD9XXX_CH(22, 6),
289 WCD9XXX_CH(23, 7),
290 WCD9XXX_CH(24, 8),
291 WCD9XXX_CH(25, 9),
292 WCD9XXX_CH(26, 10),
293 WCD9XXX_CH(27, 11),
294 WCD9XXX_CH(28, 12),
295};
296
297static const struct wcd9xxx_ch taiko_tx_chs[TAIKO_TX_MAX] = {
298 WCD9XXX_CH(0, 0),
299 WCD9XXX_CH(1, 1),
300 WCD9XXX_CH(2, 2),
301 WCD9XXX_CH(3, 3),
302 WCD9XXX_CH(4, 4),
303 WCD9XXX_CH(5, 5),
304 WCD9XXX_CH(6, 6),
305 WCD9XXX_CH(7, 7),
306 WCD9XXX_CH(8, 8),
307 WCD9XXX_CH(9, 9),
308 WCD9XXX_CH(10, 10),
309 WCD9XXX_CH(11, 11),
310 WCD9XXX_CH(12, 12),
311 WCD9XXX_CH(13, 13),
312 WCD9XXX_CH(14, 14),
313 WCD9XXX_CH(15, 15),
314};
315
316static const u32 vport_check_table[NUM_CODEC_DAIS] = {
317 0, /* AIF1_PB */
318 (1 << AIF2_CAP) | (1 << AIF3_CAP), /* AIF1_CAP */
319 0, /* AIF2_PB */
320 (1 << AIF1_CAP) | (1 << AIF3_CAP), /* AIF2_CAP */
321 0, /* AIF2_PB */
322 (1 << AIF1_CAP) | (1 << AIF2_CAP), /* AIF2_CAP */
323};
324
Venkat Sudhir96dd28c2012-12-04 17:00:19 -0800325static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
326 0, /* AIF1_PB */
327 0, /* AIF1_CAP */
Venkat Sudhir994193b2012-12-17 17:30:51 -0800328 0, /* AIF2_PB */
329 0, /* AIF2_CAP */
Venkat Sudhir96dd28c2012-12-04 17:00:19 -0800330};
331
Kiran Kandic3b24402012-06-11 00:05:59 -0700332struct taiko_priv {
333 struct snd_soc_codec *codec;
Kiran Kandic3b24402012-06-11 00:05:59 -0700334 u32 adc_count;
Kiran Kandic3b24402012-06-11 00:05:59 -0700335 u32 rx_bias_count;
336 s32 dmic_1_2_clk_cnt;
337 s32 dmic_3_4_clk_cnt;
338 s32 dmic_5_6_clk_cnt;
339
Kiran Kandic3b24402012-06-11 00:05:59 -0700340 u32 anc_slot;
Damir Didjusto2cb06bd2013-01-30 23:14:55 -0800341 bool anc_func;
Kiran Kandic3b24402012-06-11 00:05:59 -0700342
Kiran Kandic3b24402012-06-11 00:05:59 -0700343 /*track taiko interface type*/
344 u8 intf_type;
345
Kiran Kandic3b24402012-06-11 00:05:59 -0700346 /* num of slim ports required */
Kuirong Wang906ac472012-07-09 12:54:44 -0700347 struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
Kiran Kandic3b24402012-06-11 00:05:59 -0700348
349 /*compander*/
350 int comp_enabled[COMPANDER_MAX];
351 u32 comp_fs[COMPANDER_MAX];
352
353 /* Maintain the status of AUX PGA */
354 int aux_pga_cnt;
355 u8 aux_l_gain;
356 u8 aux_r_gain;
357
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800358 bool spkr_pa_widget_on;
359
Joonwoo Park1d05bb92013-03-07 16:55:06 -0800360 struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
361
Joonwoo Parka8890262012-10-15 12:04:27 -0700362 /* resmgr module */
363 struct wcd9xxx_resmgr resmgr;
364 /* mbhc module */
365 struct wcd9xxx_mbhc mbhc;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -0800366
367 /* class h specific data */
368 struct wcd9xxx_clsh_cdc_data clsh_d;
369
Kiran Kandic3b24402012-06-11 00:05:59 -0700370};
371
Kiran Kandic3b24402012-06-11 00:05:59 -0700372static const u32 comp_shift[] = {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700373 4, /* Compander 0's clock source is on interpolator 7 */
Kiran Kandic3b24402012-06-11 00:05:59 -0700374 0,
375 2,
376};
377
378static const int comp_rx_path[] = {
379 COMPANDER_1,
380 COMPANDER_1,
381 COMPANDER_2,
382 COMPANDER_2,
383 COMPANDER_2,
384 COMPANDER_2,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700385 COMPANDER_0,
Kiran Kandic3b24402012-06-11 00:05:59 -0700386 COMPANDER_MAX,
387};
388
389static const struct comp_sample_dependent_params comp_samp_params[] = {
390 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700391 /* 8 Khz */
392 .peak_det_timeout = 0x02,
393 .rms_meter_div_fact = 0x09,
394 .rms_meter_resamp_fact = 0x06,
Kiran Kandic3b24402012-06-11 00:05:59 -0700395 },
396 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700397 /* 16 Khz */
398 .peak_det_timeout = 0x03,
399 .rms_meter_div_fact = 0x0A,
400 .rms_meter_resamp_fact = 0x0C,
401 },
402 {
403 /* 32 Khz */
404 .peak_det_timeout = 0x05,
405 .rms_meter_div_fact = 0x0B,
406 .rms_meter_resamp_fact = 0x1E,
407 },
408 {
409 /* 48 Khz */
410 .peak_det_timeout = 0x05,
411 .rms_meter_div_fact = 0x0B,
Kiran Kandic3b24402012-06-11 00:05:59 -0700412 .rms_meter_resamp_fact = 0x28,
413 },
Kiran Kandic3b24402012-06-11 00:05:59 -0700414 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700415 /* 96 Khz */
416 .peak_det_timeout = 0x06,
417 .rms_meter_div_fact = 0x0C,
418 .rms_meter_resamp_fact = 0x50,
Kiran Kandic3b24402012-06-11 00:05:59 -0700419 },
Kiran Kandic3b24402012-06-11 00:05:59 -0700420 {
Joonwoo Parkc7731432012-10-17 12:41:44 -0700421 /* 192 Khz */
422 .peak_det_timeout = 0x07,
423 .rms_meter_div_fact = 0xD,
424 .rms_meter_resamp_fact = 0xA0,
Kiran Kandic3b24402012-06-11 00:05:59 -0700425 },
426};
427
428static unsigned short rx_digital_gain_reg[] = {
429 TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
430 TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
431 TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
432 TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
433 TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
434 TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
435 TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
436};
437
438
439static unsigned short tx_digital_gain_reg[] = {
440 TAIKO_A_CDC_TX1_VOL_CTL_GAIN,
441 TAIKO_A_CDC_TX2_VOL_CTL_GAIN,
442 TAIKO_A_CDC_TX3_VOL_CTL_GAIN,
443 TAIKO_A_CDC_TX4_VOL_CTL_GAIN,
444 TAIKO_A_CDC_TX5_VOL_CTL_GAIN,
445 TAIKO_A_CDC_TX6_VOL_CTL_GAIN,
446 TAIKO_A_CDC_TX7_VOL_CTL_GAIN,
447 TAIKO_A_CDC_TX8_VOL_CTL_GAIN,
448 TAIKO_A_CDC_TX9_VOL_CTL_GAIN,
449 TAIKO_A_CDC_TX10_VOL_CTL_GAIN,
450};
451
Joonwoo Park125cd4e2012-12-11 15:16:11 -0800452static int spkr_drv_wrnd_param_set(const char *val,
453 const struct kernel_param *kp)
454{
455 struct snd_soc_codec *codec;
456 int ret, old;
457 struct taiko_priv *priv;
458
459 priv = (struct taiko_priv *)atomic_read(&kp_taiko_priv);
460 if (!priv) {
461 pr_debug("%s: codec isn't yet registered\n", __func__);
462 return 0;
463 }
464
465 WCD9XXX_BCL_LOCK(&priv->resmgr);
466 old = spkr_drv_wrnd;
467 ret = param_set_int(val, kp);
468 if (ret) {
469 WCD9XXX_BCL_UNLOCK(&priv->resmgr);
470 return ret;
471 }
472
473 pr_debug("%s: spkr_drv_wrnd %d -> %d\n", __func__, old, spkr_drv_wrnd);
474 codec = priv->codec;
475 if (old == 0 && spkr_drv_wrnd == 1) {
476 wcd9xxx_resmgr_get_bandgap(&priv->resmgr,
477 WCD9XXX_BANDGAP_AUDIO_MODE);
478 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
479 } else if (old == 1 && spkr_drv_wrnd == 0) {
480 wcd9xxx_resmgr_put_bandgap(&priv->resmgr,
481 WCD9XXX_BANDGAP_AUDIO_MODE);
482 if (!priv->spkr_pa_widget_on)
483 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
484 0x00);
485 }
486
487 WCD9XXX_BCL_UNLOCK(&priv->resmgr);
488 return 0;
489}
490
Kiran Kandic3b24402012-06-11 00:05:59 -0700491static int taiko_get_anc_slot(struct snd_kcontrol *kcontrol,
492 struct snd_ctl_elem_value *ucontrol)
493{
494 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
495 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
496 ucontrol->value.integer.value[0] = taiko->anc_slot;
497 return 0;
498}
499
500static int taiko_put_anc_slot(struct snd_kcontrol *kcontrol,
501 struct snd_ctl_elem_value *ucontrol)
502{
503 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
504 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
505 taiko->anc_slot = ucontrol->value.integer.value[0];
506 return 0;
507}
508
Damir Didjusto2cb06bd2013-01-30 23:14:55 -0800509static int taiko_get_anc_func(struct snd_kcontrol *kcontrol,
510 struct snd_ctl_elem_value *ucontrol)
511{
512 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
513 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
514
515 ucontrol->value.integer.value[0] = (taiko->anc_func == true ? 1 : 0);
516 return 0;
517}
518
519static int taiko_put_anc_func(struct snd_kcontrol *kcontrol,
520 struct snd_ctl_elem_value *ucontrol)
521{
522 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
523 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
524 struct snd_soc_dapm_context *dapm = &codec->dapm;
525
526 mutex_lock(&dapm->codec->mutex);
527 taiko->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
528
529 dev_dbg(codec->dev, "%s: anc_func %x", __func__, taiko->anc_func);
530
531 if (taiko->anc_func == true) {
532 snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
533 snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
534 snd_soc_dapm_enable_pin(dapm, "ANC HEADPHONE");
535 snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
536 snd_soc_dapm_enable_pin(dapm, "ANC EAR");
537 snd_soc_dapm_disable_pin(dapm, "HPHR");
538 snd_soc_dapm_disable_pin(dapm, "HPHL");
539 snd_soc_dapm_disable_pin(dapm, "HEADPHONE");
540 snd_soc_dapm_disable_pin(dapm, "EAR PA");
541 snd_soc_dapm_disable_pin(dapm, "EAR");
542 } else {
543 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
544 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
545 snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
546 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
547 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
548 snd_soc_dapm_enable_pin(dapm, "HPHR");
549 snd_soc_dapm_enable_pin(dapm, "HPHL");
550 snd_soc_dapm_enable_pin(dapm, "HEADPHONE");
551 snd_soc_dapm_enable_pin(dapm, "EAR PA");
552 snd_soc_dapm_enable_pin(dapm, "EAR");
553 }
554 snd_soc_dapm_sync(dapm);
555 mutex_unlock(&dapm->codec->mutex);
556 return 0;
557}
558
Kiran Kandic3b24402012-06-11 00:05:59 -0700559static int taiko_pa_gain_get(struct snd_kcontrol *kcontrol,
560 struct snd_ctl_elem_value *ucontrol)
561{
562 u8 ear_pa_gain;
563 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
564
565 ear_pa_gain = snd_soc_read(codec, TAIKO_A_RX_EAR_GAIN);
566
567 ear_pa_gain = ear_pa_gain >> 5;
568
569 if (ear_pa_gain == 0x00) {
570 ucontrol->value.integer.value[0] = 0;
571 } else if (ear_pa_gain == 0x04) {
572 ucontrol->value.integer.value[0] = 1;
573 } else {
574 pr_err("%s: ERROR: Unsupported Ear Gain = 0x%x\n",
575 __func__, ear_pa_gain);
576 return -EINVAL;
577 }
578
579 pr_debug("%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
580
581 return 0;
582}
583
584static int taiko_pa_gain_put(struct snd_kcontrol *kcontrol,
585 struct snd_ctl_elem_value *ucontrol)
586{
587 u8 ear_pa_gain;
588 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
589
590 pr_debug("%s: ucontrol->value.integer.value[0] = %ld\n", __func__,
591 ucontrol->value.integer.value[0]);
592
593 switch (ucontrol->value.integer.value[0]) {
594 case 0:
595 ear_pa_gain = 0x00;
596 break;
597 case 1:
598 ear_pa_gain = 0x80;
599 break;
600 default:
601 return -EINVAL;
602 }
603
604 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_GAIN, 0xE0, ear_pa_gain);
605 return 0;
606}
607
608static int taiko_get_iir_enable_audio_mixer(
609 struct snd_kcontrol *kcontrol,
610 struct snd_ctl_elem_value *ucontrol)
611{
612 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
613 int iir_idx = ((struct soc_multi_mixer_control *)
614 kcontrol->private_value)->reg;
615 int band_idx = ((struct soc_multi_mixer_control *)
616 kcontrol->private_value)->shift;
617
618 ucontrol->value.integer.value[0] =
Ben Romberger205e14d2013-02-06 12:31:53 -0800619 (snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
620 (1 << band_idx)) != 0;
Kiran Kandic3b24402012-06-11 00:05:59 -0700621
622 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
623 iir_idx, band_idx,
624 (uint32_t)ucontrol->value.integer.value[0]);
625 return 0;
626}
627
628static int taiko_put_iir_enable_audio_mixer(
629 struct snd_kcontrol *kcontrol,
630 struct snd_ctl_elem_value *ucontrol)
631{
632 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
633 int iir_idx = ((struct soc_multi_mixer_control *)
634 kcontrol->private_value)->reg;
635 int band_idx = ((struct soc_multi_mixer_control *)
636 kcontrol->private_value)->shift;
637 int value = ucontrol->value.integer.value[0];
638
639 /* Mask first 5 bits, 6-8 are reserved */
640 snd_soc_update_bits(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx),
641 (1 << band_idx), (value << band_idx));
642
643 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
Ben Romberger205e14d2013-02-06 12:31:53 -0800644 iir_idx, band_idx,
645 ((snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
646 (1 << band_idx)) != 0));
Kiran Kandic3b24402012-06-11 00:05:59 -0700647 return 0;
648}
649static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
650 int iir_idx, int band_idx,
651 int coeff_idx)
652{
Ben Romberger205e14d2013-02-06 12:31:53 -0800653 uint32_t value = 0;
654
Kiran Kandic3b24402012-06-11 00:05:59 -0700655 /* Address does not automatically update if reading */
656 snd_soc_write(codec,
657 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
Ben Romberger205e14d2013-02-06 12:31:53 -0800658 ((band_idx * BAND_MAX + coeff_idx)
659 * sizeof(uint32_t)) & 0x7F);
660
661 value |= snd_soc_read(codec,
662 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx));
663
664 snd_soc_write(codec,
665 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
666 ((band_idx * BAND_MAX + coeff_idx)
667 * sizeof(uint32_t) + 1) & 0x7F);
668
669 value |= (snd_soc_read(codec,
670 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 8);
671
672 snd_soc_write(codec,
673 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
674 ((band_idx * BAND_MAX + coeff_idx)
675 * sizeof(uint32_t) + 2) & 0x7F);
676
677 value |= (snd_soc_read(codec,
678 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 16);
679
680 snd_soc_write(codec,
681 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
682 ((band_idx * BAND_MAX + coeff_idx)
683 * sizeof(uint32_t) + 3) & 0x7F);
Kiran Kandic3b24402012-06-11 00:05:59 -0700684
685 /* Mask bits top 2 bits since they are reserved */
Ben Romberger205e14d2013-02-06 12:31:53 -0800686 value |= ((snd_soc_read(codec,
687 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) & 0x3F) << 24);
688
689 return value;
Kiran Kandic3b24402012-06-11 00:05:59 -0700690}
691
692static int taiko_get_iir_band_audio_mixer(
693 struct snd_kcontrol *kcontrol,
694 struct snd_ctl_elem_value *ucontrol)
695{
696 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
697 int iir_idx = ((struct soc_multi_mixer_control *)
698 kcontrol->private_value)->reg;
699 int band_idx = ((struct soc_multi_mixer_control *)
700 kcontrol->private_value)->shift;
701
702 ucontrol->value.integer.value[0] =
703 get_iir_band_coeff(codec, iir_idx, band_idx, 0);
704 ucontrol->value.integer.value[1] =
705 get_iir_band_coeff(codec, iir_idx, band_idx, 1);
706 ucontrol->value.integer.value[2] =
707 get_iir_band_coeff(codec, iir_idx, band_idx, 2);
708 ucontrol->value.integer.value[3] =
709 get_iir_band_coeff(codec, iir_idx, band_idx, 3);
710 ucontrol->value.integer.value[4] =
711 get_iir_band_coeff(codec, iir_idx, band_idx, 4);
712
713 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
714 "%s: IIR #%d band #%d b1 = 0x%x\n"
715 "%s: IIR #%d band #%d b2 = 0x%x\n"
716 "%s: IIR #%d band #%d a1 = 0x%x\n"
717 "%s: IIR #%d band #%d a2 = 0x%x\n",
718 __func__, iir_idx, band_idx,
719 (uint32_t)ucontrol->value.integer.value[0],
720 __func__, iir_idx, band_idx,
721 (uint32_t)ucontrol->value.integer.value[1],
722 __func__, iir_idx, band_idx,
723 (uint32_t)ucontrol->value.integer.value[2],
724 __func__, iir_idx, band_idx,
725 (uint32_t)ucontrol->value.integer.value[3],
726 __func__, iir_idx, band_idx,
727 (uint32_t)ucontrol->value.integer.value[4]);
728 return 0;
729}
730
731static void set_iir_band_coeff(struct snd_soc_codec *codec,
732 int iir_idx, int band_idx,
Ben Romberger205e14d2013-02-06 12:31:53 -0800733 uint32_t value)
Kiran Kandic3b24402012-06-11 00:05:59 -0700734{
Kiran Kandic3b24402012-06-11 00:05:59 -0700735 snd_soc_write(codec,
Ben Romberger205e14d2013-02-06 12:31:53 -0800736 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
737 (value & 0xFF));
738
739 snd_soc_write(codec,
740 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
741 (value >> 8) & 0xFF);
742
743 snd_soc_write(codec,
744 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
745 (value >> 16) & 0xFF);
Kiran Kandic3b24402012-06-11 00:05:59 -0700746
747 /* Mask top 2 bits, 7-8 are reserved */
748 snd_soc_write(codec,
749 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
750 (value >> 24) & 0x3F);
Kiran Kandic3b24402012-06-11 00:05:59 -0700751}
752
753static int taiko_put_iir_band_audio_mixer(
754 struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
756{
757 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
758 int iir_idx = ((struct soc_multi_mixer_control *)
759 kcontrol->private_value)->reg;
760 int band_idx = ((struct soc_multi_mixer_control *)
761 kcontrol->private_value)->shift;
762
Ben Romberger205e14d2013-02-06 12:31:53 -0800763 /* Mask top bit it is reserved */
764 /* Updates addr automatically for each B2 write */
765 snd_soc_write(codec,
766 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
767 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
768
769 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700770 ucontrol->value.integer.value[0]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800771 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700772 ucontrol->value.integer.value[1]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800773 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700774 ucontrol->value.integer.value[2]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800775 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700776 ucontrol->value.integer.value[3]);
Ben Romberger205e14d2013-02-06 12:31:53 -0800777 set_iir_band_coeff(codec, iir_idx, band_idx,
Kiran Kandic3b24402012-06-11 00:05:59 -0700778 ucontrol->value.integer.value[4]);
779
780 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
781 "%s: IIR #%d band #%d b1 = 0x%x\n"
782 "%s: IIR #%d band #%d b2 = 0x%x\n"
783 "%s: IIR #%d band #%d a1 = 0x%x\n"
784 "%s: IIR #%d band #%d a2 = 0x%x\n",
785 __func__, iir_idx, band_idx,
786 get_iir_band_coeff(codec, iir_idx, band_idx, 0),
787 __func__, iir_idx, band_idx,
788 get_iir_band_coeff(codec, iir_idx, band_idx, 1),
789 __func__, iir_idx, band_idx,
790 get_iir_band_coeff(codec, iir_idx, band_idx, 2),
791 __func__, iir_idx, band_idx,
792 get_iir_band_coeff(codec, iir_idx, band_idx, 3),
793 __func__, iir_idx, band_idx,
794 get_iir_band_coeff(codec, iir_idx, band_idx, 4));
795 return 0;
796}
797
Kiran Kandic3b24402012-06-11 00:05:59 -0700798static int taiko_get_compander(struct snd_kcontrol *kcontrol,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700799 struct snd_ctl_elem_value *ucontrol)
Kiran Kandic3b24402012-06-11 00:05:59 -0700800{
801
802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
803 int comp = ((struct soc_multi_mixer_control *)
Joonwoo Parkc7731432012-10-17 12:41:44 -0700804 kcontrol->private_value)->shift;
Kiran Kandic3b24402012-06-11 00:05:59 -0700805 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
806
807 ucontrol->value.integer.value[0] = taiko->comp_enabled[comp];
Kiran Kandic3b24402012-06-11 00:05:59 -0700808 return 0;
809}
810
811static int taiko_set_compander(struct snd_kcontrol *kcontrol,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700812 struct snd_ctl_elem_value *ucontrol)
Kiran Kandic3b24402012-06-11 00:05:59 -0700813{
814 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
815 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
816 int comp = ((struct soc_multi_mixer_control *)
Joonwoo Parkc7731432012-10-17 12:41:44 -0700817 kcontrol->private_value)->shift;
Kiran Kandic3b24402012-06-11 00:05:59 -0700818 int value = ucontrol->value.integer.value[0];
819
Joonwoo Parkc7731432012-10-17 12:41:44 -0700820 pr_debug("%s: Compander %d enable current %d, new %d\n",
821 __func__, comp, taiko->comp_enabled[comp], value);
Kiran Kandic3b24402012-06-11 00:05:59 -0700822 taiko->comp_enabled[comp] = value;
823 return 0;
824}
825
Joonwoo Parkc7731432012-10-17 12:41:44 -0700826static int taiko_config_gain_compander(struct snd_soc_codec *codec,
827 int comp, bool enable)
828{
829 int ret = 0;
830
831 switch (comp) {
832 case COMPANDER_0:
833 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_GAIN,
834 1 << 2, !enable << 2);
835 break;
836 case COMPANDER_1:
837 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_L_GAIN,
838 1 << 5, !enable << 5);
839 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_R_GAIN,
840 1 << 5, !enable << 5);
841 break;
842 case COMPANDER_2:
843 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_1_GAIN,
844 1 << 5, !enable << 5);
845 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_3_GAIN,
846 1 << 5, !enable << 5);
847 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_2_GAIN,
848 1 << 5, !enable << 5);
849 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_4_GAIN,
850 1 << 5, !enable << 5);
851 break;
852 default:
853 WARN_ON(1);
854 ret = -EINVAL;
855 }
856
857 return ret;
858}
859
860static void taiko_discharge_comp(struct snd_soc_codec *codec, int comp)
861{
862 /* Update RSM to 1, DIVF to 5 */
863 snd_soc_write(codec, TAIKO_A_CDC_COMP0_B3_CTL + (comp * 8), 1);
864 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8), 0xF0,
865 1 << 5);
866 /* Wait for 1ms */
867 usleep_range(1000, 1000);
868}
Kiran Kandic3b24402012-06-11 00:05:59 -0700869
870static int taiko_config_compander(struct snd_soc_dapm_widget *w,
Joonwoo Parkc7731432012-10-17 12:41:44 -0700871 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -0700872{
Joonwoo Parkc7731432012-10-17 12:41:44 -0700873 int mask, emask;
874 bool timedout;
875 unsigned long timeout;
Kiran Kandic3b24402012-06-11 00:05:59 -0700876 struct snd_soc_codec *codec = w->codec;
877 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parkc7731432012-10-17 12:41:44 -0700878 const int comp = w->shift;
879 const u32 rate = taiko->comp_fs[comp];
880 const struct comp_sample_dependent_params *comp_params =
881 &comp_samp_params[rate];
Kiran Kandic3b24402012-06-11 00:05:59 -0700882
Joonwoo Parkc7731432012-10-17 12:41:44 -0700883 pr_debug("%s: %s event %d compander %d, enabled %d", __func__,
884 w->name, event, comp, taiko->comp_enabled[comp]);
885
886 if (!taiko->comp_enabled[comp])
887 return 0;
888
889 /* Compander 0 has single channel */
890 mask = (comp == COMPANDER_0 ? 0x01 : 0x03);
891 emask = (comp == COMPANDER_0 ? 0x02 : 0x03);
Kiran Kandid2b46332012-10-05 12:04:00 -0700892
Kiran Kandic3b24402012-06-11 00:05:59 -0700893 switch (event) {
894 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parkc7731432012-10-17 12:41:44 -0700895 /* Set gain source to compander */
896 taiko_config_gain_compander(codec, comp, true);
897 /* Enable RX interpolation path clocks */
898 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
899 mask << comp_shift[comp],
900 mask << comp_shift[comp]);
901
902 taiko_discharge_comp(codec, comp);
903
904 /* Clear compander halt */
905 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP0_B1_CTL +
906 (comp * 8),
907 1 << 2, 0);
908 /* Toggle compander reset bits */
909 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
910 mask << comp_shift[comp],
911 mask << comp_shift[comp]);
912 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
913 mask << comp_shift[comp], 0);
Kiran Kandic3b24402012-06-11 00:05:59 -0700914 break;
915 case SND_SOC_DAPM_POST_PMU:
Joonwoo Parkc7731432012-10-17 12:41:44 -0700916 /* Set sample rate dependent paramater */
917 snd_soc_update_bits(codec,
918 TAIKO_A_CDC_COMP0_FS_CFG + (comp * 8),
919 0x07, rate);
920 snd_soc_write(codec, TAIKO_A_CDC_COMP0_B3_CTL + (comp * 8),
921 comp_params->rms_meter_resamp_fact);
922 snd_soc_update_bits(codec,
923 TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8),
924 0x0F, comp_params->peak_det_timeout);
925 snd_soc_update_bits(codec,
926 TAIKO_A_CDC_COMP0_B2_CTL + (comp * 8),
927 0xF0, comp_params->rms_meter_div_fact << 4);
928 /* Compander enable */
929 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP0_B1_CTL +
930 (comp * 8), emask, emask);
Kiran Kandic3b24402012-06-11 00:05:59 -0700931 break;
932 case SND_SOC_DAPM_PRE_PMD:
Joonwoo Parkc7731432012-10-17 12:41:44 -0700933 /* Halt compander */
934 snd_soc_update_bits(codec,
935 TAIKO_A_CDC_COMP0_B1_CTL + (comp * 8),
936 1 << 2, 1 << 2);
937 /* Wait up to a second for shutdown complete */
938 timeout = jiffies + HZ;
939 do {
940 if ((snd_soc_read(codec,
941 TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS +
942 (comp * 8)) & mask) == mask)
943 break;
944 } while (!(timedout = time_after(jiffies, timeout)));
945 pr_debug("%s: Compander %d shutdown %s in %dms\n", __func__,
946 comp, timedout ? "timedout" : "completed",
947 jiffies_to_msecs(timeout - HZ - jiffies));
Kiran Kandic3b24402012-06-11 00:05:59 -0700948 break;
949 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parkc7731432012-10-17 12:41:44 -0700950 /* Disable compander */
951 snd_soc_update_bits(codec,
952 TAIKO_A_CDC_COMP0_B1_CTL + (comp * 8),
953 emask, 0x00);
954 /* Turn off the clock for compander in pair */
955 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
956 mask << comp_shift[comp], 0);
957 /* Set gain source to register */
958 taiko_config_gain_compander(codec, comp, false);
Kiran Kandic3b24402012-06-11 00:05:59 -0700959 break;
960 }
961 return 0;
962}
963
964static const char * const taiko_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
965static const struct soc_enum taiko_ear_pa_gain_enum[] = {
966 SOC_ENUM_SINGLE_EXT(2, taiko_ear_pa_gain_text),
967};
968
Damir Didjusto2cb06bd2013-01-30 23:14:55 -0800969static const char *const taiko_anc_func_text[] = {"OFF", "ON"};
970static const struct soc_enum taiko_anc_func_enum =
971 SOC_ENUM_SINGLE_EXT(2, taiko_anc_func_text);
972
973static const char *const tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
974static const struct soc_enum tabla_ear_pa_gain_enum[] = {
975 SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
976};
977
Kiran Kandic3b24402012-06-11 00:05:59 -0700978/*cut of frequency for high pass filter*/
979static const char * const cf_text[] = {
980 "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
981};
982
983static const struct soc_enum cf_dec1_enum =
984 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX1_MUX_CTL, 4, 3, cf_text);
985
986static const struct soc_enum cf_dec2_enum =
987 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX2_MUX_CTL, 4, 3, cf_text);
988
989static const struct soc_enum cf_dec3_enum =
990 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX3_MUX_CTL, 4, 3, cf_text);
991
992static const struct soc_enum cf_dec4_enum =
993 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX4_MUX_CTL, 4, 3, cf_text);
994
995static const struct soc_enum cf_dec5_enum =
996 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX5_MUX_CTL, 4, 3, cf_text);
997
998static const struct soc_enum cf_dec6_enum =
999 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX6_MUX_CTL, 4, 3, cf_text);
1000
1001static const struct soc_enum cf_dec7_enum =
1002 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX7_MUX_CTL, 4, 3, cf_text);
1003
1004static const struct soc_enum cf_dec8_enum =
1005 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX8_MUX_CTL, 4, 3, cf_text);
1006
1007static const struct soc_enum cf_dec9_enum =
1008 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX9_MUX_CTL, 4, 3, cf_text);
1009
1010static const struct soc_enum cf_dec10_enum =
1011 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX10_MUX_CTL, 4, 3, cf_text);
1012
1013static const struct soc_enum cf_rxmix1_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001014 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX1_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001015
1016static const struct soc_enum cf_rxmix2_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001017 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX2_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001018
1019static const struct soc_enum cf_rxmix3_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001020 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX3_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001021
1022static const struct soc_enum cf_rxmix4_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001023 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX4_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001024
1025static const struct soc_enum cf_rxmix5_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001026 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX5_B4_CTL, 0, 3, cf_text)
Kiran Kandic3b24402012-06-11 00:05:59 -07001027;
1028static const struct soc_enum cf_rxmix6_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001029 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX6_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001030
1031static const struct soc_enum cf_rxmix7_enum =
Joonwoo Park2000a982013-03-01 14:50:31 -08001032 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX7_B4_CTL, 0, 3, cf_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001033
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08001034static const char * const class_h_dsm_text[] = {
1035 "ZERO", "DSM_HPHL_RX1", "DSM_SPKR_RX7"
1036};
1037
1038static const struct soc_enum class_h_dsm_enum =
1039 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_CLSH_CTL, 4, 3, class_h_dsm_text);
1040
1041static const struct snd_kcontrol_new class_h_dsm_mux =
1042 SOC_DAPM_ENUM("CLASS_H_DSM MUX Mux", class_h_dsm_enum);
1043
1044
Kiran Kandic3b24402012-06-11 00:05:59 -07001045static const struct snd_kcontrol_new taiko_snd_controls[] = {
1046
1047 SOC_ENUM_EXT("EAR PA Gain", taiko_ear_pa_gain_enum[0],
1048 taiko_pa_gain_get, taiko_pa_gain_put),
1049
1050 SOC_SINGLE_TLV("LINEOUT1 Volume", TAIKO_A_RX_LINE_1_GAIN, 0, 12, 1,
1051 line_gain),
1052 SOC_SINGLE_TLV("LINEOUT2 Volume", TAIKO_A_RX_LINE_2_GAIN, 0, 12, 1,
1053 line_gain),
1054 SOC_SINGLE_TLV("LINEOUT3 Volume", TAIKO_A_RX_LINE_3_GAIN, 0, 12, 1,
1055 line_gain),
1056 SOC_SINGLE_TLV("LINEOUT4 Volume", TAIKO_A_RX_LINE_4_GAIN, 0, 12, 1,
1057 line_gain),
1058
1059 SOC_SINGLE_TLV("HPHL Volume", TAIKO_A_RX_HPH_L_GAIN, 0, 12, 1,
1060 line_gain),
1061 SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 12, 1,
1062 line_gain),
1063
Kiran Kandifd0a1da2013-01-21 09:58:45 -08001064 SOC_SINGLE_TLV("SPK DRV Volume", TAIKO_A_SPKR_DRV_GAIN, 3, 7, 1,
1065 line_gain),
1066
Kiran Kandic3b24402012-06-11 00:05:59 -07001067 SOC_SINGLE_S8_TLV("RX1 Digital Volume", TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
1068 -84, 40, digital_gain),
1069 SOC_SINGLE_S8_TLV("RX2 Digital Volume", TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
1070 -84, 40, digital_gain),
1071 SOC_SINGLE_S8_TLV("RX3 Digital Volume", TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
1072 -84, 40, digital_gain),
1073 SOC_SINGLE_S8_TLV("RX4 Digital Volume", TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
1074 -84, 40, digital_gain),
1075 SOC_SINGLE_S8_TLV("RX5 Digital Volume", TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
1076 -84, 40, digital_gain),
1077 SOC_SINGLE_S8_TLV("RX6 Digital Volume", TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
1078 -84, 40, digital_gain),
1079 SOC_SINGLE_S8_TLV("RX7 Digital Volume", TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
1080 -84, 40, digital_gain),
1081
1082 SOC_SINGLE_S8_TLV("DEC1 Volume", TAIKO_A_CDC_TX1_VOL_CTL_GAIN, -84, 40,
1083 digital_gain),
1084 SOC_SINGLE_S8_TLV("DEC2 Volume", TAIKO_A_CDC_TX2_VOL_CTL_GAIN, -84, 40,
1085 digital_gain),
1086 SOC_SINGLE_S8_TLV("DEC3 Volume", TAIKO_A_CDC_TX3_VOL_CTL_GAIN, -84, 40,
1087 digital_gain),
1088 SOC_SINGLE_S8_TLV("DEC4 Volume", TAIKO_A_CDC_TX4_VOL_CTL_GAIN, -84, 40,
1089 digital_gain),
1090 SOC_SINGLE_S8_TLV("DEC5 Volume", TAIKO_A_CDC_TX5_VOL_CTL_GAIN, -84, 40,
1091 digital_gain),
1092 SOC_SINGLE_S8_TLV("DEC6 Volume", TAIKO_A_CDC_TX6_VOL_CTL_GAIN, -84, 40,
1093 digital_gain),
1094 SOC_SINGLE_S8_TLV("DEC7 Volume", TAIKO_A_CDC_TX7_VOL_CTL_GAIN, -84, 40,
1095 digital_gain),
1096 SOC_SINGLE_S8_TLV("DEC8 Volume", TAIKO_A_CDC_TX8_VOL_CTL_GAIN, -84, 40,
1097 digital_gain),
1098 SOC_SINGLE_S8_TLV("DEC9 Volume", TAIKO_A_CDC_TX9_VOL_CTL_GAIN, -84, 40,
1099 digital_gain),
1100 SOC_SINGLE_S8_TLV("DEC10 Volume", TAIKO_A_CDC_TX10_VOL_CTL_GAIN, -84,
1101 40, digital_gain),
1102 SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, -84,
1103 40, digital_gain),
1104 SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", TAIKO_A_CDC_IIR1_GAIN_B2_CTL, -84,
1105 40, digital_gain),
1106 SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", TAIKO_A_CDC_IIR1_GAIN_B3_CTL, -84,
1107 40, digital_gain),
1108 SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", TAIKO_A_CDC_IIR1_GAIN_B4_CTL, -84,
1109 40, digital_gain),
1110 SOC_SINGLE_TLV("ADC1 Volume", TAIKO_A_TX_1_2_EN, 5, 3, 0, analog_gain),
1111 SOC_SINGLE_TLV("ADC2 Volume", TAIKO_A_TX_1_2_EN, 1, 3, 0, analog_gain),
1112 SOC_SINGLE_TLV("ADC3 Volume", TAIKO_A_TX_3_4_EN, 5, 3, 0, analog_gain),
1113 SOC_SINGLE_TLV("ADC4 Volume", TAIKO_A_TX_3_4_EN, 1, 3, 0, analog_gain),
1114 SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_TX_5_6_EN, 5, 3, 0, analog_gain),
1115 SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_TX_5_6_EN, 1, 3, 0, analog_gain),
1116
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001117 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, taiko_get_anc_slot,
Kiran Kandic3b24402012-06-11 00:05:59 -07001118 taiko_put_anc_slot),
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08001119 SOC_ENUM_EXT("ANC Function", taiko_anc_func_enum, taiko_get_anc_func,
1120 taiko_put_anc_func),
Kiran Kandic3b24402012-06-11 00:05:59 -07001121 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
1122 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
1123 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
1124 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
1125 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
1126 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
1127 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
1128 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
1129 SOC_ENUM("TX9 HPF cut off", cf_dec9_enum),
1130 SOC_ENUM("TX10 HPF cut off", cf_dec10_enum),
1131
1132 SOC_SINGLE("TX1 HPF Switch", TAIKO_A_CDC_TX1_MUX_CTL, 3, 1, 0),
1133 SOC_SINGLE("TX2 HPF Switch", TAIKO_A_CDC_TX2_MUX_CTL, 3, 1, 0),
1134 SOC_SINGLE("TX3 HPF Switch", TAIKO_A_CDC_TX3_MUX_CTL, 3, 1, 0),
1135 SOC_SINGLE("TX4 HPF Switch", TAIKO_A_CDC_TX4_MUX_CTL, 3, 1, 0),
1136 SOC_SINGLE("TX5 HPF Switch", TAIKO_A_CDC_TX5_MUX_CTL, 3, 1, 0),
1137 SOC_SINGLE("TX6 HPF Switch", TAIKO_A_CDC_TX6_MUX_CTL, 3, 1, 0),
1138 SOC_SINGLE("TX7 HPF Switch", TAIKO_A_CDC_TX7_MUX_CTL, 3, 1, 0),
1139 SOC_SINGLE("TX8 HPF Switch", TAIKO_A_CDC_TX8_MUX_CTL, 3, 1, 0),
1140 SOC_SINGLE("TX9 HPF Switch", TAIKO_A_CDC_TX9_MUX_CTL, 3, 1, 0),
1141 SOC_SINGLE("TX10 HPF Switch", TAIKO_A_CDC_TX10_MUX_CTL, 3, 1, 0),
1142
1143 SOC_SINGLE("RX1 HPF Switch", TAIKO_A_CDC_RX1_B5_CTL, 2, 1, 0),
1144 SOC_SINGLE("RX2 HPF Switch", TAIKO_A_CDC_RX2_B5_CTL, 2, 1, 0),
1145 SOC_SINGLE("RX3 HPF Switch", TAIKO_A_CDC_RX3_B5_CTL, 2, 1, 0),
1146 SOC_SINGLE("RX4 HPF Switch", TAIKO_A_CDC_RX4_B5_CTL, 2, 1, 0),
1147 SOC_SINGLE("RX5 HPF Switch", TAIKO_A_CDC_RX5_B5_CTL, 2, 1, 0),
1148 SOC_SINGLE("RX6 HPF Switch", TAIKO_A_CDC_RX6_B5_CTL, 2, 1, 0),
1149 SOC_SINGLE("RX7 HPF Switch", TAIKO_A_CDC_RX7_B5_CTL, 2, 1, 0),
1150
1151 SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
1152 SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
1153 SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
1154 SOC_ENUM("RX4 HPF cut off", cf_rxmix4_enum),
1155 SOC_ENUM("RX5 HPF cut off", cf_rxmix5_enum),
1156 SOC_ENUM("RX6 HPF cut off", cf_rxmix6_enum),
1157 SOC_ENUM("RX7 HPF cut off", cf_rxmix7_enum),
1158
1159 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
1160 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1161 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
1162 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1163 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
1164 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1165 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
1166 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1167 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
1168 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1169 SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
1170 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1171 SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
1172 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1173 SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
1174 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1175 SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
1176 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1177 SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
1178 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
1179
1180 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
1181 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1182 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
1183 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1184 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
1185 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1186 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
1187 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1188 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
1189 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1190 SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
1191 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1192 SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
1193 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1194 SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
1195 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1196 SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
1197 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1198 SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
1199 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
1200
Joonwoo Parkc7731432012-10-17 12:41:44 -07001201 SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_0, 1, 0,
1202 taiko_get_compander, taiko_set_compander),
1203 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
1204 taiko_get_compander, taiko_set_compander),
1205 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
1206 taiko_get_compander, taiko_set_compander),
Kiran Kandic3b24402012-06-11 00:05:59 -07001207
1208};
1209
1210static const char * const rx_mix1_text[] = {
1211 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2", "RX1", "RX2", "RX3", "RX4",
1212 "RX5", "RX6", "RX7"
1213};
1214
1215static const char * const rx_mix2_text[] = {
1216 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2"
1217};
1218
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001219static const char * const rx_rdac5_text[] = {
1220 "DEM4", "DEM3_INV"
Kiran Kandic3b24402012-06-11 00:05:59 -07001221};
1222
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001223static const char * const rx_rdac7_text[] = {
1224 "DEM6", "DEM5_INV"
1225};
1226
1227
Kiran Kandic3b24402012-06-11 00:05:59 -07001228static const char * const sb_tx1_mux_text[] = {
1229 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1230 "DEC1"
1231};
1232
1233static const char * const sb_tx2_mux_text[] = {
1234 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1235 "DEC2"
1236};
1237
1238static const char * const sb_tx3_mux_text[] = {
1239 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1240 "DEC3"
1241};
1242
1243static const char * const sb_tx4_mux_text[] = {
1244 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1245 "DEC4"
1246};
1247
1248static const char * const sb_tx5_mux_text[] = {
1249 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1250 "DEC5"
1251};
1252
1253static const char * const sb_tx6_mux_text[] = {
1254 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1255 "DEC6"
1256};
1257
1258static const char * const sb_tx7_to_tx10_mux_text[] = {
1259 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1260 "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1261 "DEC9", "DEC10"
1262};
1263
1264static const char * const dec1_mux_text[] = {
1265 "ZERO", "DMIC1", "ADC6",
1266};
1267
1268static const char * const dec2_mux_text[] = {
1269 "ZERO", "DMIC2", "ADC5",
1270};
1271
1272static const char * const dec3_mux_text[] = {
1273 "ZERO", "DMIC3", "ADC4",
1274};
1275
1276static const char * const dec4_mux_text[] = {
1277 "ZERO", "DMIC4", "ADC3",
1278};
1279
1280static const char * const dec5_mux_text[] = {
1281 "ZERO", "DMIC5", "ADC2",
1282};
1283
1284static const char * const dec6_mux_text[] = {
1285 "ZERO", "DMIC6", "ADC1",
1286};
1287
1288static const char * const dec7_mux_text[] = {
1289 "ZERO", "DMIC1", "DMIC6", "ADC1", "ADC6", "ANC1_FB", "ANC2_FB",
1290};
1291
1292static const char * const dec8_mux_text[] = {
1293 "ZERO", "DMIC2", "DMIC5", "ADC2", "ADC5",
1294};
1295
1296static const char * const dec9_mux_text[] = {
1297 "ZERO", "DMIC4", "DMIC5", "ADC2", "ADC3", "ADCMB", "ANC1_FB", "ANC2_FB",
1298};
1299
1300static const char * const dec10_mux_text[] = {
1301 "ZERO", "DMIC3", "DMIC6", "ADC1", "ADC4", "ADCMB", "ANC1_FB", "ANC2_FB",
1302};
1303
1304static const char * const anc_mux_text[] = {
1305 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC_MB",
1306 "RSVD_1", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6"
1307};
1308
1309static const char * const anc1_fb_mux_text[] = {
1310 "ZERO", "EAR_HPH_L", "EAR_LINE_1",
1311};
1312
1313static const char * const iir1_inp1_text[] = {
1314 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1315 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1316};
1317
1318static const struct soc_enum rx_mix1_inp1_chain_enum =
1319 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 0, 12, rx_mix1_text);
1320
1321static const struct soc_enum rx_mix1_inp2_chain_enum =
1322 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 4, 12, rx_mix1_text);
1323
1324static const struct soc_enum rx_mix1_inp3_chain_enum =
1325 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B2_CTL, 0, 12, rx_mix1_text);
1326
1327static const struct soc_enum rx2_mix1_inp1_chain_enum =
1328 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 0, 12, rx_mix1_text);
1329
1330static const struct soc_enum rx2_mix1_inp2_chain_enum =
1331 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 4, 12, rx_mix1_text);
1332
1333static const struct soc_enum rx3_mix1_inp1_chain_enum =
1334 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 0, 12, rx_mix1_text);
1335
1336static const struct soc_enum rx3_mix1_inp2_chain_enum =
1337 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 4, 12, rx_mix1_text);
1338
1339static const struct soc_enum rx4_mix1_inp1_chain_enum =
1340 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 0, 12, rx_mix1_text);
1341
1342static const struct soc_enum rx4_mix1_inp2_chain_enum =
1343 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 4, 12, rx_mix1_text);
1344
1345static const struct soc_enum rx5_mix1_inp1_chain_enum =
1346 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 0, 12, rx_mix1_text);
1347
1348static const struct soc_enum rx5_mix1_inp2_chain_enum =
1349 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 4, 12, rx_mix1_text);
1350
1351static const struct soc_enum rx6_mix1_inp1_chain_enum =
1352 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 0, 12, rx_mix1_text);
1353
1354static const struct soc_enum rx6_mix1_inp2_chain_enum =
1355 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 4, 12, rx_mix1_text);
1356
1357static const struct soc_enum rx7_mix1_inp1_chain_enum =
1358 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 0, 12, rx_mix1_text);
1359
1360static const struct soc_enum rx7_mix1_inp2_chain_enum =
1361 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 4, 12, rx_mix1_text);
1362
1363static const struct soc_enum rx1_mix2_inp1_chain_enum =
1364 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 0, 5, rx_mix2_text);
1365
1366static const struct soc_enum rx1_mix2_inp2_chain_enum =
1367 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 3, 5, rx_mix2_text);
1368
1369static const struct soc_enum rx2_mix2_inp1_chain_enum =
1370 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 0, 5, rx_mix2_text);
1371
1372static const struct soc_enum rx2_mix2_inp2_chain_enum =
1373 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 3, 5, rx_mix2_text);
1374
1375static const struct soc_enum rx7_mix2_inp1_chain_enum =
1376 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 0, 5, rx_mix2_text);
1377
1378static const struct soc_enum rx7_mix2_inp2_chain_enum =
1379 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 3, 5, rx_mix2_text);
1380
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001381static const struct soc_enum rx_rdac5_enum =
1382 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_MISC, 2, 2, rx_rdac5_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001383
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001384static const struct soc_enum rx_rdac7_enum =
1385 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_MISC, 1, 2, rx_rdac7_text);
Kiran Kandic3b24402012-06-11 00:05:59 -07001386
1387static const struct soc_enum sb_tx1_mux_enum =
1388 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0, 9, sb_tx1_mux_text);
1389
1390static const struct soc_enum sb_tx2_mux_enum =
1391 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0, 9, sb_tx2_mux_text);
1392
1393static const struct soc_enum sb_tx3_mux_enum =
1394 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0, 9, sb_tx3_mux_text);
1395
1396static const struct soc_enum sb_tx4_mux_enum =
1397 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0, 9, sb_tx4_mux_text);
1398
1399static const struct soc_enum sb_tx5_mux_enum =
1400 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0, 9, sb_tx5_mux_text);
1401
1402static const struct soc_enum sb_tx6_mux_enum =
1403 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0, 9, sb_tx6_mux_text);
1404
1405static const struct soc_enum sb_tx7_mux_enum =
1406 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0, 18,
1407 sb_tx7_to_tx10_mux_text);
1408
1409static const struct soc_enum sb_tx8_mux_enum =
1410 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0, 18,
1411 sb_tx7_to_tx10_mux_text);
1412
1413static const struct soc_enum sb_tx9_mux_enum =
1414 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0, 18,
1415 sb_tx7_to_tx10_mux_text);
1416
1417static const struct soc_enum sb_tx10_mux_enum =
1418 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0, 18,
1419 sb_tx7_to_tx10_mux_text);
1420
1421static const struct soc_enum dec1_mux_enum =
1422 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 0, 3, dec1_mux_text);
1423
1424static const struct soc_enum dec2_mux_enum =
1425 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 2, 3, dec2_mux_text);
1426
1427static const struct soc_enum dec3_mux_enum =
1428 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 4, 3, dec3_mux_text);
1429
1430static const struct soc_enum dec4_mux_enum =
1431 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 6, 3, dec4_mux_text);
1432
1433static const struct soc_enum dec5_mux_enum =
1434 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 0, 3, dec5_mux_text);
1435
1436static const struct soc_enum dec6_mux_enum =
1437 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 2, 3, dec6_mux_text);
1438
1439static const struct soc_enum dec7_mux_enum =
1440 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 4, 7, dec7_mux_text);
1441
1442static const struct soc_enum dec8_mux_enum =
1443 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 0, 7, dec8_mux_text);
1444
1445static const struct soc_enum dec9_mux_enum =
1446 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 3, 8, dec9_mux_text);
1447
1448static const struct soc_enum dec10_mux_enum =
1449 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B4_CTL, 0, 8, dec10_mux_text);
1450
1451static const struct soc_enum anc1_mux_enum =
1452 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 0, 16, anc_mux_text);
1453
1454static const struct soc_enum anc2_mux_enum =
1455 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 4, 16, anc_mux_text);
1456
1457static const struct soc_enum anc1_fb_mux_enum =
1458 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B2_CTL, 0, 3, anc1_fb_mux_text);
1459
1460static const struct soc_enum iir1_inp1_mux_enum =
1461 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir1_inp1_text);
1462
1463static const struct snd_kcontrol_new rx_mix1_inp1_mux =
1464 SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
1465
1466static const struct snd_kcontrol_new rx_mix1_inp2_mux =
1467 SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
1468
1469static const struct snd_kcontrol_new rx_mix1_inp3_mux =
1470 SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
1471
1472static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
1473 SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
1474
1475static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
1476 SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
1477
1478static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
1479 SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
1480
1481static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
1482 SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
1483
1484static const struct snd_kcontrol_new rx4_mix1_inp1_mux =
1485 SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum);
1486
1487static const struct snd_kcontrol_new rx4_mix1_inp2_mux =
1488 SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum);
1489
1490static const struct snd_kcontrol_new rx5_mix1_inp1_mux =
1491 SOC_DAPM_ENUM("RX5 MIX1 INP1 Mux", rx5_mix1_inp1_chain_enum);
1492
1493static const struct snd_kcontrol_new rx5_mix1_inp2_mux =
1494 SOC_DAPM_ENUM("RX5 MIX1 INP2 Mux", rx5_mix1_inp2_chain_enum);
1495
1496static const struct snd_kcontrol_new rx6_mix1_inp1_mux =
1497 SOC_DAPM_ENUM("RX6 MIX1 INP1 Mux", rx6_mix1_inp1_chain_enum);
1498
1499static const struct snd_kcontrol_new rx6_mix1_inp2_mux =
1500 SOC_DAPM_ENUM("RX6 MIX1 INP2 Mux", rx6_mix1_inp2_chain_enum);
1501
1502static const struct snd_kcontrol_new rx7_mix1_inp1_mux =
1503 SOC_DAPM_ENUM("RX7 MIX1 INP1 Mux", rx7_mix1_inp1_chain_enum);
1504
1505static const struct snd_kcontrol_new rx7_mix1_inp2_mux =
1506 SOC_DAPM_ENUM("RX7 MIX1 INP2 Mux", rx7_mix1_inp2_chain_enum);
1507
1508static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
1509 SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_mix2_inp1_chain_enum);
1510
1511static const struct snd_kcontrol_new rx1_mix2_inp2_mux =
1512 SOC_DAPM_ENUM("RX1 MIX2 INP2 Mux", rx1_mix2_inp2_chain_enum);
1513
1514static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
1515 SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
1516
1517static const struct snd_kcontrol_new rx2_mix2_inp2_mux =
1518 SOC_DAPM_ENUM("RX2 MIX2 INP2 Mux", rx2_mix2_inp2_chain_enum);
1519
1520static const struct snd_kcontrol_new rx7_mix2_inp1_mux =
1521 SOC_DAPM_ENUM("RX7 MIX2 INP1 Mux", rx7_mix2_inp1_chain_enum);
1522
1523static const struct snd_kcontrol_new rx7_mix2_inp2_mux =
1524 SOC_DAPM_ENUM("RX7 MIX2 INP2 Mux", rx7_mix2_inp2_chain_enum);
1525
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001526static const struct snd_kcontrol_new rx_dac5_mux =
1527 SOC_DAPM_ENUM("RDAC5 MUX Mux", rx_rdac5_enum);
Kiran Kandic3b24402012-06-11 00:05:59 -07001528
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02001529static const struct snd_kcontrol_new rx_dac7_mux =
1530 SOC_DAPM_ENUM("RDAC7 MUX Mux", rx_rdac7_enum);
Kiran Kandic3b24402012-06-11 00:05:59 -07001531
1532static const struct snd_kcontrol_new sb_tx1_mux =
1533 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
1534
1535static const struct snd_kcontrol_new sb_tx2_mux =
1536 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
1537
1538static const struct snd_kcontrol_new sb_tx3_mux =
1539 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
1540
1541static const struct snd_kcontrol_new sb_tx4_mux =
1542 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
1543
1544static const struct snd_kcontrol_new sb_tx5_mux =
1545 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
1546
1547static const struct snd_kcontrol_new sb_tx6_mux =
1548 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
1549
1550static const struct snd_kcontrol_new sb_tx7_mux =
1551 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
1552
1553static const struct snd_kcontrol_new sb_tx8_mux =
1554 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
1555
1556static const struct snd_kcontrol_new sb_tx9_mux =
1557 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
1558
1559static const struct snd_kcontrol_new sb_tx10_mux =
1560 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
1561
1562
1563static int wcd9320_put_dec_enum(struct snd_kcontrol *kcontrol,
1564 struct snd_ctl_elem_value *ucontrol)
1565{
1566 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1567 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1568 struct snd_soc_codec *codec = w->codec;
1569 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1570 unsigned int dec_mux, decimator;
1571 char *dec_name = NULL;
1572 char *widget_name = NULL;
1573 char *temp;
1574 u16 tx_mux_ctl_reg;
1575 u8 adc_dmic_sel = 0x0;
1576 int ret = 0;
1577
1578 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1579 return -EINVAL;
1580
1581 dec_mux = ucontrol->value.enumerated.item[0];
1582
1583 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
1584 if (!widget_name)
1585 return -ENOMEM;
1586 temp = widget_name;
1587
1588 dec_name = strsep(&widget_name, " ");
1589 widget_name = temp;
1590 if (!dec_name) {
1591 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
1592 ret = -EINVAL;
1593 goto out;
1594 }
1595
1596 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
1597 if (ret < 0) {
1598 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
1599 ret = -EINVAL;
1600 goto out;
1601 }
1602
1603 dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
1604 , __func__, w->name, decimator, dec_mux);
1605
1606
1607 switch (decimator) {
1608 case 1:
1609 case 2:
1610 case 3:
1611 case 4:
1612 case 5:
1613 case 6:
1614 if (dec_mux == 1)
1615 adc_dmic_sel = 0x1;
1616 else
1617 adc_dmic_sel = 0x0;
1618 break;
1619 case 7:
1620 case 8:
1621 case 9:
1622 case 10:
1623 if ((dec_mux == 1) || (dec_mux == 2))
1624 adc_dmic_sel = 0x1;
1625 else
1626 adc_dmic_sel = 0x0;
1627 break;
1628 default:
1629 pr_err("%s: Invalid Decimator = %u\n", __func__, decimator);
1630 ret = -EINVAL;
1631 goto out;
1632 }
1633
1634 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
1635
1636 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
1637
1638 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
1639
1640out:
1641 kfree(widget_name);
1642 return ret;
1643}
1644
1645#define WCD9320_DEC_ENUM(xname, xenum) \
1646{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1647 .info = snd_soc_info_enum_double, \
1648 .get = snd_soc_dapm_get_enum_double, \
1649 .put = wcd9320_put_dec_enum, \
1650 .private_value = (unsigned long)&xenum }
1651
1652static const struct snd_kcontrol_new dec1_mux =
1653 WCD9320_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
1654
1655static const struct snd_kcontrol_new dec2_mux =
1656 WCD9320_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
1657
1658static const struct snd_kcontrol_new dec3_mux =
1659 WCD9320_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum);
1660
1661static const struct snd_kcontrol_new dec4_mux =
1662 WCD9320_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum);
1663
1664static const struct snd_kcontrol_new dec5_mux =
1665 WCD9320_DEC_ENUM("DEC5 MUX Mux", dec5_mux_enum);
1666
1667static const struct snd_kcontrol_new dec6_mux =
1668 WCD9320_DEC_ENUM("DEC6 MUX Mux", dec6_mux_enum);
1669
1670static const struct snd_kcontrol_new dec7_mux =
1671 WCD9320_DEC_ENUM("DEC7 MUX Mux", dec7_mux_enum);
1672
1673static const struct snd_kcontrol_new dec8_mux =
1674 WCD9320_DEC_ENUM("DEC8 MUX Mux", dec8_mux_enum);
1675
1676static const struct snd_kcontrol_new dec9_mux =
1677 WCD9320_DEC_ENUM("DEC9 MUX Mux", dec9_mux_enum);
1678
1679static const struct snd_kcontrol_new dec10_mux =
1680 WCD9320_DEC_ENUM("DEC10 MUX Mux", dec10_mux_enum);
1681
1682static const struct snd_kcontrol_new iir1_inp1_mux =
1683 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
1684
1685static const struct snd_kcontrol_new anc1_mux =
1686 SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
1687
1688static const struct snd_kcontrol_new anc2_mux =
1689 SOC_DAPM_ENUM("ANC2 MUX Mux", anc2_mux_enum);
1690
1691static const struct snd_kcontrol_new anc1_fb_mux =
1692 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
1693
1694static const struct snd_kcontrol_new dac1_switch[] = {
1695 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_EAR_EN, 5, 1, 0)
1696};
1697static const struct snd_kcontrol_new hphl_switch[] = {
1698 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
1699};
1700
1701static const struct snd_kcontrol_new hphl_pa_mix[] = {
1702 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1703 7, 1, 0),
1704};
1705
1706static const struct snd_kcontrol_new hphr_pa_mix[] = {
1707 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1708 6, 1, 0),
1709};
1710
1711static const struct snd_kcontrol_new ear_pa_mix[] = {
1712 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1713 5, 1, 0),
1714};
1715static const struct snd_kcontrol_new lineout1_pa_mix[] = {
1716 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1717 4, 1, 0),
1718};
1719
1720static const struct snd_kcontrol_new lineout2_pa_mix[] = {
1721 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1722 3, 1, 0),
1723};
1724
1725static const struct snd_kcontrol_new lineout3_pa_mix[] = {
1726 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1727 2, 1, 0),
1728};
1729
1730static const struct snd_kcontrol_new lineout4_pa_mix[] = {
1731 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1732 1, 1, 0),
1733};
1734
1735static const struct snd_kcontrol_new lineout3_ground_switch =
1736 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_3_DAC_CTL, 6, 1, 0);
1737
1738static const struct snd_kcontrol_new lineout4_ground_switch =
1739 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_4_DAC_CTL, 6, 1, 0);
1740
Joonwoo Park9ead0e92013-03-18 11:33:33 -07001741static const struct snd_kcontrol_new aif4_mad_switch =
1742 SOC_DAPM_SINGLE("Switch", TAIKO_A_CDC_CLK_OTHR_CTL, 4, 1, 0);
1743
Kuirong Wang906ac472012-07-09 12:54:44 -07001744/* virtual port entries */
1745static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
1746 struct snd_ctl_elem_value *ucontrol)
1747{
1748 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1749 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1750
1751 ucontrol->value.integer.value[0] = widget->value;
1752 return 0;
1753}
1754
1755static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
1756 struct snd_ctl_elem_value *ucontrol)
1757{
1758 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1759 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1760 struct snd_soc_codec *codec = widget->codec;
1761 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
1762 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
1763 struct soc_multi_mixer_control *mixer =
1764 ((struct soc_multi_mixer_control *)kcontrol->private_value);
1765 u32 dai_id = widget->shift;
1766 u32 port_id = mixer->shift;
1767 u32 enable = ucontrol->value.integer.value[0];
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08001768 u32 vtable = vport_check_table[dai_id];
Kuirong Wang906ac472012-07-09 12:54:44 -07001769
1770
1771 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
1772 widget->name, ucontrol->id.name, widget->value, widget->shift,
1773 ucontrol->value.integer.value[0]);
1774
1775 mutex_lock(&codec->mutex);
1776
1777 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
1778 if (dai_id != AIF1_CAP) {
1779 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
1780 __func__);
1781 mutex_unlock(&codec->mutex);
1782 return -EINVAL;
1783 }
1784 }
Venkat Sudhira41630a2012-10-27 00:57:31 -07001785 switch (dai_id) {
1786 case AIF1_CAP:
1787 case AIF2_CAP:
1788 case AIF3_CAP:
1789 /* only add to the list if value not set
1790 */
1791 if (enable && !(widget->value & 1 << port_id)) {
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08001792
1793 if (taiko_p->intf_type ==
1794 WCD9XXX_INTERFACE_TYPE_SLIMBUS)
1795 vtable = vport_check_table[dai_id];
1796 if (taiko_p->intf_type ==
1797 WCD9XXX_INTERFACE_TYPE_I2C)
1798 vtable = vport_i2s_check_table[dai_id];
1799
Venkat Sudhira41630a2012-10-27 00:57:31 -07001800 if (wcd9xxx_tx_vport_validation(
Venkat Sudhir96dd28c2012-12-04 17:00:19 -08001801 vtable,
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001802 port_id,
1803 taiko_p->dai)) {
Venkat Sudhira41630a2012-10-27 00:57:31 -07001804 pr_debug("%s: TX%u is used by other\n"
1805 "virtual port\n",
1806 __func__, port_id + 1);
1807 mutex_unlock(&codec->mutex);
1808 return -EINVAL;
1809 }
1810 widget->value |= 1 << port_id;
1811 list_add_tail(&core->tx_chs[port_id].list,
Kuirong Wang906ac472012-07-09 12:54:44 -07001812 &taiko_p->dai[dai_id].wcd9xxx_ch_list
Venkat Sudhira41630a2012-10-27 00:57:31 -07001813 );
1814 } else if (!enable && (widget->value & 1 << port_id)) {
1815 widget->value &= ~(1 << port_id);
1816 list_del_init(&core->tx_chs[port_id].list);
1817 } else {
1818 if (enable)
1819 pr_debug("%s: TX%u port is used by\n"
1820 "this virtual port\n",
1821 __func__, port_id + 1);
1822 else
1823 pr_debug("%s: TX%u port is not used by\n"
1824 "this virtual port\n",
1825 __func__, port_id + 1);
1826 /* avoid update power function */
1827 mutex_unlock(&codec->mutex);
1828 return 0;
1829 }
1830 break;
1831 default:
1832 pr_err("Unknown AIF %d\n", dai_id);
Kuirong Wang906ac472012-07-09 12:54:44 -07001833 mutex_unlock(&codec->mutex);
Venkat Sudhira41630a2012-10-27 00:57:31 -07001834 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07001835 }
Kuirong Wang906ac472012-07-09 12:54:44 -07001836 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
1837 widget->name, widget->sname, widget->value, widget->shift);
1838
1839 snd_soc_dapm_mixer_update_power(widget, kcontrol, enable);
1840
1841 mutex_unlock(&codec->mutex);
1842 return 0;
1843}
1844
1845static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
1846 struct snd_ctl_elem_value *ucontrol)
1847{
1848 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1849 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1850
1851 ucontrol->value.enumerated.item[0] = widget->value;
1852 return 0;
1853}
1854
1855static const char *const slim_rx_mux_text[] = {
1856 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
1857};
1858
1859static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
1860 struct snd_ctl_elem_value *ucontrol)
1861{
1862 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1863 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1864 struct snd_soc_codec *codec = widget->codec;
1865 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
1866 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
1867 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1868 u32 port_id = widget->shift;
1869
1870 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
1871 widget->name, ucontrol->id.name, widget->value, widget->shift,
1872 ucontrol->value.integer.value[0]);
1873
1874 widget->value = ucontrol->value.enumerated.item[0];
1875
1876 mutex_lock(&codec->mutex);
1877
1878 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Venkat Sudhir994193b2012-12-17 17:30:51 -08001879 if (widget->value > 2) {
Kuirong Wang906ac472012-07-09 12:54:44 -07001880 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
1881 __func__);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001882 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001883 }
1884 }
1885 /* value need to match the Virtual port and AIF number
1886 */
1887 switch (widget->value) {
1888 case 0:
1889 list_del_init(&core->rx_chs[port_id].list);
1890 break;
1891 case 1:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001892 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
1893 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list))
1894 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001895 list_add_tail(&core->rx_chs[port_id].list,
1896 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list);
1897 break;
1898 case 2:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001899 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05001900 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list))
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001901 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001902 list_add_tail(&core->rx_chs[port_id].list,
1903 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list);
1904 break;
1905 case 3:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001906 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05001907 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list))
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001908 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001909 list_add_tail(&core->rx_chs[port_id].list,
1910 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list);
1911 break;
1912 default:
1913 pr_err("Unknown AIF %d\n", widget->value);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001914 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001915 }
1916
1917 snd_soc_dapm_mux_update_power(widget, kcontrol, 1, widget->value, e);
1918
1919 mutex_unlock(&codec->mutex);
1920 return 0;
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001921pr_err:
1922 pr_err("%s: RX%u is used by current requesting AIF_PB itself\n",
1923 __func__, port_id + 1);
1924err:
1925 mutex_unlock(&codec->mutex);
1926 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07001927}
1928
1929static const struct soc_enum slim_rx_mux_enum =
1930 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
1931
1932static const struct snd_kcontrol_new slim_rx_mux[TAIKO_RX_MAX] = {
1933 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
1934 slim_rx_mux_get, slim_rx_mux_put),
1935 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
1936 slim_rx_mux_get, slim_rx_mux_put),
1937 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
1938 slim_rx_mux_get, slim_rx_mux_put),
1939 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
1940 slim_rx_mux_get, slim_rx_mux_put),
1941 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
1942 slim_rx_mux_get, slim_rx_mux_put),
1943 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
1944 slim_rx_mux_get, slim_rx_mux_put),
1945 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
1946 slim_rx_mux_get, slim_rx_mux_put),
1947};
1948
1949static const struct snd_kcontrol_new aif_cap_mixer[] = {
1950 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TAIKO_TX1, 1, 0,
1951 slim_tx_mixer_get, slim_tx_mixer_put),
1952 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TAIKO_TX2, 1, 0,
1953 slim_tx_mixer_get, slim_tx_mixer_put),
1954 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TAIKO_TX3, 1, 0,
1955 slim_tx_mixer_get, slim_tx_mixer_put),
1956 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TAIKO_TX4, 1, 0,
1957 slim_tx_mixer_get, slim_tx_mixer_put),
1958 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TAIKO_TX5, 1, 0,
1959 slim_tx_mixer_get, slim_tx_mixer_put),
1960 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TAIKO_TX6, 1, 0,
1961 slim_tx_mixer_get, slim_tx_mixer_put),
1962 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TAIKO_TX7, 1, 0,
1963 slim_tx_mixer_get, slim_tx_mixer_put),
1964 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TAIKO_TX8, 1, 0,
1965 slim_tx_mixer_get, slim_tx_mixer_put),
1966 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TAIKO_TX9, 1, 0,
1967 slim_tx_mixer_get, slim_tx_mixer_put),
1968 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TAIKO_TX10, 1, 0,
1969 slim_tx_mixer_get, slim_tx_mixer_put),
1970};
1971
Kiran Kandic3b24402012-06-11 00:05:59 -07001972static void taiko_codec_enable_adc_block(struct snd_soc_codec *codec,
1973 int enable)
1974{
1975 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1976
1977 pr_debug("%s %d\n", __func__, enable);
1978
1979 if (enable) {
1980 taiko->adc_count++;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08001981 snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
1982 0x2, 0x2);
Kiran Kandic3b24402012-06-11 00:05:59 -07001983 } else {
1984 taiko->adc_count--;
1985 if (!taiko->adc_count)
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08001986 snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
Kiran Kandic3b24402012-06-11 00:05:59 -07001987 0x2, 0x0);
1988 }
1989}
1990
1991static int taiko_codec_enable_adc(struct snd_soc_dapm_widget *w,
1992 struct snd_kcontrol *kcontrol, int event)
1993{
1994 struct snd_soc_codec *codec = w->codec;
1995 u16 adc_reg;
1996 u8 init_bit_shift;
Joonwoo Park2a9170a2013-03-04 17:05:57 -08001997 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07001998
1999 pr_debug("%s %d\n", __func__, event);
2000
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002001 if (TAIKO_IS_1_0(core->version)) {
2002 if (w->reg == TAIKO_A_TX_1_2_EN) {
2003 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2004 } else if (w->reg == TAIKO_A_TX_3_4_EN) {
2005 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2006 } else if (w->reg == TAIKO_A_TX_5_6_EN) {
2007 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2008 } else {
2009 pr_err("%s: Error, invalid adc register\n", __func__);
2010 return -EINVAL;
2011 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002012
Joonwoo Park2a9170a2013-03-04 17:05:57 -08002013 if (w->shift == 3) {
2014 init_bit_shift = 6;
2015 } else if (w->shift == 7) {
2016 init_bit_shift = 7;
2017 } else {
2018 pr_err("%s: Error, invalid init bit postion adc register\n",
2019 __func__);
2020 return -EINVAL;
2021 }
2022 } else {
2023 switch (w->reg) {
2024 case TAIKO_A_CDC_TX_1_GAIN:
2025 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2026 init_bit_shift = 7;
2027 break;
2028 case TAIKO_A_CDC_TX_2_GAIN:
2029 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
2030 init_bit_shift = 6;
2031 break;
2032 case TAIKO_A_CDC_TX_3_GAIN:
2033 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2034 init_bit_shift = 7;
2035 break;
2036 case TAIKO_A_CDC_TX_4_GAIN:
2037 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
2038 init_bit_shift = 6;
2039 break;
2040 case TAIKO_A_CDC_TX_5_GAIN:
2041 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2042 init_bit_shift = 7;
2043 break;
2044 case TAIKO_A_CDC_TX_6_GAIN:
2045 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
2046 init_bit_shift = 6;
2047 break;
2048 default:
2049 pr_err("%s: Error, invalid adc register\n", __func__);
2050 return -EINVAL;
2051 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002052 }
2053
2054 switch (event) {
2055 case SND_SOC_DAPM_PRE_PMU:
2056 taiko_codec_enable_adc_block(codec, 1);
2057 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
2058 1 << init_bit_shift);
2059 break;
2060 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002061 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -07002062 break;
2063 case SND_SOC_DAPM_POST_PMD:
2064 taiko_codec_enable_adc_block(codec, 0);
2065 break;
2066 }
2067 return 0;
2068}
2069
Kiran Kandic3b24402012-06-11 00:05:59 -07002070static int taiko_codec_enable_aux_pga(struct snd_soc_dapm_widget *w,
2071 struct snd_kcontrol *kcontrol, int event)
2072{
2073 struct snd_soc_codec *codec = w->codec;
2074 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2075
2076 pr_debug("%s: %d\n", __func__, event);
2077
2078 switch (event) {
2079 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002080 WCD9XXX_BCL_LOCK(&taiko->resmgr);
2081 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
2082 WCD9XXX_BANDGAP_AUDIO_MODE);
2083 /* AUX PGA requires RCO or MCLK */
2084 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
2085 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
2086 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07002087 break;
2088
2089 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002090 WCD9XXX_BCL_LOCK(&taiko->resmgr);
2091 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
2092 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
2093 WCD9XXX_BANDGAP_AUDIO_MODE);
2094 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
2095 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07002096 break;
2097 }
2098 return 0;
2099}
2100
2101static int taiko_codec_enable_lineout(struct snd_soc_dapm_widget *w,
2102 struct snd_kcontrol *kcontrol, int event)
2103{
2104 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002105 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002106 u16 lineout_gain_reg;
2107
2108 pr_debug("%s %d %s\n", __func__, event, w->name);
2109
2110 switch (w->shift) {
2111 case 0:
2112 lineout_gain_reg = TAIKO_A_RX_LINE_1_GAIN;
2113 break;
2114 case 1:
2115 lineout_gain_reg = TAIKO_A_RX_LINE_2_GAIN;
2116 break;
2117 case 2:
2118 lineout_gain_reg = TAIKO_A_RX_LINE_3_GAIN;
2119 break;
2120 case 3:
2121 lineout_gain_reg = TAIKO_A_RX_LINE_4_GAIN;
2122 break;
2123 default:
2124 pr_err("%s: Error, incorrect lineout register value\n",
2125 __func__);
2126 return -EINVAL;
2127 }
2128
2129 switch (event) {
2130 case SND_SOC_DAPM_PRE_PMU:
2131 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
2132 break;
2133 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002134 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2135 WCD9XXX_CLSH_STATE_LO,
2136 WCD9XXX_CLSH_REQ_ENABLE,
2137 WCD9XXX_CLSH_EVENT_POST_PA);
2138 pr_debug("%s: sleeping 3 ms after %s PA turn on\n",
Kiran Kandic3b24402012-06-11 00:05:59 -07002139 __func__, w->name);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002140 usleep_range(3000, 3000);
Kiran Kandic3b24402012-06-11 00:05:59 -07002141 break;
2142 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002143 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2144 WCD9XXX_CLSH_STATE_LO,
2145 WCD9XXX_CLSH_REQ_DISABLE,
2146 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandic3b24402012-06-11 00:05:59 -07002147 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
2148 break;
2149 }
2150 return 0;
2151}
2152
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002153static int taiko_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
2154 struct snd_kcontrol *kcontrol, int event)
2155{
Joonwoo Park125cd4e2012-12-11 15:16:11 -08002156 struct snd_soc_codec *codec = w->codec;
2157 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2158
2159 pr_debug("%s: %d %s\n", __func__, event, w->name);
2160 WCD9XXX_BCL_LOCK(&taiko->resmgr);
2161 switch (event) {
2162 case SND_SOC_DAPM_PRE_PMU:
2163 taiko->spkr_pa_widget_on = true;
2164 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
2165 break;
2166 case SND_SOC_DAPM_POST_PMD:
2167 taiko->spkr_pa_widget_on = false;
2168 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x00);
2169 break;
2170 }
2171 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002172 return 0;
2173}
Kiran Kandic3b24402012-06-11 00:05:59 -07002174
2175static int taiko_codec_enable_dmic(struct snd_soc_dapm_widget *w,
2176 struct snd_kcontrol *kcontrol, int event)
2177{
2178 struct snd_soc_codec *codec = w->codec;
2179 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2180 u8 dmic_clk_en;
2181 u16 dmic_clk_reg;
2182 s32 *dmic_clk_cnt;
2183 unsigned int dmic;
2184 int ret;
2185
2186 ret = kstrtouint(strpbrk(w->name, "123456"), 10, &dmic);
2187 if (ret < 0) {
2188 pr_err("%s: Invalid DMIC line on the codec\n", __func__);
2189 return -EINVAL;
2190 }
2191
2192 switch (dmic) {
2193 case 1:
2194 case 2:
2195 dmic_clk_en = 0x01;
2196 dmic_clk_cnt = &(taiko->dmic_1_2_clk_cnt);
2197 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
2198 pr_debug("%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
2199 __func__, event, dmic, *dmic_clk_cnt);
2200
2201 break;
2202
2203 case 3:
2204 case 4:
2205 dmic_clk_en = 0x10;
2206 dmic_clk_cnt = &(taiko->dmic_3_4_clk_cnt);
2207 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
2208
2209 pr_debug("%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n",
2210 __func__, event, dmic, *dmic_clk_cnt);
2211 break;
2212
2213 case 5:
2214 case 6:
2215 dmic_clk_en = 0x01;
2216 dmic_clk_cnt = &(taiko->dmic_5_6_clk_cnt);
2217 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B2_CTL;
2218
2219 pr_debug("%s() event %d DMIC%d dmic_5_6_clk_cnt %d\n",
2220 __func__, event, dmic, *dmic_clk_cnt);
2221
2222 break;
2223
2224 default:
2225 pr_err("%s: Invalid DMIC Selection\n", __func__);
2226 return -EINVAL;
2227 }
2228
2229 switch (event) {
2230 case SND_SOC_DAPM_PRE_PMU:
2231
2232 (*dmic_clk_cnt)++;
2233 if (*dmic_clk_cnt == 1)
2234 snd_soc_update_bits(codec, dmic_clk_reg,
2235 dmic_clk_en, dmic_clk_en);
2236
2237 break;
2238 case SND_SOC_DAPM_POST_PMD:
2239
2240 (*dmic_clk_cnt)--;
2241 if (*dmic_clk_cnt == 0)
2242 snd_soc_update_bits(codec, dmic_clk_reg,
2243 dmic_clk_en, 0);
2244 break;
2245 }
2246 return 0;
2247}
2248
Joonwoo Park1d05bb92013-03-07 16:55:06 -08002249static int taiko_codec_config_mad(struct snd_soc_codec *codec)
2250{
2251 int ret;
2252 const struct firmware *fw;
2253 struct mad_audio_cal *mad_cal;
2254 const char *filename = TAIKO_MAD_AUDIO_FIRMWARE_PATH;
2255
2256 pr_debug("%s: enter\n", __func__);
2257 ret = request_firmware(&fw, filename, codec->dev);
2258 if (ret != 0) {
2259 pr_err("Failed to acquire MAD firwmare data %s: %d\n", filename,
2260 ret);
2261 return -ENODEV;
2262 }
2263
2264 if (fw->size < sizeof(struct mad_audio_cal)) {
2265 pr_err("%s: incorrect firmware size %u\n", __func__, fw->size);
2266 release_firmware(fw);
2267 return -ENOMEM;
2268 }
2269
2270 mad_cal = (struct mad_audio_cal *)(fw->data);
2271 if (!mad_cal) {
2272 pr_err("%s: Invalid calibration data\n", __func__);
2273 release_firmware(fw);
2274 return -EINVAL;
2275 }
2276
2277 snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_MAD,
2278 0x0F, mad_cal->microphone_info.input_microphone);
2279 snd_soc_write(codec, TAIKO_A_CDC_MAD_MAIN_CTL_2,
2280 mad_cal->microphone_info.cycle_time);
2281 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_MAIN_CTL_1, 0xFF << 3,
2282 ((uint16_t)mad_cal->microphone_info.settle_time)
2283 << 3);
2284
2285 /* Audio */
2286 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_8,
2287 mad_cal->audio_info.rms_omit_samples);
2288 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_1,
2289 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
2290 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_2, 0x03 << 2,
2291 mad_cal->audio_info.detection_mechanism << 2);
2292 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_7,
2293 mad_cal->audio_info.rms_diff_threshold & 0x3F);
2294 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_5,
2295 mad_cal->audio_info.rms_threshold_lsb);
2296 snd_soc_write(codec, TAIKO_A_CDC_MAD_AUDIO_CTL_6,
2297 mad_cal->audio_info.rms_threshold_msb);
2298
2299
2300 /* Beacon */
2301 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_8,
2302 mad_cal->beacon_info.rms_omit_samples);
2303 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_1,
2304 0x07 << 4, mad_cal->beacon_info.rms_comp_time);
2305 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_2, 0x03 << 2,
2306 mad_cal->beacon_info.detection_mechanism << 2);
2307 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_7,
2308 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
2309 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_5,
2310 mad_cal->beacon_info.rms_threshold_lsb);
2311 snd_soc_write(codec, TAIKO_A_CDC_MAD_BEACON_CTL_6,
2312 mad_cal->beacon_info.rms_threshold_msb);
2313
2314 /* Ultrasound */
2315 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_BEACON_CTL_1,
2316 0x07 << 4, mad_cal->beacon_info.rms_comp_time);
2317 snd_soc_update_bits(codec, TAIKO_A_CDC_MAD_ULTR_CTL_2, 0x03 << 2,
2318 mad_cal->ultrasound_info.detection_mechanism);
2319 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_7,
2320 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
2321 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_5,
2322 mad_cal->ultrasound_info.rms_threshold_lsb);
2323 snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_6,
2324 mad_cal->ultrasound_info.rms_threshold_msb);
2325
2326 release_firmware(fw);
2327 pr_debug("%s: leave ret %d\n", __func__, ret);
2328
2329 return ret;
2330}
2331
2332static int taiko_codec_enable_mad(struct snd_soc_dapm_widget *w,
2333 struct snd_kcontrol *kcontrol, int event)
2334{
2335 struct snd_soc_codec *codec = w->codec;
2336 int ret = 0;
2337
2338 pr_debug("%s %d\n", __func__, event);
2339 switch (event) {
2340 case SND_SOC_DAPM_PRE_PMU:
2341 ret = taiko_codec_config_mad(codec);
2342 if (ret) {
2343 pr_err("%s: Failed to config MAD\n", __func__);
2344 break;
2345 }
2346 break;
2347 }
2348 return ret;
2349}
2350
Kiran Kandic3b24402012-06-11 00:05:59 -07002351static int taiko_codec_enable_micbias(struct snd_soc_dapm_widget *w,
2352 struct snd_kcontrol *kcontrol, int event)
2353{
2354 struct snd_soc_codec *codec = w->codec;
2355 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Park3699ca32013-02-08 12:06:15 -08002356 u16 micb_int_reg = 0, micb_ctl_reg = 0;
Kiran Kandic3b24402012-06-11 00:05:59 -07002357 u8 cfilt_sel_val = 0;
2358 char *internal1_text = "Internal1";
2359 char *internal2_text = "Internal2";
2360 char *internal3_text = "Internal3";
Joonwoo Parka8890262012-10-15 12:04:27 -07002361 enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
Kiran Kandic3b24402012-06-11 00:05:59 -07002362
Joonwoo Park3699ca32013-02-08 12:06:15 -08002363 pr_debug("%s: w->name %s event %d\n", __func__, w->name, event);
2364 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) {
2365 micb_ctl_reg = TAIKO_A_MICB_1_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002366 micb_int_reg = TAIKO_A_MICB_1_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002367 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias1_cfilt_sel;
2368 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
2369 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
2370 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002371 } else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) {
2372 micb_ctl_reg = TAIKO_A_MICB_2_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002373 micb_int_reg = TAIKO_A_MICB_2_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002374 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias2_cfilt_sel;
2375 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
2376 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
2377 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002378 } else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) {
Damir Didjusto6e4f9d22013-03-07 10:10:57 -08002379 micb_ctl_reg = TAIKO_A_MICB_3_CTL;
Kiran Kandic3b24402012-06-11 00:05:59 -07002380 micb_int_reg = TAIKO_A_MICB_3_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002381 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias3_cfilt_sel;
2382 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
2383 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
2384 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002385 } else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) {
Damir Didjusto6e4f9d22013-03-07 10:10:57 -08002386 micb_ctl_reg = TAIKO_A_MICB_4_CTL;
Joonwoo Parka8890262012-10-15 12:04:27 -07002387 micb_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
2388 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias4_cfilt_sel;
2389 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_4_ON;
2390 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_4_ON;
2391 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_4_OFF;
Joonwoo Park3699ca32013-02-08 12:06:15 -08002392 } else {
2393 pr_err("%s: Error, invalid micbias %s\n", __func__, w->name);
Kiran Kandic3b24402012-06-11 00:05:59 -07002394 return -EINVAL;
2395 }
2396
2397 switch (event) {
2398 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002399 /* Let MBHC module know so micbias switch to be off */
2400 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002401
Joonwoo Parka8890262012-10-15 12:04:27 -07002402 /* Get cfilt */
2403 wcd9xxx_resmgr_cfilt_get(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002404
2405 if (strnstr(w->name, internal1_text, 30))
2406 snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
2407 else if (strnstr(w->name, internal2_text, 30))
2408 snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
2409 else if (strnstr(w->name, internal3_text, 30))
2410 snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
2411
Joonwoo Park3edb9892013-03-05 17:44:54 -08002412 if (micb_ctl_reg == TAIKO_A_MICB_2_CTL)
Joonwoo Park3699ca32013-02-08 12:06:15 -08002413 wcd9xxx_resmgr_add_cond_update_bits(&taiko->resmgr,
2414 WCD9XXX_COND_HPH_MIC,
2415 micb_ctl_reg, w->shift,
2416 false);
Joonwoo Park3edb9892013-03-05 17:44:54 -08002417 else
Joonwoo Park3699ca32013-02-08 12:06:15 -08002418 snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
2419 1 << w->shift);
Kiran Kandic3b24402012-06-11 00:05:59 -07002420 break;
2421 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002422 usleep_range(20000, 20000);
Joonwoo Parka8890262012-10-15 12:04:27 -07002423 /* Let MBHC module know so micbias is on */
2424 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002425 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07002426 case SND_SOC_DAPM_POST_PMD:
Joonwoo Park3edb9892013-03-05 17:44:54 -08002427 if (micb_ctl_reg == TAIKO_A_MICB_2_CTL)
Joonwoo Park3699ca32013-02-08 12:06:15 -08002428 wcd9xxx_resmgr_rm_cond_update_bits(&taiko->resmgr,
2429 WCD9XXX_COND_HPH_MIC,
2430 micb_ctl_reg, 7, false);
Joonwoo Park3edb9892013-03-05 17:44:54 -08002431 else
Joonwoo Park3699ca32013-02-08 12:06:15 -08002432 snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
2433 0);
2434
Joonwoo Parka8890262012-10-15 12:04:27 -07002435 /* Let MBHC module know so micbias switch to be off */
2436 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
Kiran Kandic3b24402012-06-11 00:05:59 -07002437
2438 if (strnstr(w->name, internal1_text, 30))
2439 snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
2440 else if (strnstr(w->name, internal2_text, 30))
2441 snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
2442 else if (strnstr(w->name, internal3_text, 30))
2443 snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
2444
Joonwoo Parka8890262012-10-15 12:04:27 -07002445 /* Put cfilt */
2446 wcd9xxx_resmgr_cfilt_put(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002447 break;
2448 }
2449
2450 return 0;
2451}
2452
2453
2454static void tx_hpf_corner_freq_callback(struct work_struct *work)
2455{
2456 struct delayed_work *hpf_delayed_work;
2457 struct hpf_work *hpf_work;
2458 struct taiko_priv *taiko;
2459 struct snd_soc_codec *codec;
2460 u16 tx_mux_ctl_reg;
2461 u8 hpf_cut_of_freq;
2462
2463 hpf_delayed_work = to_delayed_work(work);
2464 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
2465 taiko = hpf_work->taiko;
2466 codec = hpf_work->taiko->codec;
2467 hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
2468
2469 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL +
2470 (hpf_work->decimator - 1) * 8;
2471
2472 pr_debug("%s(): decimator %u hpf_cut_of_freq 0x%x\n", __func__,
2473 hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
2474
2475 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
2476}
2477
2478#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30
2479#define CF_MIN_3DB_4HZ 0x0
2480#define CF_MIN_3DB_75HZ 0x1
2481#define CF_MIN_3DB_150HZ 0x2
2482
2483static int taiko_codec_enable_dec(struct snd_soc_dapm_widget *w,
2484 struct snd_kcontrol *kcontrol, int event)
2485{
2486 struct snd_soc_codec *codec = w->codec;
2487 unsigned int decimator;
2488 char *dec_name = NULL;
2489 char *widget_name = NULL;
2490 char *temp;
2491 int ret = 0;
2492 u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
2493 u8 dec_hpf_cut_of_freq;
2494 int offset;
2495
2496
2497 pr_debug("%s %d\n", __func__, event);
2498
2499 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
2500 if (!widget_name)
2501 return -ENOMEM;
2502 temp = widget_name;
2503
2504 dec_name = strsep(&widget_name, " ");
2505 widget_name = temp;
2506 if (!dec_name) {
2507 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
2508 ret = -EINVAL;
2509 goto out;
2510 }
2511
2512 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
2513 if (ret < 0) {
2514 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
2515 ret = -EINVAL;
2516 goto out;
2517 }
2518
2519 pr_debug("%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
2520 w->name, dec_name, decimator);
2521
2522 if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
2523 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B1_CTL;
2524 offset = 0;
2525 } else if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL) {
2526 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B2_CTL;
2527 offset = 8;
2528 } else {
2529 pr_err("%s: Error, incorrect dec\n", __func__);
2530 return -EINVAL;
2531 }
2532
2533 tx_vol_ctl_reg = TAIKO_A_CDC_TX1_VOL_CTL_CFG + 8 * (decimator - 1);
2534 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
2535
2536 switch (event) {
2537 case SND_SOC_DAPM_PRE_PMU:
2538
2539 /* Enableable TX digital mute */
2540 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2541
2542 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
2543 1 << w->shift);
2544 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
2545
2546 dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
2547
2548 dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
2549
2550 tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
2551 dec_hpf_cut_of_freq;
2552
2553 if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
2554
2555 /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
2556 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
2557 CF_MIN_3DB_150HZ << 4);
2558 }
2559
2560 /* enable HPF */
2561 snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
2562
2563 break;
2564
2565 case SND_SOC_DAPM_POST_PMU:
2566
2567 /* Disable TX digital mute */
2568 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
2569
2570 if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
2571 CF_MIN_3DB_150HZ) {
2572
2573 schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
2574 msecs_to_jiffies(300));
2575 }
2576 /* apply the digital gain after the decimator is enabled*/
Damir Didjustoed406e22012-11-16 15:44:57 -08002577 if ((w->shift + offset) < ARRAY_SIZE(tx_digital_gain_reg))
Kiran Kandic3b24402012-06-11 00:05:59 -07002578 snd_soc_write(codec,
2579 tx_digital_gain_reg[w->shift + offset],
2580 snd_soc_read(codec,
2581 tx_digital_gain_reg[w->shift + offset])
2582 );
2583
2584 break;
2585
2586 case SND_SOC_DAPM_PRE_PMD:
2587
2588 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2589 cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
2590 break;
2591
2592 case SND_SOC_DAPM_POST_PMD:
2593
2594 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
2595 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
2596 (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
2597
2598 break;
2599 }
2600out:
2601 kfree(widget_name);
2602 return ret;
2603}
2604
Joonwoo Park125cd4e2012-12-11 15:16:11 -08002605static int taiko_codec_enable_vdd_spkr(struct snd_soc_dapm_widget *w,
2606 struct snd_kcontrol *kcontrol, int event)
2607{
2608 int ret = 0;
2609 struct snd_soc_codec *codec = w->codec;
2610 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2611
2612 pr_debug("%s: %d %s\n", __func__, event, w->name);
2613 switch (event) {
2614 case SND_SOC_DAPM_PRE_PMU:
2615 if (spkr_drv_wrnd > 0) {
2616 WARN_ON(!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
2617 0x80));
2618 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
2619 0x00);
2620 }
2621 if (TAIKO_IS_1_0(core->version))
2622 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
2623 0x24, 0x00);
2624 break;
2625 case SND_SOC_DAPM_POST_PMD:
2626 if (TAIKO_IS_1_0(core->version))
2627 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
2628 0x24, 0x24);
2629 if (spkr_drv_wrnd > 0) {
2630 WARN_ON(!!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
2631 0x80));
2632 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
2633 0x80);
2634 }
2635 break;
2636 }
2637
2638 return ret;
2639}
2640
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07002641static int taiko_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07002642 struct snd_kcontrol *kcontrol, int event)
2643{
2644 struct snd_soc_codec *codec = w->codec;
2645
2646 pr_debug("%s %d %s\n", __func__, event, w->name);
2647
2648 switch (event) {
2649 case SND_SOC_DAPM_PRE_PMU:
2650 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
2651 1 << w->shift, 1 << w->shift);
2652 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
2653 1 << w->shift, 0x0);
2654 break;
2655 case SND_SOC_DAPM_POST_PMU:
2656 /* apply the digital gain after the interpolator is enabled*/
2657 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
2658 snd_soc_write(codec,
2659 rx_digital_gain_reg[w->shift],
2660 snd_soc_read(codec,
2661 rx_digital_gain_reg[w->shift])
2662 );
2663 break;
2664 }
2665 return 0;
2666}
2667
2668static int taiko_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
2669 struct snd_kcontrol *kcontrol, int event)
2670{
2671 switch (event) {
2672 case SND_SOC_DAPM_POST_PMU:
2673 case SND_SOC_DAPM_POST_PMD:
2674 usleep_range(1000, 1000);
2675 break;
2676 }
2677 return 0;
2678}
2679
2680static int taiko_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
2681 struct snd_kcontrol *kcontrol, int event)
2682{
2683 struct snd_soc_codec *codec = w->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07002684 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002685
2686 pr_debug("%s %d\n", __func__, event);
2687
2688 switch (event) {
2689 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002690 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
Kiran Kandic3b24402012-06-11 00:05:59 -07002691 break;
2692 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002693 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
Kiran Kandic3b24402012-06-11 00:05:59 -07002694 break;
2695 }
2696 return 0;
2697}
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002698
2699static int taiko_hphl_dac_event(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07002700 struct snd_kcontrol *kcontrol, int event)
2701{
2702 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002703 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002704
2705 pr_debug("%s %s %d\n", __func__, w->name, event);
2706
2707 switch (event) {
2708 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002709 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
2710 0x02, 0x02);
2711 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
2712 WCD9XXX_CLSH_STATE_HPHL,
2713 WCD9XXX_CLSH_REQ_ENABLE,
2714 WCD9XXX_CLSH_EVENT_PRE_DAC);
Kiran Kandic3b24402012-06-11 00:05:59 -07002715 break;
2716 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002717 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
2718 0x02, 0x00);
2719 }
2720 return 0;
2721}
2722
2723static int taiko_hphr_dac_event(struct snd_soc_dapm_widget *w,
2724 struct snd_kcontrol *kcontrol, int event)
2725{
2726 struct snd_soc_codec *codec = w->codec;
2727 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
2728
2729 pr_debug("%s %s %d\n", __func__, w->name, event);
2730
2731 switch (event) {
2732 case SND_SOC_DAPM_PRE_PMU:
2733 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
2734 0x04, 0x04);
2735 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
2736 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
2737 WCD9XXX_CLSH_STATE_HPHR,
2738 WCD9XXX_CLSH_REQ_ENABLE,
2739 WCD9XXX_CLSH_EVENT_PRE_DAC);
2740 break;
2741 case SND_SOC_DAPM_POST_PMD:
2742 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
2743 0x04, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -07002744 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
2745 break;
2746 }
2747 return 0;
2748}
2749
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08002750static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
2751 struct snd_kcontrol *kcontrol, int event)
2752{
2753 struct snd_soc_codec *codec = w->codec;
2754 const char *filename;
2755 const struct firmware *fw;
2756 int i;
2757 int ret;
2758 int num_anc_slots;
2759 struct anc_header *anc_head;
2760 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2761 u32 anc_writes_size = 0;
2762 int anc_size_remaining;
2763 u32 *anc_ptr;
2764 u16 reg;
2765 u8 mask, val, old_val;
2766
2767
2768 if (taiko->anc_func == 0)
2769 return 0;
2770
2771 switch (event) {
2772 case SND_SOC_DAPM_PRE_PMU:
2773 filename = "wcd9320/wcd9320_anc.bin";
2774
2775 ret = request_firmware(&fw, filename, codec->dev);
2776 if (ret != 0) {
2777 dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
2778 ret);
2779 return -ENODEV;
2780 }
2781
2782 if (fw->size < sizeof(struct anc_header)) {
2783 dev_err(codec->dev, "Not enough data\n");
2784 release_firmware(fw);
2785 return -ENOMEM;
2786 }
2787
2788 /* First number is the number of register writes */
2789 anc_head = (struct anc_header *)(fw->data);
2790 anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
2791 anc_size_remaining = fw->size - sizeof(struct anc_header);
2792 num_anc_slots = anc_head->num_anc_slots;
2793
2794 if (taiko->anc_slot >= num_anc_slots) {
2795 dev_err(codec->dev, "Invalid ANC slot selected\n");
2796 release_firmware(fw);
2797 return -EINVAL;
2798 }
2799 for (i = 0; i < num_anc_slots; i++) {
2800 if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
2801 dev_err(codec->dev, "Invalid register format\n");
2802 release_firmware(fw);
2803 return -EINVAL;
2804 }
2805 anc_writes_size = (u32)(*anc_ptr);
2806 anc_size_remaining -= sizeof(u32);
2807 anc_ptr += 1;
2808
2809 if (anc_writes_size * TAIKO_PACKED_REG_SIZE
2810 > anc_size_remaining) {
2811 dev_err(codec->dev, "Invalid register format\n");
2812 release_firmware(fw);
2813 return -ENOMEM;
2814 }
2815
2816 if (taiko->anc_slot == i)
2817 break;
2818
2819 anc_size_remaining -= (anc_writes_size *
2820 TAIKO_PACKED_REG_SIZE);
2821 anc_ptr += anc_writes_size;
2822 }
2823 if (i == num_anc_slots) {
2824 dev_err(codec->dev, "Selected ANC slot not present\n");
2825 release_firmware(fw);
2826 return -ENOMEM;
2827 }
2828 for (i = 0; i < anc_writes_size; i++) {
2829 TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
2830 mask, val);
2831 old_val = snd_soc_read(codec, reg);
2832 snd_soc_write(codec, reg, (old_val & ~mask) |
2833 (val & mask));
2834 }
2835 release_firmware(fw);
2836 break;
2837 case SND_SOC_DAPM_POST_PMD:
2838 msleep(40);
2839 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B1_CTL, 0x01, 0x00);
2840 snd_soc_update_bits(codec, TAIKO_A_CDC_ANC2_B1_CTL, 0x02, 0x00);
2841 msleep(20);
2842 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0x0F);
2843 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
2844 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
2845 break;
2846 }
2847 return 0;
2848}
2849
Kiran Kandic3b24402012-06-11 00:05:59 -07002850static int taiko_hph_pa_event(struct snd_soc_dapm_widget *w,
Joonwoo Parka8890262012-10-15 12:04:27 -07002851 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07002852{
2853 struct snd_soc_codec *codec = w->codec;
2854 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07002855 enum wcd9xxx_notify_event e_pre_on, e_post_off;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002856 u8 req_clsh_state;
Joonwoo Parka8890262012-10-15 12:04:27 -07002857
Kiran Kandi4c56c592012-07-25 11:04:55 -07002858 pr_debug("%s: %s event = %d\n", __func__, w->name, event);
Joonwoo Parka8890262012-10-15 12:04:27 -07002859 if (w->shift == 5) {
Joonwoo Parka8890262012-10-15 12:04:27 -07002860 e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
2861 e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
Patrick Lai453cd742013-03-02 16:51:27 -08002862 req_clsh_state = WCD9XXX_CLSH_STATE_HPHL;
2863 } else if (w->shift == 4) {
2864 e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
2865 e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002866 req_clsh_state = WCD9XXX_CLSH_STATE_HPHR;
Joonwoo Parka8890262012-10-15 12:04:27 -07002867 } else {
2868 pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
2869 return -EINVAL;
2870 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002871
2872 switch (event) {
2873 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002874 /* Let MBHC module know PA is turning on */
2875 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002876 break;
2877
Kiran Kandi4c56c592012-07-25 11:04:55 -07002878 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002879 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2880 req_clsh_state,
2881 WCD9XXX_CLSH_REQ_ENABLE,
2882 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandi4c56c592012-07-25 11:04:55 -07002883
Kiran Kandi4c56c592012-07-25 11:04:55 -07002884
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002885 usleep_range(5000, 5000);
Kiran Kandi4c56c592012-07-25 11:04:55 -07002886 break;
2887
Kiran Kandic3b24402012-06-11 00:05:59 -07002888 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002889 /* Let MBHC module know PA turned off */
2890 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
2891
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002892 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2893 req_clsh_state,
2894 WCD9XXX_CLSH_REQ_DISABLE,
2895 WCD9XXX_CLSH_EVENT_POST_PA);
2896
Kiran Kandic3b24402012-06-11 00:05:59 -07002897 pr_debug("%s: sleep 10 ms after %s PA disable.\n", __func__,
Joonwoo Parka8890262012-10-15 12:04:27 -07002898 w->name);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002899 usleep_range(5000, 5000);
Kiran Kandic3b24402012-06-11 00:05:59 -07002900 break;
2901 }
2902 return 0;
2903}
2904
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08002905static int taiko_codec_enable_anc_hph(struct snd_soc_dapm_widget *w,
2906 struct snd_kcontrol *kcontrol, int event)
2907{
2908 struct snd_soc_codec *codec = w->codec;
2909 int ret = 0;
2910
2911 switch (event) {
2912 case SND_SOC_DAPM_PRE_PMU:
2913 ret = taiko_hph_pa_event(w, kcontrol, event);
2914 if (w->shift == 4) {
2915 ret |= taiko_codec_enable_anc(w, kcontrol, event);
2916 msleep(50);
2917 }
2918 break;
2919 case SND_SOC_DAPM_POST_PMU:
2920 if (w->shift == 4) {
2921 snd_soc_update_bits(codec,
2922 TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x30);
2923 msleep(30);
2924 }
2925 ret = taiko_hph_pa_event(w, kcontrol, event);
2926 break;
2927 case SND_SOC_DAPM_PRE_PMD:
2928 if (w->shift == 5) {
2929 snd_soc_update_bits(codec,
2930 TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x00);
2931 msleep(40);
2932 }
2933 if (w->shift == 5) {
2934 snd_soc_update_bits(codec,
2935 TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
2936 ret |= taiko_codec_enable_anc(w, kcontrol, event);
2937 }
2938 case SND_SOC_DAPM_POST_PMD:
2939 ret = taiko_hph_pa_event(w, kcontrol, event);
2940 break;
2941 }
2942 return ret;
2943}
2944
Kiran Kandic3b24402012-06-11 00:05:59 -07002945static const struct snd_soc_dapm_widget taiko_dapm_i2s_widgets[] = {
2946 SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", TAIKO_A_CDC_CLK_RX_I2S_CTL,
2947 4, 0, NULL, 0),
2948 SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", TAIKO_A_CDC_CLK_TX_I2S_CTL, 4,
2949 0, NULL, 0),
2950};
2951
2952static int taiko_lineout_dac_event(struct snd_soc_dapm_widget *w,
2953 struct snd_kcontrol *kcontrol, int event)
2954{
2955 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002956 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002957
2958 pr_debug("%s %s %d\n", __func__, w->name, event);
2959
2960 switch (event) {
2961 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08002962 wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
2963 WCD9XXX_CLSH_STATE_LO,
2964 WCD9XXX_CLSH_REQ_ENABLE,
2965 WCD9XXX_CLSH_EVENT_PRE_DAC);
Kiran Kandic3b24402012-06-11 00:05:59 -07002966 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
2967 break;
2968
2969 case SND_SOC_DAPM_POST_PMD:
2970 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
2971 break;
2972 }
2973 return 0;
2974}
2975
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002976static int taiko_spk_dac_event(struct snd_soc_dapm_widget *w,
2977 struct snd_kcontrol *kcontrol, int event)
2978{
2979 pr_debug("%s %s %d\n", __func__, w->name, event);
2980 return 0;
2981}
2982
Kiran Kandic3b24402012-06-11 00:05:59 -07002983static const struct snd_soc_dapm_route audio_i2s_map[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07002984 {"SLIM RX1", NULL, "RX_I2S_CLK"},
2985 {"SLIM RX2", NULL, "RX_I2S_CLK"},
2986 {"SLIM RX3", NULL, "RX_I2S_CLK"},
2987 {"SLIM RX4", NULL, "RX_I2S_CLK"},
2988
Venkat Sudhira41630a2012-10-27 00:57:31 -07002989 {"SLIM TX7 MUX", NULL, "TX_I2S_CLK"},
2990 {"SLIM TX8 MUX", NULL, "TX_I2S_CLK"},
2991 {"SLIM TX9 MUX", NULL, "TX_I2S_CLK"},
2992 {"SLIM TX10 MUX", NULL, "TX_I2S_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002993};
2994
Joonwoo Park559a5bf2013-02-15 14:46:36 -08002995static const struct snd_soc_dapm_route audio_i2s_map_1_0[] = {
2996 {"RX_I2S_CLK", NULL, "CDC_CONN"},
2997};
2998
2999static const struct snd_soc_dapm_route audio_i2s_map_2_0[] = {
3000 {"RX_I2S_CLK", NULL, "CDC_I2S_RX_CONN"},
3001};
3002
Kiran Kandic3b24402012-06-11 00:05:59 -07003003static const struct snd_soc_dapm_route audio_map[] = {
3004 /* SLIMBUS Connections */
Kuirong Wang906ac472012-07-09 12:54:44 -07003005 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
3006 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
3007 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003008 {"AIF4 VI", NULL, "SPK_OUT"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003009
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003010 /* MAD */
3011 {"AIF4 MAD", NULL, "CDC_CONN"},
Joonwoo Park9ead0e92013-03-18 11:33:33 -07003012 {"MADONOFF", "Switch", "MADINPUT"},
3013 {"AIF4 MAD", NULL, "MADONOFF"},
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003014
Kuirong Wang906ac472012-07-09 12:54:44 -07003015 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
3016 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3017 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3018 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3019 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3020 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3021 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3022 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3023 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3024 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3025 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3026 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
3027 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3028 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3029 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3030 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3031 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3032 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3033 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3034 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3035 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3036 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3037 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
3038 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
3039 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
3040 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
3041 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
3042 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
3043 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
3044 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
3045 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
3046 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
3047 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
3048
Kiran Kandic3b24402012-06-11 00:05:59 -07003049 {"SLIM TX1 MUX", "DEC1", "DEC1 MUX"},
3050
Kiran Kandic3b24402012-06-11 00:05:59 -07003051 {"SLIM TX2 MUX", "DEC2", "DEC2 MUX"},
3052
Kiran Kandic3b24402012-06-11 00:05:59 -07003053 {"SLIM TX3 MUX", "DEC3", "DEC3 MUX"},
3054 {"SLIM TX3 MUX", "RMIX1", "RX1 MIX1"},
3055 {"SLIM TX3 MUX", "RMIX2", "RX2 MIX1"},
3056 {"SLIM TX3 MUX", "RMIX3", "RX3 MIX1"},
3057 {"SLIM TX3 MUX", "RMIX4", "RX4 MIX1"},
3058 {"SLIM TX3 MUX", "RMIX5", "RX5 MIX1"},
3059 {"SLIM TX3 MUX", "RMIX6", "RX6 MIX1"},
3060 {"SLIM TX3 MUX", "RMIX7", "RX7 MIX1"},
3061
Kiran Kandic3b24402012-06-11 00:05:59 -07003062 {"SLIM TX4 MUX", "DEC4", "DEC4 MUX"},
3063
Kiran Kandic3b24402012-06-11 00:05:59 -07003064 {"SLIM TX5 MUX", "DEC5", "DEC5 MUX"},
3065 {"SLIM TX5 MUX", "RMIX1", "RX1 MIX1"},
3066 {"SLIM TX5 MUX", "RMIX2", "RX2 MIX1"},
3067 {"SLIM TX5 MUX", "RMIX3", "RX3 MIX1"},
3068 {"SLIM TX5 MUX", "RMIX4", "RX4 MIX1"},
3069 {"SLIM TX5 MUX", "RMIX5", "RX5 MIX1"},
3070 {"SLIM TX5 MUX", "RMIX6", "RX6 MIX1"},
3071 {"SLIM TX5 MUX", "RMIX7", "RX7 MIX1"},
3072
Kiran Kandic3b24402012-06-11 00:05:59 -07003073 {"SLIM TX6 MUX", "DEC6", "DEC6 MUX"},
3074
Kiran Kandic3b24402012-06-11 00:05:59 -07003075 {"SLIM TX7 MUX", "DEC1", "DEC1 MUX"},
3076 {"SLIM TX7 MUX", "DEC2", "DEC2 MUX"},
3077 {"SLIM TX7 MUX", "DEC3", "DEC3 MUX"},
3078 {"SLIM TX7 MUX", "DEC4", "DEC4 MUX"},
3079 {"SLIM TX7 MUX", "DEC5", "DEC5 MUX"},
3080 {"SLIM TX7 MUX", "DEC6", "DEC6 MUX"},
3081 {"SLIM TX7 MUX", "DEC7", "DEC7 MUX"},
3082 {"SLIM TX7 MUX", "DEC8", "DEC8 MUX"},
3083 {"SLIM TX7 MUX", "DEC9", "DEC9 MUX"},
3084 {"SLIM TX7 MUX", "DEC10", "DEC10 MUX"},
3085 {"SLIM TX7 MUX", "RMIX1", "RX1 MIX1"},
3086 {"SLIM TX7 MUX", "RMIX2", "RX2 MIX1"},
3087 {"SLIM TX7 MUX", "RMIX3", "RX3 MIX1"},
3088 {"SLIM TX7 MUX", "RMIX4", "RX4 MIX1"},
3089 {"SLIM TX7 MUX", "RMIX5", "RX5 MIX1"},
3090 {"SLIM TX7 MUX", "RMIX6", "RX6 MIX1"},
3091 {"SLIM TX7 MUX", "RMIX7", "RX7 MIX1"},
3092
Kiran Kandic3b24402012-06-11 00:05:59 -07003093 {"SLIM TX8 MUX", "DEC1", "DEC1 MUX"},
3094 {"SLIM TX8 MUX", "DEC2", "DEC2 MUX"},
3095 {"SLIM TX8 MUX", "DEC3", "DEC3 MUX"},
3096 {"SLIM TX8 MUX", "DEC4", "DEC4 MUX"},
3097 {"SLIM TX8 MUX", "DEC5", "DEC5 MUX"},
3098 {"SLIM TX8 MUX", "DEC6", "DEC6 MUX"},
3099 {"SLIM TX8 MUX", "DEC7", "DEC7 MUX"},
3100 {"SLIM TX8 MUX", "DEC8", "DEC8 MUX"},
3101 {"SLIM TX8 MUX", "DEC9", "DEC9 MUX"},
3102 {"SLIM TX8 MUX", "DEC10", "DEC10 MUX"},
3103
Kiran Kandic3b24402012-06-11 00:05:59 -07003104 {"SLIM TX9 MUX", "DEC1", "DEC1 MUX"},
3105 {"SLIM TX9 MUX", "DEC2", "DEC2 MUX"},
3106 {"SLIM TX9 MUX", "DEC3", "DEC3 MUX"},
3107 {"SLIM TX9 MUX", "DEC4", "DEC4 MUX"},
3108 {"SLIM TX9 MUX", "DEC5", "DEC5 MUX"},
3109 {"SLIM TX9 MUX", "DEC6", "DEC6 MUX"},
3110 {"SLIM TX9 MUX", "DEC7", "DEC7 MUX"},
3111 {"SLIM TX9 MUX", "DEC8", "DEC8 MUX"},
3112 {"SLIM TX9 MUX", "DEC9", "DEC9 MUX"},
3113 {"SLIM TX9 MUX", "DEC10", "DEC10 MUX"},
3114
Kiran Kandic3b24402012-06-11 00:05:59 -07003115 {"SLIM TX10 MUX", "DEC1", "DEC1 MUX"},
3116 {"SLIM TX10 MUX", "DEC2", "DEC2 MUX"},
3117 {"SLIM TX10 MUX", "DEC3", "DEC3 MUX"},
3118 {"SLIM TX10 MUX", "DEC4", "DEC4 MUX"},
3119 {"SLIM TX10 MUX", "DEC5", "DEC5 MUX"},
3120 {"SLIM TX10 MUX", "DEC6", "DEC6 MUX"},
3121 {"SLIM TX10 MUX", "DEC7", "DEC7 MUX"},
3122 {"SLIM TX10 MUX", "DEC8", "DEC8 MUX"},
3123 {"SLIM TX10 MUX", "DEC9", "DEC9 MUX"},
3124 {"SLIM TX10 MUX", "DEC10", "DEC10 MUX"},
3125
3126 /* Earpiece (RX MIX1) */
3127 {"EAR", NULL, "EAR PA"},
3128 {"EAR PA", NULL, "EAR_PA_MIXER"},
3129 {"EAR_PA_MIXER", NULL, "DAC1"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003130 {"DAC1", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003131
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003132 {"ANC EAR", NULL, "ANC EAR PA"},
3133 {"ANC EAR PA", NULL, "EAR_PA_MIXER"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003134 {"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
3135 {"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003136
3137 /* Headset (RX MIX1 and RX MIX2) */
3138 {"HEADPHONE", NULL, "HPHL"},
3139 {"HEADPHONE", NULL, "HPHR"},
3140
3141 {"HPHL", NULL, "HPHL_PA_MIXER"},
3142 {"HPHL_PA_MIXER", NULL, "HPHL DAC"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003143 {"HPHL DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003144
3145 {"HPHR", NULL, "HPHR_PA_MIXER"},
3146 {"HPHR_PA_MIXER", NULL, "HPHR DAC"},
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003147 {"HPHR DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003148
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003149 {"ANC HEADPHONE", NULL, "ANC HPHL"},
3150 {"ANC HEADPHONE", NULL, "ANC HPHR"},
3151
3152 {"ANC HPHL", NULL, "HPHL_PA_MIXER"},
3153 {"ANC HPHR", NULL, "HPHR_PA_MIXER"},
3154
Kiran Kandic3b24402012-06-11 00:05:59 -07003155 {"ANC1 MUX", "ADC1", "ADC1"},
3156 {"ANC1 MUX", "ADC2", "ADC2"},
3157 {"ANC1 MUX", "ADC3", "ADC3"},
3158 {"ANC1 MUX", "ADC4", "ADC4"},
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003159 {"ANC1 MUX", "DMIC1", "DMIC1"},
3160 {"ANC1 MUX", "DMIC2", "DMIC2"},
3161 {"ANC1 MUX", "DMIC3", "DMIC3"},
3162 {"ANC1 MUX", "DMIC4", "DMIC4"},
3163 {"ANC1 MUX", "DMIC5", "DMIC5"},
3164 {"ANC1 MUX", "DMIC6", "DMIC6"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003165 {"ANC2 MUX", "ADC1", "ADC1"},
3166 {"ANC2 MUX", "ADC2", "ADC2"},
3167 {"ANC2 MUX", "ADC3", "ADC3"},
3168 {"ANC2 MUX", "ADC4", "ADC4"},
3169
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003170 {"ANC HPHR", NULL, "CDC_CONN"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003171
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003172 {"DAC1", "Switch", "CLASS_H_DSM MUX"},
3173 {"HPHL DAC", "Switch", "CLASS_H_DSM MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003174 {"HPHR DAC", NULL, "RX2 CHAIN"},
3175
3176 {"LINEOUT1", NULL, "LINEOUT1 PA"},
3177 {"LINEOUT2", NULL, "LINEOUT2 PA"},
3178 {"LINEOUT3", NULL, "LINEOUT3 PA"},
3179 {"LINEOUT4", NULL, "LINEOUT4 PA"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003180 {"SPK_OUT", NULL, "SPK PA"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003181
3182 {"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
3183 {"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003184
Kiran Kandic3b24402012-06-11 00:05:59 -07003185 {"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
3186 {"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003187
Kiran Kandic3b24402012-06-11 00:05:59 -07003188 {"LINEOUT3 PA", NULL, "LINEOUT3_PA_MIXER"},
3189 {"LINEOUT3_PA_MIXER", NULL, "LINEOUT3 DAC"},
Tanya Finkelfe634462012-10-23 22:12:07 +02003190
Kiran Kandic3b24402012-06-11 00:05:59 -07003191 {"LINEOUT4 PA", NULL, "LINEOUT4_PA_MIXER"},
3192 {"LINEOUT4_PA_MIXER", NULL, "LINEOUT4 DAC"},
3193
3194 {"LINEOUT1 DAC", NULL, "RX3 MIX1"},
3195
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02003196 {"RDAC5 MUX", "DEM3_INV", "RX3 MIX1"},
3197 {"RDAC5 MUX", "DEM4", "RX4 MIX1"},
3198
3199 {"LINEOUT3 DAC", NULL, "RDAC5 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003200
3201 {"LINEOUT2 DAC", NULL, "RX5 MIX1"},
3202
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02003203 {"RDAC7 MUX", "DEM5_INV", "RX5 MIX1"},
3204 {"RDAC7 MUX", "DEM6", "RX6 MIX1"},
3205
3206 {"LINEOUT4 DAC", NULL, "RDAC7 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003207
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003208 {"SPK PA", NULL, "SPK DAC"},
Kiran Kandid2b46332012-10-05 12:04:00 -07003209 {"SPK DAC", NULL, "RX7 MIX2"},
Joonwoo Park125cd4e2012-12-11 15:16:11 -08003210 {"SPK DAC", NULL, "VDD_SPKDRV"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003211
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08003212 {"CLASS_H_DSM MUX", "DSM_HPHL_RX1", "RX1 CHAIN"},
3213
Kiran Kandic3b24402012-06-11 00:05:59 -07003214 {"RX1 CHAIN", NULL, "RX1 MIX2"},
3215 {"RX2 CHAIN", NULL, "RX2 MIX2"},
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003216 {"RX1 MIX2", NULL, "ANC1 MUX"},
3217 {"RX2 MIX2", NULL, "ANC2 MUX"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003218
Kiran Kandic3b24402012-06-11 00:05:59 -07003219 {"LINEOUT1 DAC", NULL, "RX_BIAS"},
3220 {"LINEOUT2 DAC", NULL, "RX_BIAS"},
3221 {"LINEOUT3 DAC", NULL, "RX_BIAS"},
3222 {"LINEOUT4 DAC", NULL, "RX_BIAS"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003223 {"SPK DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003224
Joonwoo Parkc7731432012-10-17 12:41:44 -07003225 {"RX7 MIX1", NULL, "COMP0_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003226 {"RX1 MIX1", NULL, "COMP1_CLK"},
3227 {"RX2 MIX1", NULL, "COMP1_CLK"},
3228 {"RX3 MIX1", NULL, "COMP2_CLK"},
3229 {"RX5 MIX1", NULL, "COMP2_CLK"},
3230
Kiran Kandic3b24402012-06-11 00:05:59 -07003231 {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
3232 {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
3233 {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
3234 {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
3235 {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
3236 {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
3237 {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
3238 {"RX4 MIX1", NULL, "RX4 MIX1 INP1"},
3239 {"RX4 MIX1", NULL, "RX4 MIX1 INP2"},
3240 {"RX5 MIX1", NULL, "RX5 MIX1 INP1"},
3241 {"RX5 MIX1", NULL, "RX5 MIX1 INP2"},
3242 {"RX6 MIX1", NULL, "RX6 MIX1 INP1"},
3243 {"RX6 MIX1", NULL, "RX6 MIX1 INP2"},
3244 {"RX7 MIX1", NULL, "RX7 MIX1 INP1"},
3245 {"RX7 MIX1", NULL, "RX7 MIX1 INP2"},
3246 {"RX1 MIX2", NULL, "RX1 MIX1"},
3247 {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
3248 {"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
3249 {"RX2 MIX2", NULL, "RX2 MIX1"},
3250 {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
3251 {"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
3252 {"RX7 MIX2", NULL, "RX7 MIX1"},
3253 {"RX7 MIX2", NULL, "RX7 MIX2 INP1"},
3254 {"RX7 MIX2", NULL, "RX7 MIX2 INP2"},
3255
Kuirong Wang906ac472012-07-09 12:54:44 -07003256 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
3257 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
3258 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
3259 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
3260 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
3261 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
3262 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
3263 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
3264 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
3265 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
3266 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
3267 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
3268 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
3269 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
3270 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
3271 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
3272 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
3273 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
3274 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
3275 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
3276 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
3277 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
3278 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
3279 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
3280
3281 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
3282 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
3283 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
3284 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
3285 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
3286 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
3287 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
3288
Kiran Kandic3b24402012-06-11 00:05:59 -07003289 {"RX1 MIX1 INP1", "RX1", "SLIM RX1"},
3290 {"RX1 MIX1 INP1", "RX2", "SLIM RX2"},
3291 {"RX1 MIX1 INP1", "RX3", "SLIM RX3"},
3292 {"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
3293 {"RX1 MIX1 INP1", "RX5", "SLIM RX5"},
3294 {"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
3295 {"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
3296 {"RX1 MIX1 INP1", "IIR1", "IIR1"},
3297 {"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
3298 {"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
3299 {"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
3300 {"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
3301 {"RX1 MIX1 INP2", "RX5", "SLIM RX5"},
3302 {"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
3303 {"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
3304 {"RX1 MIX1 INP2", "IIR1", "IIR1"},
3305 {"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
3306 {"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
3307 {"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
3308 {"RX1 MIX1 INP3", "RX4", "SLIM RX4"},
3309 {"RX1 MIX1 INP3", "RX5", "SLIM RX5"},
3310 {"RX1 MIX1 INP3", "RX6", "SLIM RX6"},
3311 {"RX1 MIX1 INP3", "RX7", "SLIM RX7"},
3312 {"RX2 MIX1 INP1", "RX1", "SLIM RX1"},
3313 {"RX2 MIX1 INP1", "RX2", "SLIM RX2"},
3314 {"RX2 MIX1 INP1", "RX3", "SLIM RX3"},
3315 {"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
3316 {"RX2 MIX1 INP1", "RX5", "SLIM RX5"},
3317 {"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
3318 {"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
3319 {"RX2 MIX1 INP1", "IIR1", "IIR1"},
3320 {"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
3321 {"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
3322 {"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
3323 {"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
3324 {"RX2 MIX1 INP2", "RX5", "SLIM RX5"},
3325 {"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
3326 {"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
3327 {"RX2 MIX1 INP2", "IIR1", "IIR1"},
3328 {"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
3329 {"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
3330 {"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
3331 {"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
3332 {"RX3 MIX1 INP1", "RX5", "SLIM RX5"},
3333 {"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
3334 {"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
3335 {"RX3 MIX1 INP1", "IIR1", "IIR1"},
3336 {"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
3337 {"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
3338 {"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
3339 {"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
3340 {"RX3 MIX1 INP2", "RX5", "SLIM RX5"},
3341 {"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
3342 {"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
3343 {"RX3 MIX1 INP2", "IIR1", "IIR1"},
3344 {"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
3345 {"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
3346 {"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
3347 {"RX4 MIX1 INP1", "RX4", "SLIM RX4"},
3348 {"RX4 MIX1 INP1", "RX5", "SLIM RX5"},
3349 {"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
3350 {"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
3351 {"RX4 MIX1 INP1", "IIR1", "IIR1"},
3352 {"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
3353 {"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
3354 {"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
3355 {"RX4 MIX1 INP2", "RX5", "SLIM RX5"},
3356 {"RX4 MIX1 INP2", "RX4", "SLIM RX4"},
3357 {"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
3358 {"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
3359 {"RX4 MIX1 INP2", "IIR1", "IIR1"},
3360 {"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
3361 {"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
3362 {"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
3363 {"RX5 MIX1 INP1", "RX4", "SLIM RX4"},
3364 {"RX5 MIX1 INP1", "RX5", "SLIM RX5"},
3365 {"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
3366 {"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
3367 {"RX5 MIX1 INP1", "IIR1", "IIR1"},
3368 {"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
3369 {"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
3370 {"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
3371 {"RX5 MIX1 INP2", "RX4", "SLIM RX4"},
3372 {"RX5 MIX1 INP2", "RX5", "SLIM RX5"},
3373 {"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
3374 {"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
3375 {"RX5 MIX1 INP2", "IIR1", "IIR1"},
3376 {"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
3377 {"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
3378 {"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
3379 {"RX6 MIX1 INP1", "RX4", "SLIM RX4"},
3380 {"RX6 MIX1 INP1", "RX5", "SLIM RX5"},
3381 {"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
3382 {"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
3383 {"RX6 MIX1 INP1", "IIR1", "IIR1"},
3384 {"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
3385 {"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
3386 {"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
3387 {"RX6 MIX1 INP2", "RX4", "SLIM RX4"},
3388 {"RX6 MIX1 INP2", "RX5", "SLIM RX5"},
3389 {"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
3390 {"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
3391 {"RX6 MIX1 INP2", "IIR1", "IIR1"},
3392 {"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
3393 {"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
3394 {"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
3395 {"RX7 MIX1 INP1", "RX4", "SLIM RX4"},
3396 {"RX7 MIX1 INP1", "RX5", "SLIM RX5"},
3397 {"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
3398 {"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
3399 {"RX7 MIX1 INP1", "IIR1", "IIR1"},
3400 {"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
3401 {"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
3402 {"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
3403 {"RX7 MIX1 INP2", "RX4", "SLIM RX4"},
3404 {"RX7 MIX1 INP2", "RX5", "SLIM RX5"},
3405 {"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
3406 {"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
3407 {"RX7 MIX1 INP2", "IIR1", "IIR1"},
3408 {"RX1 MIX2 INP1", "IIR1", "IIR1"},
3409 {"RX1 MIX2 INP2", "IIR1", "IIR1"},
3410 {"RX2 MIX2 INP1", "IIR1", "IIR1"},
3411 {"RX2 MIX2 INP2", "IIR1", "IIR1"},
3412 {"RX7 MIX2 INP1", "IIR1", "IIR1"},
3413 {"RX7 MIX2 INP2", "IIR1", "IIR1"},
3414
3415 /* Decimator Inputs */
3416 {"DEC1 MUX", "DMIC1", "DMIC1"},
3417 {"DEC1 MUX", "ADC6", "ADC6"},
3418 {"DEC1 MUX", NULL, "CDC_CONN"},
3419 {"DEC2 MUX", "DMIC2", "DMIC2"},
3420 {"DEC2 MUX", "ADC5", "ADC5"},
3421 {"DEC2 MUX", NULL, "CDC_CONN"},
3422 {"DEC3 MUX", "DMIC3", "DMIC3"},
3423 {"DEC3 MUX", "ADC4", "ADC4"},
3424 {"DEC3 MUX", NULL, "CDC_CONN"},
3425 {"DEC4 MUX", "DMIC4", "DMIC4"},
3426 {"DEC4 MUX", "ADC3", "ADC3"},
3427 {"DEC4 MUX", NULL, "CDC_CONN"},
3428 {"DEC5 MUX", "DMIC5", "DMIC5"},
3429 {"DEC5 MUX", "ADC2", "ADC2"},
3430 {"DEC5 MUX", NULL, "CDC_CONN"},
3431 {"DEC6 MUX", "DMIC6", "DMIC6"},
3432 {"DEC6 MUX", "ADC1", "ADC1"},
3433 {"DEC6 MUX", NULL, "CDC_CONN"},
3434 {"DEC7 MUX", "DMIC1", "DMIC1"},
3435 {"DEC7 MUX", "DMIC6", "DMIC6"},
3436 {"DEC7 MUX", "ADC1", "ADC1"},
3437 {"DEC7 MUX", "ADC6", "ADC6"},
3438 {"DEC7 MUX", NULL, "CDC_CONN"},
3439 {"DEC8 MUX", "DMIC2", "DMIC2"},
3440 {"DEC8 MUX", "DMIC5", "DMIC5"},
3441 {"DEC8 MUX", "ADC2", "ADC2"},
3442 {"DEC8 MUX", "ADC5", "ADC5"},
3443 {"DEC8 MUX", NULL, "CDC_CONN"},
3444 {"DEC9 MUX", "DMIC4", "DMIC4"},
3445 {"DEC9 MUX", "DMIC5", "DMIC5"},
3446 {"DEC9 MUX", "ADC2", "ADC2"},
3447 {"DEC9 MUX", "ADC3", "ADC3"},
3448 {"DEC9 MUX", NULL, "CDC_CONN"},
3449 {"DEC10 MUX", "DMIC3", "DMIC3"},
3450 {"DEC10 MUX", "DMIC6", "DMIC6"},
3451 {"DEC10 MUX", "ADC1", "ADC1"},
3452 {"DEC10 MUX", "ADC4", "ADC4"},
3453 {"DEC10 MUX", NULL, "CDC_CONN"},
3454
3455 /* ADC Connections */
3456 {"ADC1", NULL, "AMIC1"},
3457 {"ADC2", NULL, "AMIC2"},
3458 {"ADC3", NULL, "AMIC3"},
3459 {"ADC4", NULL, "AMIC4"},
3460 {"ADC5", NULL, "AMIC5"},
3461 {"ADC6", NULL, "AMIC6"},
3462
3463 /* AUX PGA Connections */
Kiran Kandic3b24402012-06-11 00:05:59 -07003464 {"EAR_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07003465 {"HPHL_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
3466 {"HPHR_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
3467 {"LINEOUT1_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
3468 {"LINEOUT2_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
3469 {"LINEOUT3_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
3470 {"LINEOUT4_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
Kiran Kandic3b24402012-06-11 00:05:59 -07003471 {"AUX_PGA_Left", NULL, "AMIC5"},
3472 {"AUX_PGA_Right", NULL, "AMIC6"},
3473
Kiran Kandic3b24402012-06-11 00:05:59 -07003474 {"IIR1", NULL, "IIR1 INP1 MUX"},
3475 {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
3476 {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
3477 {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
3478 {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
3479 {"IIR1 INP1 MUX", "DEC5", "DEC5 MUX"},
3480 {"IIR1 INP1 MUX", "DEC6", "DEC6 MUX"},
3481 {"IIR1 INP1 MUX", "DEC7", "DEC7 MUX"},
3482 {"IIR1 INP1 MUX", "DEC8", "DEC8 MUX"},
3483 {"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
3484 {"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
3485
3486 {"MIC BIAS1 Internal1", NULL, "LDO_H"},
3487 {"MIC BIAS1 Internal2", NULL, "LDO_H"},
3488 {"MIC BIAS1 External", NULL, "LDO_H"},
3489 {"MIC BIAS2 Internal1", NULL, "LDO_H"},
3490 {"MIC BIAS2 Internal2", NULL, "LDO_H"},
3491 {"MIC BIAS2 Internal3", NULL, "LDO_H"},
3492 {"MIC BIAS2 External", NULL, "LDO_H"},
3493 {"MIC BIAS3 Internal1", NULL, "LDO_H"},
3494 {"MIC BIAS3 Internal2", NULL, "LDO_H"},
3495 {"MIC BIAS3 External", NULL, "LDO_H"},
3496 {"MIC BIAS4 External", NULL, "LDO_H"},
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003497
Kiran Kandic3b24402012-06-11 00:05:59 -07003498};
3499
3500static int taiko_readable(struct snd_soc_codec *ssc, unsigned int reg)
3501{
3502 return taiko_reg_readable[reg];
3503}
3504
3505static bool taiko_is_digital_gain_register(unsigned int reg)
3506{
3507 bool rtn = false;
3508 switch (reg) {
3509 case TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL:
3510 case TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL:
3511 case TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL:
3512 case TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL:
3513 case TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL:
3514 case TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL:
3515 case TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL:
3516 case TAIKO_A_CDC_TX1_VOL_CTL_GAIN:
3517 case TAIKO_A_CDC_TX2_VOL_CTL_GAIN:
3518 case TAIKO_A_CDC_TX3_VOL_CTL_GAIN:
3519 case TAIKO_A_CDC_TX4_VOL_CTL_GAIN:
3520 case TAIKO_A_CDC_TX5_VOL_CTL_GAIN:
3521 case TAIKO_A_CDC_TX6_VOL_CTL_GAIN:
3522 case TAIKO_A_CDC_TX7_VOL_CTL_GAIN:
3523 case TAIKO_A_CDC_TX8_VOL_CTL_GAIN:
3524 case TAIKO_A_CDC_TX9_VOL_CTL_GAIN:
3525 case TAIKO_A_CDC_TX10_VOL_CTL_GAIN:
3526 rtn = true;
3527 break;
3528 default:
3529 break;
3530 }
3531 return rtn;
3532}
3533
3534static int taiko_volatile(struct snd_soc_codec *ssc, unsigned int reg)
3535{
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003536 int i;
3537
Kiran Kandic3b24402012-06-11 00:05:59 -07003538 /* Registers lower than 0x100 are top level registers which can be
3539 * written by the Taiko core driver.
3540 */
3541
3542 if ((reg >= TAIKO_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
3543 return 1;
3544
3545 /* IIR Coeff registers are not cacheable */
3546 if ((reg >= TAIKO_A_CDC_IIR1_COEF_B1_CTL) &&
3547 (reg <= TAIKO_A_CDC_IIR2_COEF_B2_CTL))
3548 return 1;
3549
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08003550 /* ANC filter registers are not cacheable */
3551 if ((reg >= TAIKO_A_CDC_ANC1_IIR_B1_CTL) &&
3552 (reg <= TAIKO_A_CDC_ANC1_LPF_B2_CTL))
3553 return 1;
3554 if ((reg >= TAIKO_A_CDC_ANC2_IIR_B1_CTL) &&
3555 (reg <= TAIKO_A_CDC_ANC2_LPF_B2_CTL))
3556 return 1;
3557
Kiran Kandic3b24402012-06-11 00:05:59 -07003558 /* Digital gain register is not cacheable so we have to write
3559 * the setting even it is the same
3560 */
3561 if (taiko_is_digital_gain_register(reg))
3562 return 1;
3563
3564 /* HPH status registers */
3565 if (reg == TAIKO_A_RX_HPH_L_STATUS || reg == TAIKO_A_RX_HPH_R_STATUS)
3566 return 1;
3567
Joonwoo Parka8890262012-10-15 12:04:27 -07003568 if (reg == TAIKO_A_MBHC_INSERT_DET_STATUS)
3569 return 1;
3570
Joonwoo Park559a5bf2013-02-15 14:46:36 -08003571 switch (reg) {
3572 case TAIKO_A_CDC_SPKR_CLIPDET_VAL0:
3573 case TAIKO_A_CDC_SPKR_CLIPDET_VAL1:
3574 case TAIKO_A_CDC_SPKR_CLIPDET_VAL2:
3575 case TAIKO_A_CDC_SPKR_CLIPDET_VAL3:
3576 case TAIKO_A_CDC_SPKR_CLIPDET_VAL4:
3577 case TAIKO_A_CDC_SPKR_CLIPDET_VAL5:
3578 case TAIKO_A_CDC_SPKR_CLIPDET_VAL6:
3579 case TAIKO_A_CDC_SPKR_CLIPDET_VAL7:
3580 case TAIKO_A_CDC_VBAT_GAIN_MON_VAL:
3581 return 1;
3582 }
3583
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003584 for (i = 0; i < ARRAY_SIZE(mad_audio_reg_cfg); i++)
3585 if (mad_audio_reg_cfg[i].reg_logical_addr -
3586 TAIKO_REGISTER_START_OFFSET == reg)
3587 return 1;
3588
Kiran Kandic3b24402012-06-11 00:05:59 -07003589 return 0;
3590}
3591
Kiran Kandic3b24402012-06-11 00:05:59 -07003592static int taiko_write(struct snd_soc_codec *codec, unsigned int reg,
3593 unsigned int value)
3594{
3595 int ret;
Kuirong Wang906ac472012-07-09 12:54:44 -07003596
3597 if (reg == SND_SOC_NOPM)
3598 return 0;
3599
Kiran Kandic3b24402012-06-11 00:05:59 -07003600 BUG_ON(reg > TAIKO_MAX_REGISTER);
3601
3602 if (!taiko_volatile(codec, reg)) {
3603 ret = snd_soc_cache_write(codec, reg, value);
3604 if (ret != 0)
3605 dev_err(codec->dev, "Cache write to %x failed: %d\n",
3606 reg, ret);
3607 }
3608
3609 return wcd9xxx_reg_write(codec->control_data, reg, value);
3610}
3611static unsigned int taiko_read(struct snd_soc_codec *codec,
3612 unsigned int reg)
3613{
3614 unsigned int val;
3615 int ret;
3616
Kuirong Wang906ac472012-07-09 12:54:44 -07003617 if (reg == SND_SOC_NOPM)
3618 return 0;
3619
Kiran Kandic3b24402012-06-11 00:05:59 -07003620 BUG_ON(reg > TAIKO_MAX_REGISTER);
3621
3622 if (!taiko_volatile(codec, reg) && taiko_readable(codec, reg) &&
3623 reg < codec->driver->reg_cache_size) {
3624 ret = snd_soc_cache_read(codec, reg, &val);
3625 if (ret >= 0) {
3626 return val;
3627 } else
3628 dev_err(codec->dev, "Cache read from %x failed: %d\n",
3629 reg, ret);
3630 }
3631
3632 val = wcd9xxx_reg_read(codec->control_data, reg);
3633 return val;
3634}
3635
Kiran Kandic3b24402012-06-11 00:05:59 -07003636static int taiko_startup(struct snd_pcm_substream *substream,
3637 struct snd_soc_dai *dai)
3638{
3639 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
3640 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
3641 substream->name, substream->stream);
3642 if ((taiko_core != NULL) &&
3643 (taiko_core->dev != NULL) &&
3644 (taiko_core->dev->parent != NULL))
3645 pm_runtime_get_sync(taiko_core->dev->parent);
3646
3647 return 0;
3648}
3649
3650static void taiko_shutdown(struct snd_pcm_substream *substream,
3651 struct snd_soc_dai *dai)
3652{
3653 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
3654 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
3655 substream->name, substream->stream);
3656 if ((taiko_core != NULL) &&
3657 (taiko_core->dev != NULL) &&
3658 (taiko_core->dev->parent != NULL)) {
3659 pm_runtime_mark_last_busy(taiko_core->dev->parent);
3660 pm_runtime_put(taiko_core->dev->parent);
3661 }
3662}
3663
3664int taiko_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm)
3665{
3666 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3667
3668 pr_debug("%s: mclk_enable = %u, dapm = %d\n", __func__, mclk_enable,
3669 dapm);
Joonwoo Parka8890262012-10-15 12:04:27 -07003670
3671 WCD9XXX_BCL_LOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07003672 if (mclk_enable) {
Joonwoo Parka8890262012-10-15 12:04:27 -07003673 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
3674 WCD9XXX_BANDGAP_AUDIO_MODE);
3675 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
Kiran Kandic3b24402012-06-11 00:05:59 -07003676 } else {
Joonwoo Parka8890262012-10-15 12:04:27 -07003677 /* Put clock and BG */
3678 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
3679 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
3680 WCD9XXX_BANDGAP_AUDIO_MODE);
Kiran Kandic3b24402012-06-11 00:05:59 -07003681 }
Joonwoo Parka8890262012-10-15 12:04:27 -07003682 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
3683
Kiran Kandic3b24402012-06-11 00:05:59 -07003684 return 0;
3685}
3686
3687static int taiko_set_dai_sysclk(struct snd_soc_dai *dai,
3688 int clk_id, unsigned int freq, int dir)
3689{
Venkat Sudhira50a3762012-11-26 12:12:15 -08003690 pr_debug("%s\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07003691 return 0;
3692}
3693
3694static int taiko_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3695{
3696 u8 val = 0;
3697 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
3698
3699 pr_debug("%s\n", __func__);
3700 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3701 case SND_SOC_DAIFMT_CBS_CFS:
3702 /* CPU is master */
3703 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3704 if (dai->id == AIF1_CAP)
3705 snd_soc_update_bits(dai->codec,
3706 TAIKO_A_CDC_CLK_TX_I2S_CTL,
3707 TAIKO_I2S_MASTER_MODE_MASK, 0);
3708 else if (dai->id == AIF1_PB)
3709 snd_soc_update_bits(dai->codec,
3710 TAIKO_A_CDC_CLK_RX_I2S_CTL,
3711 TAIKO_I2S_MASTER_MODE_MASK, 0);
3712 }
3713 break;
3714 case SND_SOC_DAIFMT_CBM_CFM:
3715 /* CPU is slave */
3716 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3717 val = TAIKO_I2S_MASTER_MODE_MASK;
3718 if (dai->id == AIF1_CAP)
3719 snd_soc_update_bits(dai->codec,
3720 TAIKO_A_CDC_CLK_TX_I2S_CTL, val, val);
3721 else if (dai->id == AIF1_PB)
3722 snd_soc_update_bits(dai->codec,
3723 TAIKO_A_CDC_CLK_RX_I2S_CTL, val, val);
3724 }
3725 break;
3726 default:
3727 return -EINVAL;
3728 }
3729 return 0;
3730}
3731
3732static int taiko_set_channel_map(struct snd_soc_dai *dai,
3733 unsigned int tx_num, unsigned int *tx_slot,
3734 unsigned int rx_num, unsigned int *rx_slot)
3735
3736{
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003737 struct wcd9xxx_codec_dai_data *dai_data = NULL;
Kiran Kandic3b24402012-06-11 00:05:59 -07003738 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07003739 struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07003740 if (!tx_slot && !rx_slot) {
3741 pr_err("%s: Invalid\n", __func__);
3742 return -EINVAL;
3743 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003744 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
3745 "taiko->intf_type %d\n",
3746 __func__, dai->name, dai->id, tx_num, rx_num,
3747 taiko->intf_type);
Kiran Kandic3b24402012-06-11 00:05:59 -07003748
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003749 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Kuirong Wang906ac472012-07-09 12:54:44 -07003750 wcd9xxx_init_slimslave(core, core->slim->laddr,
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003751 tx_num, tx_slot, rx_num, rx_slot);
3752 /*Reserve tx11 and tx12 for VI feedback path*/
3753 dai_data = &taiko->dai[AIF4_VIFEED];
3754 if (dai_data) {
3755 list_add_tail(&core->tx_chs[TAIKO_TX11].list,
3756 &dai_data->wcd9xxx_ch_list);
3757 list_add_tail(&core->tx_chs[TAIKO_TX12].list,
3758 &dai_data->wcd9xxx_ch_list);
3759 }
3760 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003761 return 0;
3762}
3763
3764static int taiko_get_channel_map(struct snd_soc_dai *dai,
3765 unsigned int *tx_num, unsigned int *tx_slot,
3766 unsigned int *rx_num, unsigned int *rx_slot)
3767
3768{
3769 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(dai->codec);
3770 u32 i = 0;
3771 struct wcd9xxx_ch *ch;
3772
3773 switch (dai->id) {
3774 case AIF1_PB:
3775 case AIF2_PB:
3776 case AIF3_PB:
3777 if (!rx_slot || !rx_num) {
3778 pr_err("%s: Invalid rx_slot %d or rx_num %d\n",
3779 __func__, (u32) rx_slot, (u32) rx_num);
3780 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07003781 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003782 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
3783 list) {
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05003784 pr_debug("%s: slot_num %u ch->ch_num %d\n",
3785 __func__, i, ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07003786 rx_slot[i++] = ch->ch_num;
3787 }
3788 pr_debug("%s: rx_num %d\n", __func__, i);
3789 *rx_num = i;
3790 break;
3791 case AIF1_CAP:
3792 case AIF2_CAP:
3793 case AIF3_CAP:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05003794 case AIF4_VIFEED:
Joonwoo Park1d05bb92013-03-07 16:55:06 -08003795 case AIF4_MAD_TX:
Kuirong Wang906ac472012-07-09 12:54:44 -07003796 if (!tx_slot || !tx_num) {
3797 pr_err("%s: Invalid tx_slot %d or tx_num %d\n",
3798 __func__, (u32) tx_slot, (u32) tx_num);
3799 return -EINVAL;
3800 }
3801 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
3802 list) {
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05003803 pr_debug("%s: slot_num %u ch->ch_num %d\n",
3804 __func__, i, ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07003805 tx_slot[i++] = ch->ch_num;
3806 }
3807 pr_debug("%s: tx_num %d\n", __func__, i);
3808 *tx_num = i;
3809 break;
3810
3811 default:
3812 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
3813 break;
3814 }
3815
3816 return 0;
3817}
3818
3819static int taiko_set_interpolator_rate(struct snd_soc_dai *dai,
3820 u8 rx_fs_rate_reg_val, u32 compander_fs, u32 sample_rate)
3821{
3822 u32 j;
3823 u8 rx_mix1_inp;
3824 u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
3825 u16 rx_fs_reg;
3826 u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
3827 struct snd_soc_codec *codec = dai->codec;
3828 struct wcd9xxx_ch *ch;
3829 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3830
3831 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
3832 /* for RX port starting from 16 instead of 10 like tabla */
3833 rx_mix1_inp = ch->port + RX_MIX1_INP_SEL_RX1 -
3834 TAIKO_TX_PORT_NUMBER;
3835 if ((rx_mix1_inp < RX_MIX1_INP_SEL_RX1) ||
3836 (rx_mix1_inp > RX_MIX1_INP_SEL_RX7)) {
3837 pr_err("%s: Invalid TAIKO_RX%u port. Dai ID is %d\n",
3838 __func__, rx_mix1_inp - 5 , dai->id);
3839 return -EINVAL;
3840 }
3841
3842 rx_mix_1_reg_1 = TAIKO_A_CDC_CONN_RX1_B1_CTL;
3843
3844 for (j = 0; j < NUM_INTERPOLATORS; j++) {
3845 rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
3846
3847 rx_mix_1_reg_1_val = snd_soc_read(codec,
3848 rx_mix_1_reg_1);
3849 rx_mix_1_reg_2_val = snd_soc_read(codec,
3850 rx_mix_1_reg_2);
3851
3852 if (((rx_mix_1_reg_1_val & 0x0F) == rx_mix1_inp) ||
3853 (((rx_mix_1_reg_1_val >> 4) & 0x0F)
3854 == rx_mix1_inp) ||
3855 ((rx_mix_1_reg_2_val & 0x0F) == rx_mix1_inp)) {
3856
3857 rx_fs_reg = TAIKO_A_CDC_RX1_B5_CTL + 8 * j;
3858
3859 pr_debug("%s: AIF_PB DAI(%d) connected to RX%u\n",
3860 __func__, dai->id, j + 1);
3861
3862 pr_debug("%s: set RX%u sample rate to %u\n",
3863 __func__, j + 1, sample_rate);
3864
3865 snd_soc_update_bits(codec, rx_fs_reg,
3866 0xE0, rx_fs_rate_reg_val);
3867
3868 if (comp_rx_path[j] < COMPANDER_MAX)
3869 taiko->comp_fs[comp_rx_path[j]]
3870 = compander_fs;
3871 }
3872 if (j <= 2)
3873 rx_mix_1_reg_1 += 3;
3874 else
3875 rx_mix_1_reg_1 += 2;
Kiran Kandic3b24402012-06-11 00:05:59 -07003876 }
3877 }
3878 return 0;
3879}
3880
Kuirong Wang906ac472012-07-09 12:54:44 -07003881static int taiko_set_decimator_rate(struct snd_soc_dai *dai,
3882 u8 tx_fs_rate_reg_val, u32 sample_rate)
Kiran Kandic3b24402012-06-11 00:05:59 -07003883{
Kuirong Wang906ac472012-07-09 12:54:44 -07003884 struct snd_soc_codec *codec = dai->codec;
3885 struct wcd9xxx_ch *ch;
3886 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3887 u32 tx_port;
3888 u16 tx_port_reg, tx_fs_reg;
3889 u8 tx_port_reg_val;
3890 s8 decimator;
Kiran Kandic3b24402012-06-11 00:05:59 -07003891
Kuirong Wang906ac472012-07-09 12:54:44 -07003892 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
Kiran Kandic3b24402012-06-11 00:05:59 -07003893
Kuirong Wang906ac472012-07-09 12:54:44 -07003894 tx_port = ch->port + 1;
3895 pr_debug("%s: dai->id = %d, tx_port = %d",
3896 __func__, dai->id, tx_port);
3897
3898 if ((tx_port < 1) || (tx_port > NUM_DECIMATORS)) {
3899 pr_err("%s: Invalid SLIM TX%u port. DAI ID is %d\n",
3900 __func__, tx_port, dai->id);
3901 return -EINVAL;
3902 }
3903
3904 tx_port_reg = TAIKO_A_CDC_CONN_TX_SB_B1_CTL + (tx_port - 1);
3905 tx_port_reg_val = snd_soc_read(codec, tx_port_reg);
3906
3907 decimator = 0;
3908
3909 if ((tx_port >= 1) && (tx_port <= 6)) {
3910
3911 tx_port_reg_val = tx_port_reg_val & 0x0F;
3912 if (tx_port_reg_val == 0x8)
3913 decimator = tx_port;
3914
3915 } else if ((tx_port >= 7) && (tx_port <= NUM_DECIMATORS)) {
3916
3917 tx_port_reg_val = tx_port_reg_val & 0x1F;
3918
3919 if ((tx_port_reg_val >= 0x8) &&
3920 (tx_port_reg_val <= 0x11)) {
3921
3922 decimator = (tx_port_reg_val - 0x8) + 1;
3923 }
3924 }
3925
3926 if (decimator) { /* SLIM_TX port has a DEC as input */
3927
3928 tx_fs_reg = TAIKO_A_CDC_TX1_CLK_FS_CTL +
3929 8 * (decimator - 1);
3930
3931 pr_debug("%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
3932 __func__, decimator, tx_port, sample_rate);
3933
3934 snd_soc_update_bits(codec, tx_fs_reg, 0x07,
3935 tx_fs_rate_reg_val);
3936
3937 } else {
3938 if ((tx_port_reg_val >= 0x1) &&
3939 (tx_port_reg_val <= 0x7)) {
3940
3941 pr_debug("%s: RMIX%u going to SLIM TX%u\n",
3942 __func__, tx_port_reg_val, tx_port);
3943
3944 } else if ((tx_port_reg_val >= 0x8) &&
3945 (tx_port_reg_val <= 0x11)) {
3946
3947 pr_err("%s: ERROR: Should not be here\n",
3948 __func__);
3949 pr_err("%s: ERROR: DEC connected to SLIM TX%u\n",
3950 __func__, tx_port);
3951 return -EINVAL;
3952
3953 } else if (tx_port_reg_val == 0) {
3954 pr_debug("%s: no signal to SLIM TX%u\n",
3955 __func__, tx_port);
3956 } else {
3957 pr_err("%s: ERROR: wrong signal to SLIM TX%u\n",
3958 __func__, tx_port);
3959 pr_err("%s: ERROR: wrong signal = %u\n",
3960 __func__, tx_port_reg_val);
3961 return -EINVAL;
3962 }
3963 }
Kiran Kandic3b24402012-06-11 00:05:59 -07003964 }
Kiran Kandic3b24402012-06-11 00:05:59 -07003965 return 0;
3966}
3967
3968static int taiko_hw_params(struct snd_pcm_substream *substream,
3969 struct snd_pcm_hw_params *params,
3970 struct snd_soc_dai *dai)
3971{
3972 struct snd_soc_codec *codec = dai->codec;
3973 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07003974 u8 tx_fs_rate, rx_fs_rate;
Kiran Kandic3b24402012-06-11 00:05:59 -07003975 u32 compander_fs;
Kuirong Wang906ac472012-07-09 12:54:44 -07003976 int ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07003977
3978 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
3979 dai->name, dai->id, params_rate(params),
3980 params_channels(params));
3981
3982 switch (params_rate(params)) {
3983 case 8000:
3984 tx_fs_rate = 0x00;
3985 rx_fs_rate = 0x00;
3986 compander_fs = COMPANDER_FS_8KHZ;
3987 break;
3988 case 16000:
3989 tx_fs_rate = 0x01;
3990 rx_fs_rate = 0x20;
3991 compander_fs = COMPANDER_FS_16KHZ;
3992 break;
3993 case 32000:
3994 tx_fs_rate = 0x02;
3995 rx_fs_rate = 0x40;
3996 compander_fs = COMPANDER_FS_32KHZ;
3997 break;
3998 case 48000:
3999 tx_fs_rate = 0x03;
4000 rx_fs_rate = 0x60;
4001 compander_fs = COMPANDER_FS_48KHZ;
4002 break;
4003 case 96000:
4004 tx_fs_rate = 0x04;
4005 rx_fs_rate = 0x80;
4006 compander_fs = COMPANDER_FS_96KHZ;
4007 break;
4008 case 192000:
4009 tx_fs_rate = 0x05;
4010 rx_fs_rate = 0xA0;
4011 compander_fs = COMPANDER_FS_192KHZ;
4012 break;
4013 default:
4014 pr_err("%s: Invalid sampling rate %d\n", __func__,
Kuirong Wang906ac472012-07-09 12:54:44 -07004015 params_rate(params));
Kiran Kandic3b24402012-06-11 00:05:59 -07004016 return -EINVAL;
4017 }
4018
Kuirong Wang906ac472012-07-09 12:54:44 -07004019 switch (substream->stream) {
4020 case SNDRV_PCM_STREAM_CAPTURE:
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004021 if (dai->id != AIF4_VIFEED) {
4022 ret = taiko_set_decimator_rate(dai, tx_fs_rate,
4023 params_rate(params));
4024 if (ret < 0) {
4025 pr_err("%s: set decimator rate failed %d\n",
4026 __func__, ret);
4027 return ret;
4028 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004029 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004030
Kiran Kandic3b24402012-06-11 00:05:59 -07004031 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4032 switch (params_format(params)) {
4033 case SNDRV_PCM_FORMAT_S16_LE:
4034 snd_soc_update_bits(codec,
4035 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4036 0x20, 0x20);
4037 break;
4038 case SNDRV_PCM_FORMAT_S32_LE:
4039 snd_soc_update_bits(codec,
4040 TAIKO_A_CDC_CLK_TX_I2S_CTL,
4041 0x20, 0x00);
4042 break;
4043 default:
4044 pr_err("invalid format\n");
4045 break;
4046 }
4047 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07004048 0x07, tx_fs_rate);
Kiran Kandic3b24402012-06-11 00:05:59 -07004049 } else {
Kuirong Wang906ac472012-07-09 12:54:44 -07004050 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07004051 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004052 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07004053
Kuirong Wang906ac472012-07-09 12:54:44 -07004054 case SNDRV_PCM_STREAM_PLAYBACK:
4055 ret = taiko_set_interpolator_rate(dai, rx_fs_rate,
4056 compander_fs,
4057 params_rate(params));
4058 if (ret < 0) {
4059 pr_err("%s: set decimator rate failed %d\n", __func__,
4060 ret);
4061 return ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07004062 }
4063 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4064 switch (params_format(params)) {
4065 case SNDRV_PCM_FORMAT_S16_LE:
4066 snd_soc_update_bits(codec,
4067 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4068 0x20, 0x20);
4069 break;
4070 case SNDRV_PCM_FORMAT_S32_LE:
4071 snd_soc_update_bits(codec,
4072 TAIKO_A_CDC_CLK_RX_I2S_CTL,
4073 0x20, 0x00);
4074 break;
4075 default:
4076 pr_err("invalid format\n");
4077 break;
4078 }
4079 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07004080 0x03, (rx_fs_rate >> 0x05));
Kiran Kandic3b24402012-06-11 00:05:59 -07004081 } else {
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004082 switch (params_format(params)) {
4083 case SNDRV_PCM_FORMAT_S16_LE:
4084 snd_soc_update_bits(codec,
4085 TAIKO_A_CDC_CONN_RX_SB_B1_CTL,
4086 0xFF, 0xAA);
4087 snd_soc_update_bits(codec,
4088 TAIKO_A_CDC_CONN_RX_SB_B2_CTL,
4089 0xFF, 0x2A);
4090 taiko->dai[dai->id].bit_width = 16;
4091 break;
4092 case SNDRV_PCM_FORMAT_S24_LE:
4093 snd_soc_update_bits(codec,
4094 TAIKO_A_CDC_CONN_RX_SB_B1_CTL,
4095 0xFF, 0x00);
4096 snd_soc_update_bits(codec,
4097 TAIKO_A_CDC_CONN_RX_SB_B2_CTL,
4098 0xFF, 0x00);
4099 taiko->dai[dai->id].bit_width = 24;
4100 break;
4101 default:
4102 dev_err(codec->dev, "Invalid format\n");
4103 break;
4104 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004105 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07004106 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004107 break;
4108 default:
4109 pr_err("%s: Invalid stream type %d\n", __func__,
4110 substream->stream);
4111 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004112 }
4113
4114 return 0;
4115}
4116
4117static struct snd_soc_dai_ops taiko_dai_ops = {
4118 .startup = taiko_startup,
4119 .shutdown = taiko_shutdown,
4120 .hw_params = taiko_hw_params,
4121 .set_sysclk = taiko_set_dai_sysclk,
4122 .set_fmt = taiko_set_dai_fmt,
4123 .set_channel_map = taiko_set_channel_map,
4124 .get_channel_map = taiko_get_channel_map,
4125};
4126
4127static struct snd_soc_dai_driver taiko_dai[] = {
4128 {
4129 .name = "taiko_rx1",
4130 .id = AIF1_PB,
4131 .playback = {
4132 .stream_name = "AIF1 Playback",
4133 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004134 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004135 .rate_max = 192000,
4136 .rate_min = 8000,
4137 .channels_min = 1,
4138 .channels_max = 2,
4139 },
4140 .ops = &taiko_dai_ops,
4141 },
4142 {
4143 .name = "taiko_tx1",
4144 .id = AIF1_CAP,
4145 .capture = {
4146 .stream_name = "AIF1 Capture",
4147 .rates = WCD9320_RATES,
4148 .formats = TAIKO_FORMATS,
4149 .rate_max = 192000,
4150 .rate_min = 8000,
4151 .channels_min = 1,
4152 .channels_max = 4,
4153 },
4154 .ops = &taiko_dai_ops,
4155 },
4156 {
4157 .name = "taiko_rx2",
4158 .id = AIF2_PB,
4159 .playback = {
4160 .stream_name = "AIF2 Playback",
4161 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004162 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004163 .rate_min = 8000,
4164 .rate_max = 192000,
4165 .channels_min = 1,
4166 .channels_max = 2,
4167 },
4168 .ops = &taiko_dai_ops,
4169 },
4170 {
4171 .name = "taiko_tx2",
4172 .id = AIF2_CAP,
4173 .capture = {
4174 .stream_name = "AIF2 Capture",
4175 .rates = WCD9320_RATES,
4176 .formats = TAIKO_FORMATS,
4177 .rate_max = 192000,
4178 .rate_min = 8000,
4179 .channels_min = 1,
4180 .channels_max = 4,
4181 },
4182 .ops = &taiko_dai_ops,
4183 },
4184 {
4185 .name = "taiko_tx3",
4186 .id = AIF3_CAP,
4187 .capture = {
4188 .stream_name = "AIF3 Capture",
4189 .rates = WCD9320_RATES,
4190 .formats = TAIKO_FORMATS,
4191 .rate_max = 48000,
4192 .rate_min = 8000,
4193 .channels_min = 1,
4194 .channels_max = 2,
4195 },
4196 .ops = &taiko_dai_ops,
4197 },
4198 {
4199 .name = "taiko_rx3",
4200 .id = AIF3_PB,
4201 .playback = {
4202 .stream_name = "AIF3 Playback",
4203 .rates = WCD9320_RATES,
Bhalchandra Gajare5b40c532013-02-19 13:36:47 -08004204 .formats = TAIKO_FORMATS_S16_S24_LE,
Kiran Kandic3b24402012-06-11 00:05:59 -07004205 .rate_min = 8000,
4206 .rate_max = 192000,
4207 .channels_min = 1,
4208 .channels_max = 2,
4209 },
4210 .ops = &taiko_dai_ops,
4211 },
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004212 {
4213 .name = "taiko_vifeedback",
4214 .id = AIF4_VIFEED,
4215 .capture = {
4216 .stream_name = "VIfeed",
4217 .rates = SNDRV_PCM_RATE_48000,
4218 .formats = TAIKO_FORMATS,
4219 .rate_max = 48000,
4220 .rate_min = 48000,
4221 .channels_min = 2,
4222 .channels_max = 2,
4223 },
4224 .ops = &taiko_dai_ops,
4225 },
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004226 {
4227 .name = "taiko_mad1",
4228 .id = AIF4_MAD_TX,
4229 .capture = {
4230 .stream_name = "AIF4 MAD TX",
4231 .rates = SNDRV_PCM_RATE_16000,
4232 .formats = TAIKO_FORMATS,
4233 .rate_min = 16000,
4234 .rate_max = 16000,
4235 .channels_min = 1,
4236 .channels_max = 1,
4237 },
4238 .ops = &taiko_dai_ops,
4239 },
Kiran Kandic3b24402012-06-11 00:05:59 -07004240};
4241
4242static struct snd_soc_dai_driver taiko_i2s_dai[] = {
4243 {
4244 .name = "taiko_i2s_rx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07004245 .id = AIF1_PB,
Kiran Kandic3b24402012-06-11 00:05:59 -07004246 .playback = {
4247 .stream_name = "AIF1 Playback",
4248 .rates = WCD9320_RATES,
4249 .formats = TAIKO_FORMATS,
4250 .rate_max = 192000,
4251 .rate_min = 8000,
4252 .channels_min = 1,
4253 .channels_max = 4,
4254 },
4255 .ops = &taiko_dai_ops,
4256 },
4257 {
4258 .name = "taiko_i2s_tx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07004259 .id = AIF1_CAP,
Kiran Kandic3b24402012-06-11 00:05:59 -07004260 .capture = {
4261 .stream_name = "AIF1 Capture",
4262 .rates = WCD9320_RATES,
4263 .formats = TAIKO_FORMATS,
4264 .rate_max = 192000,
4265 .rate_min = 8000,
4266 .channels_min = 1,
4267 .channels_max = 4,
4268 },
4269 .ops = &taiko_dai_ops,
4270 },
Venkat Sudhir994193b2012-12-17 17:30:51 -08004271 {
4272 .name = "taiko_i2s_rx2",
4273 .id = AIF1_PB,
4274 .playback = {
4275 .stream_name = "AIF2 Playback",
4276 .rates = WCD9320_RATES,
4277 .formats = TAIKO_FORMATS,
4278 .rate_max = 192000,
4279 .rate_min = 8000,
4280 .channels_min = 1,
4281 .channels_max = 4,
4282 },
4283 .ops = &taiko_dai_ops,
4284 },
4285 {
4286 .name = "taiko_i2s_tx2",
4287 .id = AIF1_CAP,
4288 .capture = {
4289 .stream_name = "AIF2 Capture",
4290 .rates = WCD9320_RATES,
4291 .formats = TAIKO_FORMATS,
4292 .rate_max = 192000,
4293 .rate_min = 8000,
4294 .channels_min = 1,
4295 .channels_max = 4,
4296 },
4297 .ops = &taiko_dai_ops,
4298 },
Kiran Kandic3b24402012-06-11 00:05:59 -07004299};
4300
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004301static int taiko_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
4302 bool up)
4303{
4304 int ret = 0;
4305 struct wcd9xxx_ch *ch;
4306
4307 if (up) {
4308 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
4309 ret = wcd9xxx_get_slave_port(ch->ch_num);
4310 if (ret < 0) {
4311 pr_err("%s: Invalid slave port ID: %d\n",
4312 __func__, ret);
4313 ret = -EINVAL;
4314 } else {
4315 set_bit(ret, &dai->ch_mask);
4316 }
4317 }
4318 } else {
4319 ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
4320 msecs_to_jiffies(
4321 TAIKO_SLIM_CLOSE_TIMEOUT));
4322 if (!ret) {
4323 pr_err("%s: Slim close tx/rx wait timeout\n", __func__);
4324 ret = -ETIMEDOUT;
4325 } else {
4326 ret = 0;
4327 }
4328 }
4329 return ret;
4330}
4331
Kiran Kandic3b24402012-06-11 00:05:59 -07004332static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07004333 struct snd_kcontrol *kcontrol,
4334 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07004335{
Kuirong Wang906ac472012-07-09 12:54:44 -07004336 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07004337 struct snd_soc_codec *codec = w->codec;
4338 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004339 int ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07004340 struct wcd9xxx_codec_dai_data *dai;
4341
4342 core = dev_get_drvdata(codec->dev->parent);
4343
4344 pr_debug("%s: event called! codec name %s num_dai %d\n"
4345 "stream name %s event %d\n",
4346 __func__, w->codec->name, w->codec->num_dai, w->sname, event);
4347
Kiran Kandic3b24402012-06-11 00:05:59 -07004348 /* Execute the callback only if interface type is slimbus */
4349 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
4350 return 0;
4351
Kuirong Wang906ac472012-07-09 12:54:44 -07004352 dai = &taiko_p->dai[w->shift];
4353 pr_debug("%s: w->name %s w->shift %d event %d\n",
4354 __func__, w->name, w->shift, event);
Kiran Kandic3b24402012-06-11 00:05:59 -07004355
4356 switch (event) {
4357 case SND_SOC_DAPM_POST_PMU:
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004358 (void) taiko_codec_enable_slim_chmask(dai, true);
Kuirong Wang906ac472012-07-09 12:54:44 -07004359 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
4360 dai->rate, dai->bit_width,
4361 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07004362 break;
4363 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07004364 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
4365 dai->grph);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004366 ret = taiko_codec_enable_slim_chmask(dai, false);
4367 if (ret < 0) {
4368 ret = wcd9xxx_disconnect_port(core,
4369 &dai->wcd9xxx_ch_list,
4370 dai->grph);
4371 pr_debug("%s: Disconnect RX port, ret = %d\n",
4372 __func__, ret);
4373 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004374 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07004375 }
4376 return ret;
4377}
4378
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004379static int taiko_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
4380 struct snd_kcontrol *kcontrol,
4381 int event)
4382{
4383 struct wcd9xxx *core = NULL;
4384 struct snd_soc_codec *codec = NULL;
4385 struct taiko_priv *taiko_p = NULL;
4386 u32 ret = 0;
4387 struct wcd9xxx_codec_dai_data *dai = NULL;
4388
4389 if (!w || !w->codec) {
4390 pr_err("%s invalid params\n", __func__);
4391 return -EINVAL;
4392 }
4393 codec = w->codec;
4394 taiko_p = snd_soc_codec_get_drvdata(codec);
4395 core = dev_get_drvdata(codec->dev->parent);
4396
4397 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
4398 __func__, w->codec->name, w->codec->num_dai, w->sname);
4399
4400 /* Execute the callback only if interface type is slimbus */
4401 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
4402 pr_err("%s Interface is not correct", __func__);
4403 return 0;
4404 }
4405
4406 pr_debug("%s(): w->name %s event %d w->shift %d\n",
4407 __func__, w->name, event, w->shift);
4408 if (w->shift != AIF4_VIFEED) {
4409 pr_err("%s Error in enabling the tx path\n", __func__);
4410 ret = -EINVAL;
4411 goto out_vi;
4412 }
4413 dai = &taiko_p->dai[w->shift];
4414 switch (event) {
4415 case SND_SOC_DAPM_POST_PMU:
4416 /*Enable Clip Detection*/
4417 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_CLIP_DET,
4418 0x8, 0x8);
4419 /*Enable V&I sensing*/
4420 snd_soc_update_bits(codec, TAIKO_A_SPKR_PROT_EN,
4421 0x88, 0x88);
4422 /*Enable spkr VI clocks*/
4423 snd_soc_update_bits(codec,
4424 TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0xC, 0xC);
4425 /*Enable Voltage Decimator*/
4426 snd_soc_update_bits(codec,
4427 TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x1F, 0x12);
4428 /*Enable Current Decimator*/
4429 snd_soc_update_bits(codec,
4430 TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x1F, 0x13);
4431 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
4432 dai->rate, dai->bit_width,
4433 &dai->grph);
4434 break;
4435 case SND_SOC_DAPM_POST_PMD:
4436 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
4437 dai->grph);
4438 if (ret)
4439 pr_err("%s error in close_slim_sch_tx %d\n",
4440 __func__, ret);
4441 /*Disable Voltage decimator*/
4442 snd_soc_update_bits(codec,
4443 TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x1F, 0x0);
4444 /*Disable Current decimator*/
4445 snd_soc_update_bits(codec,
4446 TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x1F, 0x0);
4447 /*Disable spkr VI clocks*/
4448 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL,
4449 0xC, 0x0);
4450 /*Disable V&I sensing*/
4451 snd_soc_update_bits(codec, TAIKO_A_SPKR_PROT_EN,
4452 0x88, 0x00);
4453 /*Disable clip detection*/
4454 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_CLIP_DET,
4455 0x8, 0x0);
4456 break;
4457 }
4458out_vi:
4459 return ret;
4460}
4461
Kiran Kandic3b24402012-06-11 00:05:59 -07004462static int taiko_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07004463 struct snd_kcontrol *kcontrol,
4464 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07004465{
Kuirong Wang906ac472012-07-09 12:54:44 -07004466 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07004467 struct snd_soc_codec *codec = w->codec;
4468 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07004469 u32 ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07004470 struct wcd9xxx_codec_dai_data *dai;
Kiran Kandic3b24402012-06-11 00:05:59 -07004471
Kuirong Wang906ac472012-07-09 12:54:44 -07004472 core = dev_get_drvdata(codec->dev->parent);
4473
4474 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
4475 __func__, w->codec->name, w->codec->num_dai, w->sname);
Kiran Kandic3b24402012-06-11 00:05:59 -07004476
4477 /* Execute the callback only if interface type is slimbus */
4478 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
4479 return 0;
4480
Kuirong Wang906ac472012-07-09 12:54:44 -07004481 pr_debug("%s(): w->name %s event %d w->shift %d\n",
4482 __func__, w->name, event, w->shift);
Kiran Kandic3b24402012-06-11 00:05:59 -07004483
Kuirong Wang906ac472012-07-09 12:54:44 -07004484 dai = &taiko_p->dai[w->shift];
Kiran Kandic3b24402012-06-11 00:05:59 -07004485 switch (event) {
4486 case SND_SOC_DAPM_POST_PMU:
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004487 (void) taiko_codec_enable_slim_chmask(dai, true);
Kuirong Wang906ac472012-07-09 12:54:44 -07004488 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
4489 dai->rate, dai->bit_width,
4490 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07004491 break;
4492 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07004493 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
4494 dai->grph);
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08004495 ret = taiko_codec_enable_slim_chmask(dai, false);
4496 if (ret < 0) {
4497 ret = wcd9xxx_disconnect_port(core,
4498 &dai->wcd9xxx_ch_list,
4499 dai->grph);
4500 pr_debug("%s: Disconnect RX port, ret = %d\n",
4501 __func__, ret);
4502 }
Kuirong Wang906ac472012-07-09 12:54:44 -07004503 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07004504 }
4505 return ret;
4506}
4507
Kiran Kandi4c56c592012-07-25 11:04:55 -07004508static int taiko_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
4509 struct snd_kcontrol *kcontrol, int event)
4510{
4511 struct snd_soc_codec *codec = w->codec;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004512 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandi4c56c592012-07-25 11:04:55 -07004513
4514 pr_debug("%s %s %d\n", __func__, w->name, event);
4515
4516 switch (event) {
Kiran Kandi4c56c592012-07-25 11:04:55 -07004517 case SND_SOC_DAPM_POST_PMU:
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004518 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
4519 WCD9XXX_CLSH_STATE_EAR,
4520 WCD9XXX_CLSH_REQ_ENABLE,
4521 WCD9XXX_CLSH_EVENT_POST_PA);
Kiran Kandi4c56c592012-07-25 11:04:55 -07004522
4523 usleep_range(5000, 5000);
4524 break;
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004525 case SND_SOC_DAPM_POST_PMD:
4526 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
4527 WCD9XXX_CLSH_STATE_EAR,
4528 WCD9XXX_CLSH_REQ_DISABLE,
4529 WCD9XXX_CLSH_EVENT_POST_PA);
4530 usleep_range(5000, 5000);
4531 }
4532 return 0;
4533}
4534
4535static int taiko_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
4536 struct snd_kcontrol *kcontrol, int event)
4537{
4538 struct snd_soc_codec *codec = w->codec;
4539 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
4540
4541 pr_debug("%s %s %d\n", __func__, w->name, event);
4542
4543 switch (event) {
4544 case SND_SOC_DAPM_PRE_PMU:
4545 wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
4546 WCD9XXX_CLSH_STATE_EAR,
4547 WCD9XXX_CLSH_REQ_ENABLE,
4548 WCD9XXX_CLSH_EVENT_PRE_DAC);
4549 break;
4550 }
4551
4552 return 0;
4553}
4554
4555static int taiko_codec_dsm_mux_event(struct snd_soc_dapm_widget *w,
4556 struct snd_kcontrol *kcontrol, int event)
4557{
4558 struct snd_soc_codec *codec = w->codec;
4559 u8 reg_val, zoh_mux_val = 0x00;
4560
4561 pr_debug("%s: event = %d\n", __func__, event);
4562
4563 switch (event) {
4564 case SND_SOC_DAPM_POST_PMU:
4565 reg_val = snd_soc_read(codec, TAIKO_A_CDC_CONN_CLSH_CTL);
4566
4567 if ((reg_val & 0x30) == 0x10)
4568 zoh_mux_val = 0x04;
4569 else if ((reg_val & 0x30) == 0x20)
4570 zoh_mux_val = 0x08;
4571
4572 if (zoh_mux_val != 0x00)
4573 snd_soc_update_bits(codec,
4574 TAIKO_A_CDC_CONN_CLSH_CTL,
4575 0x0C, zoh_mux_val);
4576 break;
4577
4578 case SND_SOC_DAPM_POST_PMD:
4579 snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_CLSH_CTL,
4580 0x0C, 0x00);
4581 break;
Kiran Kandi4c56c592012-07-25 11:04:55 -07004582 }
4583 return 0;
4584}
4585
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08004586static int taiko_codec_enable_anc_ear(struct snd_soc_dapm_widget *w,
4587 struct snd_kcontrol *kcontrol, int event)
4588{
4589 struct snd_soc_codec *codec = w->codec;
4590 int ret = 0;
4591
4592 switch (event) {
4593 case SND_SOC_DAPM_PRE_PMU:
4594 ret = taiko_codec_enable_anc(w, kcontrol, event);
4595 msleep(50);
4596 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x10);
4597 break;
4598 case SND_SOC_DAPM_POST_PMU:
4599 ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
4600 break;
4601 case SND_SOC_DAPM_PRE_PMD:
4602 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x00);
4603 msleep(40);
4604 ret |= taiko_codec_enable_anc(w, kcontrol, event);
4605 break;
4606 case SND_SOC_DAPM_POST_PMD:
4607 ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
4608 break;
4609 }
4610 return ret;
4611}
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004612
Kiran Kandic3b24402012-06-11 00:05:59 -07004613/* Todo: Have seperate dapm widgets for I2S and Slimbus.
4614 * Might Need to have callbacks registered only for slimbus
4615 */
4616static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
4617 /*RX stuff */
4618 SND_SOC_DAPM_OUTPUT("EAR"),
4619
Kiran Kandi4c56c592012-07-25 11:04:55 -07004620 SND_SOC_DAPM_PGA_E("EAR PA", TAIKO_A_RX_EAR_EN, 4, 0, NULL, 0,
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004621 taiko_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU |
4622 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004623
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004624 SND_SOC_DAPM_MIXER_E("DAC1", TAIKO_A_RX_EAR_EN, 6, 0, dac1_switch,
4625 ARRAY_SIZE(dac1_switch), taiko_codec_ear_dac_event,
4626 SND_SOC_DAPM_PRE_PMU),
Kiran Kandic3b24402012-06-11 00:05:59 -07004627
Kuirong Wang906ac472012-07-09 12:54:44 -07004628 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
4629 AIF1_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07004630 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07004631 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
4632 AIF2_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07004633 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07004634 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
4635 AIF3_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07004636 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4637
Kuirong Wang906ac472012-07-09 12:54:44 -07004638 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TAIKO_RX1, 0,
4639 &slim_rx_mux[TAIKO_RX1]),
4640 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TAIKO_RX2, 0,
4641 &slim_rx_mux[TAIKO_RX2]),
4642 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TAIKO_RX3, 0,
4643 &slim_rx_mux[TAIKO_RX3]),
4644 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TAIKO_RX4, 0,
4645 &slim_rx_mux[TAIKO_RX4]),
4646 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TAIKO_RX5, 0,
4647 &slim_rx_mux[TAIKO_RX5]),
4648 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TAIKO_RX6, 0,
4649 &slim_rx_mux[TAIKO_RX6]),
4650 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TAIKO_RX7, 0,
4651 &slim_rx_mux[TAIKO_RX7]),
Kiran Kandic3b24402012-06-11 00:05:59 -07004652
Kuirong Wang906ac472012-07-09 12:54:44 -07004653 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4654 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4655 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
4656 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
4657 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
4658 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
4659 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
Kiran Kandic3b24402012-06-11 00:05:59 -07004660
4661 /* Headphone */
4662 SND_SOC_DAPM_OUTPUT("HEADPHONE"),
4663 SND_SOC_DAPM_PGA_E("HPHL", TAIKO_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
4664 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07004665 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004666 SND_SOC_DAPM_MIXER_E("HPHL DAC", TAIKO_A_RX_HPH_L_DAC_CTL, 7, 0,
4667 hphl_switch, ARRAY_SIZE(hphl_switch), taiko_hphl_dac_event,
4668 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004669
4670 SND_SOC_DAPM_PGA_E("HPHR", TAIKO_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
4671 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07004672 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004673
4674 SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TAIKO_A_RX_HPH_R_DAC_CTL, 7, 0,
4675 taiko_hphr_dac_event,
4676 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4677
4678 /* Speaker */
4679 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
4680 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
4681 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
4682 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004683 SND_SOC_DAPM_OUTPUT("SPK_OUT"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004684
4685 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TAIKO_A_RX_LINE_CNP_EN, 0, 0, NULL,
4686 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
4687 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4688 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TAIKO_A_RX_LINE_CNP_EN, 1, 0, NULL,
4689 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
4690 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4691 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TAIKO_A_RX_LINE_CNP_EN, 2, 0, NULL,
4692 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
4693 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4694 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TAIKO_A_RX_LINE_CNP_EN, 3, 0, NULL,
4695 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
4696 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park125cd4e2012-12-11 15:16:11 -08004697 SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0 , NULL,
4698 0, taiko_codec_enable_spk_pa,
4699 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004700
4701 SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAIKO_A_RX_LINE_1_DAC_CTL, 7, 0
4702 , taiko_lineout_dac_event,
4703 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4704 SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TAIKO_A_RX_LINE_2_DAC_CTL, 7, 0
4705 , taiko_lineout_dac_event,
4706 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4707 SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TAIKO_A_RX_LINE_3_DAC_CTL, 7, 0
4708 , taiko_lineout_dac_event,
4709 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4710 SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
4711 &lineout3_ground_switch),
4712 SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TAIKO_A_RX_LINE_4_DAC_CTL, 7, 0
4713 , taiko_lineout_dac_event,
4714 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4715 SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
4716 &lineout4_ground_switch),
4717
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004718 SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
4719 taiko_spk_dac_event,
4720 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4721
Joonwoo Park125cd4e2012-12-11 15:16:11 -08004722 SND_SOC_DAPM_SUPPLY("VDD_SPKDRV", SND_SOC_NOPM, 0, 0,
4723 taiko_codec_enable_vdd_spkr,
4724 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4725
Kiran Kandid2b46332012-10-05 12:04:00 -07004726 SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4727 SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4728 SND_SOC_DAPM_MIXER("RX7 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4729
Kiran Kandic3b24402012-06-11 00:05:59 -07004730 SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004731 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004732 SND_SOC_DAPM_POST_PMU),
4733 SND_SOC_DAPM_MIXER_E("RX2 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004734 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004735 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07004736 SND_SOC_DAPM_MIXER_E("RX3 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004737 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004738 SND_SOC_DAPM_POST_PMU),
4739 SND_SOC_DAPM_MIXER_E("RX4 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004740 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004741 SND_SOC_DAPM_POST_PMU),
4742 SND_SOC_DAPM_MIXER_E("RX5 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004743 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004744 SND_SOC_DAPM_POST_PMU),
4745 SND_SOC_DAPM_MIXER_E("RX6 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004746 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004747 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07004748 SND_SOC_DAPM_MIXER_E("RX7 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004749 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07004750 SND_SOC_DAPM_POST_PMU),
4751
Kiran Kandic3b24402012-06-11 00:05:59 -07004752
4753 SND_SOC_DAPM_MIXER("RX1 CHAIN", TAIKO_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
4754 SND_SOC_DAPM_MIXER("RX2 CHAIN", TAIKO_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
4755
4756 SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4757 &rx_mix1_inp1_mux),
4758 SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4759 &rx_mix1_inp2_mux),
4760 SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
4761 &rx_mix1_inp3_mux),
4762 SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4763 &rx2_mix1_inp1_mux),
4764 SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4765 &rx2_mix1_inp2_mux),
4766 SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4767 &rx3_mix1_inp1_mux),
4768 SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4769 &rx3_mix1_inp2_mux),
4770 SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4771 &rx4_mix1_inp1_mux),
4772 SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4773 &rx4_mix1_inp2_mux),
4774 SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4775 &rx5_mix1_inp1_mux),
4776 SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4777 &rx5_mix1_inp2_mux),
4778 SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4779 &rx6_mix1_inp1_mux),
4780 SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4781 &rx6_mix1_inp2_mux),
4782 SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4783 &rx7_mix1_inp1_mux),
4784 SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4785 &rx7_mix1_inp2_mux),
4786 SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
4787 &rx1_mix2_inp1_mux),
4788 SND_SOC_DAPM_MUX("RX1 MIX2 INP2", SND_SOC_NOPM, 0, 0,
4789 &rx1_mix2_inp2_mux),
4790 SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
4791 &rx2_mix2_inp1_mux),
4792 SND_SOC_DAPM_MUX("RX2 MIX2 INP2", SND_SOC_NOPM, 0, 0,
4793 &rx2_mix2_inp2_mux),
4794 SND_SOC_DAPM_MUX("RX7 MIX2 INP1", SND_SOC_NOPM, 0, 0,
4795 &rx7_mix2_inp1_mux),
4796 SND_SOC_DAPM_MUX("RX7 MIX2 INP2", SND_SOC_NOPM, 0, 0,
4797 &rx7_mix2_inp2_mux),
4798
Tanya Finkeldaaa6d12012-10-25 11:22:48 +02004799 SND_SOC_DAPM_MUX("RDAC5 MUX", SND_SOC_NOPM, 0, 0,
4800 &rx_dac5_mux),
4801 SND_SOC_DAPM_MUX("RDAC7 MUX", SND_SOC_NOPM, 0, 0,
4802 &rx_dac7_mux),
4803
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004804 SND_SOC_DAPM_MUX_E("CLASS_H_DSM MUX", SND_SOC_NOPM, 0, 0,
4805 &class_h_dsm_mux, taiko_codec_dsm_mux_event,
4806 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandi4c56c592012-07-25 11:04:55 -07004807
Kiran Kandic3b24402012-06-11 00:05:59 -07004808 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
4809 taiko_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
4810 SND_SOC_DAPM_POST_PMD),
4811
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004812 SND_SOC_DAPM_SUPPLY("CDC_I2S_RX_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 5, 0,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08004813 NULL, 0),
4814
Kiran Kandic3b24402012-06-11 00:05:59 -07004815 /* TX */
4816
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08004817 SND_SOC_DAPM_SUPPLY("CDC_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
Kiran Kandic3b24402012-06-11 00:05:59 -07004818 0),
4819
4820 SND_SOC_DAPM_SUPPLY("LDO_H", TAIKO_A_LDO_H_MODE_1, 7, 0,
4821 taiko_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
4822
Joonwoo Parkc7731432012-10-17 12:41:44 -07004823 SND_SOC_DAPM_SUPPLY("COMP0_CLK", SND_SOC_NOPM, 0, 0,
Kiran Kandic3b24402012-06-11 00:05:59 -07004824 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
4825 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
Joonwoo Parkc7731432012-10-17 12:41:44 -07004826 SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 1, 0,
4827 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
4828 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
4829 SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 2, 0,
Kiran Kandic3b24402012-06-11 00:05:59 -07004830 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
4831 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
4832
4833
4834 SND_SOC_DAPM_INPUT("AMIC1"),
Joonwoo Park3699ca32013-02-08 12:06:15 -08004835 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", SND_SOC_NOPM, 7, 0,
4836 taiko_codec_enable_micbias,
4837 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4838 SND_SOC_DAPM_POST_PMD),
4839 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", SND_SOC_NOPM, 7, 0,
4840 taiko_codec_enable_micbias,
4841 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4842 SND_SOC_DAPM_POST_PMD),
4843 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", SND_SOC_NOPM, 7, 0,
4844 taiko_codec_enable_micbias,
4845 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4846 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004847
4848 SND_SOC_DAPM_INPUT("AMIC3"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004849
4850 SND_SOC_DAPM_INPUT("AMIC4"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004851
4852 SND_SOC_DAPM_INPUT("AMIC5"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004853
4854 SND_SOC_DAPM_INPUT("AMIC6"),
Kiran Kandic3b24402012-06-11 00:05:59 -07004855
4856 SND_SOC_DAPM_MUX_E("DEC1 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
4857 &dec1_mux, taiko_codec_enable_dec,
4858 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4859 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4860
4861 SND_SOC_DAPM_MUX_E("DEC2 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
4862 &dec2_mux, taiko_codec_enable_dec,
4863 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4864 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4865
4866 SND_SOC_DAPM_MUX_E("DEC3 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
4867 &dec3_mux, taiko_codec_enable_dec,
4868 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4869 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4870
4871 SND_SOC_DAPM_MUX_E("DEC4 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
4872 &dec4_mux, taiko_codec_enable_dec,
4873 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4874 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4875
4876 SND_SOC_DAPM_MUX_E("DEC5 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
4877 &dec5_mux, taiko_codec_enable_dec,
4878 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4879 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4880
4881 SND_SOC_DAPM_MUX_E("DEC6 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
4882 &dec6_mux, taiko_codec_enable_dec,
4883 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4884 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4885
4886 SND_SOC_DAPM_MUX_E("DEC7 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
4887 &dec7_mux, taiko_codec_enable_dec,
4888 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4889 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4890
4891 SND_SOC_DAPM_MUX_E("DEC8 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
4892 &dec8_mux, taiko_codec_enable_dec,
4893 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4894 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4895
4896 SND_SOC_DAPM_MUX_E("DEC9 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
4897 &dec9_mux, taiko_codec_enable_dec,
4898 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4899 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4900
4901 SND_SOC_DAPM_MUX_E("DEC10 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
4902 &dec10_mux, taiko_codec_enable_dec,
4903 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4904 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4905
4906 SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
4907 SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
4908
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08004909 SND_SOC_DAPM_OUTPUT("ANC HEADPHONE"),
4910 SND_SOC_DAPM_PGA_E("ANC HPHL", SND_SOC_NOPM, 5, 0, NULL, 0,
4911 taiko_codec_enable_anc_hph,
4912 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
4913 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
4914 SND_SOC_DAPM_PGA_E("ANC HPHR", SND_SOC_NOPM, 4, 0, NULL, 0,
4915 taiko_codec_enable_anc_hph, SND_SOC_DAPM_PRE_PMU |
4916 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
4917 SND_SOC_DAPM_POST_PMU),
4918 SND_SOC_DAPM_OUTPUT("ANC EAR"),
4919 SND_SOC_DAPM_PGA_E("ANC EAR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
4920 taiko_codec_enable_anc_ear,
4921 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
4922 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004923 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
4924
4925 SND_SOC_DAPM_INPUT("AMIC2"),
Joonwoo Park3699ca32013-02-08 12:06:15 -08004926 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 7, 0,
4927 taiko_codec_enable_micbias,
4928 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4929 SND_SOC_DAPM_POST_PMD),
4930 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 7, 0,
4931 taiko_codec_enable_micbias,
4932 SND_SOC_DAPM_PRE_PMU |
4933 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4934 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 7, 0,
4935 taiko_codec_enable_micbias,
4936 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4937 SND_SOC_DAPM_POST_PMD),
4938 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 7, 0,
4939 taiko_codec_enable_micbias,
4940 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4941 SND_SOC_DAPM_POST_PMD),
4942 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 7, 0,
4943 taiko_codec_enable_micbias,
4944 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4945 SND_SOC_DAPM_POST_PMD),
4946 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 7, 0,
4947 taiko_codec_enable_micbias,
4948 SND_SOC_DAPM_PRE_PMU |
4949 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4950 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 7, 0,
4951 taiko_codec_enable_micbias,
4952 SND_SOC_DAPM_PRE_PMU |
4953 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4954 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", SND_SOC_NOPM, 7,
4955 0, taiko_codec_enable_micbias,
4956 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4957 SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004958
Kuirong Wang906ac472012-07-09 12:54:44 -07004959 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
4960 AIF1_CAP, 0, taiko_codec_enable_slimtx,
4961 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004962
Kuirong Wang906ac472012-07-09 12:54:44 -07004963 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
4964 AIF2_CAP, 0, taiko_codec_enable_slimtx,
4965 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004966
Kuirong Wang906ac472012-07-09 12:54:44 -07004967 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
4968 AIF3_CAP, 0, taiko_codec_enable_slimtx,
4969 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004970
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004971 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
4972 AIF4_VIFEED, 0, taiko_codec_enable_slimvi_feedback,
4973 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004974 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
Joonwoo Park9ead0e92013-03-18 11:33:33 -07004975 SND_SOC_NOPM, 0, 0,
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004976 taiko_codec_enable_mad, SND_SOC_DAPM_PRE_PMU),
Joonwoo Park9ead0e92013-03-18 11:33:33 -07004977 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
4978 &aif4_mad_switch),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08004979 SND_SOC_DAPM_INPUT("MADINPUT"),
Gopikrishnaiah Anandana2627572013-02-26 13:30:50 -05004980
Kuirong Wang906ac472012-07-09 12:54:44 -07004981 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
4982 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004983
Kuirong Wang906ac472012-07-09 12:54:44 -07004984 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
4985 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004986
Kuirong Wang906ac472012-07-09 12:54:44 -07004987 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
4988 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004989
Kuirong Wang906ac472012-07-09 12:54:44 -07004990 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TAIKO_TX1, 0,
4991 &sb_tx1_mux),
4992 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TAIKO_TX2, 0,
4993 &sb_tx2_mux),
4994 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TAIKO_TX3, 0,
4995 &sb_tx3_mux),
4996 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TAIKO_TX4, 0,
4997 &sb_tx4_mux),
4998 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TAIKO_TX5, 0,
4999 &sb_tx5_mux),
5000 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TAIKO_TX6, 0,
5001 &sb_tx6_mux),
5002 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TAIKO_TX7, 0,
5003 &sb_tx7_mux),
5004 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TAIKO_TX8, 0,
5005 &sb_tx8_mux),
5006 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TAIKO_TX9, 0,
5007 &sb_tx9_mux),
5008 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TAIKO_TX10, 0,
5009 &sb_tx10_mux),
Kiran Kandic3b24402012-06-11 00:05:59 -07005010
5011 /* Digital Mic Inputs */
5012 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
5013 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5014 SND_SOC_DAPM_POST_PMD),
5015
5016 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
5017 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5018 SND_SOC_DAPM_POST_PMD),
5019
5020 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
5021 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5022 SND_SOC_DAPM_POST_PMD),
5023
5024 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
5025 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5026 SND_SOC_DAPM_POST_PMD),
5027
5028 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
5029 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5030 SND_SOC_DAPM_POST_PMD),
5031 SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
5032 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
5033 SND_SOC_DAPM_POST_PMD),
5034
5035 /* Sidetone */
5036 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
5037 SND_SOC_DAPM_PGA("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
5038
5039 /* AUX PGA */
5040 SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TAIKO_A_RX_AUX_SW_CTL, 7, 0,
5041 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
5042 SND_SOC_DAPM_POST_PMD),
5043
5044 SND_SOC_DAPM_ADC_E("AUX_PGA_Right", NULL, TAIKO_A_RX_AUX_SW_CTL, 6, 0,
5045 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
5046 SND_SOC_DAPM_POST_PMD),
5047
5048 /* Lineout, ear and HPH PA Mixers */
5049
5050 SND_SOC_DAPM_MIXER("EAR_PA_MIXER", SND_SOC_NOPM, 0, 0,
5051 ear_pa_mix, ARRAY_SIZE(ear_pa_mix)),
5052
5053 SND_SOC_DAPM_MIXER("HPHL_PA_MIXER", SND_SOC_NOPM, 0, 0,
5054 hphl_pa_mix, ARRAY_SIZE(hphl_pa_mix)),
5055
5056 SND_SOC_DAPM_MIXER("HPHR_PA_MIXER", SND_SOC_NOPM, 0, 0,
5057 hphr_pa_mix, ARRAY_SIZE(hphr_pa_mix)),
5058
5059 SND_SOC_DAPM_MIXER("LINEOUT1_PA_MIXER", SND_SOC_NOPM, 0, 0,
5060 lineout1_pa_mix, ARRAY_SIZE(lineout1_pa_mix)),
5061
5062 SND_SOC_DAPM_MIXER("LINEOUT2_PA_MIXER", SND_SOC_NOPM, 0, 0,
5063 lineout2_pa_mix, ARRAY_SIZE(lineout2_pa_mix)),
5064
5065 SND_SOC_DAPM_MIXER("LINEOUT3_PA_MIXER", SND_SOC_NOPM, 0, 0,
5066 lineout3_pa_mix, ARRAY_SIZE(lineout3_pa_mix)),
5067
5068 SND_SOC_DAPM_MIXER("LINEOUT4_PA_MIXER", SND_SOC_NOPM, 0, 0,
5069 lineout4_pa_mix, ARRAY_SIZE(lineout4_pa_mix)),
Kiran Kandic3b24402012-06-11 00:05:59 -07005070};
5071
Kiran Kandic3b24402012-06-11 00:05:59 -07005072static irqreturn_t taiko_slimbus_irq(int irq, void *data)
5073{
5074 struct taiko_priv *priv = data;
5075 struct snd_soc_codec *codec = priv->codec;
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005076 unsigned long status = 0;
5077 int i, j, port_id, k;
5078 u32 bit;
Kiran Kandic3b24402012-06-11 00:05:59 -07005079 u8 val;
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005080 bool tx, cleared;
Kiran Kandic3b24402012-06-11 00:05:59 -07005081
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005082 for (i = TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
5083 i <= TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
5084 val = wcd9xxx_interface_reg_read(codec->control_data, i);
5085 status |= ((u32)val << (8 * j));
5086 }
5087
5088 for_each_set_bit(j, &status, 32) {
5089 tx = (j >= 16 ? true : false);
5090 port_id = (tx ? j - 16 : j);
5091 val = wcd9xxx_interface_reg_read(codec->control_data,
5092 TAIKO_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
5093 if (val & TAIKO_SLIM_IRQ_OVERFLOW)
5094 pr_err_ratelimited(
5095 "%s: overflow error on %s port %d, value %x\n",
5096 __func__, (tx ? "TX" : "RX"), port_id, val);
5097 if (val & TAIKO_SLIM_IRQ_UNDERFLOW)
5098 pr_err_ratelimited(
5099 "%s: underflow error on %s port %d, value %x\n",
5100 __func__, (tx ? "TX" : "RX"), port_id, val);
5101 if (val & TAIKO_SLIM_IRQ_PORT_CLOSED) {
5102 /*
5103 * INT SOURCE register starts from RX to TX
5104 * but port number in the ch_mask is in opposite way
5105 */
5106 bit = (tx ? j - 16 : j + 16);
5107 pr_debug("%s: %s port %d closed value %x, bit %u\n",
5108 __func__, (tx ? "TX" : "RX"), port_id, val,
5109 bit);
5110 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
5111 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
5112 __func__, k, priv->dai[k].ch_mask);
5113 if (test_and_clear_bit(bit,
5114 &priv->dai[k].ch_mask)) {
5115 cleared = true;
5116 if (!priv->dai[k].ch_mask)
5117 wake_up(&priv->dai[k].dai_wait);
5118 /*
5119 * There are cases when multiple DAIs
5120 * might be using the same slimbus
5121 * channel. Hence don't break here.
5122 */
5123 }
5124 }
5125 WARN(!cleared,
5126 "Couldn't find slimbus %s port %d for closing\n",
5127 (tx ? "TX" : "RX"), port_id);
Kiran Kandic3b24402012-06-11 00:05:59 -07005128 }
5129 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005130 TAIKO_SLIM_PGD_PORT_INT_CLR_RX_0 +
5131 (j / 8),
5132 1 << (j % 8));
Joonwoo Parka8890262012-10-15 12:04:27 -07005133 }
Joonwoo Park9bbb4d12012-11-09 19:58:11 -08005134
Kiran Kandic3b24402012-06-11 00:05:59 -07005135 return IRQ_HANDLED;
5136}
5137
5138static int taiko_handle_pdata(struct taiko_priv *taiko)
5139{
5140 struct snd_soc_codec *codec = taiko->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07005141 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
Kiran Kandic3b24402012-06-11 00:05:59 -07005142 int k1, k2, k3, rc = 0;
Kiran Kandi725f8492012-08-06 13:45:16 -07005143 u8 leg_mode, txfe_bypass, txfe_buff, flag;
Kiran Kandic3b24402012-06-11 00:05:59 -07005144 u8 i = 0, j = 0;
5145 u8 val_txfe = 0, value = 0;
5146
5147 if (!pdata) {
Kiran Kandi725f8492012-08-06 13:45:16 -07005148 pr_err("%s: NULL pdata\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07005149 rc = -ENODEV;
5150 goto done;
5151 }
5152
Kiran Kandi725f8492012-08-06 13:45:16 -07005153 leg_mode = pdata->amic_settings.legacy_mode;
5154 txfe_bypass = pdata->amic_settings.txfe_enable;
5155 txfe_buff = pdata->amic_settings.txfe_buff;
5156 flag = pdata->amic_settings.use_pdata;
5157
Kiran Kandic3b24402012-06-11 00:05:59 -07005158 /* Make sure settings are correct */
Joonwoo Parka8890262012-10-15 12:04:27 -07005159 if ((pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V) ||
5160 (pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
5161 (pdata->micbias.bias2_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
5162 (pdata->micbias.bias3_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
5163 (pdata->micbias.bias4_cfilt_sel > WCD9XXX_CFILT3_SEL)) {
Kiran Kandic3b24402012-06-11 00:05:59 -07005164 rc = -EINVAL;
5165 goto done;
5166 }
Kiran Kandic3b24402012-06-11 00:05:59 -07005167 /* figure out k value */
Joonwoo Parka8890262012-10-15 12:04:27 -07005168 k1 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt1_mv);
5169 k2 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt2_mv);
5170 k3 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt3_mv);
Kiran Kandic3b24402012-06-11 00:05:59 -07005171
5172 if (IS_ERR_VALUE(k1) || IS_ERR_VALUE(k2) || IS_ERR_VALUE(k3)) {
5173 rc = -EINVAL;
5174 goto done;
5175 }
Kiran Kandic3b24402012-06-11 00:05:59 -07005176 /* Set voltage level and always use LDO */
5177 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 0x0C,
Joonwoo Parka8890262012-10-15 12:04:27 -07005178 (pdata->micbias.ldoh_v << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07005179
Joonwoo Parka8890262012-10-15 12:04:27 -07005180 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_1_VAL, 0xFC, (k1 << 2));
5181 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_2_VAL, 0xFC, (k2 << 2));
5182 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_3_VAL, 0xFC, (k3 << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07005183
5184 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07005185 (pdata->micbias.bias1_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07005186 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07005187 (pdata->micbias.bias2_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07005188 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07005189 (pdata->micbias.bias3_cfilt_sel << 5));
5190 snd_soc_update_bits(codec, taiko->resmgr.reg_addr->micb_4_ctl, 0x60,
Kiran Kandic3b24402012-06-11 00:05:59 -07005191 (pdata->micbias.bias4_cfilt_sel << 5));
5192
5193 for (i = 0; i < 6; j++, i += 2) {
5194 if (flag & (0x01 << i)) {
5195 value = (leg_mode & (0x01 << i)) ? 0x10 : 0x00;
5196 val_txfe = (txfe_bypass & (0x01 << i)) ? 0x20 : 0x00;
5197 val_txfe = val_txfe |
5198 ((txfe_buff & (0x01 << i)) ? 0x10 : 0x00);
5199 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
5200 0x10, value);
5201 snd_soc_update_bits(codec,
5202 TAIKO_A_TX_1_2_TEST_EN + j * 10,
5203 0x30, val_txfe);
5204 }
5205 if (flag & (0x01 << (i + 1))) {
5206 value = (leg_mode & (0x01 << (i + 1))) ? 0x01 : 0x00;
5207 val_txfe = (txfe_bypass &
5208 (0x01 << (i + 1))) ? 0x02 : 0x00;
5209 val_txfe |= (txfe_buff &
5210 (0x01 << (i + 1))) ? 0x01 : 0x00;
5211 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
5212 0x01, value);
5213 snd_soc_update_bits(codec,
5214 TAIKO_A_TX_1_2_TEST_EN + j * 10,
5215 0x03, val_txfe);
5216 }
5217 }
5218 if (flag & 0x40) {
5219 value = (leg_mode & 0x40) ? 0x10 : 0x00;
5220 value = value | ((txfe_bypass & 0x40) ? 0x02 : 0x00);
5221 value = value | ((txfe_buff & 0x40) ? 0x01 : 0x00);
5222 snd_soc_update_bits(codec, TAIKO_A_TX_7_MBHC_EN,
5223 0x13, value);
5224 }
5225
5226 if (pdata->ocp.use_pdata) {
5227 /* not defined in CODEC specification */
5228 if (pdata->ocp.hph_ocp_limit == 1 ||
5229 pdata->ocp.hph_ocp_limit == 5) {
5230 rc = -EINVAL;
5231 goto done;
5232 }
5233 snd_soc_update_bits(codec, TAIKO_A_RX_COM_OCP_CTL,
5234 0x0F, pdata->ocp.num_attempts);
5235 snd_soc_write(codec, TAIKO_A_RX_COM_OCP_COUNT,
5236 ((pdata->ocp.run_time << 4) | pdata->ocp.wait_time));
5237 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_OCP_CTL,
5238 0xE0, (pdata->ocp.hph_ocp_limit << 5));
5239 }
5240
5241 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
5242 if (!strncmp(pdata->regulator[i].name, "CDC_VDDA_RX", 11)) {
5243 if (pdata->regulator[i].min_uV == 1800000 &&
5244 pdata->regulator[i].max_uV == 1800000) {
5245 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
5246 0x1C);
5247 } else if (pdata->regulator[i].min_uV == 2200000 &&
5248 pdata->regulator[i].max_uV == 2200000) {
5249 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
5250 0x1E);
5251 } else {
5252 pr_err("%s: unsupported CDC_VDDA_RX voltage\n"
5253 "min %d, max %d\n", __func__,
5254 pdata->regulator[i].min_uV,
5255 pdata->regulator[i].max_uV);
5256 rc = -EINVAL;
5257 }
5258 break;
5259 }
5260 }
Kiran Kandi4c56c592012-07-25 11:04:55 -07005261
Joonwoo Park1848c762012-10-18 13:16:01 -07005262 /* Set micbias capless mode with tail current */
5263 value = (pdata->micbias.bias1_cap_mode == MICBIAS_EXT_BYP_CAP ?
5264 0x00 : 0x16);
5265 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x1E, value);
5266 value = (pdata->micbias.bias2_cap_mode == MICBIAS_EXT_BYP_CAP ?
5267 0x00 : 0x16);
5268 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x1E, value);
5269 value = (pdata->micbias.bias3_cap_mode == MICBIAS_EXT_BYP_CAP ?
5270 0x00 : 0x16);
5271 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x1E, value);
5272 value = (pdata->micbias.bias4_cap_mode == MICBIAS_EXT_BYP_CAP ?
5273 0x00 : 0x16);
5274 snd_soc_update_bits(codec, TAIKO_A_MICB_4_CTL, 0x1E, value);
5275
Kiran Kandic3b24402012-06-11 00:05:59 -07005276done:
5277 return rc;
5278}
5279
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005280static const struct wcd9xxx_reg_mask_val taiko_reg_defaults[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07005281
Kiran Kandi4c56c592012-07-25 11:04:55 -07005282 /* set MCLk to 9.6 */
Gopikrishnaiah Anandana8aec1f2013-01-23 14:26:27 -05005283 TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x02),
Kiran Kandi4c56c592012-07-25 11:04:55 -07005284 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_POWER_CTL, 0x03),
Kiran Kandic3b24402012-06-11 00:05:59 -07005285
Kiran Kandi4c56c592012-07-25 11:04:55 -07005286 /* EAR PA deafults */
5287 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CMBUFF, 0x05),
Kiran Kandic3b24402012-06-11 00:05:59 -07005288
Kiran Kandi4c56c592012-07-25 11:04:55 -07005289 /* RX deafults */
Kiran Kandic3b24402012-06-11 00:05:59 -07005290 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B5_CTL, 0x78),
5291 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B5_CTL, 0x78),
5292 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B5_CTL, 0x78),
5293 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B5_CTL, 0x78),
5294 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B5_CTL, 0x78),
5295 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B5_CTL, 0x78),
5296 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B5_CTL, 0x78),
5297
Kiran Kandi4c56c592012-07-25 11:04:55 -07005298 /* RX1 and RX2 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07005299 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B6_CTL, 0xA0),
5300 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B6_CTL, 0xA0),
5301
Kiran Kandi4c56c592012-07-25 11:04:55 -07005302 /* RX3 to RX7 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07005303 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B6_CTL, 0x80),
5304 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B6_CTL, 0x80),
5305 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B6_CTL, 0x80),
5306 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B6_CTL, 0x80),
5307 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005308
5309 /* MAD registers */
5310 TAIKO_REG_VAL(TAIKO_A_MAD_ANA_CTRL, 0xF1),
5311 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_MAIN_CTL_1, 0x00),
5312 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_MAIN_CTL_2, 0x00),
5313 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_1, 0x00),
5314 /* Set SAMPLE_TX_EN bit */
5315 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_2, 0x03),
5316 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_3, 0x00),
5317 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_4, 0x00),
5318 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_5, 0x00),
5319 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_6, 0x00),
5320 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_7, 0x00),
5321 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_CTL_8, 0x00),
5322 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_PTR, 0x00),
5323 TAIKO_REG_VAL(TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_VAL, 0x40),
5324 TAIKO_REG_VAL(TAIKO_A_CDC_DEBUG_B7_CTL, 0x00),
5325 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL, 0x00),
5326 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_CTL, 0x00),
5327 TAIKO_REG_VAL(TAIKO_A_CDC_CONN_MAD, 0x01),
Kiran Kandic3b24402012-06-11 00:05:59 -07005328};
5329
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005330static const struct wcd9xxx_reg_mask_val taiko_1_0_reg_defaults[] = {
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005331 /*
5332 * The following only need to be written for Taiko 1.0 parts.
5333 * Taiko 2.0 will have appropriate defaults for these registers.
5334 */
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005335
5336 /* BUCK default */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005337 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x50),
5338
5339 /* Required defaults for class H operation */
5340 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xF4),
5341 TAIKO_REG_VAL(TAIKO_A_BIAS_CURR_CTL_2, 0x08),
5342 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
5343 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_3, 0x60),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005344
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005345 /* Choose max non-overlap time for NCP */
5346 TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
5347 /* Use 25mV/50mV for deltap/m to reduce ripple */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005348 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x08),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005349 /*
5350 * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
5351 * Note that the other bits of this register will be changed during
5352 * Rx PA bring up.
5353 */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005354 TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005355 /* Reduce HPH DAC bias to 70% */
5356 TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
5357 /*Reduce EAR DAC bias to 70% */
5358 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
5359 /* Reduce LINE DAC bias to 70% */
5360 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
Joonwoo Parkd87ec4c2012-10-30 15:44:18 -07005361
5362 /*
5363 * There is a diode to pull down the micbias while doing
5364 * insertion detection. This diode can cause leakage.
5365 * Set bit 0 to 1 to prevent leakage.
5366 * Setting this bit of micbias 2 prevents leakage for all other micbias.
5367 */
5368 TAIKO_REG_VAL(TAIKO_A_MICB_2_MBHC, 0x41),
Joonwoo Park3c7bca62012-10-31 12:44:23 -07005369
5370 /* Disable TX7 internal biasing path which can cause leakage */
5371 TAIKO_REG_VAL(TAIKO_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
Joonwoo Park03604052012-11-06 18:40:25 -08005372 /* Enable MICB 4 VDDIO switch to prevent leakage */
5373 TAIKO_REG_VAL(TAIKO_A_MICB_4_MBHC, 0x81),
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005374
5375 /* Close leakage on the spkdrv */
5376 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_DBG_PWRSTG, 0x24),
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005377};
5378
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005379/*
5380 * Don't update TAIKO_A_CHIP_CTL, TAIKO_A_BUCK_CTRL_CCL_1 and
5381 * TAIKO_A_RX_EAR_CMBUFF as those are updated in taiko_reg_defaults
5382 */
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005383static const struct wcd9xxx_reg_mask_val taiko_2_0_reg_defaults[] = {
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005384 TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_GAIN, 0x2),
5385 TAIKO_REG_VAL(TAIKO_A_CDC_TX_2_GAIN, 0x2),
5386 TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_2_ADC_IB, 0x44),
5387 TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_GAIN, 0x2),
5388 TAIKO_REG_VAL(TAIKO_A_CDC_TX_4_GAIN, 0x2),
5389 TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_4_ADC_IB, 0x44),
5390 TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_GAIN, 0x2),
5391 TAIKO_REG_VAL(TAIKO_A_CDC_TX_6_GAIN, 0x2),
5392 TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_6_ADC_IB, 0x44),
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005393 TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
5394 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x8),
5395 TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x51),
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005396 TAIKO_REG_VAL(TAIKO_A_NCP_DTEST, 0x10),
5397 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xA4),
5398 TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
5399 TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x69),
5400 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_CTL, 0xDA),
5401 TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_TIME, 0x15),
5402 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
5403 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CNP, 0xC0),
5404 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
5405 TAIKO_REG_VAL(TAIKO_A_RX_LINE_1_TEST, 0x2),
5406 TAIKO_REG_VAL(TAIKO_A_RX_LINE_2_TEST, 0x2),
5407 TAIKO_REG_VAL(TAIKO_A_RX_LINE_3_TEST, 0x2),
5408 TAIKO_REG_VAL(TAIKO_A_RX_LINE_4_TEST, 0x2),
5409 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_OCP_CTL, 0x97),
5410 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_CLIP_DET, 0x1),
5411 TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_IEC, 0x0),
5412 TAIKO_REG_VAL(TAIKO_A_CDC_TX1_MUX_CTL, 0x48),
5413 TAIKO_REG_VAL(TAIKO_A_CDC_TX2_MUX_CTL, 0x48),
5414 TAIKO_REG_VAL(TAIKO_A_CDC_TX3_MUX_CTL, 0x48),
5415 TAIKO_REG_VAL(TAIKO_A_CDC_TX4_MUX_CTL, 0x48),
5416 TAIKO_REG_VAL(TAIKO_A_CDC_TX5_MUX_CTL, 0x48),
5417 TAIKO_REG_VAL(TAIKO_A_CDC_TX6_MUX_CTL, 0x48),
5418 TAIKO_REG_VAL(TAIKO_A_CDC_TX7_MUX_CTL, 0x48),
5419 TAIKO_REG_VAL(TAIKO_A_CDC_TX8_MUX_CTL, 0x48),
5420 TAIKO_REG_VAL(TAIKO_A_CDC_TX9_MUX_CTL, 0x48),
5421 TAIKO_REG_VAL(TAIKO_A_CDC_TX10_MUX_CTL, 0x48),
5422 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B4_CTL, 0x8),
5423 TAIKO_REG_VAL(TAIKO_A_CDC_VBAT_GAIN_UPD_MON, 0x0),
5424 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B1_CTL, 0x0),
5425 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B2_CTL, 0x0),
5426 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B3_CTL, 0x0),
5427 TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B4_CTL, 0x0),
5428 TAIKO_REG_VAL(TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL, 0x0),
5429 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B4_CTL, 0x37),
5430 TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
5431};
5432
Kiran Kandic3b24402012-06-11 00:05:59 -07005433static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
5434{
5435 u32 i;
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005436 struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07005437
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005438 for (i = 0; i < ARRAY_SIZE(taiko_reg_defaults); i++)
5439 snd_soc_write(codec, taiko_reg_defaults[i].reg,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005440 taiko_reg_defaults[i].val);
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005441
5442 if (TAIKO_IS_1_0(taiko_core->version)) {
5443 for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
5444 snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005445 taiko_1_0_reg_defaults[i].val);
5446 if (spkr_drv_wrnd == 1)
5447 snd_soc_write(codec, TAIKO_A_SPKR_DRV_EN, 0xEF);
5448 } else {
5449 for (i = 0; i < ARRAY_SIZE(taiko_2_0_reg_defaults); i++)
5450 snd_soc_write(codec, taiko_2_0_reg_defaults[i].reg,
5451 taiko_2_0_reg_defaults[i].val);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005452 spkr_drv_wrnd = -1;
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005453 }
Kiran Kandic3b24402012-06-11 00:05:59 -07005454}
5455
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005456static const struct wcd9xxx_reg_mask_val taiko_codec_reg_init_val[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07005457 /* Initialize current threshold to 350MA
5458 * number of wait and run cycles to 4096
5459 */
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005460 {TAIKO_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
Kiran Kandic3b24402012-06-11 00:05:59 -07005461 {TAIKO_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
Patrick Lai92833bf2012-12-01 10:31:35 -08005462 {TAIKO_A_RX_HPH_L_TEST, 0x01, 0x01},
5463 {TAIKO_A_RX_HPH_R_TEST, 0x01, 0x01},
Kiran Kandic3b24402012-06-11 00:05:59 -07005464
Kiran Kandic3b24402012-06-11 00:05:59 -07005465 /* Initialize gain registers to use register gain */
Kiran Kandi4c56c592012-07-25 11:04:55 -07005466 {TAIKO_A_RX_HPH_L_GAIN, 0x20, 0x20},
5467 {TAIKO_A_RX_HPH_R_GAIN, 0x20, 0x20},
5468 {TAIKO_A_RX_LINE_1_GAIN, 0x20, 0x20},
5469 {TAIKO_A_RX_LINE_2_GAIN, 0x20, 0x20},
5470 {TAIKO_A_RX_LINE_3_GAIN, 0x20, 0x20},
5471 {TAIKO_A_RX_LINE_4_GAIN, 0x20, 0x20},
Joonwoo Parkc7731432012-10-17 12:41:44 -07005472 {TAIKO_A_SPKR_DRV_GAIN, 0x04, 0x04},
Kiran Kandic3b24402012-06-11 00:05:59 -07005473
Kiran Kandic3b24402012-06-11 00:05:59 -07005474 /* Use 16 bit sample size for TX1 to TX6 */
5475 {TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0x30, 0x20},
5476 {TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0x30, 0x20},
5477 {TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0x30, 0x20},
5478 {TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0x30, 0x20},
5479 {TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0x30, 0x20},
5480 {TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0x30, 0x20},
5481
5482 /* Use 16 bit sample size for TX7 to TX10 */
5483 {TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0x60, 0x40},
5484 {TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0x60, 0x40},
5485 {TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x60, 0x40},
5486 {TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x60, 0x40},
5487
Kiran Kandic3b24402012-06-11 00:05:59 -07005488 /*enable HPF filter for TX paths */
5489 {TAIKO_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
5490 {TAIKO_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
5491 {TAIKO_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
5492 {TAIKO_A_CDC_TX4_MUX_CTL, 0x8, 0x0},
5493 {TAIKO_A_CDC_TX5_MUX_CTL, 0x8, 0x0},
5494 {TAIKO_A_CDC_TX6_MUX_CTL, 0x8, 0x0},
5495 {TAIKO_A_CDC_TX7_MUX_CTL, 0x8, 0x0},
5496 {TAIKO_A_CDC_TX8_MUX_CTL, 0x8, 0x0},
5497 {TAIKO_A_CDC_TX9_MUX_CTL, 0x8, 0x0},
5498 {TAIKO_A_CDC_TX10_MUX_CTL, 0x8, 0x0},
5499
Kiran Kandi4c56c592012-07-25 11:04:55 -07005500 /* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
5501 {TAIKO_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
5502 {TAIKO_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
5503 {TAIKO_A_CDC_TX3_DMIC_CTL, 0x7, 0x1},
5504 {TAIKO_A_CDC_TX4_DMIC_CTL, 0x7, 0x1},
5505 {TAIKO_A_CDC_TX5_DMIC_CTL, 0x7, 0x1},
5506 {TAIKO_A_CDC_TX6_DMIC_CTL, 0x7, 0x1},
5507 {TAIKO_A_CDC_TX7_DMIC_CTL, 0x7, 0x1},
5508 {TAIKO_A_CDC_TX8_DMIC_CTL, 0x7, 0x1},
5509 {TAIKO_A_CDC_TX9_DMIC_CTL, 0x7, 0x1},
5510 {TAIKO_A_CDC_TX10_DMIC_CTL, 0x7, 0x1},
Kiran Kandic3b24402012-06-11 00:05:59 -07005511
Kiran Kandi4c56c592012-07-25 11:04:55 -07005512 /* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
5513 {TAIKO_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
5514 {TAIKO_A_CDC_CLK_DMIC_B2_CTL, 0x0E, 0x02},
5515
Joonwoo Parkc7731432012-10-17 12:41:44 -07005516 /* Compander zone selection */
5517 {TAIKO_A_CDC_COMP0_B4_CTL, 0x3F, 0x37},
5518 {TAIKO_A_CDC_COMP1_B4_CTL, 0x3F, 0x37},
5519 {TAIKO_A_CDC_COMP2_B4_CTL, 0x3F, 0x37},
5520 {TAIKO_A_CDC_COMP0_B5_CTL, 0x7F, 0x7F},
5521 {TAIKO_A_CDC_COMP1_B5_CTL, 0x7F, 0x7F},
5522 {TAIKO_A_CDC_COMP2_B5_CTL, 0x7F, 0x7F},
Kiran Kandic3b24402012-06-11 00:05:59 -07005523};
5524
5525static void taiko_codec_init_reg(struct snd_soc_codec *codec)
5526{
5527 u32 i;
5528
5529 for (i = 0; i < ARRAY_SIZE(taiko_codec_reg_init_val); i++)
5530 snd_soc_update_bits(codec, taiko_codec_reg_init_val[i].reg,
5531 taiko_codec_reg_init_val[i].mask,
5532 taiko_codec_reg_init_val[i].val);
5533}
5534
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005535static int taiko_setup_irqs(struct taiko_priv *taiko)
5536{
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005537 int i;
Joonwoo Parka8890262012-10-15 12:04:27 -07005538 int ret = 0;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005539 struct snd_soc_codec *codec = taiko->codec;
5540
Joonwoo Parkf6574c72012-10-10 17:29:57 -07005541 ret = wcd9xxx_request_irq(codec->control_data, WCD9XXX_IRQ_SLIMBUS,
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005542 taiko_slimbus_irq, "SLIMBUS Slave", taiko);
5543 if (ret) {
5544 pr_err("%s: Failed to request irq %d\n", __func__,
Joonwoo Parkf6574c72012-10-10 17:29:57 -07005545 WCD9XXX_IRQ_SLIMBUS);
Joonwoo Parka8890262012-10-15 12:04:27 -07005546 goto exit;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005547 }
5548
5549 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
5550 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Parka8890262012-10-15 12:04:27 -07005551 TAIKO_SLIM_PGD_PORT_INT_EN0 + i,
5552 0xFF);
5553exit:
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005554 return ret;
5555}
5556
Joonwoo Parka8890262012-10-15 12:04:27 -07005557int taiko_hs_detect(struct snd_soc_codec *codec,
5558 struct wcd9xxx_mbhc_config *mbhc_cfg)
5559{
5560 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
5561 return wcd9xxx_mbhc_start(&taiko->mbhc, mbhc_cfg);
5562}
5563EXPORT_SYMBOL_GPL(taiko_hs_detect);
5564
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005565static void taiko_init_slim_slave_cfg(struct snd_soc_codec *codec)
5566{
5567 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
5568 struct afe_param_cdc_slimbus_slave_cfg *cfg;
5569 struct wcd9xxx *wcd9xxx = codec->control_data;
5570 uint64_t eaddr = 0;
5571
5572 cfg = &priv->slimbus_slave_cfg;
5573 cfg->minor_version = 1;
5574 cfg->tx_slave_port_offset = 0;
5575 cfg->rx_slave_port_offset = 16;
5576
5577 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
5578 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
5579 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
5580 cfg->device_enum_addr_msw = eaddr >> 32;
5581
5582 pr_debug("%s: slimbus logical address 0x%llx\n", __func__, eaddr);
5583}
5584
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005585static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
5586{
5587 int ret = 0;
5588 struct snd_soc_codec *codec;
5589 struct taiko_priv *taiko;
5590
5591 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
5592 taiko = snd_soc_codec_get_drvdata(codec);
5593 mutex_lock(&codec->mutex);
5594 WCD9XXX_BCL_LOCK(&taiko->resmgr);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005595
5596 if (codec->reg_def_copy) {
5597 pr_debug("%s: Update ASOC cache", __func__);
5598 kfree(codec->reg_cache);
5599 codec->reg_cache = kmemdup(codec->reg_def_copy,
5600 codec->reg_size, GFP_KERNEL);
5601 }
5602
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08005603 wcd9xxx_resmgr_post_ssr(&taiko->resmgr);
5604 if (spkr_drv_wrnd == 1)
5605 snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
5606 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
5607
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005608 taiko_update_reg_defaults(codec);
5609 taiko_codec_init_reg(codec);
5610 ret = taiko_handle_pdata(taiko);
5611 if (IS_ERR_VALUE(ret))
5612 pr_err("%s: bad pdata\n", __func__);
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08005613
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005614 taiko_init_slim_slave_cfg(codec);
5615
Ravishankar Sarawadi2293efe2013-01-11 16:37:23 -08005616 wcd9xxx_mbhc_deinit(&taiko->mbhc);
5617 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
5618 if (ret)
5619 pr_err("%s: mbhc init failed %d\n", __func__, ret);
5620 else
5621 wcd9xxx_mbhc_start(&taiko->mbhc, taiko->mbhc.mbhc_cfg);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005622 mutex_unlock(&codec->mutex);
5623 return ret;
5624}
5625
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005626void *taiko_get_afe_config(struct snd_soc_codec *codec,
5627 enum afe_config_type config_type)
5628{
5629 struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
5630
5631 switch (config_type) {
5632 case AFE_SLIMBUS_SLAVE_CONFIG:
5633 return &priv->slimbus_slave_cfg;
5634 case AFE_CDC_REGISTERS_CONFIG:
5635 return &taiko_mad_audio_reg_cfg;
5636 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
5637 return &taiko_slimbus_slave_port_cfg;
5638 default:
5639 pr_err("%s: Unknown config_type 0x%x\n", __func__, config_type);
5640 return NULL;
5641 }
5642}
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005643
Joonwoo Parka8890262012-10-15 12:04:27 -07005644static struct wcd9xxx_reg_address taiko_reg_address = {
5645 .micb_4_mbhc = TAIKO_A_MICB_4_MBHC,
5646 .micb_4_int_rbias = TAIKO_A_MICB_4_INT_RBIAS,
5647 .micb_4_ctl = TAIKO_A_MICB_4_CTL,
5648};
5649
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005650static int wcd9xxx_ssr_register(struct wcd9xxx *control,
5651 int (*post_reset_cb)(struct wcd9xxx *wcd9xxx), void *priv)
5652{
5653 control->post_reset = post_reset_cb;
5654 control->ssr_priv = priv;
5655 return 0;
5656}
5657
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005658static int taiko_codec_get_buck_mv(struct snd_soc_codec *codec)
5659{
5660 int buck_volt = WCD9XXX_CDC_BUCK_UNSUPPORTED;
5661 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
5662 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
5663 int i;
5664
5665 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
5666 if (!strncmp(pdata->regulator[i].name,
5667 WCD9XXX_SUPPLY_BUCK_NAME,
5668 sizeof(WCD9XXX_SUPPLY_BUCK_NAME))) {
5669 buck_volt = pdata->regulator[i].min_uV;
5670 break;
5671 }
5672 }
5673 return buck_volt;
5674}
5675
Joonwoo Park2a9170a2013-03-04 17:05:57 -08005676static const struct snd_soc_dapm_widget taiko_1_dapm_widgets[] = {
5677 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_TX_1_2_EN, 7, 0,
5678 taiko_codec_enable_adc,
5679 SND_SOC_DAPM_PRE_PMU |
5680 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5681 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_TX_1_2_EN, 3, 0,
5682 taiko_codec_enable_adc,
5683 SND_SOC_DAPM_PRE_PMU |
5684 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5685 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_TX_3_4_EN, 7, 0,
5686 taiko_codec_enable_adc,
5687 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5688 SND_SOC_DAPM_POST_PMD),
5689 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_TX_3_4_EN, 3, 0,
5690 taiko_codec_enable_adc,
5691 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5692 SND_SOC_DAPM_POST_PMD),
5693 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_TX_5_6_EN, 7, 0,
5694 taiko_codec_enable_adc,
5695 SND_SOC_DAPM_POST_PMU),
5696 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_TX_5_6_EN, 3, 0,
5697 taiko_codec_enable_adc,
5698 SND_SOC_DAPM_POST_PMU),
5699};
5700
5701static const struct snd_soc_dapm_widget taiko_2_dapm_widgets[] = {
5702 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_CDC_TX_1_GAIN, 7, 0,
5703 taiko_codec_enable_adc,
5704 SND_SOC_DAPM_PRE_PMU |
5705 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5706 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_CDC_TX_2_GAIN, 7, 0,
5707 taiko_codec_enable_adc,
5708 SND_SOC_DAPM_PRE_PMU |
5709 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
5710 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_CDC_TX_3_GAIN, 7, 0,
5711 taiko_codec_enable_adc,
5712 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5713 SND_SOC_DAPM_POST_PMD),
5714 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_CDC_TX_4_GAIN, 7, 0,
5715 taiko_codec_enable_adc,
5716 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
5717 SND_SOC_DAPM_POST_PMD),
5718 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_CDC_TX_5_GAIN, 7, 0,
5719 taiko_codec_enable_adc,
5720 SND_SOC_DAPM_POST_PMU),
5721 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_CDC_TX_6_GAIN, 7, 0,
5722 taiko_codec_enable_adc,
5723 SND_SOC_DAPM_POST_PMU),
5724};
5725
Kiran Kandic3b24402012-06-11 00:05:59 -07005726static int taiko_codec_probe(struct snd_soc_codec *codec)
5727{
5728 struct wcd9xxx *control;
5729 struct taiko_priv *taiko;
Joonwoo Parka8890262012-10-15 12:04:27 -07005730 struct wcd9xxx_pdata *pdata;
5731 struct wcd9xxx *wcd9xxx;
Kiran Kandic3b24402012-06-11 00:05:59 -07005732 struct snd_soc_dapm_context *dapm = &codec->dapm;
5733 int ret = 0;
5734 int i;
Kuirong Wang906ac472012-07-09 12:54:44 -07005735 void *ptr = NULL;
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005736 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07005737
5738 codec->control_data = dev_get_drvdata(codec->dev->parent);
5739 control = codec->control_data;
5740
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08005741 wcd9xxx_ssr_register(control, taiko_post_reset_cb, (void *)codec);
5742
Kiran Kandi4c56c592012-07-25 11:04:55 -07005743 dev_info(codec->dev, "%s()\n", __func__);
5744
Kiran Kandic3b24402012-06-11 00:05:59 -07005745 taiko = kzalloc(sizeof(struct taiko_priv), GFP_KERNEL);
5746 if (!taiko) {
5747 dev_err(codec->dev, "Failed to allocate private data\n");
5748 return -ENOMEM;
5749 }
5750 for (i = 0 ; i < NUM_DECIMATORS; i++) {
5751 tx_hpf_work[i].taiko = taiko;
5752 tx_hpf_work[i].decimator = i + 1;
5753 INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
5754 tx_hpf_corner_freq_callback);
5755 }
5756
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005757
Kiran Kandic3b24402012-06-11 00:05:59 -07005758 snd_soc_codec_set_drvdata(codec, taiko);
5759
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005760
Joonwoo Parka8890262012-10-15 12:04:27 -07005761 /* codec resmgr module init */
5762 wcd9xxx = codec->control_data;
5763 pdata = dev_get_platdata(codec->dev->parent);
5764 ret = wcd9xxx_resmgr_init(&taiko->resmgr, codec, wcd9xxx, pdata,
5765 &taiko_reg_address);
5766 if (ret) {
5767 pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
5768 return ret;
5769 }
5770
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005771 taiko->clsh_d.buck_mv = taiko_codec_get_buck_mv(codec);
Joonwoo Parka08e0552013-03-05 18:28:23 -08005772 wcd9xxx_clsh_init(&taiko->clsh_d, &taiko->resmgr);
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -08005773
Joonwoo Parka8890262012-10-15 12:04:27 -07005774 /* init and start mbhc */
5775 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
5776 if (ret) {
5777 pr_err("%s: mbhc init failed %d\n", __func__, ret);
5778 return ret;
5779 }
5780
Kiran Kandic3b24402012-06-11 00:05:59 -07005781 taiko->codec = codec;
Kiran Kandic3b24402012-06-11 00:05:59 -07005782 for (i = 0; i < COMPANDER_MAX; i++) {
5783 taiko->comp_enabled[i] = 0;
5784 taiko->comp_fs[i] = COMPANDER_FS_48KHZ;
5785 }
Kiran Kandic3b24402012-06-11 00:05:59 -07005786 taiko->intf_type = wcd9xxx_get_intf_type();
5787 taiko->aux_pga_cnt = 0;
5788 taiko->aux_l_gain = 0x1F;
5789 taiko->aux_r_gain = 0x1F;
Kiran Kandic3b24402012-06-11 00:05:59 -07005790 taiko_update_reg_defaults(codec);
Venkat Sudhira50a3762012-11-26 12:12:15 -08005791 pr_debug("%s: MCLK Rate = %x\n", __func__, wcd9xxx->mclk_rate);
5792 if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ)
Venkat Sudhir16d95e62013-02-04 16:57:33 -08005793 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x0);
Venkat Sudhira50a3762012-11-26 12:12:15 -08005794 else if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_9P6HZ)
Venkat Sudhir16d95e62013-02-04 16:57:33 -08005795 snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x2);
Kiran Kandic3b24402012-06-11 00:05:59 -07005796 taiko_codec_init_reg(codec);
5797 ret = taiko_handle_pdata(taiko);
5798 if (IS_ERR_VALUE(ret)) {
5799 pr_err("%s: bad pdata\n", __func__);
5800 goto err_pdata;
5801 }
5802
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005803 if (spkr_drv_wrnd > 0) {
5804 WCD9XXX_BCL_LOCK(&taiko->resmgr);
5805 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
5806 WCD9XXX_BANDGAP_AUDIO_MODE);
5807 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
5808 }
5809
Kuirong Wang906ac472012-07-09 12:54:44 -07005810 ptr = kmalloc((sizeof(taiko_rx_chs) +
5811 sizeof(taiko_tx_chs)), GFP_KERNEL);
5812 if (!ptr) {
5813 pr_err("%s: no mem for slim chan ctl data\n", __func__);
5814 ret = -ENOMEM;
5815 goto err_nomem_slimch;
5816 }
5817
Kiran Kandic3b24402012-06-11 00:05:59 -07005818 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
5819 snd_soc_dapm_new_controls(dapm, taiko_dapm_i2s_widgets,
5820 ARRAY_SIZE(taiko_dapm_i2s_widgets));
5821 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
5822 ARRAY_SIZE(audio_i2s_map));
Joonwoo Park559a5bf2013-02-15 14:46:36 -08005823 if (TAIKO_IS_1_0(core->version))
5824 snd_soc_dapm_add_routes(dapm, audio_i2s_map_1_0,
5825 ARRAY_SIZE(audio_i2s_map_1_0));
5826 else
5827 snd_soc_dapm_add_routes(dapm, audio_i2s_map_2_0,
5828 ARRAY_SIZE(audio_i2s_map_2_0));
Kuirong Wang906ac472012-07-09 12:54:44 -07005829 for (i = 0; i < ARRAY_SIZE(taiko_i2s_dai); i++)
5830 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
5831 } else if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
5832 for (i = 0; i < NUM_CODEC_DAIS; i++) {
5833 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
5834 init_waitqueue_head(&taiko->dai[i].dai_wait);
5835 }
Joonwoo Park1d05bb92013-03-07 16:55:06 -08005836 taiko_slimbus_slave_port_cfg.slave_dev_intfdev_la =
5837 control->slim_slave->laddr;
5838 taiko_slimbus_slave_port_cfg.slave_dev_pgd_la =
5839 control->slim->laddr;
5840 taiko_slimbus_slave_port_cfg.slave_port_mapping[0] =
5841 TAIKO_MAD_SLIMBUS_TX_PORT;
5842
5843 taiko_init_slim_slave_cfg(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07005844 }
5845
Joonwoo Park2a9170a2013-03-04 17:05:57 -08005846 if (TAIKO_IS_1_0(control->version))
5847 snd_soc_dapm_new_controls(dapm, taiko_1_dapm_widgets,
5848 ARRAY_SIZE(taiko_1_dapm_widgets));
5849 else
5850 snd_soc_dapm_new_controls(dapm, taiko_2_dapm_widgets,
5851 ARRAY_SIZE(taiko_2_dapm_widgets));
5852
Kuirong Wang906ac472012-07-09 12:54:44 -07005853 control->num_rx_port = TAIKO_RX_MAX;
5854 control->rx_chs = ptr;
5855 memcpy(control->rx_chs, taiko_rx_chs, sizeof(taiko_rx_chs));
5856 control->num_tx_port = TAIKO_TX_MAX;
5857 control->tx_chs = ptr + sizeof(taiko_rx_chs);
5858 memcpy(control->tx_chs, taiko_tx_chs, sizeof(taiko_tx_chs));
5859
Kiran Kandic3b24402012-06-11 00:05:59 -07005860 snd_soc_dapm_sync(dapm);
5861
Joonwoo Park7680b9f2012-07-13 11:36:48 -07005862 (void) taiko_setup_irqs(taiko);
Kiran Kandic3b24402012-06-11 00:05:59 -07005863
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005864 atomic_set(&kp_taiko_priv, (unsigned long)taiko);
Damir Didjusto2cb06bd2013-01-30 23:14:55 -08005865 mutex_lock(&dapm->codec->mutex);
5866 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
5867 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
5868 snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
5869 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
5870 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
5871 snd_soc_dapm_sync(dapm);
5872 mutex_unlock(&dapm->codec->mutex);
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005873
Kiran Kandic3b24402012-06-11 00:05:59 -07005874 codec->ignore_pmdown_time = 1;
5875 return ret;
5876
Kiran Kandic3b24402012-06-11 00:05:59 -07005877err_pdata:
Kuirong Wang906ac472012-07-09 12:54:44 -07005878 kfree(ptr);
5879err_nomem_slimch:
Kiran Kandic3b24402012-06-11 00:05:59 -07005880 kfree(taiko);
5881 return ret;
5882}
5883static int taiko_codec_remove(struct snd_soc_codec *codec)
5884{
Kiran Kandic3b24402012-06-11 00:05:59 -07005885 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07005886
Joonwoo Park125cd4e2012-12-11 15:16:11 -08005887 WCD9XXX_BCL_LOCK(&taiko->resmgr);
5888 atomic_set(&kp_taiko_priv, 0);
5889
5890 if (spkr_drv_wrnd > 0)
5891 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
5892 WCD9XXX_BANDGAP_AUDIO_MODE);
5893 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
5894
Joonwoo Parka8890262012-10-15 12:04:27 -07005895 /* cleanup MBHC */
5896 wcd9xxx_mbhc_deinit(&taiko->mbhc);
5897 /* cleanup resmgr */
5898 wcd9xxx_resmgr_deinit(&taiko->resmgr);
5899
Kiran Kandic3b24402012-06-11 00:05:59 -07005900 kfree(taiko);
5901 return 0;
5902}
5903static struct snd_soc_codec_driver soc_codec_dev_taiko = {
5904 .probe = taiko_codec_probe,
5905 .remove = taiko_codec_remove,
5906
5907 .read = taiko_read,
5908 .write = taiko_write,
5909
5910 .readable_register = taiko_readable,
5911 .volatile_register = taiko_volatile,
5912
5913 .reg_cache_size = TAIKO_CACHE_SIZE,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07005914 .reg_cache_default = taiko_reset_reg_defaults,
Kiran Kandic3b24402012-06-11 00:05:59 -07005915 .reg_word_size = 1,
5916
5917 .controls = taiko_snd_controls,
5918 .num_controls = ARRAY_SIZE(taiko_snd_controls),
5919 .dapm_widgets = taiko_dapm_widgets,
5920 .num_dapm_widgets = ARRAY_SIZE(taiko_dapm_widgets),
5921 .dapm_routes = audio_map,
5922 .num_dapm_routes = ARRAY_SIZE(audio_map),
5923};
5924
5925#ifdef CONFIG_PM
5926static int taiko_suspend(struct device *dev)
5927{
5928 dev_dbg(dev, "%s: system suspend\n", __func__);
5929 return 0;
5930}
5931
5932static int taiko_resume(struct device *dev)
5933{
5934 struct platform_device *pdev = to_platform_device(dev);
5935 struct taiko_priv *taiko = platform_get_drvdata(pdev);
5936 dev_dbg(dev, "%s: system resume\n", __func__);
Joonwoo Parka8890262012-10-15 12:04:27 -07005937 /* Notify */
5938 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, WCD9XXX_EVENT_POST_RESUME);
Kiran Kandic3b24402012-06-11 00:05:59 -07005939 return 0;
5940}
5941
5942static const struct dev_pm_ops taiko_pm_ops = {
5943 .suspend = taiko_suspend,
5944 .resume = taiko_resume,
5945};
5946#endif
5947
5948static int __devinit taiko_probe(struct platform_device *pdev)
5949{
5950 int ret = 0;
5951 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
5952 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
5953 taiko_dai, ARRAY_SIZE(taiko_dai));
5954 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
5955 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
5956 taiko_i2s_dai, ARRAY_SIZE(taiko_i2s_dai));
5957 return ret;
5958}
5959static int __devexit taiko_remove(struct platform_device *pdev)
5960{
5961 snd_soc_unregister_codec(&pdev->dev);
5962 return 0;
5963}
5964static struct platform_driver taiko_codec_driver = {
5965 .probe = taiko_probe,
5966 .remove = taiko_remove,
5967 .driver = {
5968 .name = "taiko_codec",
5969 .owner = THIS_MODULE,
5970#ifdef CONFIG_PM
5971 .pm = &taiko_pm_ops,
5972#endif
5973 },
5974};
5975
5976static int __init taiko_codec_init(void)
5977{
5978 return platform_driver_register(&taiko_codec_driver);
5979}
5980
5981static void __exit taiko_codec_exit(void)
5982{
5983 platform_driver_unregister(&taiko_codec_driver);
5984}
5985
5986module_init(taiko_codec_init);
5987module_exit(taiko_codec_exit);
5988
5989MODULE_DESCRIPTION("Taiko codec driver");
5990MODULE_LICENSE("GPL v2");