blob: fb8e44d1a8e4c85d1bdfa86691c474c7a0c3f3c0 [file] [log] [blame]
Kiran Kandic3b24402012-06-11 00:05:59 -07001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
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>
21#include <linux/mfd/wcd9xxx/core.h>
22#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
23#include <linux/mfd/wcd9xxx/wcd9320_registers.h>
24#include <linux/mfd/wcd9xxx/pdata.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/tlv.h>
30#include <linux/bitops.h>
31#include <linux/delay.h>
32#include <linux/pm_runtime.h>
33#include <linux/kernel.h>
34#include <linux/gpio.h>
35#include "wcd9320.h"
Joonwoo Parka8890262012-10-15 12:04:27 -070036#include "wcd9xxx-resmgr.h"
Kiran Kandic3b24402012-06-11 00:05:59 -070037
38#define WCD9320_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
39 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
40 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
41
Kiran Kandic3b24402012-06-11 00:05:59 -070042#define NUM_DECIMATORS 10
43#define NUM_INTERPOLATORS 7
44#define BITS_PER_REG 8
Kuirong Wang906ac472012-07-09 12:54:44 -070045#define TAIKO_TX_PORT_NUMBER 16
Kiran Kandic3b24402012-06-11 00:05:59 -070046
Kiran Kandic3b24402012-06-11 00:05:59 -070047#define TAIKO_I2S_MASTER_MODE_MASK 0x08
48
Kuirong Wang906ac472012-07-09 12:54:44 -070049enum {
50 AIF1_PB = 0,
51 AIF1_CAP,
52 AIF2_PB,
53 AIF2_CAP,
54 AIF3_PB,
55 AIF3_CAP,
56 NUM_CODEC_DAIS,
Kiran Kandic3b24402012-06-11 00:05:59 -070057};
58
Kuirong Wang906ac472012-07-09 12:54:44 -070059enum {
60 RX_MIX1_INP_SEL_ZERO = 0,
61 RX_MIX1_INP_SEL_SRC1,
62 RX_MIX1_INP_SEL_SRC2,
63 RX_MIX1_INP_SEL_IIR1,
64 RX_MIX1_INP_SEL_IIR2,
65 RX_MIX1_INP_SEL_RX1,
66 RX_MIX1_INP_SEL_RX2,
67 RX_MIX1_INP_SEL_RX3,
68 RX_MIX1_INP_SEL_RX4,
69 RX_MIX1_INP_SEL_RX5,
70 RX_MIX1_INP_SEL_RX6,
71 RX_MIX1_INP_SEL_RX7,
72 RX_MIX1_INP_SEL_AUXRX,
73};
74
75#define TAIKO_COMP_DIGITAL_GAIN_OFFSET 3
76
Kiran Kandic3b24402012-06-11 00:05:59 -070077static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
78static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
79static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
80static struct snd_soc_dai_driver taiko_dai[];
81static const DECLARE_TLV_DB_SCALE(aux_pga_gain, 0, 2, 0);
82
Kiran Kandic3b24402012-06-11 00:05:59 -070083/* Codec supports 2 IIR filters */
84enum {
85 IIR1 = 0,
86 IIR2,
87 IIR_MAX,
88};
89/* Codec supports 5 bands */
90enum {
91 BAND1 = 0,
92 BAND2,
93 BAND3,
94 BAND4,
95 BAND5,
96 BAND_MAX,
97};
98
99enum {
100 COMPANDER_1 = 0,
101 COMPANDER_2,
102 COMPANDER_MAX,
103};
104
105enum {
106 COMPANDER_FS_8KHZ = 0,
107 COMPANDER_FS_16KHZ,
108 COMPANDER_FS_32KHZ,
109 COMPANDER_FS_48KHZ,
110 COMPANDER_FS_96KHZ,
111 COMPANDER_FS_192KHZ,
112 COMPANDER_FS_MAX,
113};
114
Kiran Kandic3b24402012-06-11 00:05:59 -0700115struct comp_sample_dependent_params {
116 u32 peak_det_timeout;
117 u32 rms_meter_div_fact;
118 u32 rms_meter_resamp_fact;
119};
120
Kiran Kandic3b24402012-06-11 00:05:59 -0700121struct hpf_work {
122 struct taiko_priv *taiko;
123 u32 decimator;
124 u8 tx_hpf_cut_of_freq;
125 struct delayed_work dwork;
126};
127
128static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
129
Kuirong Wang906ac472012-07-09 12:54:44 -0700130static const struct wcd9xxx_ch taiko_rx_chs[TAIKO_RX_MAX] = {
131 WCD9XXX_CH(16, 0),
132 WCD9XXX_CH(17, 1),
133 WCD9XXX_CH(18, 2),
134 WCD9XXX_CH(19, 3),
135 WCD9XXX_CH(20, 4),
136 WCD9XXX_CH(21, 5),
137 WCD9XXX_CH(22, 6),
138 WCD9XXX_CH(23, 7),
139 WCD9XXX_CH(24, 8),
140 WCD9XXX_CH(25, 9),
141 WCD9XXX_CH(26, 10),
142 WCD9XXX_CH(27, 11),
143 WCD9XXX_CH(28, 12),
144};
145
146static const struct wcd9xxx_ch taiko_tx_chs[TAIKO_TX_MAX] = {
147 WCD9XXX_CH(0, 0),
148 WCD9XXX_CH(1, 1),
149 WCD9XXX_CH(2, 2),
150 WCD9XXX_CH(3, 3),
151 WCD9XXX_CH(4, 4),
152 WCD9XXX_CH(5, 5),
153 WCD9XXX_CH(6, 6),
154 WCD9XXX_CH(7, 7),
155 WCD9XXX_CH(8, 8),
156 WCD9XXX_CH(9, 9),
157 WCD9XXX_CH(10, 10),
158 WCD9XXX_CH(11, 11),
159 WCD9XXX_CH(12, 12),
160 WCD9XXX_CH(13, 13),
161 WCD9XXX_CH(14, 14),
162 WCD9XXX_CH(15, 15),
163};
164
165static const u32 vport_check_table[NUM_CODEC_DAIS] = {
166 0, /* AIF1_PB */
167 (1 << AIF2_CAP) | (1 << AIF3_CAP), /* AIF1_CAP */
168 0, /* AIF2_PB */
169 (1 << AIF1_CAP) | (1 << AIF3_CAP), /* AIF2_CAP */
170 0, /* AIF2_PB */
171 (1 << AIF1_CAP) | (1 << AIF2_CAP), /* AIF2_CAP */
172};
173
Kiran Kandic3b24402012-06-11 00:05:59 -0700174struct taiko_priv {
175 struct snd_soc_codec *codec;
Kiran Kandic3b24402012-06-11 00:05:59 -0700176 u32 adc_count;
Kiran Kandic3b24402012-06-11 00:05:59 -0700177 u32 rx_bias_count;
178 s32 dmic_1_2_clk_cnt;
179 s32 dmic_3_4_clk_cnt;
180 s32 dmic_5_6_clk_cnt;
181
Kiran Kandic3b24402012-06-11 00:05:59 -0700182 u32 anc_slot;
183
Kiran Kandic3b24402012-06-11 00:05:59 -0700184 /*track taiko interface type*/
185 u8 intf_type;
186
Kiran Kandic3b24402012-06-11 00:05:59 -0700187 /* num of slim ports required */
Kuirong Wang906ac472012-07-09 12:54:44 -0700188 struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
Kiran Kandic3b24402012-06-11 00:05:59 -0700189
190 /*compander*/
191 int comp_enabled[COMPANDER_MAX];
192 u32 comp_fs[COMPANDER_MAX];
193
194 /* Maintain the status of AUX PGA */
195 int aux_pga_cnt;
196 u8 aux_l_gain;
197 u8 aux_r_gain;
198
Joonwoo Parka8890262012-10-15 12:04:27 -0700199 /* resmgr module */
200 struct wcd9xxx_resmgr resmgr;
201 /* mbhc module */
202 struct wcd9xxx_mbhc mbhc;
Kiran Kandic3b24402012-06-11 00:05:59 -0700203};
204
Kiran Kandic3b24402012-06-11 00:05:59 -0700205static const u32 comp_shift[] = {
206 0,
207 2,
208};
209
210static const int comp_rx_path[] = {
211 COMPANDER_1,
212 COMPANDER_1,
213 COMPANDER_2,
214 COMPANDER_2,
215 COMPANDER_2,
216 COMPANDER_2,
217 COMPANDER_MAX,
218};
219
220static const struct comp_sample_dependent_params comp_samp_params[] = {
221 {
222 .peak_det_timeout = 0x2,
223 .rms_meter_div_fact = 0x8 << 4,
224 .rms_meter_resamp_fact = 0x21,
225 },
226 {
227 .peak_det_timeout = 0x3,
228 .rms_meter_div_fact = 0x9 << 4,
229 .rms_meter_resamp_fact = 0x28,
230 },
231
232 {
233 .peak_det_timeout = 0x5,
234 .rms_meter_div_fact = 0xB << 4,
235 .rms_meter_resamp_fact = 0x28,
236 },
237
238 {
239 .peak_det_timeout = 0x5,
240 .rms_meter_div_fact = 0xB << 4,
241 .rms_meter_resamp_fact = 0x28,
242 },
243};
244
245static unsigned short rx_digital_gain_reg[] = {
246 TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
247 TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
248 TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
249 TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
250 TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
251 TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
252 TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
253};
254
255
256static unsigned short tx_digital_gain_reg[] = {
257 TAIKO_A_CDC_TX1_VOL_CTL_GAIN,
258 TAIKO_A_CDC_TX2_VOL_CTL_GAIN,
259 TAIKO_A_CDC_TX3_VOL_CTL_GAIN,
260 TAIKO_A_CDC_TX4_VOL_CTL_GAIN,
261 TAIKO_A_CDC_TX5_VOL_CTL_GAIN,
262 TAIKO_A_CDC_TX6_VOL_CTL_GAIN,
263 TAIKO_A_CDC_TX7_VOL_CTL_GAIN,
264 TAIKO_A_CDC_TX8_VOL_CTL_GAIN,
265 TAIKO_A_CDC_TX9_VOL_CTL_GAIN,
266 TAIKO_A_CDC_TX10_VOL_CTL_GAIN,
267};
268
Kiran Kandi4c56c592012-07-25 11:04:55 -0700269static int taiko_codec_enable_class_h_clk(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -0700270 struct snd_kcontrol *kcontrol, int event)
271{
272 struct snd_soc_codec *codec = w->codec;
273
Kiran Kandi4c56c592012-07-25 11:04:55 -0700274 pr_debug("%s %s %d\n", __func__, w->name, event);
Kiran Kandic3b24402012-06-11 00:05:59 -0700275
Kiran Kandic3b24402012-06-11 00:05:59 -0700276 switch (event) {
Kiran Kandi4c56c592012-07-25 11:04:55 -0700277 case SND_SOC_DAPM_PRE_PMU:
278 snd_soc_update_bits(codec, TAIKO_A_CDC_CLSH_B1_CTL, 0x01, 0x01);
Kiran Kandic3b24402012-06-11 00:05:59 -0700279 break;
280 case SND_SOC_DAPM_PRE_PMD:
Kiran Kandi4c56c592012-07-25 11:04:55 -0700281 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_1, 0x80, 0x00);
282 snd_soc_update_bits(codec, TAIKO_A_CDC_CLSH_B1_CTL, 0x01, 0x00);
Kiran Kandic3b24402012-06-11 00:05:59 -0700283 break;
284 }
285 return 0;
286}
287
Kiran Kandi4c56c592012-07-25 11:04:55 -0700288static int taiko_codec_enable_class_h(struct snd_soc_dapm_widget *w,
289 struct snd_kcontrol *kcontrol, int event)
290{
291 struct snd_soc_codec *codec = w->codec;
292
293 pr_debug("%s %s %d\n", __func__, w->name, event);
294
295 switch (event) {
296 case SND_SOC_DAPM_POST_PMU:
297 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_5, 0x02, 0x02);
298 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_4, 0xFF, 0xFF);
299 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_1, 0x04, 0x04);
300 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x04, 0x00);
301 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x08, 0x00);
302 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_1, 0x80, 0x80);
303 usleep_range(1000, 1000);
304 break;
305 }
306 return 0;
307}
308
309static int taiko_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
310 struct snd_kcontrol *kcontrol, int event)
311{
312 pr_debug("%s %s %d\n", __func__, w->name, event);
313
314 switch (event) {
315 case SND_SOC_DAPM_POST_PMU:
316 usleep_range(1000, 1000);
317 break;
318 }
319 return 0;
320}
321
322
Kiran Kandic3b24402012-06-11 00:05:59 -0700323static int taiko_get_anc_slot(struct snd_kcontrol *kcontrol,
324 struct snd_ctl_elem_value *ucontrol)
325{
326 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
327 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
328 ucontrol->value.integer.value[0] = taiko->anc_slot;
329 return 0;
330}
331
332static int taiko_put_anc_slot(struct snd_kcontrol *kcontrol,
333 struct snd_ctl_elem_value *ucontrol)
334{
335 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
336 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
337 taiko->anc_slot = ucontrol->value.integer.value[0];
338 return 0;
339}
340
341static int taiko_pa_gain_get(struct snd_kcontrol *kcontrol,
342 struct snd_ctl_elem_value *ucontrol)
343{
344 u8 ear_pa_gain;
345 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
346
347 ear_pa_gain = snd_soc_read(codec, TAIKO_A_RX_EAR_GAIN);
348
349 ear_pa_gain = ear_pa_gain >> 5;
350
351 if (ear_pa_gain == 0x00) {
352 ucontrol->value.integer.value[0] = 0;
353 } else if (ear_pa_gain == 0x04) {
354 ucontrol->value.integer.value[0] = 1;
355 } else {
356 pr_err("%s: ERROR: Unsupported Ear Gain = 0x%x\n",
357 __func__, ear_pa_gain);
358 return -EINVAL;
359 }
360
361 pr_debug("%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
362
363 return 0;
364}
365
366static int taiko_pa_gain_put(struct snd_kcontrol *kcontrol,
367 struct snd_ctl_elem_value *ucontrol)
368{
369 u8 ear_pa_gain;
370 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
371
372 pr_debug("%s: ucontrol->value.integer.value[0] = %ld\n", __func__,
373 ucontrol->value.integer.value[0]);
374
375 switch (ucontrol->value.integer.value[0]) {
376 case 0:
377 ear_pa_gain = 0x00;
378 break;
379 case 1:
380 ear_pa_gain = 0x80;
381 break;
382 default:
383 return -EINVAL;
384 }
385
386 snd_soc_update_bits(codec, TAIKO_A_RX_EAR_GAIN, 0xE0, ear_pa_gain);
387 return 0;
388}
389
390static int taiko_get_iir_enable_audio_mixer(
391 struct snd_kcontrol *kcontrol,
392 struct snd_ctl_elem_value *ucontrol)
393{
394 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
395 int iir_idx = ((struct soc_multi_mixer_control *)
396 kcontrol->private_value)->reg;
397 int band_idx = ((struct soc_multi_mixer_control *)
398 kcontrol->private_value)->shift;
399
400 ucontrol->value.integer.value[0] =
401 snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
402 (1 << band_idx);
403
404 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
405 iir_idx, band_idx,
406 (uint32_t)ucontrol->value.integer.value[0]);
407 return 0;
408}
409
410static int taiko_put_iir_enable_audio_mixer(
411 struct snd_kcontrol *kcontrol,
412 struct snd_ctl_elem_value *ucontrol)
413{
414 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
415 int iir_idx = ((struct soc_multi_mixer_control *)
416 kcontrol->private_value)->reg;
417 int band_idx = ((struct soc_multi_mixer_control *)
418 kcontrol->private_value)->shift;
419 int value = ucontrol->value.integer.value[0];
420
421 /* Mask first 5 bits, 6-8 are reserved */
422 snd_soc_update_bits(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx),
423 (1 << band_idx), (value << band_idx));
424
425 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
426 iir_idx, band_idx, value);
427 return 0;
428}
429static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
430 int iir_idx, int band_idx,
431 int coeff_idx)
432{
433 /* Address does not automatically update if reading */
434 snd_soc_write(codec,
435 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
436 (band_idx * BAND_MAX + coeff_idx) & 0x1F);
437
438 /* Mask bits top 2 bits since they are reserved */
439 return ((snd_soc_read(codec,
440 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 24)) &
441 0x3FFFFFFF;
442}
443
444static int taiko_get_iir_band_audio_mixer(
445 struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
447{
448 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
449 int iir_idx = ((struct soc_multi_mixer_control *)
450 kcontrol->private_value)->reg;
451 int band_idx = ((struct soc_multi_mixer_control *)
452 kcontrol->private_value)->shift;
453
454 ucontrol->value.integer.value[0] =
455 get_iir_band_coeff(codec, iir_idx, band_idx, 0);
456 ucontrol->value.integer.value[1] =
457 get_iir_band_coeff(codec, iir_idx, band_idx, 1);
458 ucontrol->value.integer.value[2] =
459 get_iir_band_coeff(codec, iir_idx, band_idx, 2);
460 ucontrol->value.integer.value[3] =
461 get_iir_band_coeff(codec, iir_idx, band_idx, 3);
462 ucontrol->value.integer.value[4] =
463 get_iir_band_coeff(codec, iir_idx, band_idx, 4);
464
465 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
466 "%s: IIR #%d band #%d b1 = 0x%x\n"
467 "%s: IIR #%d band #%d b2 = 0x%x\n"
468 "%s: IIR #%d band #%d a1 = 0x%x\n"
469 "%s: IIR #%d band #%d a2 = 0x%x\n",
470 __func__, iir_idx, band_idx,
471 (uint32_t)ucontrol->value.integer.value[0],
472 __func__, iir_idx, band_idx,
473 (uint32_t)ucontrol->value.integer.value[1],
474 __func__, iir_idx, band_idx,
475 (uint32_t)ucontrol->value.integer.value[2],
476 __func__, iir_idx, band_idx,
477 (uint32_t)ucontrol->value.integer.value[3],
478 __func__, iir_idx, band_idx,
479 (uint32_t)ucontrol->value.integer.value[4]);
480 return 0;
481}
482
483static void set_iir_band_coeff(struct snd_soc_codec *codec,
484 int iir_idx, int band_idx,
485 int coeff_idx, uint32_t value)
486{
487 /* Mask top 3 bits, 6-8 are reserved */
488 /* Update address manually each time */
489 snd_soc_write(codec,
490 (TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
491 (band_idx * BAND_MAX + coeff_idx) & 0x1F);
492
493 /* Mask top 2 bits, 7-8 are reserved */
494 snd_soc_write(codec,
495 (TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
496 (value >> 24) & 0x3F);
497
498}
499
500static int taiko_put_iir_band_audio_mixer(
501 struct snd_kcontrol *kcontrol,
502 struct snd_ctl_elem_value *ucontrol)
503{
504 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
505 int iir_idx = ((struct soc_multi_mixer_control *)
506 kcontrol->private_value)->reg;
507 int band_idx = ((struct soc_multi_mixer_control *)
508 kcontrol->private_value)->shift;
509
510 set_iir_band_coeff(codec, iir_idx, band_idx, 0,
511 ucontrol->value.integer.value[0]);
512 set_iir_band_coeff(codec, iir_idx, band_idx, 1,
513 ucontrol->value.integer.value[1]);
514 set_iir_band_coeff(codec, iir_idx, band_idx, 2,
515 ucontrol->value.integer.value[2]);
516 set_iir_band_coeff(codec, iir_idx, band_idx, 3,
517 ucontrol->value.integer.value[3]);
518 set_iir_band_coeff(codec, iir_idx, band_idx, 4,
519 ucontrol->value.integer.value[4]);
520
521 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
522 "%s: IIR #%d band #%d b1 = 0x%x\n"
523 "%s: IIR #%d band #%d b2 = 0x%x\n"
524 "%s: IIR #%d band #%d a1 = 0x%x\n"
525 "%s: IIR #%d band #%d a2 = 0x%x\n",
526 __func__, iir_idx, band_idx,
527 get_iir_band_coeff(codec, iir_idx, band_idx, 0),
528 __func__, iir_idx, band_idx,
529 get_iir_band_coeff(codec, iir_idx, band_idx, 1),
530 __func__, iir_idx, band_idx,
531 get_iir_band_coeff(codec, iir_idx, band_idx, 2),
532 __func__, iir_idx, band_idx,
533 get_iir_band_coeff(codec, iir_idx, band_idx, 3),
534 __func__, iir_idx, band_idx,
535 get_iir_band_coeff(codec, iir_idx, band_idx, 4));
536 return 0;
537}
538
539static int taiko_compander_gain_offset(
540 struct snd_soc_codec *codec, u32 enable,
541 unsigned int reg, int mask, int event)
542{
543 int pa_mode = snd_soc_read(codec, reg) & mask;
544 int gain_offset = 0;
545 /* if PMU && enable is 1-> offset is 3
546 * if PMU && enable is 0-> offset is 0
547 * if PMD && pa_mode is PA -> offset is 0: PMU compander is off
548 * if PMD && pa_mode is comp -> offset is -3: PMU compander is on.
549 */
550
551 if (SND_SOC_DAPM_EVENT_ON(event) && (enable != 0))
552 gain_offset = TAIKO_COMP_DIGITAL_GAIN_OFFSET;
553 if (SND_SOC_DAPM_EVENT_OFF(event) && (pa_mode == 0))
554 gain_offset = -TAIKO_COMP_DIGITAL_GAIN_OFFSET;
555 return gain_offset;
556}
557
558
559static int taiko_config_gain_compander(
560 struct snd_soc_codec *codec,
561 u32 compander, u32 enable, int event)
562{
563 int value = 0;
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -0700564 int mask = 1 << 5;
Kiran Kandic3b24402012-06-11 00:05:59 -0700565 int gain = 0;
566 int gain_offset;
567 if (compander >= COMPANDER_MAX) {
568 pr_err("%s: Error, invalid compander channel\n", __func__);
569 return -EINVAL;
570 }
571
572 if ((enable == 0) || SND_SOC_DAPM_EVENT_OFF(event))
573 value = 1 << 4;
574
575 if (compander == COMPANDER_1) {
576 gain_offset = taiko_compander_gain_offset(codec, enable,
577 TAIKO_A_RX_HPH_L_GAIN, mask, event);
578 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_L_GAIN, mask, value);
579 gain = snd_soc_read(codec, TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL);
580 snd_soc_update_bits(codec, TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
581 0xFF, gain - gain_offset);
582 gain_offset = taiko_compander_gain_offset(codec, enable,
583 TAIKO_A_RX_HPH_R_GAIN, mask, event);
584 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_R_GAIN, mask, value);
585 gain = snd_soc_read(codec, TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL);
586 snd_soc_update_bits(codec, TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
587 0xFF, gain - gain_offset);
588 } else if (compander == COMPANDER_2) {
589 gain_offset = taiko_compander_gain_offset(codec, enable,
590 TAIKO_A_RX_LINE_1_GAIN, mask, event);
591 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_1_GAIN, mask, value);
592 gain = snd_soc_read(codec, TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL);
593 snd_soc_update_bits(codec, TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
594 0xFF, gain - gain_offset);
595 gain_offset = taiko_compander_gain_offset(codec, enable,
596 TAIKO_A_RX_LINE_3_GAIN, mask, event);
597 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_3_GAIN, mask, value);
598 gain = snd_soc_read(codec, TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL);
599 snd_soc_update_bits(codec, TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
600 0xFF, gain - gain_offset);
601 gain_offset = taiko_compander_gain_offset(codec, enable,
602 TAIKO_A_RX_LINE_2_GAIN, mask, event);
603 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_2_GAIN, mask, value);
604 gain = snd_soc_read(codec, TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL);
605 snd_soc_update_bits(codec, TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
606 0xFF, gain - gain_offset);
607 gain_offset = taiko_compander_gain_offset(codec, enable,
608 TAIKO_A_RX_LINE_4_GAIN, mask, event);
609 snd_soc_update_bits(codec, TAIKO_A_RX_LINE_4_GAIN, mask, value);
610 gain = snd_soc_read(codec, TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL);
611 snd_soc_update_bits(codec, TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
612 0xFF, gain - gain_offset);
613 }
614 return 0;
615}
616static int taiko_get_compander(struct snd_kcontrol *kcontrol,
617 struct snd_ctl_elem_value *ucontrol)
618{
619
620 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
621 int comp = ((struct soc_multi_mixer_control *)
622 kcontrol->private_value)->max;
623 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
624
625 ucontrol->value.integer.value[0] = taiko->comp_enabled[comp];
626
627 return 0;
628}
629
630static int taiko_set_compander(struct snd_kcontrol *kcontrol,
631 struct snd_ctl_elem_value *ucontrol)
632{
633 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
634 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
635 int comp = ((struct soc_multi_mixer_control *)
636 kcontrol->private_value)->max;
637 int value = ucontrol->value.integer.value[0];
638
639 if (value == taiko->comp_enabled[comp]) {
640 pr_debug("%s: compander #%d enable %d no change\n",
641 __func__, comp, value);
642 return 0;
643 }
644 taiko->comp_enabled[comp] = value;
645 return 0;
646}
647
648
649static int taiko_config_compander(struct snd_soc_dapm_widget *w,
650 struct snd_kcontrol *kcontrol,
651 int event)
652{
653 struct snd_soc_codec *codec = w->codec;
654 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
655 u32 rate = taiko->comp_fs[w->shift];
656
Kiran Kandid2b46332012-10-05 12:04:00 -0700657 pr_debug("%s: %s event %d enabled = %d", __func__, w->name,
658 event, taiko->comp_enabled[w->shift]);
659
Kiran Kandic3b24402012-06-11 00:05:59 -0700660 switch (event) {
661 case SND_SOC_DAPM_PRE_PMU:
662 if (taiko->comp_enabled[w->shift] != 0) {
663 /* Enable both L/R compander clocks */
664 snd_soc_update_bits(codec,
665 TAIKO_A_CDC_CLK_RX_B2_CTL,
666 0x03 << comp_shift[w->shift],
667 0x03 << comp_shift[w->shift]);
668 /* Clar the HALT for the compander*/
669 snd_soc_update_bits(codec,
670 TAIKO_A_CDC_COMP1_B1_CTL +
671 w->shift * 8, 1 << 2, 0);
672 /* Toggle compander reset bits*/
673 snd_soc_update_bits(codec,
674 TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
675 0x03 << comp_shift[w->shift],
676 0x03 << comp_shift[w->shift]);
677 snd_soc_update_bits(codec,
678 TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL,
679 0x03 << comp_shift[w->shift], 0);
680 taiko_config_gain_compander(codec, w->shift, 1, event);
681 /* Update the RMS meter resampling*/
682 snd_soc_update_bits(codec,
683 TAIKO_A_CDC_COMP1_B3_CTL +
684 w->shift * 8, 0xFF, 0x01);
685 /* Wait for 1ms*/
686 usleep_range(1000, 1000);
687 }
688 break;
689 case SND_SOC_DAPM_POST_PMU:
690 /* Set sample rate dependent paramater*/
691 if (taiko->comp_enabled[w->shift] != 0) {
692 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_FS_CFG +
693 w->shift * 8, 0x03, rate);
694 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B2_CTL +
695 w->shift * 8, 0x0F,
696 comp_samp_params[rate].peak_det_timeout);
697 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B2_CTL +
698 w->shift * 8, 0xF0,
699 comp_samp_params[rate].rms_meter_div_fact);
700 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B3_CTL +
701 w->shift * 8, 0xFF,
702 comp_samp_params[rate].rms_meter_resamp_fact);
703 /* Compander enable -> 0x370/0x378*/
704 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B1_CTL +
705 w->shift * 8, 0x03, 0x03);
706 }
707 break;
708 case SND_SOC_DAPM_PRE_PMD:
709 /* Halt the compander*/
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -0700710 if (taiko->comp_enabled[w->shift] != 0) {
711 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B1_CTL +
712 w->shift * 8, 1 << 2, 1 << 2);
713 }
Kiran Kandic3b24402012-06-11 00:05:59 -0700714 break;
715 case SND_SOC_DAPM_POST_PMD:
716 /* Restore the gain */
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -0700717 if (taiko->comp_enabled[w->shift] != 0) {
718 taiko_config_gain_compander(codec, w->shift,
719 taiko->comp_enabled[w->shift], event);
720 /* Disable the compander*/
721 snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B1_CTL +
722 w->shift * 8, 0x03, 0x00);
723 /* Turn off the clock for compander in pair*/
724 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
725 0x03 << comp_shift[w->shift], 0);
726 }
Kiran Kandic3b24402012-06-11 00:05:59 -0700727 break;
728 }
729 return 0;
730}
731
732static const char * const taiko_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
733static const struct soc_enum taiko_ear_pa_gain_enum[] = {
734 SOC_ENUM_SINGLE_EXT(2, taiko_ear_pa_gain_text),
735};
736
737/*cut of frequency for high pass filter*/
738static const char * const cf_text[] = {
739 "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
740};
741
742static const struct soc_enum cf_dec1_enum =
743 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX1_MUX_CTL, 4, 3, cf_text);
744
745static const struct soc_enum cf_dec2_enum =
746 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX2_MUX_CTL, 4, 3, cf_text);
747
748static const struct soc_enum cf_dec3_enum =
749 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX3_MUX_CTL, 4, 3, cf_text);
750
751static const struct soc_enum cf_dec4_enum =
752 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX4_MUX_CTL, 4, 3, cf_text);
753
754static const struct soc_enum cf_dec5_enum =
755 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX5_MUX_CTL, 4, 3, cf_text);
756
757static const struct soc_enum cf_dec6_enum =
758 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX6_MUX_CTL, 4, 3, cf_text);
759
760static const struct soc_enum cf_dec7_enum =
761 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX7_MUX_CTL, 4, 3, cf_text);
762
763static const struct soc_enum cf_dec8_enum =
764 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX8_MUX_CTL, 4, 3, cf_text);
765
766static const struct soc_enum cf_dec9_enum =
767 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX9_MUX_CTL, 4, 3, cf_text);
768
769static const struct soc_enum cf_dec10_enum =
770 SOC_ENUM_SINGLE(TAIKO_A_CDC_TX10_MUX_CTL, 4, 3, cf_text);
771
772static const struct soc_enum cf_rxmix1_enum =
773 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX1_B4_CTL, 1, 3, cf_text);
774
775static const struct soc_enum cf_rxmix2_enum =
776 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX2_B4_CTL, 1, 3, cf_text);
777
778static const struct soc_enum cf_rxmix3_enum =
779 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX3_B4_CTL, 1, 3, cf_text);
780
781static const struct soc_enum cf_rxmix4_enum =
782 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX4_B4_CTL, 1, 3, cf_text);
783
784static const struct soc_enum cf_rxmix5_enum =
785 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX5_B4_CTL, 1, 3, cf_text)
786;
787static const struct soc_enum cf_rxmix6_enum =
788 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX6_B4_CTL, 1, 3, cf_text);
789
790static const struct soc_enum cf_rxmix7_enum =
791 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX7_B4_CTL, 1, 3, cf_text);
792
793static const struct snd_kcontrol_new taiko_snd_controls[] = {
794
795 SOC_ENUM_EXT("EAR PA Gain", taiko_ear_pa_gain_enum[0],
796 taiko_pa_gain_get, taiko_pa_gain_put),
797
798 SOC_SINGLE_TLV("LINEOUT1 Volume", TAIKO_A_RX_LINE_1_GAIN, 0, 12, 1,
799 line_gain),
800 SOC_SINGLE_TLV("LINEOUT2 Volume", TAIKO_A_RX_LINE_2_GAIN, 0, 12, 1,
801 line_gain),
802 SOC_SINGLE_TLV("LINEOUT3 Volume", TAIKO_A_RX_LINE_3_GAIN, 0, 12, 1,
803 line_gain),
804 SOC_SINGLE_TLV("LINEOUT4 Volume", TAIKO_A_RX_LINE_4_GAIN, 0, 12, 1,
805 line_gain),
806
807 SOC_SINGLE_TLV("HPHL Volume", TAIKO_A_RX_HPH_L_GAIN, 0, 12, 1,
808 line_gain),
809 SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 12, 1,
810 line_gain),
811
812 SOC_SINGLE_S8_TLV("RX1 Digital Volume", TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
813 -84, 40, digital_gain),
814 SOC_SINGLE_S8_TLV("RX2 Digital Volume", TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
815 -84, 40, digital_gain),
816 SOC_SINGLE_S8_TLV("RX3 Digital Volume", TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL,
817 -84, 40, digital_gain),
818 SOC_SINGLE_S8_TLV("RX4 Digital Volume", TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL,
819 -84, 40, digital_gain),
820 SOC_SINGLE_S8_TLV("RX5 Digital Volume", TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL,
821 -84, 40, digital_gain),
822 SOC_SINGLE_S8_TLV("RX6 Digital Volume", TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL,
823 -84, 40, digital_gain),
824 SOC_SINGLE_S8_TLV("RX7 Digital Volume", TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL,
825 -84, 40, digital_gain),
826
827 SOC_SINGLE_S8_TLV("DEC1 Volume", TAIKO_A_CDC_TX1_VOL_CTL_GAIN, -84, 40,
828 digital_gain),
829 SOC_SINGLE_S8_TLV("DEC2 Volume", TAIKO_A_CDC_TX2_VOL_CTL_GAIN, -84, 40,
830 digital_gain),
831 SOC_SINGLE_S8_TLV("DEC3 Volume", TAIKO_A_CDC_TX3_VOL_CTL_GAIN, -84, 40,
832 digital_gain),
833 SOC_SINGLE_S8_TLV("DEC4 Volume", TAIKO_A_CDC_TX4_VOL_CTL_GAIN, -84, 40,
834 digital_gain),
835 SOC_SINGLE_S8_TLV("DEC5 Volume", TAIKO_A_CDC_TX5_VOL_CTL_GAIN, -84, 40,
836 digital_gain),
837 SOC_SINGLE_S8_TLV("DEC6 Volume", TAIKO_A_CDC_TX6_VOL_CTL_GAIN, -84, 40,
838 digital_gain),
839 SOC_SINGLE_S8_TLV("DEC7 Volume", TAIKO_A_CDC_TX7_VOL_CTL_GAIN, -84, 40,
840 digital_gain),
841 SOC_SINGLE_S8_TLV("DEC8 Volume", TAIKO_A_CDC_TX8_VOL_CTL_GAIN, -84, 40,
842 digital_gain),
843 SOC_SINGLE_S8_TLV("DEC9 Volume", TAIKO_A_CDC_TX9_VOL_CTL_GAIN, -84, 40,
844 digital_gain),
845 SOC_SINGLE_S8_TLV("DEC10 Volume", TAIKO_A_CDC_TX10_VOL_CTL_GAIN, -84,
846 40, digital_gain),
847 SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, -84,
848 40, digital_gain),
849 SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", TAIKO_A_CDC_IIR1_GAIN_B2_CTL, -84,
850 40, digital_gain),
851 SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", TAIKO_A_CDC_IIR1_GAIN_B3_CTL, -84,
852 40, digital_gain),
853 SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", TAIKO_A_CDC_IIR1_GAIN_B4_CTL, -84,
854 40, digital_gain),
855 SOC_SINGLE_TLV("ADC1 Volume", TAIKO_A_TX_1_2_EN, 5, 3, 0, analog_gain),
856 SOC_SINGLE_TLV("ADC2 Volume", TAIKO_A_TX_1_2_EN, 1, 3, 0, analog_gain),
857 SOC_SINGLE_TLV("ADC3 Volume", TAIKO_A_TX_3_4_EN, 5, 3, 0, analog_gain),
858 SOC_SINGLE_TLV("ADC4 Volume", TAIKO_A_TX_3_4_EN, 1, 3, 0, analog_gain),
859 SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_TX_5_6_EN, 5, 3, 0, analog_gain),
860 SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_TX_5_6_EN, 1, 3, 0, analog_gain),
861
862
863 SOC_SINGLE("MICBIAS1 CAPLESS Switch", TAIKO_A_MICB_1_CTL, 4, 1, 1),
864 SOC_SINGLE("MICBIAS2 CAPLESS Switch", TAIKO_A_MICB_2_CTL, 4, 1, 1),
865 SOC_SINGLE("MICBIAS3 CAPLESS Switch", TAIKO_A_MICB_3_CTL, 4, 1, 1),
866 SOC_SINGLE("MICBIAS4 CAPLESS Switch", TAIKO_A_MICB_4_CTL, 4, 1, 1),
867
868 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 0, 100, taiko_get_anc_slot,
869 taiko_put_anc_slot),
870 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
871 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
872 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
873 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
874 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
875 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
876 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
877 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
878 SOC_ENUM("TX9 HPF cut off", cf_dec9_enum),
879 SOC_ENUM("TX10 HPF cut off", cf_dec10_enum),
880
881 SOC_SINGLE("TX1 HPF Switch", TAIKO_A_CDC_TX1_MUX_CTL, 3, 1, 0),
882 SOC_SINGLE("TX2 HPF Switch", TAIKO_A_CDC_TX2_MUX_CTL, 3, 1, 0),
883 SOC_SINGLE("TX3 HPF Switch", TAIKO_A_CDC_TX3_MUX_CTL, 3, 1, 0),
884 SOC_SINGLE("TX4 HPF Switch", TAIKO_A_CDC_TX4_MUX_CTL, 3, 1, 0),
885 SOC_SINGLE("TX5 HPF Switch", TAIKO_A_CDC_TX5_MUX_CTL, 3, 1, 0),
886 SOC_SINGLE("TX6 HPF Switch", TAIKO_A_CDC_TX6_MUX_CTL, 3, 1, 0),
887 SOC_SINGLE("TX7 HPF Switch", TAIKO_A_CDC_TX7_MUX_CTL, 3, 1, 0),
888 SOC_SINGLE("TX8 HPF Switch", TAIKO_A_CDC_TX8_MUX_CTL, 3, 1, 0),
889 SOC_SINGLE("TX9 HPF Switch", TAIKO_A_CDC_TX9_MUX_CTL, 3, 1, 0),
890 SOC_SINGLE("TX10 HPF Switch", TAIKO_A_CDC_TX10_MUX_CTL, 3, 1, 0),
891
892 SOC_SINGLE("RX1 HPF Switch", TAIKO_A_CDC_RX1_B5_CTL, 2, 1, 0),
893 SOC_SINGLE("RX2 HPF Switch", TAIKO_A_CDC_RX2_B5_CTL, 2, 1, 0),
894 SOC_SINGLE("RX3 HPF Switch", TAIKO_A_CDC_RX3_B5_CTL, 2, 1, 0),
895 SOC_SINGLE("RX4 HPF Switch", TAIKO_A_CDC_RX4_B5_CTL, 2, 1, 0),
896 SOC_SINGLE("RX5 HPF Switch", TAIKO_A_CDC_RX5_B5_CTL, 2, 1, 0),
897 SOC_SINGLE("RX6 HPF Switch", TAIKO_A_CDC_RX6_B5_CTL, 2, 1, 0),
898 SOC_SINGLE("RX7 HPF Switch", TAIKO_A_CDC_RX7_B5_CTL, 2, 1, 0),
899
900 SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
901 SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
902 SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
903 SOC_ENUM("RX4 HPF cut off", cf_rxmix4_enum),
904 SOC_ENUM("RX5 HPF cut off", cf_rxmix5_enum),
905 SOC_ENUM("RX6 HPF cut off", cf_rxmix6_enum),
906 SOC_ENUM("RX7 HPF cut off", cf_rxmix7_enum),
907
908 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
909 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
910 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
911 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
912 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
913 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
914 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
915 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
916 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
917 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
918 SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
919 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
920 SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
921 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
922 SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
923 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
924 SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
925 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
926 SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
927 taiko_get_iir_enable_audio_mixer, taiko_put_iir_enable_audio_mixer),
928
929 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
930 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
931 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
932 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
933 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
934 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
935 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
936 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
937 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
938 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
939 SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
940 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
941 SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
942 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
943 SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
944 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
945 SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
946 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
947 SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
948 taiko_get_iir_band_audio_mixer, taiko_put_iir_band_audio_mixer),
949
950 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, 1, COMPANDER_1, 0,
951 taiko_get_compander, taiko_set_compander),
952 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, 0, COMPANDER_2, 0,
953 taiko_get_compander, taiko_set_compander),
954
955};
956
957static const char * const rx_mix1_text[] = {
958 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2", "RX1", "RX2", "RX3", "RX4",
959 "RX5", "RX6", "RX7"
960};
961
962static const char * const rx_mix2_text[] = {
963 "ZERO", "SRC1", "SRC2", "IIR1", "IIR2"
964};
965
966static const char * const rx_dsm_text[] = {
967 "CIC_OUT", "DSM_INV"
968};
969
970static const char * const sb_tx1_mux_text[] = {
971 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
972 "DEC1"
973};
974
975static const char * const sb_tx2_mux_text[] = {
976 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
977 "DEC2"
978};
979
980static const char * const sb_tx3_mux_text[] = {
981 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
982 "DEC3"
983};
984
985static const char * const sb_tx4_mux_text[] = {
986 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
987 "DEC4"
988};
989
990static const char * const sb_tx5_mux_text[] = {
991 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
992 "DEC5"
993};
994
995static const char * const sb_tx6_mux_text[] = {
996 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
997 "DEC6"
998};
999
1000static const char * const sb_tx7_to_tx10_mux_text[] = {
1001 "ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
1002 "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1003 "DEC9", "DEC10"
1004};
1005
1006static const char * const dec1_mux_text[] = {
1007 "ZERO", "DMIC1", "ADC6",
1008};
1009
1010static const char * const dec2_mux_text[] = {
1011 "ZERO", "DMIC2", "ADC5",
1012};
1013
1014static const char * const dec3_mux_text[] = {
1015 "ZERO", "DMIC3", "ADC4",
1016};
1017
1018static const char * const dec4_mux_text[] = {
1019 "ZERO", "DMIC4", "ADC3",
1020};
1021
1022static const char * const dec5_mux_text[] = {
1023 "ZERO", "DMIC5", "ADC2",
1024};
1025
1026static const char * const dec6_mux_text[] = {
1027 "ZERO", "DMIC6", "ADC1",
1028};
1029
1030static const char * const dec7_mux_text[] = {
1031 "ZERO", "DMIC1", "DMIC6", "ADC1", "ADC6", "ANC1_FB", "ANC2_FB",
1032};
1033
1034static const char * const dec8_mux_text[] = {
1035 "ZERO", "DMIC2", "DMIC5", "ADC2", "ADC5",
1036};
1037
1038static const char * const dec9_mux_text[] = {
1039 "ZERO", "DMIC4", "DMIC5", "ADC2", "ADC3", "ADCMB", "ANC1_FB", "ANC2_FB",
1040};
1041
1042static const char * const dec10_mux_text[] = {
1043 "ZERO", "DMIC3", "DMIC6", "ADC1", "ADC4", "ADCMB", "ANC1_FB", "ANC2_FB",
1044};
1045
1046static const char * const anc_mux_text[] = {
1047 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC_MB",
1048 "RSVD_1", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6"
1049};
1050
1051static const char * const anc1_fb_mux_text[] = {
1052 "ZERO", "EAR_HPH_L", "EAR_LINE_1",
1053};
1054
1055static const char * const iir1_inp1_text[] = {
1056 "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
1057 "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
1058};
1059
1060static const struct soc_enum rx_mix1_inp1_chain_enum =
1061 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 0, 12, rx_mix1_text);
1062
1063static const struct soc_enum rx_mix1_inp2_chain_enum =
1064 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 4, 12, rx_mix1_text);
1065
1066static const struct soc_enum rx_mix1_inp3_chain_enum =
1067 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B2_CTL, 0, 12, rx_mix1_text);
1068
1069static const struct soc_enum rx2_mix1_inp1_chain_enum =
1070 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 0, 12, rx_mix1_text);
1071
1072static const struct soc_enum rx2_mix1_inp2_chain_enum =
1073 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B1_CTL, 4, 12, rx_mix1_text);
1074
1075static const struct soc_enum rx3_mix1_inp1_chain_enum =
1076 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 0, 12, rx_mix1_text);
1077
1078static const struct soc_enum rx3_mix1_inp2_chain_enum =
1079 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX3_B1_CTL, 4, 12, rx_mix1_text);
1080
1081static const struct soc_enum rx4_mix1_inp1_chain_enum =
1082 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 0, 12, rx_mix1_text);
1083
1084static const struct soc_enum rx4_mix1_inp2_chain_enum =
1085 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX4_B1_CTL, 4, 12, rx_mix1_text);
1086
1087static const struct soc_enum rx5_mix1_inp1_chain_enum =
1088 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 0, 12, rx_mix1_text);
1089
1090static const struct soc_enum rx5_mix1_inp2_chain_enum =
1091 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX5_B1_CTL, 4, 12, rx_mix1_text);
1092
1093static const struct soc_enum rx6_mix1_inp1_chain_enum =
1094 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 0, 12, rx_mix1_text);
1095
1096static const struct soc_enum rx6_mix1_inp2_chain_enum =
1097 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX6_B1_CTL, 4, 12, rx_mix1_text);
1098
1099static const struct soc_enum rx7_mix1_inp1_chain_enum =
1100 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 0, 12, rx_mix1_text);
1101
1102static const struct soc_enum rx7_mix1_inp2_chain_enum =
1103 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B1_CTL, 4, 12, rx_mix1_text);
1104
1105static const struct soc_enum rx1_mix2_inp1_chain_enum =
1106 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 0, 5, rx_mix2_text);
1107
1108static const struct soc_enum rx1_mix2_inp2_chain_enum =
1109 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B3_CTL, 3, 5, rx_mix2_text);
1110
1111static const struct soc_enum rx2_mix2_inp1_chain_enum =
1112 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 0, 5, rx_mix2_text);
1113
1114static const struct soc_enum rx2_mix2_inp2_chain_enum =
1115 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX2_B3_CTL, 3, 5, rx_mix2_text);
1116
1117static const struct soc_enum rx7_mix2_inp1_chain_enum =
1118 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 0, 5, rx_mix2_text);
1119
1120static const struct soc_enum rx7_mix2_inp2_chain_enum =
1121 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX7_B3_CTL, 3, 5, rx_mix2_text);
1122
1123static const struct soc_enum rx4_dsm_enum =
1124 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX4_B6_CTL, 4, 2, rx_dsm_text);
1125
1126static const struct soc_enum rx6_dsm_enum =
1127 SOC_ENUM_SINGLE(TAIKO_A_CDC_RX6_B6_CTL, 4, 2, rx_dsm_text);
1128
1129static const struct soc_enum sb_tx1_mux_enum =
1130 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0, 9, sb_tx1_mux_text);
1131
1132static const struct soc_enum sb_tx2_mux_enum =
1133 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0, 9, sb_tx2_mux_text);
1134
1135static const struct soc_enum sb_tx3_mux_enum =
1136 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0, 9, sb_tx3_mux_text);
1137
1138static const struct soc_enum sb_tx4_mux_enum =
1139 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0, 9, sb_tx4_mux_text);
1140
1141static const struct soc_enum sb_tx5_mux_enum =
1142 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0, 9, sb_tx5_mux_text);
1143
1144static const struct soc_enum sb_tx6_mux_enum =
1145 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0, 9, sb_tx6_mux_text);
1146
1147static const struct soc_enum sb_tx7_mux_enum =
1148 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0, 18,
1149 sb_tx7_to_tx10_mux_text);
1150
1151static const struct soc_enum sb_tx8_mux_enum =
1152 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0, 18,
1153 sb_tx7_to_tx10_mux_text);
1154
1155static const struct soc_enum sb_tx9_mux_enum =
1156 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0, 18,
1157 sb_tx7_to_tx10_mux_text);
1158
1159static const struct soc_enum sb_tx10_mux_enum =
1160 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0, 18,
1161 sb_tx7_to_tx10_mux_text);
1162
1163static const struct soc_enum dec1_mux_enum =
1164 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 0, 3, dec1_mux_text);
1165
1166static const struct soc_enum dec2_mux_enum =
1167 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 2, 3, dec2_mux_text);
1168
1169static const struct soc_enum dec3_mux_enum =
1170 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 4, 3, dec3_mux_text);
1171
1172static const struct soc_enum dec4_mux_enum =
1173 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B1_CTL, 6, 3, dec4_mux_text);
1174
1175static const struct soc_enum dec5_mux_enum =
1176 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 0, 3, dec5_mux_text);
1177
1178static const struct soc_enum dec6_mux_enum =
1179 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 2, 3, dec6_mux_text);
1180
1181static const struct soc_enum dec7_mux_enum =
1182 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B2_CTL, 4, 7, dec7_mux_text);
1183
1184static const struct soc_enum dec8_mux_enum =
1185 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 0, 7, dec8_mux_text);
1186
1187static const struct soc_enum dec9_mux_enum =
1188 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B3_CTL, 3, 8, dec9_mux_text);
1189
1190static const struct soc_enum dec10_mux_enum =
1191 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_TX_B4_CTL, 0, 8, dec10_mux_text);
1192
1193static const struct soc_enum anc1_mux_enum =
1194 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 0, 16, anc_mux_text);
1195
1196static const struct soc_enum anc2_mux_enum =
1197 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B1_CTL, 4, 16, anc_mux_text);
1198
1199static const struct soc_enum anc1_fb_mux_enum =
1200 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_ANC_B2_CTL, 0, 3, anc1_fb_mux_text);
1201
1202static const struct soc_enum iir1_inp1_mux_enum =
1203 SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir1_inp1_text);
1204
1205static const struct snd_kcontrol_new rx_mix1_inp1_mux =
1206 SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
1207
1208static const struct snd_kcontrol_new rx_mix1_inp2_mux =
1209 SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
1210
1211static const struct snd_kcontrol_new rx_mix1_inp3_mux =
1212 SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
1213
1214static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
1215 SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
1216
1217static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
1218 SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
1219
1220static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
1221 SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
1222
1223static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
1224 SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
1225
1226static const struct snd_kcontrol_new rx4_mix1_inp1_mux =
1227 SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum);
1228
1229static const struct snd_kcontrol_new rx4_mix1_inp2_mux =
1230 SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum);
1231
1232static const struct snd_kcontrol_new rx5_mix1_inp1_mux =
1233 SOC_DAPM_ENUM("RX5 MIX1 INP1 Mux", rx5_mix1_inp1_chain_enum);
1234
1235static const struct snd_kcontrol_new rx5_mix1_inp2_mux =
1236 SOC_DAPM_ENUM("RX5 MIX1 INP2 Mux", rx5_mix1_inp2_chain_enum);
1237
1238static const struct snd_kcontrol_new rx6_mix1_inp1_mux =
1239 SOC_DAPM_ENUM("RX6 MIX1 INP1 Mux", rx6_mix1_inp1_chain_enum);
1240
1241static const struct snd_kcontrol_new rx6_mix1_inp2_mux =
1242 SOC_DAPM_ENUM("RX6 MIX1 INP2 Mux", rx6_mix1_inp2_chain_enum);
1243
1244static const struct snd_kcontrol_new rx7_mix1_inp1_mux =
1245 SOC_DAPM_ENUM("RX7 MIX1 INP1 Mux", rx7_mix1_inp1_chain_enum);
1246
1247static const struct snd_kcontrol_new rx7_mix1_inp2_mux =
1248 SOC_DAPM_ENUM("RX7 MIX1 INP2 Mux", rx7_mix1_inp2_chain_enum);
1249
1250static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
1251 SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_mix2_inp1_chain_enum);
1252
1253static const struct snd_kcontrol_new rx1_mix2_inp2_mux =
1254 SOC_DAPM_ENUM("RX1 MIX2 INP2 Mux", rx1_mix2_inp2_chain_enum);
1255
1256static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
1257 SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
1258
1259static const struct snd_kcontrol_new rx2_mix2_inp2_mux =
1260 SOC_DAPM_ENUM("RX2 MIX2 INP2 Mux", rx2_mix2_inp2_chain_enum);
1261
1262static const struct snd_kcontrol_new rx7_mix2_inp1_mux =
1263 SOC_DAPM_ENUM("RX7 MIX2 INP1 Mux", rx7_mix2_inp1_chain_enum);
1264
1265static const struct snd_kcontrol_new rx7_mix2_inp2_mux =
1266 SOC_DAPM_ENUM("RX7 MIX2 INP2 Mux", rx7_mix2_inp2_chain_enum);
1267
1268static const struct snd_kcontrol_new rx4_dsm_mux =
1269 SOC_DAPM_ENUM("RX4 DSM MUX Mux", rx4_dsm_enum);
1270
1271static const struct snd_kcontrol_new rx6_dsm_mux =
1272 SOC_DAPM_ENUM("RX6 DSM MUX Mux", rx6_dsm_enum);
1273
1274static const struct snd_kcontrol_new sb_tx1_mux =
1275 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
1276
1277static const struct snd_kcontrol_new sb_tx2_mux =
1278 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
1279
1280static const struct snd_kcontrol_new sb_tx3_mux =
1281 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
1282
1283static const struct snd_kcontrol_new sb_tx4_mux =
1284 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
1285
1286static const struct snd_kcontrol_new sb_tx5_mux =
1287 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
1288
1289static const struct snd_kcontrol_new sb_tx6_mux =
1290 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
1291
1292static const struct snd_kcontrol_new sb_tx7_mux =
1293 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
1294
1295static const struct snd_kcontrol_new sb_tx8_mux =
1296 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
1297
1298static const struct snd_kcontrol_new sb_tx9_mux =
1299 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
1300
1301static const struct snd_kcontrol_new sb_tx10_mux =
1302 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
1303
1304
1305static int wcd9320_put_dec_enum(struct snd_kcontrol *kcontrol,
1306 struct snd_ctl_elem_value *ucontrol)
1307{
1308 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1309 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1310 struct snd_soc_codec *codec = w->codec;
1311 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1312 unsigned int dec_mux, decimator;
1313 char *dec_name = NULL;
1314 char *widget_name = NULL;
1315 char *temp;
1316 u16 tx_mux_ctl_reg;
1317 u8 adc_dmic_sel = 0x0;
1318 int ret = 0;
1319
1320 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1321 return -EINVAL;
1322
1323 dec_mux = ucontrol->value.enumerated.item[0];
1324
1325 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
1326 if (!widget_name)
1327 return -ENOMEM;
1328 temp = widget_name;
1329
1330 dec_name = strsep(&widget_name, " ");
1331 widget_name = temp;
1332 if (!dec_name) {
1333 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
1334 ret = -EINVAL;
1335 goto out;
1336 }
1337
1338 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
1339 if (ret < 0) {
1340 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
1341 ret = -EINVAL;
1342 goto out;
1343 }
1344
1345 dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
1346 , __func__, w->name, decimator, dec_mux);
1347
1348
1349 switch (decimator) {
1350 case 1:
1351 case 2:
1352 case 3:
1353 case 4:
1354 case 5:
1355 case 6:
1356 if (dec_mux == 1)
1357 adc_dmic_sel = 0x1;
1358 else
1359 adc_dmic_sel = 0x0;
1360 break;
1361 case 7:
1362 case 8:
1363 case 9:
1364 case 10:
1365 if ((dec_mux == 1) || (dec_mux == 2))
1366 adc_dmic_sel = 0x1;
1367 else
1368 adc_dmic_sel = 0x0;
1369 break;
1370 default:
1371 pr_err("%s: Invalid Decimator = %u\n", __func__, decimator);
1372 ret = -EINVAL;
1373 goto out;
1374 }
1375
1376 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
1377
1378 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
1379
1380 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
1381
1382out:
1383 kfree(widget_name);
1384 return ret;
1385}
1386
1387#define WCD9320_DEC_ENUM(xname, xenum) \
1388{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1389 .info = snd_soc_info_enum_double, \
1390 .get = snd_soc_dapm_get_enum_double, \
1391 .put = wcd9320_put_dec_enum, \
1392 .private_value = (unsigned long)&xenum }
1393
1394static const struct snd_kcontrol_new dec1_mux =
1395 WCD9320_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
1396
1397static const struct snd_kcontrol_new dec2_mux =
1398 WCD9320_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
1399
1400static const struct snd_kcontrol_new dec3_mux =
1401 WCD9320_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum);
1402
1403static const struct snd_kcontrol_new dec4_mux =
1404 WCD9320_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum);
1405
1406static const struct snd_kcontrol_new dec5_mux =
1407 WCD9320_DEC_ENUM("DEC5 MUX Mux", dec5_mux_enum);
1408
1409static const struct snd_kcontrol_new dec6_mux =
1410 WCD9320_DEC_ENUM("DEC6 MUX Mux", dec6_mux_enum);
1411
1412static const struct snd_kcontrol_new dec7_mux =
1413 WCD9320_DEC_ENUM("DEC7 MUX Mux", dec7_mux_enum);
1414
1415static const struct snd_kcontrol_new dec8_mux =
1416 WCD9320_DEC_ENUM("DEC8 MUX Mux", dec8_mux_enum);
1417
1418static const struct snd_kcontrol_new dec9_mux =
1419 WCD9320_DEC_ENUM("DEC9 MUX Mux", dec9_mux_enum);
1420
1421static const struct snd_kcontrol_new dec10_mux =
1422 WCD9320_DEC_ENUM("DEC10 MUX Mux", dec10_mux_enum);
1423
1424static const struct snd_kcontrol_new iir1_inp1_mux =
1425 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
1426
1427static const struct snd_kcontrol_new anc1_mux =
1428 SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
1429
1430static const struct snd_kcontrol_new anc2_mux =
1431 SOC_DAPM_ENUM("ANC2 MUX Mux", anc2_mux_enum);
1432
1433static const struct snd_kcontrol_new anc1_fb_mux =
1434 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
1435
1436static const struct snd_kcontrol_new dac1_switch[] = {
1437 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_EAR_EN, 5, 1, 0)
1438};
1439static const struct snd_kcontrol_new hphl_switch[] = {
1440 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
1441};
1442
1443static const struct snd_kcontrol_new hphl_pa_mix[] = {
1444 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1445 7, 1, 0),
1446};
1447
1448static const struct snd_kcontrol_new hphr_pa_mix[] = {
1449 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1450 6, 1, 0),
1451};
1452
1453static const struct snd_kcontrol_new ear_pa_mix[] = {
1454 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1455 5, 1, 0),
1456};
1457static const struct snd_kcontrol_new lineout1_pa_mix[] = {
1458 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1459 4, 1, 0),
1460};
1461
1462static const struct snd_kcontrol_new lineout2_pa_mix[] = {
1463 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1464 3, 1, 0),
1465};
1466
1467static const struct snd_kcontrol_new lineout3_pa_mix[] = {
1468 SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1469 2, 1, 0),
1470};
1471
1472static const struct snd_kcontrol_new lineout4_pa_mix[] = {
1473 SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAIKO_A_RX_PA_AUX_IN_CONN,
1474 1, 1, 0),
1475};
1476
1477static const struct snd_kcontrol_new lineout3_ground_switch =
1478 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_3_DAC_CTL, 6, 1, 0);
1479
1480static const struct snd_kcontrol_new lineout4_ground_switch =
1481 SOC_DAPM_SINGLE("Switch", TAIKO_A_RX_LINE_4_DAC_CTL, 6, 1, 0);
1482
Kuirong Wang906ac472012-07-09 12:54:44 -07001483/* virtual port entries */
1484static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
1485 struct snd_ctl_elem_value *ucontrol)
1486{
1487 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1488 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1489
1490 ucontrol->value.integer.value[0] = widget->value;
1491 return 0;
1492}
1493
1494static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
1495 struct snd_ctl_elem_value *ucontrol)
1496{
1497 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1498 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1499 struct snd_soc_codec *codec = widget->codec;
1500 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
1501 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
1502 struct soc_multi_mixer_control *mixer =
1503 ((struct soc_multi_mixer_control *)kcontrol->private_value);
1504 u32 dai_id = widget->shift;
1505 u32 port_id = mixer->shift;
1506 u32 enable = ucontrol->value.integer.value[0];
1507
1508
1509 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
1510 widget->name, ucontrol->id.name, widget->value, widget->shift,
1511 ucontrol->value.integer.value[0]);
1512
1513 mutex_lock(&codec->mutex);
1514
1515 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
1516 if (dai_id != AIF1_CAP) {
1517 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
1518 __func__);
1519 mutex_unlock(&codec->mutex);
1520 return -EINVAL;
1521 }
1522 }
1523 switch (dai_id) {
1524 case AIF1_CAP:
1525 case AIF2_CAP:
1526 case AIF3_CAP:
1527 /* only add to the list if value not set
1528 */
1529 if (enable && !(widget->value & 1 << port_id)) {
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001530 if (wcd9xxx_tx_vport_validation(
1531 vport_check_table[dai_id],
1532 port_id,
1533 taiko_p->dai)) {
Kuirong Wang906ac472012-07-09 12:54:44 -07001534 pr_info("%s: TX%u is used by other virtual port\n",
1535 __func__, port_id + 1);
1536 mutex_unlock(&codec->mutex);
1537 return -EINVAL;
1538 }
1539 widget->value |= 1 << port_id;
1540 list_add_tail(&core->tx_chs[port_id].list,
1541 &taiko_p->dai[dai_id].wcd9xxx_ch_list
1542 );
1543 } else if (!enable && (widget->value & 1 << port_id)) {
1544 widget->value &= ~(1 << port_id);
1545 list_del_init(&core->tx_chs[port_id].list);
1546 } else {
1547 if (enable)
1548 pr_info("%s: TX%u port is used by this virtual port\n",
1549 __func__, port_id + 1);
1550 else
1551 pr_info("%s: TX%u port is not used by this virtual port\n",
1552 __func__, port_id + 1);
1553 /* avoid update power function */
1554 mutex_unlock(&codec->mutex);
1555 return 0;
1556 }
1557 break;
1558 default:
1559 pr_err("Unknown AIF %d\n", dai_id);
1560 mutex_unlock(&codec->mutex);
1561 return -EINVAL;
1562 }
1563 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
1564 widget->name, widget->sname, widget->value, widget->shift);
1565
1566 snd_soc_dapm_mixer_update_power(widget, kcontrol, enable);
1567
1568 mutex_unlock(&codec->mutex);
1569 return 0;
1570}
1571
1572static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
1573 struct snd_ctl_elem_value *ucontrol)
1574{
1575 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1576 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1577
1578 ucontrol->value.enumerated.item[0] = widget->value;
1579 return 0;
1580}
1581
1582static const char *const slim_rx_mux_text[] = {
1583 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
1584};
1585
1586static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
1587 struct snd_ctl_elem_value *ucontrol)
1588{
1589 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1590 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1591 struct snd_soc_codec *codec = widget->codec;
1592 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
1593 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
1594 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1595 u32 port_id = widget->shift;
1596
1597 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
1598 widget->name, ucontrol->id.name, widget->value, widget->shift,
1599 ucontrol->value.integer.value[0]);
1600
1601 widget->value = ucontrol->value.enumerated.item[0];
1602
1603 mutex_lock(&codec->mutex);
1604
1605 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
1606 if (widget->value > 1) {
1607 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
1608 __func__);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001609 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001610 }
1611 }
1612 /* value need to match the Virtual port and AIF number
1613 */
1614 switch (widget->value) {
1615 case 0:
1616 list_del_init(&core->rx_chs[port_id].list);
1617 break;
1618 case 1:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001619 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
1620 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list))
1621 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001622 list_add_tail(&core->rx_chs[port_id].list,
1623 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list);
1624 break;
1625 case 2:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001626 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
1627 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list))
1628 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001629 list_add_tail(&core->rx_chs[port_id].list,
1630 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list);
1631 break;
1632 case 3:
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001633 if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
1634 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list))
1635 goto pr_err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001636 list_add_tail(&core->rx_chs[port_id].list,
1637 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list);
1638 break;
1639 default:
1640 pr_err("Unknown AIF %d\n", widget->value);
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001641 goto err;
Kuirong Wang906ac472012-07-09 12:54:44 -07001642 }
1643
1644 snd_soc_dapm_mux_update_power(widget, kcontrol, 1, widget->value, e);
1645
1646 mutex_unlock(&codec->mutex);
1647 return 0;
Kuirong Wangdcc392e2012-10-19 00:33:38 -07001648pr_err:
1649 pr_err("%s: RX%u is used by current requesting AIF_PB itself\n",
1650 __func__, port_id + 1);
1651err:
1652 mutex_unlock(&codec->mutex);
1653 return -EINVAL;
Kuirong Wang906ac472012-07-09 12:54:44 -07001654}
1655
1656static const struct soc_enum slim_rx_mux_enum =
1657 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
1658
1659static const struct snd_kcontrol_new slim_rx_mux[TAIKO_RX_MAX] = {
1660 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
1661 slim_rx_mux_get, slim_rx_mux_put),
1662 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
1663 slim_rx_mux_get, slim_rx_mux_put),
1664 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
1665 slim_rx_mux_get, slim_rx_mux_put),
1666 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
1667 slim_rx_mux_get, slim_rx_mux_put),
1668 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
1669 slim_rx_mux_get, slim_rx_mux_put),
1670 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
1671 slim_rx_mux_get, slim_rx_mux_put),
1672 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
1673 slim_rx_mux_get, slim_rx_mux_put),
1674};
1675
1676static const struct snd_kcontrol_new aif_cap_mixer[] = {
1677 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TAIKO_TX1, 1, 0,
1678 slim_tx_mixer_get, slim_tx_mixer_put),
1679 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TAIKO_TX2, 1, 0,
1680 slim_tx_mixer_get, slim_tx_mixer_put),
1681 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TAIKO_TX3, 1, 0,
1682 slim_tx_mixer_get, slim_tx_mixer_put),
1683 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TAIKO_TX4, 1, 0,
1684 slim_tx_mixer_get, slim_tx_mixer_put),
1685 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TAIKO_TX5, 1, 0,
1686 slim_tx_mixer_get, slim_tx_mixer_put),
1687 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TAIKO_TX6, 1, 0,
1688 slim_tx_mixer_get, slim_tx_mixer_put),
1689 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TAIKO_TX7, 1, 0,
1690 slim_tx_mixer_get, slim_tx_mixer_put),
1691 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TAIKO_TX8, 1, 0,
1692 slim_tx_mixer_get, slim_tx_mixer_put),
1693 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TAIKO_TX9, 1, 0,
1694 slim_tx_mixer_get, slim_tx_mixer_put),
1695 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TAIKO_TX10, 1, 0,
1696 slim_tx_mixer_get, slim_tx_mixer_put),
1697};
1698
Kiran Kandic3b24402012-06-11 00:05:59 -07001699static void taiko_codec_enable_adc_block(struct snd_soc_codec *codec,
1700 int enable)
1701{
1702 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1703
1704 pr_debug("%s %d\n", __func__, enable);
1705
1706 if (enable) {
1707 taiko->adc_count++;
1708 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_CTL, 0x2, 0x2);
1709 } else {
1710 taiko->adc_count--;
1711 if (!taiko->adc_count)
1712 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_CTL,
1713 0x2, 0x0);
1714 }
1715}
1716
1717static int taiko_codec_enable_adc(struct snd_soc_dapm_widget *w,
1718 struct snd_kcontrol *kcontrol, int event)
1719{
1720 struct snd_soc_codec *codec = w->codec;
1721 u16 adc_reg;
1722 u8 init_bit_shift;
1723
1724 pr_debug("%s %d\n", __func__, event);
1725
1726 if (w->reg == TAIKO_A_TX_1_2_EN)
1727 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
1728 else if (w->reg == TAIKO_A_TX_3_4_EN)
1729 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
1730 else if (w->reg == TAIKO_A_TX_5_6_EN)
1731 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
1732 else {
1733 pr_err("%s: Error, invalid adc register\n", __func__);
1734 return -EINVAL;
1735 }
1736
1737 if (w->shift == 3)
1738 init_bit_shift = 6;
1739 else if (w->shift == 7)
1740 init_bit_shift = 7;
1741 else {
1742 pr_err("%s: Error, invalid init bit postion adc register\n",
1743 __func__);
1744 return -EINVAL;
1745 }
1746
1747 switch (event) {
1748 case SND_SOC_DAPM_PRE_PMU:
1749 taiko_codec_enable_adc_block(codec, 1);
1750 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
1751 1 << init_bit_shift);
1752 break;
1753 case SND_SOC_DAPM_POST_PMU:
1754
1755 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
1756
1757 break;
1758 case SND_SOC_DAPM_POST_PMD:
1759 taiko_codec_enable_adc_block(codec, 0);
1760 break;
1761 }
1762 return 0;
1763}
1764
Kiran Kandic3b24402012-06-11 00:05:59 -07001765static int taiko_codec_enable_aux_pga(struct snd_soc_dapm_widget *w,
1766 struct snd_kcontrol *kcontrol, int event)
1767{
1768 struct snd_soc_codec *codec = w->codec;
1769 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1770
1771 pr_debug("%s: %d\n", __func__, event);
1772
1773 switch (event) {
1774 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07001775 WCD9XXX_BCL_LOCK(&taiko->resmgr);
1776 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
1777 WCD9XXX_BANDGAP_AUDIO_MODE);
1778 /* AUX PGA requires RCO or MCLK */
1779 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
1780 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
1781 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07001782 break;
1783
1784 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07001785 WCD9XXX_BCL_LOCK(&taiko->resmgr);
1786 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
1787 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
1788 WCD9XXX_BANDGAP_AUDIO_MODE);
1789 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
1790 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07001791 break;
1792 }
1793 return 0;
1794}
1795
1796static int taiko_codec_enable_lineout(struct snd_soc_dapm_widget *w,
1797 struct snd_kcontrol *kcontrol, int event)
1798{
1799 struct snd_soc_codec *codec = w->codec;
1800 u16 lineout_gain_reg;
1801
1802 pr_debug("%s %d %s\n", __func__, event, w->name);
1803
1804 switch (w->shift) {
1805 case 0:
1806 lineout_gain_reg = TAIKO_A_RX_LINE_1_GAIN;
1807 break;
1808 case 1:
1809 lineout_gain_reg = TAIKO_A_RX_LINE_2_GAIN;
1810 break;
1811 case 2:
1812 lineout_gain_reg = TAIKO_A_RX_LINE_3_GAIN;
1813 break;
1814 case 3:
1815 lineout_gain_reg = TAIKO_A_RX_LINE_4_GAIN;
1816 break;
1817 default:
1818 pr_err("%s: Error, incorrect lineout register value\n",
1819 __func__);
1820 return -EINVAL;
1821 }
1822
1823 switch (event) {
1824 case SND_SOC_DAPM_PRE_PMU:
1825 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
1826 break;
1827 case SND_SOC_DAPM_POST_PMU:
1828 pr_debug("%s: sleeping 16 ms after %s PA turn on\n",
1829 __func__, w->name);
1830 usleep_range(16000, 16000);
1831 break;
1832 case SND_SOC_DAPM_POST_PMD:
1833 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
1834 break;
1835 }
1836 return 0;
1837}
1838
Joonwoo Park7680b9f2012-07-13 11:36:48 -07001839static int taiko_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
1840 struct snd_kcontrol *kcontrol, int event)
1841{
1842 pr_debug("%s %d %s\n", __func__, event, w->name);
1843 return 0;
1844}
Kiran Kandic3b24402012-06-11 00:05:59 -07001845
1846static int taiko_codec_enable_dmic(struct snd_soc_dapm_widget *w,
1847 struct snd_kcontrol *kcontrol, int event)
1848{
1849 struct snd_soc_codec *codec = w->codec;
1850 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1851 u8 dmic_clk_en;
1852 u16 dmic_clk_reg;
1853 s32 *dmic_clk_cnt;
1854 unsigned int dmic;
1855 int ret;
1856
1857 ret = kstrtouint(strpbrk(w->name, "123456"), 10, &dmic);
1858 if (ret < 0) {
1859 pr_err("%s: Invalid DMIC line on the codec\n", __func__);
1860 return -EINVAL;
1861 }
1862
1863 switch (dmic) {
1864 case 1:
1865 case 2:
1866 dmic_clk_en = 0x01;
1867 dmic_clk_cnt = &(taiko->dmic_1_2_clk_cnt);
1868 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
1869 pr_debug("%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
1870 __func__, event, dmic, *dmic_clk_cnt);
1871
1872 break;
1873
1874 case 3:
1875 case 4:
1876 dmic_clk_en = 0x10;
1877 dmic_clk_cnt = &(taiko->dmic_3_4_clk_cnt);
1878 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
1879
1880 pr_debug("%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n",
1881 __func__, event, dmic, *dmic_clk_cnt);
1882 break;
1883
1884 case 5:
1885 case 6:
1886 dmic_clk_en = 0x01;
1887 dmic_clk_cnt = &(taiko->dmic_5_6_clk_cnt);
1888 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B2_CTL;
1889
1890 pr_debug("%s() event %d DMIC%d dmic_5_6_clk_cnt %d\n",
1891 __func__, event, dmic, *dmic_clk_cnt);
1892
1893 break;
1894
1895 default:
1896 pr_err("%s: Invalid DMIC Selection\n", __func__);
1897 return -EINVAL;
1898 }
1899
1900 switch (event) {
1901 case SND_SOC_DAPM_PRE_PMU:
1902
1903 (*dmic_clk_cnt)++;
1904 if (*dmic_clk_cnt == 1)
1905 snd_soc_update_bits(codec, dmic_clk_reg,
1906 dmic_clk_en, dmic_clk_en);
1907
1908 break;
1909 case SND_SOC_DAPM_POST_PMD:
1910
1911 (*dmic_clk_cnt)--;
1912 if (*dmic_clk_cnt == 0)
1913 snd_soc_update_bits(codec, dmic_clk_reg,
1914 dmic_clk_en, 0);
1915 break;
1916 }
1917 return 0;
1918}
1919
1920static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
1921 struct snd_kcontrol *kcontrol, int event)
1922{
1923 struct snd_soc_codec *codec = w->codec;
1924 const char *filename;
1925 const struct firmware *fw;
1926 int i;
1927 int ret;
1928 int num_anc_slots;
1929 struct anc_header *anc_head;
1930 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1931 u32 anc_writes_size = 0;
1932 int anc_size_remaining;
1933 u32 *anc_ptr;
1934 u16 reg;
1935 u8 mask, val, old_val;
1936
1937 pr_debug("%s %d\n", __func__, event);
1938 switch (event) {
1939 case SND_SOC_DAPM_PRE_PMU:
1940
1941 filename = "wcd9320/wcd9320_anc.bin";
1942
1943 ret = request_firmware(&fw, filename, codec->dev);
1944 if (ret != 0) {
1945 dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
1946 ret);
1947 return -ENODEV;
1948 }
1949
1950 if (fw->size < sizeof(struct anc_header)) {
1951 dev_err(codec->dev, "Not enough data\n");
1952 release_firmware(fw);
1953 return -ENOMEM;
1954 }
1955
1956 /* First number is the number of register writes */
1957 anc_head = (struct anc_header *)(fw->data);
1958 anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
1959 anc_size_remaining = fw->size - sizeof(struct anc_header);
1960 num_anc_slots = anc_head->num_anc_slots;
1961
1962 if (taiko->anc_slot >= num_anc_slots) {
1963 dev_err(codec->dev, "Invalid ANC slot selected\n");
1964 release_firmware(fw);
1965 return -EINVAL;
1966 }
1967
1968 for (i = 0; i < num_anc_slots; i++) {
1969
1970 if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
1971 dev_err(codec->dev, "Invalid register format\n");
1972 release_firmware(fw);
1973 return -EINVAL;
1974 }
1975 anc_writes_size = (u32)(*anc_ptr);
1976 anc_size_remaining -= sizeof(u32);
1977 anc_ptr += 1;
1978
1979 if (anc_writes_size * TAIKO_PACKED_REG_SIZE
1980 > anc_size_remaining) {
1981 dev_err(codec->dev, "Invalid register format\n");
1982 release_firmware(fw);
1983 return -ENOMEM;
1984 }
1985
1986 if (taiko->anc_slot == i)
1987 break;
1988
1989 anc_size_remaining -= (anc_writes_size *
1990 TAIKO_PACKED_REG_SIZE);
1991 anc_ptr += anc_writes_size;
1992 }
1993 if (i == num_anc_slots) {
1994 dev_err(codec->dev, "Selected ANC slot not present\n");
1995 release_firmware(fw);
1996 return -ENOMEM;
1997 }
1998
1999 for (i = 0; i < anc_writes_size; i++) {
2000 TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
2001 mask, val);
2002 old_val = snd_soc_read(codec, reg);
2003 snd_soc_write(codec, reg, (old_val & ~mask) |
2004 (val & mask));
2005 }
2006 release_firmware(fw);
2007
2008 break;
2009 case SND_SOC_DAPM_POST_PMD:
2010 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
2011 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
2012 break;
2013 }
2014 return 0;
2015}
2016
Kiran Kandic3b24402012-06-11 00:05:59 -07002017static int taiko_codec_enable_micbias(struct snd_soc_dapm_widget *w,
2018 struct snd_kcontrol *kcontrol, int event)
2019{
2020 struct snd_soc_codec *codec = w->codec;
2021 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2022 u16 micb_int_reg;
Kiran Kandic3b24402012-06-11 00:05:59 -07002023 u8 cfilt_sel_val = 0;
2024 char *internal1_text = "Internal1";
2025 char *internal2_text = "Internal2";
2026 char *internal3_text = "Internal3";
Joonwoo Parka8890262012-10-15 12:04:27 -07002027 enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
Kiran Kandic3b24402012-06-11 00:05:59 -07002028
2029 pr_debug("%s %d\n", __func__, event);
2030 switch (w->reg) {
2031 case TAIKO_A_MICB_1_CTL:
2032 micb_int_reg = TAIKO_A_MICB_1_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002033 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias1_cfilt_sel;
2034 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
2035 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
2036 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
Kiran Kandic3b24402012-06-11 00:05:59 -07002037 break;
2038 case TAIKO_A_MICB_2_CTL:
2039 micb_int_reg = TAIKO_A_MICB_2_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002040 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias2_cfilt_sel;
2041 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
2042 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
2043 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
Kiran Kandic3b24402012-06-11 00:05:59 -07002044 break;
2045 case TAIKO_A_MICB_3_CTL:
2046 micb_int_reg = TAIKO_A_MICB_3_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002047 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias3_cfilt_sel;
2048 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
2049 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
2050 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
Kiran Kandic3b24402012-06-11 00:05:59 -07002051 break;
2052 case TAIKO_A_MICB_4_CTL:
Joonwoo Parka8890262012-10-15 12:04:27 -07002053 micb_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
2054 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias4_cfilt_sel;
2055 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_4_ON;
2056 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_4_ON;
2057 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_4_OFF;
Kiran Kandic3b24402012-06-11 00:05:59 -07002058 break;
2059 default:
2060 pr_err("%s: Error, invalid micbias register\n", __func__);
2061 return -EINVAL;
2062 }
2063
2064 switch (event) {
2065 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002066 /* Let MBHC module know so micbias switch to be off */
2067 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002068
2069 snd_soc_update_bits(codec, w->reg, 0x0E, 0x0A);
Joonwoo Parka8890262012-10-15 12:04:27 -07002070 /* Get cfilt */
2071 wcd9xxx_resmgr_cfilt_get(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002072
2073 if (strnstr(w->name, internal1_text, 30))
2074 snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
2075 else if (strnstr(w->name, internal2_text, 30))
2076 snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
2077 else if (strnstr(w->name, internal3_text, 30))
2078 snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
2079
2080 break;
2081 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002082 usleep_range(20000, 20000);
Joonwoo Parka8890262012-10-15 12:04:27 -07002083 /* Let MBHC module know so micbias is on */
2084 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002085 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07002086 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002087 /* Let MBHC module know so micbias switch to be off */
2088 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
Kiran Kandic3b24402012-06-11 00:05:59 -07002089
2090 if (strnstr(w->name, internal1_text, 30))
2091 snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
2092 else if (strnstr(w->name, internal2_text, 30))
2093 snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
2094 else if (strnstr(w->name, internal3_text, 30))
2095 snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
2096
Joonwoo Parka8890262012-10-15 12:04:27 -07002097 /* Put cfilt */
2098 wcd9xxx_resmgr_cfilt_put(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002099 break;
2100 }
2101
2102 return 0;
2103}
2104
2105
2106static void tx_hpf_corner_freq_callback(struct work_struct *work)
2107{
2108 struct delayed_work *hpf_delayed_work;
2109 struct hpf_work *hpf_work;
2110 struct taiko_priv *taiko;
2111 struct snd_soc_codec *codec;
2112 u16 tx_mux_ctl_reg;
2113 u8 hpf_cut_of_freq;
2114
2115 hpf_delayed_work = to_delayed_work(work);
2116 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
2117 taiko = hpf_work->taiko;
2118 codec = hpf_work->taiko->codec;
2119 hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
2120
2121 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL +
2122 (hpf_work->decimator - 1) * 8;
2123
2124 pr_debug("%s(): decimator %u hpf_cut_of_freq 0x%x\n", __func__,
2125 hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
2126
2127 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
2128}
2129
2130#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30
2131#define CF_MIN_3DB_4HZ 0x0
2132#define CF_MIN_3DB_75HZ 0x1
2133#define CF_MIN_3DB_150HZ 0x2
2134
2135static int taiko_codec_enable_dec(struct snd_soc_dapm_widget *w,
2136 struct snd_kcontrol *kcontrol, int event)
2137{
2138 struct snd_soc_codec *codec = w->codec;
2139 unsigned int decimator;
2140 char *dec_name = NULL;
2141 char *widget_name = NULL;
2142 char *temp;
2143 int ret = 0;
2144 u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
2145 u8 dec_hpf_cut_of_freq;
2146 int offset;
2147
2148
2149 pr_debug("%s %d\n", __func__, event);
2150
2151 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
2152 if (!widget_name)
2153 return -ENOMEM;
2154 temp = widget_name;
2155
2156 dec_name = strsep(&widget_name, " ");
2157 widget_name = temp;
2158 if (!dec_name) {
2159 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
2160 ret = -EINVAL;
2161 goto out;
2162 }
2163
2164 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
2165 if (ret < 0) {
2166 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
2167 ret = -EINVAL;
2168 goto out;
2169 }
2170
2171 pr_debug("%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
2172 w->name, dec_name, decimator);
2173
2174 if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
2175 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B1_CTL;
2176 offset = 0;
2177 } else if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL) {
2178 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B2_CTL;
2179 offset = 8;
2180 } else {
2181 pr_err("%s: Error, incorrect dec\n", __func__);
2182 return -EINVAL;
2183 }
2184
2185 tx_vol_ctl_reg = TAIKO_A_CDC_TX1_VOL_CTL_CFG + 8 * (decimator - 1);
2186 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
2187
2188 switch (event) {
2189 case SND_SOC_DAPM_PRE_PMU:
2190
2191 /* Enableable TX digital mute */
2192 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2193
2194 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
2195 1 << w->shift);
2196 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
2197
2198 dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
2199
2200 dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
2201
2202 tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
2203 dec_hpf_cut_of_freq;
2204
2205 if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
2206
2207 /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
2208 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
2209 CF_MIN_3DB_150HZ << 4);
2210 }
2211
2212 /* enable HPF */
2213 snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
2214
2215 break;
2216
2217 case SND_SOC_DAPM_POST_PMU:
2218
2219 /* Disable TX digital mute */
2220 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
2221
2222 if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
2223 CF_MIN_3DB_150HZ) {
2224
2225 schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
2226 msecs_to_jiffies(300));
2227 }
2228 /* apply the digital gain after the decimator is enabled*/
2229 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
2230 snd_soc_write(codec,
2231 tx_digital_gain_reg[w->shift + offset],
2232 snd_soc_read(codec,
2233 tx_digital_gain_reg[w->shift + offset])
2234 );
2235
2236 break;
2237
2238 case SND_SOC_DAPM_PRE_PMD:
2239
2240 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2241 cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
2242 break;
2243
2244 case SND_SOC_DAPM_POST_PMD:
2245
2246 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
2247 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
2248 (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
2249
2250 break;
2251 }
2252out:
2253 kfree(widget_name);
2254 return ret;
2255}
2256
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07002257static int taiko_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07002258 struct snd_kcontrol *kcontrol, int event)
2259{
2260 struct snd_soc_codec *codec = w->codec;
2261
2262 pr_debug("%s %d %s\n", __func__, event, w->name);
2263
2264 switch (event) {
2265 case SND_SOC_DAPM_PRE_PMU:
2266 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
2267 1 << w->shift, 1 << w->shift);
2268 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
2269 1 << w->shift, 0x0);
2270 break;
2271 case SND_SOC_DAPM_POST_PMU:
2272 /* apply the digital gain after the interpolator is enabled*/
2273 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
2274 snd_soc_write(codec,
2275 rx_digital_gain_reg[w->shift],
2276 snd_soc_read(codec,
2277 rx_digital_gain_reg[w->shift])
2278 );
2279 break;
2280 }
2281 return 0;
2282}
2283
2284static int taiko_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
2285 struct snd_kcontrol *kcontrol, int event)
2286{
2287 switch (event) {
2288 case SND_SOC_DAPM_POST_PMU:
2289 case SND_SOC_DAPM_POST_PMD:
2290 usleep_range(1000, 1000);
2291 break;
2292 }
2293 return 0;
2294}
2295
2296static int taiko_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
2297 struct snd_kcontrol *kcontrol, int event)
2298{
2299 struct snd_soc_codec *codec = w->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07002300 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002301
2302 pr_debug("%s %d\n", __func__, event);
2303
2304 switch (event) {
2305 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002306 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
Kiran Kandic3b24402012-06-11 00:05:59 -07002307 break;
2308 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002309 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
Kiran Kandic3b24402012-06-11 00:05:59 -07002310 break;
2311 }
2312 return 0;
2313}
2314static int taiko_hphr_dac_event(struct snd_soc_dapm_widget *w,
2315 struct snd_kcontrol *kcontrol, int event)
2316{
2317 struct snd_soc_codec *codec = w->codec;
2318
2319 pr_debug("%s %s %d\n", __func__, w->name, event);
2320
2321 switch (event) {
2322 case SND_SOC_DAPM_PRE_PMU:
2323 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
2324 break;
2325 case SND_SOC_DAPM_POST_PMD:
2326 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
2327 break;
2328 }
2329 return 0;
2330}
2331
Kiran Kandic3b24402012-06-11 00:05:59 -07002332static int taiko_hph_pa_event(struct snd_soc_dapm_widget *w,
Joonwoo Parka8890262012-10-15 12:04:27 -07002333 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07002334{
2335 struct snd_soc_codec *codec = w->codec;
2336 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07002337 enum wcd9xxx_notify_event e_pre_on, e_post_off;
2338
Kiran Kandi4c56c592012-07-25 11:04:55 -07002339 pr_debug("%s: %s event = %d\n", __func__, w->name, event);
Joonwoo Parka8890262012-10-15 12:04:27 -07002340 if (w->shift == 5) {
2341 e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
2342 e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
2343 } else if (w->shift == 4) {
2344 e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
2345 e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
2346 } else {
2347 pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
2348 return -EINVAL;
2349 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002350
2351 switch (event) {
2352 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002353 /* Let MBHC module know PA is turning on */
2354 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002355 break;
2356
Kiran Kandi4c56c592012-07-25 11:04:55 -07002357 case SND_SOC_DAPM_POST_PMU:
Kiran Kandi4c56c592012-07-25 11:04:55 -07002358 usleep_range(10000, 10000);
2359
2360 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_5, 0x02, 0x00);
2361 snd_soc_update_bits(codec, TAIKO_A_NCP_STATIC, 0x20, 0x00);
2362 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x04, 0x04);
2363 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x08, 0x00);
2364
2365 usleep_range(10, 10);
Kiran Kandi4c56c592012-07-25 11:04:55 -07002366 break;
2367
Kiran Kandic3b24402012-06-11 00:05:59 -07002368 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002369 /* Let MBHC module know PA turned off */
2370 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
2371
2372 /*
2373 * schedule work is required because at the time HPH PA DAPM
Kiran Kandic3b24402012-06-11 00:05:59 -07002374 * event callback is called by DAPM framework, CODEC dapm mutex
2375 * would have been locked while snd_soc_jack_report also
2376 * attempts to acquire same lock.
2377 */
Kiran Kandic3b24402012-06-11 00:05:59 -07002378 pr_debug("%s: sleep 10 ms after %s PA disable.\n", __func__,
Joonwoo Parka8890262012-10-15 12:04:27 -07002379 w->name);
Kiran Kandic3b24402012-06-11 00:05:59 -07002380 usleep_range(10000, 10000);
2381 break;
2382 }
2383 return 0;
2384}
2385
Kiran Kandic3b24402012-06-11 00:05:59 -07002386static const struct snd_soc_dapm_widget taiko_dapm_i2s_widgets[] = {
2387 SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", TAIKO_A_CDC_CLK_RX_I2S_CTL,
2388 4, 0, NULL, 0),
2389 SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", TAIKO_A_CDC_CLK_TX_I2S_CTL, 4,
2390 0, NULL, 0),
2391};
2392
2393static int taiko_lineout_dac_event(struct snd_soc_dapm_widget *w,
2394 struct snd_kcontrol *kcontrol, int event)
2395{
2396 struct snd_soc_codec *codec = w->codec;
2397
2398 pr_debug("%s %s %d\n", __func__, w->name, event);
2399
2400 switch (event) {
2401 case SND_SOC_DAPM_PRE_PMU:
2402 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
2403 break;
2404
2405 case SND_SOC_DAPM_POST_PMD:
2406 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
2407 break;
2408 }
2409 return 0;
2410}
2411
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002412static int taiko_spk_dac_event(struct snd_soc_dapm_widget *w,
2413 struct snd_kcontrol *kcontrol, int event)
2414{
2415 pr_debug("%s %s %d\n", __func__, w->name, event);
2416 return 0;
2417}
2418
Kiran Kandic3b24402012-06-11 00:05:59 -07002419static const struct snd_soc_dapm_route audio_i2s_map[] = {
2420 {"RX_I2S_CLK", NULL, "CDC_CONN"},
2421 {"SLIM RX1", NULL, "RX_I2S_CLK"},
2422 {"SLIM RX2", NULL, "RX_I2S_CLK"},
2423 {"SLIM RX3", NULL, "RX_I2S_CLK"},
2424 {"SLIM RX4", NULL, "RX_I2S_CLK"},
2425
2426 {"SLIM TX7", NULL, "TX_I2S_CLK"},
2427 {"SLIM TX8", NULL, "TX_I2S_CLK"},
2428 {"SLIM TX9", NULL, "TX_I2S_CLK"},
2429 {"SLIM TX10", NULL, "TX_I2S_CLK"},
2430};
2431
2432static const struct snd_soc_dapm_route audio_map[] = {
2433 /* SLIMBUS Connections */
Kuirong Wang906ac472012-07-09 12:54:44 -07002434 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
2435 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
2436 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002437
Kuirong Wang906ac472012-07-09 12:54:44 -07002438 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
2439 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
2440 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
2441 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
2442 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
2443 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
2444 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
2445 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
2446 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
2447 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
2448 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
2449 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
2450 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
2451 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
2452 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
2453 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
2454 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
2455 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
2456 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
2457 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
2458 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
2459 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
2460 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
2461 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
2462 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
2463 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
2464 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
2465 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
2466 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
2467 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
2468 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
2469 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
2470 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
2471
Kiran Kandic3b24402012-06-11 00:05:59 -07002472 {"SLIM TX1 MUX", "DEC1", "DEC1 MUX"},
2473
Kiran Kandic3b24402012-06-11 00:05:59 -07002474 {"SLIM TX2 MUX", "DEC2", "DEC2 MUX"},
2475
Kiran Kandic3b24402012-06-11 00:05:59 -07002476 {"SLIM TX3 MUX", "DEC3", "DEC3 MUX"},
2477 {"SLIM TX3 MUX", "RMIX1", "RX1 MIX1"},
2478 {"SLIM TX3 MUX", "RMIX2", "RX2 MIX1"},
2479 {"SLIM TX3 MUX", "RMIX3", "RX3 MIX1"},
2480 {"SLIM TX3 MUX", "RMIX4", "RX4 MIX1"},
2481 {"SLIM TX3 MUX", "RMIX5", "RX5 MIX1"},
2482 {"SLIM TX3 MUX", "RMIX6", "RX6 MIX1"},
2483 {"SLIM TX3 MUX", "RMIX7", "RX7 MIX1"},
2484
Kiran Kandic3b24402012-06-11 00:05:59 -07002485 {"SLIM TX4 MUX", "DEC4", "DEC4 MUX"},
2486
Kiran Kandic3b24402012-06-11 00:05:59 -07002487 {"SLIM TX5 MUX", "DEC5", "DEC5 MUX"},
2488 {"SLIM TX5 MUX", "RMIX1", "RX1 MIX1"},
2489 {"SLIM TX5 MUX", "RMIX2", "RX2 MIX1"},
2490 {"SLIM TX5 MUX", "RMIX3", "RX3 MIX1"},
2491 {"SLIM TX5 MUX", "RMIX4", "RX4 MIX1"},
2492 {"SLIM TX5 MUX", "RMIX5", "RX5 MIX1"},
2493 {"SLIM TX5 MUX", "RMIX6", "RX6 MIX1"},
2494 {"SLIM TX5 MUX", "RMIX7", "RX7 MIX1"},
2495
Kiran Kandic3b24402012-06-11 00:05:59 -07002496 {"SLIM TX6 MUX", "DEC6", "DEC6 MUX"},
2497
Kiran Kandic3b24402012-06-11 00:05:59 -07002498 {"SLIM TX7 MUX", "DEC1", "DEC1 MUX"},
2499 {"SLIM TX7 MUX", "DEC2", "DEC2 MUX"},
2500 {"SLIM TX7 MUX", "DEC3", "DEC3 MUX"},
2501 {"SLIM TX7 MUX", "DEC4", "DEC4 MUX"},
2502 {"SLIM TX7 MUX", "DEC5", "DEC5 MUX"},
2503 {"SLIM TX7 MUX", "DEC6", "DEC6 MUX"},
2504 {"SLIM TX7 MUX", "DEC7", "DEC7 MUX"},
2505 {"SLIM TX7 MUX", "DEC8", "DEC8 MUX"},
2506 {"SLIM TX7 MUX", "DEC9", "DEC9 MUX"},
2507 {"SLIM TX7 MUX", "DEC10", "DEC10 MUX"},
2508 {"SLIM TX7 MUX", "RMIX1", "RX1 MIX1"},
2509 {"SLIM TX7 MUX", "RMIX2", "RX2 MIX1"},
2510 {"SLIM TX7 MUX", "RMIX3", "RX3 MIX1"},
2511 {"SLIM TX7 MUX", "RMIX4", "RX4 MIX1"},
2512 {"SLIM TX7 MUX", "RMIX5", "RX5 MIX1"},
2513 {"SLIM TX7 MUX", "RMIX6", "RX6 MIX1"},
2514 {"SLIM TX7 MUX", "RMIX7", "RX7 MIX1"},
2515
Kiran Kandic3b24402012-06-11 00:05:59 -07002516 {"SLIM TX8 MUX", "DEC1", "DEC1 MUX"},
2517 {"SLIM TX8 MUX", "DEC2", "DEC2 MUX"},
2518 {"SLIM TX8 MUX", "DEC3", "DEC3 MUX"},
2519 {"SLIM TX8 MUX", "DEC4", "DEC4 MUX"},
2520 {"SLIM TX8 MUX", "DEC5", "DEC5 MUX"},
2521 {"SLIM TX8 MUX", "DEC6", "DEC6 MUX"},
2522 {"SLIM TX8 MUX", "DEC7", "DEC7 MUX"},
2523 {"SLIM TX8 MUX", "DEC8", "DEC8 MUX"},
2524 {"SLIM TX8 MUX", "DEC9", "DEC9 MUX"},
2525 {"SLIM TX8 MUX", "DEC10", "DEC10 MUX"},
2526
Kiran Kandic3b24402012-06-11 00:05:59 -07002527 {"SLIM TX9 MUX", "DEC1", "DEC1 MUX"},
2528 {"SLIM TX9 MUX", "DEC2", "DEC2 MUX"},
2529 {"SLIM TX9 MUX", "DEC3", "DEC3 MUX"},
2530 {"SLIM TX9 MUX", "DEC4", "DEC4 MUX"},
2531 {"SLIM TX9 MUX", "DEC5", "DEC5 MUX"},
2532 {"SLIM TX9 MUX", "DEC6", "DEC6 MUX"},
2533 {"SLIM TX9 MUX", "DEC7", "DEC7 MUX"},
2534 {"SLIM TX9 MUX", "DEC8", "DEC8 MUX"},
2535 {"SLIM TX9 MUX", "DEC9", "DEC9 MUX"},
2536 {"SLIM TX9 MUX", "DEC10", "DEC10 MUX"},
2537
Kiran Kandic3b24402012-06-11 00:05:59 -07002538 {"SLIM TX10 MUX", "DEC1", "DEC1 MUX"},
2539 {"SLIM TX10 MUX", "DEC2", "DEC2 MUX"},
2540 {"SLIM TX10 MUX", "DEC3", "DEC3 MUX"},
2541 {"SLIM TX10 MUX", "DEC4", "DEC4 MUX"},
2542 {"SLIM TX10 MUX", "DEC5", "DEC5 MUX"},
2543 {"SLIM TX10 MUX", "DEC6", "DEC6 MUX"},
2544 {"SLIM TX10 MUX", "DEC7", "DEC7 MUX"},
2545 {"SLIM TX10 MUX", "DEC8", "DEC8 MUX"},
2546 {"SLIM TX10 MUX", "DEC9", "DEC9 MUX"},
2547 {"SLIM TX10 MUX", "DEC10", "DEC10 MUX"},
2548
2549 /* Earpiece (RX MIX1) */
2550 {"EAR", NULL, "EAR PA"},
2551 {"EAR PA", NULL, "EAR_PA_MIXER"},
2552 {"EAR_PA_MIXER", NULL, "DAC1"},
2553 {"DAC1", NULL, "CP"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07002554 {"CP", NULL, "CLASS_H_EAR"},
2555 {"CLASS_H_EAR", NULL, "CLASS_H_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002556
2557 {"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
2558 {"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
2559 {"ANC", NULL, "ANC1 FB MUX"},
2560
2561 /* Headset (RX MIX1 and RX MIX2) */
2562 {"HEADPHONE", NULL, "HPHL"},
2563 {"HEADPHONE", NULL, "HPHR"},
2564
2565 {"HPHL", NULL, "HPHL_PA_MIXER"},
2566 {"HPHL_PA_MIXER", NULL, "HPHL DAC"},
2567
2568 {"HPHR", NULL, "HPHR_PA_MIXER"},
2569 {"HPHR_PA_MIXER", NULL, "HPHR DAC"},
2570
2571 {"HPHL DAC", NULL, "CP"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07002572 {"CP", NULL, "CLASS_H_HPH_L"},
2573 {"CLASS_H_HPH_L", NULL, "CLASS_H_CLK"},
2574
Kiran Kandic3b24402012-06-11 00:05:59 -07002575 {"HPHR DAC", NULL, "CP"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07002576 {"CP", NULL, "CLASS_H_HPH_R"},
2577 {"CLASS_H_HPH_R", NULL, "CLASS_H_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002578
2579 {"ANC", NULL, "ANC1 MUX"},
2580 {"ANC", NULL, "ANC2 MUX"},
2581 {"ANC1 MUX", "ADC1", "ADC1"},
2582 {"ANC1 MUX", "ADC2", "ADC2"},
2583 {"ANC1 MUX", "ADC3", "ADC3"},
2584 {"ANC1 MUX", "ADC4", "ADC4"},
2585 {"ANC2 MUX", "ADC1", "ADC1"},
2586 {"ANC2 MUX", "ADC2", "ADC2"},
2587 {"ANC2 MUX", "ADC3", "ADC3"},
2588 {"ANC2 MUX", "ADC4", "ADC4"},
2589
2590 {"ANC", NULL, "CDC_CONN"},
2591
2592 {"DAC1", "Switch", "RX1 CHAIN"},
2593 {"HPHL DAC", "Switch", "RX1 CHAIN"},
2594 {"HPHR DAC", NULL, "RX2 CHAIN"},
2595
2596 {"LINEOUT1", NULL, "LINEOUT1 PA"},
2597 {"LINEOUT2", NULL, "LINEOUT2 PA"},
2598 {"LINEOUT3", NULL, "LINEOUT3 PA"},
2599 {"LINEOUT4", NULL, "LINEOUT4 PA"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002600 {"SPK_OUT", NULL, "SPK PA"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002601
2602 {"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
2603 {"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
2604 {"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
2605 {"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
2606 {"LINEOUT3 PA", NULL, "LINEOUT3_PA_MIXER"},
2607 {"LINEOUT3_PA_MIXER", NULL, "LINEOUT3 DAC"},
2608 {"LINEOUT4 PA", NULL, "LINEOUT4_PA_MIXER"},
2609 {"LINEOUT4_PA_MIXER", NULL, "LINEOUT4 DAC"},
2610
2611 {"LINEOUT1 DAC", NULL, "RX3 MIX1"},
2612
2613 {"RX4 DSM MUX", "DSM_INV", "RX3 MIX1"},
2614 {"RX4 DSM MUX", "CIC_OUT", "RX4 MIX1"},
2615 {"LINEOUT3 DAC", NULL, "RX4 DSM MUX"},
2616
2617 {"LINEOUT2 DAC", NULL, "RX5 MIX1"},
2618
2619 {"RX6 DSM MUX", "DSM_INV", "RX5 MIX1"},
2620 {"RX6 DSM MUX", "CIC_OUT", "RX6 MIX1"},
2621 {"LINEOUT4 DAC", NULL, "RX6 DSM MUX"},
2622
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002623 {"SPK PA", NULL, "SPK DAC"},
Kiran Kandid2b46332012-10-05 12:04:00 -07002624 {"SPK DAC", NULL, "RX7 MIX2"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002625
Kiran Kandic3b24402012-06-11 00:05:59 -07002626 {"RX1 CHAIN", NULL, "RX1 MIX2"},
2627 {"RX2 CHAIN", NULL, "RX2 MIX2"},
2628 {"RX1 CHAIN", NULL, "ANC"},
2629 {"RX2 CHAIN", NULL, "ANC"},
2630
Kiran Kandi4c56c592012-07-25 11:04:55 -07002631 {"CLASS_H_CLK", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002632 {"LINEOUT1 DAC", NULL, "RX_BIAS"},
2633 {"LINEOUT2 DAC", NULL, "RX_BIAS"},
2634 {"LINEOUT3 DAC", NULL, "RX_BIAS"},
2635 {"LINEOUT4 DAC", NULL, "RX_BIAS"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002636 {"SPK DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002637
2638 {"RX1 MIX1", NULL, "COMP1_CLK"},
2639 {"RX2 MIX1", NULL, "COMP1_CLK"},
2640 {"RX3 MIX1", NULL, "COMP2_CLK"},
2641 {"RX5 MIX1", NULL, "COMP2_CLK"},
2642
Kiran Kandic3b24402012-06-11 00:05:59 -07002643 {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
2644 {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
2645 {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
2646 {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
2647 {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
2648 {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
2649 {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
2650 {"RX4 MIX1", NULL, "RX4 MIX1 INP1"},
2651 {"RX4 MIX1", NULL, "RX4 MIX1 INP2"},
2652 {"RX5 MIX1", NULL, "RX5 MIX1 INP1"},
2653 {"RX5 MIX1", NULL, "RX5 MIX1 INP2"},
2654 {"RX6 MIX1", NULL, "RX6 MIX1 INP1"},
2655 {"RX6 MIX1", NULL, "RX6 MIX1 INP2"},
2656 {"RX7 MIX1", NULL, "RX7 MIX1 INP1"},
2657 {"RX7 MIX1", NULL, "RX7 MIX1 INP2"},
2658 {"RX1 MIX2", NULL, "RX1 MIX1"},
2659 {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
2660 {"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
2661 {"RX2 MIX2", NULL, "RX2 MIX1"},
2662 {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
2663 {"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
2664 {"RX7 MIX2", NULL, "RX7 MIX1"},
2665 {"RX7 MIX2", NULL, "RX7 MIX2 INP1"},
2666 {"RX7 MIX2", NULL, "RX7 MIX2 INP2"},
2667
Kuirong Wang906ac472012-07-09 12:54:44 -07002668 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
2669 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
2670 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
2671 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
2672 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
2673 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
2674 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
2675 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
2676 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
2677 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
2678 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
2679 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
2680 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
2681 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
2682 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
2683 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
2684 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
2685 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
2686 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
2687 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
2688 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
2689 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
2690 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
2691 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
2692
2693 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
2694 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
2695 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
2696 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
2697 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
2698 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
2699 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
2700
Kiran Kandic3b24402012-06-11 00:05:59 -07002701 {"RX1 MIX1 INP1", "RX1", "SLIM RX1"},
2702 {"RX1 MIX1 INP1", "RX2", "SLIM RX2"},
2703 {"RX1 MIX1 INP1", "RX3", "SLIM RX3"},
2704 {"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
2705 {"RX1 MIX1 INP1", "RX5", "SLIM RX5"},
2706 {"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
2707 {"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
2708 {"RX1 MIX1 INP1", "IIR1", "IIR1"},
2709 {"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
2710 {"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
2711 {"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
2712 {"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
2713 {"RX1 MIX1 INP2", "RX5", "SLIM RX5"},
2714 {"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
2715 {"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
2716 {"RX1 MIX1 INP2", "IIR1", "IIR1"},
2717 {"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
2718 {"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
2719 {"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
2720 {"RX1 MIX1 INP3", "RX4", "SLIM RX4"},
2721 {"RX1 MIX1 INP3", "RX5", "SLIM RX5"},
2722 {"RX1 MIX1 INP3", "RX6", "SLIM RX6"},
2723 {"RX1 MIX1 INP3", "RX7", "SLIM RX7"},
2724 {"RX2 MIX1 INP1", "RX1", "SLIM RX1"},
2725 {"RX2 MIX1 INP1", "RX2", "SLIM RX2"},
2726 {"RX2 MIX1 INP1", "RX3", "SLIM RX3"},
2727 {"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
2728 {"RX2 MIX1 INP1", "RX5", "SLIM RX5"},
2729 {"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
2730 {"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
2731 {"RX2 MIX1 INP1", "IIR1", "IIR1"},
2732 {"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
2733 {"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
2734 {"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
2735 {"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
2736 {"RX2 MIX1 INP2", "RX5", "SLIM RX5"},
2737 {"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
2738 {"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
2739 {"RX2 MIX1 INP2", "IIR1", "IIR1"},
2740 {"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
2741 {"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
2742 {"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
2743 {"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
2744 {"RX3 MIX1 INP1", "RX5", "SLIM RX5"},
2745 {"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
2746 {"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
2747 {"RX3 MIX1 INP1", "IIR1", "IIR1"},
2748 {"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
2749 {"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
2750 {"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
2751 {"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
2752 {"RX3 MIX1 INP2", "RX5", "SLIM RX5"},
2753 {"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
2754 {"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
2755 {"RX3 MIX1 INP2", "IIR1", "IIR1"},
2756 {"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
2757 {"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
2758 {"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
2759 {"RX4 MIX1 INP1", "RX4", "SLIM RX4"},
2760 {"RX4 MIX1 INP1", "RX5", "SLIM RX5"},
2761 {"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
2762 {"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
2763 {"RX4 MIX1 INP1", "IIR1", "IIR1"},
2764 {"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
2765 {"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
2766 {"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
2767 {"RX4 MIX1 INP2", "RX5", "SLIM RX5"},
2768 {"RX4 MIX1 INP2", "RX4", "SLIM RX4"},
2769 {"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
2770 {"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
2771 {"RX4 MIX1 INP2", "IIR1", "IIR1"},
2772 {"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
2773 {"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
2774 {"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
2775 {"RX5 MIX1 INP1", "RX4", "SLIM RX4"},
2776 {"RX5 MIX1 INP1", "RX5", "SLIM RX5"},
2777 {"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
2778 {"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
2779 {"RX5 MIX1 INP1", "IIR1", "IIR1"},
2780 {"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
2781 {"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
2782 {"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
2783 {"RX5 MIX1 INP2", "RX4", "SLIM RX4"},
2784 {"RX5 MIX1 INP2", "RX5", "SLIM RX5"},
2785 {"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
2786 {"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
2787 {"RX5 MIX1 INP2", "IIR1", "IIR1"},
2788 {"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
2789 {"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
2790 {"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
2791 {"RX6 MIX1 INP1", "RX4", "SLIM RX4"},
2792 {"RX6 MIX1 INP1", "RX5", "SLIM RX5"},
2793 {"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
2794 {"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
2795 {"RX6 MIX1 INP1", "IIR1", "IIR1"},
2796 {"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
2797 {"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
2798 {"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
2799 {"RX6 MIX1 INP2", "RX4", "SLIM RX4"},
2800 {"RX6 MIX1 INP2", "RX5", "SLIM RX5"},
2801 {"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
2802 {"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
2803 {"RX6 MIX1 INP2", "IIR1", "IIR1"},
2804 {"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
2805 {"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
2806 {"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
2807 {"RX7 MIX1 INP1", "RX4", "SLIM RX4"},
2808 {"RX7 MIX1 INP1", "RX5", "SLIM RX5"},
2809 {"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
2810 {"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
2811 {"RX7 MIX1 INP1", "IIR1", "IIR1"},
2812 {"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
2813 {"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
2814 {"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
2815 {"RX7 MIX1 INP2", "RX4", "SLIM RX4"},
2816 {"RX7 MIX1 INP2", "RX5", "SLIM RX5"},
2817 {"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
2818 {"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
2819 {"RX7 MIX1 INP2", "IIR1", "IIR1"},
2820 {"RX1 MIX2 INP1", "IIR1", "IIR1"},
2821 {"RX1 MIX2 INP2", "IIR1", "IIR1"},
2822 {"RX2 MIX2 INP1", "IIR1", "IIR1"},
2823 {"RX2 MIX2 INP2", "IIR1", "IIR1"},
2824 {"RX7 MIX2 INP1", "IIR1", "IIR1"},
2825 {"RX7 MIX2 INP2", "IIR1", "IIR1"},
2826
2827 /* Decimator Inputs */
2828 {"DEC1 MUX", "DMIC1", "DMIC1"},
2829 {"DEC1 MUX", "ADC6", "ADC6"},
2830 {"DEC1 MUX", NULL, "CDC_CONN"},
2831 {"DEC2 MUX", "DMIC2", "DMIC2"},
2832 {"DEC2 MUX", "ADC5", "ADC5"},
2833 {"DEC2 MUX", NULL, "CDC_CONN"},
2834 {"DEC3 MUX", "DMIC3", "DMIC3"},
2835 {"DEC3 MUX", "ADC4", "ADC4"},
2836 {"DEC3 MUX", NULL, "CDC_CONN"},
2837 {"DEC4 MUX", "DMIC4", "DMIC4"},
2838 {"DEC4 MUX", "ADC3", "ADC3"},
2839 {"DEC4 MUX", NULL, "CDC_CONN"},
2840 {"DEC5 MUX", "DMIC5", "DMIC5"},
2841 {"DEC5 MUX", "ADC2", "ADC2"},
2842 {"DEC5 MUX", NULL, "CDC_CONN"},
2843 {"DEC6 MUX", "DMIC6", "DMIC6"},
2844 {"DEC6 MUX", "ADC1", "ADC1"},
2845 {"DEC6 MUX", NULL, "CDC_CONN"},
2846 {"DEC7 MUX", "DMIC1", "DMIC1"},
2847 {"DEC7 MUX", "DMIC6", "DMIC6"},
2848 {"DEC7 MUX", "ADC1", "ADC1"},
2849 {"DEC7 MUX", "ADC6", "ADC6"},
2850 {"DEC7 MUX", NULL, "CDC_CONN"},
2851 {"DEC8 MUX", "DMIC2", "DMIC2"},
2852 {"DEC8 MUX", "DMIC5", "DMIC5"},
2853 {"DEC8 MUX", "ADC2", "ADC2"},
2854 {"DEC8 MUX", "ADC5", "ADC5"},
2855 {"DEC8 MUX", NULL, "CDC_CONN"},
2856 {"DEC9 MUX", "DMIC4", "DMIC4"},
2857 {"DEC9 MUX", "DMIC5", "DMIC5"},
2858 {"DEC9 MUX", "ADC2", "ADC2"},
2859 {"DEC9 MUX", "ADC3", "ADC3"},
2860 {"DEC9 MUX", NULL, "CDC_CONN"},
2861 {"DEC10 MUX", "DMIC3", "DMIC3"},
2862 {"DEC10 MUX", "DMIC6", "DMIC6"},
2863 {"DEC10 MUX", "ADC1", "ADC1"},
2864 {"DEC10 MUX", "ADC4", "ADC4"},
2865 {"DEC10 MUX", NULL, "CDC_CONN"},
2866
2867 /* ADC Connections */
2868 {"ADC1", NULL, "AMIC1"},
2869 {"ADC2", NULL, "AMIC2"},
2870 {"ADC3", NULL, "AMIC3"},
2871 {"ADC4", NULL, "AMIC4"},
2872 {"ADC5", NULL, "AMIC5"},
2873 {"ADC6", NULL, "AMIC6"},
2874
2875 /* AUX PGA Connections */
Kiran Kandic3b24402012-06-11 00:05:59 -07002876 {"EAR_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07002877 {"HPHL_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
2878 {"HPHR_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
2879 {"LINEOUT1_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
2880 {"LINEOUT2_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
2881 {"LINEOUT3_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
2882 {"LINEOUT4_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002883 {"AUX_PGA_Left", NULL, "AMIC5"},
2884 {"AUX_PGA_Right", NULL, "AMIC6"},
2885
Kiran Kandic3b24402012-06-11 00:05:59 -07002886 {"IIR1", NULL, "IIR1 INP1 MUX"},
2887 {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
2888 {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
2889 {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
2890 {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
2891 {"IIR1 INP1 MUX", "DEC5", "DEC5 MUX"},
2892 {"IIR1 INP1 MUX", "DEC6", "DEC6 MUX"},
2893 {"IIR1 INP1 MUX", "DEC7", "DEC7 MUX"},
2894 {"IIR1 INP1 MUX", "DEC8", "DEC8 MUX"},
2895 {"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
2896 {"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
2897
2898 {"MIC BIAS1 Internal1", NULL, "LDO_H"},
2899 {"MIC BIAS1 Internal2", NULL, "LDO_H"},
2900 {"MIC BIAS1 External", NULL, "LDO_H"},
2901 {"MIC BIAS2 Internal1", NULL, "LDO_H"},
2902 {"MIC BIAS2 Internal2", NULL, "LDO_H"},
2903 {"MIC BIAS2 Internal3", NULL, "LDO_H"},
2904 {"MIC BIAS2 External", NULL, "LDO_H"},
2905 {"MIC BIAS3 Internal1", NULL, "LDO_H"},
2906 {"MIC BIAS3 Internal2", NULL, "LDO_H"},
2907 {"MIC BIAS3 External", NULL, "LDO_H"},
2908 {"MIC BIAS4 External", NULL, "LDO_H"},
2909};
2910
2911static int taiko_readable(struct snd_soc_codec *ssc, unsigned int reg)
2912{
2913 return taiko_reg_readable[reg];
2914}
2915
2916static bool taiko_is_digital_gain_register(unsigned int reg)
2917{
2918 bool rtn = false;
2919 switch (reg) {
2920 case TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL:
2921 case TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL:
2922 case TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL:
2923 case TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL:
2924 case TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL:
2925 case TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL:
2926 case TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL:
2927 case TAIKO_A_CDC_TX1_VOL_CTL_GAIN:
2928 case TAIKO_A_CDC_TX2_VOL_CTL_GAIN:
2929 case TAIKO_A_CDC_TX3_VOL_CTL_GAIN:
2930 case TAIKO_A_CDC_TX4_VOL_CTL_GAIN:
2931 case TAIKO_A_CDC_TX5_VOL_CTL_GAIN:
2932 case TAIKO_A_CDC_TX6_VOL_CTL_GAIN:
2933 case TAIKO_A_CDC_TX7_VOL_CTL_GAIN:
2934 case TAIKO_A_CDC_TX8_VOL_CTL_GAIN:
2935 case TAIKO_A_CDC_TX9_VOL_CTL_GAIN:
2936 case TAIKO_A_CDC_TX10_VOL_CTL_GAIN:
2937 rtn = true;
2938 break;
2939 default:
2940 break;
2941 }
2942 return rtn;
2943}
2944
2945static int taiko_volatile(struct snd_soc_codec *ssc, unsigned int reg)
2946{
2947 /* Registers lower than 0x100 are top level registers which can be
2948 * written by the Taiko core driver.
2949 */
2950
2951 if ((reg >= TAIKO_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
2952 return 1;
2953
2954 /* IIR Coeff registers are not cacheable */
2955 if ((reg >= TAIKO_A_CDC_IIR1_COEF_B1_CTL) &&
2956 (reg <= TAIKO_A_CDC_IIR2_COEF_B2_CTL))
2957 return 1;
2958
2959 /* Digital gain register is not cacheable so we have to write
2960 * the setting even it is the same
2961 */
2962 if (taiko_is_digital_gain_register(reg))
2963 return 1;
2964
2965 /* HPH status registers */
2966 if (reg == TAIKO_A_RX_HPH_L_STATUS || reg == TAIKO_A_RX_HPH_R_STATUS)
2967 return 1;
2968
Joonwoo Parka8890262012-10-15 12:04:27 -07002969 if (reg == TAIKO_A_MBHC_INSERT_DET_STATUS)
2970 return 1;
2971
Kiran Kandic3b24402012-06-11 00:05:59 -07002972 return 0;
2973}
2974
2975#define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
2976static int taiko_write(struct snd_soc_codec *codec, unsigned int reg,
2977 unsigned int value)
2978{
2979 int ret;
Kuirong Wang906ac472012-07-09 12:54:44 -07002980
2981 if (reg == SND_SOC_NOPM)
2982 return 0;
2983
Kiran Kandic3b24402012-06-11 00:05:59 -07002984 BUG_ON(reg > TAIKO_MAX_REGISTER);
2985
2986 if (!taiko_volatile(codec, reg)) {
2987 ret = snd_soc_cache_write(codec, reg, value);
2988 if (ret != 0)
2989 dev_err(codec->dev, "Cache write to %x failed: %d\n",
2990 reg, ret);
2991 }
2992
2993 return wcd9xxx_reg_write(codec->control_data, reg, value);
2994}
2995static unsigned int taiko_read(struct snd_soc_codec *codec,
2996 unsigned int reg)
2997{
2998 unsigned int val;
2999 int ret;
3000
Kuirong Wang906ac472012-07-09 12:54:44 -07003001 if (reg == SND_SOC_NOPM)
3002 return 0;
3003
Kiran Kandic3b24402012-06-11 00:05:59 -07003004 BUG_ON(reg > TAIKO_MAX_REGISTER);
3005
3006 if (!taiko_volatile(codec, reg) && taiko_readable(codec, reg) &&
3007 reg < codec->driver->reg_cache_size) {
3008 ret = snd_soc_cache_read(codec, reg, &val);
3009 if (ret >= 0) {
3010 return val;
3011 } else
3012 dev_err(codec->dev, "Cache read from %x failed: %d\n",
3013 reg, ret);
3014 }
3015
3016 val = wcd9xxx_reg_read(codec->control_data, reg);
3017 return val;
3018}
3019
Kiran Kandic3b24402012-06-11 00:05:59 -07003020static int taiko_startup(struct snd_pcm_substream *substream,
3021 struct snd_soc_dai *dai)
3022{
3023 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
3024 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
3025 substream->name, substream->stream);
3026 if ((taiko_core != NULL) &&
3027 (taiko_core->dev != NULL) &&
3028 (taiko_core->dev->parent != NULL))
3029 pm_runtime_get_sync(taiko_core->dev->parent);
3030
3031 return 0;
3032}
3033
3034static void taiko_shutdown(struct snd_pcm_substream *substream,
3035 struct snd_soc_dai *dai)
3036{
3037 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
3038 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
3039 substream->name, substream->stream);
3040 if ((taiko_core != NULL) &&
3041 (taiko_core->dev != NULL) &&
3042 (taiko_core->dev->parent != NULL)) {
3043 pm_runtime_mark_last_busy(taiko_core->dev->parent);
3044 pm_runtime_put(taiko_core->dev->parent);
3045 }
3046}
3047
3048int taiko_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm)
3049{
3050 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3051
3052 pr_debug("%s: mclk_enable = %u, dapm = %d\n", __func__, mclk_enable,
3053 dapm);
Joonwoo Parka8890262012-10-15 12:04:27 -07003054
3055 WCD9XXX_BCL_LOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07003056 if (mclk_enable) {
Joonwoo Parka8890262012-10-15 12:04:27 -07003057 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
3058 WCD9XXX_BANDGAP_AUDIO_MODE);
3059 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
Kiran Kandic3b24402012-06-11 00:05:59 -07003060 } else {
Joonwoo Parka8890262012-10-15 12:04:27 -07003061 /* Put clock and BG */
3062 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
3063 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
3064 WCD9XXX_BANDGAP_AUDIO_MODE);
Kiran Kandic3b24402012-06-11 00:05:59 -07003065 }
Joonwoo Parka8890262012-10-15 12:04:27 -07003066 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
3067
Kiran Kandic3b24402012-06-11 00:05:59 -07003068 return 0;
3069}
3070
3071static int taiko_set_dai_sysclk(struct snd_soc_dai *dai,
3072 int clk_id, unsigned int freq, int dir)
3073{
3074 pr_debug("%s\n", __func__);
3075 return 0;
3076}
3077
3078static int taiko_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3079{
3080 u8 val = 0;
3081 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
3082
3083 pr_debug("%s\n", __func__);
3084 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3085 case SND_SOC_DAIFMT_CBS_CFS:
3086 /* CPU is master */
3087 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3088 if (dai->id == AIF1_CAP)
3089 snd_soc_update_bits(dai->codec,
3090 TAIKO_A_CDC_CLK_TX_I2S_CTL,
3091 TAIKO_I2S_MASTER_MODE_MASK, 0);
3092 else if (dai->id == AIF1_PB)
3093 snd_soc_update_bits(dai->codec,
3094 TAIKO_A_CDC_CLK_RX_I2S_CTL,
3095 TAIKO_I2S_MASTER_MODE_MASK, 0);
3096 }
3097 break;
3098 case SND_SOC_DAIFMT_CBM_CFM:
3099 /* CPU is slave */
3100 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3101 val = TAIKO_I2S_MASTER_MODE_MASK;
3102 if (dai->id == AIF1_CAP)
3103 snd_soc_update_bits(dai->codec,
3104 TAIKO_A_CDC_CLK_TX_I2S_CTL, val, val);
3105 else if (dai->id == AIF1_PB)
3106 snd_soc_update_bits(dai->codec,
3107 TAIKO_A_CDC_CLK_RX_I2S_CTL, val, val);
3108 }
3109 break;
3110 default:
3111 return -EINVAL;
3112 }
3113 return 0;
3114}
3115
3116static int taiko_set_channel_map(struct snd_soc_dai *dai,
3117 unsigned int tx_num, unsigned int *tx_slot,
3118 unsigned int rx_num, unsigned int *rx_slot)
3119
3120{
3121 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07003122 struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07003123 if (!tx_slot && !rx_slot) {
3124 pr_err("%s: Invalid\n", __func__);
3125 return -EINVAL;
3126 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003127 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
3128 "taiko->intf_type %d\n",
3129 __func__, dai->name, dai->id, tx_num, rx_num,
3130 taiko->intf_type);
Kiran Kandic3b24402012-06-11 00:05:59 -07003131
Kuirong Wang906ac472012-07-09 12:54:44 -07003132 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3133 wcd9xxx_init_slimslave(core, core->slim->laddr,
3134 tx_num, tx_slot, rx_num, rx_slot);
3135 return 0;
3136}
3137
3138static int taiko_get_channel_map(struct snd_soc_dai *dai,
3139 unsigned int *tx_num, unsigned int *tx_slot,
3140 unsigned int *rx_num, unsigned int *rx_slot)
3141
3142{
3143 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(dai->codec);
3144 u32 i = 0;
3145 struct wcd9xxx_ch *ch;
3146
3147 switch (dai->id) {
3148 case AIF1_PB:
3149 case AIF2_PB:
3150 case AIF3_PB:
3151 if (!rx_slot || !rx_num) {
3152 pr_err("%s: Invalid rx_slot %d or rx_num %d\n",
3153 __func__, (u32) rx_slot, (u32) rx_num);
3154 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07003155 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003156 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
3157 list) {
Kuirong Wangdcc392e2012-10-19 00:33:38 -07003158 pr_debug("%s: rx_slot[%d] %d, ch->ch_num %d\n",
3159 __func__, i, rx_slot[i], ch->ch_num);
Kuirong Wang906ac472012-07-09 12:54:44 -07003160 rx_slot[i++] = ch->ch_num;
3161 }
3162 pr_debug("%s: rx_num %d\n", __func__, i);
3163 *rx_num = i;
3164 break;
3165 case AIF1_CAP:
3166 case AIF2_CAP:
3167 case AIF3_CAP:
3168 if (!tx_slot || !tx_num) {
3169 pr_err("%s: Invalid tx_slot %d or tx_num %d\n",
3170 __func__, (u32) tx_slot, (u32) tx_num);
3171 return -EINVAL;
3172 }
3173 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
3174 list) {
3175 pr_debug("%s: tx_slot[%d] %d, ch->ch_num %d\n",
3176 __func__, i, tx_slot[i], ch->ch_num);
3177 tx_slot[i++] = ch->ch_num;
3178 }
3179 pr_debug("%s: tx_num %d\n", __func__, i);
3180 *tx_num = i;
3181 break;
3182
3183 default:
3184 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
3185 break;
3186 }
3187
3188 return 0;
3189}
3190
3191static int taiko_set_interpolator_rate(struct snd_soc_dai *dai,
3192 u8 rx_fs_rate_reg_val, u32 compander_fs, u32 sample_rate)
3193{
3194 u32 j;
3195 u8 rx_mix1_inp;
3196 u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
3197 u16 rx_fs_reg;
3198 u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
3199 struct snd_soc_codec *codec = dai->codec;
3200 struct wcd9xxx_ch *ch;
3201 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3202
3203 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
3204 /* for RX port starting from 16 instead of 10 like tabla */
3205 rx_mix1_inp = ch->port + RX_MIX1_INP_SEL_RX1 -
3206 TAIKO_TX_PORT_NUMBER;
3207 if ((rx_mix1_inp < RX_MIX1_INP_SEL_RX1) ||
3208 (rx_mix1_inp > RX_MIX1_INP_SEL_RX7)) {
3209 pr_err("%s: Invalid TAIKO_RX%u port. Dai ID is %d\n",
3210 __func__, rx_mix1_inp - 5 , dai->id);
3211 return -EINVAL;
3212 }
3213
3214 rx_mix_1_reg_1 = TAIKO_A_CDC_CONN_RX1_B1_CTL;
3215
3216 for (j = 0; j < NUM_INTERPOLATORS; j++) {
3217 rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
3218
3219 rx_mix_1_reg_1_val = snd_soc_read(codec,
3220 rx_mix_1_reg_1);
3221 rx_mix_1_reg_2_val = snd_soc_read(codec,
3222 rx_mix_1_reg_2);
3223
3224 if (((rx_mix_1_reg_1_val & 0x0F) == rx_mix1_inp) ||
3225 (((rx_mix_1_reg_1_val >> 4) & 0x0F)
3226 == rx_mix1_inp) ||
3227 ((rx_mix_1_reg_2_val & 0x0F) == rx_mix1_inp)) {
3228
3229 rx_fs_reg = TAIKO_A_CDC_RX1_B5_CTL + 8 * j;
3230
3231 pr_debug("%s: AIF_PB DAI(%d) connected to RX%u\n",
3232 __func__, dai->id, j + 1);
3233
3234 pr_debug("%s: set RX%u sample rate to %u\n",
3235 __func__, j + 1, sample_rate);
3236
3237 snd_soc_update_bits(codec, rx_fs_reg,
3238 0xE0, rx_fs_rate_reg_val);
3239
3240 if (comp_rx_path[j] < COMPANDER_MAX)
3241 taiko->comp_fs[comp_rx_path[j]]
3242 = compander_fs;
3243 }
3244 if (j <= 2)
3245 rx_mix_1_reg_1 += 3;
3246 else
3247 rx_mix_1_reg_1 += 2;
Kiran Kandic3b24402012-06-11 00:05:59 -07003248 }
3249 }
3250 return 0;
3251}
3252
Kuirong Wang906ac472012-07-09 12:54:44 -07003253static int taiko_set_decimator_rate(struct snd_soc_dai *dai,
3254 u8 tx_fs_rate_reg_val, u32 sample_rate)
Kiran Kandic3b24402012-06-11 00:05:59 -07003255{
Kuirong Wang906ac472012-07-09 12:54:44 -07003256 struct snd_soc_codec *codec = dai->codec;
3257 struct wcd9xxx_ch *ch;
3258 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3259 u32 tx_port;
3260 u16 tx_port_reg, tx_fs_reg;
3261 u8 tx_port_reg_val;
3262 s8 decimator;
Kiran Kandic3b24402012-06-11 00:05:59 -07003263
Kuirong Wang906ac472012-07-09 12:54:44 -07003264 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
Kiran Kandic3b24402012-06-11 00:05:59 -07003265
Kuirong Wang906ac472012-07-09 12:54:44 -07003266 tx_port = ch->port + 1;
3267 pr_debug("%s: dai->id = %d, tx_port = %d",
3268 __func__, dai->id, tx_port);
3269
3270 if ((tx_port < 1) || (tx_port > NUM_DECIMATORS)) {
3271 pr_err("%s: Invalid SLIM TX%u port. DAI ID is %d\n",
3272 __func__, tx_port, dai->id);
3273 return -EINVAL;
3274 }
3275
3276 tx_port_reg = TAIKO_A_CDC_CONN_TX_SB_B1_CTL + (tx_port - 1);
3277 tx_port_reg_val = snd_soc_read(codec, tx_port_reg);
3278
3279 decimator = 0;
3280
3281 if ((tx_port >= 1) && (tx_port <= 6)) {
3282
3283 tx_port_reg_val = tx_port_reg_val & 0x0F;
3284 if (tx_port_reg_val == 0x8)
3285 decimator = tx_port;
3286
3287 } else if ((tx_port >= 7) && (tx_port <= NUM_DECIMATORS)) {
3288
3289 tx_port_reg_val = tx_port_reg_val & 0x1F;
3290
3291 if ((tx_port_reg_val >= 0x8) &&
3292 (tx_port_reg_val <= 0x11)) {
3293
3294 decimator = (tx_port_reg_val - 0x8) + 1;
3295 }
3296 }
3297
3298 if (decimator) { /* SLIM_TX port has a DEC as input */
3299
3300 tx_fs_reg = TAIKO_A_CDC_TX1_CLK_FS_CTL +
3301 8 * (decimator - 1);
3302
3303 pr_debug("%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
3304 __func__, decimator, tx_port, sample_rate);
3305
3306 snd_soc_update_bits(codec, tx_fs_reg, 0x07,
3307 tx_fs_rate_reg_val);
3308
3309 } else {
3310 if ((tx_port_reg_val >= 0x1) &&
3311 (tx_port_reg_val <= 0x7)) {
3312
3313 pr_debug("%s: RMIX%u going to SLIM TX%u\n",
3314 __func__, tx_port_reg_val, tx_port);
3315
3316 } else if ((tx_port_reg_val >= 0x8) &&
3317 (tx_port_reg_val <= 0x11)) {
3318
3319 pr_err("%s: ERROR: Should not be here\n",
3320 __func__);
3321 pr_err("%s: ERROR: DEC connected to SLIM TX%u\n",
3322 __func__, tx_port);
3323 return -EINVAL;
3324
3325 } else if (tx_port_reg_val == 0) {
3326 pr_debug("%s: no signal to SLIM TX%u\n",
3327 __func__, tx_port);
3328 } else {
3329 pr_err("%s: ERROR: wrong signal to SLIM TX%u\n",
3330 __func__, tx_port);
3331 pr_err("%s: ERROR: wrong signal = %u\n",
3332 __func__, tx_port_reg_val);
3333 return -EINVAL;
3334 }
3335 }
Kiran Kandic3b24402012-06-11 00:05:59 -07003336 }
Kiran Kandic3b24402012-06-11 00:05:59 -07003337 return 0;
3338}
3339
3340static int taiko_hw_params(struct snd_pcm_substream *substream,
3341 struct snd_pcm_hw_params *params,
3342 struct snd_soc_dai *dai)
3343{
3344 struct snd_soc_codec *codec = dai->codec;
3345 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07003346 u8 tx_fs_rate, rx_fs_rate;
Kiran Kandic3b24402012-06-11 00:05:59 -07003347 u32 compander_fs;
Kuirong Wang906ac472012-07-09 12:54:44 -07003348 int ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07003349
3350 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
3351 dai->name, dai->id, params_rate(params),
3352 params_channels(params));
3353
3354 switch (params_rate(params)) {
3355 case 8000:
3356 tx_fs_rate = 0x00;
3357 rx_fs_rate = 0x00;
3358 compander_fs = COMPANDER_FS_8KHZ;
3359 break;
3360 case 16000:
3361 tx_fs_rate = 0x01;
3362 rx_fs_rate = 0x20;
3363 compander_fs = COMPANDER_FS_16KHZ;
3364 break;
3365 case 32000:
3366 tx_fs_rate = 0x02;
3367 rx_fs_rate = 0x40;
3368 compander_fs = COMPANDER_FS_32KHZ;
3369 break;
3370 case 48000:
3371 tx_fs_rate = 0x03;
3372 rx_fs_rate = 0x60;
3373 compander_fs = COMPANDER_FS_48KHZ;
3374 break;
3375 case 96000:
3376 tx_fs_rate = 0x04;
3377 rx_fs_rate = 0x80;
3378 compander_fs = COMPANDER_FS_96KHZ;
3379 break;
3380 case 192000:
3381 tx_fs_rate = 0x05;
3382 rx_fs_rate = 0xA0;
3383 compander_fs = COMPANDER_FS_192KHZ;
3384 break;
3385 default:
3386 pr_err("%s: Invalid sampling rate %d\n", __func__,
Kuirong Wang906ac472012-07-09 12:54:44 -07003387 params_rate(params));
Kiran Kandic3b24402012-06-11 00:05:59 -07003388 return -EINVAL;
3389 }
3390
Kuirong Wang906ac472012-07-09 12:54:44 -07003391 switch (substream->stream) {
3392 case SNDRV_PCM_STREAM_CAPTURE:
3393 ret = taiko_set_decimator_rate(dai, tx_fs_rate,
3394 params_rate(params));
3395 if (ret < 0) {
3396 pr_err("%s: set decimator rate failed %d\n", __func__,
3397 ret);
3398 return ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07003399 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003400
Kiran Kandic3b24402012-06-11 00:05:59 -07003401 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3402 switch (params_format(params)) {
3403 case SNDRV_PCM_FORMAT_S16_LE:
3404 snd_soc_update_bits(codec,
3405 TAIKO_A_CDC_CLK_TX_I2S_CTL,
3406 0x20, 0x20);
3407 break;
3408 case SNDRV_PCM_FORMAT_S32_LE:
3409 snd_soc_update_bits(codec,
3410 TAIKO_A_CDC_CLK_TX_I2S_CTL,
3411 0x20, 0x00);
3412 break;
3413 default:
3414 pr_err("invalid format\n");
3415 break;
3416 }
3417 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07003418 0x07, tx_fs_rate);
Kiran Kandic3b24402012-06-11 00:05:59 -07003419 } else {
Kuirong Wang906ac472012-07-09 12:54:44 -07003420 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07003421 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003422 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07003423
Kuirong Wang906ac472012-07-09 12:54:44 -07003424 case SNDRV_PCM_STREAM_PLAYBACK:
3425 ret = taiko_set_interpolator_rate(dai, rx_fs_rate,
3426 compander_fs,
3427 params_rate(params));
3428 if (ret < 0) {
3429 pr_err("%s: set decimator rate failed %d\n", __func__,
3430 ret);
3431 return ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07003432 }
3433 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3434 switch (params_format(params)) {
3435 case SNDRV_PCM_FORMAT_S16_LE:
3436 snd_soc_update_bits(codec,
3437 TAIKO_A_CDC_CLK_RX_I2S_CTL,
3438 0x20, 0x20);
3439 break;
3440 case SNDRV_PCM_FORMAT_S32_LE:
3441 snd_soc_update_bits(codec,
3442 TAIKO_A_CDC_CLK_RX_I2S_CTL,
3443 0x20, 0x00);
3444 break;
3445 default:
3446 pr_err("invalid format\n");
3447 break;
3448 }
3449 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07003450 0x03, (rx_fs_rate >> 0x05));
Kiran Kandic3b24402012-06-11 00:05:59 -07003451 } else {
Kuirong Wang906ac472012-07-09 12:54:44 -07003452 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07003453 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003454 break;
3455 default:
3456 pr_err("%s: Invalid stream type %d\n", __func__,
3457 substream->stream);
3458 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07003459 }
3460
3461 return 0;
3462}
3463
3464static struct snd_soc_dai_ops taiko_dai_ops = {
3465 .startup = taiko_startup,
3466 .shutdown = taiko_shutdown,
3467 .hw_params = taiko_hw_params,
3468 .set_sysclk = taiko_set_dai_sysclk,
3469 .set_fmt = taiko_set_dai_fmt,
3470 .set_channel_map = taiko_set_channel_map,
3471 .get_channel_map = taiko_get_channel_map,
3472};
3473
3474static struct snd_soc_dai_driver taiko_dai[] = {
3475 {
3476 .name = "taiko_rx1",
3477 .id = AIF1_PB,
3478 .playback = {
3479 .stream_name = "AIF1 Playback",
3480 .rates = WCD9320_RATES,
3481 .formats = TAIKO_FORMATS,
3482 .rate_max = 192000,
3483 .rate_min = 8000,
3484 .channels_min = 1,
3485 .channels_max = 2,
3486 },
3487 .ops = &taiko_dai_ops,
3488 },
3489 {
3490 .name = "taiko_tx1",
3491 .id = AIF1_CAP,
3492 .capture = {
3493 .stream_name = "AIF1 Capture",
3494 .rates = WCD9320_RATES,
3495 .formats = TAIKO_FORMATS,
3496 .rate_max = 192000,
3497 .rate_min = 8000,
3498 .channels_min = 1,
3499 .channels_max = 4,
3500 },
3501 .ops = &taiko_dai_ops,
3502 },
3503 {
3504 .name = "taiko_rx2",
3505 .id = AIF2_PB,
3506 .playback = {
3507 .stream_name = "AIF2 Playback",
3508 .rates = WCD9320_RATES,
3509 .formats = TAIKO_FORMATS,
3510 .rate_min = 8000,
3511 .rate_max = 192000,
3512 .channels_min = 1,
3513 .channels_max = 2,
3514 },
3515 .ops = &taiko_dai_ops,
3516 },
3517 {
3518 .name = "taiko_tx2",
3519 .id = AIF2_CAP,
3520 .capture = {
3521 .stream_name = "AIF2 Capture",
3522 .rates = WCD9320_RATES,
3523 .formats = TAIKO_FORMATS,
3524 .rate_max = 192000,
3525 .rate_min = 8000,
3526 .channels_min = 1,
3527 .channels_max = 4,
3528 },
3529 .ops = &taiko_dai_ops,
3530 },
3531 {
3532 .name = "taiko_tx3",
3533 .id = AIF3_CAP,
3534 .capture = {
3535 .stream_name = "AIF3 Capture",
3536 .rates = WCD9320_RATES,
3537 .formats = TAIKO_FORMATS,
3538 .rate_max = 48000,
3539 .rate_min = 8000,
3540 .channels_min = 1,
3541 .channels_max = 2,
3542 },
3543 .ops = &taiko_dai_ops,
3544 },
3545 {
3546 .name = "taiko_rx3",
3547 .id = AIF3_PB,
3548 .playback = {
3549 .stream_name = "AIF3 Playback",
3550 .rates = WCD9320_RATES,
3551 .formats = TAIKO_FORMATS,
3552 .rate_min = 8000,
3553 .rate_max = 192000,
3554 .channels_min = 1,
3555 .channels_max = 2,
3556 },
3557 .ops = &taiko_dai_ops,
3558 },
3559};
3560
3561static struct snd_soc_dai_driver taiko_i2s_dai[] = {
3562 {
3563 .name = "taiko_i2s_rx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07003564 .id = AIF1_PB,
Kiran Kandic3b24402012-06-11 00:05:59 -07003565 .playback = {
3566 .stream_name = "AIF1 Playback",
3567 .rates = WCD9320_RATES,
3568 .formats = TAIKO_FORMATS,
3569 .rate_max = 192000,
3570 .rate_min = 8000,
3571 .channels_min = 1,
3572 .channels_max = 4,
3573 },
3574 .ops = &taiko_dai_ops,
3575 },
3576 {
3577 .name = "taiko_i2s_tx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07003578 .id = AIF1_CAP,
Kiran Kandic3b24402012-06-11 00:05:59 -07003579 .capture = {
3580 .stream_name = "AIF1 Capture",
3581 .rates = WCD9320_RATES,
3582 .formats = TAIKO_FORMATS,
3583 .rate_max = 192000,
3584 .rate_min = 8000,
3585 .channels_min = 1,
3586 .channels_max = 4,
3587 },
3588 .ops = &taiko_dai_ops,
3589 },
3590};
3591
3592static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07003593 struct snd_kcontrol *kcontrol,
3594 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07003595{
Kuirong Wang906ac472012-07-09 12:54:44 -07003596 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07003597 struct snd_soc_codec *codec = w->codec;
3598 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003599 u32 ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07003600 struct wcd9xxx_codec_dai_data *dai;
3601
3602 core = dev_get_drvdata(codec->dev->parent);
3603
3604 pr_debug("%s: event called! codec name %s num_dai %d\n"
3605 "stream name %s event %d\n",
3606 __func__, w->codec->name, w->codec->num_dai, w->sname, event);
3607
Kiran Kandic3b24402012-06-11 00:05:59 -07003608 /* Execute the callback only if interface type is slimbus */
3609 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3610 return 0;
3611
Kuirong Wang906ac472012-07-09 12:54:44 -07003612 dai = &taiko_p->dai[w->shift];
3613 pr_debug("%s: w->name %s w->shift %d event %d\n",
3614 __func__, w->name, w->shift, event);
Kiran Kandic3b24402012-06-11 00:05:59 -07003615
3616 switch (event) {
3617 case SND_SOC_DAPM_POST_PMU:
Kuirong Wang906ac472012-07-09 12:54:44 -07003618 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3619 dai->rate, dai->bit_width,
3620 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07003621 break;
3622 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07003623 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3624 dai->grph);
3625 usleep_range(15000, 15000);
3626 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07003627 }
3628 return ret;
3629}
3630
3631static int taiko_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07003632 struct snd_kcontrol *kcontrol,
3633 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07003634{
Kuirong Wang906ac472012-07-09 12:54:44 -07003635 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07003636 struct snd_soc_codec *codec = w->codec;
3637 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003638 u32 ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07003639 struct wcd9xxx_codec_dai_data *dai;
Kiran Kandic3b24402012-06-11 00:05:59 -07003640
Kuirong Wang906ac472012-07-09 12:54:44 -07003641 core = dev_get_drvdata(codec->dev->parent);
3642
3643 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
3644 __func__, w->codec->name, w->codec->num_dai, w->sname);
Kiran Kandic3b24402012-06-11 00:05:59 -07003645
3646 /* Execute the callback only if interface type is slimbus */
3647 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3648 return 0;
3649
Kuirong Wang906ac472012-07-09 12:54:44 -07003650 pr_debug("%s(): w->name %s event %d w->shift %d\n",
3651 __func__, w->name, event, w->shift);
Kiran Kandic3b24402012-06-11 00:05:59 -07003652
Kuirong Wang906ac472012-07-09 12:54:44 -07003653 dai = &taiko_p->dai[w->shift];
Kiran Kandic3b24402012-06-11 00:05:59 -07003654 switch (event) {
3655 case SND_SOC_DAPM_POST_PMU:
Kuirong Wang906ac472012-07-09 12:54:44 -07003656 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3657 dai->rate, dai->bit_width,
3658 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07003659 break;
3660 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07003661 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3662 dai->grph);
3663 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07003664 }
3665 return ret;
3666}
3667
Kiran Kandi4c56c592012-07-25 11:04:55 -07003668static int taiko_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
3669 struct snd_kcontrol *kcontrol, int event)
3670{
3671 struct snd_soc_codec *codec = w->codec;
3672
3673 pr_debug("%s %s %d\n", __func__, w->name, event);
3674
3675 switch (event) {
3676 break;
3677 case SND_SOC_DAPM_POST_PMU:
3678
3679 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_5, 0x02, 0x00);
3680 snd_soc_update_bits(codec, TAIKO_A_NCP_STATIC, 0x20, 0x00);
3681 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x04, 0x04);
3682 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x08, 0x00);
3683
3684 usleep_range(5000, 5000);
3685 break;
3686 }
3687 return 0;
3688}
3689
Kiran Kandic3b24402012-06-11 00:05:59 -07003690/* Todo: Have seperate dapm widgets for I2S and Slimbus.
3691 * Might Need to have callbacks registered only for slimbus
3692 */
3693static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
3694 /*RX stuff */
3695 SND_SOC_DAPM_OUTPUT("EAR"),
3696
Kiran Kandi4c56c592012-07-25 11:04:55 -07003697 SND_SOC_DAPM_PGA_E("EAR PA", TAIKO_A_RX_EAR_EN, 4, 0, NULL, 0,
3698 taiko_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU),
Kiran Kandic3b24402012-06-11 00:05:59 -07003699
3700 SND_SOC_DAPM_MIXER("DAC1", TAIKO_A_RX_EAR_EN, 6, 0, dac1_switch,
3701 ARRAY_SIZE(dac1_switch)),
3702
Kuirong Wang906ac472012-07-09 12:54:44 -07003703 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
3704 AIF1_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07003705 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07003706 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
3707 AIF2_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07003708 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07003709 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
3710 AIF3_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07003711 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3712
Kuirong Wang906ac472012-07-09 12:54:44 -07003713 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TAIKO_RX1, 0,
3714 &slim_rx_mux[TAIKO_RX1]),
3715 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TAIKO_RX2, 0,
3716 &slim_rx_mux[TAIKO_RX2]),
3717 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TAIKO_RX3, 0,
3718 &slim_rx_mux[TAIKO_RX3]),
3719 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TAIKO_RX4, 0,
3720 &slim_rx_mux[TAIKO_RX4]),
3721 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TAIKO_RX5, 0,
3722 &slim_rx_mux[TAIKO_RX5]),
3723 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TAIKO_RX6, 0,
3724 &slim_rx_mux[TAIKO_RX6]),
3725 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TAIKO_RX7, 0,
3726 &slim_rx_mux[TAIKO_RX7]),
Kiran Kandic3b24402012-06-11 00:05:59 -07003727
Kuirong Wang906ac472012-07-09 12:54:44 -07003728 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3729 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3730 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
3731 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
3732 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
3733 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
3734 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
Kiran Kandic3b24402012-06-11 00:05:59 -07003735
3736 /* Headphone */
3737 SND_SOC_DAPM_OUTPUT("HEADPHONE"),
3738 SND_SOC_DAPM_PGA_E("HPHL", TAIKO_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
3739 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07003740 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07003741 SND_SOC_DAPM_MIXER("HPHL DAC", TAIKO_A_RX_HPH_L_DAC_CTL, 7, 0,
3742 hphl_switch, ARRAY_SIZE(hphl_switch)),
3743
3744 SND_SOC_DAPM_PGA_E("HPHR", TAIKO_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
3745 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07003746 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07003747
3748 SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TAIKO_A_RX_HPH_R_DAC_CTL, 7, 0,
3749 taiko_hphr_dac_event,
3750 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3751
3752 /* Speaker */
3753 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
3754 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
3755 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
3756 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003757 SND_SOC_DAPM_OUTPUT("SPK_OUT"),
Kiran Kandic3b24402012-06-11 00:05:59 -07003758
3759 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TAIKO_A_RX_LINE_CNP_EN, 0, 0, NULL,
3760 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
3761 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3762 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TAIKO_A_RX_LINE_CNP_EN, 1, 0, NULL,
3763 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
3764 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3765 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TAIKO_A_RX_LINE_CNP_EN, 2, 0, NULL,
3766 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
3767 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3768 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TAIKO_A_RX_LINE_CNP_EN, 3, 0, NULL,
3769 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
3770 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003771 SND_SOC_DAPM_PGA_E("SPK PA", TAIKO_A_SPKR_DRV_EN, 7, 0 , NULL,
3772 0, taiko_codec_enable_spk_pa, SND_SOC_DAPM_PRE_PMU |
3773 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07003774
3775 SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAIKO_A_RX_LINE_1_DAC_CTL, 7, 0
3776 , taiko_lineout_dac_event,
3777 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3778 SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TAIKO_A_RX_LINE_2_DAC_CTL, 7, 0
3779 , taiko_lineout_dac_event,
3780 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3781 SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TAIKO_A_RX_LINE_3_DAC_CTL, 7, 0
3782 , taiko_lineout_dac_event,
3783 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3784 SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
3785 &lineout3_ground_switch),
3786 SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TAIKO_A_RX_LINE_4_DAC_CTL, 7, 0
3787 , taiko_lineout_dac_event,
3788 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3789 SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
3790 &lineout4_ground_switch),
3791
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003792 SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
3793 taiko_spk_dac_event,
3794 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3795
Kiran Kandid2b46332012-10-05 12:04:00 -07003796 SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3797 SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3798 SND_SOC_DAPM_MIXER("RX7 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3799
Kiran Kandic3b24402012-06-11 00:05:59 -07003800 SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003801 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003802 SND_SOC_DAPM_POST_PMU),
3803 SND_SOC_DAPM_MIXER_E("RX2 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003804 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003805 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07003806 SND_SOC_DAPM_MIXER_E("RX3 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003807 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003808 SND_SOC_DAPM_POST_PMU),
3809 SND_SOC_DAPM_MIXER_E("RX4 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003810 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003811 SND_SOC_DAPM_POST_PMU),
3812 SND_SOC_DAPM_MIXER_E("RX5 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003813 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003814 SND_SOC_DAPM_POST_PMU),
3815 SND_SOC_DAPM_MIXER_E("RX6 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003816 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003817 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07003818 SND_SOC_DAPM_MIXER_E("RX7 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003819 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003820 SND_SOC_DAPM_POST_PMU),
3821
Kiran Kandic3b24402012-06-11 00:05:59 -07003822 SND_SOC_DAPM_MUX_E("RX4 DSM MUX", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003823 &rx4_dsm_mux, taiko_codec_enable_interpolator,
Kiran Kandic3b24402012-06-11 00:05:59 -07003824 SND_SOC_DAPM_PRE_PMU),
3825
3826 SND_SOC_DAPM_MUX_E("RX6 DSM MUX", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003827 &rx6_dsm_mux, taiko_codec_enable_interpolator,
Kiran Kandic3b24402012-06-11 00:05:59 -07003828 SND_SOC_DAPM_PRE_PMU),
3829
3830 SND_SOC_DAPM_MIXER("RX1 CHAIN", TAIKO_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
3831 SND_SOC_DAPM_MIXER("RX2 CHAIN", TAIKO_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
3832
3833 SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3834 &rx_mix1_inp1_mux),
3835 SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3836 &rx_mix1_inp2_mux),
3837 SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
3838 &rx_mix1_inp3_mux),
3839 SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3840 &rx2_mix1_inp1_mux),
3841 SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3842 &rx2_mix1_inp2_mux),
3843 SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3844 &rx3_mix1_inp1_mux),
3845 SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3846 &rx3_mix1_inp2_mux),
3847 SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3848 &rx4_mix1_inp1_mux),
3849 SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3850 &rx4_mix1_inp2_mux),
3851 SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3852 &rx5_mix1_inp1_mux),
3853 SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3854 &rx5_mix1_inp2_mux),
3855 SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3856 &rx6_mix1_inp1_mux),
3857 SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3858 &rx6_mix1_inp2_mux),
3859 SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3860 &rx7_mix1_inp1_mux),
3861 SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3862 &rx7_mix1_inp2_mux),
3863 SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
3864 &rx1_mix2_inp1_mux),
3865 SND_SOC_DAPM_MUX("RX1 MIX2 INP2", SND_SOC_NOPM, 0, 0,
3866 &rx1_mix2_inp2_mux),
3867 SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
3868 &rx2_mix2_inp1_mux),
3869 SND_SOC_DAPM_MUX("RX2 MIX2 INP2", SND_SOC_NOPM, 0, 0,
3870 &rx2_mix2_inp2_mux),
3871 SND_SOC_DAPM_MUX("RX7 MIX2 INP1", SND_SOC_NOPM, 0, 0,
3872 &rx7_mix2_inp1_mux),
3873 SND_SOC_DAPM_MUX("RX7 MIX2 INP2", SND_SOC_NOPM, 0, 0,
3874 &rx7_mix2_inp2_mux),
3875
Kiran Kandi4c56c592012-07-25 11:04:55 -07003876 SND_SOC_DAPM_SUPPLY("CLASS_H_CLK", TAIKO_A_CDC_CLK_OTHR_CTL, 0, 0,
3877 taiko_codec_enable_class_h_clk, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003878 SND_SOC_DAPM_PRE_PMD),
3879
Kiran Kandi4c56c592012-07-25 11:04:55 -07003880 SND_SOC_DAPM_SUPPLY("CLASS_H_EAR", TAIKO_A_CDC_CLSH_B1_CTL, 4, 0,
3881 taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
3882
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003883 SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_L", TAIKO_A_CDC_CLSH_B1_CTL, 3, 0,
Kiran Kandi4c56c592012-07-25 11:04:55 -07003884 taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
3885
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003886 SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_R", TAIKO_A_CDC_CLSH_B1_CTL, 2, 0,
Kiran Kandi4c56c592012-07-25 11:04:55 -07003887 taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
3888
3889 SND_SOC_DAPM_SUPPLY("CP", TAIKO_A_NCP_EN, 0, 0,
3890 taiko_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU |
3891 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
3892
Kiran Kandic3b24402012-06-11 00:05:59 -07003893 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
3894 taiko_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
3895 SND_SOC_DAPM_POST_PMD),
3896
3897 /* TX */
3898
3899 SND_SOC_DAPM_SUPPLY("CDC_CONN", TAIKO_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
3900 0),
3901
3902 SND_SOC_DAPM_SUPPLY("LDO_H", TAIKO_A_LDO_H_MODE_1, 7, 0,
3903 taiko_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
3904
3905 SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 0, 0,
3906 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
3907 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
3908 SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 1, 0,
3909 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
3910 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
3911
3912
3913 SND_SOC_DAPM_INPUT("AMIC1"),
3914 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TAIKO_A_MICB_1_CTL, 7, 0,
3915 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
3916 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3917 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TAIKO_A_MICB_1_CTL, 7, 0,
3918 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
3919 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3920 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TAIKO_A_MICB_1_CTL, 7, 0,
3921 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
3922 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3923 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_TX_1_2_EN, 7, 0,
3924 taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
3925 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3926
3927 SND_SOC_DAPM_INPUT("AMIC3"),
3928 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_TX_3_4_EN, 7, 0,
3929 taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
3930 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3931
3932 SND_SOC_DAPM_INPUT("AMIC4"),
3933 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_TX_3_4_EN, 3, 0,
3934 taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
3935 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3936
3937 SND_SOC_DAPM_INPUT("AMIC5"),
3938 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_TX_5_6_EN, 7, 0,
3939 taiko_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
3940
3941 SND_SOC_DAPM_INPUT("AMIC6"),
3942 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_TX_5_6_EN, 3, 0,
3943 taiko_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
3944
3945 SND_SOC_DAPM_MUX_E("DEC1 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
3946 &dec1_mux, taiko_codec_enable_dec,
3947 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3948 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3949
3950 SND_SOC_DAPM_MUX_E("DEC2 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
3951 &dec2_mux, taiko_codec_enable_dec,
3952 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3953 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3954
3955 SND_SOC_DAPM_MUX_E("DEC3 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
3956 &dec3_mux, taiko_codec_enable_dec,
3957 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3958 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3959
3960 SND_SOC_DAPM_MUX_E("DEC4 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
3961 &dec4_mux, taiko_codec_enable_dec,
3962 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3963 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3964
3965 SND_SOC_DAPM_MUX_E("DEC5 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
3966 &dec5_mux, taiko_codec_enable_dec,
3967 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3968 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3969
3970 SND_SOC_DAPM_MUX_E("DEC6 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
3971 &dec6_mux, taiko_codec_enable_dec,
3972 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3973 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3974
3975 SND_SOC_DAPM_MUX_E("DEC7 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
3976 &dec7_mux, taiko_codec_enable_dec,
3977 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3978 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3979
3980 SND_SOC_DAPM_MUX_E("DEC8 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
3981 &dec8_mux, taiko_codec_enable_dec,
3982 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3983 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3984
3985 SND_SOC_DAPM_MUX_E("DEC9 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
3986 &dec9_mux, taiko_codec_enable_dec,
3987 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3988 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3989
3990 SND_SOC_DAPM_MUX_E("DEC10 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
3991 &dec10_mux, taiko_codec_enable_dec,
3992 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3993 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3994
3995 SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
3996 SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
3997
3998 SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
3999 taiko_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
4000 SND_SOC_DAPM_POST_PMD),
4001
4002 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
4003
4004 SND_SOC_DAPM_INPUT("AMIC2"),
4005 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TAIKO_A_MICB_2_CTL, 7, 0,
4006 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4007 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4008 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TAIKO_A_MICB_2_CTL, 7, 0,
4009 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4010 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4011 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TAIKO_A_MICB_2_CTL, 7, 0,
4012 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4013 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4014 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TAIKO_A_MICB_2_CTL, 7, 0,
4015 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4016 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4017 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TAIKO_A_MICB_3_CTL, 7, 0,
4018 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4019 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4020 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TAIKO_A_MICB_3_CTL, 7, 0,
4021 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4022 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4023 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TAIKO_A_MICB_3_CTL, 7, 0,
4024 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4025 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4026 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TAIKO_A_MICB_4_CTL, 7,
4027 0, taiko_codec_enable_micbias,
4028 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4029 SND_SOC_DAPM_POST_PMD),
4030
4031 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_TX_1_2_EN, 3, 0,
4032 taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
4033 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4034
Kuirong Wang906ac472012-07-09 12:54:44 -07004035 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
4036 AIF1_CAP, 0, taiko_codec_enable_slimtx,
4037 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004038
Kuirong Wang906ac472012-07-09 12:54:44 -07004039 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
4040 AIF2_CAP, 0, taiko_codec_enable_slimtx,
4041 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004042
Kuirong Wang906ac472012-07-09 12:54:44 -07004043 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
4044 AIF3_CAP, 0, taiko_codec_enable_slimtx,
4045 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004046
Kuirong Wang906ac472012-07-09 12:54:44 -07004047 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
4048 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004049
Kuirong Wang906ac472012-07-09 12:54:44 -07004050 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
4051 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004052
Kuirong Wang906ac472012-07-09 12:54:44 -07004053 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
4054 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004055
Kuirong Wang906ac472012-07-09 12:54:44 -07004056 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TAIKO_TX1, 0,
4057 &sb_tx1_mux),
4058 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TAIKO_TX2, 0,
4059 &sb_tx2_mux),
4060 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TAIKO_TX3, 0,
4061 &sb_tx3_mux),
4062 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TAIKO_TX4, 0,
4063 &sb_tx4_mux),
4064 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TAIKO_TX5, 0,
4065 &sb_tx5_mux),
4066 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TAIKO_TX6, 0,
4067 &sb_tx6_mux),
4068 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TAIKO_TX7, 0,
4069 &sb_tx7_mux),
4070 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TAIKO_TX8, 0,
4071 &sb_tx8_mux),
4072 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TAIKO_TX9, 0,
4073 &sb_tx9_mux),
4074 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TAIKO_TX10, 0,
4075 &sb_tx10_mux),
Kiran Kandic3b24402012-06-11 00:05:59 -07004076
4077 /* Digital Mic Inputs */
4078 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
4079 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4080 SND_SOC_DAPM_POST_PMD),
4081
4082 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
4083 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4084 SND_SOC_DAPM_POST_PMD),
4085
4086 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
4087 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4088 SND_SOC_DAPM_POST_PMD),
4089
4090 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
4091 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4092 SND_SOC_DAPM_POST_PMD),
4093
4094 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
4095 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4096 SND_SOC_DAPM_POST_PMD),
4097 SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
4098 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4099 SND_SOC_DAPM_POST_PMD),
4100
4101 /* Sidetone */
4102 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
4103 SND_SOC_DAPM_PGA("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
4104
4105 /* AUX PGA */
4106 SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TAIKO_A_RX_AUX_SW_CTL, 7, 0,
4107 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
4108 SND_SOC_DAPM_POST_PMD),
4109
4110 SND_SOC_DAPM_ADC_E("AUX_PGA_Right", NULL, TAIKO_A_RX_AUX_SW_CTL, 6, 0,
4111 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
4112 SND_SOC_DAPM_POST_PMD),
4113
4114 /* Lineout, ear and HPH PA Mixers */
4115
4116 SND_SOC_DAPM_MIXER("EAR_PA_MIXER", SND_SOC_NOPM, 0, 0,
4117 ear_pa_mix, ARRAY_SIZE(ear_pa_mix)),
4118
4119 SND_SOC_DAPM_MIXER("HPHL_PA_MIXER", SND_SOC_NOPM, 0, 0,
4120 hphl_pa_mix, ARRAY_SIZE(hphl_pa_mix)),
4121
4122 SND_SOC_DAPM_MIXER("HPHR_PA_MIXER", SND_SOC_NOPM, 0, 0,
4123 hphr_pa_mix, ARRAY_SIZE(hphr_pa_mix)),
4124
4125 SND_SOC_DAPM_MIXER("LINEOUT1_PA_MIXER", SND_SOC_NOPM, 0, 0,
4126 lineout1_pa_mix, ARRAY_SIZE(lineout1_pa_mix)),
4127
4128 SND_SOC_DAPM_MIXER("LINEOUT2_PA_MIXER", SND_SOC_NOPM, 0, 0,
4129 lineout2_pa_mix, ARRAY_SIZE(lineout2_pa_mix)),
4130
4131 SND_SOC_DAPM_MIXER("LINEOUT3_PA_MIXER", SND_SOC_NOPM, 0, 0,
4132 lineout3_pa_mix, ARRAY_SIZE(lineout3_pa_mix)),
4133
4134 SND_SOC_DAPM_MIXER("LINEOUT4_PA_MIXER", SND_SOC_NOPM, 0, 0,
4135 lineout4_pa_mix, ARRAY_SIZE(lineout4_pa_mix)),
4136
4137};
4138
Kiran Kandic3b24402012-06-11 00:05:59 -07004139static unsigned long slimbus_value;
4140
4141static irqreturn_t taiko_slimbus_irq(int irq, void *data)
4142{
4143 struct taiko_priv *priv = data;
4144 struct snd_soc_codec *codec = priv->codec;
4145 int i, j;
4146 u8 val;
4147
4148 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) {
4149 slimbus_value = wcd9xxx_interface_reg_read(codec->control_data,
4150 TAIKO_SLIM_PGD_PORT_INT_STATUS0 + i);
4151 for_each_set_bit(j, &slimbus_value, BITS_PER_BYTE) {
4152 val = wcd9xxx_interface_reg_read(codec->control_data,
4153 TAIKO_SLIM_PGD_PORT_INT_SOURCE0 + i*8 + j);
4154 if (val & 0x1)
4155 pr_err_ratelimited(
4156 "overflow error on port %x, value %x\n",
4157 i*8 + j, val);
4158 if (val & 0x2)
4159 pr_err_ratelimited(
4160 "underflow error on port %x, value %x\n",
4161 i*8 + j, val);
4162 }
4163 wcd9xxx_interface_reg_write(codec->control_data,
4164 TAIKO_SLIM_PGD_PORT_INT_CLR0 + i, 0xFF);
Kiran Kandic3b24402012-06-11 00:05:59 -07004165
Joonwoo Parka8890262012-10-15 12:04:27 -07004166 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004167 return IRQ_HANDLED;
4168}
4169
Kiran Kandi4c56c592012-07-25 11:04:55 -07004170static const struct taiko_reg_mask_val taiko_1_0_class_h_ear[] = {
4171
4172 /* CLASS-H EAR IDLE_THRESHOLD Table */
4173 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_IDLE_EAR_THSD, 0x26),
4174 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_FCLKONLY_EAR_THSD, 0x2C),
4175
4176 /* CLASS-H EAR I_PA_FACT Table. */
4177 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_L, 0xA9),
4178 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_U, 0x07),
4179
4180 /* CLASS-H EAR Voltage Headroom , Voltage Min. */
4181 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_HD_EAR, 0x0D),
4182 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_MIN_EAR, 0x3A),
4183
4184 /* CLASS-H EAR K values --chnages from load. */
4185 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_ADDR, 0x08),
4186 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x1B),
4187 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4188 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x2D),
4189 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4190 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x36),
4191 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4192 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x37),
4193 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4194 /** end of Ear PA load 32 */
4195};
4196
Kiran Kandi4c56c592012-07-25 11:04:55 -07004197static const struct taiko_reg_mask_val taiko_1_0_class_h_hph[] = {
4198
4199 /* CLASS-H HPH IDLE_THRESHOLD Table */
4200 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_IDLE_HPH_THSD, 0x13),
4201 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0x19),
4202
4203 /* CLASS-H HPH I_PA_FACT Table */
4204 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_L, 0x9A),
4205 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_U, 0x06),
4206
4207 /* CLASS-H HPH Voltage Headroom , Voltage Min */
4208 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_HD_HPH, 0x0D),
4209 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_MIN_HPH, 0x1D),
4210
4211 /* CLASS-H HPH K values --chnages from load .*/
4212 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_ADDR, 0x00),
4213 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0xAE),
4214 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x01),
4215 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x1C),
4216 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4217 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x25),
4218 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4219 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x27),
4220 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4221};
4222
4223static int taiko_config_ear_class_h(struct snd_soc_codec *codec, u32 ear_load)
4224{
4225 u32 i;
4226
4227 if (ear_load != 32)
4228 return -EINVAL;
4229
4230 for (i = 0; i < ARRAY_SIZE(taiko_1_0_class_h_ear); i++)
4231 snd_soc_write(codec, taiko_1_0_class_h_ear[i].reg,
4232 taiko_1_0_class_h_ear[i].val);
4233 return 0;
4234}
4235
4236static int taiko_config_hph_class_h(struct snd_soc_codec *codec, u32 hph_load)
4237{
4238 u32 i;
4239 if (hph_load != 16)
4240 return -EINVAL;
4241
4242 for (i = 0; i < ARRAY_SIZE(taiko_1_0_class_h_hph); i++)
4243 snd_soc_write(codec, taiko_1_0_class_h_hph[i].reg,
4244 taiko_1_0_class_h_hph[i].val);
4245 return 0;
4246}
4247
Kiran Kandic3b24402012-06-11 00:05:59 -07004248static int taiko_handle_pdata(struct taiko_priv *taiko)
4249{
4250 struct snd_soc_codec *codec = taiko->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07004251 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
Kiran Kandic3b24402012-06-11 00:05:59 -07004252 int k1, k2, k3, rc = 0;
Kiran Kandi725f8492012-08-06 13:45:16 -07004253 u8 leg_mode, txfe_bypass, txfe_buff, flag;
Kiran Kandic3b24402012-06-11 00:05:59 -07004254 u8 i = 0, j = 0;
4255 u8 val_txfe = 0, value = 0;
4256
4257 if (!pdata) {
Kiran Kandi725f8492012-08-06 13:45:16 -07004258 pr_err("%s: NULL pdata\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07004259 rc = -ENODEV;
4260 goto done;
4261 }
4262
Kiran Kandi725f8492012-08-06 13:45:16 -07004263 leg_mode = pdata->amic_settings.legacy_mode;
4264 txfe_bypass = pdata->amic_settings.txfe_enable;
4265 txfe_buff = pdata->amic_settings.txfe_buff;
4266 flag = pdata->amic_settings.use_pdata;
4267
Kiran Kandic3b24402012-06-11 00:05:59 -07004268 /* Make sure settings are correct */
Joonwoo Parka8890262012-10-15 12:04:27 -07004269 if ((pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V) ||
4270 (pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
4271 (pdata->micbias.bias2_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
4272 (pdata->micbias.bias3_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
4273 (pdata->micbias.bias4_cfilt_sel > WCD9XXX_CFILT3_SEL)) {
Kiran Kandic3b24402012-06-11 00:05:59 -07004274 rc = -EINVAL;
4275 goto done;
4276 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004277 /* figure out k value */
Joonwoo Parka8890262012-10-15 12:04:27 -07004278 k1 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt1_mv);
4279 k2 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt2_mv);
4280 k3 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt3_mv);
Kiran Kandic3b24402012-06-11 00:05:59 -07004281
4282 if (IS_ERR_VALUE(k1) || IS_ERR_VALUE(k2) || IS_ERR_VALUE(k3)) {
4283 rc = -EINVAL;
4284 goto done;
4285 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004286 /* Set voltage level and always use LDO */
4287 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 0x0C,
Joonwoo Parka8890262012-10-15 12:04:27 -07004288 (pdata->micbias.ldoh_v << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07004289
Joonwoo Parka8890262012-10-15 12:04:27 -07004290 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_1_VAL, 0xFC, (k1 << 2));
4291 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_2_VAL, 0xFC, (k2 << 2));
4292 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_3_VAL, 0xFC, (k3 << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07004293
4294 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07004295 (pdata->micbias.bias1_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07004296 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07004297 (pdata->micbias.bias2_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07004298 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07004299 (pdata->micbias.bias3_cfilt_sel << 5));
4300 snd_soc_update_bits(codec, taiko->resmgr.reg_addr->micb_4_ctl, 0x60,
Kiran Kandic3b24402012-06-11 00:05:59 -07004301 (pdata->micbias.bias4_cfilt_sel << 5));
4302
4303 for (i = 0; i < 6; j++, i += 2) {
4304 if (flag & (0x01 << i)) {
4305 value = (leg_mode & (0x01 << i)) ? 0x10 : 0x00;
4306 val_txfe = (txfe_bypass & (0x01 << i)) ? 0x20 : 0x00;
4307 val_txfe = val_txfe |
4308 ((txfe_buff & (0x01 << i)) ? 0x10 : 0x00);
4309 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
4310 0x10, value);
4311 snd_soc_update_bits(codec,
4312 TAIKO_A_TX_1_2_TEST_EN + j * 10,
4313 0x30, val_txfe);
4314 }
4315 if (flag & (0x01 << (i + 1))) {
4316 value = (leg_mode & (0x01 << (i + 1))) ? 0x01 : 0x00;
4317 val_txfe = (txfe_bypass &
4318 (0x01 << (i + 1))) ? 0x02 : 0x00;
4319 val_txfe |= (txfe_buff &
4320 (0x01 << (i + 1))) ? 0x01 : 0x00;
4321 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
4322 0x01, value);
4323 snd_soc_update_bits(codec,
4324 TAIKO_A_TX_1_2_TEST_EN + j * 10,
4325 0x03, val_txfe);
4326 }
4327 }
4328 if (flag & 0x40) {
4329 value = (leg_mode & 0x40) ? 0x10 : 0x00;
4330 value = value | ((txfe_bypass & 0x40) ? 0x02 : 0x00);
4331 value = value | ((txfe_buff & 0x40) ? 0x01 : 0x00);
4332 snd_soc_update_bits(codec, TAIKO_A_TX_7_MBHC_EN,
4333 0x13, value);
4334 }
4335
4336 if (pdata->ocp.use_pdata) {
4337 /* not defined in CODEC specification */
4338 if (pdata->ocp.hph_ocp_limit == 1 ||
4339 pdata->ocp.hph_ocp_limit == 5) {
4340 rc = -EINVAL;
4341 goto done;
4342 }
4343 snd_soc_update_bits(codec, TAIKO_A_RX_COM_OCP_CTL,
4344 0x0F, pdata->ocp.num_attempts);
4345 snd_soc_write(codec, TAIKO_A_RX_COM_OCP_COUNT,
4346 ((pdata->ocp.run_time << 4) | pdata->ocp.wait_time));
4347 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_OCP_CTL,
4348 0xE0, (pdata->ocp.hph_ocp_limit << 5));
4349 }
4350
4351 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
4352 if (!strncmp(pdata->regulator[i].name, "CDC_VDDA_RX", 11)) {
4353 if (pdata->regulator[i].min_uV == 1800000 &&
4354 pdata->regulator[i].max_uV == 1800000) {
4355 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
4356 0x1C);
4357 } else if (pdata->regulator[i].min_uV == 2200000 &&
4358 pdata->regulator[i].max_uV == 2200000) {
4359 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
4360 0x1E);
4361 } else {
4362 pr_err("%s: unsupported CDC_VDDA_RX voltage\n"
4363 "min %d, max %d\n", __func__,
4364 pdata->regulator[i].min_uV,
4365 pdata->regulator[i].max_uV);
4366 rc = -EINVAL;
4367 }
4368 break;
4369 }
4370 }
Kiran Kandi4c56c592012-07-25 11:04:55 -07004371
Joonwoo Park1848c762012-10-18 13:16:01 -07004372 /* Set micbias capless mode with tail current */
4373 value = (pdata->micbias.bias1_cap_mode == MICBIAS_EXT_BYP_CAP ?
4374 0x00 : 0x16);
4375 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x1E, value);
4376 value = (pdata->micbias.bias2_cap_mode == MICBIAS_EXT_BYP_CAP ?
4377 0x00 : 0x16);
4378 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x1E, value);
4379 value = (pdata->micbias.bias3_cap_mode == MICBIAS_EXT_BYP_CAP ?
4380 0x00 : 0x16);
4381 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x1E, value);
4382 value = (pdata->micbias.bias4_cap_mode == MICBIAS_EXT_BYP_CAP ?
4383 0x00 : 0x16);
4384 snd_soc_update_bits(codec, TAIKO_A_MICB_4_CTL, 0x1E, value);
4385
Kiran Kandi4c56c592012-07-25 11:04:55 -07004386 taiko_config_ear_class_h(codec, 32);
4387 taiko_config_hph_class_h(codec, 16);
4388
Kiran Kandic3b24402012-06-11 00:05:59 -07004389done:
4390 return rc;
4391}
4392
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004393static const struct taiko_reg_mask_val taiko_reg_defaults[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07004394
Kiran Kandi4c56c592012-07-25 11:04:55 -07004395 /* set MCLk to 9.6 */
4396 TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x0A),
4397 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_POWER_CTL, 0x03),
Kiran Kandic3b24402012-06-11 00:05:59 -07004398
Kiran Kandi4c56c592012-07-25 11:04:55 -07004399 /* EAR PA deafults */
4400 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CMBUFF, 0x05),
Kiran Kandic3b24402012-06-11 00:05:59 -07004401
Kiran Kandi4c56c592012-07-25 11:04:55 -07004402 /** BUCK and NCP defaults for EAR and HS */
4403 TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_4, 0x50),
Kiran Kandi4c56c592012-07-25 11:04:55 -07004404 TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_1, 0x5B),
Kiran Kandi4c56c592012-07-25 11:04:55 -07004405
4406 /* CLASS-H defaults for EAR and HS */
4407 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_BUCK_NCP_VARS, 0x00),
4408 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_BUCK_NCP_VARS, 0x04),
4409 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x01),
4410 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x05),
4411 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x35),
4412 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B3_CTL, 0x30),
4413 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B3_CTL, 0x3B),
4414
4415 /*
4416 * For CLASS-H, Enable ANC delay buffer,
4417 * set HPHL and EAR PA ref gain to 0 DB.
4418 */
4419 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B1_CTL, 0x26),
Kiran Kandic3b24402012-06-11 00:05:59 -07004420
Kiran Kandi4c56c592012-07-25 11:04:55 -07004421 /* RX deafults */
Kiran Kandic3b24402012-06-11 00:05:59 -07004422 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B5_CTL, 0x78),
4423 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B5_CTL, 0x78),
4424 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B5_CTL, 0x78),
4425 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B5_CTL, 0x78),
4426 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B5_CTL, 0x78),
4427 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B5_CTL, 0x78),
4428 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B5_CTL, 0x78),
4429
Kiran Kandi4c56c592012-07-25 11:04:55 -07004430 /* RX1 and RX2 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07004431 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B6_CTL, 0xA0),
4432 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B6_CTL, 0xA0),
4433
Kiran Kandi4c56c592012-07-25 11:04:55 -07004434 /* RX3 to RX7 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07004435 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B6_CTL, 0x80),
4436 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B6_CTL, 0x80),
4437 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B6_CTL, 0x80),
4438 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B6_CTL, 0x80),
4439 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
Kiran Kandic3b24402012-06-11 00:05:59 -07004440};
4441
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004442static const struct taiko_reg_mask_val taiko_1_0_reg_defaults[] = {
4443 /*
4444 * The following only need to be written for Taiko 1.0 parts.
4445 * Taiko 2.0 will have appropriate defaults for these registers.
4446 */
4447 /* Choose max non-overlap time for NCP */
4448 TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
4449 /* Use 25mV/50mV for deltap/m to reduce ripple */
4450 TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_VCL_1, 0x08),
4451 /*
4452 * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
4453 * Note that the other bits of this register will be changed during
4454 * Rx PA bring up.
4455 */
4456 TAIKO_REG_VAL(TAIKO_A_BUCK_MODE_3, 0xCE),
4457 /* Reduce HPH DAC bias to 70% */
4458 TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
4459 /*Reduce EAR DAC bias to 70% */
4460 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
4461 /* Reduce LINE DAC bias to 70% */
4462 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
4463};
4464
Kiran Kandic3b24402012-06-11 00:05:59 -07004465static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
4466{
4467 u32 i;
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004468 struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07004469
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004470 for (i = 0; i < ARRAY_SIZE(taiko_reg_defaults); i++)
4471 snd_soc_write(codec, taiko_reg_defaults[i].reg,
4472 taiko_reg_defaults[i].val);
4473
4474 if (TAIKO_IS_1_0(taiko_core->version)) {
4475 for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
4476 snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
Kiran Kandic3b24402012-06-11 00:05:59 -07004477 taiko_1_0_reg_defaults[i].val);
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004478 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004479}
4480
4481static const struct taiko_reg_mask_val taiko_codec_reg_init_val[] = {
4482 /* Initialize current threshold to 350MA
4483 * number of wait and run cycles to 4096
4484 */
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004485 {TAIKO_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
Kiran Kandic3b24402012-06-11 00:05:59 -07004486 {TAIKO_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
4487
Kiran Kandic3b24402012-06-11 00:05:59 -07004488 /* Initialize gain registers to use register gain */
Kiran Kandi4c56c592012-07-25 11:04:55 -07004489 {TAIKO_A_RX_HPH_L_GAIN, 0x20, 0x20},
4490 {TAIKO_A_RX_HPH_R_GAIN, 0x20, 0x20},
4491 {TAIKO_A_RX_LINE_1_GAIN, 0x20, 0x20},
4492 {TAIKO_A_RX_LINE_2_GAIN, 0x20, 0x20},
4493 {TAIKO_A_RX_LINE_3_GAIN, 0x20, 0x20},
4494 {TAIKO_A_RX_LINE_4_GAIN, 0x20, 0x20},
Kiran Kandic3b24402012-06-11 00:05:59 -07004495
Kiran Kandi4c56c592012-07-25 11:04:55 -07004496 /* CLASS H config */
4497 {TAIKO_A_CDC_CONN_CLSH_CTL, 0x3C, 0x14},
Kiran Kandic3b24402012-06-11 00:05:59 -07004498
4499 /* Use 16 bit sample size for TX1 to TX6 */
4500 {TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0x30, 0x20},
4501 {TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0x30, 0x20},
4502 {TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0x30, 0x20},
4503 {TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0x30, 0x20},
4504 {TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0x30, 0x20},
4505 {TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0x30, 0x20},
4506
4507 /* Use 16 bit sample size for TX7 to TX10 */
4508 {TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0x60, 0x40},
4509 {TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0x60, 0x40},
4510 {TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x60, 0x40},
4511 {TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x60, 0x40},
4512
4513 /* Use 16 bit sample size for RX */
4514 {TAIKO_A_CDC_CONN_RX_SB_B1_CTL, 0xFF, 0xAA},
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004515 {TAIKO_A_CDC_CONN_RX_SB_B2_CTL, 0xFF, 0x2A},
Kiran Kandic3b24402012-06-11 00:05:59 -07004516
4517 /*enable HPF filter for TX paths */
4518 {TAIKO_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
4519 {TAIKO_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
4520 {TAIKO_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
4521 {TAIKO_A_CDC_TX4_MUX_CTL, 0x8, 0x0},
4522 {TAIKO_A_CDC_TX5_MUX_CTL, 0x8, 0x0},
4523 {TAIKO_A_CDC_TX6_MUX_CTL, 0x8, 0x0},
4524 {TAIKO_A_CDC_TX7_MUX_CTL, 0x8, 0x0},
4525 {TAIKO_A_CDC_TX8_MUX_CTL, 0x8, 0x0},
4526 {TAIKO_A_CDC_TX9_MUX_CTL, 0x8, 0x0},
4527 {TAIKO_A_CDC_TX10_MUX_CTL, 0x8, 0x0},
4528
Kiran Kandi4c56c592012-07-25 11:04:55 -07004529 /* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
4530 {TAIKO_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
4531 {TAIKO_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
4532 {TAIKO_A_CDC_TX3_DMIC_CTL, 0x7, 0x1},
4533 {TAIKO_A_CDC_TX4_DMIC_CTL, 0x7, 0x1},
4534 {TAIKO_A_CDC_TX5_DMIC_CTL, 0x7, 0x1},
4535 {TAIKO_A_CDC_TX6_DMIC_CTL, 0x7, 0x1},
4536 {TAIKO_A_CDC_TX7_DMIC_CTL, 0x7, 0x1},
4537 {TAIKO_A_CDC_TX8_DMIC_CTL, 0x7, 0x1},
4538 {TAIKO_A_CDC_TX9_DMIC_CTL, 0x7, 0x1},
4539 {TAIKO_A_CDC_TX10_DMIC_CTL, 0x7, 0x1},
Kiran Kandic3b24402012-06-11 00:05:59 -07004540
Kiran Kandi4c56c592012-07-25 11:04:55 -07004541 /* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
4542 {TAIKO_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
4543 {TAIKO_A_CDC_CLK_DMIC_B2_CTL, 0x0E, 0x02},
4544
Kiran Kandic3b24402012-06-11 00:05:59 -07004545};
4546
4547static void taiko_codec_init_reg(struct snd_soc_codec *codec)
4548{
4549 u32 i;
4550
4551 for (i = 0; i < ARRAY_SIZE(taiko_codec_reg_init_val); i++)
4552 snd_soc_update_bits(codec, taiko_codec_reg_init_val[i].reg,
4553 taiko_codec_reg_init_val[i].mask,
4554 taiko_codec_reg_init_val[i].val);
4555}
4556
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004557static int taiko_setup_irqs(struct taiko_priv *taiko)
4558{
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004559 int i;
Joonwoo Parka8890262012-10-15 12:04:27 -07004560 int ret = 0;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004561 struct snd_soc_codec *codec = taiko->codec;
4562
Joonwoo Parkf6574c72012-10-10 17:29:57 -07004563 ret = wcd9xxx_request_irq(codec->control_data, WCD9XXX_IRQ_SLIMBUS,
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004564 taiko_slimbus_irq, "SLIMBUS Slave", taiko);
4565 if (ret) {
4566 pr_err("%s: Failed to request irq %d\n", __func__,
Joonwoo Parkf6574c72012-10-10 17:29:57 -07004567 WCD9XXX_IRQ_SLIMBUS);
Joonwoo Parka8890262012-10-15 12:04:27 -07004568 goto exit;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004569 }
4570
4571 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
4572 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Parka8890262012-10-15 12:04:27 -07004573 TAIKO_SLIM_PGD_PORT_INT_EN0 + i,
4574 0xFF);
4575exit:
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004576 return ret;
4577}
4578
Joonwoo Parka8890262012-10-15 12:04:27 -07004579int taiko_hs_detect(struct snd_soc_codec *codec,
4580 struct wcd9xxx_mbhc_config *mbhc_cfg)
4581{
4582 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
4583 return wcd9xxx_mbhc_start(&taiko->mbhc, mbhc_cfg);
4584}
4585EXPORT_SYMBOL_GPL(taiko_hs_detect);
4586
4587static struct wcd9xxx_reg_address taiko_reg_address = {
4588 .micb_4_mbhc = TAIKO_A_MICB_4_MBHC,
4589 .micb_4_int_rbias = TAIKO_A_MICB_4_INT_RBIAS,
4590 .micb_4_ctl = TAIKO_A_MICB_4_CTL,
4591};
4592
Kiran Kandic3b24402012-06-11 00:05:59 -07004593static int taiko_codec_probe(struct snd_soc_codec *codec)
4594{
4595 struct wcd9xxx *control;
4596 struct taiko_priv *taiko;
Joonwoo Parka8890262012-10-15 12:04:27 -07004597 struct wcd9xxx_pdata *pdata;
4598 struct wcd9xxx *wcd9xxx;
Kiran Kandic3b24402012-06-11 00:05:59 -07004599 struct snd_soc_dapm_context *dapm = &codec->dapm;
4600 int ret = 0;
4601 int i;
Kuirong Wang906ac472012-07-09 12:54:44 -07004602 void *ptr = NULL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004603
4604 codec->control_data = dev_get_drvdata(codec->dev->parent);
4605 control = codec->control_data;
4606
Kiran Kandi4c56c592012-07-25 11:04:55 -07004607 dev_info(codec->dev, "%s()\n", __func__);
4608
Kiran Kandic3b24402012-06-11 00:05:59 -07004609 taiko = kzalloc(sizeof(struct taiko_priv), GFP_KERNEL);
4610 if (!taiko) {
4611 dev_err(codec->dev, "Failed to allocate private data\n");
4612 return -ENOMEM;
4613 }
4614 for (i = 0 ; i < NUM_DECIMATORS; i++) {
4615 tx_hpf_work[i].taiko = taiko;
4616 tx_hpf_work[i].decimator = i + 1;
4617 INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
4618 tx_hpf_corner_freq_callback);
4619 }
4620
Kiran Kandic3b24402012-06-11 00:05:59 -07004621 snd_soc_codec_set_drvdata(codec, taiko);
4622
Joonwoo Parka8890262012-10-15 12:04:27 -07004623 /* codec resmgr module init */
4624 wcd9xxx = codec->control_data;
4625 pdata = dev_get_platdata(codec->dev->parent);
4626 ret = wcd9xxx_resmgr_init(&taiko->resmgr, codec, wcd9xxx, pdata,
4627 &taiko_reg_address);
4628 if (ret) {
4629 pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
4630 return ret;
4631 }
4632
4633 /* init and start mbhc */
4634 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
4635 if (ret) {
4636 pr_err("%s: mbhc init failed %d\n", __func__, ret);
4637 return ret;
4638 }
4639
Kiran Kandic3b24402012-06-11 00:05:59 -07004640 taiko->codec = codec;
Kiran Kandic3b24402012-06-11 00:05:59 -07004641 for (i = 0; i < COMPANDER_MAX; i++) {
4642 taiko->comp_enabled[i] = 0;
4643 taiko->comp_fs[i] = COMPANDER_FS_48KHZ;
4644 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004645 taiko->intf_type = wcd9xxx_get_intf_type();
4646 taiko->aux_pga_cnt = 0;
4647 taiko->aux_l_gain = 0x1F;
4648 taiko->aux_r_gain = 0x1F;
Kiran Kandic3b24402012-06-11 00:05:59 -07004649 taiko_update_reg_defaults(codec);
4650 taiko_codec_init_reg(codec);
4651 ret = taiko_handle_pdata(taiko);
4652 if (IS_ERR_VALUE(ret)) {
4653 pr_err("%s: bad pdata\n", __func__);
4654 goto err_pdata;
4655 }
4656
Kuirong Wang906ac472012-07-09 12:54:44 -07004657 ptr = kmalloc((sizeof(taiko_rx_chs) +
4658 sizeof(taiko_tx_chs)), GFP_KERNEL);
4659 if (!ptr) {
4660 pr_err("%s: no mem for slim chan ctl data\n", __func__);
4661 ret = -ENOMEM;
4662 goto err_nomem_slimch;
4663 }
4664
Kiran Kandic3b24402012-06-11 00:05:59 -07004665 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4666 snd_soc_dapm_new_controls(dapm, taiko_dapm_i2s_widgets,
4667 ARRAY_SIZE(taiko_dapm_i2s_widgets));
4668 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
4669 ARRAY_SIZE(audio_i2s_map));
Kuirong Wang906ac472012-07-09 12:54:44 -07004670 for (i = 0; i < ARRAY_SIZE(taiko_i2s_dai); i++)
4671 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
4672 } else if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
4673 for (i = 0; i < NUM_CODEC_DAIS; i++) {
4674 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
4675 init_waitqueue_head(&taiko->dai[i].dai_wait);
4676 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004677 }
4678
Kuirong Wang906ac472012-07-09 12:54:44 -07004679 control->num_rx_port = TAIKO_RX_MAX;
4680 control->rx_chs = ptr;
4681 memcpy(control->rx_chs, taiko_rx_chs, sizeof(taiko_rx_chs));
4682 control->num_tx_port = TAIKO_TX_MAX;
4683 control->tx_chs = ptr + sizeof(taiko_rx_chs);
4684 memcpy(control->tx_chs, taiko_tx_chs, sizeof(taiko_tx_chs));
4685
Kiran Kandic3b24402012-06-11 00:05:59 -07004686 snd_soc_dapm_sync(dapm);
4687
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004688 (void) taiko_setup_irqs(taiko);
Kiran Kandic3b24402012-06-11 00:05:59 -07004689
Kiran Kandic3b24402012-06-11 00:05:59 -07004690 codec->ignore_pmdown_time = 1;
4691 return ret;
4692
Kiran Kandic3b24402012-06-11 00:05:59 -07004693err_pdata:
Kuirong Wang906ac472012-07-09 12:54:44 -07004694 kfree(ptr);
4695err_nomem_slimch:
Kiran Kandic3b24402012-06-11 00:05:59 -07004696 kfree(taiko);
4697 return ret;
4698}
4699static int taiko_codec_remove(struct snd_soc_codec *codec)
4700{
Kiran Kandic3b24402012-06-11 00:05:59 -07004701 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07004702
4703 /* cleanup MBHC */
4704 wcd9xxx_mbhc_deinit(&taiko->mbhc);
4705 /* cleanup resmgr */
4706 wcd9xxx_resmgr_deinit(&taiko->resmgr);
4707
Kiran Kandic3b24402012-06-11 00:05:59 -07004708 kfree(taiko);
4709 return 0;
4710}
4711static struct snd_soc_codec_driver soc_codec_dev_taiko = {
4712 .probe = taiko_codec_probe,
4713 .remove = taiko_codec_remove,
4714
4715 .read = taiko_read,
4716 .write = taiko_write,
4717
4718 .readable_register = taiko_readable,
4719 .volatile_register = taiko_volatile,
4720
4721 .reg_cache_size = TAIKO_CACHE_SIZE,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004722 .reg_cache_default = taiko_reset_reg_defaults,
Kiran Kandic3b24402012-06-11 00:05:59 -07004723 .reg_word_size = 1,
4724
4725 .controls = taiko_snd_controls,
4726 .num_controls = ARRAY_SIZE(taiko_snd_controls),
4727 .dapm_widgets = taiko_dapm_widgets,
4728 .num_dapm_widgets = ARRAY_SIZE(taiko_dapm_widgets),
4729 .dapm_routes = audio_map,
4730 .num_dapm_routes = ARRAY_SIZE(audio_map),
4731};
4732
4733#ifdef CONFIG_PM
4734static int taiko_suspend(struct device *dev)
4735{
4736 dev_dbg(dev, "%s: system suspend\n", __func__);
4737 return 0;
4738}
4739
4740static int taiko_resume(struct device *dev)
4741{
4742 struct platform_device *pdev = to_platform_device(dev);
4743 struct taiko_priv *taiko = platform_get_drvdata(pdev);
4744 dev_dbg(dev, "%s: system resume\n", __func__);
Joonwoo Parka8890262012-10-15 12:04:27 -07004745 /* Notify */
4746 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, WCD9XXX_EVENT_POST_RESUME);
Kiran Kandic3b24402012-06-11 00:05:59 -07004747 return 0;
4748}
4749
4750static const struct dev_pm_ops taiko_pm_ops = {
4751 .suspend = taiko_suspend,
4752 .resume = taiko_resume,
4753};
4754#endif
4755
4756static int __devinit taiko_probe(struct platform_device *pdev)
4757{
4758 int ret = 0;
4759 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
4760 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
4761 taiko_dai, ARRAY_SIZE(taiko_dai));
4762 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
4763 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
4764 taiko_i2s_dai, ARRAY_SIZE(taiko_i2s_dai));
4765 return ret;
4766}
4767static int __devexit taiko_remove(struct platform_device *pdev)
4768{
4769 snd_soc_unregister_codec(&pdev->dev);
4770 return 0;
4771}
4772static struct platform_driver taiko_codec_driver = {
4773 .probe = taiko_probe,
4774 .remove = taiko_remove,
4775 .driver = {
4776 .name = "taiko_codec",
4777 .owner = THIS_MODULE,
4778#ifdef CONFIG_PM
4779 .pm = &taiko_pm_ops,
4780#endif
4781 },
4782};
4783
4784static int __init taiko_codec_init(void)
4785{
4786 return platform_driver_register(&taiko_codec_driver);
4787}
4788
4789static void __exit taiko_codec_exit(void)
4790{
4791 platform_driver_unregister(&taiko_codec_driver);
4792}
4793
4794module_init(taiko_codec_init);
4795module_exit(taiko_codec_exit);
4796
4797MODULE_DESCRIPTION("Taiko codec driver");
4798MODULE_LICENSE("GPL v2");