aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic326x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tlv320aic326x.c')
-rw-r--r--sound/soc/codecs/tlv320aic326x.c4528
1 files changed, 4528 insertions, 0 deletions
diff --git a/sound/soc/codecs/tlv320aic326x.c b/sound/soc/codecs/tlv320aic326x.c
new file mode 100644
index 00000000000..8bbd295a332
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic326x.c
@@ -0,0 +1,4528 @@
1/*
2* linux/sound/soc/codecs/tlv320aic3262.c
3*
4* Copyright (C) 2012 Texas Instruments, Inc.
5*
6* Based on sound/soc/codecs/tlv320aic3262.c
7*
8* This package is free software; you can redistribute it and/or modify
9* it under the terms of the GNU General Public License version 2 as
10* published by the Free Software Foundation.
11*
12* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15*
16* The TLV320AIC3262 is a flexible, low-power, low-voltage stereo audio
17* codec with digital microphone inputs and programmable outputs.
18*
19* History:
20*
21* Rev 0.1 ASoC driver support 20-01-2011
22*
23* The AIC325x ASoC driver is ported for the codec AIC3262.
24* Rev 0.2 ASoC driver support 21-03-2011
25* The AIC326x ASoC driver is updated abe changes.
26*
27* Rev 0.3 ASoC driver support 12.09.2011
28* fixed the compilation issues for Whistler support
29*
30* Rev 0.4 ASoC driver support 27.09.2011
31* The AIC326x driver ported for Nvidia cardhu.
32*
33* Rev 0.5 Modified to support Multiple ASI Ports 08-Nov-2011
34* Driver updated to support ASI Ports of AIC3262
35*
36* Modified by Nvidia 23-Nov-2011 for K39 ASoC changes.
37*/
38
39/*
40 *****************************************************************************
41 * INCLUDES
42 *****************************************************************************
43 */
44#include <linux/module.h>
45#include <linux/moduleparam.h>
46#include <linux/kernel.h>
47#include <linux/init.h>
48#include <linux/delay.h>
49#include <linux/pm.h>
50#include <linux/i2c.h>
51#include <linux/platform_device.h>
52#include <linux/slab.h>
53#include <sound/core.h>
54#include <sound/pcm.h>
55#include <sound/pcm_params.h>
56#include <sound/soc.h>
57#include <sound/soc-dapm.h>
58#include <sound/initval.h>
59#include <sound/tlv.h>
60#include <asm/div64.h>
61#include <sound/tlv320aic326x.h>
62#include <sound/jack.h>
63#include <linux/spi/spi.h>
64
65#include "tlv320aic326x.h"
66#include <linux/gpio.h>
67/*
68 *****************************************************************************
69 * Global Variable
70 *****************************************************************************
71 */
72static u8 aic3262_reg_ctl;
73
74#ifdef AIC3262_TiLoad
75 extern int aic3262_driver_init(struct snd_soc_codec *codec);
76#endif
77
78
79
80/* whenever aplay/arecord is run, aic3262_hw_params() function gets called.
81 * This function reprograms the clock dividers etc. this flag can be used to
82 * disable this when the clock dividers are programmed by pps config file
83 */
84static int soc_static_freq_config = 1;
85static struct aic3262_priv *aic3262_priv_data;
86static struct i2c_client *i2c_pdev;
87static struct snd_soc_codec *aic3262_codec;
88
89/*
90 *****************************************************************************
91 * Macros
92 *****************************************************************************
93 */
94
95/* ASoC Widget Control definition for a single Register based Control */
96#define SOC_SINGLE_AIC3262(xname) \
97{\
98 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
99 .info = __new_control_info, .get = __new_control_get,\
100 .put = __new_control_put, \
101 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
102}
103#define SOC_SINGLE_N(xname, xreg, xshift, xmax, xinvert) \
104{\
105 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
106 .info = n_control_info, .get = n_control_get,\
107 .put = n_control_put, \
108 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
109 .private_value = ((unsigned long)&(struct soc_mixer_control)) \
110 {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \
111 .invert = xinvert} }
112
113/* ASoC Widget Control definition for a Double Register based Control */
114
115#define SOC_DOUBLE_R_N(xname, reg_left, reg_right, xshift, xmax, xinvert) \
116{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
117 .info = snd_soc_info_volsw_2r_n, \
118 .get = snd_soc_get_volsw_2r_n, .put = snd_soc_put_volsw_2r_n, \
119 .private_value = (unsigned long)&(struct soc_mixer_control) \
120 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
121 .max = xmax, .invert = xinvert} }
122
123#define SND_SOC_DAPM_SWITCH_N(wname, wreg, wshift, winvert) \
124{ .id = snd_soc_dapm_switch, .name = wname, .reg = wreg, .shift = wshift,\
125 .invert = winvert, .kcontrols = NULL, .num_kcontrols = 0}
126/*
127 *****************************************************************************
128 * Function Prototype
129 *****************************************************************************
130 */
131static int aic3262_set_bias_level(struct snd_soc_codec *codec,
132 enum snd_soc_bias_level level);
133
134static int __new_control_info(struct snd_kcontrol *kcontrol,
135 struct snd_ctl_elem_info *uinfo);
136
137static int __new_control_get(struct snd_kcontrol *kcontrol,
138 struct snd_ctl_elem_value *ucontrol);
139
140static int __new_control_put(struct snd_kcontrol *kcontrol,
141 struct snd_ctl_elem_value *ucontrol);
142
143static inline int aic3262_get_divs(int mclk, int rate);
144
145static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
146 struct snd_pcm_hw_params *params,
147 struct snd_soc_dai *dai);
148
149static int aic3262_multi_i2s_set_dai_sysclk(struct snd_soc_dai *codec_dai,
150 int clk_id, unsigned int freq, int dir);
151static int aic3262_multi_i2s_set_dai_pll(struct snd_soc_dai *codec_dai,
152 int pll_id, int source, unsigned int freq_in,
153 unsigned int freq_out);
154
155static int aic3262_multi_i2s_asi1_set_dai_fmt(struct snd_soc_dai *codec_dai,
156 unsigned int fmt);
157
158static int aic3262_multi_i2s_asi2_set_dai_fmt(struct snd_soc_dai *codec_dai,
159 unsigned int fmt);
160
161static int aic3262_multi_i2s_asi3_set_dai_fmt(struct snd_soc_dai *codec_dai,
162 unsigned int fmt);
163
164static int aic3262_multi_i2s_asi1_mute(struct snd_soc_dai *dai, int mute);
165
166static int aic3262_multi_i2s_asi2_mute(struct snd_soc_dai *dai, int mute);
167
168static int aic3262_multi_i2s_asi3_mute(struct snd_soc_dai *dai, int mute);
169
170#if 0
171static const char *wclk1_pincontrol[] = {
172 "ASI1 Word Clock Input/Output", "CLKOUT output"};
173static const char *dout1_pincontrol[] = {
174 "disabled", "ASI1 data output", "gpio", "clock out",
175 "INT1", "INT2", "SAR ADC interrupt"};
176
177static const char *din1_pincontrol[] = {"disabled", "enabled"};
178
179static const char *wclk2_pincontrol[] = {
180 "diabled", "ASI1 secondary wclk", "general purpose input",
181 "general purpose output", "clkout", "INT1 interrupt",
182 "IN2 interrupt", "output digital microphone",
183 "SAR ADC interrupt", "data output for ASI1"};
184
185static const char *bclk2_pincontrol[] = {
186 "diabled", "ASI1 secondary wclk", "general purpose input",
187 "general purpose output", "clkout", "INT1 interrupt",
188 "IN2 interrupt", "output digital microphone",
189 "SAR ADC interrupt", "data output for ASI1"};
190
191static const char *dout2_pincontrol[] = {
192 "disabled", "ASI2 Data Output", "General Purpose Output",
193 "INT1 Interrupt", "INT2 Interrupt", "SAR ADC interrupt",
194 "Output for digital microphone", "Data Output for ASI1"};
195
196static const char *din2_pincontrol[] = {"disabled", "enabled"};
197
198static const char *wclk3_pincontrol[] = {
199 "Disabled", "ASI3 WCLK", "General Purpose Input",
200 "General Purpose output", "Data Output for ASI1"};
201
202static const char *bclk3_pincontrol[] = {
203 "Disabled", "ASI3 BCLK", "General Purpose Input",
204 "General Purpose output", "Data Output for ASI1"};
205
206static const char *dout3_pincontrol[] = {
207 "disabled", "ASI3 data ooutput", "General Purpose Output",
208 "ASI1 Word Clock Output", "Data Output for ASI1"};
209
210static const char *din3_pincontrol[] = {"disabled", "enabled"};
211
212static const char *clkin[] = {
213 "mclk1", "bclk1", "gpio1", "pll_clk", "bclk2", "gpi1",
214 "hf_ref_clk", "hf_osc_clk", "mclk2", "gpio2", "gpi2"};
215
216#endif
217#ifdef DAC_INDEPENDENT_VOL
218/*
219 *----------------------------------------------------------------------------
220 * Function : n_control_info
221 * Purpose : This function is to initialize data for new control required to
222 * program the AIC3262 registers.
223 *
224 *----------------------------------------------------------------------------
225 */
226static int n_control_info(struct snd_kcontrol *kcontrol,
227 struct snd_ctl_elem_info *uinfo)
228{
229 struct soc_mixer_control *mc =
230 (struct soc_mixer_control *)kcontrol->private_value;
231 int max = mc->max;
232 unsigned int shift = mc->shift;
233 unsigned int rshift = mc->rshift;
234
235 if (max == 1)
236 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
237 else
238 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
239
240 uinfo->count = shift == rshift ? 1 : 2;
241 uinfo->value.integer.min = 0;
242 uinfo->value.integer.max = max;
243 return 0;
244}
245
246/*
247 *----------------------------------------------------------------------------
248 * Function : n_control_get
249 * Purpose : This function is to read data of new control for
250 * program the AIC3262 registers.
251 *
252 *----------------------------------------------------------------------------
253 */
254static int n_control_get(struct snd_kcontrol *kcontrol,
255 struct snd_ctl_elem_value *ucontrol)
256{
257 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
258 u32 val;
259 unsigned short mask, shift;
260 struct soc_mixer_control *mc =
261 (struct soc_mixer_control *)kcontrol->private_value;
262 if (!strcmp(kcontrol->id.name, "Left DAC Volume")) {
263 mask = AIC3262_8BITS_MASK;
264 shift = 0;
265 val = snd_soc_read(codec, mc->reg);
266 ucontrol->value.integer.value[0] =
267 (val <= 48) ? (val + 127) : (val - 129);
268 }
269 if (!strcmp(kcontrol->id.name, "Right DAC Volume")) {
270 mask = AIC3262_8BITS_MASK;
271 shift = 0;
272 val = snd_soc_read(codec, mc->reg);
273 ucontrol->value.integer.value[0] =
274 (val <= 48) ? (val + 127) : (val - 129);
275 }
276
277 return 0;
278}
279
280/*
281 *----------------------------------------------------------------------------
282 * Function : __new_control_put
283 * Purpose : new_control_put is called to pass data from user/application to
284 * the driver.
285 *
286 *----------------------------------------------------------------------------
287 */
288static int n_control_put(struct snd_kcontrol *kcontrol,
289 struct snd_ctl_elem_value *ucontrol)
290{
291 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
292 struct soc_mixer_control *mc =
293 (struct soc_mixer_control *)kcontrol->private_value;
294 u8 val, val_mask;
295 int reg, err;
296 unsigned int invert = mc->invert;
297 int max = mc->max;
298 DBG("n_control_put\n");
299 reg = mc->reg;
300 val = ucontrol->value.integer.value[0];
301 if (invert)
302 val = max - val;
303 if (!strcmp(kcontrol->id.name, "Left DAC Volume")) {
304 DBG("LDAC\n");
305 val = (val >= 127) ? (val - 127) : (val + 129);
306 val_mask = AIC3262_8BITS_MASK;
307 }
308 if (!strcmp(kcontrol->id.name, "Right DAC Volume")) {
309 DBG("RDAC\n");
310 val = (val >= 127) ? (val - 127) : (val + 129);
311 val_mask = AIC3262_8BITS_MASK;
312 }
313
314 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
315 if (err < 0) {
316 printk(KERN_ERR "Error while updating bits\n");
317 return err;
318 }
319
320 return 0;
321}
322#endif /*#ifdef DAC_INDEPENDENT_VOL*/
323/*
324 *------------------------------------------------------------------------------
325 * snd_soc_info_volsw_2r_n - double mixer info callback
326 * @kcontrol: mixer control
327 * @uinfo: control element information
328 *
329 * Callback to provide information about a double mixer control that
330 * spans 2 codec registers.
331 *
332 * Returns 0 for success.
333 *------------------------------------------------------------------------------
334 */
335int snd_soc_info_volsw_2r_n(struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_info *uinfo)
337{
338 struct soc_mixer_control *mc =
339 (struct soc_mixer_control *)kcontrol->private_value;
340 int max = mc->max;
341
342 if (max == 1)
343 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
344 else
345 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
346
347 uinfo->count = 2;
348 uinfo->value.integer.min = 0;
349 uinfo->value.integer.max = max;
350 return 0;
351}
352
353/*
354 *------------------------------------------------------------------------------
355 * snd_soc_get_volsw_2r_n - double mixer get callback
356 * @kcontrol: mixer control
357 * @ucontrol: control element information
358 *
359 * Callback to get the value of a double mixer control that spans 2 registers.
360 *
361 * Returns 0 for success.
362 *------------------------------------------------------------------------------
363 */
364int snd_soc_get_volsw_2r_n(struct snd_kcontrol *kcontrol,
365 struct snd_ctl_elem_value *ucontrol)
366{
367 struct soc_mixer_control *mc =
368 (struct soc_mixer_control *)kcontrol->private_value;
369 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
370 unsigned int reg = mc->reg;
371 unsigned int reg2 = mc->rreg;
372 unsigned int shift = mc->shift;
373 int max = mc->max;
374 unsigned int mask;
375 unsigned int invert = mc->invert;
376 unsigned short val, val2;
377
378 if (!strcmp(kcontrol->id.name, "PCM Playback Volume")) {
379 mask = AIC3262_8BITS_MASK;
380 shift = 0;
381 } else if (!strcmp(kcontrol->id.name, "HP Driver Gain")) {
382 mask = 0x3F;
383 shift = 0;
384 } else if (!strcmp(kcontrol->id.name, "PGA Capture Volume")) {
385 mask = 0x7F;
386 shift = 0;
387 } else if (!strcmp(kcontrol->id.name, "REC Driver Volume")) {
388 mask = 0x3F;
389 shift = 0;
390 } else if (!strcmp(kcontrol->id.name, "LO to HP Volume")) {
391 mask = 0x7F;
392 shift = 0;
393 } else if (!strcmp(kcontrol->id.name, "MA Volume")) {
394 mask = 0x7F;
395 shift = 0;
396 } else {
397 printk(KERN_ERR "Invalid kcontrol name\n");
398 return -1;
399 }
400
401 /* Read, update the corresponding Registers */
402 val = (snd_soc_read(codec, reg) >> shift) & mask;
403 val2 = (snd_soc_read(codec, reg2) >> shift) & mask;
404
405 if (!strcmp(kcontrol->id.name, "PCM Playback Volume")) {
406 ucontrol->value.integer.value[0] =
407 (val <= 48) ? (val + 127) : (val - 129);
408 ucontrol->value.integer.value[1] =
409 (val2 <= 48) ? (val2 + 127) : (val2 - 129);
410 } else if (!strcmp(kcontrol->id.name, "HP Driver Gain")) {
411 ucontrol->value.integer.value[0] =
412 (val >= 57) ? (val - 57) : (val + 7);
413 ucontrol->value.integer.value[1] =
414 (val2 >= 57) ? (val2 - 57) : (val2 + 7);
415 } else if (!strcmp(kcontrol->id.name, "PGA Capture Volume")) {
416 ucontrol->value.integer.value[0] =
417 (val <= 40) ? (val + 24) : (val - 104);
418 ucontrol->value.integer.value[1] =
419 (val2 <= 40) ? (val2 + 24) : (val2 - 104);
420 } else if (!strcmp(kcontrol->id.name, "REC Driver Volume")) {
421 ucontrol->value.integer.value[0] = ((val >= 0) & (val <= 29)) ?
422 (val + 7) : (val - 57);
423 ucontrol->value.integer.value[1] = ((val2 >= 0) &
424 (val2 <= 29)) ? (val2 + 7) : (val2 - 57);
425
426 } else if (!strcmp(kcontrol->id.name, "LO to HP Volume")) {
427 ucontrol->value.integer.value[0] = ((val >= 0) & (val <= 116)) ?
428 (val + 1) : ((val == 127) ? (0) : (117));
429 ucontrol->value.integer.value[1] = ((val2 >= 0) & (val2 <= 116))
430 ? (val2 + 1) : ((val2 == 127) ? (0) : (117));
431
432 } else if (!strcmp(kcontrol->id.name, "MA Volume")) {
433 ucontrol->value.integer.value[0] = (val <= 40) ?
434 (41 - val) : (val = 0);
435 ucontrol->value.integer.value[1] = (val2 <= 40) ?
436 (41 - val2) : (val2 = 0);
437 }
438
439 if (invert) {
440 ucontrol->value.integer.value[0] =
441 max - ucontrol->value.integer.value[0];
442 ucontrol->value.integer.value[1] =
443 max - ucontrol->value.integer.value[1];
444 }
445
446 return 0;
447}
448/*
449*-------------------------------------------------------------------------------
450* snd_soc_put_volsw_2r_n - double mixer set callback
451* @kcontrol: mixer control
452* @ucontrol: control element information
453*
454* Callback to set the value of a double mixer control that spans 2 registers.
455*
456* Returns 0 for success.
457*-------------------------------------------------------------------------------
458*/
459int snd_soc_put_volsw_2r_n(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_value *ucontrol)
461{
462 struct soc_mixer_control *mc =
463 (struct soc_mixer_control *)kcontrol->private_value;
464 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
465 unsigned int reg = mc->reg;
466 unsigned int reg2 = mc->rreg;
467 unsigned int shift = mc->shift;
468 int max = mc->max;
469 unsigned int mask;
470 unsigned int invert = mc->invert;
471 int err;
472 unsigned short val, val2, val_mask;
473
474 mask = 0x00FF;
475
476 val = (ucontrol->value.integer.value[0] & mask);
477 val2 = (ucontrol->value.integer.value[1] & mask);
478 if (invert) {
479 val = max - val;
480 val2 = max - val2;
481 }
482
483 /* Check for the string name of the kcontrol */
484 if (!strcmp(kcontrol->id.name, "PCM Playback Volume")) {
485 val = (val >= 127) ? (val - 127) : (val + 129);
486 val2 = (val2 >= 127) ? (val2 - 127) : (val2 + 129);
487 val_mask = AIC3262_8BITS_MASK; /* 8 bits */
488 } else if ((!strcmp(kcontrol->id.name, "HP Driver Gain")) ||
489 (!strcmp(kcontrol->id.name, "LO Driver Gain"))) {
490 val = (val <= 6) ? (val + 57) : (val - 7);
491 val2 = (val2 <= 6) ? (val2 + 57) : (val2 - 7);
492 val_mask = 0x3F; /* 6 bits */
493 DBG("val=%d, val2=%d", val, val2);
494 } else if (!strcmp(kcontrol->id.name, "PGA Capture Volume")) {
495 val = (val >= 24) ? ((val <= 64) ?
496 (val-24) : (40)) : (val + 104);
497 val2 = (val2 >= 24) ?
498 ((val2 <= 64) ? (val2 - 24) : (40)) : (val2 + 104);
499 val_mask = 0x7F; /* 7 bits */
500 } else if (!strcmp(kcontrol->id.name, "LO to REC Volume")) {
501
502 val = (val <= 116) ?
503 (val % 116) : ((val == 117) ? (127) : (117));
504 val2 = (val2 <= 116) ?
505 (val2 % 116) : ((val2 == 117) ? (127) : (117));
506 val_mask = 0x7F;
507 } else if (!strcmp(kcontrol->id.name, "REC Driver Volume")) {
508
509 val = (val <= 7) ? (val + 57) : ((val < 36) ? (val - 7) : (29));
510 val2 = (val2 <= 7) ?
511 (val2 + 57) : ((val2 < 36) ? (val2 - 7) : (29));
512 val_mask = 0x3F;
513 } else if (!strcmp(kcontrol->id.name, "LO to HP Volume")) {
514
515 val = ((val > 0) & (val <= 117)) ?
516 (val - 1) : ((val == 0) ? (127) : (116));
517 val2 = ((val2 > 0) & (val2 <= 117)) ?
518 (val2 - 1) : ((val2 == 0) ? (127) : (116));
519 val_mask = 0x7F;
520 } else if (!strcmp(kcontrol->id.name, "MA Volume")) {
521
522 val = ((val <= 41) & (val > 0)) ?
523 (41 - val) : ((val > 41) ? (val = 41) : (63));
524 val2 = ((val2 <= 41) & (val2 > 0)) ?
525 (41 - val2) : ((val2 > 41) ? (val2 = 41) : (63));
526 val_mask = 0x7F;
527 } else {
528 printk(KERN_ERR "Invalid control name\n");
529 return -1;
530 }
531
532 val = val << shift;
533 val2 = val2 << shift;
534
535 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
536 if (err < 0)
537 return err;
538
539 err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
540 return err;
541}
542
543static int __new_control_info(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_info *uinfo)
545{
546 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
547 uinfo->count = 1;
548 uinfo->value.integer.min = 0;
549 uinfo->value.integer.max = 65535;
550
551 return 0;
552}
553
554/*
555 *----------------------------------------------------------------------------
556 * Function : __new_control_get
557 * Purpose : This function is to read data of new control for
558 * program the AIC3262 registers.
559 *
560 *----------------------------------------------------------------------------
561 */
562static int __new_control_get(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
566 u32 val;
567 val = snd_soc_read(codec, aic3262_reg_ctl);
568 ucontrol->value.integer.value[0] = val;
569 return 0;
570}
571
572/*
573 *----------------------------------------------------------------------------
574 * Function : __new_control_put
575 * Purpose : new_control_put is called to pass data from user/application to
576 * the driver.
577 *
578 *----------------------------------------------------------------------------
579 */
580static int __new_control_put(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
582{
583 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
584 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
585 u8 data[2];
586 int ret = 0;
587
588 u32 data_from_user = ucontrol->value.integer.value[0];
589
590 aic3262_change_book(codec, 0);
591 aic3262_reg_ctl = data[0] = (u8) ((data_from_user & 0xFF00) >> 8);
592 data[1] = (u8) ((data_from_user & 0x00FF));
593
594 if (!data[0])
595 aic3262->page_no = data[1];
596
597 DBG("reg = %d val = %x\n", data[0], data[1]);
598#if defined(LOCAL_REG_ACCESS)
599 if (codec->hw_write(codec->control_data, data, 2) != 2)
600 ret = -EIO;
601#else
602 ret = snd_soc_write(codec, data[0], data[1]);
603#endif
604 if (ret)
605 printk(KERN_ERR "Error in i2c write\n");
606
607 return ret;
608}
609
610
611/*
612 *****************************************************************************
613 * Structure Initialization
614 *****************************************************************************
615 */
616static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0);
617static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1200, 50, 0);
618static const DECLARE_TLV_DB_SCALE(spk_gain_tlv, 600, 600, 0);
619static const DECLARE_TLV_DB_SCALE(output_gain_tlv, -600, 100, 0);
620static const DECLARE_TLV_DB_SCALE(micpga_gain_tlv, 0, 50, 0);
621static const DECLARE_TLV_DB_SCALE(adc_fine_gain_tlv, -40, 10, 0);
622static const DECLARE_TLV_DB_SCALE(beep_gen_volume_tlv, -6300, 100, 0);
623
624/* Chip-level Input and Output CM Mode Controls */
625static const char *input_common_mode_text[] = {
626 "0.9v", "0.75v" };
627
628static const char *output_common_mode_text[] = {
629 "Input CM", "1.25v", "1.5v", "1.65v" };
630
631static const struct soc_enum input_cm_mode =
632 SOC_ENUM_SINGLE(CM_REG, 2, 2, input_common_mode_text);
633
634static const struct soc_enum output_cm_mode =
635 SOC_ENUM_SINGLE(CM_REG, 0, 4, output_common_mode_text);
636
637/*
638 *****************************************************************************
639 * Structure Initialization
640 *****************************************************************************
641 */
642static const struct snd_kcontrol_new aic3262_snd_controls[] = {
643 /* Output */
644#ifndef DAC_INDEPENDENT_VOL
645 /* sound new kcontrol for PCM Playback volume control */
646
647 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
648 DAC_LVOL, DAC_RVOL, 8,0xffffff81, 0x30, dac_vol_tlv),
649#endif
650 /*HP Driver Gain Control*/
651 SOC_DOUBLE_R_SX_TLV("HeadPhone Driver Amplifier Volume",
652 HPL_VOL, HPR_VOL, 6, 0xfffffffa, 0xe, output_gain_tlv),
653
654 /*LO Driver Gain Control*/
655 SOC_DOUBLE_TLV("Speaker Amplifier Volume",
656 SPK_AMP_CNTL_R4, 4, 0, 5, 0, spk_gain_tlv),
657
658 SOC_DOUBLE_R_SX_TLV("Receiver Amplifier Volume",
659 REC_AMP_CNTL_R5, RAMPR_VOL, 6, 0xfffffffa, 0x1d, output_gain_tlv),
660
661 SOC_DOUBLE_R_SX_TLV("PCM Capture Volume",
662 LADC_VOL, RADC_VOL, 7,0xffffff68, 0x24, adc_vol_tlv),
663
664
665 SOC_DOUBLE_R_TLV ("MicPGA Volume Control",
666 MICL_PGA, MICR_PGA, 0, 0x5F, 0, micpga_gain_tlv),
667 SOC_DOUBLE_TLV("PCM Capture Fine Gain Volume",
668 ADC_FINE_GAIN, 4, 0, 5, 1, adc_fine_gain_tlv),
669
670 SOC_DOUBLE("ADC channel mute", ADC_FINE_GAIN, 7, 3, 1, 0),
671
672 SOC_DOUBLE("DAC MUTE", DAC_MVOL_CONF, 2, 3, 1, 1),
673
674 /* sound new kcontrol for Programming the registers from user space */
675 SOC_SINGLE_AIC3262("Program Registers"),
676
677 SOC_SINGLE("RESET", RESET_REG, 0,1,0),
678
679 SOC_SINGLE("DAC VOL SOFT STEPPING", DAC_MVOL_CONF, 0, 2, 0),
680
681#ifdef DAC_INDEPENDENT_VOL
682 /*SOC_SINGLE_N("Left DAC Volume", DAC_LVOL, 0, 0xAF, 0),
683 SOC_SINGLE_N("Right DAC Volume", DAC_RVOL, 0, 0xAF, 0),*/
684#endif
685
686 SOC_SINGLE("DAC AUTO MUTE CONTROL", DAC_MVOL_CONF, 4, 7, 0),
687 SOC_SINGLE("RIGHT MODULATOR SETUP", DAC_MVOL_CONF, 7, 1, 0),
688
689 SOC_SINGLE("ADC Volume soft stepping", ADC_CHANNEL_POW, 0, 3, 0),
690
691 SOC_DOUBLE_R("MICPGA enable/disable",MICL_PGA,MICR_PGA,7, 1, 0),
692
693 SOC_SINGLE("Mic Bias ext independent enable", MIC_BIAS_CNTL, 7, 1, 0),
694 SOC_SINGLE("MICBIAS_EXT ON", MIC_BIAS_CNTL, 6, 1, 0),
695 SOC_SINGLE("MICBIAS EXT Power Level", MIC_BIAS_CNTL, 4, 3, 0),
696
697 SOC_SINGLE("MICBIAS_INT ON", MIC_BIAS_CNTL, 2, 1, 0),
698 SOC_SINGLE("MICBIAS INT Power Level", MIC_BIAS_CNTL, 0, 3, 0),
699
700 SOC_DOUBLE("DRC_EN_CTL", DRC_CNTL_R1, 6, 5, 1, 0),
701 SOC_SINGLE("DRC_THRESHOLD_LEVEL", DRC_CNTL_R1, 2, 7, 1),
702 SOC_SINGLE("DRC_HYSTERISIS_LEVEL", DRC_CNTL_R1, 0, 7, 0),
703
704 SOC_SINGLE("DRC_HOLD_LEVEL", DRC_CNTL_R2, 3, 0x0F, 0),
705 SOC_SINGLE("DRC_GAIN_RATE", DRC_CNTL_R2, 0, 4, 0),
706 SOC_SINGLE("DRC_ATTACK_RATE", DRC_CNTL_R3, 4, 0x0F, 1),
707 SOC_SINGLE("DRC_DECAY_RATE", DRC_CNTL_R3, 0, 0x0F, 1),
708
709 SOC_SINGLE("BEEP_GEN_EN", BEEP_CNTL_R1, 7, 1, 0),
710 SOC_DOUBLE_R("BEEP_VOL_CNTL", BEEP_CNTL_R1, BEEP_CNTL_R2, 0, 0x0F, 1),
711 SOC_SINGLE("BEEP_MAS_VOL", BEEP_CNTL_R2, 6, 3, 0),
712
713 SOC_DOUBLE_R("AGC_EN", LAGC_CNTL, RAGC_CNTL, 7, 1, 0),
714 SOC_DOUBLE_R("AGC_TARGET_LEVEL", LAGC_CNTL, RAGC_CNTL, 4, 7, 1),
715
716 SOC_DOUBLE_R("AGC_GAIN_HYSTERESIS", LAGC_CNTL, RAGC_CNTL, 0, 3, 0),
717 SOC_DOUBLE_R("AGC_HYSTERESIS", LAGC_CNTL_R2, RAGC_CNTL_R2, 6, 3, 0),
718 SOC_DOUBLE_R("AGC_NOISE_THRESHOLD", LAGC_CNTL_R2,
719 RAGC_CNTL_R2, 1, 31, 1),
720
721 SOC_DOUBLE_R("AGC_MAX_GAIN", LAGC_CNTL_R3, RAGC_CNTL_R3, 0, 116, 0),
722 SOC_DOUBLE_R("AGC_ATCK_TIME", LAGC_CNTL_R4, RAGC_CNTL_R4, 3, 31, 0),
723 SOC_DOUBLE_R("AGC_ATCK_SCALE_FACTOR",
724 LAGC_CNTL_R4, RAGC_CNTL_R4, 0, 7, 0),
725
726 SOC_DOUBLE_R("AGC_DECAY_TIME", LAGC_CNTL_R5, RAGC_CNTL_R5, 3, 31, 0),
727 SOC_DOUBLE_R("AGC_DECAY_SCALE_FACTOR",
728 LAGC_CNTL_R5, RAGC_CNTL_R5, 0, 7, 0),
729 SOC_DOUBLE_R("AGC_NOISE_DEB_TIME", LAGC_CNTL_R6,
730 RAGC_CNTL_R6, 0, 31, 0),
731
732 SOC_DOUBLE_R("AGC_SGL_DEB_TIME", LAGC_CNTL_R7,
733 RAGC_CNTL_R7, 0, 0x0F, 0),
734
735 SOC_SINGLE("DAC PRB Selection",DAC_PRB, 0, 25, 0),
736 SOC_SINGLE("HP_DEPOP", HP_DEPOP, 0, 255,0),
737 SOC_DOUBLE("IN1 LO BYPASS VOLUME" , LINE_AMP_CNTL_R2, 3, 0, 3, 1),
738 SOC_ENUM("Input CM mode", input_cm_mode),
739 SOC_ENUM("Output CM mode", output_cm_mode),
740};
741
742
743/* the sturcture contains the different values for mclk */
744static const struct aic3262_rate_divs aic3262_divs[] = {
745/*
746 * mclk, rate, p_val, pll_j, pll_d, dosr, ndac, mdac, aosr, nadc, madc, blck_N,
747 * codec_speficic_initializations
748 */
749 /* 8k rate */
750#ifdef CONFIG_MINI_DSP
751 {12000000, 8000, 1, 8, 1920, 768, 8, 2, 128, 8, 12, 4,
752 {{0, 60, 0}, {0, 61, 0} } },
753#else
754 {12000000, 8000, 1, 8, 1920, 128, 12, 8, 128, 8, 6, 4,
755 {{0, 60, 1}, {0, 61, 1} } },
756 {12288000, 8000, 1, 1, 3333, 128, 12, 8, 128, 8, 6, 4,
757 {{0, 60, 1}, {0, 61, 1} } },
758 {24000000, 8000, 1, 4, 96, 128, 12, 8, 128, 12, 8, 4,
759 {{0, 60, 1}, {0, 61, 1} } },
760#endif
761 /* 11.025k rate */
762 {12000000, 11025, 1, 1, 8816, 1024, 8, 2, 128, 8, 2, 48,
763 {{0, 60, 1}, {0, 61, 1} } },
764 {12288000, 11025, 1, 1, 8375, 1024, 8, 2, 128, 8, 2, 48,
765 {{0, 60, 1}, {0, 61, 1} } },
766 {24000000, 11025, 1, 3, 7632, 128, 8, 8, 128, 8, 8, 4,
767 {{0, 60, 1}, {0, 61, 1} } },
768
769 /* 16k rate */
770#ifdef CONFIG_MINI_DSP
771 {12000000, 16000, 1, 8, 1920, 384, 4, 4, 128, 4, 12, 12,
772 {{0, 60, 0}, {0, 61, 0} } },
773 {12288000, 16000, 1, 9, 0, 216, 2, 16, 72, 2, 48, 27,
774 {{0, 60, 0}, {0, 61, 0} } },
775#else
776 {12000000, 16000, 1, 8, 1920, 128, 8, 6, 128, 8, 6, 4,
777 {{0, 60, 1}, {0, 61, 1} } },
778 {12288000, 16000, 1, 2, 6667, 128, 8, 6, 128, 8, 6, 4,
779 {{0, 60, 1}, {0, 61, 1} } },
780 {24000000, 16000, 1, 4, 96, 128, 8, 6, 128, 8, 6, 4,
781 {{0, 60, 1}, {0, 61, 1} } },
782#endif
783 /* 22.05k rate */
784 {12000000, 22050, 1, 3, 7632, 128, 8, 2, 128, 8, 2, 4,
785 {{0, 60, 1}, {0, 61, 1} } },
786 {12288000, 22050, 1, 3, 675, 128, 8, 2, 128, 8, 2, 4,
787 {{0, 60, 1}, {0, 61, 1} } },
788 {24000000, 22050, 1, 3, 7632, 128, 8, 3, 128, 8, 3, 4,
789 {{0, 60, 1}, {0, 61, 1} } },
790 /* 32k rate */
791 {12000000, 32000, 1, 5, 4613, 128, 8, 2, 128, 8, 2, 4,
792 {{0, 60, 1}, {0, 61, 1} } },
793 {12288000, 32000, 1, 5, 3333, 128, 8, 2, 128, 8, 2, 4,
794 {{0, 60, 1}, {0, 61, 1} } },
795 {24000000, 32000, 1, 4, 96, 128, 6, 4, 128, 6, 4, 4,
796 {{0, 60, 1}, {0, 61, 1} } },
797
798#ifdef CONFIG_MINI_DSP
799 {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4,
800 {{0, 60, 0}, {0, 61, 0} } },
801 {12288000, 44100, 1, 7, 3548, 128, 2, 8, 128, 8, 2, 4,
802 {{0, 60, 0}, {0, 61, 0} } },
803#else
804 /* 44.1k rate */
805 {12000000, 44100, 1, 7, 5264, 128, 8, 2, 128, 8, 2, 4,
806 {{0, 60, 1}, {0, 61, 1} } },
807 {12288000, 44100, 1, 7, 3548, 128, 8, 2, 128, 8, 2, 4,
808 {{0, 60, 1}, {0, 61, 1} } },
809 {24000000, 44100, 1, 3, 7632, 128, 4, 4, 64, 4, 4, 4,
810 {{0, 60, 1}, {0, 61, 1} } },
811#endif
812
813#ifdef CONFIG_MINI_DSP
814 {12288000, 48000, 1, 8, 52, 128, 2, 8, 128, 2, 8, 4,
815 {{0, 60, 0}, {0, 61, 0} } },
816 {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4,
817 {{0, 60, 0}, {0, 61, 0}}},
818#else
819 /* 48k rate */
820 {12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2, 4,
821 {{0, 60, 1}, {0, 61, 1} } },
822 {12288000, 48000, 1, 8, 52, 128, 8, 2, 128, 8, 2, 4,
823 {{0, 60, 1}, {0, 61, 1} } },
824 {24000000, 48000, 1, 4, 960, 128, 4, 4, 128, 4, 4, 4,
825 {{0, 60, 1}, {0, 61, 1} } },
826#endif
827
828 /*96k rate */
829 {12000000, 96000, 1, 16, 3840, 128, 8, 2, 128, 8, 2 , 4,
830 {{0, 60, 7}, {0, 61, 7} } },
831 {24000000, 96000, 1, 4, 960, 128, 4, 2, 128, 4, 2, 2,
832 {{0, 60, 7}, {0, 61, 7} } },
833 /*192k */
834 {12000000, 192000, 1, 32, 7680, 128, 8, 2, 128, 8, 2, 4,
835 {{0, 60, 17}, {0, 61, 13} } },
836 {24000000, 192000, 1, 4, 960, 128, 2, 2, 128, 2, 2, 4,
837 {{0, 60, 17}, {0, 61, 13} } },
838};
839
840
841
842/*
843*----------------------------------------------------------------------------
844* Function : aic3262_multi_i2s_dump_regs
845* Purpose : This function is to mute or unmute the left and right DAC
846*
847*----------------------------------------------------------------------------
848*/
849static void aic3262_multi_i2s_dump_regs(struct snd_soc_dai *dai)
850{
851 struct snd_soc_codec *codec = dai->codec;
852 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
853 unsigned int counter;
854
855 DBG(KERN_INFO "#%s: Dai Active %d ASI%d REGS DUMP\n",
856 __func__, aic3262->active_count, dai->id);
857
858 aic3262_change_page(codec, 0);
859 aic3262_change_book(codec, 0);
860
861 DBG(KERN_INFO "#Page0 REGS..\n");
862 for (counter = 0; counter < 85; counter++) {
863 DBG(KERN_INFO "#%2d -> 0x%x\n", counter,
864 snd_soc_read(codec, counter));
865 }
866
867 DBG(KERN_INFO "#Page1 REGS..\n");
868 for (counter = 128; counter < 176; counter++) {
869 DBG(KERN_INFO "#%2d -> 0x%x\n", (counter % 128),
870 snd_soc_read(codec, counter));
871 }
872
873 DBG(KERN_INFO "#Page4 REGS..\n");
874 for (counter = 512; counter < 631; counter++) {
875 DBG(KERN_INFO "#%2d -> 0x%x\n",
876 (counter % 128), snd_soc_read(codec, counter));
877 }
878
879 for (counter = 0; counter < MAX_ASI_COUNT; counter++) {
880 DBG(KERN_INFO "#ASI%d Frame %s @ %dHz Playback %d Record %d\n",
881 (counter + 1),
882 (aic3262->asiCtxt[counter].master == 1) ? "Master" : "Slave",
883 aic3262->asiCtxt[counter].sampling_rate,
884 aic3262->asiCtxt[counter].playback_mode,
885 aic3262->asiCtxt[counter].capture_mode);
886 DBG(KERN_INFO "#DAC Option [%d,%d] ADC Option %d WLEN %d\n\n",
887 aic3262->asiCtxt[counter].left_dac_output,
888 aic3262->asiCtxt[counter].right_dac_output,
889 aic3262->asiCtxt[counter].adc_input,
890 aic3262->asiCtxt[counter].word_len);
891 }
892 return;
893}
894
895/*
896 *----------------------------------------------------------------------------
897 * Function : aic3262_multi_i2s_mute
898 * Purpose : This function is to mute or unmute the left and right DAC
899 *
900 *----------------------------------------------------------------------------
901 */
902static int aic3262_multi_i2s_mute(struct snd_soc_dai *dai, int mute)
903{
904 struct snd_soc_codec *codec = dai->codec;
905 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
906
907 DBG(KERN_INFO "#%s : mute entered with %d\n", __func__, mute);
908
909 /* If we are doing both Recording and Playback on this DAI interface,
910 * do not MUTE the Codec.
911 */
912 if (mute && (aic3262->asiCtxt[dai->id - 1].asi_active > 1)) {
913 DBG("#%s Cannot Mute the ASI%d Now..\n",
914 __func__, dai->id);
915 } else {
916 switch (dai->id) {
917 case 1:
918 aic3262_multi_i2s_asi1_mute(dai, mute);
919 break;
920 case 2:
921 aic3262_multi_i2s_asi2_mute(dai, mute);
922 break;
923 case 3:
924 aic3262_multi_i2s_asi3_mute(dai, mute);
925 break;
926 default:
927 printk(KERN_ERR "#%s: Invalid DAI id\n", __func__);
928 return -EINVAL;
929 }
930 }
931 DBG(KERN_INFO "#%s : mute ended\n", __func__);
932 return 0;
933}
934
935
936/*
937*----------------------------------------------------------------------------
938* Function : aic3262_multi_i2s_asi1_mute
939* Purpose : This function is to mute or unmute the left and right DAC
940*
941*----------------------------------------------------------------------------
942*/
943static int aic3262_multi_i2s_asi1_mute(struct snd_soc_dai *dai, int mute)
944{
945 struct snd_soc_codec *codec = dai->codec;
946 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
947
948 DBG(KERN_INFO "#%s : mute %d started\n", __func__, mute);
949
950 if (mute && !aic3262->asiCtxt[0].port_muted ) {
951 DBG(KERN_INFO "Mute if part\n");
952
953
954 snd_soc_update_bits(codec, DAC_MVOL_CONF, DAC_LR_MUTE_MASK,DAC_LR_MUTE);
955
956 /* First check if both Playback and Recording is going on
957 * this interface.
958 */
959 if (aic3262->asiCtxt[0].asi_active > 1) {
960 DBG("#%s Cannot Mute the ASI Now..\n", __func__);
961 } else if (!(aic3262->asiCtxt[1].playback_mode) &&
962 !(aic3262->asiCtxt[2].playback_mode)) {
963 /* Before Muting, please check if any other
964 * ASI is active. if so, we cannot simply mute the
965 * DAC and ADC Registers.
966 */
967 DBG("#%s None of the ASI's are active now..\n", __func__);
968 snd_soc_write(codec, DAC_MVOL_CONF,
969 ((aic3262->dac_reg & 0xF3) | 0x0C));
970 snd_soc_write(codec, ADC_FINE_GAIN,
971 ((aic3262->adc_gain & 0x77) | 0x88));
972 snd_soc_write(codec, HPL_VOL, 0xB9);
973 snd_soc_write(codec, HPR_VOL, 0xB9);
974 snd_soc_write(codec, REC_AMP_CNTL_R5, 0x39);
975 snd_soc_write(codec, RAMPR_VOL, 0x39);
976 snd_soc_write(codec, SPK_AMP_CNTL_R4, 0x00);
977 aic3262->asiCtxt[0].port_muted = 1;
978 }
979 } else {
980 DBG(KERN_INFO "Mute else part\n");
981 snd_soc_update_bits(codec, DAC_MVOL_CONF,
982 DAC_LR_MUTE_MASK, 0x0);
983 snd_soc_write(codec, ADC_FINE_GAIN,(0X00 & 0x77) | 0x0);
984 aic3262_multi_i2s_dump_regs(dai);
985 }
986
987 DBG(KERN_INFO "#%s : mute %d ended\n", __func__, mute);
988
989 return 0;
990}
991
992/*
993*----------------------------------------------------------------------------
994* Function : aic3262_multi_i2s_asi2_maic3262_asi3_clk_configute
995* Purpose : This function is to mute or unmute the left and right DAC
996*
997*----------------------------------------------------------------------------
998*/
999static int aic3262_multi_i2s_asi2_mute(struct snd_soc_dai *dai, int mute)
1000{
1001 struct snd_soc_codec *codec = dai->codec;
1002 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1003
1004 DBG(KERN_INFO "#%s : mute %d started\n", __func__, mute);
1005
1006 if (mute && !aic3262->asiCtxt[1].port_muted ) {
1007 DBG(KERN_INFO "Mute if part\n");
1008 snd_soc_update_bits(codec, DAC_MVOL_CONF, DAC_LR_MUTE_MASK,DAC_LR_MUTE);
1009
1010 /* First check if both Playback and Recording is going on
1011 * this interface.
1012 */
1013 if (aic3262->asiCtxt[1].asi_active > 1) {
1014 DBG("#%s Cannot Mute the ASI Now..\n", __func__);
1015 } else if (!(aic3262->asiCtxt[0].playback_mode) &&
1016 !(aic3262->asiCtxt[2].playback_mode)) {
1017 /* Before Muting, please check if any other
1018 * ASI is active. if so, we cannot simply mute the
1019 * DAC and ADC Registers.
1020 */
1021 snd_soc_write(codec, DAC_MVOL_CONF,
1022 ((aic3262->dac_reg & 0xF3) | 0x0C));
1023 snd_soc_write(codec, ADC_FINE_GAIN,
1024 ((aic3262->adc_gain & 0x77) | 0x88));
1025 snd_soc_write(codec, HPL_VOL, 0xB9);
1026 snd_soc_write(codec, HPR_VOL, 0xB9);
1027 snd_soc_write(codec, REC_AMP_CNTL_R5, 0x39);
1028 snd_soc_write(codec, RAMPR_VOL, 0x39);
1029 snd_soc_write(codec, SPK_AMP_CNTL_R4, 0x00);
1030 aic3262->asiCtxt[1].port_muted = 1;
1031 }
1032 } else {
1033 DBG(KERN_INFO "Mute else part\n");
1034 snd_soc_update_bits(codec, DAC_MVOL_CONF,
1035 DAC_LR_MUTE_MASK, 0x0);
1036
1037 /*aic3262_multi_i2s_dump_regs(dai);*/
1038 }
1039
1040 DBG(KERN_INFO "#%s : mute %d ended\n", __func__, mute);
1041
1042 return 0;
1043}
1044
1045/*
1046*----------------------------------------------------------------------------
1047* Function : aic3262_multi_i2s_asi3_mute
1048* Purpose : This function is to mute or unmute the left and right DAC
1049*
1050*----------------------------------------------------------------------------
1051*/
1052static int aic3262_multi_i2s_asi3_mute(struct snd_soc_dai *dai, int mute)
1053{
1054 struct snd_soc_codec *codec = dai->codec;
1055 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1056
1057 DBG(KERN_INFO "#%s : mute %d started\n", __func__, mute);
1058
1059 if (mute && !aic3262->asiCtxt[2].port_muted) {
1060 DBG("Mute if part\n");
1061 snd_soc_update_bits(codec, DAC_MVOL_CONF, DAC_LR_MUTE_MASK,DAC_LR_MUTE);
1062
1063 /* First check if both Playback and Recording is going on
1064 * this interface.
1065 */
1066 if (aic3262->asiCtxt[2].asi_active > 1) {
1067 DBG("#%s Cannot Mute the ASI Now..\n", __func__);
1068 } else if (!(aic3262->asiCtxt[0].playback_mode) &&
1069 !(aic3262->asiCtxt[1].playback_mode)) {
1070 /* Before Muting, please check if any other
1071 * ASI is active. if so, we cannot simply mute the
1072 * DAC and ADC Registers.
1073 */
1074 snd_soc_write(codec, DAC_MVOL_CONF,
1075 ((aic3262->dac_reg & 0xF3) | 0x0C));
1076 snd_soc_write(codec, ADC_FINE_GAIN,
1077 ((aic3262->adc_gain & 0x77) | 0x88));
1078 snd_soc_write(codec, HPL_VOL, 0xB9);
1079 snd_soc_write(codec, HPR_VOL, 0xB9);
1080 snd_soc_write(codec, REC_AMP_CNTL_R5, 0x39);
1081 snd_soc_write(codec, RAMPR_VOL, 0x39);
1082 snd_soc_write(codec, SPK_AMP_CNTL_R4, 0x00);
1083 aic3262->asiCtxt[2].port_muted = 1;
1084 }
1085 } else {
1086 DBG("Mute else part\n");
1087 snd_soc_update_bits(codec, DAC_MVOL_CONF,
1088 DAC_LR_MUTE_MASK, 0x0);
1089
1090 /*aic3262_multi_i2s_dump_regs(dai);*/
1091
1092 }
1093
1094 DBG(KERN_INFO "#%s : mute %d ended\n", __func__, mute);
1095
1096 return 0;
1097}
1098
1099/*
1100 *----------------------------------------------------------------------------
1101 * Function : aic3262_multi_i2s_set_dai_fmt
1102 * Purpose : This function is to set the DAI format
1103 *
1104 *----------------------------------------------------------------------------
1105 */
1106static int aic3262_multi_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1107 unsigned int fmt)
1108{
1109 /* Check the DAI Id and based on that switch the configuration for
1110 * the Individual ASI Port.
1111 */
1112 switch (codec_dai->id) {
1113 case 1:
1114 aic3262_multi_i2s_asi1_set_dai_fmt(codec_dai, fmt);
1115 break;
1116 case 2:
1117 aic3262_multi_i2s_asi2_set_dai_fmt(codec_dai, fmt);
1118 break;
1119 case 3:
1120 aic3262_multi_i2s_asi3_set_dai_fmt(codec_dai, fmt);
1121 break;
1122 default:
1123 printk(KERN_ERR
1124 "#%s: Invalid DAI interface format\n", __func__);
1125 return -EINVAL;
1126 }
1127 return 0;
1128}
1129
1130
1131
1132/*
1133*----------------------------------------------------------------------------
1134* Function : aic3262_multi_i2s_asi1_set_dai_fmt
1135* Purpose : This function is to set the DAI format for ASI1 Port
1136*
1137*----------------------------------------------------------------------------
1138*/
1139static int aic3262_multi_i2s_asi1_set_dai_fmt(struct snd_soc_dai *codec_dai,
1140 unsigned int fmt)
1141{
1142 struct snd_soc_codec *codec = codec_dai->codec;
1143 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1144 u8 iface_reg, clk_reg;
1145 u8 regvalue;
1146
1147 DBG(KERN_INFO "%s: DAI_ID %d fmt %d\n",
1148 __func__, codec_dai->id, fmt);
1149
1150 /* Read the B0_P4_R4 and B0_P4_R10 Registers to configure the
1151 * ASI1 Bus and Clock Formats depending on the PCM Format.
1152 */
1153 iface_reg = snd_soc_read(codec, ASI1_BUS_FMT);
1154 clk_reg = snd_soc_read(codec, ASI1_BWCLK_CNTL_REG);
1155
1156 /* set master/slave audio interface */
1157 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1158 case SND_SOC_DAIFMT_CBM_CFM:
1159 DBG(KERN_INFO "#%s: Configuring ASI%d as Frame Master..\n",
1160 __func__, codec_dai->id);
1161 aic3262->asiCtxt[0].master = 1;
1162 clk_reg |= (BIT5 | BIT2); /* Codec Interface as Master */
1163 break;
1164 case SND_SOC_DAIFMT_CBS_CFS:
1165 DBG(KERN_INFO "#%s: Configuring ASI%d as Frame Slave..\n",
1166 __func__, codec_dai->id);
1167 clk_reg &= ~0xFC; /* Reset bits D[7:5] and D[4:2] to zero */
1168 aic3262->asiCtxt[0].master = 0;
1169 break;
1170 case SND_SOC_DAIFMT_CBS_CFM:
1171 /* new case..just for debugging */
1172 DBG(KERN_INFO "%s: SND_SOC_DAIFMT_CBS_CFM\n", __func__);
1173 aic3262->asiCtxt[0].master = 0;
1174 clk_reg |= BIT5; /* Only WCLK1 Output from Codec */
1175 clk_reg &= ~0x1C; /* BCLK1 Input to Codec */
1176 break;
1177 default:
1178 printk(KERN_ERR "#%s: Invalid DAI master/slave interface\n",
1179 __func__);
1180 return -EINVAL;
1181 }
1182 aic3262->asiCtxt[0].pcm_format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1183 /* interface format */
1184 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1185 case SND_SOC_DAIFMT_I2S:
1186 DBG(KERN_INFO "#%s: Configuring ASI%d for I2s Mode..\n",
1187 __func__, codec_dai->id);
1188 iface_reg = (iface_reg & 0x1f);
1189 break;
1190 case SND_SOC_DAIFMT_DSP_A:
1191 DBG(KERN_INFO "#%s: Configuring ASI%d for DSP_A Mode..\n",
1192 __func__, codec_dai->id);
1193 iface_reg = (iface_reg & 0x1f) | 0x20;
1194 break;
1195 case SND_SOC_DAIFMT_RIGHT_J:
1196 iface_reg = (iface_reg & 0x1f) | 0x40;
1197 break;
1198 case SND_SOC_DAIFMT_LEFT_J:
1199 iface_reg = (iface_reg & 0x1f) | 0x60;
1200 break;
1201 case SND_SOC_DAIFMT_DSP_B:
1202 DBG(KERN_INFO "#%s: Configuring ASI%d for DSP_B Mode..\n",
1203 __func__, codec_dai->id);
1204 iface_reg = (iface_reg & 0x1f) | 0x80;
1205 /* voice call need data offset in 1 bitclock */
1206 snd_soc_write(codec, ASI1_LCH_OFFSET, 1);
1207 break;
1208 default:
1209 printk(KERN_ERR
1210 "#%s: Invalid DAI interface format\n", __func__);
1211 return -EINVAL;
1212 }
1213 /* Also Configure the Pin Control Registers before writing into
1214 * the ASI specific Clock Control and Format Registers
1215 */
1216
1217 /* Configure B0_P4_R65_D[5:2] to 001 This configures the
1218 * WCLK1 Pin to ASI1
1219 */
1220 regvalue = snd_soc_read(codec, WCLK1_PIN_CNTL_REG);
1221 snd_soc_write(codec, WCLK1_PIN_CNTL_REG, (regvalue | BIT2));
1222
1223 /* Configure B0_P4_R68_d[6:5] = 01 and B0_P4_R67_D[4:1] to 0001
1224 * to ensure that the DIN1 and DOUT1 Pins are configured
1225 * correctly
1226 */
1227 regvalue = snd_soc_read(codec, DIN1_PIN_CNTL_REG);
1228 snd_soc_write(codec, DIN1_PIN_CNTL_REG, (regvalue | BIT5));
1229 regvalue = snd_soc_read(codec, DOUT1_PIN_CNTL_REG);
1230 snd_soc_write(codec, DOUT1_PIN_CNTL_REG, (regvalue | BIT1));
1231
1232 snd_soc_write(codec, ASI1_BWCLK_CNTL_REG, clk_reg);
1233
1234 snd_soc_write(codec, ASI1_BUS_FMT, iface_reg);
1235
1236 return 0;
1237}
1238
1239
1240/*
1241*----------------------------------------------------------------------------
1242* Function : aic3262_multi_i2s_asi2_set_dai_fmt
1243* Purpose : This function is to set the DAI format for ASI2 Port
1244*
1245*----------------------------------------------------------------------------
1246*/
1247static int aic3262_multi_i2s_asi2_set_dai_fmt(struct snd_soc_dai *codec_dai,
1248 unsigned int fmt)
1249{
1250 struct snd_soc_codec *codec = codec_dai->codec;
1251 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1252 u8 iface_reg, clk_reg;
1253 u8 regvalue;
1254
1255 DBG(KERN_INFO "%s: DAI_ID %d fmt %d\n",
1256 __func__, codec_dai->id, fmt);
1257
1258 /* Read the B0_P4_R17 and B0_P4_R26 Registers to configure the
1259 * ASI1 Bus and Clock Formats depending on the PCM Format.
1260 */
1261 iface_reg = snd_soc_read(codec, ASI2_BUS_FMT);
1262 clk_reg = snd_soc_read(codec, ASI2_BWCLK_CNTL_REG);
1263
1264 /* set master/slave audio interface */
1265 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1266 case SND_SOC_DAIFMT_CBM_CFM:
1267 DBG(KERN_INFO "#%s: Configuring ASI%d as Frame Master..\n",
1268 __func__, codec_dai->id);
1269 aic3262->asiCtxt[1].master = 1;
1270 clk_reg |= (BIT5 | BIT2);
1271 break;
1272 case SND_SOC_DAIFMT_CBS_CFS:
1273 DBG(KERN_INFO "#%s: Configuring ASI%d as Frame Slave..\n",
1274 __func__, codec_dai->id);
1275
1276 clk_reg &= ~0xFC;
1277 aic3262->asiCtxt[1].master = 0;
1278 break;
1279 case SND_SOC_DAIFMT_CBS_CFM:
1280 /*new case..just for debugging */
1281 DBG(KERN_INFO "%s: SND_SOC_DAIFMT_CBS_CFM\n", __func__);
1282 aic3262->asiCtxt[1].master = 0;
1283 clk_reg |= BIT5;
1284 clk_reg &= ~0x1C;
1285 break;
1286 default:
1287 printk(KERN_ERR "#%s:Invalid DAI master/slave interface\n",
1288 __func__);
1289 return -EINVAL;
1290 }
1291 aic3262->asiCtxt[1].pcm_format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1292 /* interface format */
1293 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1294 case SND_SOC_DAIFMT_I2S:
1295 DBG(KERN_INFO "#%s: Configuring ASI%d for I2S Mode..\n",
1296 __func__, codec_dai->id);
1297 iface_reg = (iface_reg & 0x1f);
1298 break;
1299 case SND_SOC_DAIFMT_DSP_A:
1300 DBG(KERN_INFO "#%s: Configuring ASI%d for DSP_A Mode..\n",
1301 __func__, codec_dai->id);
1302 iface_reg = (iface_reg & 0x1f) | 0x20;
1303 break;
1304 case SND_SOC_DAIFMT_RIGHT_J:
1305 iface_reg = (iface_reg & 0x1f) | 0x40;
1306 break;
1307 case SND_SOC_DAIFMT_LEFT_J:
1308 iface_reg = (iface_reg & 0x1f) | 0x60;
1309 break;
1310 case SND_SOC_DAIFMT_DSP_B:
1311 DBG(KERN_INFO "#%s: Configuring ASI%d for DSP Mode..\n",
1312 __func__, codec_dai->id);
1313 iface_reg = (iface_reg & 0x1f) | 0x80;
1314 /* voice call need data offset in 1 bitclock */
1315 snd_soc_write(codec, ASI2_LCH_OFFSET, 1);
1316 break;
1317 default:
1318 printk(KERN_ERR "#%s:Invalid DAI interface format\n", __func__);
1319 return -EINVAL;
1320 }
1321
1322 /* Also Configure the Pin Control Registers before writing into
1323 * the ASI2 specific Clock Control and Format Registers
1324 */
1325
1326 /* Configure B0_P4_R69_D[5:2] to 001 This configures the
1327 * WCLK2 Pin to ASI2
1328 */
1329
1330 regvalue = snd_soc_read(codec, WCLK2_PIN_CNTL_REG);
1331 snd_soc_write(codec, WCLK2_PIN_CNTL_REG, (regvalue | BIT2));
1332
1333 regvalue = snd_soc_read(codec, BCLK2_PIN_CNTL_REG);
1334 snd_soc_write(codec, BCLK2_PIN_CNTL_REG, (regvalue | BIT2));
1335
1336 /* Configure B0_P4_R72_d[6:5] = 01 and B0_P4_R71_D[4:1] to 0001
1337 * to ensure that the DIN2 and DOUT2 Pins are configured
1338 * correctly
1339 */
1340 regvalue = snd_soc_read(codec, DIN2_PIN_CNTL_REG);
1341 snd_soc_write(codec, DIN2_PIN_CNTL_REG, (regvalue | BIT5));
1342
1343 regvalue = snd_soc_read(codec, DOUT2_PIN_CNTL_REG);
1344 snd_soc_write(codec, DOUT2_PIN_CNTL_REG, (regvalue | BIT5 | BIT1));
1345
1346 snd_soc_write(codec, ASI2_BWCLK_CNTL_REG, clk_reg);
1347
1348 snd_soc_write(codec, ASI2_BUS_FMT, iface_reg);
1349
1350 return 0;
1351}
1352
1353/*
1354*----------------------------------------------------------------------------
1355* Function : aic3262_multi_i2s_asi3_set_dai_fmt
1356* Purpose : This function is to set the DAI format for ASI3 Port
1357*
1358*----------------------------------------------------------------------------
1359*/
1360static int aic3262_multi_i2s_asi3_set_dai_fmt(struct snd_soc_dai *codec_dai,
1361 unsigned int fmt)
1362{
1363 struct snd_soc_codec *codec = codec_dai->codec;
1364 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1365 u8 iface_reg, clk_reg;
1366 u8 regvalue;
1367
1368 DBG(KERN_INFO "%s: DAI_ID %d fmt %d\n",
1369 __func__, codec_dai->id, fmt);
1370
1371 /* Read the B0_P4_R33 and B0_P4_R42 Registers to configure the
1372 * ASI1 Bus and Clock Formats depending on the PCM Format.
1373 */
1374 iface_reg = snd_soc_read(codec, ASI3_BUS_FMT);
1375 clk_reg = snd_soc_read(codec, ASI3_BWCLK_CNTL_REG);
1376
1377 /* set master/slave audio interface */
1378 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1379 case SND_SOC_DAIFMT_CBM_CFM:
1380 DBG(KERN_INFO "#%s: Configuring ASI%d as Frame Master..\n",
1381 __func__, codec_dai->id);
1382 aic3262->asiCtxt[2].master = 1;
1383 clk_reg |= (BIT5 | BIT2);
1384 break;
1385 case SND_SOC_DAIFMT_CBS_CFS:
1386 DBG(KERN_INFO "#%s: Configuring ASI%d as Frame Slave..\n",
1387 __func__, codec_dai->id);
1388 clk_reg &= ~0xFC;
1389 aic3262->asiCtxt[2].master = 0;
1390 break;
1391 case SND_SOC_DAIFMT_CBS_CFM:
1392 /* new case..just for debugging */
1393 DBG(KERN_INFO "%s: SND_SOC_DAIFMT_CBS_CFM\n", __func__);
1394 aic3262->asiCtxt[2].master = 0;
1395 clk_reg |= BIT5;
1396 clk_reg &= ~0x1C;
1397 break;
1398 default:
1399 printk(KERN_ERR "Invalid DAI master/slave interface\n");
1400 return -EINVAL;
1401 }
1402 aic3262->asiCtxt[2].pcm_format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1403 /* interface format */
1404 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1405 case SND_SOC_DAIFMT_I2S:
1406 DBG(KERN_INFO "#%s: Configuring ASI%d for I2S Mode..\n",
1407 __func__, codec_dai->id);
1408 iface_reg = (iface_reg & 0x1f);
1409 break;
1410 case SND_SOC_DAIFMT_DSP_A:
1411 DBG(KERN_INFO "#%s: Configuring ASI%d for DSP_A Mode..\n",
1412 __func__, codec_dai->id);
1413 iface_reg = (iface_reg & 0x1f) | 0x20;
1414 break;
1415 case SND_SOC_DAIFMT_RIGHT_J:
1416 iface_reg = (iface_reg & 0x1f) | 0x40;
1417 break;
1418 case SND_SOC_DAIFMT_LEFT_J:
1419 iface_reg = (iface_reg & 0x1f) | 0x60;
1420 break;
1421 case SND_SOC_DAIFMT_DSP_B:
1422 DBG(KERN_INFO "#%s: Configuring ASI%d for DSP Mode..\n",
1423 __func__, codec_dai->id);
1424 iface_reg = (iface_reg & 0x1f) | 0x80;
1425 /* voice call need data offset in 1 bitclock */
1426 snd_soc_write(codec, ASI3_LCH_OFFSET, 1);
1427 break;
1428 default:
1429 printk(KERN_ERR
1430 "#%s: Invalid DAI interface format\n", __func__);
1431 return -EINVAL;
1432 }
1433
1434 /* Also Configure the Pin Control Registers before writing into
1435 * the ASI specific Clock Control and Format Registers
1436 */
1437 /* Configure B0_P4_R73_D[5:2] to 0001 This configures the
1438 * WCLK1 Pin to ASI1
1439 */
1440 regvalue = snd_soc_read(codec, WCLK3_PIN_CNTL_REG);
1441 snd_soc_write(codec, WCLK3_PIN_CNTL_REG, (regvalue | BIT2));
1442
1443 regvalue = snd_soc_read(codec, BCLK3_PIN_CNTL_REG);
1444 snd_soc_write(codec, BCLK3_PIN_CNTL_REG, (regvalue | BIT2));
1445
1446 /* Configure B0_P4_R76_d[6:5] = 01 and B0_P4_R75_D[4:1] to 0001
1447 * to ensure that the DIN1 and DOUT1 Pins are configured
1448 * correctly
1449 */
1450 regvalue = snd_soc_read(codec, DIN3_PIN_CNTL_REG);
1451 snd_soc_write(codec, DIN3_PIN_CNTL_REG, (regvalue | BIT5));
1452 regvalue = snd_soc_read(codec, DOUT3_PIN_CNTL_REG);
1453 snd_soc_write(codec, DOUT3_PIN_CNTL_REG, (regvalue | BIT1));
1454
1455 snd_soc_write(codec, ASI3_BWCLK_CNTL_REG, clk_reg);
1456
1457 snd_soc_write(codec, ASI3_BUS_FMT, iface_reg);
1458
1459 return 0;
1460}
1461
1462/*
1463 * Clock after PLL and dividers
1464 */
1465static int aic3262_multi_i2s_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1466 int clk_id, unsigned int freq, int dir)
1467{
1468 struct snd_soc_codec *codec = codec_dai->codec;
1469 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1470
1471 DBG(KERN_INFO "#%s: DAI ID %d Freq %d Direction %d\n",
1472 __func__, codec_dai->id, freq, dir);
1473 switch (freq) {
1474 case AIC3262_FREQ_12000000:
1475 case AIC3262_FREQ_12288000:
1476 case AIC3262_FREQ_24000000:
1477 aic3262->sysclk = freq;
1478 return 0;
1479 break;
1480 }
1481 printk(KERN_ERR "Invalid frequency to set DAI system clock\n");
1482 return -EINVAL;
1483}
1484
1485/*
1486* aic3262_multi_i2s_set_pll
1487*
1488* This function is invoked as part of the PLL call-back
1489* handler from the ALSA layer.
1490*/
1491static int aic3262_multi_i2s_set_dai_pll(struct snd_soc_dai *codec_dai,
1492 int pll_id, int source, unsigned int freq_in,
1493 unsigned int freq_out)
1494{
1495
1496 printk(KERN_INFO "%s: DAI ID %d PLL_ID %d InFreq %d OutFreq %d\n",
1497 __func__, pll_id, codec_dai->id, freq_in, freq_out);
1498
1499 return 0;
1500}
1501
1502/*
1503* aic3262_asi1_clk_config
1504*
1505* This function is used to configure the BCLK1, WCLK1 pins which
1506* are specific to ASI1 Interface. This function just enables the
1507* BCLk and WCLK along with the miniDSP Port Control Registers.
1508* However, depending on the user requirement, this function can also be
1509* extended to configure the sourc for the BCLK and WCLK on a ASI basis.
1510*/
1511static int aic3262_asi1_clk_config(struct snd_soc_codec *codec,
1512 struct snd_pcm_hw_params *params)
1513{
1514 u8 bclk_N_value, wclk_N_value;
1515 u8 minidspD_data, minidspA_data;
1516 u8 regval;
1517
1518 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1519
1520 DBG(KERN_INFO "%s: Invoked\n", __func__);
1521
1522 /* Configure the BCLK and WCLK Output Mux Options */
1523 regval = snd_soc_read(codec, ASI1_BWCLK_OUT_CNTL);
1524 regval &= ~(AIC3262_ASI_BCLK_MUX_MASK | AIC3262_ASI_WCLK_MUX_MASK);
1525
1526 regval |= (aic3262->asiCtxt[0].bclk_output <<
1527 AIC3262_ASI_BCLK_MUX_SHIFT);
1528 regval |= aic3262->asiCtxt[0].wclk_output;
1529 snd_soc_write(codec, ASI1_BWCLK_OUT_CNTL, regval);
1530
1531 /* Configure the corresponding miniDSP Data Ports */
1532 minidspD_data = snd_soc_read(codec, MINIDSP_PORT_CNTL_REG);
1533 minidspD_data &= ~(BIT5 | BIT4);
1534 snd_soc_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
1535
1536 minidspA_data = snd_soc_read(codec, ASI1_ADC_INPUT_CNTL);
1537 minidspA_data &= ~(BIT2 | BIT1 | BIT0);
1538 minidspA_data |= aic3262->asiCtxt[0].adc_input;
1539 snd_soc_write(codec, ASI1_ADC_INPUT_CNTL, minidspA_data);
1540
1541
1542 if (aic3262->asiCtxt[0].master == 1) {
1543 DBG(KERN_INFO
1544 "#%s: Codec Master on ASI1 Port. Enabling BCLK WCLK Divider.\n",
1545 __func__);
1546 bclk_N_value = aic3262->asiCtxt[0].bclk_div;
1547 snd_soc_write(codec, ASI1_BCLK_N, (bclk_N_value | 0x80));
1548
1549 wclk_N_value = snd_soc_read(codec, ASI1_WCLK_N);
1550 snd_soc_write(codec, ASI1_WCLK_N, (wclk_N_value | 0xA0));
1551 }
1552 return 0;
1553
1554}
1555
1556/*
1557* aic3262_asi2_clk_config
1558*
1559* This function is used to configure the BCLK2, WCLK2 pins which
1560* are specific to ASI2 Interface. This function just enables the
1561* BCLk and WCLK along with the miniDSP Port Control Registers.
1562* However, depending on the user requirement, this function can also be
1563* extended to configure the sourc for the BCLK and WCLK on a ASI basis.
1564*/
1565static int aic3262_asi2_clk_config(struct snd_soc_codec *codec,
1566 struct snd_pcm_hw_params *params)
1567{
1568 u8 bclk_N_value, wclk_N_value, minidspD_data, minidspA_data;
1569 u8 regval;
1570
1571 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1572
1573 DBG(KERN_INFO "%s: Invoked\n", __func__);
1574
1575
1576 /* Configure the BCLK and WCLK Output Mux Options */
1577 regval = snd_soc_read(codec, ASI2_BWCLK_OUT_CNTL);
1578 regval &= ~(AIC3262_ASI_BCLK_MUX_MASK | AIC3262_ASI_WCLK_MUX_MASK);
1579 regval |= (aic3262->asiCtxt[1].bclk_output <<
1580 AIC3262_ASI_BCLK_MUX_SHIFT);
1581 regval |= aic3262->asiCtxt[1].wclk_output;
1582
1583 snd_soc_write(codec, ASI2_BWCLK_OUT_CNTL, regval);
1584 /* Configure the corresponding miniDSP Data Ports */
1585 minidspD_data = snd_soc_read(codec, MINIDSP_PORT_CNTL_REG);
1586 minidspD_data |= (BIT2);
1587 snd_soc_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
1588
1589 minidspA_data = snd_soc_read(codec, ASI2_ADC_INPUT_CNTL);
1590 minidspA_data &= ~(BIT2 | BIT1 | BIT0);
1591 minidspA_data |= aic3262->asiCtxt[1].adc_input;
1592 snd_soc_write(codec, ASI2_ADC_INPUT_CNTL, minidspA_data);
1593
1594 /* NO Manual configuration of WCLK and BCLK for Master Mode.
1595 * DAPM Handles all the required modifications.
1596 */
1597 if (aic3262->asiCtxt[1].master == 1) {
1598 DBG(KERN_INFO
1599 "#%s: Codec Master on ASI2 Port. Enabling BCLK WCLK Divider.\n",
1600 __func__);
1601 bclk_N_value = aic3262->asiCtxt[1].bclk_div;
1602 snd_soc_write(codec, ASI2_BCLK_N, (bclk_N_value | 0x80));
1603
1604 wclk_N_value = snd_soc_read(codec, ASI2_WCLK_N);
1605 snd_soc_write(codec, ASI2_WCLK_N, (wclk_N_value | 0xA0));
1606 }
1607
1608 return 0;
1609
1610}
1611
1612/*
1613* aic3262_asi3_clk_config
1614*
1615* This function is used to configure the BCLK3, WCLK3 pins which
1616* are specific to ASI3 Interface. This function just enables the
1617* BCLk and WCLK along with the miniDSP Port Control Registers.
1618* However, depending on the user requirement, this function can also be
1619* extended to configure the sourc for the BCLK and WCLK on a ASI basis.
1620*/
1621static int aic3262_asi3_clk_config(struct snd_soc_codec *codec,
1622 struct snd_pcm_hw_params *params)
1623{
1624 u8 bclk_N_value, wclk_N_value, minidspD_data, minidspA_data;
1625 u8 regval;
1626
1627 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1628
1629 DBG(KERN_INFO "%s:\n", __func__);
1630
1631
1632 /* Configure the BCLK and WCLK Output Mux Options */
1633 regval = snd_soc_read(codec, ASI3_BWCLK_OUT_CNTL);
1634 regval &= ~(AIC3262_ASI_BCLK_MUX_MASK | AIC3262_ASI_WCLK_MUX_MASK);
1635 regval |= (aic3262->asiCtxt[2].bclk_output <<
1636 AIC3262_ASI_BCLK_MUX_SHIFT);
1637 regval |= aic3262->asiCtxt[2].wclk_output;
1638 snd_soc_write(codec, ASI3_BWCLK_OUT_CNTL, regval);
1639
1640 minidspD_data = snd_soc_read(codec, MINIDSP_PORT_CNTL_REG);
1641 minidspD_data |= (BIT1);
1642 snd_soc_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
1643
1644 minidspA_data = snd_soc_read(codec, ASI3_ADC_INPUT_CNTL);
1645 minidspA_data &= ~(BIT2 | BIT1 | BIT0);
1646 minidspA_data |= aic3262->asiCtxt[2].adc_input;
1647 snd_soc_write(codec, ASI3_ADC_INPUT_CNTL, minidspA_data);
1648
1649 if (aic3262->asiCtxt[2].master == 1) {
1650 DBG(KERN_INFO
1651 "#%s: Codec Master on ASI3 Port. Enabling BCLK WCLK Divider.\n",
1652 __func__);
1653 bclk_N_value = aic3262->asiCtxt[2].bclk_div;
1654 snd_soc_write(codec, ASI2_BCLK_N, (bclk_N_value | 0x80));
1655
1656 wclk_N_value = snd_soc_read(codec, ASI3_WCLK_N);
1657 snd_soc_write(codec, ASI3_WCLK_N, (wclk_N_value | 0xA0));
1658 }
1659 return 0;
1660
1661}
1662
1663/*
1664* aic3262_multi_i2s_hw_params
1665*
1666* This function is used to configure the individual ASI port registers
1667* depending on the configuration passed on by the snd_pcm_hw_params
1668* structure.
1669* This function internally configures the ASI specific pins and clock
1670* Control Registers.
1671*/
1672static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
1673 struct snd_pcm_hw_params *params,
1674 struct snd_soc_dai *dai)
1675{
1676 int i, j;
1677 u8 data;
1678 u16 regoffset = 0;
1679 u8 dacpath = 0;
1680 u8 adcpath = 0;
1681 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1682 struct snd_soc_codec *codec = rtd->codec;
1683 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1684
1685 DBG(KERN_INFO "#%s: Invoked for ASI%d Port for %s Mode\n",
1686 __func__, dai->id,
1687 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1688 ? "Playback" : "Record");
1689
1690 i = aic3262_get_divs(aic3262->sysclk, params_rate(params));
1691
1692 i2c_verify_book0(codec);
1693
1694 if (i < 0) {
1695 printk(KERN_ERR "#%s: Sampling rate %d not supported\n",
1696 __func__, params_rate(params));
1697 return i;
1698 }
1699
1700 aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1701
1702 /* Configure the PLL J, R D values only if none of the ASI
1703 * Interfaces are Active.
1704 */
1705
1706 if (1) {
1707 DBG(KERN_INFO "#%s: None of the ASIs active yet...\n",
1708 __func__);
1709 /*We will fix R value to 1 and make P & J=K.D as variable */
1710 /* Setting P & R values are set to 1 and 1 at init*/
1711
1712 /* J value */
1713 snd_soc_write(codec, PLL_J_REG, aic3262_divs[i].pll_j);
1714
1715 /* MSB & LSB for D value */
1716
1717 snd_soc_write(codec, PLL_D_MSB, (aic3262_divs[i].pll_d >> 8));
1718 snd_soc_write(codec, PLL_D_LSB,
1719 (aic3262_divs[i].pll_d & AIC3262_8BITS_MASK));
1720
1721 /* NDAC divider value */
1722 data = snd_soc_read(codec, NDAC_DIV_POW_REG);
1723 DBG(KERN_INFO "# reading NDAC = %d , NDAC_DIV_POW_REG = %x\n",
1724 aic3262_divs[i].ndac, data);
1725 snd_soc_write(codec, NDAC_DIV_POW_REG,
1726 ((data & 0x80)|(aic3262_divs[i].ndac)));
1727 DBG(KERN_INFO "# writing NDAC = %d , NDAC_DIV_POW_REG = %x\n",
1728 aic3262_divs[i].ndac,
1729 ((data & 0x80)|(aic3262_divs[i].ndac)));
1730
1731 /* MDAC divider value */
1732 data = snd_soc_read(codec, MDAC_DIV_POW_REG);
1733 DBG(KERN_INFO "# reading MDAC = %d , MDAC_DIV_POW_REG = %x\n",
1734 aic3262_divs[i].mdac, data);
1735 snd_soc_write(codec, MDAC_DIV_POW_REG,
1736 ((data & 0x80)|(aic3262_divs[i].mdac)));
1737 DBG(KERN_INFO "# writing MDAC = %d , MDAC_DIV_POW_REG = %x\n",
1738 aic3262_divs[i].mdac, ((data & 0x80)|(aic3262_divs[i].mdac)));
1739
1740 /* DOSR MSB & LSB values */
1741 snd_soc_write(codec, DOSR_MSB_REG, aic3262_divs[i].dosr >> 8);
1742 DBG(KERN_INFO "# writing DOSR_MSB_REG = %d\n",
1743 (aic3262_divs[i].dosr >> 8));
1744 snd_soc_write(codec, DOSR_LSB_REG,
1745 aic3262_divs[i].dosr & AIC3262_8BITS_MASK);
1746 DBG(KERN_INFO "# writing DOSR_LSB_REG = %d\n",
1747 (aic3262_divs[i].dosr & AIC3262_8BITS_MASK));
1748
1749 /* NADC divider value */
1750 data = snd_soc_read(codec, NADC_DIV_POW_REG);
1751 snd_soc_write(codec, NADC_DIV_POW_REG,
1752 ((data & 0x80)|(aic3262_divs[i].nadc)));
1753 DBG(KERN_INFO "# writing NADC_DIV_POW_REG = %d\n",
1754 aic3262_divs[i].nadc);
1755
1756 /* MADC divider value */
1757 data = snd_soc_read(codec, MADC_DIV_POW_REG);
1758 snd_soc_write(codec, MADC_DIV_POW_REG,
1759 ((data & 0x80)|(aic3262_divs[i].madc)));
1760 DBG(KERN_INFO "# writing MADC_DIV_POW_REG = %d\n",
1761 aic3262_divs[i].madc);
1762
1763 /* AOSR value */
1764 snd_soc_write(codec, AOSR_REG, aic3262_divs[i].aosr);
1765 DBG(KERN_INFO "# writing AOSR = %d\n", aic3262_divs[i].aosr);
1766 } else {
1767 DBG(KERN_INFO "#Atleast 1 ASI Active. Cannot Program PLL..\n");
1768 }
1769 /* Check for the DAI ID to know which ASI needs
1770 * Configuration.
1771 */
1772 switch (dai->id) {
1773 case 1:
1774 regoffset = ASI1_BUS_FMT;
1775
1776 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1777 DBG(KERN_INFO "#%s: ASI1 DAC Inputs enabled..\n",
1778 __func__);
1779 /* Read the DAC Control Register and configure it
1780 * as per the ASIContext Structure Settings.
1781 */
1782 dacpath = snd_soc_read(codec, ASI1_DAC_OUT_CNTL);
1783 dacpath &= ~(AIC3262_ASI_LDAC_PATH_MASK |
1784 AIC3262_ASI_RDAC_PATH_MASK);
1785 dacpath |= (aic3262->asiCtxt[0].left_dac_output
1786 << AIC3262_ASI_LDAC_PATH_SHIFT);
1787
1788 dacpath |= (aic3262->asiCtxt[0].right_dac_output
1789 << AIC3262_ASI_RDAC_PATH_SHIFT);
1790 snd_soc_write(codec, ASI1_DAC_OUT_CNTL, dacpath);
1791
1792 aic3262->asiCtxt[0].playback_mode = 1;
1793 aic3262->asiCtxt[0].bclk_div =
1794 aic3262_divs[i].blck_N;
1795 } else {
1796 /* For Recording, Configure the DOUT Pin as per
1797 * ASIContext Structure Settings.
1798 */
1799 adcpath = snd_soc_read(codec, ASI1_DATA_OUT);
1800 adcpath &= ~(AIC3262_ASI_DOUT_MASK);
1801
1802 adcpath |= aic3262->asiCtxt[0].dout_option;
1803 snd_soc_write(codec, ASI1_DATA_OUT, adcpath);
1804
1805 aic3262->asiCtxt[0].capture_mode = 1;
1806 }
1807 break;
1808 case 2:
1809 regoffset = ASI2_BUS_FMT;
1810
1811 /* Since we are configuring ASI2, please check if Playback
1812 * is expected. If so, enable ASI2 Inputs to Left and
1813 * Right DACs
1814 */
1815 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1816 DBG(KERN_INFO "#%s: ASI2 DAC Inputs enabled..\n",
1817 __func__);
1818 /* Read the DAC Control Register and configure it
1819 * as per theASIContext Structure Settings.
1820 */
1821 dacpath = snd_soc_read(codec, ASI2_DAC_OUT_CNTL);
1822 dacpath &= ~(AIC3262_ASI_LDAC_PATH_MASK |
1823 AIC3262_ASI_RDAC_PATH_MASK);
1824 dacpath |= (aic3262->asiCtxt[1].left_dac_output
1825 << AIC3262_ASI_LDAC_PATH_SHIFT);
1826
1827 dacpath |= (aic3262->asiCtxt[1].right_dac_output
1828 << AIC3262_ASI_RDAC_PATH_SHIFT);
1829 snd_soc_write(codec, ASI2_DAC_OUT_CNTL, dacpath);
1830 aic3262->asiCtxt[1].playback_mode = 1;
1831
1832 aic3262->asiCtxt[1].bclk_div =
1833 aic3262_divs[i].blck_N;
1834 } else {
1835 /* For Recording, Configure the DOUT Pin as per
1836 * ASIContext Structure Settings.
1837 */
1838 adcpath = snd_soc_read(codec, ASI2_DATA_OUT);
1839 adcpath &= ~(AIC3262_ASI_DOUT_MASK);
1840 adcpath |= aic3262->asiCtxt[1].dout_option;
1841 snd_soc_write(codec, ASI2_DATA_OUT, adcpath);
1842
1843 aic3262->asiCtxt[1].capture_mode = 1;
1844 }
1845 break;
1846 case 3:
1847 regoffset = ASI3_BUS_FMT;
1848 /* Since we are configuring ASI3, please check if Playback
1849 * is expected. If so, enable ASI3 Inputs to Left and
1850 * Right DACs
1851 */
1852 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1853 DBG(KERN_INFO "#%s:ASI3 DAC Inputs enabled.\n",
1854 __func__);
1855 /* Read the DAC Control Register and configure
1856 * it as per the ASIContext Structure Settings.
1857 */
1858 dacpath = snd_soc_read(codec, ASI3_DAC_OUT_CNTL);
1859 dacpath &= ~(AIC3262_ASI_LDAC_PATH_MASK |
1860 AIC3262_ASI_RDAC_PATH_MASK);
1861 dacpath |= (aic3262->asiCtxt[2].left_dac_output
1862 << AIC3262_ASI_LDAC_PATH_SHIFT);
1863 dacpath |= (aic3262->asiCtxt[2].right_dac_output
1864 << AIC3262_ASI_RDAC_PATH_SHIFT);
1865 snd_soc_write(codec,
1866 ASI3_DAC_OUT_CNTL, dacpath);
1867
1868 aic3262->asiCtxt[2].playback_mode = 1;
1869
1870 aic3262->asiCtxt[2].bclk_div =
1871 aic3262_divs[i].blck_N;
1872 } else {
1873 /* For Recording, Configure the DOUT Pin as per
1874 * ASIContext Structure Settings.
1875 */
1876 adcpath &= ~(AIC3262_ASI_DOUT_MASK);
1877 adcpath |= aic3262->asiCtxt[2].dout_option;
1878 snd_soc_write(codec, ASI3_DATA_OUT, adcpath);
1879
1880 aic3262->asiCtxt[2].capture_mode = 1;
1881 }
1882 break;
1883 default:
1884 printk(KERN_ERR "Invalid Dai ID %d in %s",
1885 dai->id, __func__);
1886 break;
1887 }
1888 DBG(KERN_INFO "#%s: Reading Pg %d Reg %d for Bus Format Control.\n",
1889 __func__, (regoffset/128), (regoffset % 128));
1890
1891 /* Read the correspondig ASI DAI Interface Register */
1892 data = snd_soc_read(codec, regoffset);
1893
1894 data = data & 0xe7;
1895
1896 switch (params_format(params)) {
1897 case SNDRV_PCM_FORMAT_S16_LE:
1898 DBG(KERN_INFO "#%s: Configuring ASI%d S16_LE Fmt..\n",
1899 __func__, dai->id);
1900 data = data | 0x00;
1901 aic3262->asiCtxt[dai->id - 1].word_len = 16;
1902 break;
1903 case SNDRV_PCM_FORMAT_S20_3LE:
1904 data |= (0x08);
1905 aic3262->asiCtxt[dai->id - 1].word_len = 20;
1906 break;
1907 case SNDRV_PCM_FORMAT_S24_LE:
1908 DBG(KERN_INFO "#%s: Configuring ASI%d S24_LE Fmt..\n",
1909 __func__, dai->id);
1910 data |= (0x10);
1911 aic3262->asiCtxt[dai->id - 1].word_len = 24;
1912 break;
1913 case SNDRV_PCM_FORMAT_S32_LE:
1914 DBG(KERN_INFO "#%s: Configuring ASI%d S32_LE Fmt..\n",
1915 __func__, dai->id);
1916 data |= (0x18);
1917 aic3262->asiCtxt[dai->id - 1].word_len = 32;
1918 break;
1919 }
1920
1921 /* configure the respective Registers for the above configuration */
1922 snd_soc_write(codec, regoffset, data);
1923
1924 for (j = 0; j < NO_FEATURE_REGS; j++) {
1925 snd_soc_write(codec,
1926 aic3262_divs[i].codec_specific_regs[j].reg_offset,
1927 aic3262_divs[i].codec_specific_regs[j].reg_val);
1928 }
1929
1930 /* Enable the PLL, MDAC, NDAC, NADC, MADC and BCLK Dividers */
1931 aic3262_set_bias_level(codec, SND_SOC_BIAS_ON);
1932
1933 /* Based on the DAI ID we enable the corresponding pins related to the
1934 * ASI Port.
1935 */
1936 switch (dai->id) {
1937 case 1:
1938 aic3262_asi1_clk_config(codec, params);
1939 break;
1940 case 2:
1941 aic3262_asi2_clk_config(codec, params);
1942 break;
1943 case 3:
1944 aic3262_asi3_clk_config(codec, params);
1945 break;
1946 default:
1947 printk(KERN_ERR "Invalid Dai ID %d in %s",
1948 dai->id, __func__);
1949 break;
1950 }
1951 /* Depending on the DAI->ID update the local Flags */
1952 aic3262->asiCtxt[dai->id - 1].asi_active++;
1953 aic3262->asiCtxt[dai->id - 1].sampling_rate = params_rate(params);
1954 /* Update the active_count flag */
1955 aic3262->active_count++;
1956
1957 return 0;
1958}
1959
1960/*
1961*
1962* aic3262_multi_i2s_hw_free
1963*
1964* This function is used to configure the Codec after the usage is completed.
1965* We can use this function to disable the DAC and ADC specific inputs from the
1966* individual ASI Ports of the Audio Codec.
1967*/
1968static int aic3262_multi_i2s_shutdown(struct snd_pcm_substream *substream,
1969 struct snd_soc_dai *dai)
1970{
1971 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1972 struct snd_soc_codec *codec = rtd->codec;
1973 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1974
1975 u8 value;
1976 u8 dacpath;
1977 u8 adcpath;
1978 u16 dacregoffset = 0;
1979 u16 adcregoffset = 0;
1980
1981 DBG(KERN_INFO "#%s: ASI%d Port for %s Mode\n",
1982 __func__, dai->id,
1983 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
1984 "Playback" : "Record");
1985
1986 /* Check if this function was already executed earlier for the same
1987 * ASI Port
1988 */
1989 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
1990 (aic3262->asiCtxt[dai->id - 1].playback_mode == 0)) {
1991 DBG(KERN_INFO "#%s: Function Already Executed. Exiting..\n",
1992 __func__);
1993 goto err;
1994 } else if ((substream->stream != SNDRV_PCM_STREAM_PLAYBACK) &&
1995 (aic3262->asiCtxt[dai->id - 1].capture_mode == 0)) {
1996 DBG(KERN_INFO "#%s: Function Already Executed. Exiting..\n",
1997 __func__);
1998 goto err;
1999 }
2000
2001 switch (dai->id) {
2002 case 1:
2003 /* In case we are Frame Master on this Interface, Switch off
2004 * the Bit Clock Divider and Word Clock Dividers
2005 */
2006 if (aic3262->asiCtxt[0].master == 1) {
2007 /* Also check if either Playback or Recording is still
2008 * going on this ASI Interface
2009 */
2010
2011 value = snd_soc_read(codec, ASI1_BCLK_N);
2012 snd_soc_write(codec, ASI1_BCLK_N, (value & 0x7f));
2013
2014 value = snd_soc_read(codec, ASI1_WCLK_N);
2015 snd_soc_write(codec, ASI1_WCLK_N, (value & 0x7f));
2016 }
2017
2018 dacregoffset = ASI1_DAC_OUT_CNTL;
2019 adcregoffset = ASI1_ADC_INPUT_CNTL;
2020 break;
2021 case 2:
2022 /* In case we are Frame Master on this Interface, Switch off
2023 * the Bit Clock Divider and Word Clock Dividers
2024 */
2025 if (aic3262->asiCtxt[1].master == 1) {
2026 value = snd_soc_read(codec, ASI2_BCLK_N);
2027 snd_soc_write(codec, ASI2_BCLK_N, (value & 0x7f));
2028
2029 value = snd_soc_read(codec, ASI2_WCLK_N);
2030 snd_soc_write(codec, ASI2_WCLK_N, (value & 0x7f));
2031 }
2032 dacregoffset = ASI2_DAC_OUT_CNTL;
2033 adcregoffset = ASI2_ADC_INPUT_CNTL;
2034 break;
2035 case 3:
2036 /* In case we are Frame Master on this Interface, Switch off
2037 * the Bit Clock Divider and Word Clock Dividers
2038 */
2039 if (aic3262->asiCtxt[2].master == 1) {
2040 value = snd_soc_read(codec, ASI3_BCLK_N);
2041 snd_soc_write(codec, ASI3_BCLK_N, (value & 0x7f));
2042
2043 value = snd_soc_read(codec, ASI3_WCLK_N);
2044 snd_soc_write(codec, ASI3_WCLK_N, (value & 0x7f));
2045 }
2046 dacregoffset = ASI3_DAC_OUT_CNTL;
2047 adcregoffset = ASI3_ADC_INPUT_CNTL;
2048 break;
2049 default:
2050 printk(KERN_ERR "#%s: Invalid dai id\n", __func__);
2051 }
2052 /* If this was a Playback Stream Stop, then only
2053 * switch off the DAC Inputs
2054 */
2055 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
2056 (dacregoffset != 0)) {
2057 DBG(KERN_INFO "#%s: Disabling Pg %d Reg %d DAC Inputs ..\n",
2058 __func__, (dacregoffset/128), (dacregoffset % 128));
2059
2060 dacpath = snd_soc_read(codec, dacregoffset);
2061 snd_soc_write(codec, dacregoffset, (dacpath & ~(BIT6 | BIT4)));
2062
2063 aic3262->asiCtxt[dai->id - 1].playback_mode = 0;
2064 } else {
2065 /* Switch off the ADC Input Control Registers here */
2066 DBG(KERN_INFO "#%s: Disabling Pg %d Reg %d for ADC Inputs..\n",
2067 __func__, (adcregoffset/128), (adcregoffset % 128));
2068
2069 adcpath = snd_soc_read(codec, adcregoffset);
2070 snd_soc_write(codec, adcregoffset,
2071 (adcpath & ~(BIT2 | BIT1 | BIT0)));
2072
2073 aic3262->asiCtxt[dai->id - 1].capture_mode = 0;
2074 }
2075
2076 /* If we were configured in mono PCM Mode earlier, then reset the
2077 * Left Channel and Right Channel offset Registers here.
2078 */
2079 switch (dai->id) {
2080 case 1:
2081 if (aic3262->asiCtxt[0].pcm_format == SND_SOC_DAIFMT_DSP_B) {
2082 snd_soc_write(codec, ASI1_LCH_OFFSET, 0x00);
2083 snd_soc_write(codec, ASI1_RCH_OFFSET, 0x00);
2084 }
2085 break;
2086 case 2:
2087 if (aic3262->asiCtxt[1].pcm_format == SND_SOC_DAIFMT_DSP_B) {
2088 snd_soc_write(codec, ASI2_LCH_OFFSET, 0x00);
2089 snd_soc_write(codec, ASI2_RCH_OFFSET, 0x00);
2090 }
2091
2092 break;
2093 case 3:
2094 if (aic3262->asiCtxt[2].pcm_format == SND_SOC_DAIFMT_DSP_B) {
2095 snd_soc_write(codec, ASI3_LCH_OFFSET, 0x00);
2096 snd_soc_write(codec, ASI3_RCH_OFFSET, 0x00);
2097 }
2098 break;
2099 }
2100 /* Depending on the DAI->ID update the asi_active Flags */
2101 if (aic3262->asiCtxt[dai->id - 1].asi_active) {
2102 aic3262->asiCtxt[dai->id - 1].asi_active--;
2103
2104 /* Update the active_count flag */
2105 if (aic3262->active_count)
2106 aic3262->active_count--;
2107 }
2108err:
2109 return 0;
2110}
2111
2112
2113/*
2114*
2115* aic3262_multi_i2s_set_clkdiv
2116*
2117*/
2118static int aic3262_multi_i2s_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
2119{
2120 int value;
2121 struct snd_soc_codec *codec = codec_dai->codec;
2122 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
2123
2124
2125 value = snd_soc_read(codec, div_id);
2126 snd_soc_write(codec, div_id, (value | div));
2127
2128 printk(KERN_INFO "#%s: DAI ID %d Page %d Register %d Divider_Val %d Final_Value 0x%x\n",
2129 __func__, codec_dai->id, (div_id /128), (div_id%128), div,
2130 (value | div));
2131
2132 /* Store the Clock Divider inside the Private Structure */
2133 switch(codec_dai->id) {
2134 case 1:
2135 if (div_id == ASI1_BCLK_N)
2136 aic3262->asiCtxt[0].bclk_div = div;
2137 if (div_id == ASI1_WCLK_N)
2138 aic3262->asiCtxt[0].wclk_div = div;
2139 break;
2140 case 2:
2141 if (div_id == ASI2_BCLK_N)
2142 aic3262->asiCtxt[1].bclk_div = div;
2143 if (div_id == ASI2_WCLK_N)
2144 aic3262->asiCtxt[1].wclk_div = div;
2145 break;
2146 case 3:
2147 if (div_id == ASI3_BCLK_N)
2148 aic3262->asiCtxt[2].bclk_div = div;
2149 if (div_id == ASI3_WCLK_N)
2150 aic3262->asiCtxt[2].wclk_div = div;
2151 break;
2152 }
2153 return 0;
2154}
2155
2156
2157/*
2158 *----------------------------------------------------------------------------
2159 * @struct snd_soc_codec_dai |
2160 * It is SoC Codec DAI structure which has DAI capabilities viz.,
2161 * playback and capture, DAI runtime information viz. state of DAI
2162 * and pop wait state, and DAI private data.
2163 * The AIC3262 rates ranges from 8k to 192k
2164 * The PCM bit format supported are 16, 20, 24 and 32 bits
2165 *----------------------------------------------------------------------------
2166 */
2167struct snd_soc_dai_ops aic3262_multi_i2s_dai_ops = {
2168 .hw_params = aic3262_multi_i2s_hw_params,
2169 .digital_mute = aic3262_multi_i2s_mute,
2170 .set_fmt = aic3262_multi_i2s_set_dai_fmt,
2171 .set_pll = aic3262_multi_i2s_set_dai_pll,
2172 .set_sysclk = aic3262_multi_i2s_set_dai_sysclk,
2173 .shutdown = aic3262_multi_i2s_shutdown,
2174 .set_clkdiv = aic3262_multi_i2s_set_clkdiv,
2175};
2176
2177
2178static struct snd_soc_dai_driver tlv320aic3262_dai[] = {
2179/* AIC3262 ASI1 DAI */
2180{
2181 .name = "aic3262-asi1",
2182 .id = 1,
2183 .playback = {
2184 .stream_name = "ASI1 Playback",
2185 .channels_min = 1,
2186 .channels_max = 2,
2187 .rates = AIC3262_RATES,
2188 .formats = AIC3262_FORMATS},
2189 .capture = { /* dummy for fast DAI switching */
2190 .stream_name = "ASI1 Capture",
2191 .channels_min = 1,
2192 .channels_max = 2,
2193 .rates = AIC3262_RATES,
2194 .formats = AIC3262_FORMATS},
2195 .ops = &aic3262_multi_i2s_dai_ops,
2196},
2197/* AIC3262 ASI2 DAI */
2198{
2199 .name = "aic3262-asi2",
2200 .id = 2,
2201 .playback = {
2202 .stream_name = "ASI2 Playback",
2203 .channels_min = 1,
2204 .channels_max = 2,
2205 .rates = AIC3262_RATES,
2206 .formats = AIC3262_FORMATS,},
2207 .capture = {
2208 .stream_name = "ASI2 Capture",
2209 .channels_min = 1,
2210 .channels_max = 2,
2211 .rates = AIC3262_RATES,
2212 .formats = AIC3262_FORMATS,},
2213 .ops = &aic3262_multi_i2s_dai_ops,
2214
2215},
2216/* AIC3262 ASI3 DAI */
2217{
2218 .name = "aic3262-asi3",
2219 .id = 3,
2220 .playback = {
2221 .stream_name = "ASI3 Playback",
2222 .channels_min = 1,
2223 .channels_max = 2,
2224 .rates = AIC3262_RATES,
2225 .formats = AIC3262_FORMATS, },
2226 .capture = {
2227 .stream_name = "ASI3 Capture",
2228 .channels_min = 1,
2229 .channels_max = 2,
2230 .rates = AIC3262_RATES,
2231 .formats = AIC3262_FORMATS, },
2232 .ops = &aic3262_multi_i2s_dai_ops,
2233
2234},
2235};
2236
2237/*
2238 *****************************************************************************
2239 * Initializations
2240 *****************************************************************************
2241 */
2242/*
2243 * AIC3262 register cache
2244 * We are caching the registers here.
2245 * There is no point in caching the reset register.
2246 *
2247 * NOTE: In AIC3262, there are 127 registers supported in both page0 and page1
2248 * The following table contains the page0 and page 1 and page 3
2249 * registers values.
2250 */
2251static const u8 aic3262_reg[AIC3262_CACHEREGNUM] = {
2252 0x00, 0x00, 0x10, 0x00, /* 0 */
2253 0x03, 0x40, 0x11, 0x08, /* 4 */
2254 0x00, 0x00, 0x00, 0x82, /* 8 */
2255 0x88, 0x00, 0x80, 0x02, /* 12 */
2256 0x00, 0x08, 0x01, 0x01, /* 16 */
2257 0x80, 0x01, 0x00, 0x04, /* 20 */
2258 0x00, 0x00, 0x01, 0x00, /* 24 */
2259 0x00, 0x00, 0x01, 0x00, /* 28 */
2260 0x00, 0x00, 0x00, 0x00, /* 32 */
2261 0x00, 0x00, 0x00, 0x00, /* 36 */
2262 0x00, 0x00, 0x00, 0x00, /* 40 */
2263 0x00, 0x00, 0x00, 0x00, /* 44 */
2264 0x00, 0x00, 0x00, 0x00, /* 48 */
2265 0x00, 0x42, 0x02, 0x02, /* 52 */
2266 0x42, 0x02, 0x02, 0x02, /* 56 */
2267 0x00, 0x00, 0x00, 0x01, /* 60 */
2268 0x01, 0x00, 0x14, 0x00, /* 64 */
2269 0x0C, 0x00, 0x00, 0x00, /* 68 */
2270 0x00, 0x00, 0x00, 0xEE, /* 72 */
2271 0x10, 0xD8, 0x10, 0xD8, /* 76 */
2272 0x00, 0x00, 0x88, 0x00, /* 80 */
2273 0x00, 0x00, 0x00, 0x00, /* 84 */
2274 0x7F, 0x00, 0x00, 0x00, /* 88 */
2275 0x00, 0x00, 0x00, 0x00, /* 92 */
2276 0x7F, 0x00, 0x00, 0x00, /* 96 */
2277 0x00, 0x00, 0x00, 0x00, /* 100 */
2278 0x00, 0x00, 0x00, 0x00, /* 104 */
2279 0x00, 0x00, 0x00, 0x00, /* 108 */
2280 0x00, 0x00, 0x00, 0x00, /* 112 */
2281 0x00, 0x00, 0x00, 0x00, /* 116 */
2282 0x00, 0x00, 0x00, 0x00, /* 120 */
2283 0x00, 0x00, 0x00, 0x00, /* 124 - PAGE0 Registers(127) ends here */
2284 0x01, 0x00, 0x08, 0x00, /* 128, PAGE1-0 */
2285 0x00, 0x00, 0x00, 0x00, /* 132, PAGE1-4 */
2286 0x00, 0x00, 0x00, 0x10, /* 136, PAGE1-8 */
2287 0x00, 0x00, 0x00, 0x00, /* 140, PAGE1-12 */
2288 0x40, 0x40, 0x40, 0x40, /* 144, PAGE1-16 */
2289 0x00, 0x00, 0x00, 0x00, /* 148, PAGE1-20 */
2290 0x00, 0x00, 0x00, 0x00, /* 152, PAGE1-24 */
2291 0x00, 0x00, 0x00, 0x00, /* 156, PAGE1-28 */
2292 0x00, 0x00, 0x00, 0x00, /* 160, PAGE1-32 */
2293 0x00, 0x00, 0x00, 0x00, /* 164, PAGE1-36 */
2294 0x00, 0x00, 0x00, 0x00, /* 168, PAGE1-40 */
2295 0x00, 0x00, 0x00, 0x00, /* 172, PAGE1-44 */
2296 0x00, 0x00, 0x00, 0x00, /* 176, PAGE1-48 */
2297 0x00, 0x00, 0x00, 0x00, /* 180, PAGE1-52 */
2298 0x00, 0x00, 0x00, 0x80, /* 184, PAGE1-56 */
2299 0x80, 0x00, 0x00, 0x00, /* 188, PAGE1-60 */
2300 0x00, 0x00, 0x00, 0x00, /* 192, PAGE1-64 */
2301 0x00, 0x00, 0x00, 0x00, /* 196, PAGE1-68 */
2302 0x00, 0x00, 0x00, 0x00, /* 200, PAGE1-72 */
2303 0x00, 0x00, 0x00, 0x00, /* 204, PAGE1-76 */
2304 0x00, 0x00, 0x00, 0x00, /* 208, PAGE1-80 */
2305 0x00, 0x00, 0x00, 0x00, /* 212, PAGE1-84 */
2306 0x00, 0x00, 0x00, 0x00, /* 216, PAGE1-88 */
2307 0x00, 0x00, 0x00, 0x00, /* 220, PAGE1-92 */
2308 0x00, 0x00, 0x00, 0x00, /* 224, PAGE1-96 */
2309 0x00, 0x00, 0x00, 0x00, /* 228, PAGE1-100 */
2310 0x00, 0x00, 0x00, 0x00, /* 232, PAGE1-104 */
2311 0x00, 0x00, 0x00, 0x00, /* 236, PAGE1-108 */
2312 0x00, 0x00, 0x00, 0x00, /* 240, PAGE1-112 */
2313 0x00, 0x00, 0x00, 0x00, /* 244, PAGE1-116 */
2314 0x00, 0x00, 0x00, 0x00, /* 248, PAGE1-120 */
2315 0x00, 0x00, 0x00, 0x00, /* 252, PAGE1-124 Page 1 Registers Ends Here */
2316 0x00, 0x00, 0x00, 0x00, /* 256, PAGE2-0 */
2317 0x00, 0x00, 0x00, 0x00, /* 260, PAGE2-4 */
2318 0x00, 0x00, 0x00, 0x00, /* 264, PAGE2-8 */
2319 0x00, 0x00, 0x00, 0x00, /* 268, PAGE2-12 */
2320 0x00, 0x00, 0x00, 0x00, /* 272, PAGE2-16 */
2321 0x00, 0x00, 0x00, 0x00, /* 276, PAGE2-20 */
2322 0x00, 0x00, 0x00, 0x00, /* 280, PAGE2-24 */
2323 0x00, 0x00, 0x00, 0x00, /* 284, PAGE2-28 */
2324 0x00, 0x00, 0x00, 0x00, /* 288, PAGE2-32 */
2325 0x00, 0x00, 0x00, 0x00, /* 292, PAGE2-36 */
2326 0x00, 0x00, 0x00, 0x00, /* 296, PAGE2-40 */
2327 0x00, 0x00, 0x00, 0x00, /* 300, PAGE2-44 */
2328 0x00, 0x00, 0x00, 0x00, /* 304, PAGE2-48 */
2329 0x00, 0x00, 0x00, 0x00, /* 308, PAGE2-52 */
2330 0x00, 0x00, 0x00, 0x00, /* 312, PAGE2-56 */
2331 0x00, 0x00, 0x00, 0x00, /* 316, PAGE2-60 */
2332 0x00, 0x00, 0x00, 0x00, /* 320, PAGE2-64 */
2333 0x00, 0x00, 0x00, 0x00, /* 324, PAGE2-68 */
2334 0x00, 0x00, 0x00, 0x00, /* 328, PAGE2-72 */
2335 0x00, 0x00, 0x00, 0x00, /* 332, PAGE2-76 */
2336 0x00, 0x00, 0x00, 0x00, /* 336, PAGE2-80 */
2337 0x00, 0x00, 0x00, 0x00, /* 340, PAGE2-84 */
2338 0x00, 0x00, 0x00, 0x00, /* 344, PAGE2-88 */
2339 0x00, 0x00, 0x00, 0x00, /* 348, PAGE2-92 */
2340 0x00, 0x00, 0x00, 0x00, /* 352, PAGE2-96 */
2341 0x00, 0x00, 0x00, 0x00, /* 356, PAGE2-100 */
2342 0x00, 0x00, 0x00, 0x00, /* 360, PAGE2-104 */
2343 0x00, 0x00, 0x00, 0x00, /* 364, PAGE2-108 */
2344 0x00, 0x00, 0x00, 0x00, /* 368, PAGE2-112*/
2345 0x00, 0x00, 0x00, 0x00, /* 372, PAGE2-116*/
2346 0x00, 0x00, 0x00, 0x00, /* 376, PAGE2-120*/
2347 0x00, 0x00, 0x00, 0x00, /* 380, PAGE2-124 Page 2 Registers Ends Here */
2348 0x00, 0x00, 0x00, 0x00, /* 384, PAGE3-0 */
2349 0x00, 0x00, 0x00, 0x00, /* 388, PAGE3-4 */
2350 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-8 */
2351 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-12 */
2352 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-16 */
2353 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-20 */
2354 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-24 */
2355 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-28 */
2356 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-32 */
2357 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-36 */
2358 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-40 */
2359 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-44 */
2360 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-48 */
2361 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-52 */
2362 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-56 */
2363 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-60 */
2364 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-64 */
2365 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-68 */
2366 0x00, 0x00, 0x00, 0x00, /* 328, PAGE3-72 */
2367 0x00, 0x00, 0x00, 0x00, /* 332, PAGE3-76 */
2368 0x00, 0x00, 0x00, 0x00, /* 336, PAGE3-80 */
2369 0x00, 0x00, 0x00, 0x00, /* 340, PAGE3-84 */
2370 0x00, 0x00, 0x00, 0x00, /* 344, PAGE3-88 */
2371 0x00, 0x00, 0x00, 0x00, /* 348, PAGE3-92 */
2372 0x00, 0x00, 0x00, 0x00, /* 352, PAGE3-96 */
2373 0x00, 0x00, 0x00, 0x00, /* 356, PAGE3-100 */
2374 0x00, 0x00, 0x00, 0x00, /* 360, PAGE3-104 */
2375 0x00, 0x00, 0x00, 0x00, /* 364, PAGE3-108 */
2376 0x00, 0x00, 0x00, 0x00, /* 368, PAGE3-112*/
2377 0x00, 0x00, 0x00, 0x00, /* 372, PAGE3-116*/
2378 0x00, 0x00, 0x00, 0x00, /* 376, PAGE3-120*/
2379 0x00, 0x00, 0x00, 0x00, /* 380, PAGE3-124 Page 3 Registers Ends Here */
2380 0x00, 0x00, 0x00, 0x00, /* 384, PAGE4-0 */
2381 0x00, 0x00, 0x00, 0x00, /* 388, PAGE4-4 */
2382 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-8 */
2383 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-12 */
2384 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-16 */
2385 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-20 */
2386 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-24 */
2387 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-28 */
2388 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-32 */
2389 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-36 */
2390 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-40 */
2391 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-44 */
2392 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-48 */
2393 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-52 */
2394 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-56 */
2395 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-60 */
2396 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-64 */
2397 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-68 */
2398 0x00, 0x00, 0x00, 0x00, /* 328, PAGE4-72 */
2399 0x00, 0x00, 0x00, 0x00, /* 332, PAGE4-76 */
2400 0x00, 0x00, 0x00, 0x00, /* 336, PAGE4-80 */
2401 0x00, 0x00, 0x00, 0x00, /* 340, PAGE4-84 */
2402 0x00, 0x00, 0x00, 0x00, /* 344, PAGE4-88 */
2403 0x00, 0x00, 0x00, 0x00, /* 348, PAGE4-92 */
2404 0x00, 0x00, 0x00, 0x00, /* 352, PAGE4-96 */
2405 0x00, 0x00, 0x00, 0x00, /* 356, PAGE4-100 */
2406 0x00, 0x00, 0x00, 0x00, /* 360, PAGE4-104 */
2407 0x00, 0x00, 0x00, 0x00, /* 364, PAGE4-108 */
2408 0x00, 0x00, 0x00, 0x00, /* 368, PAGE4-112*/
2409 0x00, 0x00, 0x00, 0x00, /* 372, PAGE4-116*/
2410 0x00, 0x00, 0x00, 0x00, /* 376, PAGE4-120*/
2411 0x00, 0x00, 0x00, 0x00, /* 380, PAGE4-124 Page 2 Registers Ends Here */
2412
2413};
2414
2415/*
2416 *------------------------------------------------------------------------------
2417 * aic3262 initialization data
2418 * This structure initialization contains the initialization required for
2419 * AIC326x.
2420 * These registers values (reg_val) are written into the respective AIC3262
2421 * register offset (reg_offset) to initialize AIC326x.
2422 * These values are used in aic3262_init() function only.
2423 *------------------------------------------------------------------------------
2424 */
2425static const struct aic3262_configs aic3262_reg_init[] = {
2426 /* CLOCKING */
2427
2428 {0, RESET_REG, 1},
2429 {0, RESET_REG, 0},
2430
2431 {0, PASI_DAC_DP_SETUP, 0xc0}, /*DAC */
2432 {0, DAC_MVOL_CONF, 0x00}, /*DAC un-muted*/
2433 /* set default volumes */
2434 {0, DAC_LVOL, 0x01},
2435 {0, DAC_RVOL, 0x01},
2436 {0, HPL_VOL, 0x80},
2437 {0, HPR_VOL, 0x80},
2438 {0, SPK_AMP_CNTL_R2, 0x14},
2439 {0, SPK_AMP_CNTL_R3, 0x14},
2440 {0, SPK_AMP_CNTL_R4, 0x33},
2441 {0, REC_AMP_CNTL_R5, 0x82},
2442 {0, RAMPR_VOL, 20},
2443 {0, RAMP_CNTL_R1, 70},
2444 {0, RAMP_CNTL_R2, 70},
2445
2446 /* DRC Defaults */
2447 {0, DRC_CNTL_R1, 0x6c},
2448 {0, DRC_CNTL_R2, 16},
2449
2450 /* DEPOP SETTINGS */
2451 {0, HP_DEPOP, 0x14},
2452 {0, RECV_DEPOP, 0x14},
2453
2454 {0, POWER_CONF, 0x00}, /* Disconnecting AVDD-DVD weak link*/
2455 {0, REF_PWR_DLY, 0x01},
2456 {0, CM_REG, 0x00}, /*CM - default*/
2457 {0, LDAC_PTM, 0}, /*LDAC_PTM - default*/
2458 {0, RDAC_PTM, 0}, /*RDAC_PTM - default*/
2459 {0, HP_CTL, 0x30}, /*HP output percentage - at 75%*/
2460 {0, LADC_VOL, 0x01}, /*LADC volume*/
2461 {0, RADC_VOL, 0x01}, /*RADC volume*/
2462
2463 {0, DAC_ADC_CLKIN_REG, 0x33}, /*DAC ADC CLKIN*/
2464 {0, PLL_CLKIN_REG, 0x00}, /*PLL CLKIN*/
2465 {0, PLL_PR_POW_REG, 0x11}, /*PLL Power=0-down, P=1, R=1 vals*/
2466 {0, 0x3d, 1},
2467
2468 {0, LMIC_PGA_PIN, 0x0}, /*IN1_L select - - 10k -LMICPGA_P*/
2469 {0, LMIC_PGA_MIN, 0x40}, /*CM to LMICPGA-M*/
2470 {0, RMIC_PGA_PIN, 0x0}, /*IN1_R select - - 10k -RMIC_PGA_P*/
2471 {0, RMIC_PGA_MIN, 0x0}, /*CM to RMICPGA_M*/
2472 {0, MIC_PWR_DLY , 33}, /*LMIC-PGA-POWERUP-DELAY - default*/
2473 {0, REF_PWR_DLY, 1}, /*FIXMELATER*/
2474
2475
2476 {0, ADC_CHANNEL_POW, 0x0}, /*ladc, radc ON , SOFT STEP disabled*/
2477 {0, ADC_FINE_GAIN, 0x00}, /*ladc - unmute, radc - unmute*/
2478 {0, MICL_PGA, 0x3f},
2479 {0, MICR_PGA, 0x3f},
2480 /*controls MicBias ext power based on B0_P1_R51_D6*/
2481 {0, MIC_BIAS_CNTL, 0x80},
2482 /* ASI1 Configuration */
2483 {0, ASI1_BUS_FMT, 0},
2484 {0, ASI1_BWCLK_CNTL_REG, 0x00}, /* originaly 0x24*/
2485 {0, ASI1_BCLK_N_CNTL, 1},
2486 {0, ASI1_BCLK_N, 0x04},
2487
2488 {0, MA_CNTL, 0}, /* Mixer Amp disabled */
2489 {0, LINE_AMP_CNTL_R2, 0x00}, /* Line Amp Cntl disabled */
2490
2491 /* ASI2 Configuration */
2492 {0, ASI2_BUS_FMT, 0},
2493 {0, ASI2_BCLK_N_CNTL, 0x01},
2494 {0, ASI2_BCLK_N, 0x04},
2495 {0, ASI2_BWCLK_OUT_CNTL, 0x20},
2496
2497 {0, BEEP_CNTL_R1, 0x05},
2498 {0, BEEP_CNTL_R2, 0x04},
2499
2500 /* Interrupt config for headset detection */
2501 {0,HEADSET_TUNING1_REG,0x7f},
2502 {0, INT1_CNTL, 0x40},
2503 /*{0, TIMER_REG, 0x8c},*/
2504 {0, INT_FMT, 0x40},
2505 {0, GPIO1_IO_CNTL, 0x14},
2506 {0, HP_DETECT, 0x96},
2507
2508#if defined(CONFIG_MINI_DSP)
2509 {0, 60, 0},
2510 {0, 61, 0},
2511 /* Added the below set of values after consulting the miniDSP
2512 * Program Section Array
2513 */
2514 {0, MINIDSP_ACCESS_CTRL, 0x00},
2515#endif
2516
2517
2518};
2519
2520static int reg_init_size =
2521 sizeof(aic3262_reg_init) / sizeof(struct aic3262_configs);
2522
2523static const unsigned int adc_ma_tlv[] = {
2524TLV_DB_RANGE_HEAD(4),
2525 0, 29, TLV_DB_SCALE_ITEM(-1450, 500, 0),
2526 30, 35, TLV_DB_SCALE_ITEM(-2060, 1000, 0),
2527 36, 38, TLV_DB_SCALE_ITEM(-2660, 2000, 0),
2528 39, 40, TLV_DB_SCALE_ITEM(-3610, 5000, 0),
2529};
2530static const DECLARE_TLV_DB_SCALE(lo_hp_tlv, -7830, 50, 0);
2531
2532static const struct snd_kcontrol_new mal_pga_mixer_controls[] = {
2533 SOC_DAPM_SINGLE("IN1L Switch", MA_CNTL, 5, 1, 0),
2534 SOC_DAPM_SINGLE_TLV("Left MicPGA Volume", LADC_PGA_MAL_VOL, 0,
2535 0x3f, 1, adc_ma_tlv),
2536
2537};
2538
2539static const struct snd_kcontrol_new mar_pga_mixer_controls[] = {
2540 SOC_DAPM_SINGLE("IN1R Switch", MA_CNTL, 4, 1, 0),
2541 SOC_DAPM_SINGLE_TLV("Right MicPGA Volume", RADC_PGA_MAR_VOL, 0,
2542 0x3f, 1, adc_ma_tlv),
2543};
2544
2545/* Left HPL Mixer */
2546static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
2547 SOC_DAPM_SINGLE("MAL Switch", HP_AMP_CNTL_R1, 7, 1, 0),
2548 SOC_DAPM_SINGLE("LDAC Switch", HP_AMP_CNTL_R1, 5, 1, 0),
2549 SOC_DAPM_SINGLE_TLV("LOL-B1 Volume", HP_AMP_CNTL_R2, 0,
2550 0x7f, 1, lo_hp_tlv),
2551};
2552
2553/* Right HPR Mixer */
2554static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
2555 SOC_DAPM_SINGLE_TLV("LOR-B1 Volume", HP_AMP_CNTL_R3, 0,
2556 0x7f, 1, lo_hp_tlv),
2557 SOC_DAPM_SINGLE("LDAC Switch", HP_AMP_CNTL_R1, 2, 1, 0),
2558 SOC_DAPM_SINGLE("RDAC Switch", HP_AMP_CNTL_R1, 4, 1, 0),
2559 SOC_DAPM_SINGLE("MAR Switch", HP_AMP_CNTL_R1, 6, 1, 0),
2560};
2561
2562/* Left LOL Mixer */
2563static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
2564 SOC_DAPM_SINGLE("MAL Switch", LINE_AMP_CNTL_R2, 7, 1, 0),
2565 SOC_DAPM_SINGLE("IN1L-B Switch", LINE_AMP_CNTL_R2, 3, 1,0),
2566 SOC_DAPM_SINGLE("LDAC Switch", LINE_AMP_CNTL_R1, 7, 1, 0),
2567 SOC_DAPM_SINGLE("RDAC Switch", LINE_AMP_CNTL_R1, 5, 1, 0),
2568};
2569
2570/* Right LOR Mixer */
2571static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
2572 SOC_DAPM_SINGLE("LOL Switch", LINE_AMP_CNTL_R1, 2, 1, 0),
2573 SOC_DAPM_SINGLE("RDAC Switch", LINE_AMP_CNTL_R1, 6, 1, 0),
2574 SOC_DAPM_SINGLE("MAR Switch", LINE_AMP_CNTL_R2, 6, 1, 0),
2575 SOC_DAPM_SINGLE("IN1R-B Switch", LINE_AMP_CNTL_R2, 0, 1,0),
2576};
2577
2578/* Left SPKL Mixer */
2579static const struct snd_kcontrol_new spkl_output_mixer_controls[] = {
2580 SOC_DAPM_SINGLE("MAL Switch", SPK_AMP_CNTL_R1, 7, 1, 0),
2581 SOC_DAPM_SINGLE_TLV("LOL Volume", SPK_AMP_CNTL_R2, 0, 0x7f,0,
2582 lo_hp_tlv),
2583 SOC_DAPM_SINGLE("SPR_IN Switch", SPK_AMP_CNTL_R1, 2, 1, 0),
2584};
2585
2586/* Right SPKR Mixer */
2587static const struct snd_kcontrol_new spkr_output_mixer_controls[] = {
2588 SOC_DAPM_SINGLE_TLV("LOR Volume", SPK_AMP_CNTL_R3, 0, 0x7f, 0,
2589 lo_hp_tlv),
2590 SOC_DAPM_SINGLE("MAR Switch", SPK_AMP_CNTL_R1, 6, 1, 0),
2591};
2592
2593/* REC Mixer */
2594static const struct snd_kcontrol_new rec_output_mixer_controls[] = {
2595 SOC_DAPM_SINGLE_TLV("LOL-B2 Volume", RAMP_CNTL_R1, 0, 0x7f,0,
2596 lo_hp_tlv),
2597 SOC_DAPM_SINGLE_TLV("IN1L Volume", IN1L_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
2598 SOC_DAPM_SINGLE_TLV("IN1R Volume", IN1R_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
2599 SOC_DAPM_SINGLE_TLV("LOR-B2 Volume", RAMP_CNTL_R2, 0,0x7f, 0,lo_hp_tlv),
2600};
2601
2602/* Left Input Mixer */
2603static const struct snd_kcontrol_new left_input_mixer_controls[] = {
2604 SOC_DAPM_SINGLE("IN1L Switch", LMIC_PGA_PIN, 6, 1, 0),
2605 SOC_DAPM_SINGLE("IN2L Switch", LMIC_PGA_PIN, 4, 1, 0),
2606 SOC_DAPM_SINGLE("IN3L Switch", LMIC_PGA_PIN, 2, 1, 0),
2607 SOC_DAPM_SINGLE("IN4L Switch", LMIC_PGA_PM_IN4, 5, 1, 0),
2608 SOC_DAPM_SINGLE("IN1R Switch", LMIC_PGA_PIN, 0, 1, 0),
2609 SOC_DAPM_SINGLE("IN2R Switch", LMIC_PGA_MIN, 4, 1, 0),
2610 SOC_DAPM_SINGLE("IN3R Switch", LMIC_PGA_MIN, 2, 1, 0),
2611 SOC_DAPM_SINGLE("IN4R Switch", LMIC_PGA_PM_IN4, 4, 1, 0),
2612 SOC_DAPM_SINGLE("CM2L Switch", LMIC_PGA_MIN, 0, 1, 0),
2613 SOC_DAPM_SINGLE("CM1L Switch", LMIC_PGA_MIN, 6, 1, 0),
2614};
2615
2616/* Right Input Mixer */
2617static const struct snd_kcontrol_new right_input_mixer_controls[] = {
2618 SOC_DAPM_SINGLE("IN1R Switch", RMIC_PGA_PIN, 6, 1, 0),
2619 SOC_DAPM_SINGLE("IN2R Switch", RMIC_PGA_PIN, 4, 1, 0),
2620 SOC_DAPM_SINGLE("IN3R Switch", RMIC_PGA_PIN, 2, 1, 0),
2621 SOC_DAPM_SINGLE("IN4R Switch", RMIC_PGA_PM_IN4, 5, 1, 0),
2622 SOC_DAPM_SINGLE("IN2L Switch", RMIC_PGA_PIN, 0, 1, 0),
2623 SOC_DAPM_SINGLE("IN1L Switch", RMIC_PGA_MIN, 4, 1, 0),
2624 SOC_DAPM_SINGLE("IN3L Switch", RMIC_PGA_MIN, 2, 1, 0),
2625 SOC_DAPM_SINGLE("IN4L Switch", RMIC_PGA_PM_IN4, 4, 1, 0),
2626 SOC_DAPM_SINGLE("CM1R Switch", RMIC_PGA_MIN, 6, 1, 0),
2627 SOC_DAPM_SINGLE("CM2R Switch", RMIC_PGA_MIN, 0, 1, 0),
2628};
2629
2630
2631static const char *asi1lin_text[] = {
2632 "Off", "ASI1 Left In","ASI1 Right In","ASI1 MonoMix In"
2633};
2634
2635SOC_ENUM_SINGLE_DECL(asi1lin_enum, ASI1_DAC_OUT_CNTL, 6, asi1lin_text);
2636
2637static const struct snd_kcontrol_new asi1lin_control =
2638 SOC_DAPM_ENUM("ASI1LIN Route", asi1lin_enum);
2639
2640
2641static const char *asi1rin_text[] = {
2642 "Off", "ASI1 Right In","ASI1 Left In","ASI1 MonoMix In"
2643};
2644
2645SOC_ENUM_SINGLE_DECL(asi1rin_enum, ASI1_DAC_OUT_CNTL, 4, asi1rin_text);
2646
2647static const struct snd_kcontrol_new asi1rin_control =
2648 SOC_DAPM_ENUM("ASI1RIN Route", asi1rin_enum);
2649
2650static const char *asi2lin_text[] = {
2651 "Off", "ASI2 Left In","ASI2 Right In","ASI2 MonoMix In"
2652};
2653
2654SOC_ENUM_SINGLE_DECL(asi2lin_enum, ASI2_DAC_OUT_CNTL, 6, asi2lin_text);
2655static const struct snd_kcontrol_new asi2lin_control =
2656 SOC_DAPM_ENUM("ASI2LIN Route", asi2lin_enum);
2657
2658static const char *asi2rin_text[] = {
2659 "Off", "ASI2 Right In","ASI2 Left In","ASI2 MonoMix In"
2660};
2661
2662
2663SOC_ENUM_SINGLE_DECL(asi2rin_enum, ASI2_DAC_OUT_CNTL, 4, asi2rin_text);
2664
2665static const struct snd_kcontrol_new asi2rin_control =
2666 SOC_DAPM_ENUM("ASI2RIN Route", asi2rin_enum);
2667
2668static const char *asi3lin_text[] = {
2669 "Off", "ASI3 Left In","ASI3 Right In","ASI3 MonoMix In"
2670};
2671
2672
2673SOC_ENUM_SINGLE_DECL(asi3lin_enum, ASI3_DAC_OUT_CNTL, 6, asi3lin_text);
2674static const struct snd_kcontrol_new asi3lin_control =
2675 SOC_DAPM_ENUM("ASI3LIN Route", asi3lin_enum);
2676
2677
2678static const char *asi3rin_text[] = {
2679 "Off", "ASI3 Right In","ASI3 Left In","ASI3 MonoMix In"
2680};
2681
2682
2683SOC_ENUM_SINGLE_DECL(asi3rin_enum, ASI3_DAC_OUT_CNTL, 4, asi3rin_text);
2684static const struct snd_kcontrol_new asi3rin_control =
2685 SOC_DAPM_ENUM("ASI3RIN Route", asi3rin_enum);
2686
2687
2688static const char *dacminidspin1_text[] = {
2689 "ASI1 In", "ASI2 In","ASI3 In","ADC MiniDSP Out"
2690};
2691
2692SOC_ENUM_SINGLE_DECL(dacminidspin1_enum, MINIDSP_PORT_CNTL_REG, 4, dacminidspin1_text);
2693static const struct snd_kcontrol_new dacminidspin1_control =
2694 SOC_DAPM_ENUM("DAC MiniDSP IN1 Route", dacminidspin1_enum);
2695
2696static const char *dacminidspin2_text[] = {
2697 "ASI1 In", "ASI2 In","ASI3 In"
2698};
2699
2700//static const struct soc_enum dacminidspin1_enum =
2701// SOC_ENUM_SINGLE(MINIDSP_DATA_PORT_CNTL, 5, 2, dacminidspin1_text);
2702SOC_ENUM_SINGLE_DECL(dacminidspin2_enum, MINIDSP_PORT_CNTL_REG, 2, dacminidspin2_text);
2703
2704static const struct snd_kcontrol_new dacminidspin2_control =
2705 SOC_DAPM_ENUM("DAC MiniDSP IN2 Route", dacminidspin2_enum);
2706
2707static const char *dacminidspin3_text[] = {
2708 "ASI1 In", "ASI2 In","ASI3 In"
2709};
2710
2711//static const struct soc_enum dacminidspin1_enum =
2712// SOC_ENUM_SINGLE(MINIDSP_DATA_PORT_CNTL, 5, 2, dacminidspin1_text);
2713SOC_ENUM_SINGLE_DECL(dacminidspin3_enum, MINIDSP_PORT_CNTL_REG, 0, dacminidspin3_text);
2714
2715static const struct snd_kcontrol_new dacminidspin3_control =
2716SOC_DAPM_ENUM("DAC MiniDSP IN3 Route", dacminidspin3_enum);
2717
2718static const char *asi1out_text[] = {
2719 "Off",
2720 "ASI1 Out",
2721 "ASI1In Bypass",
2722 "ASI2In Bypass",
2723 "ASI3In Bypass",
2724};
2725SOC_ENUM_SINGLE_DECL(asi1out_enum, ASI1_ADC_INPUT_CNTL, 0, asi1out_text);
2726static const struct snd_kcontrol_new asi1out_control =
2727 SOC_DAPM_ENUM("ASI1OUT Route", asi1out_enum);
2728
2729static const char *asi2out_text[] = {
2730 "Off",
2731 "ASI1 Out",
2732 "ASI1In Bypass",
2733 "ASI2In Bypass",
2734 "ASI3In Bypass",
2735 "ASI2 Out",
2736};
2737SOC_ENUM_SINGLE_DECL(asi2out_enum, ASI2_ADC_INPUT_CNTL, 0, asi2out_text);
2738static const struct snd_kcontrol_new asi2out_control =
2739 SOC_DAPM_ENUM("ASI2OUT Route", asi2out_enum);
2740static const char *asi3out_text[] = {
2741 "Off",
2742 "ASI1 Out",
2743 "ASI1In Bypass",
2744 "ASI2In Bypass",
2745 "ASI3In Bypass",
2746 "ASI3 Out",
2747};
2748SOC_ENUM_SINGLE_DECL(asi3out_enum, ASI3_ADC_INPUT_CNTL, 0, asi3out_text);
2749static const struct snd_kcontrol_new asi3out_control =
2750 SOC_DAPM_ENUM("ASI3OUT Route", asi3out_enum);
2751
2752static const char *asi1bclk_text[] = {
2753 "DAC_CLK",
2754 "DAC_MOD_CLK",
2755 "ADC_CLK",
2756 "ADC_MOD_CLK",
2757};
2758
2759SOC_ENUM_SINGLE_DECL(asi1bclk_enum, ASI1_BCLK_N_CNTL, 0, asi1bclk_text);
2760static const struct snd_kcontrol_new asi1bclk_control =
2761 SOC_DAPM_ENUM("ASI1_BCLK Route", asi1bclk_enum);
2762
2763static const char *asi2bclk_text[] = {
2764 "DAC_CLK",
2765 "DAC_MOD_CLK",
2766 "ADC_CLK",
2767 "ADC_MOD_CLK",
2768};
2769SOC_ENUM_SINGLE_DECL(asi2bclk_enum, ASI2_BCLK_N_CNTL, 0, asi2bclk_text);
2770static const struct snd_kcontrol_new asi2bclk_control =
2771 SOC_DAPM_ENUM("ASI2_BCLK Route", asi2bclk_enum);
2772static const char *asi3bclk_text[] = {
2773 "DAC_CLK",
2774 "DAC_MOD_CLK",
2775 "ADC_CLK",
2776 "ADC_MOD_CLK",
2777};
2778SOC_ENUM_SINGLE_DECL(asi3bclk_enum, ASI3_BCLK_N_CNTL, 0, asi3bclk_text);
2779static const struct snd_kcontrol_new asi3bclk_control =
2780 SOC_DAPM_ENUM("ASI3_BCLK Route", asi3bclk_enum);
2781
2782static int aic326x_hp_event(struct snd_soc_dapm_widget *w,
2783 struct snd_kcontrol *kcontrol, int event)
2784{
2785 return 0;
2786}
2787static int pll_power_on_event(struct snd_soc_dapm_widget *w,
2788 struct snd_kcontrol *kcontrol, int event)
2789{
2790 if (event == SND_SOC_DAPM_POST_PMU)
2791 {
2792 mdelay(10);
2793 }
2794 return 0;
2795}
2796
2797static int polling_loop(struct snd_soc_codec *codec, unsigned int reg,
2798 int mask, int on_off)
2799{
2800 unsigned int counter, status;
2801
2802 counter = 0;
2803 switch(on_off) {
2804 case 0: /*off*/
2805 do {
2806 status = snd_soc_read(codec, reg);
2807 counter++;
2808 } while ((counter < 500) && ((status & mask) == mask));
2809 break;
2810 case 1: /*on*/
2811 do {
2812 status = snd_soc_read(codec, reg);
2813 counter++;
2814 } while ((counter < 500) && ((status & mask) != mask));
2815 break;
2816 default:
2817 printk("%s: unknown arguement\n", __func__);
2818 break;
2819 }
2820
2821 printk("%s: exiting with count value %d \n", __func__, counter);
2822 if(counter >= 500)
2823 return -1;
2824 return 0;
2825}
2826
2827int poll_dac(struct snd_soc_codec *codec, int left_right, int on_off)
2828{
2829 int ret = 0;
2830
2831 aic3262_change_page(codec, 0);
2832 aic3262_change_book(codec, 0);
2833
2834 switch(on_off) {
2835
2836 case 0:/*power off polling*/
2837 /*DAC power polling logic*/
2838 switch(left_right) {
2839 case 0: /*left dac polling*/
2840 ret = polling_loop(codec, DAC_FLAG_R1, LDAC_POW_FLAG_MASK, 0);
2841 break;
2842 case 1:/*right dac polling*/
2843 ret = polling_loop(codec, DAC_FLAG_R1, RDAC_POW_FLAG_MASK, 0);
2844 break;
2845 }
2846 break;
2847 case 1:/*power on polling*/
2848 /*DAC power polling logic*/
2849 switch(left_right) {
2850 case 0: /*left dac polling*/
2851 ret = polling_loop(codec, DAC_FLAG_R1, LDAC_POW_FLAG_MASK, 1);
2852 break;
2853 case 1:/*right dac polling*/
2854 ret = polling_loop(codec, DAC_FLAG_R1, RDAC_POW_FLAG_MASK, 1);
2855 break;
2856 }
2857 break;
2858 default:
2859 printk("%s:unknown arguement\n", __func__);
2860 break;
2861 }
2862 if(ret)
2863 printk("%s: power %s %s failure", __func__, left_right?"right":"left", on_off?"on":"off");
2864 return ret;
2865}
2866
2867int poll_adc(struct snd_soc_codec *codec, int left_right, int on_off)
2868{
2869 int ret = 0;
2870
2871 aic3262_change_page(codec, 0);
2872 aic3262_change_book(codec, 0);
2873
2874 switch(on_off) {
2875
2876 case 0:/*power off polling*/
2877 /*DAC power polling logic*/
2878 switch(left_right) {
2879 case 0: /*left dac polling*/
2880 ret = polling_loop(codec, ADC_FLAG_R1, LADC_POW_FLAG_MASK, 0);
2881 break;
2882 case 1:/*right dac polling*/
2883 ret = polling_loop(codec, ADC_FLAG_R1, RADC_POW_FLAG_MASK, 0);
2884 break;
2885 }
2886 break;
2887 case 1:/*power on polling*/
2888 /*DAC power polling logic*/
2889 switch(left_right) {
2890 case 0: /*left dac polling*/
2891 ret = polling_loop(codec, ADC_FLAG_R1, LADC_POW_FLAG_MASK, 1);
2892 break;
2893 case 1:/*right dac polling*/
2894 ret = polling_loop(codec, ADC_FLAG_R1, RADC_POW_FLAG_MASK, 1);
2895 break;
2896 }
2897 break;
2898 default:
2899 printk("%s:unknown arguement\n", __func__);
2900 break;
2901 }
2902
2903 if(ret)
2904 printk("%s: power %s %s failure", __func__, left_right?"right":"left", on_off?"on":"off");
2905 return ret;
2906}
2907
2908static int slave_dac_event(struct snd_soc_dapm_widget *w,
2909 struct snd_kcontrol *kcontrol, int event)
2910
2911{
2912 struct snd_soc_codec *codec = w->codec;
2913
2914 if (event & SND_SOC_DAPM_POST_PMU) {
2915 /* Poll for DAC Power-up first */
2916 poll_dac(codec, 0, 1);
2917 poll_dac(codec, 1, 1);
2918 }
2919
2920 if (event & SND_SOC_DAPM_POST_PMD) {
2921 poll_dac(codec, 0, 0);
2922 poll_dac(codec, 1, 0);
2923 }
2924 return 0;
2925}
2926
2927
2928static int slave_adc_event(struct snd_soc_dapm_widget *w,
2929 struct snd_kcontrol *kcontrol, int event)
2930
2931{
2932 struct snd_soc_codec *codec = w->codec;
2933
2934 if (event & SND_SOC_DAPM_POST_PMU) {
2935
2936 /* Poll for ADC Power-up first */
2937 poll_adc(codec, 0, 1);
2938 poll_adc(codec, 1, 1);
2939 }
2940
2941
2942 if (event & SND_SOC_DAPM_POST_PMD) {
2943 poll_adc(codec, 0, 0);
2944 poll_adc(codec, 1, 0);
2945 }
2946
2947 return 0;
2948}
2949
2950static const struct snd_soc_dapm_widget aic3262_dapm_widgets[] = {
2951 /* TODO: Can we switch these off ? */
2952 SND_SOC_DAPM_AIF_IN("ASI1IN", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
2953 SND_SOC_DAPM_AIF_IN("ASI2IN", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0),
2954 SND_SOC_DAPM_AIF_IN("ASI3IN", "ASI3 Playback", 0, SND_SOC_NOPM, 0, 0),
2955
2956
2957 SND_SOC_DAPM_DAC_E("Left DAC", NULL, PASI_DAC_DP_SETUP, 7, 0,
2958 slave_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD |
2959 SND_SOC_DAPM_PRE_PMD),
2960 SND_SOC_DAPM_DAC_E("Right DAC", NULL, PASI_DAC_DP_SETUP, 6, 0,
2961 slave_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD |
2962 SND_SOC_DAPM_PRE_PMD),
2963
2964 /* dapm widget (path domain) for HPL Output Mixer */
2965 SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
2966 &hpl_output_mixer_controls[0],
2967 ARRAY_SIZE(hpl_output_mixer_controls)),
2968
2969 /* dapm widget (path domain) for HPR Output Mixer */
2970 SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
2971 &hpr_output_mixer_controls[0],
2972 ARRAY_SIZE(hpr_output_mixer_controls)),
2973
2974
2975 SND_SOC_DAPM_PGA_E("HPL Driver", HP_AMP_CNTL_R1, 1, 0, NULL, 0,
2976 aic326x_hp_event, SND_SOC_DAPM_POST_PMU),
2977 SND_SOC_DAPM_PGA_E("HPR Driver", HP_AMP_CNTL_R1, 0, 0, NULL, 0,
2978 aic326x_hp_event, SND_SOC_DAPM_POST_PMU),
2979
2980
2981 /* dapm widget (path domain) for LOL Output Mixer */
2982 SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
2983 &lol_output_mixer_controls[0],
2984 ARRAY_SIZE(lol_output_mixer_controls)),
2985
2986 /* dapm widget (path domain) for LOR Output Mixer mixer */
2987 SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
2988 &lor_output_mixer_controls[0],
2989 ARRAY_SIZE(lor_output_mixer_controls)),
2990
2991 SND_SOC_DAPM_PGA("LOL Driver", LINE_AMP_CNTL_R1, 1, 0, NULL, 0),
2992 SND_SOC_DAPM_PGA("LOR Driver", LINE_AMP_CNTL_R1, 0, 0, NULL, 0),
2993
2994
2995 /* dapm widget (path domain) for SPKL Output Mixer */
2996 SND_SOC_DAPM_MIXER("SPKL Output Mixer", SND_SOC_NOPM, 0, 0,
2997 &spkl_output_mixer_controls[0],
2998 ARRAY_SIZE(spkl_output_mixer_controls)),
2999
3000 /* dapm widget (path domain) for SPKR Output Mixer */
3001 SND_SOC_DAPM_MIXER("SPKR Output Mixer", SND_SOC_NOPM, 0, 0,
3002 &spkr_output_mixer_controls[0],
3003 ARRAY_SIZE(spkr_output_mixer_controls)),
3004
3005 SND_SOC_DAPM_PGA("SPKL Driver", SPK_AMP_CNTL_R1, 1, 0, NULL, 0),
3006 SND_SOC_DAPM_PGA("SPKR Driver", SPK_AMP_CNTL_R1, 0, 0, NULL, 0),
3007
3008
3009 /* dapm widget (path domain) for SPKR Output Mixer */
3010 SND_SOC_DAPM_MIXER("REC Output Mixer", SND_SOC_NOPM, 0, 0,
3011 &rec_output_mixer_controls[0],
3012 ARRAY_SIZE(rec_output_mixer_controls)),
3013
3014 SND_SOC_DAPM_PGA("RECP Driver", REC_AMP_CNTL_R5, 7, 0, NULL, 0),
3015 SND_SOC_DAPM_PGA("RECM Driver", REC_AMP_CNTL_R5, 6, 0, NULL, 0),
3016
3017
3018 SND_SOC_DAPM_MUX("ASI1LIN Route",
3019 SND_SOC_NOPM, 0, 0, &asi1lin_control),
3020 SND_SOC_DAPM_MUX("ASI1RIN Route",
3021 SND_SOC_NOPM, 0, 0, &asi1rin_control),
3022 SND_SOC_DAPM_MUX("ASI2LIN Route",
3023 SND_SOC_NOPM, 0, 0, &asi2lin_control),
3024 SND_SOC_DAPM_MUX("ASI2RIN Route",
3025 SND_SOC_NOPM, 0, 0, &asi2rin_control),
3026 SND_SOC_DAPM_MUX("ASI3LIN Route",
3027 SND_SOC_NOPM, 0, 0, &asi3lin_control),
3028 SND_SOC_DAPM_MUX("ASI3RIN Route",
3029 SND_SOC_NOPM, 0, 0, &asi3rin_control),
3030
3031 SND_SOC_DAPM_PGA("ASI1LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3032 SND_SOC_DAPM_PGA("ASI1RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3033 SND_SOC_DAPM_PGA("ASI2LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3034 SND_SOC_DAPM_PGA("ASI2RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3035 SND_SOC_DAPM_PGA("ASI3LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3036 SND_SOC_DAPM_PGA("ASI3RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3037
3038 SND_SOC_DAPM_PGA("ASI1LOUT", SND_SOC_NOPM, 0, 0, NULL, 0),
3039 SND_SOC_DAPM_PGA("ASI1ROUT", SND_SOC_NOPM, 0, 0, NULL, 0),
3040 SND_SOC_DAPM_PGA("ASI2LOUT", SND_SOC_NOPM, 0, 0, NULL, 0),
3041 SND_SOC_DAPM_PGA("ASI2ROUT", SND_SOC_NOPM, 0, 0, NULL, 0),
3042 SND_SOC_DAPM_PGA("ASI3LOUT", SND_SOC_NOPM, 0, 0, NULL, 0),
3043 SND_SOC_DAPM_PGA("ASI3ROUT", SND_SOC_NOPM, 0, 0, NULL, 0),
3044
3045 SND_SOC_DAPM_PGA("ASI1MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3046 SND_SOC_DAPM_PGA("ASI2MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3047 SND_SOC_DAPM_PGA("ASI3MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
3048 /* TODO: Can we switch the ASIxIN off? */
3049 SND_SOC_DAPM_PGA("ASI1IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
3050 SND_SOC_DAPM_PGA("ASI2IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
3051 SND_SOC_DAPM_PGA("ASI3IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
3052
3053
3054 SND_SOC_DAPM_MUX("DAC MiniDSP IN1 Route",
3055 SND_SOC_NOPM, 0, 0, &dacminidspin1_control),
3056SND_SOC_DAPM_MUX("DAC MiniDSP IN2 Route",
3057 SND_SOC_NOPM, 0, 0, &dacminidspin2_control),
3058 SND_SOC_DAPM_MUX("DAC MiniDSP IN3 Route",
3059 SND_SOC_NOPM, 0, 0, &dacminidspin3_control),
3060
3061 SND_SOC_DAPM_PGA("CM", SND_SOC_NOPM, 0, 0, NULL, 0),
3062 SND_SOC_DAPM_PGA("CM1L", SND_SOC_NOPM, 0, 0, NULL, 0),
3063 SND_SOC_DAPM_PGA("CM2L", SND_SOC_NOPM, 0, 0, NULL, 0),
3064 SND_SOC_DAPM_PGA("CM1R", SND_SOC_NOPM, 0, 0, NULL, 0),
3065 SND_SOC_DAPM_PGA("CM2R", SND_SOC_NOPM, 0, 0, NULL, 0),
3066
3067 /* TODO: Can we switch these off ? */
3068 SND_SOC_DAPM_AIF_OUT("ASI1OUT","ASI1 Capture", 0, SND_SOC_NOPM, 0, 0),
3069 SND_SOC_DAPM_AIF_OUT("ASI2OUT", "ASI2 Capture",0, SND_SOC_NOPM, 0, 0),
3070 SND_SOC_DAPM_AIF_OUT("ASI3OUT", "ASI3 Capture",0, SND_SOC_NOPM, 0, 0),
3071
3072 SND_SOC_DAPM_MUX("ASI1OUT Route",
3073 SND_SOC_NOPM, 0, 0, &asi1out_control),
3074 SND_SOC_DAPM_MUX("ASI2OUT Route",
3075 SND_SOC_NOPM, 0, 0, &asi2out_control),
3076 SND_SOC_DAPM_MUX("ASI3OUT Route",
3077 SND_SOC_NOPM, 0, 0, &asi3out_control),
3078
3079 /* TODO: Will be used during MINIDSP programming */
3080 /* TODO: Can we switch them off? */
3081 SND_SOC_DAPM_PGA("ADC MiniDSP OUT1", SND_SOC_NOPM, 0, 0, NULL, 0),
3082 SND_SOC_DAPM_PGA("ADC MiniDSP OUT2", SND_SOC_NOPM, 0, 0, NULL, 0),
3083 SND_SOC_DAPM_PGA("ADC MiniDSP OUT3", SND_SOC_NOPM, 0, 0, NULL, 0),
3084
3085
3086
3087 SND_SOC_DAPM_ADC_E("Left ADC", NULL, ADC_CHANNEL_POW, 7, 0,
3088 slave_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD |
3089 SND_SOC_DAPM_PRE_PMD),
3090 SND_SOC_DAPM_ADC_E("Right ADC", NULL, ADC_CHANNEL_POW, 6, 0,
3091 slave_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD |
3092 SND_SOC_DAPM_PRE_PMD),
3093
3094 SND_SOC_DAPM_PGA("Left MicPGA",MICL_PGA, 7, 1, NULL, 0),
3095 SND_SOC_DAPM_PGA("Right MicPGA",MICR_PGA, 7, 1, NULL, 0),
3096
3097 SND_SOC_DAPM_PGA("MAL PGA", MA_CNTL, 3, 0, NULL, 0),
3098 SND_SOC_DAPM_PGA("MAR PGA", MA_CNTL, 2, 0, NULL, 0),
3099
3100
3101 /* dapm widget for MAL PGA Mixer*/
3102 SND_SOC_DAPM_MIXER("MAL PGA Mixer", SND_SOC_NOPM, 0, 0,
3103 &mal_pga_mixer_controls[0],
3104 ARRAY_SIZE(mal_pga_mixer_controls)),
3105
3106 /* dapm widget for MAR PGA Mixer*/
3107 SND_SOC_DAPM_MIXER("MAR PGA Mixer", SND_SOC_NOPM, 0, 0,
3108 &mar_pga_mixer_controls[0],
3109 ARRAY_SIZE(mar_pga_mixer_controls)),
3110
3111 /* dapm widget for Left Input Mixer*/
3112 SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
3113 &left_input_mixer_controls[0],
3114 ARRAY_SIZE(left_input_mixer_controls)),
3115
3116 /* dapm widget for Right Input Mixer*/
3117 SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
3118 &right_input_mixer_controls[0],
3119 ARRAY_SIZE(right_input_mixer_controls)),
3120
3121
3122 SND_SOC_DAPM_OUTPUT("HPL"),
3123 SND_SOC_DAPM_OUTPUT("HPR"),
3124 SND_SOC_DAPM_OUTPUT("LOL"),
3125 SND_SOC_DAPM_OUTPUT("LOR"),
3126 SND_SOC_DAPM_OUTPUT("SPKL"),
3127 SND_SOC_DAPM_OUTPUT("SPKR"),
3128 SND_SOC_DAPM_OUTPUT("RECP"),
3129 SND_SOC_DAPM_OUTPUT("RECM"),
3130
3131 SND_SOC_DAPM_INPUT("IN1L"),
3132 SND_SOC_DAPM_INPUT("IN2L"),
3133 SND_SOC_DAPM_INPUT("IN3L"),
3134 SND_SOC_DAPM_INPUT("IN4L"),
3135 SND_SOC_DAPM_INPUT("IN1R"),
3136 SND_SOC_DAPM_INPUT("IN2R"),
3137 SND_SOC_DAPM_INPUT("IN3R"),
3138 SND_SOC_DAPM_INPUT("IN4R"),
3139
3140
3141 SND_SOC_DAPM_MICBIAS("Mic Bias Ext", MIC_BIAS_CNTL, 6, 0),
3142 SND_SOC_DAPM_MICBIAS("Mic Bias Int", MIC_BIAS_CNTL, 2, 0),
3143
3144 SND_SOC_DAPM_SUPPLY("PLLCLK",PLL_PR_POW_REG,7,0,pll_power_on_event,
3145 SND_SOC_DAPM_POST_PMU),
3146 SND_SOC_DAPM_SUPPLY("DACCLK",NDAC_DIV_POW_REG,7,0, NULL, 0),
3147 SND_SOC_DAPM_SUPPLY("CODEC_CLK_IN",SND_SOC_NOPM,0,0, NULL, 0),
3148 SND_SOC_DAPM_SUPPLY("DAC_MOD_CLK",MDAC_DIV_POW_REG,7,0, NULL, 0),
3149 SND_SOC_DAPM_SUPPLY("ADCCLK",NADC_DIV_POW_REG,7,0, NULL, 0),
3150 SND_SOC_DAPM_SUPPLY("ADC_MOD_CLK",MADC_DIV_POW_REG,7,0, NULL, 0),
3151 SND_SOC_DAPM_SUPPLY("ASI1_BCLK",ASI1_BCLK_N,7,0, NULL, 0),
3152 SND_SOC_DAPM_SUPPLY("ASI1_WCLK",ASI1_WCLK_N,7,0, NULL, 0),
3153 SND_SOC_DAPM_SUPPLY("ASI2_BCLK",ASI2_BCLK_N,7,0, NULL, 0),
3154 SND_SOC_DAPM_SUPPLY("ASI2_WCLK",ASI2_WCLK_N,7,0, NULL, 0),
3155 SND_SOC_DAPM_SUPPLY("ASI3_BCLK",ASI3_BCLK_N,7,0, NULL, 0),
3156 SND_SOC_DAPM_SUPPLY("ASI3_WCLK",ASI3_WCLK_N,7,0, NULL, 0),
3157 SND_SOC_DAPM_MUX("ASI1_BCLK Route",
3158 SND_SOC_NOPM, 0, 0, &asi1bclk_control),
3159 SND_SOC_DAPM_MUX("ASI2_BCLK Route", SND_SOC_NOPM, 0, 0, &asi2bclk_control),
3160 SND_SOC_DAPM_MUX("ASI3_BCLK Route", SND_SOC_NOPM, 0, 0, &asi3bclk_control),
3161};
3162
3163static const struct snd_soc_dapm_route aic3262_dapm_routes[] ={
3164 /* TODO: Do we need only DACCLK for ASIIN's and ADCCLK for ASIOUT??? */
3165 /* Clock portion */
3166 {"CODEC_CLK_IN", NULL, "PLLCLK"},
3167 {"DACCLK", NULL, "CODEC_CLK_IN"},
3168 {"ADCCLK", NULL, "CODEC_CLK_IN"},
3169 {"DAC_MOD_CLK", NULL, "DACCLK"},
3170#ifdef AIC3262_SYNC_MODE
3171 {"ADC_MOD_CLK", NULL,"DACCLK"},
3172#else
3173 {"ADC_MOD_CLK", NULL, "ADCCLK"},
3174#endif
3175
3176 {"ASI1_BCLK Route","DAC_CLK","DACCLK"},
3177 {"ASI1_BCLK Route","DAC_MOD_CLK","DAC_MOD_CLK"},
3178 {"ASI1_BCLK Route","ADC_CLK","ADCCLK"},
3179 {"ASI1_BCLK Route","ADC_MOD_CLK","ADC_MOD_CLK"},
3180
3181 {"ASI2_BCLK Route","DAC_CLK","DACCLK"},
3182 {"ASI2_BCLK Route","DAC_MOD_CLK","DAC_MOD_CLK"},
3183 {"ASI2_BCLK Route","ADC_CLK","ADCCLK"},
3184 {"ASI2_BCLK Route","ADC_MOD_CLK","ADC_MOD_CLK"},
3185
3186 {"ASI3_BCLK Route","DAC_CLK","DACCLK"},
3187 {"ASI3_BCLK Route","DAC_MOD_CLK","DAC_MOD_CLK"},
3188 {"ASI3_BCLK Route","ADC_CLK","ADCCLK"},
3189 {"ASI3_BCLK Route","ADC_MOD_CLK","ADC_MOD_CLK"},
3190
3191 {"ASI1_BCLK", NULL, "ASI1_BCLK Route"},
3192 {"ASI2_BCLK", NULL, "ASI2_BCLK Route"},
3193 {"ASI3_BCLK", NULL, "ASI3_BCLK Route"},
3194
3195
3196 {"ASI1IN", NULL , "PLLCLK"},
3197 {"ASI1IN", NULL , "DACCLK"},
3198 {"ASI1IN", NULL , "ADCCLK"},
3199 {"ASI1IN", NULL , "DAC_MOD_CLK"},
3200 {"ASI1IN", NULL , "ADC_MOD_CLK"},
3201
3202 {"ASI1OUT", NULL , "PLLCLK"},
3203 {"ASI1OUT", NULL , "DACCLK"},
3204 {"ASI1OUT", NULL , "ADCCLK"},
3205 {"ASI1OUT", NULL , "DAC_MOD_CLK"},
3206 {"ASI1OUT", NULL , "ADC_MOD_CLK"},
3207#ifdef AIC3262_ASI1_MASTER
3208 {"ASI1IN", NULL , "ASI1_BCLK"},
3209 {"ASI1OUT", NULL , "ASI1_BCLK"},
3210 {"ASI1IN", NULL , "ASI1_WCLK"},
3211 {"ASI1OUT", NULL , "ASI1_WCLK"},
3212#else
3213
3214#endif
3215
3216 {"ASI2IN", NULL , "PLLCLK"},
3217 {"ASI2IN", NULL , "DACCLK"},
3218 {"ASI2IN", NULL , "ADCCLK"},
3219 {"ASI2IN", NULL , "DAC_MOD_CLK"},
3220 {"ASI2IN", NULL , "ADC_MOD_CLK"},
3221
3222 {"ASI2OUT", NULL , "PLLCLK"},
3223 {"ASI2OUT", NULL , "DACCLK"},
3224 {"ASI2OUT", NULL , "ADCCLK"},
3225 {"ASI2OUT", NULL , "DAC_MOD_CLK"},
3226 {"ASI2OUT", NULL , "ADC_MOD_CLK"},
3227
3228#ifdef AIC3262_ASI2_MASTER
3229 {"ASI2IN", NULL , "ASI2_BCLK"},
3230 {"ASI2OUT", NULL , "ASI2_BCLK"},
3231 {"ASI2IN", NULL , "ASI2_WCLK"},
3232 {"ASI2OUT", NULL , "ASI2_WCLK"},
3233#else
3234
3235#endif
3236 {"ASI3IN", NULL , "PLLCLK"},
3237 {"ASI3IN", NULL , "DACCLK"},
3238 {"ASI3IN", NULL , "ADCCLK"},
3239 {"ASI3IN", NULL , "DAC_MOD_CLK"},
3240 {"ASI3IN", NULL , "ADC_MOD_CLK"},
3241
3242
3243 {"ASI3OUT", NULL , "PLLCLK"},
3244 {"ASI3OUT", NULL , "DACCLK"},
3245 {"ASI3OUT", NULL , "ADCCLK"},
3246 {"ASI3OUT", NULL , "DAC_MOD_CLK"},
3247 {"ASI3OUT", NULL , "ADC_MOD_CLK"},
3248
3249#ifdef AIC3262_ASI3_MASTER
3250 {"ASI3IN", NULL , "ASI3_BCLK"},
3251 {"ASI3OUT", NULL , "ASI3_BCLK"},
3252 {"ASI3IN", NULL , "ASI3_WCLK"},
3253 {"ASI3OUT", NULL , "ASI3_WCLK"},
3254#else
3255#endif
3256
3257/* Playback (DAC) Portion */
3258 {"HPL Output Mixer","LDAC Switch","Left DAC"},
3259 {"HPL Output Mixer","MAL Switch","MAL PGA"},
3260 {"HPL Output Mixer","LOL-B1 Volume","LOL"},
3261
3262 {"HPR Output Mixer","LOR-B1 Volume","LOR"},
3263 {"HPR Output Mixer","LDAC Switch","Left DAC"},
3264 {"HPR Output Mixer","RDAC Switch","Right DAC"},
3265 {"HPR Output Mixer","MAR Switch","MAR PGA"},
3266
3267 {"HPL Driver",NULL,"HPL Output Mixer"},
3268 {"HPR Driver",NULL,"HPR Output Mixer"},
3269
3270 {"HPL",NULL,"HPL Driver"},
3271 {"HPR",NULL,"HPR Driver"},
3272
3273 {"LOL Output Mixer","MAL Switch","MAL PGA"},
3274 {"LOL Output Mixer","IN1L-B Switch","IN1L"},
3275 {"LOL Output Mixer","LDAC Switch","Left DAC"},
3276 {"LOL Output Mixer","RDAC Switch","Right DAC"},
3277
3278 {"LOR Output Mixer","LOL Switch","LOL"},
3279 {"LOR Output Mixer","RDAC Switch","Right DAC"},
3280 {"LOR Output Mixer","MAR Switch","MAR PGA"},
3281 {"LOR Output Mixer","IN1R-B Switch","IN1R"},
3282
3283 {"LOL Driver",NULL,"LOL Output Mixer"},
3284 {"LOR Driver",NULL,"LOR Output Mixer"},
3285
3286 {"LOL",NULL,"LOL Driver"},
3287 {"LOR",NULL,"LOR Driver"},
3288
3289 {"REC Output Mixer","LOL-B2 Volume","LOL"},
3290 {"REC Output Mixer","IN1L Volume","IN1L"},
3291 {"REC Output Mixer","IN1R Volume","IN1R"},
3292 {"REC Output Mixer","LOR-B2 Volume","LOR"},
3293
3294 {"RECP Driver",NULL,"REC Output Mixer"},
3295 {"RECM Driver",NULL,"REC Output Mixer"},
3296
3297 {"RECP",NULL,"RECP Driver"},
3298 {"RECM",NULL,"RECM Driver"},
3299
3300 {"SPKL Output Mixer","MAL Switch","MAL PGA"},
3301 {"SPKL Output Mixer","LOL Volume","LOL"},
3302 {"SPKL Output Mixer","SPR_IN Switch","SPKR Output Mixer"},
3303
3304 {"SPKR Output Mixer", "LOR Volume","LOR"},
3305 {"SPKR Output Mixer", "MAR Switch","MAR PGA"},
3306
3307
3308 {"SPKL Driver",NULL,"SPKL Output Mixer"},
3309 {"SPKR Driver",NULL,"SPKR Output Mixer"},
3310
3311 {"SPKL",NULL,"SPKL Driver"},
3312 {"SPKR",NULL,"SPKR Driver"},
3313/* ASI Input routing */
3314 {"ASI1LIN", NULL, "ASI1IN"},
3315 {"ASI1RIN", NULL, "ASI1IN"},
3316 {"ASI2LIN", NULL, "ASI2IN"},
3317 {"ASI2RIN", NULL, "ASI2IN"},
3318 {"ASI3LIN", NULL, "ASI3IN"},
3319 {"ASI3RIN", NULL, "ASI3IN"},
3320
3321 {"ASI1MonoMixIN", NULL, "ASI1IN"},
3322 {"ASI2MonoMixIN", NULL, "ASI2IN"},
3323 {"ASI3MonoMixIN", NULL, "ASI3IN"},
3324
3325 {"ASI1LIN Route","ASI1 Left In","ASI1LIN"},
3326 {"ASI1LIN Route","ASI1 Right In","ASI1RIN"},
3327 {"ASI1LIN Route","ASI1 MonoMix In","ASI1MonoMixIN"},
3328
3329 {"ASI1RIN Route", "ASI1 Right In","ASI1RIN"},
3330 {"ASI1RIN Route","ASI1 Left In","ASI1LIN"},
3331 {"ASI1RIN Route","ASI1 MonoMix In","ASI1MonoMixIN"},
3332
3333
3334 {"ASI2LIN Route","ASI2 Left In","ASI2LIN"},
3335 {"ASI2LIN Route","ASI2 Right In","ASI2RIN"},
3336 {"ASI2LIN Route","ASI2 MonoMix In","ASI2MonoMixIN"},
3337
3338 {"ASI2RIN Route","ASI2 Right In","ASI2RIN"},
3339 {"ASI2RIN Route","ASI2 Left In","ASI2LIN"},
3340 {"ASI2RIN Route","ASI2 MonoMix In","ASI2MonoMixIN"},
3341
3342
3343 {"ASI3LIN Route","ASI3 Left In","ASI3LIN"},
3344 {"ASI3LIN Route","ASI3 Right In","ASI3RIN"},
3345 {"ASI3LIN Route","ASI3 MonoMix In","ASI3MonoMixIN"},
3346
3347 {"ASI3RIN Route","ASI3 Right In","ASI3RIN"},
3348 {"ASI3RIN Route","ASI3 Left In","ASI3LIN"},
3349 {"ASI3RIN Route","ASI3 MonoMix In","ASI3MonoMixIN"},
3350
3351 {"ASI1IN Port", NULL, "ASI1LIN Route"},
3352 {"ASI1IN Port", NULL, "ASI1RIN Route"},
3353 {"ASI2IN Port", NULL, "ASI2LIN Route"},
3354 {"ASI2IN Port", NULL, "ASI2RIN Route"},
3355 {"ASI3IN Port", NULL, "ASI3LIN Route"},
3356 {"ASI3IN Port", NULL, "ASI3RIN Route"},
3357
3358 {"DAC MiniDSP IN1 Route", "ASI1 In","ASI1IN Port"},
3359 {"DAC MiniDSP IN1 Route","ASI2 In","ASI2IN Port"},
3360 {"DAC MiniDSP IN1 Route","ASI3 In","ASI3IN Port"},
3361 {"DAC MiniDSP IN1 Route","ADC MiniDSP Out","ADC MiniDSP OUT1"},
3362
3363 {"DAC MiniDSP IN2 Route","ASI1 In","ASI1IN Port"},
3364 {"DAC MiniDSP IN2 Route","ASI2 In","ASI2IN Port"},
3365 {"DAC MiniDSP IN2 Route","ASI3 In","ASI3IN Port"},
3366
3367 {"DAC MiniDSP IN3 Route","ASI1 In","ASI1IN Port"},
3368 {"DAC MiniDSP IN3 Route","ASI2 In","ASI2IN Port"},
3369 {"DAC MiniDSP IN3 Route","ASI3 In","ASI3IN Port"},
3370
3371 {"Left DAC", "NULL", "DAC MiniDSP IN1 Route"},
3372 {"Right DAC", "NULL", "DAC MiniDSP IN1 Route"},
3373
3374 {"Left DAC", "NULL","DAC MiniDSP IN2 Route"},
3375 {"Right DAC", "NULL","DAC MiniDSP IN2 Route"},
3376
3377 {"Left DAC", "NULL","DAC MiniDSP IN3 Route"},
3378 {"Right DAC", "NULL","DAC MiniDSP IN3 Route"},
3379
3380
3381/* Mixer Amplifier */
3382
3383 {"MAL PGA Mixer", "IN1L Switch","IN1L"},
3384 {"MAL PGA Mixer", "Left MicPGA Volume","Left MicPGA"},
3385
3386 {"MAL PGA", NULL, "MAL PGA Mixer"},
3387
3388
3389 {"MAR PGA Mixer", "IN1R Switch","IN1R"},
3390 {"MAR PGA Mixer", "Right MicPGA Volume","Right MicPGA"},
3391
3392 {"MAR PGA", NULL, "MAR PGA Mixer"},
3393
3394
3395/* Capture (ADC) portions */
3396 /* Left Positive PGA input */
3397 {"Left Input Mixer","IN1L Switch","IN1L"},
3398 {"Left Input Mixer","IN2L Switch","IN2L"},
3399 {"Left Input Mixer","IN3L Switch","IN3L"},
3400 {"Left Input Mixer","IN4L Switch","IN4L"},
3401 {"Left Input Mixer","IN1R Switch","IN1R"},
3402 /* Left Negative PGA input */
3403 {"Left Input Mixer","IN2R Switch","IN2R"},
3404 {"Left Input Mixer","IN3R Switch","IN3R"},
3405 {"Left Input Mixer","IN4R Switch","IN4R"},
3406 {"Left Input Mixer","CM2L Switch","CM2L"},
3407 {"Left Input Mixer","CM1L Switch","CM1L"},
3408
3409 /* Right Positive PGA Input */
3410 {"Right Input Mixer","IN1R Switch","IN1R"},
3411 {"Right Input Mixer","IN2R Switch","IN2R"},
3412 {"Right Input Mixer","IN3R Switch","IN3R"},
3413 {"Right Input Mixer","IN4R Switch","IN4R"},
3414 {"Right Input Mixer","IN2L Switch","IN2L"},
3415
3416 /* Right Negative PGA Input */
3417 {"Right Input Mixer","IN1L Switch","IN1L"},
3418 {"Right Input Mixer","IN3L Switch","IN3L"},
3419 {"Right Input Mixer","IN4L Switch","IN4L"},
3420 {"Right Input Mixer","CM1R Switch","CM1R"},
3421 {"Right Input Mixer","CM2R Switch","CM2R"},
3422
3423 {"CM1L", NULL, "CM"},
3424 {"CM2L", NULL, "CM"},
3425 {"CM1R", NULL, "CM"},
3426 {"CM2R", NULL, "CM"},
3427
3428 {"Left MicPGA",NULL,"Left Input Mixer"},
3429 {"Right MicPGA",NULL,"Right Input Mixer"},
3430
3431 {"Left ADC", NULL, "Left MicPGA"},
3432 {"Right ADC", NULL, "Right MicPGA"},
3433
3434/* ASI Output Routing */
3435 {"ADC MiniDSP OUT1", NULL, "Left ADC"},
3436 {"ADC MiniDSP OUT1", NULL, "Right ADC"},
3437 {"ADC MiniDSP OUT2", NULL, "Left ADC"},
3438 {"ADC MiniDSP OUT2", NULL, "Right ADC"},
3439 {"ADC MiniDSP OUT3", NULL, "Left ADC"},
3440 {"ADC MiniDSP OUT3", NULL, "Right ADC"},
3441
3442 {"ASI1OUT Route", "ASI1 Out","ADC MiniDSP OUT1"},// Port 1
3443 {"ASI1OUT Route", "ASI1In Bypass","ASI1IN Port"},
3444 {"ASI1OUT Route", "ASI2In Bypass","ASI2IN Port"},
3445 {"ASI1OUT Route", "ASI3In Bypass","ASI3IN Port"},
3446
3447 {"ASI2OUT Route", "ASI1 Out","ADC MiniDSP OUT1"},// Port 1
3448 {"ASI2OUT Route", "ASI1In Bypass","ASI1IN Port"},
3449 {"ASI2OUT Route", "ASI2In Bypass","ASI2IN Port"},
3450 {"ASI2OUT Route", "ASI3In Bypass","ASI3IN Port"},
3451 {"ASI2OUT Route", "ASI2 Out","ADC MiniDSP OUT2"},// Port 2
3452
3453 {"ASI3OUT Route", "ASI1 Out","ADC MiniDSP OUT1"},// Port 1
3454 {"ASI3OUT Route", "ASI1In Bypass","ASI1IN Port"},
3455 {"ASI3OUT Route", "ASI2In Bypass","ASI2IN Port"},
3456 {"ASI3OUT Route", "ASI3In Bypass","ASI3IN Port"},
3457 {"ASI3OUT Route", "ASI3 Out","ADC MiniDSP OUT3"},// Port 3
3458
3459 {"ASI1OUT",NULL,"ASI1OUT Route"},
3460 {"ASI2OUT",NULL,"ASI2OUT Route"},
3461 {"ASI3OUT",NULL,"ASI3OUT Route"},
3462
3463};
3464
3465
3466#define AIC3262_DAPM_ROUTE_NUM (sizeof(aic3262_dapm_routes)/sizeof(struct snd_soc_dapm_route))
3467
3468/*
3469 *****************************************************************************
3470 * Function Definitions
3471 *****************************************************************************
3472 */
3473
3474
3475/*
3476 *----------------------------------------------------------------------------
3477 * Function : aic3262_change_page
3478 * Purpose : This function is to switch between page 0 and page 1.
3479 *
3480 *----------------------------------------------------------------------------
3481 */
3482int aic3262_change_page(struct snd_soc_codec *codec, u8 new_page)
3483{
3484 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
3485 u8 data[2];
3486 int ret = 0;
3487
3488 data[0] = 0;
3489 data[1] = new_page;
3490 aic3262->page_no = new_page;
3491
3492#if defined(LOCAL_REG_ACCESS)
3493 if (codec->hw_write(codec->control_data, data, 2) != 2)
3494 ret = -EIO;
3495#else
3496 ret = snd_soc_write(codec, data[0], data[1]);
3497#endif
3498 if (ret)
3499 printk(KERN_ERR "Error in changing page to %d\n", new_page);
3500
3501 /*DBG("# Changing page to %d\r\n", new_page);*/
3502
3503 return ret;
3504}
3505/*
3506 *----------------------------------------------------------------------------
3507 * Function : aic3262_change_book
3508 * Purpose : This function is to switch between books
3509 *
3510 *----------------------------------------------------------------------------
3511 */
3512int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book)
3513{
3514 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
3515 u8 data[2];
3516 int ret = 0;
3517
3518 data[0] = 0x7F;
3519 data[1] = new_book;
3520 aic3262->book_no = new_book;
3521
3522 ret = aic3262_change_page(codec, 0);
3523 if (ret)
3524 return ret;
3525
3526#if defined(LOCAL_REG_ACCESS)
3527 if (codec->hw_write(codec->control_data, data, 2) != 2)
3528 ret = -EIO;
3529#else
3530 ret = snd_soc_write(codec, data[0], data[1]);
3531#endif
3532 if (ret)
3533 printk(KERN_ERR "Error in changing Book\n");
3534
3535 /*DBG("# Changing book to %d\r\n", new_book);*/
3536
3537 return ret;
3538}
3539/*
3540 *----------------------------------------------------------------------------
3541 * Function : aic3262_write_reg_cache
3542 * Purpose : This function is to write aic3262 register cache
3543 *
3544 *----------------------------------------------------------------------------
3545 */
3546void aic3262_write_reg_cache(struct snd_soc_codec *codec,
3547 u16 reg, u8 value)
3548{
3549#if defined(EN_REG_CACHE)
3550 u8 *cache = codec->reg_cache;
3551
3552 if (reg >= AIC3262_CACHEREGNUM)
3553 return;
3554
3555 if (cache)
3556 cache[reg] = value;
3557#endif
3558}
3559
3560/*
3561 *----------------------------------------------------------------------------
3562 * Function : aic3262_read
3563 * Purpose : This function is to read the aic3262 register space.
3564 *
3565 *----------------------------------------------------------------------------
3566 */
3567
3568u8 aic3262_read(struct snd_soc_codec *codec, u16 reg)
3569{
3570 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
3571 u8 value;
3572 u8 page = reg / 128;
3573 u16 *cache = codec->reg_cache;
3574 u16 cmd;
3575 u8 buffer[2];
3576 int rc;
3577 reg = reg % 128;
3578
3579 if (reg >= AIC3262_CACHEREGNUM) {
3580 return 0;
3581 }
3582
3583 if (aic3262->control_type == SND_SOC_I2C) {
3584 if (aic3262->page_no != page) {
3585 aic3262_change_page(codec, page);
3586 }
3587 i2c_master_send(codec->control_data, (char *)&reg, 1);
3588 i2c_master_recv(codec->control_data, &value, 1);
3589 /*DBG("r %2x %02x\r\n", reg, value); */
3590 } else if (aic3262->control_type == SND_SOC_SPI) {
3591 u16 value;
3592
3593 /* Do SPI transfer; first 16bits are command; remaining is
3594 * register contents */
3595 cmd = AIC3262_READ_COMMAND_WORD(reg);
3596 buffer[0] = (cmd >> 8) & 0xff;
3597 buffer[1] = cmd & 0xff;
3598 //rc = spi_write_then_read(aic3262->spi, buffer, 2, buffer, 2);
3599
3600 if (rc) {
3601 dev_err(&aic3262->spi->dev, "AIC26 reg read error\n");
3602 return -EIO;
3603 }
3604 value = (buffer[0] << 8) | buffer[1];
3605 } else {
3606 printk(KERN_ERR "Unknown Interface Type in aic3262_read\n");
3607 }
3608
3609 /* Update the cache before returning with the value */
3610 cache[reg] = value;
3611 return value;
3612
3613}
3614
3615/*
3616 *----------------------------------------------------------------------------
3617 * Function : aic3262_write
3618 * Purpose : This function is to write to the aic3262 register space.
3619 *
3620 *----------------------------------------------------------------------------
3621 */
3622int aic3262_write(struct snd_soc_codec *codec, u16 reg, u8 value)
3623{
3624 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
3625 u8 data[2];
3626 u8 page;
3627 int ret = 0;
3628
3629 page = reg / 128;
3630 data[AIC3262_REG_OFFSET_INDEX] = reg % 128;
3631 if (aic3262->page_no != page)
3632 aic3262_change_page(codec, page);
3633
3634 /* data is
3635 * D15..D8 aic3262 register offset
3636 * D7...D0 register data
3637 */
3638 data[AIC3262_REG_DATA_INDEX] = value & AIC3262_8BITS_MASK;
3639#if defined(EN_REG_CACHE)
3640 if ((page >= 0) & (page <= 4))
3641 aic3262_write_reg_cache(codec, reg, value);
3642
3643#endif
3644 if (!data[AIC3262_REG_OFFSET_INDEX]) {
3645 /* if the write is to reg0 update aic3262->page_no */
3646 aic3262->page_no = value;
3647 }
3648
3649 /*DBG("w %2x %02x\r\n",
3650 data[AIC3262_REG_OFFSET_INDEX], data[AIC3262_REG_DATA_INDEX]);*/
3651
3652#if defined(LOCAL_REG_ACCESS)
3653 if (codec->hw_write(codec->control_data, data, 2) != 2)
3654 ret = -EIO;
3655#else
3656 ret = snd_soc_write(codec, data[AIC3262_REG_OFFSET_INDEX],
3657 data[AIC3262_REG_DATA_INDEX]);
3658#endif
3659 if (ret)
3660 printk(KERN_ERR "Error in i2c write\n");
3661
3662 return ret;
3663}
3664
3665/*
3666 *------------------------------------------------------------------------------
3667 * Function : aic3262_write__
3668 * Purpose : This function is to write to the aic3262 register space.
3669 * (low level).
3670 *------------------------------------------------------------------------------
3671 */
3672
3673int aic3262_write__(struct i2c_client *client, const char *buf, int count)
3674{
3675 u8 data[3];
3676 int ret;
3677 data[0] = *buf;
3678 data[1] = *(buf+1);
3679 data[2] = *(buf+2);
3680 /*DBG("w %2x %02x\r\n",
3681 data[AIC3262_REG_OFFSET_INDEX], data[AIC3262_REG_DATA_INDEX]);*/
3682 ret = i2c_master_send(client, data, 2);
3683 if (ret < 2) {
3684 printk(
3685 KERN_ERR "I2C write Error : bytes written = %d\n\n", ret);
3686 return -EIO;
3687 }
3688
3689 return ret;
3690}
3691/*
3692 *----------------------------------------------------------------------------
3693 * Function : aic3262_reset_cache
3694 * Purpose : This function is to reset the cache.
3695 *----------------------------------------------------------------------------
3696 */
3697int aic3262_reset_cache(struct snd_soc_codec *codec)
3698{
3699#if defined(EN_REG_CACHE)
3700 if (codec->reg_cache) {
3701 memcpy(codec->reg_cache, aic3262_reg, sizeof(aic3262_reg));
3702 return 0;
3703 }
3704
3705 codec->reg_cache = kmemdup(aic3262_reg,
3706 sizeof(aic3262_reg), GFP_KERNEL);
3707 if (!codec->reg_cache) {
3708 printk(KERN_ERR "aic32x4: kmemdup failed\n");
3709 return -ENOMEM;
3710 }
3711#endif
3712 return 0;
3713}
3714
3715/*
3716 *----------------------------------------------------------------------------
3717 * Function : aic3262_get_divs
3718 * Purpose : This function is to get required divisor from the "aic3262_divs"
3719 * table.
3720 *
3721 *----------------------------------------------------------------------------
3722 */
3723static inline int aic3262_get_divs(int mclk, int rate)
3724{
3725 int i;
3726
3727 for (i = 0; i < ARRAY_SIZE(aic3262_divs); i++) {
3728 if ((aic3262_divs[i].rate == rate)
3729 && (aic3262_divs[i].mclk == mclk)) {
3730 DBG(KERN_INFO "#%s: Found Entry %d in Clock_Array\n",
3731 __func__, i);
3732 return i;
3733 }
3734 }
3735 printk(KERN_ERR "Master clock and sample rate is not supported\n");
3736 return -EINVAL;
3737}
3738
3739/*
3740 *----------------------------------------------------------------------------
3741 * Function : aic3262_add_widgets
3742 * Purpose : This function is to add the dapm widgets
3743 * The following are the main widgets supported
3744 * # Left DAC to Left Outputs
3745 * # Right DAC to Right Outputs
3746 * # Left Inputs to Left ADC
3747 * # Right Inputs to Right ADC
3748 *
3749 *----------------------------------------------------------------------------
3750 */
3751static int aic3262_add_widgets(struct snd_soc_codec *codec)
3752{
3753 int ret;
3754 struct snd_soc_dapm_context *dapm = &codec->dapm;
3755#ifndef AIC3262_MULTI_I2S
3756 int i;
3757 for (i = 0; i < ARRAY_SIZE(aic3262_dapm_widgets); i++)
3758 ret = snd_soc_dapm_new_control(dapm, &aic3262_dapm_widgets[i]);
3759#else
3760 ret = snd_soc_dapm_new_controls(dapm, aic3262_dapm_widgets,
3761 ARRAY_SIZE(aic3262_dapm_widgets));
3762 if (ret != 0) {
3763 printk(KERN_ERR "#%s: Unable to add DAPM Controls. Err %d\n",
3764 __func__, ret);
3765 }
3766#endif
3767 /* set up audio path interconnects */
3768 DBG("#Completed adding new dapm widget controls size=%d\n",
3769 ARRAY_SIZE(aic3262_dapm_widgets));
3770 snd_soc_dapm_add_routes(dapm, aic3262_dapm_routes,
3771 ARRAY_SIZE(aic3262_dapm_routes));
3772 DBG("#Completed adding DAPM routes\n");
3773 snd_soc_dapm_new_widgets(dapm);
3774 DBG("#Completed updating dapm\n");
3775 return 0;
3776}
3777/*
3778 *----------------------------------------------------------------------------
3779 * Function : reg_def_conf
3780 * Purpose : This function is to reset the codec book 0 registers
3781 *
3782 *----------------------------------------------------------------------------
3783 */
3784int reg_def_conf(struct snd_soc_codec *codec)
3785{
3786 int i = 0, ret;
3787 DBG(KERN_INFO "#%s: Invoked..\n", __func__);
3788
3789 ret = aic3262_change_page(codec, 0);
3790 if (ret != 0)
3791 return ret;
3792
3793 ret = aic3262_change_book(codec, 0);
3794 if (ret != 0)
3795 return ret;
3796
3797 /* Configure the Codec with the default Initialization Values */
3798 for (i = 0; i < reg_init_size; i++) {
3799 ret = snd_soc_write(codec, aic3262_reg_init[i].reg_offset,
3800 aic3262_reg_init[i].reg_val);
3801 if (ret)
3802 break;
3803 }
3804 DBG(KERN_INFO "#%s: Done..\n", __func__);
3805 return ret;
3806}
3807
3808/*
3809 * i2c_verify_book0
3810 *
3811 * This function is used to dump the values of the Book 0 Pages.
3812 */
3813int i2c_verify_book0(struct snd_soc_codec *codec)
3814{
3815 int i, j, k = 0;
3816 u8 val1;
3817
3818 DBG("starting i2c_verify\n");
3819 DBG("Resetting page to 0\n");
3820 aic3262_change_book(codec, 0);
3821 for (j = 0; j < 3; j++) {
3822 if (j == 0) {
3823 aic3262_change_page(codec, 0);
3824 k = 0;
3825 }
3826 if (j == 1) {
3827 aic3262_change_page(codec, 1);
3828 k = 1;
3829 }
3830 /*
3831 if (j == 2) {
3832 aic3262_change_page(codec, 4);
3833 k = 4;
3834 }*/
3835 for (i = 0; i <= 127; i++) {
3836#if defined(LOCAL_REG_ACCESS)
3837 val1 = i2c_smbus_read_byte_data(codec->control_data, i);
3838#else
3839 val1 = snd_soc_read(codec, i);
3840#endif
3841 /* printk("[%d][%d]=[0x%2x]\n",k,i,val1); */
3842 }
3843 }
3844 return 0;
3845}
3846
3847/*
3848 *----------------------------------------------------------------------------
3849 * Function : aic3262_set_bias_level
3850 * Purpose : This function is to get triggered when dapm events occurs.
3851 *
3852 *----------------------------------------------------------------------------
3853 */
3854
3855static int aic3262_set_bias_level(struct snd_soc_codec *codec,
3856 enum snd_soc_bias_level level)
3857{
3858 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
3859 u8 value;
3860 switch (level) {
3861 /* full On */
3862 case SND_SOC_BIAS_ON:
3863
3864 /* all power is driven by DAPM system */
3865 dev_dbg(codec->dev, "set_bias_on\n");
3866 break;
3867
3868 /* partial On */
3869 case SND_SOC_BIAS_PREPARE:
3870
3871 dev_dbg(codec->dev, "set_bias_prepare\n");
3872
3873 break;
3874
3875 /* Off, with power */
3876 case SND_SOC_BIAS_STANDBY:
3877 /*
3878 * all power is driven by DAPM system,
3879 * so output power is safe if bypass was set
3880 */
3881 dev_dbg(codec->dev, "set_bias_stby\n");
3882
3883 break;
3884 /* Off, without power */
3885 case SND_SOC_BIAS_OFF:
3886 dev_dbg(codec->dev, "set_bias_off\n");
3887
3888 break;
3889 }
3890 codec->dapm.bias_level=level;
3891
3892 return 0;
3893}
3894
3895
3896/*
3897 *----------------------------------------------------------------------------
3898 * Function : aic3262_suspend
3899 * Purpose : This function is to suspend the AIC3262 driver.
3900 *
3901 *----------------------------------------------------------------------------
3902 */
3903static int aic3262_suspend(struct snd_soc_codec *codec, pm_message_t state)
3904{
3905 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
3906 DBG(KERN_INFO "#%s: Invoked..\n", __func__);
3907 if (aic3262)
3908 disable_irq(aic3262->irq);
3909
3910 aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3911
3912 return 0;
3913}
3914
3915/*
3916 *----------------------------------------------------------------------------
3917 * Function : aic3262_resume
3918 * Purpose : This function is to resume the AIC3262 driver
3919 *
3920 *----------------------------------------------------------------------------
3921 */
3922static int aic3262_resume(struct snd_soc_codec *codec)
3923{
3924 int i;
3925 u8 data[2];
3926 int ret = 0;
3927 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
3928 u8 *cache = codec->reg_cache;
3929 DBG(KERN_INFO "#%s: Invoked..\n", __func__);
3930
3931 ret = aic3262_change_page(codec, 0);
3932 if (ret)
3933 return ret;
3934#if defined(EN_REG_CACHE)
3935 /* Sync reg_cache with the hardware */
3936 for (i = 0; i < ARRAY_SIZE(aic3262_reg); i++) {
3937 data[0] = i % 128;
3938 data[1] = cache[i];
3939#if defined(LOCAL_REG_ACCESS)
3940 codec->hw_write(codec->control_data, data, 2);
3941#else
3942 ret = snd_soc_write(codec, data[0], data[1]);
3943 if (ret)
3944 break;
3945#endif
3946 }
3947#endif
3948 if (!ret) {
3949 aic3262_change_page(codec, 0);
3950 aic3262_set_bias_level(codec, SND_SOC_BIAS_ON);
3951
3952 if (aic3262)
3953 enable_irq(aic3262->irq);
3954 }
3955 return ret;
3956}
3957/*
3958 *----------------------------------------------------------------------------
3959 * Function : aic3262_hw_read
3960 * Purpose : This is a low level harware read function.
3961 *
3962 *----------------------------------------------------------------------------
3963 */
3964unsigned int aic3262_hw_read(struct snd_soc_codec *codec, unsigned int count)
3965{
3966 struct i2c_client *client = codec->control_data;
3967 unsigned int buf;
3968
3969 if (count > (sizeof(unsigned int)))
3970 return 0;
3971
3972 i2c_master_recv(client, (char *)&buf, count);
3973 return buf;
3974}
3975
3976/*
3977* aic3262_jack_handler
3978*
3979* This function is called from the Interrupt Handler
3980* to check the status of the AIC3262 Registers related to Headset Detection
3981*/
3982static irqreturn_t aic3262_jack_handler(int irq, void *data)
3983{
3984 struct snd_soc_codec *codec = data;
3985 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
3986 unsigned int value;
3987 unsigned int micbits, hsbits = 0;
3988 DBG(KERN_INFO "%s++\n", __func__);
3989
3990 aic3262_change_page(codec, 0);
3991
3992 /* Read the Jack Status Register*/
3993 value = snd_soc_read(codec, STICKY_FLAG2);
3994 DBG(KERN_INFO "reg44 0x%x\n", value);
3995
3996
3997 value = snd_soc_read(codec, INT_FLAG2);
3998 DBG(KERN_INFO "reg46 0x%x\n", value);
3999
4000 value = snd_soc_read(codec, DAC_FLAG_R1);
4001 DBG(KERN_INFO "reg37 0x%x\n", value);
4002
4003 micbits = value & DAC_FLAG_MIC_MASKBITS;
4004 DBG(KERN_INFO "micbits 0x%x\n", micbits);
4005
4006 hsbits = value & DAC_FLAG_HS_MASKBITS;
4007 DBG(KERN_INFO "hsbits 0x%x\n", hsbits);
4008
4009
4010 /* No Headphone or Headset*/
4011 if (!micbits && !hsbits) {
4012 DBG(KERN_INFO "no headset/headphone\n");
4013 snd_soc_jack_report(aic3262->headset_jack,
4014 0, SND_JACK_HEADSET);
4015 }
4016
4017 /* Headphone Detected */
4018 if ((micbits == DAC_FLAG_R1_NOMIC) || (hsbits)) {
4019 DBG(KERN_INFO "headphone\n");
4020 snd_soc_jack_report(aic3262->headset_jack,
4021 SND_JACK_HEADPHONE, SND_JACK_HEADSET);
4022 }
4023
4024 /* Headset Detected - only with capless */
4025 if (micbits == DAC_FLAG_R1_MIC) {
4026 DBG(KERN_INFO "headset\n");
4027 snd_soc_jack_report(aic3262->headset_jack,
4028 SND_JACK_HEADSET, SND_JACK_HEADSET);
4029 }
4030 DBG(KERN_INFO "%s--\n", __func__);
4031 return IRQ_HANDLED;
4032}
4033
4034/*
4035* aic326x_headset_detect
4036*
4037* Call-back function called to check the status of Headset Pin.
4038*/
4039int aic326x_headset_detect(struct snd_soc_codec *codec,
4040 struct snd_soc_jack *jack, int jack_type)
4041{
4042 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
4043
4044 aic3262->headset_jack = jack;
4045 /*Enable the Headset Interrupts*/
4046 snd_soc_write(codec, INT1_CNTL, 0x80);
4047
4048 return 0;
4049}
4050EXPORT_SYMBOL_GPL(aic326x_headset_detect);
4051
4052int aic326x_headset_button_init(struct snd_soc_codec *codec,
4053 struct snd_soc_jack *jack, int jack_type)
4054{
4055 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
4056
4057 aic3262->button_dev = input_allocate_device();
4058 aic3262->button_dev->name = "aic326x_headset_button";
4059 aic3262->button_dev->phys = "codec/input0";
4060 aic3262->button_dev->dev.parent = snd_card_get_device_link(codec->card->snd_card);
4061 input_set_capability(aic3262->button_dev, EV_KEY, KEY_MEDIA);
4062
4063 if (input_register_device(aic3262->button_dev))
4064 {
4065 printk( "Unable to register input device headset button");
4066 }
4067
4068 aic3262_jack_handler(aic3262->irq, codec);
4069 return 0;
4070}
4071#ifdef AIC3262_MULTI_I2S
4072/*
4073* aic3262_asi_default_config
4074*
4075* This function is used to perform the default pin configurations for
4076* the functionalities which are specific to each ASI Port of the AIC3262
4077* Audio Codec Chipset. The user is encouraged to change these values
4078* if required on their platforms.
4079*/
4080static void aic3262_asi_default_config(struct snd_soc_codec *codec)
4081{
4082 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
4083 u16 counter;
4084
4085 DBG(KERN_INFO
4086 "#%s: Invoked. Will Config ASI Registers to Defaults..\n",
4087 __func__);
4088 for (counter = 0; counter < MAX_ASI_COUNT; counter++) {
4089 aic3262->asiCtxt[counter].asi_active = 0;
4090 aic3262->asiCtxt[counter].bclk_div = 1;
4091 aic3262->asiCtxt[counter].wclk_div = 1;
4092 aic3262->asiCtxt[counter].port_muted = 1;
4093 aic3262->asiCtxt[counter].bclk_div_option =
4094 BDIV_CLKIN_DAC_MOD_CLK;
4095 aic3262->asiCtxt[counter].offset1 = 0;
4096 aic3262->asiCtxt[counter].offset2 = 0;
4097 }
4098 /* ASI1 Defaults */
4099 aic3262->asiCtxt[0].bclk_output = ASI1_BCLK_DIVIDER_OUTPUT;
4100 aic3262->asiCtxt[0].wclk_output = GENERATED_DAC_FS;
4101 aic3262->asiCtxt[0].left_dac_output = DAC_PATH_LEFT;
4102 aic3262->asiCtxt[0].right_dac_output = DAC_PATH_LEFT;
4103 aic3262->asiCtxt[0].adc_input = ADC_PATH_MINIDSP_1;
4104 aic3262->asiCtxt[0].dout_option = ASI_OUTPUT;
4105
4106 /* ASI2 Defaults */
4107 aic3262->asiCtxt[1].bclk_output = ASI2_BCLK_DIVIDER_OUTPUT;
4108 aic3262->asiCtxt[1].wclk_output = GENERATED_DAC_FS;
4109 aic3262->asiCtxt[1].left_dac_output = DAC_PATH_LEFT;
4110 aic3262->asiCtxt[1].right_dac_output = DAC_PATH_LEFT;
4111 aic3262->asiCtxt[1].adc_input = ADC_PATH_MINIDSP_2;
4112 aic3262->asiCtxt[1].dout_option = ASI_OUTPUT;
4113
4114 /* ASI3 Defaults */
4115 aic3262->asiCtxt[2].bclk_output = ASI3_BCLK_DIVIDER_OUTPUT;
4116 aic3262->asiCtxt[2].wclk_output = GENERATED_DAC_FS;
4117 aic3262->asiCtxt[2].left_dac_output = DAC_PATH_LEFT;
4118 aic3262->asiCtxt[2].right_dac_output = DAC_PATH_LEFT;
4119 aic3262->asiCtxt[2].adc_input = ADC_PATH_MINIDSP_3;
4120 aic3262->asiCtxt[2].dout_option = ASI2_INPUT;
4121 return;
4122}
4123
4124#endif /* #ifdef AIC3262_MULTI_I2S */
4125
4126/*
4127 *----------------------------------------------------------------------------
4128 * Function : aic3262_probe
4129 * Purpose : This is first driver function called by the SoC core driver.
4130 *
4131 *----------------------------------------------------------------------------
4132 */
4133
4134static int aic3262_probe(struct snd_soc_codec *codec)
4135{
4136 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
4137 int ret = 0;
4138
4139 DBG(KERN_INFO "#%s: Invoked..\n", __func__);
4140
4141#if defined(EN_REG_CACHE)
4142 codec->reg_cache =
4143 kmemdup(aic3262_reg, sizeof(aic3262_reg), GFP_KERNEL);
4144
4145 if (!codec->reg_cache) {
4146 printk(KERN_ERR "aic3262: kmemdup failed\n");
4147 return -ENOMEM;
4148 }
4149#else
4150 /* Setting cache bypass - not to overwrite the cache registers,
4151 Codec registers have 4 pages which is not handled in the common
4152 cache code properly - bypass it in write value and save it
4153 using separate call*/
4154 codec->cache_bypass = 1;
4155#endif
4156
4157#if defined(LOCAL_REG_ACCESS)
4158 codec->control_data = aic3262->control_data;
4159 codec->hw_write = (hw_write_t) aic3262_write__;
4160 codec->hw_read = aic3262_hw_read;
4161#else
4162 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
4163 if (ret != 0) {
4164 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
4165 return ret;
4166 }
4167#endif
4168 ret = reg_def_conf(codec);
4169 if (ret != 0) {
4170 printk(KERN_ERR "Failed to init TI codec: %d\n", ret);
4171 return ret;
4172 }
4173
4174 if (aic3262->irq) {
4175 /* audio interrupt */
4176 ret = request_threaded_irq(aic3262->irq, NULL,
4177 aic3262_jack_handler,
4178 IRQF_TRIGGER_FALLING,
4179 "tlv320aic3262", codec);
4180 if (ret) {
4181 printk(KERN_INFO "#%s: IRQ Registration failed..[%d]",
4182 __func__, ret);
4183 dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
4184 return ret;
4185 } else
4186 DBG(KERN_INFO
4187 "#%s: irq Registration for IRQ %d done..\n",
4188 __func__, aic3262->irq);
4189 } else {
4190 DBG(KERN_INFO "#%s: I2C IRQ Configuration is Wrong. \
4191 Please check it..\n", __func__);
4192 }
4193
4194 aic3262_asi_default_config(codec);
4195
4196 /* off, with power on */
4197 aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
4198
4199 ret = snd_soc_add_controls(codec, aic3262_snd_controls,
4200 ARRAY_SIZE(aic3262_snd_controls));
4201 if(ret)
4202 {
4203 printk(KERN_INFO "%s failed\n", __func__);
4204 }
4205
4206 aic3262_add_widgets(codec);
4207 /*TODO*/
4208 snd_soc_write(codec, MIC_BIAS_CNTL, 0x66);
4209
4210#ifdef AIC3262_TiLoad
4211 ret = aic3262_driver_init(codec);
4212 if (ret < 0)
4213 printk(KERN_ERR
4214 "\nAIC3262 CODEC: aic3262_probe :TiLoad Initialization failed\n");
4215#endif
4216
4217
4218#ifdef CONFIG_MINI_DSP
4219 /* Program MINI DSP for ADC and DAC */
4220 aic3262_minidsp_program(codec);
4221 aic3262_add_minidsp_controls(codec);
4222 aic3262_change_book(codec, 0x0);
4223#endif
4224
4225#ifdef MULTIBYTE_CONFIG_SUPPORT
4226 aic3262_add_multiconfig_controls(codec);
4227#endif
4228
4229 DBG(KERN_INFO "#%s: done..\n", __func__);
4230 return ret;
4231}
4232
4233
4234
4235/*
4236 *----------------------------------------------------------------------------
4237 * Function : aic3262_remove
4238 * Purpose : to remove aic3262 soc device
4239 *
4240 *----------------------------------------------------------------------------
4241 */
4242static int aic3262_remove(struct snd_soc_codec *codec)
4243{
4244
4245 /* power down chip */
4246 aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
4247
4248 return 0;
4249}
4250
4251
4252/*
4253 *----------------------------------------------------------------------------
4254 * @struct snd_soc_codec_device |
4255 * This structure is soc audio codec device sturecute which pointer
4256 * to basic functions aic3262_probe(), aic3262_remove(),
4257 * aic3262_suspend() and aic3262_resume()
4258 *----------------------------------------------------------------------------
4259 */
4260static struct snd_soc_codec_driver soc_codec_dev_aic3262 = {
4261 .probe = aic3262_probe,
4262 .remove = aic3262_remove,
4263 .suspend = aic3262_suspend,
4264 .resume = aic3262_resume,
4265 .set_bias_level = aic3262_set_bias_level,
4266#if defined(LOCAL_REG_ACCESS)
4267 .read = aic3262_read,
4268 .write = aic3262_write,
4269#endif
4270#if !defined(EN_REG_CACHE)
4271 .reg_cache_size = ARRAY_SIZE(aic3262_reg),
4272 .reg_word_size = sizeof(u8),
4273 .reg_cache_default = aic3262_reg,
4274#endif
4275};
4276
4277
4278#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
4279/*
4280 *----------------------------------------------------------------------------
4281 * Function : aic3262_codec_probe
4282 * Purpose : This function attaches the i2c client and initializes
4283 * AIC3262 CODEC.
4284 * NOTE:
4285 * This function is called from i2c core when the I2C address is
4286 * valid.
4287 * If the i2c layer weren't so broken, we could pass this kind of
4288 * data around
4289 *
4290 *----------------------------------------------------------------------------
4291 */
4292static __devinit int aic3262_codec_probe(struct i2c_client *i2c,
4293 const struct i2c_device_id *id)
4294{
4295 int ret;
4296
4297 struct aic3262_priv *aic3262;
4298
4299 DBG(KERN_INFO "#%s: Entered\n", __func__);
4300
4301 aic3262 = kzalloc(sizeof(struct aic3262_priv), GFP_KERNEL);
4302
4303 if (!aic3262) {
4304 printk(KERN_ERR "#%s: Unable to Allocate Priv struct..\n",
4305 __func__);
4306 return -ENOMEM;
4307 }
4308
4309 i2c_set_clientdata(i2c, aic3262);
4310#if defined(LOCAL_REG_ACCESS)
4311 aic3262->control_data = i2c;
4312#endif
4313 aic3262->control_type = SND_SOC_I2C;
4314 aic3262->irq = i2c->irq;
4315 aic3262->pdata = i2c->dev.platform_data;
4316
4317 /* The Configuration Support will be by default to 3 which
4318 * holds the MAIN Patch Configuration.
4319 */
4320 aic3262->current_dac_config[0] = -1;
4321 aic3262->current_dac_config[1] = -1;
4322 aic3262->current_adc_config[0] = -1;
4323 aic3262->current_adc_config[1] = -1;
4324
4325 aic3262->mute_codec = 1;
4326
4327 aic3262->page_no = 0;
4328 aic3262->book_no = 0;
4329 aic3262->active_count = 0;
4330 aic3262->dac_clkin_option = 3;
4331 aic3262->adc_clkin_option = 3;
4332
4333 ret = snd_soc_register_codec(&i2c->dev,
4334 &soc_codec_dev_aic3262,
4335 tlv320aic3262_dai, ARRAY_SIZE(tlv320aic3262_dai));
4336
4337 if (ret < 0)
4338 kfree(aic3262);
4339 DBG(KERN_INFO "#%s: Done ret %d\n", __func__, ret);
4340 return ret;
4341}
4342
4343/*
4344 *----------------------------------------------------------------------------
4345 * Function : aic3262_i2c_remove
4346 * Purpose : This function removes the i2c client and uninitializes
4347 * AIC3262 CODEC.
4348 * NOTE:
4349 * This function is called from i2c core
4350 * If the i2c layer weren't so broken, we could pass this kind of
4351 * data around
4352 *
4353 *----------------------------------------------------------------------------
4354 */
4355static __devexit int aic3262_i2c_remove(struct i2c_client *i2c)
4356{
4357 snd_soc_unregister_codec(&i2c->dev);
4358 kfree(i2c_get_clientdata(i2c));
4359 return 0;
4360}
4361
4362static const struct i2c_device_id tlv320aic3262_id[] = {
4363 {"aic3262-codec", 0},
4364 {}
4365};
4366MODULE_DEVICE_TABLE(i2c, tlv320aic3262_id);
4367
4368static struct i2c_driver tlv320aic3262_i2c_driver = {
4369 .driver = {
4370 .name = "aic3262-codec",
4371 .owner = THIS_MODULE,
4372 },
4373 .probe = aic3262_codec_probe,
4374 .remove = __devexit_p(aic3262_i2c_remove),
4375 .id_table = tlv320aic3262_id,
4376};
4377#endif /*#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)*/
4378
4379#if defined(CONFIG_SPI_MASTER)
4380static int aic3262_spi_write(struct spi_device *spi, const char *data, int len)
4381{
4382 struct spi_transfer t;
4383 struct spi_message m;
4384 u8 msg[2];
4385
4386 if (len <= 0)
4387 return 0;
4388
4389 msg[0] = data[0];
4390 msg[1] = data[1];
4391
4392 spi_message_init(&m);
4393 memset(&t, 0, (sizeof t));
4394 t.tx_buf = &msg[0];
4395 t.len = len;
4396
4397 spi_message_add_tail(&t, &m);
4398 spi_sync(spi, &m);
4399
4400 return len;
4401}
4402
4403/*
4404 * This function forces any delayed work to be queued and run.
4405 */
4406static int run_delayed_work(struct delayed_work *dwork)
4407{
4408 int ret;
4409
4410 /* cancel any work waiting to be queued. */
4411 ret = cancel_delayed_work(dwork);
4412
4413 /* if there was any work waiting then we run it now and
4414 * wait for it's completion */
4415 if (ret) {
4416 schedule_delayed_work(dwork, 0);
4417 flush_scheduled_work();
4418 }
4419 return ret;
4420}
4421static int __devinit aic3262_spi_probe(struct spi_device *spi)
4422{
4423 int ret;
4424 struct snd_soc_codec *codec;
4425 struct aic3262_priv *aic3262;
4426 printk(KERN_INFO "%s entering\n",__func__);
4427 aic3262 = kzalloc(sizeof(struct aic3262_priv), GFP_KERNEL);
4428
4429 if (!aic3262) {
4430 printk(KERN_ERR "#%s: Unable to Allocate Priv struct..\n",
4431 __func__);
4432 return -ENOMEM;
4433 }
4434 codec = &aic3262->codec;
4435 codec->control_data = spi;
4436 aic3262->control_type = SND_SOC_SPI;
4437 codec->hw_write = (hw_write_t)aic3262_spi_write;
4438 codec->dev = &spi->dev;
4439
4440 aic3262->pdata = spi->dev.platform_data;
4441
4442 /* The Configuration Support will be by default to 3 which
4443 * holds the MAIN Patch Configuration.
4444 */
4445 aic3262->current_dac_config[0] = -1;
4446 aic3262->current_dac_config[1] = -1;
4447 aic3262->current_adc_config[0] = -1;
4448 aic3262->current_adc_config[1] = -1;
4449
4450 aic3262->mute_codec = 1;
4451
4452 aic3262->page_no = 0;
4453 aic3262->book_no = 0;
4454 aic3262->active_count = 0;
4455 aic3262->dac_clkin_option = 3;
4456 aic3262->adc_clkin_option = 3;
4457 dev_set_drvdata(&spi->dev, aic3262);
4458 spi_set_drvdata(spi, aic3262);
4459 ret = snd_soc_register_codec(&spi->dev,
4460 &soc_codec_dev_aic3262,
4461 tlv320aic3262_dai, ARRAY_SIZE(tlv320aic3262_dai));
4462
4463 if (ret < 0) {
4464 printk(KERN_INFO "%s codec registeration failed\n",__func__);
4465 kfree(aic3262);
4466 }
4467 else {
4468 printk(KERN_INFO "%s registered\n",__func__);
4469 }
4470 printk(KERN_INFO "#%s: Done ret %d\n", __func__, ret);
4471 return ret;
4472}
4473
4474static int __devexit aic3262_spi_remove(struct spi_device *spi)
4475{
4476 struct aic3262_priv *aic3262 = dev_get_drvdata(&spi->dev);
4477 aic3262_set_bias_level(&aic3262->codec, SND_SOC_BIAS_OFF);
4478 snd_soc_unregister_codec(&spi->dev);
4479 kfree(aic3262);
4480 aic3262_codec = NULL;
4481 return 0;
4482
4483}
4484
4485static struct spi_driver aic3262_spi_driver = {
4486 .driver = {
4487 .name = "aic3262-codec",
4488 .bus = &spi_bus_type,
4489 .owner = THIS_MODULE,
4490 },
4491 .probe = aic3262_spi_probe,
4492 .remove = __devexit_p(aic3262_spi_remove),
4493};
4494#endif
4495static int __init tlv320aic3262_modinit(void)
4496{
4497 int ret = 0;
4498 printk(KERN_INFO "In %s\n",__func__);
4499#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
4500 ret = i2c_add_driver(&tlv320aic3262_i2c_driver);
4501 if (ret != 0)
4502 printk(KERN_ERR "Failed to register aic326x i2c driver %d\n",
4503 ret);
4504#endif
4505#if defined(CONFIG_SPI_MASTER)
4506 printk(KERN_INFO "Inside config_spi_master\n");
4507 ret = spi_register_driver(&aic3262_spi_driver);
4508 if (ret != 0)
4509 printk(KERN_ERR "Failed to register aic3262 SPI driver: %d\n", ret);
4510#endif
4511 return ret;
4512
4513}
4514
4515module_init(tlv320aic3262_modinit);
4516
4517static void __exit tlv320aic3262_exit(void)
4518{
4519#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
4520 i2c_del_driver(&tlv320aic3262_i2c_driver);
4521#endif
4522}
4523module_exit(tlv320aic3262_exit);
4524
4525MODULE_DESCRIPTION("ASoC TLV320AIC3262 codec driver");
4526MODULE_AUTHOR("Barani Prashanth<gvbarani@mistralsolutions.com>");
4527MODULE_AUTHOR("Ravindra<ravindra@mistralsolutions.com>");
4528MODULE_LICENSE("GPL");