blob: 0728932eb931964516baa746efcbf3e4f50d5721 [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 -07001483static int slim_tx_vport_validation(u32 dai_id, u32 port_id,
1484 struct taiko_priv *taiko_p)
1485{
1486 struct wcd9xxx_ch *ch;
1487 int ret = 0;
1488 int index = 0;
1489 u32 vtable = vport_check_table[dai_id];
1490 pr_debug("%s: dai_id %u vtable 0x%x port_id %u\n", __func__,
1491 dai_id, vtable, port_id);
1492 while (vtable) {
1493 if (vtable & 1) {
1494 list_for_each_entry(ch,
1495 &taiko_p->dai[index].wcd9xxx_ch_list,
1496 list) {
1497 pr_debug("%s: index %u ch->port %u vtable 0x%x\n",
1498 __func__, index, ch->port, vtable);
1499 if (ch->port == port_id) {
1500 pr_err("%s: TX%u is used by AIF%u_CAP Mixer\n",
1501 __func__, port_id + 1,
1502 (index + 1)/2);
1503 ret = -EINVAL;
1504 break;
1505 }
1506 }
1507 }
1508 if (ret)
1509 break;
1510 index++;
1511 vtable = vtable >> 1;
1512 }
1513 return ret;
1514}
1515
1516/* virtual port entries */
1517static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
1518 struct snd_ctl_elem_value *ucontrol)
1519{
1520 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1521 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1522
1523 ucontrol->value.integer.value[0] = widget->value;
1524 return 0;
1525}
1526
1527static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
1528 struct snd_ctl_elem_value *ucontrol)
1529{
1530 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1531 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1532 struct snd_soc_codec *codec = widget->codec;
1533 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
1534 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
1535 struct soc_multi_mixer_control *mixer =
1536 ((struct soc_multi_mixer_control *)kcontrol->private_value);
1537 u32 dai_id = widget->shift;
1538 u32 port_id = mixer->shift;
1539 u32 enable = ucontrol->value.integer.value[0];
1540
1541
1542 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
1543 widget->name, ucontrol->id.name, widget->value, widget->shift,
1544 ucontrol->value.integer.value[0]);
1545
1546 mutex_lock(&codec->mutex);
1547
1548 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
1549 if (dai_id != AIF1_CAP) {
1550 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
1551 __func__);
1552 mutex_unlock(&codec->mutex);
1553 return -EINVAL;
1554 }
1555 }
1556 switch (dai_id) {
1557 case AIF1_CAP:
1558 case AIF2_CAP:
1559 case AIF3_CAP:
1560 /* only add to the list if value not set
1561 */
1562 if (enable && !(widget->value & 1 << port_id)) {
1563 if (slim_tx_vport_validation(dai_id,
1564 port_id, taiko_p)) {
1565 pr_info("%s: TX%u is used by other virtual port\n",
1566 __func__, port_id + 1);
1567 mutex_unlock(&codec->mutex);
1568 return -EINVAL;
1569 }
1570 widget->value |= 1 << port_id;
1571 list_add_tail(&core->tx_chs[port_id].list,
1572 &taiko_p->dai[dai_id].wcd9xxx_ch_list
1573 );
1574 } else if (!enable && (widget->value & 1 << port_id)) {
1575 widget->value &= ~(1 << port_id);
1576 list_del_init(&core->tx_chs[port_id].list);
1577 } else {
1578 if (enable)
1579 pr_info("%s: TX%u port is used by this virtual port\n",
1580 __func__, port_id + 1);
1581 else
1582 pr_info("%s: TX%u port is not used by this virtual port\n",
1583 __func__, port_id + 1);
1584 /* avoid update power function */
1585 mutex_unlock(&codec->mutex);
1586 return 0;
1587 }
1588 break;
1589 default:
1590 pr_err("Unknown AIF %d\n", dai_id);
1591 mutex_unlock(&codec->mutex);
1592 return -EINVAL;
1593 }
1594 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
1595 widget->name, widget->sname, widget->value, widget->shift);
1596
1597 snd_soc_dapm_mixer_update_power(widget, kcontrol, enable);
1598
1599 mutex_unlock(&codec->mutex);
1600 return 0;
1601}
1602
1603static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
1604 struct snd_ctl_elem_value *ucontrol)
1605{
1606 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1607 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1608
1609 ucontrol->value.enumerated.item[0] = widget->value;
1610 return 0;
1611}
1612
1613static const char *const slim_rx_mux_text[] = {
1614 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
1615};
1616
1617static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
1618 struct snd_ctl_elem_value *ucontrol)
1619{
1620 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1621 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1622 struct snd_soc_codec *codec = widget->codec;
1623 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
1624 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
1625 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1626 u32 port_id = widget->shift;
1627
1628 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
1629 widget->name, ucontrol->id.name, widget->value, widget->shift,
1630 ucontrol->value.integer.value[0]);
1631
1632 widget->value = ucontrol->value.enumerated.item[0];
1633
1634 mutex_lock(&codec->mutex);
1635
1636 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
1637 if (widget->value > 1) {
1638 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
1639 __func__);
1640 mutex_unlock(&codec->mutex);
1641 return -EINVAL;
1642 }
1643 }
1644 /* value need to match the Virtual port and AIF number
1645 */
1646 switch (widget->value) {
1647 case 0:
1648 list_del_init(&core->rx_chs[port_id].list);
1649 break;
1650 case 1:
1651 list_add_tail(&core->rx_chs[port_id].list,
1652 &taiko_p->dai[AIF1_PB].wcd9xxx_ch_list);
1653 break;
1654 case 2:
1655 list_add_tail(&core->rx_chs[port_id].list,
1656 &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list);
1657 break;
1658 case 3:
1659 list_add_tail(&core->rx_chs[port_id].list,
1660 &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list);
1661 break;
1662 default:
1663 pr_err("Unknown AIF %d\n", widget->value);
1664 mutex_unlock(&codec->mutex);
1665 return -EINVAL;
1666 }
1667
1668 snd_soc_dapm_mux_update_power(widget, kcontrol, 1, widget->value, e);
1669
1670 mutex_unlock(&codec->mutex);
1671 return 0;
1672}
1673
1674static const struct soc_enum slim_rx_mux_enum =
1675 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
1676
1677static const struct snd_kcontrol_new slim_rx_mux[TAIKO_RX_MAX] = {
1678 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
1679 slim_rx_mux_get, slim_rx_mux_put),
1680 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
1681 slim_rx_mux_get, slim_rx_mux_put),
1682 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
1683 slim_rx_mux_get, slim_rx_mux_put),
1684 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
1685 slim_rx_mux_get, slim_rx_mux_put),
1686 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
1687 slim_rx_mux_get, slim_rx_mux_put),
1688 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
1689 slim_rx_mux_get, slim_rx_mux_put),
1690 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
1691 slim_rx_mux_get, slim_rx_mux_put),
1692};
1693
1694static const struct snd_kcontrol_new aif_cap_mixer[] = {
1695 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TAIKO_TX1, 1, 0,
1696 slim_tx_mixer_get, slim_tx_mixer_put),
1697 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TAIKO_TX2, 1, 0,
1698 slim_tx_mixer_get, slim_tx_mixer_put),
1699 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TAIKO_TX3, 1, 0,
1700 slim_tx_mixer_get, slim_tx_mixer_put),
1701 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TAIKO_TX4, 1, 0,
1702 slim_tx_mixer_get, slim_tx_mixer_put),
1703 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TAIKO_TX5, 1, 0,
1704 slim_tx_mixer_get, slim_tx_mixer_put),
1705 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TAIKO_TX6, 1, 0,
1706 slim_tx_mixer_get, slim_tx_mixer_put),
1707 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TAIKO_TX7, 1, 0,
1708 slim_tx_mixer_get, slim_tx_mixer_put),
1709 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TAIKO_TX8, 1, 0,
1710 slim_tx_mixer_get, slim_tx_mixer_put),
1711 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TAIKO_TX9, 1, 0,
1712 slim_tx_mixer_get, slim_tx_mixer_put),
1713 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TAIKO_TX10, 1, 0,
1714 slim_tx_mixer_get, slim_tx_mixer_put),
1715};
1716
Kiran Kandic3b24402012-06-11 00:05:59 -07001717static void taiko_codec_enable_adc_block(struct snd_soc_codec *codec,
1718 int enable)
1719{
1720 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1721
1722 pr_debug("%s %d\n", __func__, enable);
1723
1724 if (enable) {
1725 taiko->adc_count++;
1726 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_CTL, 0x2, 0x2);
1727 } else {
1728 taiko->adc_count--;
1729 if (!taiko->adc_count)
1730 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_CTL,
1731 0x2, 0x0);
1732 }
1733}
1734
1735static int taiko_codec_enable_adc(struct snd_soc_dapm_widget *w,
1736 struct snd_kcontrol *kcontrol, int event)
1737{
1738 struct snd_soc_codec *codec = w->codec;
1739 u16 adc_reg;
1740 u8 init_bit_shift;
1741
1742 pr_debug("%s %d\n", __func__, event);
1743
1744 if (w->reg == TAIKO_A_TX_1_2_EN)
1745 adc_reg = TAIKO_A_TX_1_2_TEST_CTL;
1746 else if (w->reg == TAIKO_A_TX_3_4_EN)
1747 adc_reg = TAIKO_A_TX_3_4_TEST_CTL;
1748 else if (w->reg == TAIKO_A_TX_5_6_EN)
1749 adc_reg = TAIKO_A_TX_5_6_TEST_CTL;
1750 else {
1751 pr_err("%s: Error, invalid adc register\n", __func__);
1752 return -EINVAL;
1753 }
1754
1755 if (w->shift == 3)
1756 init_bit_shift = 6;
1757 else if (w->shift == 7)
1758 init_bit_shift = 7;
1759 else {
1760 pr_err("%s: Error, invalid init bit postion adc register\n",
1761 __func__);
1762 return -EINVAL;
1763 }
1764
1765 switch (event) {
1766 case SND_SOC_DAPM_PRE_PMU:
1767 taiko_codec_enable_adc_block(codec, 1);
1768 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
1769 1 << init_bit_shift);
1770 break;
1771 case SND_SOC_DAPM_POST_PMU:
1772
1773 snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
1774
1775 break;
1776 case SND_SOC_DAPM_POST_PMD:
1777 taiko_codec_enable_adc_block(codec, 0);
1778 break;
1779 }
1780 return 0;
1781}
1782
Kiran Kandic3b24402012-06-11 00:05:59 -07001783static int taiko_codec_enable_aux_pga(struct snd_soc_dapm_widget *w,
1784 struct snd_kcontrol *kcontrol, int event)
1785{
1786 struct snd_soc_codec *codec = w->codec;
1787 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1788
1789 pr_debug("%s: %d\n", __func__, event);
1790
1791 switch (event) {
1792 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07001793 WCD9XXX_BCL_LOCK(&taiko->resmgr);
1794 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
1795 WCD9XXX_BANDGAP_AUDIO_MODE);
1796 /* AUX PGA requires RCO or MCLK */
1797 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
1798 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
1799 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07001800 break;
1801
1802 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07001803 WCD9XXX_BCL_LOCK(&taiko->resmgr);
1804 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
1805 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
1806 WCD9XXX_BANDGAP_AUDIO_MODE);
1807 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_RCO);
1808 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07001809 break;
1810 }
1811 return 0;
1812}
1813
1814static int taiko_codec_enable_lineout(struct snd_soc_dapm_widget *w,
1815 struct snd_kcontrol *kcontrol, int event)
1816{
1817 struct snd_soc_codec *codec = w->codec;
1818 u16 lineout_gain_reg;
1819
1820 pr_debug("%s %d %s\n", __func__, event, w->name);
1821
1822 switch (w->shift) {
1823 case 0:
1824 lineout_gain_reg = TAIKO_A_RX_LINE_1_GAIN;
1825 break;
1826 case 1:
1827 lineout_gain_reg = TAIKO_A_RX_LINE_2_GAIN;
1828 break;
1829 case 2:
1830 lineout_gain_reg = TAIKO_A_RX_LINE_3_GAIN;
1831 break;
1832 case 3:
1833 lineout_gain_reg = TAIKO_A_RX_LINE_4_GAIN;
1834 break;
1835 default:
1836 pr_err("%s: Error, incorrect lineout register value\n",
1837 __func__);
1838 return -EINVAL;
1839 }
1840
1841 switch (event) {
1842 case SND_SOC_DAPM_PRE_PMU:
1843 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
1844 break;
1845 case SND_SOC_DAPM_POST_PMU:
1846 pr_debug("%s: sleeping 16 ms after %s PA turn on\n",
1847 __func__, w->name);
1848 usleep_range(16000, 16000);
1849 break;
1850 case SND_SOC_DAPM_POST_PMD:
1851 snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
1852 break;
1853 }
1854 return 0;
1855}
1856
Joonwoo Park7680b9f2012-07-13 11:36:48 -07001857static int taiko_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
1858 struct snd_kcontrol *kcontrol, int event)
1859{
1860 pr_debug("%s %d %s\n", __func__, event, w->name);
1861 return 0;
1862}
Kiran Kandic3b24402012-06-11 00:05:59 -07001863
1864static int taiko_codec_enable_dmic(struct snd_soc_dapm_widget *w,
1865 struct snd_kcontrol *kcontrol, int event)
1866{
1867 struct snd_soc_codec *codec = w->codec;
1868 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1869 u8 dmic_clk_en;
1870 u16 dmic_clk_reg;
1871 s32 *dmic_clk_cnt;
1872 unsigned int dmic;
1873 int ret;
1874
1875 ret = kstrtouint(strpbrk(w->name, "123456"), 10, &dmic);
1876 if (ret < 0) {
1877 pr_err("%s: Invalid DMIC line on the codec\n", __func__);
1878 return -EINVAL;
1879 }
1880
1881 switch (dmic) {
1882 case 1:
1883 case 2:
1884 dmic_clk_en = 0x01;
1885 dmic_clk_cnt = &(taiko->dmic_1_2_clk_cnt);
1886 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
1887 pr_debug("%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
1888 __func__, event, dmic, *dmic_clk_cnt);
1889
1890 break;
1891
1892 case 3:
1893 case 4:
1894 dmic_clk_en = 0x10;
1895 dmic_clk_cnt = &(taiko->dmic_3_4_clk_cnt);
1896 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B1_CTL;
1897
1898 pr_debug("%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n",
1899 __func__, event, dmic, *dmic_clk_cnt);
1900 break;
1901
1902 case 5:
1903 case 6:
1904 dmic_clk_en = 0x01;
1905 dmic_clk_cnt = &(taiko->dmic_5_6_clk_cnt);
1906 dmic_clk_reg = TAIKO_A_CDC_CLK_DMIC_B2_CTL;
1907
1908 pr_debug("%s() event %d DMIC%d dmic_5_6_clk_cnt %d\n",
1909 __func__, event, dmic, *dmic_clk_cnt);
1910
1911 break;
1912
1913 default:
1914 pr_err("%s: Invalid DMIC Selection\n", __func__);
1915 return -EINVAL;
1916 }
1917
1918 switch (event) {
1919 case SND_SOC_DAPM_PRE_PMU:
1920
1921 (*dmic_clk_cnt)++;
1922 if (*dmic_clk_cnt == 1)
1923 snd_soc_update_bits(codec, dmic_clk_reg,
1924 dmic_clk_en, dmic_clk_en);
1925
1926 break;
1927 case SND_SOC_DAPM_POST_PMD:
1928
1929 (*dmic_clk_cnt)--;
1930 if (*dmic_clk_cnt == 0)
1931 snd_soc_update_bits(codec, dmic_clk_reg,
1932 dmic_clk_en, 0);
1933 break;
1934 }
1935 return 0;
1936}
1937
1938static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
1939 struct snd_kcontrol *kcontrol, int event)
1940{
1941 struct snd_soc_codec *codec = w->codec;
1942 const char *filename;
1943 const struct firmware *fw;
1944 int i;
1945 int ret;
1946 int num_anc_slots;
1947 struct anc_header *anc_head;
1948 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
1949 u32 anc_writes_size = 0;
1950 int anc_size_remaining;
1951 u32 *anc_ptr;
1952 u16 reg;
Kiran Kandi1b2d1ef2012-10-23 15:29:00 -07001953 u8 mask, val;
Kiran Kandic3b24402012-06-11 00:05:59 -07001954
1955 pr_debug("%s %d\n", __func__, event);
1956 switch (event) {
1957 case SND_SOC_DAPM_PRE_PMU:
1958
1959 filename = "wcd9320/wcd9320_anc.bin";
1960
1961 ret = request_firmware(&fw, filename, codec->dev);
1962 if (ret != 0) {
1963 dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
1964 ret);
1965 return -ENODEV;
1966 }
1967
1968 if (fw->size < sizeof(struct anc_header)) {
1969 dev_err(codec->dev, "Not enough data\n");
1970 release_firmware(fw);
1971 return -ENOMEM;
1972 }
1973
1974 /* First number is the number of register writes */
1975 anc_head = (struct anc_header *)(fw->data);
1976 anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
1977 anc_size_remaining = fw->size - sizeof(struct anc_header);
1978 num_anc_slots = anc_head->num_anc_slots;
1979
1980 if (taiko->anc_slot >= num_anc_slots) {
1981 dev_err(codec->dev, "Invalid ANC slot selected\n");
1982 release_firmware(fw);
1983 return -EINVAL;
1984 }
1985
1986 for (i = 0; i < num_anc_slots; i++) {
1987
1988 if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
1989 dev_err(codec->dev, "Invalid register format\n");
1990 release_firmware(fw);
1991 return -EINVAL;
1992 }
1993 anc_writes_size = (u32)(*anc_ptr);
1994 anc_size_remaining -= sizeof(u32);
1995 anc_ptr += 1;
1996
1997 if (anc_writes_size * TAIKO_PACKED_REG_SIZE
1998 > anc_size_remaining) {
1999 dev_err(codec->dev, "Invalid register format\n");
2000 release_firmware(fw);
2001 return -ENOMEM;
2002 }
2003
2004 if (taiko->anc_slot == i)
2005 break;
2006
2007 anc_size_remaining -= (anc_writes_size *
2008 TAIKO_PACKED_REG_SIZE);
2009 anc_ptr += anc_writes_size;
2010 }
2011 if (i == num_anc_slots) {
2012 dev_err(codec->dev, "Selected ANC slot not present\n");
2013 release_firmware(fw);
2014 return -ENOMEM;
2015 }
2016
2017 for (i = 0; i < anc_writes_size; i++) {
2018 TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
2019 mask, val);
Kiran Kandi1b2d1ef2012-10-23 15:29:00 -07002020 snd_soc_write(codec, reg, val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002021 }
2022 release_firmware(fw);
2023
2024 break;
2025 case SND_SOC_DAPM_POST_PMD:
2026 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
2027 snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
2028 break;
2029 }
2030 return 0;
2031}
2032
Kiran Kandic3b24402012-06-11 00:05:59 -07002033static int taiko_codec_enable_micbias(struct snd_soc_dapm_widget *w,
2034 struct snd_kcontrol *kcontrol, int event)
2035{
2036 struct snd_soc_codec *codec = w->codec;
2037 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
2038 u16 micb_int_reg;
Kiran Kandic3b24402012-06-11 00:05:59 -07002039 u8 cfilt_sel_val = 0;
2040 char *internal1_text = "Internal1";
2041 char *internal2_text = "Internal2";
2042 char *internal3_text = "Internal3";
Joonwoo Parka8890262012-10-15 12:04:27 -07002043 enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
Kiran Kandic3b24402012-06-11 00:05:59 -07002044
2045 pr_debug("%s %d\n", __func__, event);
2046 switch (w->reg) {
2047 case TAIKO_A_MICB_1_CTL:
2048 micb_int_reg = TAIKO_A_MICB_1_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002049 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias1_cfilt_sel;
2050 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
2051 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
2052 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
Kiran Kandic3b24402012-06-11 00:05:59 -07002053 break;
2054 case TAIKO_A_MICB_2_CTL:
2055 micb_int_reg = TAIKO_A_MICB_2_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002056 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias2_cfilt_sel;
2057 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
2058 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
2059 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
Kiran Kandic3b24402012-06-11 00:05:59 -07002060 break;
2061 case TAIKO_A_MICB_3_CTL:
2062 micb_int_reg = TAIKO_A_MICB_3_INT_RBIAS;
Joonwoo Parka8890262012-10-15 12:04:27 -07002063 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias3_cfilt_sel;
2064 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
2065 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
2066 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
Kiran Kandic3b24402012-06-11 00:05:59 -07002067 break;
2068 case TAIKO_A_MICB_4_CTL:
Joonwoo Parka8890262012-10-15 12:04:27 -07002069 micb_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
2070 cfilt_sel_val = taiko->resmgr.pdata->micbias.bias4_cfilt_sel;
2071 e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_4_ON;
2072 e_post_on = WCD9XXX_EVENT_POST_MICBIAS_4_ON;
2073 e_post_off = WCD9XXX_EVENT_POST_MICBIAS_4_OFF;
Kiran Kandic3b24402012-06-11 00:05:59 -07002074 break;
2075 default:
2076 pr_err("%s: Error, invalid micbias register\n", __func__);
2077 return -EINVAL;
2078 }
2079
2080 switch (event) {
2081 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002082 /* Let MBHC module know so micbias switch to be off */
2083 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002084
2085 snd_soc_update_bits(codec, w->reg, 0x0E, 0x0A);
Joonwoo Parka8890262012-10-15 12:04:27 -07002086 /* Get cfilt */
2087 wcd9xxx_resmgr_cfilt_get(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002088
2089 if (strnstr(w->name, internal1_text, 30))
2090 snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
2091 else if (strnstr(w->name, internal2_text, 30))
2092 snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
2093 else if (strnstr(w->name, internal3_text, 30))
2094 snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
2095
2096 break;
2097 case SND_SOC_DAPM_POST_PMU:
Kiran Kandic3b24402012-06-11 00:05:59 -07002098 usleep_range(20000, 20000);
Joonwoo Parka8890262012-10-15 12:04:27 -07002099 /* Let MBHC module know so micbias is on */
2100 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002101 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07002102 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002103 /* Let MBHC module know so micbias switch to be off */
2104 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
Kiran Kandic3b24402012-06-11 00:05:59 -07002105
2106 if (strnstr(w->name, internal1_text, 30))
2107 snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
2108 else if (strnstr(w->name, internal2_text, 30))
2109 snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
2110 else if (strnstr(w->name, internal3_text, 30))
2111 snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
2112
Joonwoo Parka8890262012-10-15 12:04:27 -07002113 /* Put cfilt */
2114 wcd9xxx_resmgr_cfilt_put(&taiko->resmgr, cfilt_sel_val);
Kiran Kandic3b24402012-06-11 00:05:59 -07002115 break;
2116 }
2117
2118 return 0;
2119}
2120
2121
2122static void tx_hpf_corner_freq_callback(struct work_struct *work)
2123{
2124 struct delayed_work *hpf_delayed_work;
2125 struct hpf_work *hpf_work;
2126 struct taiko_priv *taiko;
2127 struct snd_soc_codec *codec;
2128 u16 tx_mux_ctl_reg;
2129 u8 hpf_cut_of_freq;
2130
2131 hpf_delayed_work = to_delayed_work(work);
2132 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
2133 taiko = hpf_work->taiko;
2134 codec = hpf_work->taiko->codec;
2135 hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
2136
2137 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL +
2138 (hpf_work->decimator - 1) * 8;
2139
2140 pr_debug("%s(): decimator %u hpf_cut_of_freq 0x%x\n", __func__,
2141 hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
2142
2143 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
2144}
2145
2146#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30
2147#define CF_MIN_3DB_4HZ 0x0
2148#define CF_MIN_3DB_75HZ 0x1
2149#define CF_MIN_3DB_150HZ 0x2
2150
2151static int taiko_codec_enable_dec(struct snd_soc_dapm_widget *w,
2152 struct snd_kcontrol *kcontrol, int event)
2153{
2154 struct snd_soc_codec *codec = w->codec;
2155 unsigned int decimator;
2156 char *dec_name = NULL;
2157 char *widget_name = NULL;
2158 char *temp;
2159 int ret = 0;
2160 u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
2161 u8 dec_hpf_cut_of_freq;
2162 int offset;
2163
2164
2165 pr_debug("%s %d\n", __func__, event);
2166
2167 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
2168 if (!widget_name)
2169 return -ENOMEM;
2170 temp = widget_name;
2171
2172 dec_name = strsep(&widget_name, " ");
2173 widget_name = temp;
2174 if (!dec_name) {
2175 pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
2176 ret = -EINVAL;
2177 goto out;
2178 }
2179
2180 ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
2181 if (ret < 0) {
2182 pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
2183 ret = -EINVAL;
2184 goto out;
2185 }
2186
2187 pr_debug("%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
2188 w->name, dec_name, decimator);
2189
2190 if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
2191 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B1_CTL;
2192 offset = 0;
2193 } else if (w->reg == TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL) {
2194 dec_reset_reg = TAIKO_A_CDC_CLK_TX_RESET_B2_CTL;
2195 offset = 8;
2196 } else {
2197 pr_err("%s: Error, incorrect dec\n", __func__);
2198 return -EINVAL;
2199 }
2200
2201 tx_vol_ctl_reg = TAIKO_A_CDC_TX1_VOL_CTL_CFG + 8 * (decimator - 1);
2202 tx_mux_ctl_reg = TAIKO_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
2203
2204 switch (event) {
2205 case SND_SOC_DAPM_PRE_PMU:
2206
2207 /* Enableable TX digital mute */
2208 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2209
2210 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
2211 1 << w->shift);
2212 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
2213
2214 dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
2215
2216 dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
2217
2218 tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
2219 dec_hpf_cut_of_freq;
2220
2221 if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
2222
2223 /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
2224 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
2225 CF_MIN_3DB_150HZ << 4);
2226 }
2227
2228 /* enable HPF */
2229 snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
2230
2231 break;
2232
2233 case SND_SOC_DAPM_POST_PMU:
2234
2235 /* Disable TX digital mute */
2236 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
2237
2238 if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
2239 CF_MIN_3DB_150HZ) {
2240
2241 schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
2242 msecs_to_jiffies(300));
2243 }
2244 /* apply the digital gain after the decimator is enabled*/
2245 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
2246 snd_soc_write(codec,
2247 tx_digital_gain_reg[w->shift + offset],
2248 snd_soc_read(codec,
2249 tx_digital_gain_reg[w->shift + offset])
2250 );
2251
2252 break;
2253
2254 case SND_SOC_DAPM_PRE_PMD:
2255
2256 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
2257 cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
2258 break;
2259
2260 case SND_SOC_DAPM_POST_PMD:
2261
2262 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
2263 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
2264 (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
2265
2266 break;
2267 }
2268out:
2269 kfree(widget_name);
2270 return ret;
2271}
2272
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07002273static int taiko_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
Kiran Kandic3b24402012-06-11 00:05:59 -07002274 struct snd_kcontrol *kcontrol, int event)
2275{
2276 struct snd_soc_codec *codec = w->codec;
2277
2278 pr_debug("%s %d %s\n", __func__, event, w->name);
2279
2280 switch (event) {
2281 case SND_SOC_DAPM_PRE_PMU:
2282 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
2283 1 << w->shift, 1 << w->shift);
2284 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_RESET_CTL,
2285 1 << w->shift, 0x0);
2286 break;
2287 case SND_SOC_DAPM_POST_PMU:
2288 /* apply the digital gain after the interpolator is enabled*/
2289 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
2290 snd_soc_write(codec,
2291 rx_digital_gain_reg[w->shift],
2292 snd_soc_read(codec,
2293 rx_digital_gain_reg[w->shift])
2294 );
2295 break;
2296 }
2297 return 0;
2298}
2299
2300static int taiko_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
2301 struct snd_kcontrol *kcontrol, int event)
2302{
2303 switch (event) {
2304 case SND_SOC_DAPM_POST_PMU:
2305 case SND_SOC_DAPM_POST_PMD:
2306 usleep_range(1000, 1000);
2307 break;
2308 }
2309 return 0;
2310}
2311
2312static int taiko_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
2313 struct snd_kcontrol *kcontrol, int event)
2314{
2315 struct snd_soc_codec *codec = w->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07002316 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07002317
2318 pr_debug("%s %d\n", __func__, event);
2319
2320 switch (event) {
2321 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002322 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 1);
Kiran Kandic3b24402012-06-11 00:05:59 -07002323 break;
2324 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002325 wcd9xxx_resmgr_enable_rx_bias(&taiko->resmgr, 0);
Kiran Kandic3b24402012-06-11 00:05:59 -07002326 break;
2327 }
2328 return 0;
2329}
2330static int taiko_hphr_dac_event(struct snd_soc_dapm_widget *w,
2331 struct snd_kcontrol *kcontrol, int event)
2332{
2333 struct snd_soc_codec *codec = w->codec;
2334
2335 pr_debug("%s %s %d\n", __func__, w->name, event);
2336
2337 switch (event) {
2338 case SND_SOC_DAPM_PRE_PMU:
2339 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
2340 break;
2341 case SND_SOC_DAPM_POST_PMD:
2342 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
2343 break;
2344 }
2345 return 0;
2346}
2347
Kiran Kandic3b24402012-06-11 00:05:59 -07002348static int taiko_hph_pa_event(struct snd_soc_dapm_widget *w,
Joonwoo Parka8890262012-10-15 12:04:27 -07002349 struct snd_kcontrol *kcontrol, int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07002350{
2351 struct snd_soc_codec *codec = w->codec;
2352 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07002353 enum wcd9xxx_notify_event e_pre_on, e_post_off;
2354
Kiran Kandi4c56c592012-07-25 11:04:55 -07002355 pr_debug("%s: %s event = %d\n", __func__, w->name, event);
Joonwoo Parka8890262012-10-15 12:04:27 -07002356 if (w->shift == 5) {
2357 e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
2358 e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
2359 } else if (w->shift == 4) {
2360 e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
2361 e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
2362 } else {
2363 pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
2364 return -EINVAL;
2365 }
Kiran Kandic3b24402012-06-11 00:05:59 -07002366
2367 switch (event) {
2368 case SND_SOC_DAPM_PRE_PMU:
Joonwoo Parka8890262012-10-15 12:04:27 -07002369 /* Let MBHC module know PA is turning on */
2370 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
Kiran Kandic3b24402012-06-11 00:05:59 -07002371 break;
2372
Kiran Kandi4c56c592012-07-25 11:04:55 -07002373 case SND_SOC_DAPM_POST_PMU:
Kiran Kandi4c56c592012-07-25 11:04:55 -07002374 usleep_range(10000, 10000);
2375
2376 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_5, 0x02, 0x00);
2377 snd_soc_update_bits(codec, TAIKO_A_NCP_STATIC, 0x20, 0x00);
2378 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x04, 0x04);
2379 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x08, 0x00);
2380
2381 usleep_range(10, 10);
Kiran Kandi4c56c592012-07-25 11:04:55 -07002382 break;
2383
Kiran Kandic3b24402012-06-11 00:05:59 -07002384 case SND_SOC_DAPM_POST_PMD:
Joonwoo Parka8890262012-10-15 12:04:27 -07002385 /* Let MBHC module know PA turned off */
2386 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
2387
2388 /*
2389 * schedule work is required because at the time HPH PA DAPM
Kiran Kandic3b24402012-06-11 00:05:59 -07002390 * event callback is called by DAPM framework, CODEC dapm mutex
2391 * would have been locked while snd_soc_jack_report also
2392 * attempts to acquire same lock.
2393 */
Kiran Kandic3b24402012-06-11 00:05:59 -07002394 pr_debug("%s: sleep 10 ms after %s PA disable.\n", __func__,
Joonwoo Parka8890262012-10-15 12:04:27 -07002395 w->name);
Kiran Kandic3b24402012-06-11 00:05:59 -07002396 usleep_range(10000, 10000);
2397 break;
2398 }
2399 return 0;
2400}
2401
Kiran Kandic3b24402012-06-11 00:05:59 -07002402static const struct snd_soc_dapm_widget taiko_dapm_i2s_widgets[] = {
2403 SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", TAIKO_A_CDC_CLK_RX_I2S_CTL,
2404 4, 0, NULL, 0),
2405 SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", TAIKO_A_CDC_CLK_TX_I2S_CTL, 4,
2406 0, NULL, 0),
2407};
2408
2409static int taiko_lineout_dac_event(struct snd_soc_dapm_widget *w,
2410 struct snd_kcontrol *kcontrol, int event)
2411{
2412 struct snd_soc_codec *codec = w->codec;
2413
2414 pr_debug("%s %s %d\n", __func__, w->name, event);
2415
2416 switch (event) {
2417 case SND_SOC_DAPM_PRE_PMU:
2418 snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
2419 break;
2420
2421 case SND_SOC_DAPM_POST_PMD:
2422 snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
2423 break;
2424 }
2425 return 0;
2426}
2427
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002428static int taiko_spk_dac_event(struct snd_soc_dapm_widget *w,
2429 struct snd_kcontrol *kcontrol, int event)
2430{
2431 pr_debug("%s %s %d\n", __func__, w->name, event);
2432 return 0;
2433}
2434
Kiran Kandic3b24402012-06-11 00:05:59 -07002435static const struct snd_soc_dapm_route audio_i2s_map[] = {
2436 {"RX_I2S_CLK", NULL, "CDC_CONN"},
2437 {"SLIM RX1", NULL, "RX_I2S_CLK"},
2438 {"SLIM RX2", NULL, "RX_I2S_CLK"},
2439 {"SLIM RX3", NULL, "RX_I2S_CLK"},
2440 {"SLIM RX4", NULL, "RX_I2S_CLK"},
2441
2442 {"SLIM TX7", NULL, "TX_I2S_CLK"},
2443 {"SLIM TX8", NULL, "TX_I2S_CLK"},
2444 {"SLIM TX9", NULL, "TX_I2S_CLK"},
2445 {"SLIM TX10", NULL, "TX_I2S_CLK"},
2446};
2447
2448static const struct snd_soc_dapm_route audio_map[] = {
2449 /* SLIMBUS Connections */
Kuirong Wang906ac472012-07-09 12:54:44 -07002450 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
2451 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
2452 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002453
Kuirong Wang906ac472012-07-09 12:54:44 -07002454 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
2455 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
2456 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
2457 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
2458 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
2459 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
2460 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
2461 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
2462 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
2463 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
2464 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
2465 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
2466 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
2467 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
2468 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
2469 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
2470 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
2471 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
2472 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
2473 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
2474 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
2475 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
2476 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
2477 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
2478 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
2479 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
2480 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
2481 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
2482 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
2483 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
2484 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
2485 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
2486 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
2487
Kiran Kandic3b24402012-06-11 00:05:59 -07002488 {"SLIM TX1 MUX", "DEC1", "DEC1 MUX"},
2489
Kiran Kandic3b24402012-06-11 00:05:59 -07002490 {"SLIM TX2 MUX", "DEC2", "DEC2 MUX"},
2491
Kiran Kandic3b24402012-06-11 00:05:59 -07002492 {"SLIM TX3 MUX", "DEC3", "DEC3 MUX"},
2493 {"SLIM TX3 MUX", "RMIX1", "RX1 MIX1"},
2494 {"SLIM TX3 MUX", "RMIX2", "RX2 MIX1"},
2495 {"SLIM TX3 MUX", "RMIX3", "RX3 MIX1"},
2496 {"SLIM TX3 MUX", "RMIX4", "RX4 MIX1"},
2497 {"SLIM TX3 MUX", "RMIX5", "RX5 MIX1"},
2498 {"SLIM TX3 MUX", "RMIX6", "RX6 MIX1"},
2499 {"SLIM TX3 MUX", "RMIX7", "RX7 MIX1"},
2500
Kiran Kandic3b24402012-06-11 00:05:59 -07002501 {"SLIM TX4 MUX", "DEC4", "DEC4 MUX"},
2502
Kiran Kandic3b24402012-06-11 00:05:59 -07002503 {"SLIM TX5 MUX", "DEC5", "DEC5 MUX"},
2504 {"SLIM TX5 MUX", "RMIX1", "RX1 MIX1"},
2505 {"SLIM TX5 MUX", "RMIX2", "RX2 MIX1"},
2506 {"SLIM TX5 MUX", "RMIX3", "RX3 MIX1"},
2507 {"SLIM TX5 MUX", "RMIX4", "RX4 MIX1"},
2508 {"SLIM TX5 MUX", "RMIX5", "RX5 MIX1"},
2509 {"SLIM TX5 MUX", "RMIX6", "RX6 MIX1"},
2510 {"SLIM TX5 MUX", "RMIX7", "RX7 MIX1"},
2511
Kiran Kandic3b24402012-06-11 00:05:59 -07002512 {"SLIM TX6 MUX", "DEC6", "DEC6 MUX"},
2513
Kiran Kandic3b24402012-06-11 00:05:59 -07002514 {"SLIM TX7 MUX", "DEC1", "DEC1 MUX"},
2515 {"SLIM TX7 MUX", "DEC2", "DEC2 MUX"},
2516 {"SLIM TX7 MUX", "DEC3", "DEC3 MUX"},
2517 {"SLIM TX7 MUX", "DEC4", "DEC4 MUX"},
2518 {"SLIM TX7 MUX", "DEC5", "DEC5 MUX"},
2519 {"SLIM TX7 MUX", "DEC6", "DEC6 MUX"},
2520 {"SLIM TX7 MUX", "DEC7", "DEC7 MUX"},
2521 {"SLIM TX7 MUX", "DEC8", "DEC8 MUX"},
2522 {"SLIM TX7 MUX", "DEC9", "DEC9 MUX"},
2523 {"SLIM TX7 MUX", "DEC10", "DEC10 MUX"},
2524 {"SLIM TX7 MUX", "RMIX1", "RX1 MIX1"},
2525 {"SLIM TX7 MUX", "RMIX2", "RX2 MIX1"},
2526 {"SLIM TX7 MUX", "RMIX3", "RX3 MIX1"},
2527 {"SLIM TX7 MUX", "RMIX4", "RX4 MIX1"},
2528 {"SLIM TX7 MUX", "RMIX5", "RX5 MIX1"},
2529 {"SLIM TX7 MUX", "RMIX6", "RX6 MIX1"},
2530 {"SLIM TX7 MUX", "RMIX7", "RX7 MIX1"},
2531
Kiran Kandic3b24402012-06-11 00:05:59 -07002532 {"SLIM TX8 MUX", "DEC1", "DEC1 MUX"},
2533 {"SLIM TX8 MUX", "DEC2", "DEC2 MUX"},
2534 {"SLIM TX8 MUX", "DEC3", "DEC3 MUX"},
2535 {"SLIM TX8 MUX", "DEC4", "DEC4 MUX"},
2536 {"SLIM TX8 MUX", "DEC5", "DEC5 MUX"},
2537 {"SLIM TX8 MUX", "DEC6", "DEC6 MUX"},
2538 {"SLIM TX8 MUX", "DEC7", "DEC7 MUX"},
2539 {"SLIM TX8 MUX", "DEC8", "DEC8 MUX"},
2540 {"SLIM TX8 MUX", "DEC9", "DEC9 MUX"},
2541 {"SLIM TX8 MUX", "DEC10", "DEC10 MUX"},
2542
Kiran Kandic3b24402012-06-11 00:05:59 -07002543 {"SLIM TX9 MUX", "DEC1", "DEC1 MUX"},
2544 {"SLIM TX9 MUX", "DEC2", "DEC2 MUX"},
2545 {"SLIM TX9 MUX", "DEC3", "DEC3 MUX"},
2546 {"SLIM TX9 MUX", "DEC4", "DEC4 MUX"},
2547 {"SLIM TX9 MUX", "DEC5", "DEC5 MUX"},
2548 {"SLIM TX9 MUX", "DEC6", "DEC6 MUX"},
2549 {"SLIM TX9 MUX", "DEC7", "DEC7 MUX"},
2550 {"SLIM TX9 MUX", "DEC8", "DEC8 MUX"},
2551 {"SLIM TX9 MUX", "DEC9", "DEC9 MUX"},
2552 {"SLIM TX9 MUX", "DEC10", "DEC10 MUX"},
2553
Kiran Kandic3b24402012-06-11 00:05:59 -07002554 {"SLIM TX10 MUX", "DEC1", "DEC1 MUX"},
2555 {"SLIM TX10 MUX", "DEC2", "DEC2 MUX"},
2556 {"SLIM TX10 MUX", "DEC3", "DEC3 MUX"},
2557 {"SLIM TX10 MUX", "DEC4", "DEC4 MUX"},
2558 {"SLIM TX10 MUX", "DEC5", "DEC5 MUX"},
2559 {"SLIM TX10 MUX", "DEC6", "DEC6 MUX"},
2560 {"SLIM TX10 MUX", "DEC7", "DEC7 MUX"},
2561 {"SLIM TX10 MUX", "DEC8", "DEC8 MUX"},
2562 {"SLIM TX10 MUX", "DEC9", "DEC9 MUX"},
2563 {"SLIM TX10 MUX", "DEC10", "DEC10 MUX"},
2564
2565 /* Earpiece (RX MIX1) */
2566 {"EAR", NULL, "EAR PA"},
2567 {"EAR PA", NULL, "EAR_PA_MIXER"},
2568 {"EAR_PA_MIXER", NULL, "DAC1"},
2569 {"DAC1", NULL, "CP"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07002570 {"CP", NULL, "CLASS_H_EAR"},
2571 {"CLASS_H_EAR", NULL, "CLASS_H_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002572
2573 {"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
2574 {"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
2575 {"ANC", NULL, "ANC1 FB MUX"},
2576
2577 /* Headset (RX MIX1 and RX MIX2) */
2578 {"HEADPHONE", NULL, "HPHL"},
2579 {"HEADPHONE", NULL, "HPHR"},
2580
2581 {"HPHL", NULL, "HPHL_PA_MIXER"},
2582 {"HPHL_PA_MIXER", NULL, "HPHL DAC"},
2583
2584 {"HPHR", NULL, "HPHR_PA_MIXER"},
2585 {"HPHR_PA_MIXER", NULL, "HPHR DAC"},
2586
2587 {"HPHL DAC", NULL, "CP"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07002588 {"CP", NULL, "CLASS_H_HPH_L"},
2589 {"CLASS_H_HPH_L", NULL, "CLASS_H_CLK"},
2590
Kiran Kandic3b24402012-06-11 00:05:59 -07002591 {"HPHR DAC", NULL, "CP"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07002592 {"CP", NULL, "CLASS_H_HPH_R"},
2593 {"CLASS_H_HPH_R", NULL, "CLASS_H_CLK"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002594
2595 {"ANC", NULL, "ANC1 MUX"},
2596 {"ANC", NULL, "ANC2 MUX"},
2597 {"ANC1 MUX", "ADC1", "ADC1"},
2598 {"ANC1 MUX", "ADC2", "ADC2"},
2599 {"ANC1 MUX", "ADC3", "ADC3"},
2600 {"ANC1 MUX", "ADC4", "ADC4"},
2601 {"ANC2 MUX", "ADC1", "ADC1"},
2602 {"ANC2 MUX", "ADC2", "ADC2"},
2603 {"ANC2 MUX", "ADC3", "ADC3"},
2604 {"ANC2 MUX", "ADC4", "ADC4"},
2605
2606 {"ANC", NULL, "CDC_CONN"},
2607
2608 {"DAC1", "Switch", "RX1 CHAIN"},
2609 {"HPHL DAC", "Switch", "RX1 CHAIN"},
2610 {"HPHR DAC", NULL, "RX2 CHAIN"},
2611
2612 {"LINEOUT1", NULL, "LINEOUT1 PA"},
2613 {"LINEOUT2", NULL, "LINEOUT2 PA"},
2614 {"LINEOUT3", NULL, "LINEOUT3 PA"},
2615 {"LINEOUT4", NULL, "LINEOUT4 PA"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002616 {"SPK_OUT", NULL, "SPK PA"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002617
2618 {"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
2619 {"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
2620 {"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
2621 {"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
2622 {"LINEOUT3 PA", NULL, "LINEOUT3_PA_MIXER"},
2623 {"LINEOUT3_PA_MIXER", NULL, "LINEOUT3 DAC"},
2624 {"LINEOUT4 PA", NULL, "LINEOUT4_PA_MIXER"},
2625 {"LINEOUT4_PA_MIXER", NULL, "LINEOUT4 DAC"},
2626
2627 {"LINEOUT1 DAC", NULL, "RX3 MIX1"},
2628
2629 {"RX4 DSM MUX", "DSM_INV", "RX3 MIX1"},
2630 {"RX4 DSM MUX", "CIC_OUT", "RX4 MIX1"},
2631 {"LINEOUT3 DAC", NULL, "RX4 DSM MUX"},
2632
2633 {"LINEOUT2 DAC", NULL, "RX5 MIX1"},
2634
2635 {"RX6 DSM MUX", "DSM_INV", "RX5 MIX1"},
2636 {"RX6 DSM MUX", "CIC_OUT", "RX6 MIX1"},
2637 {"LINEOUT4 DAC", NULL, "RX6 DSM MUX"},
2638
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002639 {"SPK PA", NULL, "SPK DAC"},
Kiran Kandid2b46332012-10-05 12:04:00 -07002640 {"SPK DAC", NULL, "RX7 MIX2"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002641
Kiran Kandic3b24402012-06-11 00:05:59 -07002642 {"RX1 CHAIN", NULL, "RX1 MIX2"},
2643 {"RX2 CHAIN", NULL, "RX2 MIX2"},
2644 {"RX1 CHAIN", NULL, "ANC"},
2645 {"RX2 CHAIN", NULL, "ANC"},
2646
Kiran Kandi4c56c592012-07-25 11:04:55 -07002647 {"CLASS_H_CLK", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002648 {"LINEOUT1 DAC", NULL, "RX_BIAS"},
2649 {"LINEOUT2 DAC", NULL, "RX_BIAS"},
2650 {"LINEOUT3 DAC", NULL, "RX_BIAS"},
2651 {"LINEOUT4 DAC", NULL, "RX_BIAS"},
Joonwoo Park7680b9f2012-07-13 11:36:48 -07002652 {"SPK DAC", NULL, "RX_BIAS"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002653
2654 {"RX1 MIX1", NULL, "COMP1_CLK"},
2655 {"RX2 MIX1", NULL, "COMP1_CLK"},
2656 {"RX3 MIX1", NULL, "COMP2_CLK"},
2657 {"RX5 MIX1", NULL, "COMP2_CLK"},
2658
Kiran Kandic3b24402012-06-11 00:05:59 -07002659 {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
2660 {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
2661 {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
2662 {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
2663 {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
2664 {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
2665 {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
2666 {"RX4 MIX1", NULL, "RX4 MIX1 INP1"},
2667 {"RX4 MIX1", NULL, "RX4 MIX1 INP2"},
2668 {"RX5 MIX1", NULL, "RX5 MIX1 INP1"},
2669 {"RX5 MIX1", NULL, "RX5 MIX1 INP2"},
2670 {"RX6 MIX1", NULL, "RX6 MIX1 INP1"},
2671 {"RX6 MIX1", NULL, "RX6 MIX1 INP2"},
2672 {"RX7 MIX1", NULL, "RX7 MIX1 INP1"},
2673 {"RX7 MIX1", NULL, "RX7 MIX1 INP2"},
2674 {"RX1 MIX2", NULL, "RX1 MIX1"},
2675 {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
2676 {"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
2677 {"RX2 MIX2", NULL, "RX2 MIX1"},
2678 {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
2679 {"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
2680 {"RX7 MIX2", NULL, "RX7 MIX1"},
2681 {"RX7 MIX2", NULL, "RX7 MIX2 INP1"},
2682 {"RX7 MIX2", NULL, "RX7 MIX2 INP2"},
2683
Kuirong Wang906ac472012-07-09 12:54:44 -07002684 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
2685 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
2686 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
2687 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
2688 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
2689 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
2690 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
2691 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
2692 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
2693 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
2694 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
2695 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
2696 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
2697 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
2698 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
2699 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
2700 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
2701 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
2702 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
2703 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
2704 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
2705 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
2706 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
2707 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
2708
2709 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
2710 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
2711 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
2712 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
2713 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
2714 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
2715 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
2716
Kiran Kandic3b24402012-06-11 00:05:59 -07002717 {"RX1 MIX1 INP1", "RX1", "SLIM RX1"},
2718 {"RX1 MIX1 INP1", "RX2", "SLIM RX2"},
2719 {"RX1 MIX1 INP1", "RX3", "SLIM RX3"},
2720 {"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
2721 {"RX1 MIX1 INP1", "RX5", "SLIM RX5"},
2722 {"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
2723 {"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
2724 {"RX1 MIX1 INP1", "IIR1", "IIR1"},
2725 {"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
2726 {"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
2727 {"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
2728 {"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
2729 {"RX1 MIX1 INP2", "RX5", "SLIM RX5"},
2730 {"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
2731 {"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
2732 {"RX1 MIX1 INP2", "IIR1", "IIR1"},
2733 {"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
2734 {"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
2735 {"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
2736 {"RX1 MIX1 INP3", "RX4", "SLIM RX4"},
2737 {"RX1 MIX1 INP3", "RX5", "SLIM RX5"},
2738 {"RX1 MIX1 INP3", "RX6", "SLIM RX6"},
2739 {"RX1 MIX1 INP3", "RX7", "SLIM RX7"},
2740 {"RX2 MIX1 INP1", "RX1", "SLIM RX1"},
2741 {"RX2 MIX1 INP1", "RX2", "SLIM RX2"},
2742 {"RX2 MIX1 INP1", "RX3", "SLIM RX3"},
2743 {"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
2744 {"RX2 MIX1 INP1", "RX5", "SLIM RX5"},
2745 {"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
2746 {"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
2747 {"RX2 MIX1 INP1", "IIR1", "IIR1"},
2748 {"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
2749 {"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
2750 {"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
2751 {"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
2752 {"RX2 MIX1 INP2", "RX5", "SLIM RX5"},
2753 {"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
2754 {"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
2755 {"RX2 MIX1 INP2", "IIR1", "IIR1"},
2756 {"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
2757 {"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
2758 {"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
2759 {"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
2760 {"RX3 MIX1 INP1", "RX5", "SLIM RX5"},
2761 {"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
2762 {"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
2763 {"RX3 MIX1 INP1", "IIR1", "IIR1"},
2764 {"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
2765 {"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
2766 {"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
2767 {"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
2768 {"RX3 MIX1 INP2", "RX5", "SLIM RX5"},
2769 {"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
2770 {"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
2771 {"RX3 MIX1 INP2", "IIR1", "IIR1"},
2772 {"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
2773 {"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
2774 {"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
2775 {"RX4 MIX1 INP1", "RX4", "SLIM RX4"},
2776 {"RX4 MIX1 INP1", "RX5", "SLIM RX5"},
2777 {"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
2778 {"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
2779 {"RX4 MIX1 INP1", "IIR1", "IIR1"},
2780 {"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
2781 {"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
2782 {"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
2783 {"RX4 MIX1 INP2", "RX5", "SLIM RX5"},
2784 {"RX4 MIX1 INP2", "RX4", "SLIM RX4"},
2785 {"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
2786 {"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
2787 {"RX4 MIX1 INP2", "IIR1", "IIR1"},
2788 {"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
2789 {"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
2790 {"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
2791 {"RX5 MIX1 INP1", "RX4", "SLIM RX4"},
2792 {"RX5 MIX1 INP1", "RX5", "SLIM RX5"},
2793 {"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
2794 {"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
2795 {"RX5 MIX1 INP1", "IIR1", "IIR1"},
2796 {"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
2797 {"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
2798 {"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
2799 {"RX5 MIX1 INP2", "RX4", "SLIM RX4"},
2800 {"RX5 MIX1 INP2", "RX5", "SLIM RX5"},
2801 {"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
2802 {"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
2803 {"RX5 MIX1 INP2", "IIR1", "IIR1"},
2804 {"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
2805 {"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
2806 {"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
2807 {"RX6 MIX1 INP1", "RX4", "SLIM RX4"},
2808 {"RX6 MIX1 INP1", "RX5", "SLIM RX5"},
2809 {"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
2810 {"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
2811 {"RX6 MIX1 INP1", "IIR1", "IIR1"},
2812 {"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
2813 {"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
2814 {"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
2815 {"RX6 MIX1 INP2", "RX4", "SLIM RX4"},
2816 {"RX6 MIX1 INP2", "RX5", "SLIM RX5"},
2817 {"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
2818 {"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
2819 {"RX6 MIX1 INP2", "IIR1", "IIR1"},
2820 {"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
2821 {"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
2822 {"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
2823 {"RX7 MIX1 INP1", "RX4", "SLIM RX4"},
2824 {"RX7 MIX1 INP1", "RX5", "SLIM RX5"},
2825 {"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
2826 {"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
2827 {"RX7 MIX1 INP1", "IIR1", "IIR1"},
2828 {"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
2829 {"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
2830 {"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
2831 {"RX7 MIX1 INP2", "RX4", "SLIM RX4"},
2832 {"RX7 MIX1 INP2", "RX5", "SLIM RX5"},
2833 {"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
2834 {"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
2835 {"RX7 MIX1 INP2", "IIR1", "IIR1"},
2836 {"RX1 MIX2 INP1", "IIR1", "IIR1"},
2837 {"RX1 MIX2 INP2", "IIR1", "IIR1"},
2838 {"RX2 MIX2 INP1", "IIR1", "IIR1"},
2839 {"RX2 MIX2 INP2", "IIR1", "IIR1"},
2840 {"RX7 MIX2 INP1", "IIR1", "IIR1"},
2841 {"RX7 MIX2 INP2", "IIR1", "IIR1"},
2842
2843 /* Decimator Inputs */
2844 {"DEC1 MUX", "DMIC1", "DMIC1"},
2845 {"DEC1 MUX", "ADC6", "ADC6"},
2846 {"DEC1 MUX", NULL, "CDC_CONN"},
2847 {"DEC2 MUX", "DMIC2", "DMIC2"},
2848 {"DEC2 MUX", "ADC5", "ADC5"},
2849 {"DEC2 MUX", NULL, "CDC_CONN"},
2850 {"DEC3 MUX", "DMIC3", "DMIC3"},
2851 {"DEC3 MUX", "ADC4", "ADC4"},
2852 {"DEC3 MUX", NULL, "CDC_CONN"},
2853 {"DEC4 MUX", "DMIC4", "DMIC4"},
2854 {"DEC4 MUX", "ADC3", "ADC3"},
2855 {"DEC4 MUX", NULL, "CDC_CONN"},
2856 {"DEC5 MUX", "DMIC5", "DMIC5"},
2857 {"DEC5 MUX", "ADC2", "ADC2"},
2858 {"DEC5 MUX", NULL, "CDC_CONN"},
2859 {"DEC6 MUX", "DMIC6", "DMIC6"},
2860 {"DEC6 MUX", "ADC1", "ADC1"},
2861 {"DEC6 MUX", NULL, "CDC_CONN"},
2862 {"DEC7 MUX", "DMIC1", "DMIC1"},
2863 {"DEC7 MUX", "DMIC6", "DMIC6"},
2864 {"DEC7 MUX", "ADC1", "ADC1"},
2865 {"DEC7 MUX", "ADC6", "ADC6"},
2866 {"DEC7 MUX", NULL, "CDC_CONN"},
2867 {"DEC8 MUX", "DMIC2", "DMIC2"},
2868 {"DEC8 MUX", "DMIC5", "DMIC5"},
2869 {"DEC8 MUX", "ADC2", "ADC2"},
2870 {"DEC8 MUX", "ADC5", "ADC5"},
2871 {"DEC8 MUX", NULL, "CDC_CONN"},
2872 {"DEC9 MUX", "DMIC4", "DMIC4"},
2873 {"DEC9 MUX", "DMIC5", "DMIC5"},
2874 {"DEC9 MUX", "ADC2", "ADC2"},
2875 {"DEC9 MUX", "ADC3", "ADC3"},
2876 {"DEC9 MUX", NULL, "CDC_CONN"},
2877 {"DEC10 MUX", "DMIC3", "DMIC3"},
2878 {"DEC10 MUX", "DMIC6", "DMIC6"},
2879 {"DEC10 MUX", "ADC1", "ADC1"},
2880 {"DEC10 MUX", "ADC4", "ADC4"},
2881 {"DEC10 MUX", NULL, "CDC_CONN"},
2882
2883 /* ADC Connections */
2884 {"ADC1", NULL, "AMIC1"},
2885 {"ADC2", NULL, "AMIC2"},
2886 {"ADC3", NULL, "AMIC3"},
2887 {"ADC4", NULL, "AMIC4"},
2888 {"ADC5", NULL, "AMIC5"},
2889 {"ADC6", NULL, "AMIC6"},
2890
2891 /* AUX PGA Connections */
Kiran Kandic3b24402012-06-11 00:05:59 -07002892 {"EAR_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
Kiran Kandi4c56c592012-07-25 11:04:55 -07002893 {"HPHL_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
2894 {"HPHR_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
2895 {"LINEOUT1_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
2896 {"LINEOUT2_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
2897 {"LINEOUT3_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
2898 {"LINEOUT4_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
Kiran Kandic3b24402012-06-11 00:05:59 -07002899 {"AUX_PGA_Left", NULL, "AMIC5"},
2900 {"AUX_PGA_Right", NULL, "AMIC6"},
2901
Kiran Kandic3b24402012-06-11 00:05:59 -07002902 {"IIR1", NULL, "IIR1 INP1 MUX"},
2903 {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
2904 {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
2905 {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
2906 {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
2907 {"IIR1 INP1 MUX", "DEC5", "DEC5 MUX"},
2908 {"IIR1 INP1 MUX", "DEC6", "DEC6 MUX"},
2909 {"IIR1 INP1 MUX", "DEC7", "DEC7 MUX"},
2910 {"IIR1 INP1 MUX", "DEC8", "DEC8 MUX"},
2911 {"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
2912 {"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
2913
2914 {"MIC BIAS1 Internal1", NULL, "LDO_H"},
2915 {"MIC BIAS1 Internal2", NULL, "LDO_H"},
2916 {"MIC BIAS1 External", NULL, "LDO_H"},
2917 {"MIC BIAS2 Internal1", NULL, "LDO_H"},
2918 {"MIC BIAS2 Internal2", NULL, "LDO_H"},
2919 {"MIC BIAS2 Internal3", NULL, "LDO_H"},
2920 {"MIC BIAS2 External", NULL, "LDO_H"},
2921 {"MIC BIAS3 Internal1", NULL, "LDO_H"},
2922 {"MIC BIAS3 Internal2", NULL, "LDO_H"},
2923 {"MIC BIAS3 External", NULL, "LDO_H"},
2924 {"MIC BIAS4 External", NULL, "LDO_H"},
2925};
2926
2927static int taiko_readable(struct snd_soc_codec *ssc, unsigned int reg)
2928{
2929 return taiko_reg_readable[reg];
2930}
2931
2932static bool taiko_is_digital_gain_register(unsigned int reg)
2933{
2934 bool rtn = false;
2935 switch (reg) {
2936 case TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL:
2937 case TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL:
2938 case TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL:
2939 case TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL:
2940 case TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL:
2941 case TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL:
2942 case TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL:
2943 case TAIKO_A_CDC_TX1_VOL_CTL_GAIN:
2944 case TAIKO_A_CDC_TX2_VOL_CTL_GAIN:
2945 case TAIKO_A_CDC_TX3_VOL_CTL_GAIN:
2946 case TAIKO_A_CDC_TX4_VOL_CTL_GAIN:
2947 case TAIKO_A_CDC_TX5_VOL_CTL_GAIN:
2948 case TAIKO_A_CDC_TX6_VOL_CTL_GAIN:
2949 case TAIKO_A_CDC_TX7_VOL_CTL_GAIN:
2950 case TAIKO_A_CDC_TX8_VOL_CTL_GAIN:
2951 case TAIKO_A_CDC_TX9_VOL_CTL_GAIN:
2952 case TAIKO_A_CDC_TX10_VOL_CTL_GAIN:
2953 rtn = true;
2954 break;
2955 default:
2956 break;
2957 }
2958 return rtn;
2959}
2960
2961static int taiko_volatile(struct snd_soc_codec *ssc, unsigned int reg)
2962{
2963 /* Registers lower than 0x100 are top level registers which can be
2964 * written by the Taiko core driver.
2965 */
2966
2967 if ((reg >= TAIKO_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
2968 return 1;
2969
2970 /* IIR Coeff registers are not cacheable */
2971 if ((reg >= TAIKO_A_CDC_IIR1_COEF_B1_CTL) &&
2972 (reg <= TAIKO_A_CDC_IIR2_COEF_B2_CTL))
2973 return 1;
2974
2975 /* Digital gain register is not cacheable so we have to write
2976 * the setting even it is the same
2977 */
2978 if (taiko_is_digital_gain_register(reg))
2979 return 1;
2980
2981 /* HPH status registers */
2982 if (reg == TAIKO_A_RX_HPH_L_STATUS || reg == TAIKO_A_RX_HPH_R_STATUS)
2983 return 1;
2984
Joonwoo Parka8890262012-10-15 12:04:27 -07002985 if (reg == TAIKO_A_MBHC_INSERT_DET_STATUS)
2986 return 1;
2987
Kiran Kandic3b24402012-06-11 00:05:59 -07002988 return 0;
2989}
2990
2991#define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
2992static int taiko_write(struct snd_soc_codec *codec, unsigned int reg,
2993 unsigned int value)
2994{
2995 int ret;
Kuirong Wang906ac472012-07-09 12:54:44 -07002996
2997 if (reg == SND_SOC_NOPM)
2998 return 0;
2999
Kiran Kandic3b24402012-06-11 00:05:59 -07003000 BUG_ON(reg > TAIKO_MAX_REGISTER);
3001
3002 if (!taiko_volatile(codec, reg)) {
3003 ret = snd_soc_cache_write(codec, reg, value);
3004 if (ret != 0)
3005 dev_err(codec->dev, "Cache write to %x failed: %d\n",
3006 reg, ret);
3007 }
3008
3009 return wcd9xxx_reg_write(codec->control_data, reg, value);
3010}
3011static unsigned int taiko_read(struct snd_soc_codec *codec,
3012 unsigned int reg)
3013{
3014 unsigned int val;
3015 int ret;
3016
Kuirong Wang906ac472012-07-09 12:54:44 -07003017 if (reg == SND_SOC_NOPM)
3018 return 0;
3019
Kiran Kandic3b24402012-06-11 00:05:59 -07003020 BUG_ON(reg > TAIKO_MAX_REGISTER);
3021
3022 if (!taiko_volatile(codec, reg) && taiko_readable(codec, reg) &&
3023 reg < codec->driver->reg_cache_size) {
3024 ret = snd_soc_cache_read(codec, reg, &val);
3025 if (ret >= 0) {
3026 return val;
3027 } else
3028 dev_err(codec->dev, "Cache read from %x failed: %d\n",
3029 reg, ret);
3030 }
3031
3032 val = wcd9xxx_reg_read(codec->control_data, reg);
3033 return val;
3034}
3035
Kiran Kandic3b24402012-06-11 00:05:59 -07003036static int taiko_startup(struct snd_pcm_substream *substream,
3037 struct snd_soc_dai *dai)
3038{
3039 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
3040 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
3041 substream->name, substream->stream);
3042 if ((taiko_core != NULL) &&
3043 (taiko_core->dev != NULL) &&
3044 (taiko_core->dev->parent != NULL))
3045 pm_runtime_get_sync(taiko_core->dev->parent);
3046
3047 return 0;
3048}
3049
3050static void taiko_shutdown(struct snd_pcm_substream *substream,
3051 struct snd_soc_dai *dai)
3052{
3053 struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
3054 pr_debug("%s(): substream = %s stream = %d\n" , __func__,
3055 substream->name, substream->stream);
3056 if ((taiko_core != NULL) &&
3057 (taiko_core->dev != NULL) &&
3058 (taiko_core->dev->parent != NULL)) {
3059 pm_runtime_mark_last_busy(taiko_core->dev->parent);
3060 pm_runtime_put(taiko_core->dev->parent);
3061 }
3062}
3063
3064int taiko_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm)
3065{
3066 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3067
3068 pr_debug("%s: mclk_enable = %u, dapm = %d\n", __func__, mclk_enable,
3069 dapm);
Joonwoo Parka8890262012-10-15 12:04:27 -07003070
3071 WCD9XXX_BCL_LOCK(&taiko->resmgr);
Kiran Kandic3b24402012-06-11 00:05:59 -07003072 if (mclk_enable) {
Joonwoo Parka8890262012-10-15 12:04:27 -07003073 wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
3074 WCD9XXX_BANDGAP_AUDIO_MODE);
3075 wcd9xxx_resmgr_get_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
Kiran Kandic3b24402012-06-11 00:05:59 -07003076 } else {
Joonwoo Parka8890262012-10-15 12:04:27 -07003077 /* Put clock and BG */
3078 wcd9xxx_resmgr_put_clk_block(&taiko->resmgr, WCD9XXX_CLK_MCLK);
3079 wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
3080 WCD9XXX_BANDGAP_AUDIO_MODE);
Kiran Kandic3b24402012-06-11 00:05:59 -07003081 }
Joonwoo Parka8890262012-10-15 12:04:27 -07003082 WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
3083
Kiran Kandic3b24402012-06-11 00:05:59 -07003084 return 0;
3085}
3086
3087static int taiko_set_dai_sysclk(struct snd_soc_dai *dai,
3088 int clk_id, unsigned int freq, int dir)
3089{
3090 pr_debug("%s\n", __func__);
3091 return 0;
3092}
3093
3094static int taiko_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3095{
3096 u8 val = 0;
3097 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
3098
3099 pr_debug("%s\n", __func__);
3100 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3101 case SND_SOC_DAIFMT_CBS_CFS:
3102 /* CPU is master */
3103 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3104 if (dai->id == AIF1_CAP)
3105 snd_soc_update_bits(dai->codec,
3106 TAIKO_A_CDC_CLK_TX_I2S_CTL,
3107 TAIKO_I2S_MASTER_MODE_MASK, 0);
3108 else if (dai->id == AIF1_PB)
3109 snd_soc_update_bits(dai->codec,
3110 TAIKO_A_CDC_CLK_RX_I2S_CTL,
3111 TAIKO_I2S_MASTER_MODE_MASK, 0);
3112 }
3113 break;
3114 case SND_SOC_DAIFMT_CBM_CFM:
3115 /* CPU is slave */
3116 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3117 val = TAIKO_I2S_MASTER_MODE_MASK;
3118 if (dai->id == AIF1_CAP)
3119 snd_soc_update_bits(dai->codec,
3120 TAIKO_A_CDC_CLK_TX_I2S_CTL, val, val);
3121 else if (dai->id == AIF1_PB)
3122 snd_soc_update_bits(dai->codec,
3123 TAIKO_A_CDC_CLK_RX_I2S_CTL, val, val);
3124 }
3125 break;
3126 default:
3127 return -EINVAL;
3128 }
3129 return 0;
3130}
3131
3132static int taiko_set_channel_map(struct snd_soc_dai *dai,
3133 unsigned int tx_num, unsigned int *tx_slot,
3134 unsigned int rx_num, unsigned int *rx_slot)
3135
3136{
3137 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07003138 struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07003139 if (!tx_slot && !rx_slot) {
3140 pr_err("%s: Invalid\n", __func__);
3141 return -EINVAL;
3142 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003143 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
3144 "taiko->intf_type %d\n",
3145 __func__, dai->name, dai->id, tx_num, rx_num,
3146 taiko->intf_type);
Kiran Kandic3b24402012-06-11 00:05:59 -07003147
Kuirong Wang906ac472012-07-09 12:54:44 -07003148 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3149 wcd9xxx_init_slimslave(core, core->slim->laddr,
3150 tx_num, tx_slot, rx_num, rx_slot);
3151 return 0;
3152}
3153
3154static int taiko_get_channel_map(struct snd_soc_dai *dai,
3155 unsigned int *tx_num, unsigned int *tx_slot,
3156 unsigned int *rx_num, unsigned int *rx_slot)
3157
3158{
3159 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(dai->codec);
3160 u32 i = 0;
3161 struct wcd9xxx_ch *ch;
3162
3163 switch (dai->id) {
3164 case AIF1_PB:
3165 case AIF2_PB:
3166 case AIF3_PB:
3167 if (!rx_slot || !rx_num) {
3168 pr_err("%s: Invalid rx_slot %d or rx_num %d\n",
3169 __func__, (u32) rx_slot, (u32) rx_num);
3170 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07003171 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003172 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
3173 list) {
3174 pr_debug("%s: tx_slot[%d] %d, ch->ch_num %d\n",
3175 __func__, i, tx_slot[i], ch->ch_num);
3176 rx_slot[i++] = ch->ch_num;
3177 }
3178 pr_debug("%s: rx_num %d\n", __func__, i);
3179 *rx_num = i;
3180 break;
3181 case AIF1_CAP:
3182 case AIF2_CAP:
3183 case AIF3_CAP:
3184 if (!tx_slot || !tx_num) {
3185 pr_err("%s: Invalid tx_slot %d or tx_num %d\n",
3186 __func__, (u32) tx_slot, (u32) tx_num);
3187 return -EINVAL;
3188 }
3189 list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
3190 list) {
3191 pr_debug("%s: tx_slot[%d] %d, ch->ch_num %d\n",
3192 __func__, i, tx_slot[i], ch->ch_num);
3193 tx_slot[i++] = ch->ch_num;
3194 }
3195 pr_debug("%s: tx_num %d\n", __func__, i);
3196 *tx_num = i;
3197 break;
3198
3199 default:
3200 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
3201 break;
3202 }
3203
3204 return 0;
3205}
3206
3207static int taiko_set_interpolator_rate(struct snd_soc_dai *dai,
3208 u8 rx_fs_rate_reg_val, u32 compander_fs, u32 sample_rate)
3209{
3210 u32 j;
3211 u8 rx_mix1_inp;
3212 u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
3213 u16 rx_fs_reg;
3214 u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
3215 struct snd_soc_codec *codec = dai->codec;
3216 struct wcd9xxx_ch *ch;
3217 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3218
3219 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
3220 /* for RX port starting from 16 instead of 10 like tabla */
3221 rx_mix1_inp = ch->port + RX_MIX1_INP_SEL_RX1 -
3222 TAIKO_TX_PORT_NUMBER;
3223 if ((rx_mix1_inp < RX_MIX1_INP_SEL_RX1) ||
3224 (rx_mix1_inp > RX_MIX1_INP_SEL_RX7)) {
3225 pr_err("%s: Invalid TAIKO_RX%u port. Dai ID is %d\n",
3226 __func__, rx_mix1_inp - 5 , dai->id);
3227 return -EINVAL;
3228 }
3229
3230 rx_mix_1_reg_1 = TAIKO_A_CDC_CONN_RX1_B1_CTL;
3231
3232 for (j = 0; j < NUM_INTERPOLATORS; j++) {
3233 rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
3234
3235 rx_mix_1_reg_1_val = snd_soc_read(codec,
3236 rx_mix_1_reg_1);
3237 rx_mix_1_reg_2_val = snd_soc_read(codec,
3238 rx_mix_1_reg_2);
3239
3240 if (((rx_mix_1_reg_1_val & 0x0F) == rx_mix1_inp) ||
3241 (((rx_mix_1_reg_1_val >> 4) & 0x0F)
3242 == rx_mix1_inp) ||
3243 ((rx_mix_1_reg_2_val & 0x0F) == rx_mix1_inp)) {
3244
3245 rx_fs_reg = TAIKO_A_CDC_RX1_B5_CTL + 8 * j;
3246
3247 pr_debug("%s: AIF_PB DAI(%d) connected to RX%u\n",
3248 __func__, dai->id, j + 1);
3249
3250 pr_debug("%s: set RX%u sample rate to %u\n",
3251 __func__, j + 1, sample_rate);
3252
3253 snd_soc_update_bits(codec, rx_fs_reg,
3254 0xE0, rx_fs_rate_reg_val);
3255
3256 if (comp_rx_path[j] < COMPANDER_MAX)
3257 taiko->comp_fs[comp_rx_path[j]]
3258 = compander_fs;
3259 }
3260 if (j <= 2)
3261 rx_mix_1_reg_1 += 3;
3262 else
3263 rx_mix_1_reg_1 += 2;
Kiran Kandic3b24402012-06-11 00:05:59 -07003264 }
3265 }
3266 return 0;
3267}
3268
Kuirong Wang906ac472012-07-09 12:54:44 -07003269static int taiko_set_decimator_rate(struct snd_soc_dai *dai,
3270 u8 tx_fs_rate_reg_val, u32 sample_rate)
Kiran Kandic3b24402012-06-11 00:05:59 -07003271{
Kuirong Wang906ac472012-07-09 12:54:44 -07003272 struct snd_soc_codec *codec = dai->codec;
3273 struct wcd9xxx_ch *ch;
3274 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
3275 u32 tx_port;
3276 u16 tx_port_reg, tx_fs_reg;
3277 u8 tx_port_reg_val;
3278 s8 decimator;
Kiran Kandic3b24402012-06-11 00:05:59 -07003279
Kuirong Wang906ac472012-07-09 12:54:44 -07003280 list_for_each_entry(ch, &taiko->dai[dai->id].wcd9xxx_ch_list, list) {
Kiran Kandic3b24402012-06-11 00:05:59 -07003281
Kuirong Wang906ac472012-07-09 12:54:44 -07003282 tx_port = ch->port + 1;
3283 pr_debug("%s: dai->id = %d, tx_port = %d",
3284 __func__, dai->id, tx_port);
3285
3286 if ((tx_port < 1) || (tx_port > NUM_DECIMATORS)) {
3287 pr_err("%s: Invalid SLIM TX%u port. DAI ID is %d\n",
3288 __func__, tx_port, dai->id);
3289 return -EINVAL;
3290 }
3291
3292 tx_port_reg = TAIKO_A_CDC_CONN_TX_SB_B1_CTL + (tx_port - 1);
3293 tx_port_reg_val = snd_soc_read(codec, tx_port_reg);
3294
3295 decimator = 0;
3296
3297 if ((tx_port >= 1) && (tx_port <= 6)) {
3298
3299 tx_port_reg_val = tx_port_reg_val & 0x0F;
3300 if (tx_port_reg_val == 0x8)
3301 decimator = tx_port;
3302
3303 } else if ((tx_port >= 7) && (tx_port <= NUM_DECIMATORS)) {
3304
3305 tx_port_reg_val = tx_port_reg_val & 0x1F;
3306
3307 if ((tx_port_reg_val >= 0x8) &&
3308 (tx_port_reg_val <= 0x11)) {
3309
3310 decimator = (tx_port_reg_val - 0x8) + 1;
3311 }
3312 }
3313
3314 if (decimator) { /* SLIM_TX port has a DEC as input */
3315
3316 tx_fs_reg = TAIKO_A_CDC_TX1_CLK_FS_CTL +
3317 8 * (decimator - 1);
3318
3319 pr_debug("%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
3320 __func__, decimator, tx_port, sample_rate);
3321
3322 snd_soc_update_bits(codec, tx_fs_reg, 0x07,
3323 tx_fs_rate_reg_val);
3324
3325 } else {
3326 if ((tx_port_reg_val >= 0x1) &&
3327 (tx_port_reg_val <= 0x7)) {
3328
3329 pr_debug("%s: RMIX%u going to SLIM TX%u\n",
3330 __func__, tx_port_reg_val, tx_port);
3331
3332 } else if ((tx_port_reg_val >= 0x8) &&
3333 (tx_port_reg_val <= 0x11)) {
3334
3335 pr_err("%s: ERROR: Should not be here\n",
3336 __func__);
3337 pr_err("%s: ERROR: DEC connected to SLIM TX%u\n",
3338 __func__, tx_port);
3339 return -EINVAL;
3340
3341 } else if (tx_port_reg_val == 0) {
3342 pr_debug("%s: no signal to SLIM TX%u\n",
3343 __func__, tx_port);
3344 } else {
3345 pr_err("%s: ERROR: wrong signal to SLIM TX%u\n",
3346 __func__, tx_port);
3347 pr_err("%s: ERROR: wrong signal = %u\n",
3348 __func__, tx_port_reg_val);
3349 return -EINVAL;
3350 }
3351 }
Kiran Kandic3b24402012-06-11 00:05:59 -07003352 }
Kiran Kandic3b24402012-06-11 00:05:59 -07003353 return 0;
3354}
3355
3356static int taiko_hw_params(struct snd_pcm_substream *substream,
3357 struct snd_pcm_hw_params *params,
3358 struct snd_soc_dai *dai)
3359{
3360 struct snd_soc_codec *codec = dai->codec;
3361 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec);
Kuirong Wang906ac472012-07-09 12:54:44 -07003362 u8 tx_fs_rate, rx_fs_rate;
Kiran Kandic3b24402012-06-11 00:05:59 -07003363 u32 compander_fs;
Kuirong Wang906ac472012-07-09 12:54:44 -07003364 int ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07003365
3366 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
3367 dai->name, dai->id, params_rate(params),
3368 params_channels(params));
3369
3370 switch (params_rate(params)) {
3371 case 8000:
3372 tx_fs_rate = 0x00;
3373 rx_fs_rate = 0x00;
3374 compander_fs = COMPANDER_FS_8KHZ;
3375 break;
3376 case 16000:
3377 tx_fs_rate = 0x01;
3378 rx_fs_rate = 0x20;
3379 compander_fs = COMPANDER_FS_16KHZ;
3380 break;
3381 case 32000:
3382 tx_fs_rate = 0x02;
3383 rx_fs_rate = 0x40;
3384 compander_fs = COMPANDER_FS_32KHZ;
3385 break;
3386 case 48000:
3387 tx_fs_rate = 0x03;
3388 rx_fs_rate = 0x60;
3389 compander_fs = COMPANDER_FS_48KHZ;
3390 break;
3391 case 96000:
3392 tx_fs_rate = 0x04;
3393 rx_fs_rate = 0x80;
3394 compander_fs = COMPANDER_FS_96KHZ;
3395 break;
3396 case 192000:
3397 tx_fs_rate = 0x05;
3398 rx_fs_rate = 0xA0;
3399 compander_fs = COMPANDER_FS_192KHZ;
3400 break;
3401 default:
3402 pr_err("%s: Invalid sampling rate %d\n", __func__,
Kuirong Wang906ac472012-07-09 12:54:44 -07003403 params_rate(params));
Kiran Kandic3b24402012-06-11 00:05:59 -07003404 return -EINVAL;
3405 }
3406
Kuirong Wang906ac472012-07-09 12:54:44 -07003407 switch (substream->stream) {
3408 case SNDRV_PCM_STREAM_CAPTURE:
3409 ret = taiko_set_decimator_rate(dai, tx_fs_rate,
3410 params_rate(params));
3411 if (ret < 0) {
3412 pr_err("%s: set decimator rate failed %d\n", __func__,
3413 ret);
3414 return ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07003415 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003416
Kiran Kandic3b24402012-06-11 00:05:59 -07003417 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3418 switch (params_format(params)) {
3419 case SNDRV_PCM_FORMAT_S16_LE:
3420 snd_soc_update_bits(codec,
3421 TAIKO_A_CDC_CLK_TX_I2S_CTL,
3422 0x20, 0x20);
3423 break;
3424 case SNDRV_PCM_FORMAT_S32_LE:
3425 snd_soc_update_bits(codec,
3426 TAIKO_A_CDC_CLK_TX_I2S_CTL,
3427 0x20, 0x00);
3428 break;
3429 default:
3430 pr_err("invalid format\n");
3431 break;
3432 }
3433 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_TX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07003434 0x07, tx_fs_rate);
Kiran Kandic3b24402012-06-11 00:05:59 -07003435 } else {
Kuirong Wang906ac472012-07-09 12:54:44 -07003436 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07003437 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003438 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07003439
Kuirong Wang906ac472012-07-09 12:54:44 -07003440 case SNDRV_PCM_STREAM_PLAYBACK:
3441 ret = taiko_set_interpolator_rate(dai, rx_fs_rate,
3442 compander_fs,
3443 params_rate(params));
3444 if (ret < 0) {
3445 pr_err("%s: set decimator rate failed %d\n", __func__,
3446 ret);
3447 return ret;
Kiran Kandic3b24402012-06-11 00:05:59 -07003448 }
3449 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
3450 switch (params_format(params)) {
3451 case SNDRV_PCM_FORMAT_S16_LE:
3452 snd_soc_update_bits(codec,
3453 TAIKO_A_CDC_CLK_RX_I2S_CTL,
3454 0x20, 0x20);
3455 break;
3456 case SNDRV_PCM_FORMAT_S32_LE:
3457 snd_soc_update_bits(codec,
3458 TAIKO_A_CDC_CLK_RX_I2S_CTL,
3459 0x20, 0x00);
3460 break;
3461 default:
3462 pr_err("invalid format\n");
3463 break;
3464 }
3465 snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_I2S_CTL,
Kuirong Wang906ac472012-07-09 12:54:44 -07003466 0x03, (rx_fs_rate >> 0x05));
Kiran Kandic3b24402012-06-11 00:05:59 -07003467 } else {
Kuirong Wang906ac472012-07-09 12:54:44 -07003468 taiko->dai[dai->id].rate = params_rate(params);
Kiran Kandic3b24402012-06-11 00:05:59 -07003469 }
Kuirong Wang906ac472012-07-09 12:54:44 -07003470 break;
3471 default:
3472 pr_err("%s: Invalid stream type %d\n", __func__,
3473 substream->stream);
3474 return -EINVAL;
Kiran Kandic3b24402012-06-11 00:05:59 -07003475 }
3476
3477 return 0;
3478}
3479
3480static struct snd_soc_dai_ops taiko_dai_ops = {
3481 .startup = taiko_startup,
3482 .shutdown = taiko_shutdown,
3483 .hw_params = taiko_hw_params,
3484 .set_sysclk = taiko_set_dai_sysclk,
3485 .set_fmt = taiko_set_dai_fmt,
3486 .set_channel_map = taiko_set_channel_map,
3487 .get_channel_map = taiko_get_channel_map,
3488};
3489
3490static struct snd_soc_dai_driver taiko_dai[] = {
3491 {
3492 .name = "taiko_rx1",
3493 .id = AIF1_PB,
3494 .playback = {
3495 .stream_name = "AIF1 Playback",
3496 .rates = WCD9320_RATES,
3497 .formats = TAIKO_FORMATS,
3498 .rate_max = 192000,
3499 .rate_min = 8000,
3500 .channels_min = 1,
3501 .channels_max = 2,
3502 },
3503 .ops = &taiko_dai_ops,
3504 },
3505 {
3506 .name = "taiko_tx1",
3507 .id = AIF1_CAP,
3508 .capture = {
3509 .stream_name = "AIF1 Capture",
3510 .rates = WCD9320_RATES,
3511 .formats = TAIKO_FORMATS,
3512 .rate_max = 192000,
3513 .rate_min = 8000,
3514 .channels_min = 1,
3515 .channels_max = 4,
3516 },
3517 .ops = &taiko_dai_ops,
3518 },
3519 {
3520 .name = "taiko_rx2",
3521 .id = AIF2_PB,
3522 .playback = {
3523 .stream_name = "AIF2 Playback",
3524 .rates = WCD9320_RATES,
3525 .formats = TAIKO_FORMATS,
3526 .rate_min = 8000,
3527 .rate_max = 192000,
3528 .channels_min = 1,
3529 .channels_max = 2,
3530 },
3531 .ops = &taiko_dai_ops,
3532 },
3533 {
3534 .name = "taiko_tx2",
3535 .id = AIF2_CAP,
3536 .capture = {
3537 .stream_name = "AIF2 Capture",
3538 .rates = WCD9320_RATES,
3539 .formats = TAIKO_FORMATS,
3540 .rate_max = 192000,
3541 .rate_min = 8000,
3542 .channels_min = 1,
3543 .channels_max = 4,
3544 },
3545 .ops = &taiko_dai_ops,
3546 },
3547 {
3548 .name = "taiko_tx3",
3549 .id = AIF3_CAP,
3550 .capture = {
3551 .stream_name = "AIF3 Capture",
3552 .rates = WCD9320_RATES,
3553 .formats = TAIKO_FORMATS,
3554 .rate_max = 48000,
3555 .rate_min = 8000,
3556 .channels_min = 1,
3557 .channels_max = 2,
3558 },
3559 .ops = &taiko_dai_ops,
3560 },
3561 {
3562 .name = "taiko_rx3",
3563 .id = AIF3_PB,
3564 .playback = {
3565 .stream_name = "AIF3 Playback",
3566 .rates = WCD9320_RATES,
3567 .formats = TAIKO_FORMATS,
3568 .rate_min = 8000,
3569 .rate_max = 192000,
3570 .channels_min = 1,
3571 .channels_max = 2,
3572 },
3573 .ops = &taiko_dai_ops,
3574 },
3575};
3576
3577static struct snd_soc_dai_driver taiko_i2s_dai[] = {
3578 {
3579 .name = "taiko_i2s_rx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07003580 .id = AIF1_PB,
Kiran Kandic3b24402012-06-11 00:05:59 -07003581 .playback = {
3582 .stream_name = "AIF1 Playback",
3583 .rates = WCD9320_RATES,
3584 .formats = TAIKO_FORMATS,
3585 .rate_max = 192000,
3586 .rate_min = 8000,
3587 .channels_min = 1,
3588 .channels_max = 4,
3589 },
3590 .ops = &taiko_dai_ops,
3591 },
3592 {
3593 .name = "taiko_i2s_tx1",
Kuirong Wang906ac472012-07-09 12:54:44 -07003594 .id = AIF1_CAP,
Kiran Kandic3b24402012-06-11 00:05:59 -07003595 .capture = {
3596 .stream_name = "AIF1 Capture",
3597 .rates = WCD9320_RATES,
3598 .formats = TAIKO_FORMATS,
3599 .rate_max = 192000,
3600 .rate_min = 8000,
3601 .channels_min = 1,
3602 .channels_max = 4,
3603 },
3604 .ops = &taiko_dai_ops,
3605 },
3606};
3607
3608static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07003609 struct snd_kcontrol *kcontrol,
3610 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07003611{
Kuirong Wang906ac472012-07-09 12:54:44 -07003612 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07003613 struct snd_soc_codec *codec = w->codec;
3614 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003615 u32 ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07003616 struct wcd9xxx_codec_dai_data *dai;
3617
3618 core = dev_get_drvdata(codec->dev->parent);
3619
3620 pr_debug("%s: event called! codec name %s num_dai %d\n"
3621 "stream name %s event %d\n",
3622 __func__, w->codec->name, w->codec->num_dai, w->sname, event);
3623
Kiran Kandic3b24402012-06-11 00:05:59 -07003624 /* Execute the callback only if interface type is slimbus */
3625 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3626 return 0;
3627
Kuirong Wang906ac472012-07-09 12:54:44 -07003628 dai = &taiko_p->dai[w->shift];
3629 pr_debug("%s: w->name %s w->shift %d event %d\n",
3630 __func__, w->name, w->shift, event);
Kiran Kandic3b24402012-06-11 00:05:59 -07003631
3632 switch (event) {
3633 case SND_SOC_DAPM_POST_PMU:
Kuirong Wang906ac472012-07-09 12:54:44 -07003634 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3635 dai->rate, dai->bit_width,
3636 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07003637 break;
3638 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07003639 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3640 dai->grph);
3641 usleep_range(15000, 15000);
3642 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07003643 }
3644 return ret;
3645}
3646
3647static int taiko_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
Kuirong Wang906ac472012-07-09 12:54:44 -07003648 struct snd_kcontrol *kcontrol,
3649 int event)
Kiran Kandic3b24402012-06-11 00:05:59 -07003650{
Kuirong Wang906ac472012-07-09 12:54:44 -07003651 struct wcd9xxx *core;
Kiran Kandic3b24402012-06-11 00:05:59 -07003652 struct snd_soc_codec *codec = w->codec;
3653 struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
Kiran Kandic3b24402012-06-11 00:05:59 -07003654 u32 ret = 0;
Kuirong Wang906ac472012-07-09 12:54:44 -07003655 struct wcd9xxx_codec_dai_data *dai;
Kiran Kandic3b24402012-06-11 00:05:59 -07003656
Kuirong Wang906ac472012-07-09 12:54:44 -07003657 core = dev_get_drvdata(codec->dev->parent);
3658
3659 pr_debug("%s: event called! codec name %s num_dai %d stream name %s\n",
3660 __func__, w->codec->name, w->codec->num_dai, w->sname);
Kiran Kandic3b24402012-06-11 00:05:59 -07003661
3662 /* Execute the callback only if interface type is slimbus */
3663 if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3664 return 0;
3665
Kuirong Wang906ac472012-07-09 12:54:44 -07003666 pr_debug("%s(): w->name %s event %d w->shift %d\n",
3667 __func__, w->name, event, w->shift);
Kiran Kandic3b24402012-06-11 00:05:59 -07003668
Kuirong Wang906ac472012-07-09 12:54:44 -07003669 dai = &taiko_p->dai[w->shift];
Kiran Kandic3b24402012-06-11 00:05:59 -07003670 switch (event) {
3671 case SND_SOC_DAPM_POST_PMU:
Kuirong Wang906ac472012-07-09 12:54:44 -07003672 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3673 dai->rate, dai->bit_width,
3674 &dai->grph);
Kiran Kandic3b24402012-06-11 00:05:59 -07003675 break;
3676 case SND_SOC_DAPM_POST_PMD:
Kuirong Wang906ac472012-07-09 12:54:44 -07003677 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3678 dai->grph);
3679 break;
Kiran Kandic3b24402012-06-11 00:05:59 -07003680 }
3681 return ret;
3682}
3683
Kiran Kandi4c56c592012-07-25 11:04:55 -07003684static int taiko_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
3685 struct snd_kcontrol *kcontrol, int event)
3686{
3687 struct snd_soc_codec *codec = w->codec;
3688
3689 pr_debug("%s %s %d\n", __func__, w->name, event);
3690
3691 switch (event) {
3692 break;
3693 case SND_SOC_DAPM_POST_PMU:
3694
3695 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_5, 0x02, 0x00);
3696 snd_soc_update_bits(codec, TAIKO_A_NCP_STATIC, 0x20, 0x00);
3697 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x04, 0x04);
3698 snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x08, 0x00);
3699
3700 usleep_range(5000, 5000);
3701 break;
3702 }
3703 return 0;
3704}
3705
Kiran Kandic3b24402012-06-11 00:05:59 -07003706/* Todo: Have seperate dapm widgets for I2S and Slimbus.
3707 * Might Need to have callbacks registered only for slimbus
3708 */
3709static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
3710 /*RX stuff */
3711 SND_SOC_DAPM_OUTPUT("EAR"),
3712
Kiran Kandi4c56c592012-07-25 11:04:55 -07003713 SND_SOC_DAPM_PGA_E("EAR PA", TAIKO_A_RX_EAR_EN, 4, 0, NULL, 0,
3714 taiko_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU),
Kiran Kandic3b24402012-06-11 00:05:59 -07003715
3716 SND_SOC_DAPM_MIXER("DAC1", TAIKO_A_RX_EAR_EN, 6, 0, dac1_switch,
3717 ARRAY_SIZE(dac1_switch)),
3718
Kuirong Wang906ac472012-07-09 12:54:44 -07003719 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
3720 AIF1_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07003721 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07003722 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
3723 AIF2_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07003724 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kuirong Wang906ac472012-07-09 12:54:44 -07003725 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
3726 AIF3_PB, 0, taiko_codec_enable_slimrx,
Kiran Kandic3b24402012-06-11 00:05:59 -07003727 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3728
Kuirong Wang906ac472012-07-09 12:54:44 -07003729 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TAIKO_RX1, 0,
3730 &slim_rx_mux[TAIKO_RX1]),
3731 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TAIKO_RX2, 0,
3732 &slim_rx_mux[TAIKO_RX2]),
3733 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TAIKO_RX3, 0,
3734 &slim_rx_mux[TAIKO_RX3]),
3735 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TAIKO_RX4, 0,
3736 &slim_rx_mux[TAIKO_RX4]),
3737 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TAIKO_RX5, 0,
3738 &slim_rx_mux[TAIKO_RX5]),
3739 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TAIKO_RX6, 0,
3740 &slim_rx_mux[TAIKO_RX6]),
3741 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TAIKO_RX7, 0,
3742 &slim_rx_mux[TAIKO_RX7]),
Kiran Kandic3b24402012-06-11 00:05:59 -07003743
Kuirong Wang906ac472012-07-09 12:54:44 -07003744 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3745 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3746 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
3747 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
3748 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
3749 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
3750 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
Kiran Kandic3b24402012-06-11 00:05:59 -07003751
3752 /* Headphone */
3753 SND_SOC_DAPM_OUTPUT("HEADPHONE"),
3754 SND_SOC_DAPM_PGA_E("HPHL", TAIKO_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
3755 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07003756 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07003757 SND_SOC_DAPM_MIXER("HPHL DAC", TAIKO_A_RX_HPH_L_DAC_CTL, 7, 0,
3758 hphl_switch, ARRAY_SIZE(hphl_switch)),
3759
3760 SND_SOC_DAPM_PGA_E("HPHR", TAIKO_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
3761 taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
Kiran Kandi4c56c592012-07-25 11:04:55 -07003762 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07003763
3764 SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TAIKO_A_RX_HPH_R_DAC_CTL, 7, 0,
3765 taiko_hphr_dac_event,
3766 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3767
3768 /* Speaker */
3769 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
3770 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
3771 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
3772 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003773 SND_SOC_DAPM_OUTPUT("SPK_OUT"),
Kiran Kandic3b24402012-06-11 00:05:59 -07003774
3775 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TAIKO_A_RX_LINE_CNP_EN, 0, 0, NULL,
3776 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
3777 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3778 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TAIKO_A_RX_LINE_CNP_EN, 1, 0, NULL,
3779 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
3780 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3781 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TAIKO_A_RX_LINE_CNP_EN, 2, 0, NULL,
3782 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
3783 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3784 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TAIKO_A_RX_LINE_CNP_EN, 3, 0, NULL,
3785 0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
3786 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003787 SND_SOC_DAPM_PGA_E("SPK PA", TAIKO_A_SPKR_DRV_EN, 7, 0 , NULL,
3788 0, taiko_codec_enable_spk_pa, SND_SOC_DAPM_PRE_PMU |
3789 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07003790
3791 SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAIKO_A_RX_LINE_1_DAC_CTL, 7, 0
3792 , taiko_lineout_dac_event,
3793 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3794 SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TAIKO_A_RX_LINE_2_DAC_CTL, 7, 0
3795 , taiko_lineout_dac_event,
3796 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3797 SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TAIKO_A_RX_LINE_3_DAC_CTL, 7, 0
3798 , taiko_lineout_dac_event,
3799 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3800 SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
3801 &lineout3_ground_switch),
3802 SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TAIKO_A_RX_LINE_4_DAC_CTL, 7, 0
3803 , taiko_lineout_dac_event,
3804 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3805 SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
3806 &lineout4_ground_switch),
3807
Joonwoo Park7680b9f2012-07-13 11:36:48 -07003808 SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
3809 taiko_spk_dac_event,
3810 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3811
Kiran Kandid2b46332012-10-05 12:04:00 -07003812 SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3813 SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3814 SND_SOC_DAPM_MIXER("RX7 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3815
Kiran Kandic3b24402012-06-11 00:05:59 -07003816 SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003817 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003818 SND_SOC_DAPM_POST_PMU),
3819 SND_SOC_DAPM_MIXER_E("RX2 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003820 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003821 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07003822 SND_SOC_DAPM_MIXER_E("RX3 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003823 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003824 SND_SOC_DAPM_POST_PMU),
3825 SND_SOC_DAPM_MIXER_E("RX4 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003826 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003827 SND_SOC_DAPM_POST_PMU),
3828 SND_SOC_DAPM_MIXER_E("RX5 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003829 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003830 SND_SOC_DAPM_POST_PMU),
3831 SND_SOC_DAPM_MIXER_E("RX6 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003832 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003833 SND_SOC_DAPM_POST_PMU),
Kiran Kandid2b46332012-10-05 12:04:00 -07003834 SND_SOC_DAPM_MIXER_E("RX7 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003835 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003836 SND_SOC_DAPM_POST_PMU),
3837
Kiran Kandic3b24402012-06-11 00:05:59 -07003838 SND_SOC_DAPM_MUX_E("RX4 DSM MUX", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003839 &rx4_dsm_mux, taiko_codec_enable_interpolator,
Kiran Kandic3b24402012-06-11 00:05:59 -07003840 SND_SOC_DAPM_PRE_PMU),
3841
3842 SND_SOC_DAPM_MUX_E("RX6 DSM MUX", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003843 &rx6_dsm_mux, taiko_codec_enable_interpolator,
Kiran Kandic3b24402012-06-11 00:05:59 -07003844 SND_SOC_DAPM_PRE_PMU),
3845
3846 SND_SOC_DAPM_MIXER("RX1 CHAIN", TAIKO_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
3847 SND_SOC_DAPM_MIXER("RX2 CHAIN", TAIKO_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
3848
3849 SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3850 &rx_mix1_inp1_mux),
3851 SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3852 &rx_mix1_inp2_mux),
3853 SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
3854 &rx_mix1_inp3_mux),
3855 SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3856 &rx2_mix1_inp1_mux),
3857 SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3858 &rx2_mix1_inp2_mux),
3859 SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3860 &rx3_mix1_inp1_mux),
3861 SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3862 &rx3_mix1_inp2_mux),
3863 SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3864 &rx4_mix1_inp1_mux),
3865 SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3866 &rx4_mix1_inp2_mux),
3867 SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3868 &rx5_mix1_inp1_mux),
3869 SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3870 &rx5_mix1_inp2_mux),
3871 SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3872 &rx6_mix1_inp1_mux),
3873 SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3874 &rx6_mix1_inp2_mux),
3875 SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3876 &rx7_mix1_inp1_mux),
3877 SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3878 &rx7_mix1_inp2_mux),
3879 SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
3880 &rx1_mix2_inp1_mux),
3881 SND_SOC_DAPM_MUX("RX1 MIX2 INP2", SND_SOC_NOPM, 0, 0,
3882 &rx1_mix2_inp2_mux),
3883 SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
3884 &rx2_mix2_inp1_mux),
3885 SND_SOC_DAPM_MUX("RX2 MIX2 INP2", SND_SOC_NOPM, 0, 0,
3886 &rx2_mix2_inp2_mux),
3887 SND_SOC_DAPM_MUX("RX7 MIX2 INP1", SND_SOC_NOPM, 0, 0,
3888 &rx7_mix2_inp1_mux),
3889 SND_SOC_DAPM_MUX("RX7 MIX2 INP2", SND_SOC_NOPM, 0, 0,
3890 &rx7_mix2_inp2_mux),
3891
Kiran Kandi4c56c592012-07-25 11:04:55 -07003892 SND_SOC_DAPM_SUPPLY("CLASS_H_CLK", TAIKO_A_CDC_CLK_OTHR_CTL, 0, 0,
3893 taiko_codec_enable_class_h_clk, SND_SOC_DAPM_PRE_PMU |
Kiran Kandic3b24402012-06-11 00:05:59 -07003894 SND_SOC_DAPM_PRE_PMD),
3895
Kiran Kandi4c56c592012-07-25 11:04:55 -07003896 SND_SOC_DAPM_SUPPLY("CLASS_H_EAR", TAIKO_A_CDC_CLSH_B1_CTL, 4, 0,
3897 taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
3898
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003899 SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_L", TAIKO_A_CDC_CLSH_B1_CTL, 3, 0,
Kiran Kandi4c56c592012-07-25 11:04:55 -07003900 taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
3901
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07003902 SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_R", TAIKO_A_CDC_CLSH_B1_CTL, 2, 0,
Kiran Kandi4c56c592012-07-25 11:04:55 -07003903 taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
3904
3905 SND_SOC_DAPM_SUPPLY("CP", TAIKO_A_NCP_EN, 0, 0,
3906 taiko_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU |
3907 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
3908
Kiran Kandic3b24402012-06-11 00:05:59 -07003909 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
3910 taiko_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
3911 SND_SOC_DAPM_POST_PMD),
3912
3913 /* TX */
3914
3915 SND_SOC_DAPM_SUPPLY("CDC_CONN", TAIKO_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
3916 0),
3917
3918 SND_SOC_DAPM_SUPPLY("LDO_H", TAIKO_A_LDO_H_MODE_1, 7, 0,
3919 taiko_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
3920
3921 SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 0, 0,
3922 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
3923 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
3924 SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 1, 0,
3925 taiko_config_compander, SND_SOC_DAPM_PRE_PMU |
3926 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
3927
3928
3929 SND_SOC_DAPM_INPUT("AMIC1"),
3930 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TAIKO_A_MICB_1_CTL, 7, 0,
3931 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
3932 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3933 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TAIKO_A_MICB_1_CTL, 7, 0,
3934 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
3935 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3936 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TAIKO_A_MICB_1_CTL, 7, 0,
3937 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
3938 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3939 SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_TX_1_2_EN, 7, 0,
3940 taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
3941 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3942
3943 SND_SOC_DAPM_INPUT("AMIC3"),
3944 SND_SOC_DAPM_ADC_E("ADC3", NULL, TAIKO_A_TX_3_4_EN, 7, 0,
3945 taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
3946 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3947
3948 SND_SOC_DAPM_INPUT("AMIC4"),
3949 SND_SOC_DAPM_ADC_E("ADC4", NULL, TAIKO_A_TX_3_4_EN, 3, 0,
3950 taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
3951 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
3952
3953 SND_SOC_DAPM_INPUT("AMIC5"),
3954 SND_SOC_DAPM_ADC_E("ADC5", NULL, TAIKO_A_TX_5_6_EN, 7, 0,
3955 taiko_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
3956
3957 SND_SOC_DAPM_INPUT("AMIC6"),
3958 SND_SOC_DAPM_ADC_E("ADC6", NULL, TAIKO_A_TX_5_6_EN, 3, 0,
3959 taiko_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
3960
3961 SND_SOC_DAPM_MUX_E("DEC1 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
3962 &dec1_mux, taiko_codec_enable_dec,
3963 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3964 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3965
3966 SND_SOC_DAPM_MUX_E("DEC2 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
3967 &dec2_mux, taiko_codec_enable_dec,
3968 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3969 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3970
3971 SND_SOC_DAPM_MUX_E("DEC3 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
3972 &dec3_mux, taiko_codec_enable_dec,
3973 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3974 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3975
3976 SND_SOC_DAPM_MUX_E("DEC4 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
3977 &dec4_mux, taiko_codec_enable_dec,
3978 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3979 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3980
3981 SND_SOC_DAPM_MUX_E("DEC5 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
3982 &dec5_mux, taiko_codec_enable_dec,
3983 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3984 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3985
3986 SND_SOC_DAPM_MUX_E("DEC6 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
3987 &dec6_mux, taiko_codec_enable_dec,
3988 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3989 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3990
3991 SND_SOC_DAPM_MUX_E("DEC7 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
3992 &dec7_mux, taiko_codec_enable_dec,
3993 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3994 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3995
3996 SND_SOC_DAPM_MUX_E("DEC8 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
3997 &dec8_mux, taiko_codec_enable_dec,
3998 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3999 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4000
4001 SND_SOC_DAPM_MUX_E("DEC9 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
4002 &dec9_mux, taiko_codec_enable_dec,
4003 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4004 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4005
4006 SND_SOC_DAPM_MUX_E("DEC10 MUX", TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
4007 &dec10_mux, taiko_codec_enable_dec,
4008 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4009 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4010
4011 SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
4012 SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
4013
4014 SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
4015 taiko_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
4016 SND_SOC_DAPM_POST_PMD),
4017
4018 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
4019
4020 SND_SOC_DAPM_INPUT("AMIC2"),
4021 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TAIKO_A_MICB_2_CTL, 7, 0,
4022 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4023 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4024 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TAIKO_A_MICB_2_CTL, 7, 0,
4025 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4026 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4027 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TAIKO_A_MICB_2_CTL, 7, 0,
4028 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4029 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4030 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TAIKO_A_MICB_2_CTL, 7, 0,
4031 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4032 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4033 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TAIKO_A_MICB_3_CTL, 7, 0,
4034 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4035 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4036 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TAIKO_A_MICB_3_CTL, 7, 0,
4037 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4038 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4039 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TAIKO_A_MICB_3_CTL, 7, 0,
4040 taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
4041 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4042 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TAIKO_A_MICB_4_CTL, 7,
4043 0, taiko_codec_enable_micbias,
4044 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4045 SND_SOC_DAPM_POST_PMD),
4046
4047 SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_TX_1_2_EN, 3, 0,
4048 taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
4049 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4050
Kuirong Wang906ac472012-07-09 12:54:44 -07004051 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
4052 AIF1_CAP, 0, taiko_codec_enable_slimtx,
4053 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004054
Kuirong Wang906ac472012-07-09 12:54:44 -07004055 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
4056 AIF2_CAP, 0, taiko_codec_enable_slimtx,
4057 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004058
Kuirong Wang906ac472012-07-09 12:54:44 -07004059 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
4060 AIF3_CAP, 0, taiko_codec_enable_slimtx,
4061 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
Kiran Kandic3b24402012-06-11 00:05:59 -07004062
Kuirong Wang906ac472012-07-09 12:54:44 -07004063 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
4064 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004065
Kuirong Wang906ac472012-07-09 12:54:44 -07004066 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
4067 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004068
Kuirong Wang906ac472012-07-09 12:54:44 -07004069 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
4070 aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
Kiran Kandic3b24402012-06-11 00:05:59 -07004071
Kuirong Wang906ac472012-07-09 12:54:44 -07004072 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TAIKO_TX1, 0,
4073 &sb_tx1_mux),
4074 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TAIKO_TX2, 0,
4075 &sb_tx2_mux),
4076 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TAIKO_TX3, 0,
4077 &sb_tx3_mux),
4078 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TAIKO_TX4, 0,
4079 &sb_tx4_mux),
4080 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TAIKO_TX5, 0,
4081 &sb_tx5_mux),
4082 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TAIKO_TX6, 0,
4083 &sb_tx6_mux),
4084 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TAIKO_TX7, 0,
4085 &sb_tx7_mux),
4086 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TAIKO_TX8, 0,
4087 &sb_tx8_mux),
4088 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TAIKO_TX9, 0,
4089 &sb_tx9_mux),
4090 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TAIKO_TX10, 0,
4091 &sb_tx10_mux),
Kiran Kandic3b24402012-06-11 00:05:59 -07004092
4093 /* Digital Mic Inputs */
4094 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
4095 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4096 SND_SOC_DAPM_POST_PMD),
4097
4098 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
4099 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4100 SND_SOC_DAPM_POST_PMD),
4101
4102 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
4103 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4104 SND_SOC_DAPM_POST_PMD),
4105
4106 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
4107 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4108 SND_SOC_DAPM_POST_PMD),
4109
4110 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
4111 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4112 SND_SOC_DAPM_POST_PMD),
4113 SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
4114 taiko_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4115 SND_SOC_DAPM_POST_PMD),
4116
4117 /* Sidetone */
4118 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
4119 SND_SOC_DAPM_PGA("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
4120
4121 /* AUX PGA */
4122 SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TAIKO_A_RX_AUX_SW_CTL, 7, 0,
4123 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
4124 SND_SOC_DAPM_POST_PMD),
4125
4126 SND_SOC_DAPM_ADC_E("AUX_PGA_Right", NULL, TAIKO_A_RX_AUX_SW_CTL, 6, 0,
4127 taiko_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
4128 SND_SOC_DAPM_POST_PMD),
4129
4130 /* Lineout, ear and HPH PA Mixers */
4131
4132 SND_SOC_DAPM_MIXER("EAR_PA_MIXER", SND_SOC_NOPM, 0, 0,
4133 ear_pa_mix, ARRAY_SIZE(ear_pa_mix)),
4134
4135 SND_SOC_DAPM_MIXER("HPHL_PA_MIXER", SND_SOC_NOPM, 0, 0,
4136 hphl_pa_mix, ARRAY_SIZE(hphl_pa_mix)),
4137
4138 SND_SOC_DAPM_MIXER("HPHR_PA_MIXER", SND_SOC_NOPM, 0, 0,
4139 hphr_pa_mix, ARRAY_SIZE(hphr_pa_mix)),
4140
4141 SND_SOC_DAPM_MIXER("LINEOUT1_PA_MIXER", SND_SOC_NOPM, 0, 0,
4142 lineout1_pa_mix, ARRAY_SIZE(lineout1_pa_mix)),
4143
4144 SND_SOC_DAPM_MIXER("LINEOUT2_PA_MIXER", SND_SOC_NOPM, 0, 0,
4145 lineout2_pa_mix, ARRAY_SIZE(lineout2_pa_mix)),
4146
4147 SND_SOC_DAPM_MIXER("LINEOUT3_PA_MIXER", SND_SOC_NOPM, 0, 0,
4148 lineout3_pa_mix, ARRAY_SIZE(lineout3_pa_mix)),
4149
4150 SND_SOC_DAPM_MIXER("LINEOUT4_PA_MIXER", SND_SOC_NOPM, 0, 0,
4151 lineout4_pa_mix, ARRAY_SIZE(lineout4_pa_mix)),
4152
4153};
4154
Kiran Kandic3b24402012-06-11 00:05:59 -07004155static unsigned long slimbus_value;
4156
4157static irqreturn_t taiko_slimbus_irq(int irq, void *data)
4158{
4159 struct taiko_priv *priv = data;
4160 struct snd_soc_codec *codec = priv->codec;
4161 int i, j;
4162 u8 val;
4163
4164 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) {
4165 slimbus_value = wcd9xxx_interface_reg_read(codec->control_data,
4166 TAIKO_SLIM_PGD_PORT_INT_STATUS0 + i);
4167 for_each_set_bit(j, &slimbus_value, BITS_PER_BYTE) {
4168 val = wcd9xxx_interface_reg_read(codec->control_data,
4169 TAIKO_SLIM_PGD_PORT_INT_SOURCE0 + i*8 + j);
4170 if (val & 0x1)
4171 pr_err_ratelimited(
4172 "overflow error on port %x, value %x\n",
4173 i*8 + j, val);
4174 if (val & 0x2)
4175 pr_err_ratelimited(
4176 "underflow error on port %x, value %x\n",
4177 i*8 + j, val);
4178 }
4179 wcd9xxx_interface_reg_write(codec->control_data,
4180 TAIKO_SLIM_PGD_PORT_INT_CLR0 + i, 0xFF);
Kiran Kandic3b24402012-06-11 00:05:59 -07004181
Joonwoo Parka8890262012-10-15 12:04:27 -07004182 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004183 return IRQ_HANDLED;
4184}
4185
Kiran Kandi4c56c592012-07-25 11:04:55 -07004186static const struct taiko_reg_mask_val taiko_1_0_class_h_ear[] = {
4187
4188 /* CLASS-H EAR IDLE_THRESHOLD Table */
4189 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_IDLE_EAR_THSD, 0x26),
4190 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_FCLKONLY_EAR_THSD, 0x2C),
4191
4192 /* CLASS-H EAR I_PA_FACT Table. */
4193 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_L, 0xA9),
4194 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_U, 0x07),
4195
4196 /* CLASS-H EAR Voltage Headroom , Voltage Min. */
4197 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_HD_EAR, 0x0D),
4198 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_MIN_EAR, 0x3A),
4199
4200 /* CLASS-H EAR K values --chnages from load. */
4201 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_ADDR, 0x08),
4202 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x1B),
4203 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4204 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x2D),
4205 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4206 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x36),
4207 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4208 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x37),
4209 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4210 /** end of Ear PA load 32 */
4211};
4212
Kiran Kandi4c56c592012-07-25 11:04:55 -07004213static const struct taiko_reg_mask_val taiko_1_0_class_h_hph[] = {
4214
4215 /* CLASS-H HPH IDLE_THRESHOLD Table */
4216 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_IDLE_HPH_THSD, 0x13),
4217 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0x19),
4218
4219 /* CLASS-H HPH I_PA_FACT Table */
4220 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_L, 0x9A),
4221 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_U, 0x06),
4222
4223 /* CLASS-H HPH Voltage Headroom , Voltage Min */
4224 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_HD_HPH, 0x0D),
4225 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_MIN_HPH, 0x1D),
4226
4227 /* CLASS-H HPH K values --chnages from load .*/
4228 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_ADDR, 0x00),
4229 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0xAE),
4230 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x01),
4231 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x1C),
4232 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4233 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x25),
4234 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4235 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x27),
4236 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
4237};
4238
4239static int taiko_config_ear_class_h(struct snd_soc_codec *codec, u32 ear_load)
4240{
4241 u32 i;
4242
4243 if (ear_load != 32)
4244 return -EINVAL;
4245
4246 for (i = 0; i < ARRAY_SIZE(taiko_1_0_class_h_ear); i++)
4247 snd_soc_write(codec, taiko_1_0_class_h_ear[i].reg,
4248 taiko_1_0_class_h_ear[i].val);
4249 return 0;
4250}
4251
4252static int taiko_config_hph_class_h(struct snd_soc_codec *codec, u32 hph_load)
4253{
4254 u32 i;
4255 if (hph_load != 16)
4256 return -EINVAL;
4257
4258 for (i = 0; i < ARRAY_SIZE(taiko_1_0_class_h_hph); i++)
4259 snd_soc_write(codec, taiko_1_0_class_h_hph[i].reg,
4260 taiko_1_0_class_h_hph[i].val);
4261 return 0;
4262}
4263
Kiran Kandic3b24402012-06-11 00:05:59 -07004264static int taiko_handle_pdata(struct taiko_priv *taiko)
4265{
4266 struct snd_soc_codec *codec = taiko->codec;
Joonwoo Parka8890262012-10-15 12:04:27 -07004267 struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
Kiran Kandic3b24402012-06-11 00:05:59 -07004268 int k1, k2, k3, rc = 0;
Kiran Kandi725f8492012-08-06 13:45:16 -07004269 u8 leg_mode, txfe_bypass, txfe_buff, flag;
Kiran Kandic3b24402012-06-11 00:05:59 -07004270 u8 i = 0, j = 0;
4271 u8 val_txfe = 0, value = 0;
4272
4273 if (!pdata) {
Kiran Kandi725f8492012-08-06 13:45:16 -07004274 pr_err("%s: NULL pdata\n", __func__);
Kiran Kandic3b24402012-06-11 00:05:59 -07004275 rc = -ENODEV;
4276 goto done;
4277 }
4278
Kiran Kandi725f8492012-08-06 13:45:16 -07004279 leg_mode = pdata->amic_settings.legacy_mode;
4280 txfe_bypass = pdata->amic_settings.txfe_enable;
4281 txfe_buff = pdata->amic_settings.txfe_buff;
4282 flag = pdata->amic_settings.use_pdata;
4283
Kiran Kandic3b24402012-06-11 00:05:59 -07004284 /* Make sure settings are correct */
Joonwoo Parka8890262012-10-15 12:04:27 -07004285 if ((pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V) ||
4286 (pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
4287 (pdata->micbias.bias2_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
4288 (pdata->micbias.bias3_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
4289 (pdata->micbias.bias4_cfilt_sel > WCD9XXX_CFILT3_SEL)) {
Kiran Kandic3b24402012-06-11 00:05:59 -07004290 rc = -EINVAL;
4291 goto done;
4292 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004293 /* figure out k value */
Joonwoo Parka8890262012-10-15 12:04:27 -07004294 k1 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt1_mv);
4295 k2 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt2_mv);
4296 k3 = wcd9xxx_resmgr_get_k_val(&taiko->resmgr, pdata->micbias.cfilt3_mv);
Kiran Kandic3b24402012-06-11 00:05:59 -07004297
4298 if (IS_ERR_VALUE(k1) || IS_ERR_VALUE(k2) || IS_ERR_VALUE(k3)) {
4299 rc = -EINVAL;
4300 goto done;
4301 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004302 /* Set voltage level and always use LDO */
4303 snd_soc_update_bits(codec, TAIKO_A_LDO_H_MODE_1, 0x0C,
Joonwoo Parka8890262012-10-15 12:04:27 -07004304 (pdata->micbias.ldoh_v << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07004305
Joonwoo Parka8890262012-10-15 12:04:27 -07004306 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_1_VAL, 0xFC, (k1 << 2));
4307 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_2_VAL, 0xFC, (k2 << 2));
4308 snd_soc_update_bits(codec, TAIKO_A_MICB_CFILT_3_VAL, 0xFC, (k3 << 2));
Kiran Kandic3b24402012-06-11 00:05:59 -07004309
4310 snd_soc_update_bits(codec, TAIKO_A_MICB_1_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07004311 (pdata->micbias.bias1_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07004312 snd_soc_update_bits(codec, TAIKO_A_MICB_2_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07004313 (pdata->micbias.bias2_cfilt_sel << 5));
Kiran Kandic3b24402012-06-11 00:05:59 -07004314 snd_soc_update_bits(codec, TAIKO_A_MICB_3_CTL, 0x60,
Joonwoo Parka8890262012-10-15 12:04:27 -07004315 (pdata->micbias.bias3_cfilt_sel << 5));
4316 snd_soc_update_bits(codec, taiko->resmgr.reg_addr->micb_4_ctl, 0x60,
Kiran Kandic3b24402012-06-11 00:05:59 -07004317 (pdata->micbias.bias4_cfilt_sel << 5));
4318
4319 for (i = 0; i < 6; j++, i += 2) {
4320 if (flag & (0x01 << i)) {
4321 value = (leg_mode & (0x01 << i)) ? 0x10 : 0x00;
4322 val_txfe = (txfe_bypass & (0x01 << i)) ? 0x20 : 0x00;
4323 val_txfe = val_txfe |
4324 ((txfe_buff & (0x01 << i)) ? 0x10 : 0x00);
4325 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
4326 0x10, value);
4327 snd_soc_update_bits(codec,
4328 TAIKO_A_TX_1_2_TEST_EN + j * 10,
4329 0x30, val_txfe);
4330 }
4331 if (flag & (0x01 << (i + 1))) {
4332 value = (leg_mode & (0x01 << (i + 1))) ? 0x01 : 0x00;
4333 val_txfe = (txfe_bypass &
4334 (0x01 << (i + 1))) ? 0x02 : 0x00;
4335 val_txfe |= (txfe_buff &
4336 (0x01 << (i + 1))) ? 0x01 : 0x00;
4337 snd_soc_update_bits(codec, TAIKO_A_TX_1_2_EN + j * 10,
4338 0x01, value);
4339 snd_soc_update_bits(codec,
4340 TAIKO_A_TX_1_2_TEST_EN + j * 10,
4341 0x03, val_txfe);
4342 }
4343 }
4344 if (flag & 0x40) {
4345 value = (leg_mode & 0x40) ? 0x10 : 0x00;
4346 value = value | ((txfe_bypass & 0x40) ? 0x02 : 0x00);
4347 value = value | ((txfe_buff & 0x40) ? 0x01 : 0x00);
4348 snd_soc_update_bits(codec, TAIKO_A_TX_7_MBHC_EN,
4349 0x13, value);
4350 }
4351
4352 if (pdata->ocp.use_pdata) {
4353 /* not defined in CODEC specification */
4354 if (pdata->ocp.hph_ocp_limit == 1 ||
4355 pdata->ocp.hph_ocp_limit == 5) {
4356 rc = -EINVAL;
4357 goto done;
4358 }
4359 snd_soc_update_bits(codec, TAIKO_A_RX_COM_OCP_CTL,
4360 0x0F, pdata->ocp.num_attempts);
4361 snd_soc_write(codec, TAIKO_A_RX_COM_OCP_COUNT,
4362 ((pdata->ocp.run_time << 4) | pdata->ocp.wait_time));
4363 snd_soc_update_bits(codec, TAIKO_A_RX_HPH_OCP_CTL,
4364 0xE0, (pdata->ocp.hph_ocp_limit << 5));
4365 }
4366
4367 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
4368 if (!strncmp(pdata->regulator[i].name, "CDC_VDDA_RX", 11)) {
4369 if (pdata->regulator[i].min_uV == 1800000 &&
4370 pdata->regulator[i].max_uV == 1800000) {
4371 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
4372 0x1C);
4373 } else if (pdata->regulator[i].min_uV == 2200000 &&
4374 pdata->regulator[i].max_uV == 2200000) {
4375 snd_soc_write(codec, TAIKO_A_BIAS_REF_CTL,
4376 0x1E);
4377 } else {
4378 pr_err("%s: unsupported CDC_VDDA_RX voltage\n"
4379 "min %d, max %d\n", __func__,
4380 pdata->regulator[i].min_uV,
4381 pdata->regulator[i].max_uV);
4382 rc = -EINVAL;
4383 }
4384 break;
4385 }
4386 }
Kiran Kandi4c56c592012-07-25 11:04:55 -07004387
4388 taiko_config_ear_class_h(codec, 32);
4389 taiko_config_hph_class_h(codec, 16);
4390
Kiran Kandic3b24402012-06-11 00:05:59 -07004391done:
4392 return rc;
4393}
4394
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004395static const struct taiko_reg_mask_val taiko_reg_defaults[] = {
Kiran Kandic3b24402012-06-11 00:05:59 -07004396
Kiran Kandi4c56c592012-07-25 11:04:55 -07004397 /* set MCLk to 9.6 */
4398 TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x0A),
4399 TAIKO_REG_VAL(TAIKO_A_CDC_CLK_POWER_CTL, 0x03),
Kiran Kandic3b24402012-06-11 00:05:59 -07004400
Kiran Kandi4c56c592012-07-25 11:04:55 -07004401 /* EAR PA deafults */
4402 TAIKO_REG_VAL(TAIKO_A_RX_EAR_CMBUFF, 0x05),
Kiran Kandic3b24402012-06-11 00:05:59 -07004403
Kiran Kandi4c56c592012-07-25 11:04:55 -07004404 /** BUCK and NCP defaults for EAR and HS */
4405 TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_4, 0x50),
Kiran Kandi4c56c592012-07-25 11:04:55 -07004406 TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_1, 0x5B),
Kiran Kandi4c56c592012-07-25 11:04:55 -07004407
4408 /* CLASS-H defaults for EAR and HS */
4409 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_BUCK_NCP_VARS, 0x00),
4410 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_BUCK_NCP_VARS, 0x04),
4411 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x01),
4412 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x05),
4413 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x35),
4414 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B3_CTL, 0x30),
4415 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B3_CTL, 0x3B),
4416
4417 /*
4418 * For CLASS-H, Enable ANC delay buffer,
4419 * set HPHL and EAR PA ref gain to 0 DB.
4420 */
4421 TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B1_CTL, 0x26),
Kiran Kandic3b24402012-06-11 00:05:59 -07004422
Kiran Kandi4c56c592012-07-25 11:04:55 -07004423 /* RX deafults */
Kiran Kandic3b24402012-06-11 00:05:59 -07004424 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B5_CTL, 0x78),
4425 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B5_CTL, 0x78),
4426 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B5_CTL, 0x78),
4427 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B5_CTL, 0x78),
4428 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B5_CTL, 0x78),
4429 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B5_CTL, 0x78),
4430 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B5_CTL, 0x78),
4431
Kiran Kandi4c56c592012-07-25 11:04:55 -07004432 /* RX1 and RX2 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07004433 TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B6_CTL, 0xA0),
4434 TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B6_CTL, 0xA0),
4435
Kiran Kandi4c56c592012-07-25 11:04:55 -07004436 /* RX3 to RX7 defaults */
Kiran Kandic3b24402012-06-11 00:05:59 -07004437 TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B6_CTL, 0x80),
4438 TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B6_CTL, 0x80),
4439 TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B6_CTL, 0x80),
4440 TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B6_CTL, 0x80),
4441 TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
Kiran Kandic3b24402012-06-11 00:05:59 -07004442};
4443
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004444static const struct taiko_reg_mask_val taiko_1_0_reg_defaults[] = {
4445 /*
4446 * The following only need to be written for Taiko 1.0 parts.
4447 * Taiko 2.0 will have appropriate defaults for these registers.
4448 */
4449 /* Choose max non-overlap time for NCP */
4450 TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
4451 /* Use 25mV/50mV for deltap/m to reduce ripple */
4452 TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_VCL_1, 0x08),
4453 /*
4454 * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
4455 * Note that the other bits of this register will be changed during
4456 * Rx PA bring up.
4457 */
4458 TAIKO_REG_VAL(TAIKO_A_BUCK_MODE_3, 0xCE),
4459 /* Reduce HPH DAC bias to 70% */
4460 TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
4461 /*Reduce EAR DAC bias to 70% */
4462 TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
4463 /* Reduce LINE DAC bias to 70% */
4464 TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
4465};
4466
Kiran Kandic3b24402012-06-11 00:05:59 -07004467static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
4468{
4469 u32 i;
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004470 struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
Kiran Kandic3b24402012-06-11 00:05:59 -07004471
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004472 for (i = 0; i < ARRAY_SIZE(taiko_reg_defaults); i++)
4473 snd_soc_write(codec, taiko_reg_defaults[i].reg,
4474 taiko_reg_defaults[i].val);
4475
4476 if (TAIKO_IS_1_0(taiko_core->version)) {
4477 for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
4478 snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
Kiran Kandic3b24402012-06-11 00:05:59 -07004479 taiko_1_0_reg_defaults[i].val);
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004480 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004481}
4482
4483static const struct taiko_reg_mask_val taiko_codec_reg_init_val[] = {
4484 /* Initialize current threshold to 350MA
4485 * number of wait and run cycles to 4096
4486 */
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004487 {TAIKO_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
Kiran Kandic3b24402012-06-11 00:05:59 -07004488 {TAIKO_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
4489
Kiran Kandic3b24402012-06-11 00:05:59 -07004490 /* Initialize gain registers to use register gain */
Kiran Kandi4c56c592012-07-25 11:04:55 -07004491 {TAIKO_A_RX_HPH_L_GAIN, 0x20, 0x20},
4492 {TAIKO_A_RX_HPH_R_GAIN, 0x20, 0x20},
4493 {TAIKO_A_RX_LINE_1_GAIN, 0x20, 0x20},
4494 {TAIKO_A_RX_LINE_2_GAIN, 0x20, 0x20},
4495 {TAIKO_A_RX_LINE_3_GAIN, 0x20, 0x20},
4496 {TAIKO_A_RX_LINE_4_GAIN, 0x20, 0x20},
Kiran Kandic3b24402012-06-11 00:05:59 -07004497
Kiran Kandi4c56c592012-07-25 11:04:55 -07004498 /* CLASS H config */
4499 {TAIKO_A_CDC_CONN_CLSH_CTL, 0x3C, 0x14},
Kiran Kandic3b24402012-06-11 00:05:59 -07004500
4501 /* Use 16 bit sample size for TX1 to TX6 */
4502 {TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0x30, 0x20},
4503 {TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0x30, 0x20},
4504 {TAIKO_A_CDC_CONN_TX_SB_B3_CTL, 0x30, 0x20},
4505 {TAIKO_A_CDC_CONN_TX_SB_B4_CTL, 0x30, 0x20},
4506 {TAIKO_A_CDC_CONN_TX_SB_B5_CTL, 0x30, 0x20},
4507 {TAIKO_A_CDC_CONN_TX_SB_B6_CTL, 0x30, 0x20},
4508
4509 /* Use 16 bit sample size for TX7 to TX10 */
4510 {TAIKO_A_CDC_CONN_TX_SB_B7_CTL, 0x60, 0x40},
4511 {TAIKO_A_CDC_CONN_TX_SB_B8_CTL, 0x60, 0x40},
4512 {TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x60, 0x40},
4513 {TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x60, 0x40},
4514
4515 /* Use 16 bit sample size for RX */
4516 {TAIKO_A_CDC_CONN_RX_SB_B1_CTL, 0xFF, 0xAA},
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004517 {TAIKO_A_CDC_CONN_RX_SB_B2_CTL, 0xFF, 0x2A},
Kiran Kandic3b24402012-06-11 00:05:59 -07004518
4519 /*enable HPF filter for TX paths */
4520 {TAIKO_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
4521 {TAIKO_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
4522 {TAIKO_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
4523 {TAIKO_A_CDC_TX4_MUX_CTL, 0x8, 0x0},
4524 {TAIKO_A_CDC_TX5_MUX_CTL, 0x8, 0x0},
4525 {TAIKO_A_CDC_TX6_MUX_CTL, 0x8, 0x0},
4526 {TAIKO_A_CDC_TX7_MUX_CTL, 0x8, 0x0},
4527 {TAIKO_A_CDC_TX8_MUX_CTL, 0x8, 0x0},
4528 {TAIKO_A_CDC_TX9_MUX_CTL, 0x8, 0x0},
4529 {TAIKO_A_CDC_TX10_MUX_CTL, 0x8, 0x0},
4530
Kiran Kandi4c56c592012-07-25 11:04:55 -07004531 /* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
4532 {TAIKO_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
4533 {TAIKO_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
4534 {TAIKO_A_CDC_TX3_DMIC_CTL, 0x7, 0x1},
4535 {TAIKO_A_CDC_TX4_DMIC_CTL, 0x7, 0x1},
4536 {TAIKO_A_CDC_TX5_DMIC_CTL, 0x7, 0x1},
4537 {TAIKO_A_CDC_TX6_DMIC_CTL, 0x7, 0x1},
4538 {TAIKO_A_CDC_TX7_DMIC_CTL, 0x7, 0x1},
4539 {TAIKO_A_CDC_TX8_DMIC_CTL, 0x7, 0x1},
4540 {TAIKO_A_CDC_TX9_DMIC_CTL, 0x7, 0x1},
4541 {TAIKO_A_CDC_TX10_DMIC_CTL, 0x7, 0x1},
Kiran Kandic3b24402012-06-11 00:05:59 -07004542
Kiran Kandi4c56c592012-07-25 11:04:55 -07004543 /* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
4544 {TAIKO_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
4545 {TAIKO_A_CDC_CLK_DMIC_B2_CTL, 0x0E, 0x02},
4546
Kiran Kandic3b24402012-06-11 00:05:59 -07004547};
4548
4549static void taiko_codec_init_reg(struct snd_soc_codec *codec)
4550{
4551 u32 i;
4552
4553 for (i = 0; i < ARRAY_SIZE(taiko_codec_reg_init_val); i++)
4554 snd_soc_update_bits(codec, taiko_codec_reg_init_val[i].reg,
4555 taiko_codec_reg_init_val[i].mask,
4556 taiko_codec_reg_init_val[i].val);
4557}
4558
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004559static int taiko_setup_irqs(struct taiko_priv *taiko)
4560{
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004561 int i;
Joonwoo Parka8890262012-10-15 12:04:27 -07004562 int ret = 0;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004563 struct snd_soc_codec *codec = taiko->codec;
4564
Joonwoo Parkf6574c72012-10-10 17:29:57 -07004565 ret = wcd9xxx_request_irq(codec->control_data, WCD9XXX_IRQ_SLIMBUS,
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004566 taiko_slimbus_irq, "SLIMBUS Slave", taiko);
4567 if (ret) {
4568 pr_err("%s: Failed to request irq %d\n", __func__,
Joonwoo Parkf6574c72012-10-10 17:29:57 -07004569 WCD9XXX_IRQ_SLIMBUS);
Joonwoo Parka8890262012-10-15 12:04:27 -07004570 goto exit;
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004571 }
4572
4573 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
4574 wcd9xxx_interface_reg_write(codec->control_data,
Joonwoo Parka8890262012-10-15 12:04:27 -07004575 TAIKO_SLIM_PGD_PORT_INT_EN0 + i,
4576 0xFF);
4577exit:
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004578 return ret;
4579}
4580
Joonwoo Parka8890262012-10-15 12:04:27 -07004581int taiko_hs_detect(struct snd_soc_codec *codec,
4582 struct wcd9xxx_mbhc_config *mbhc_cfg)
4583{
4584 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
4585 return wcd9xxx_mbhc_start(&taiko->mbhc, mbhc_cfg);
4586}
4587EXPORT_SYMBOL_GPL(taiko_hs_detect);
4588
4589static struct wcd9xxx_reg_address taiko_reg_address = {
4590 .micb_4_mbhc = TAIKO_A_MICB_4_MBHC,
4591 .micb_4_int_rbias = TAIKO_A_MICB_4_INT_RBIAS,
4592 .micb_4_ctl = TAIKO_A_MICB_4_CTL,
4593};
4594
Kiran Kandic3b24402012-06-11 00:05:59 -07004595static int taiko_codec_probe(struct snd_soc_codec *codec)
4596{
4597 struct wcd9xxx *control;
4598 struct taiko_priv *taiko;
Joonwoo Parka8890262012-10-15 12:04:27 -07004599 struct wcd9xxx_pdata *pdata;
4600 struct wcd9xxx *wcd9xxx;
Kiran Kandic3b24402012-06-11 00:05:59 -07004601 struct snd_soc_dapm_context *dapm = &codec->dapm;
4602 int ret = 0;
4603 int i;
Kuirong Wang906ac472012-07-09 12:54:44 -07004604 void *ptr = NULL;
Kiran Kandic3b24402012-06-11 00:05:59 -07004605
4606 codec->control_data = dev_get_drvdata(codec->dev->parent);
4607 control = codec->control_data;
4608
Kiran Kandi4c56c592012-07-25 11:04:55 -07004609 dev_info(codec->dev, "%s()\n", __func__);
4610
Kiran Kandic3b24402012-06-11 00:05:59 -07004611 taiko = kzalloc(sizeof(struct taiko_priv), GFP_KERNEL);
4612 if (!taiko) {
4613 dev_err(codec->dev, "Failed to allocate private data\n");
4614 return -ENOMEM;
4615 }
4616 for (i = 0 ; i < NUM_DECIMATORS; i++) {
4617 tx_hpf_work[i].taiko = taiko;
4618 tx_hpf_work[i].decimator = i + 1;
4619 INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
4620 tx_hpf_corner_freq_callback);
4621 }
4622
Kiran Kandic3b24402012-06-11 00:05:59 -07004623 snd_soc_codec_set_drvdata(codec, taiko);
4624
Joonwoo Parka8890262012-10-15 12:04:27 -07004625 /* codec resmgr module init */
4626 wcd9xxx = codec->control_data;
4627 pdata = dev_get_platdata(codec->dev->parent);
4628 ret = wcd9xxx_resmgr_init(&taiko->resmgr, codec, wcd9xxx, pdata,
4629 &taiko_reg_address);
4630 if (ret) {
4631 pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
4632 return ret;
4633 }
4634
4635 /* init and start mbhc */
4636 ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
4637 if (ret) {
4638 pr_err("%s: mbhc init failed %d\n", __func__, ret);
4639 return ret;
4640 }
4641
Kiran Kandic3b24402012-06-11 00:05:59 -07004642 taiko->codec = codec;
Kiran Kandic3b24402012-06-11 00:05:59 -07004643 for (i = 0; i < COMPANDER_MAX; i++) {
4644 taiko->comp_enabled[i] = 0;
4645 taiko->comp_fs[i] = COMPANDER_FS_48KHZ;
4646 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004647 taiko->intf_type = wcd9xxx_get_intf_type();
4648 taiko->aux_pga_cnt = 0;
4649 taiko->aux_l_gain = 0x1F;
4650 taiko->aux_r_gain = 0x1F;
Kiran Kandic3b24402012-06-11 00:05:59 -07004651 taiko_update_reg_defaults(codec);
4652 taiko_codec_init_reg(codec);
4653 ret = taiko_handle_pdata(taiko);
4654 if (IS_ERR_VALUE(ret)) {
4655 pr_err("%s: bad pdata\n", __func__);
4656 goto err_pdata;
4657 }
4658
Kuirong Wang906ac472012-07-09 12:54:44 -07004659 ptr = kmalloc((sizeof(taiko_rx_chs) +
4660 sizeof(taiko_tx_chs)), GFP_KERNEL);
4661 if (!ptr) {
4662 pr_err("%s: no mem for slim chan ctl data\n", __func__);
4663 ret = -ENOMEM;
4664 goto err_nomem_slimch;
4665 }
4666
Kiran Kandic3b24402012-06-11 00:05:59 -07004667 if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
4668 snd_soc_dapm_new_controls(dapm, taiko_dapm_i2s_widgets,
4669 ARRAY_SIZE(taiko_dapm_i2s_widgets));
4670 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
4671 ARRAY_SIZE(audio_i2s_map));
Kuirong Wang906ac472012-07-09 12:54:44 -07004672 for (i = 0; i < ARRAY_SIZE(taiko_i2s_dai); i++)
4673 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
4674 } else if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
4675 for (i = 0; i < NUM_CODEC_DAIS; i++) {
4676 INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
4677 init_waitqueue_head(&taiko->dai[i].dai_wait);
4678 }
Kiran Kandic3b24402012-06-11 00:05:59 -07004679 }
4680
Kuirong Wang906ac472012-07-09 12:54:44 -07004681 control->num_rx_port = TAIKO_RX_MAX;
4682 control->rx_chs = ptr;
4683 memcpy(control->rx_chs, taiko_rx_chs, sizeof(taiko_rx_chs));
4684 control->num_tx_port = TAIKO_TX_MAX;
4685 control->tx_chs = ptr + sizeof(taiko_rx_chs);
4686 memcpy(control->tx_chs, taiko_tx_chs, sizeof(taiko_tx_chs));
4687
Kiran Kandic3b24402012-06-11 00:05:59 -07004688 snd_soc_dapm_sync(dapm);
4689
Joonwoo Park7680b9f2012-07-13 11:36:48 -07004690 (void) taiko_setup_irqs(taiko);
Kiran Kandic3b24402012-06-11 00:05:59 -07004691
Kiran Kandic3b24402012-06-11 00:05:59 -07004692 codec->ignore_pmdown_time = 1;
4693 return ret;
4694
Kiran Kandic3b24402012-06-11 00:05:59 -07004695err_pdata:
Kuirong Wang906ac472012-07-09 12:54:44 -07004696 kfree(ptr);
4697err_nomem_slimch:
Kiran Kandic3b24402012-06-11 00:05:59 -07004698 kfree(taiko);
4699 return ret;
4700}
4701static int taiko_codec_remove(struct snd_soc_codec *codec)
4702{
Kiran Kandic3b24402012-06-11 00:05:59 -07004703 struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
Joonwoo Parka8890262012-10-15 12:04:27 -07004704
4705 /* cleanup MBHC */
4706 wcd9xxx_mbhc_deinit(&taiko->mbhc);
4707 /* cleanup resmgr */
4708 wcd9xxx_resmgr_deinit(&taiko->resmgr);
4709
Kiran Kandic3b24402012-06-11 00:05:59 -07004710 kfree(taiko);
4711 return 0;
4712}
4713static struct snd_soc_codec_driver soc_codec_dev_taiko = {
4714 .probe = taiko_codec_probe,
4715 .remove = taiko_codec_remove,
4716
4717 .read = taiko_read,
4718 .write = taiko_write,
4719
4720 .readable_register = taiko_readable,
4721 .volatile_register = taiko_volatile,
4722
4723 .reg_cache_size = TAIKO_CACHE_SIZE,
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -07004724 .reg_cache_default = taiko_reset_reg_defaults,
Kiran Kandic3b24402012-06-11 00:05:59 -07004725 .reg_word_size = 1,
4726
4727 .controls = taiko_snd_controls,
4728 .num_controls = ARRAY_SIZE(taiko_snd_controls),
4729 .dapm_widgets = taiko_dapm_widgets,
4730 .num_dapm_widgets = ARRAY_SIZE(taiko_dapm_widgets),
4731 .dapm_routes = audio_map,
4732 .num_dapm_routes = ARRAY_SIZE(audio_map),
4733};
4734
4735#ifdef CONFIG_PM
4736static int taiko_suspend(struct device *dev)
4737{
4738 dev_dbg(dev, "%s: system suspend\n", __func__);
4739 return 0;
4740}
4741
4742static int taiko_resume(struct device *dev)
4743{
4744 struct platform_device *pdev = to_platform_device(dev);
4745 struct taiko_priv *taiko = platform_get_drvdata(pdev);
4746 dev_dbg(dev, "%s: system resume\n", __func__);
Joonwoo Parka8890262012-10-15 12:04:27 -07004747 /* Notify */
4748 wcd9xxx_resmgr_notifier_call(&taiko->resmgr, WCD9XXX_EVENT_POST_RESUME);
Kiran Kandic3b24402012-06-11 00:05:59 -07004749 return 0;
4750}
4751
4752static const struct dev_pm_ops taiko_pm_ops = {
4753 .suspend = taiko_suspend,
4754 .resume = taiko_resume,
4755};
4756#endif
4757
4758static int __devinit taiko_probe(struct platform_device *pdev)
4759{
4760 int ret = 0;
4761 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
4762 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
4763 taiko_dai, ARRAY_SIZE(taiko_dai));
4764 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
4765 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_taiko,
4766 taiko_i2s_dai, ARRAY_SIZE(taiko_i2s_dai));
4767 return ret;
4768}
4769static int __devexit taiko_remove(struct platform_device *pdev)
4770{
4771 snd_soc_unregister_codec(&pdev->dev);
4772 return 0;
4773}
4774static struct platform_driver taiko_codec_driver = {
4775 .probe = taiko_probe,
4776 .remove = taiko_remove,
4777 .driver = {
4778 .name = "taiko_codec",
4779 .owner = THIS_MODULE,
4780#ifdef CONFIG_PM
4781 .pm = &taiko_pm_ops,
4782#endif
4783 },
4784};
4785
4786static int __init taiko_codec_init(void)
4787{
4788 return platform_driver_register(&taiko_codec_driver);
4789}
4790
4791static void __exit taiko_codec_exit(void)
4792{
4793 platform_driver_unregister(&taiko_codec_driver);
4794}
4795
4796module_init(taiko_codec_init);
4797module_exit(taiko_codec_exit);
4798
4799MODULE_DESCRIPTION("Taiko codec driver");
4800MODULE_LICENSE("GPL v2");