2 * linux/sound/soc/codecs/tlv320aic326x.c
4 * Copyright (C) 2011 Texas Instruments Inc.,
6 * This package is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
11 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
12 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14 * The TLV320AIC3262 is a flexible, low-power, low-voltage stereo audio
15 * codec with digital microphone inputs and programmable outputs.
19 * Rev 0.1 ASoC driver support TI 20-01-2011
21 * The AIC325x ASoC driver is ported for the codec AIC3262.
22 * Rev 0.2 ASoC driver support TI 21-03-2011
23 * The AIC326x ASoC driver is updated for linux 2.6.32 Kernel.
24 * Rev 0.3 ASoC driver support TI 20-04-2011
25 * The AIC326x ASoC driver is ported to 2.6.35 omap4 kernel
29 *****************************************************************************
31 *****************************************************************************
35 #include <linux/module.h>
36 #include <linux/moduleparam.h>
37 #include <linux/init.h>
38 #include <linux/delay.h>
40 #include <linux/i2c.h>
41 #include <linux/pm_runtime.h>
42 #include <linux/spi/spi.h>
43 #include <linux/platform_device.h>
44 #include <linux/switch.h>
45 #include <sound/jack.h>
46 #include <linux/irq.h>
47 #include <linux/interrupt.h>
48 #include <linux/cdev.h>
49 #include <linux/slab.h>
50 #include <linux/firmware.h>
52 #include <sound/tlv.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 <linux/mfd/tlv320aic3262-registers.h>
60 #include <linux/mfd/tlv320aic3262-core.h>
61 #include "aic3xxx_cfw.h"
62 #include "aic3xxx_cfw_ops.h"
64 #include "tlv320aic326x.h"
65 #include "aic3262_codec_ops.h"
66 #include "tlv320aic3262_default_fw.h"
70 extern int aic3262_driver_init(struct snd_soc_codec *codec);
75 #include <linux/proc_fs.h>
76 #include <linux/seq_file.h>
77 #include <linux/vmalloc.h>
78 char debug_write_read = 0;
81 static struct snd_soc_codec *aic3262_codec;
84 *******************************************************************************
86 *******************************************************************************
88 static u32 aic3262_reg_ctl;
90 /* whenever aplay/arecord is run, aic3262_hw_params() function gets called.
91 * This function reprograms the clock dividers etc. this flag can be used to
92 * disable this when the clock dividers are programmed by pps config file
94 //static int soc_static_freq_config = 1;
96 /******************************************************************************
98 ******************************************************************************/
101 /* ASoC Widget Control definition for a single Register based Control */
102 #define SOC_SINGLE_AIC3262(xname) \
104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
105 .info = __new_control_info, .get = __new_control_get,\
106 .put = __new_control_put, \
107 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
110 *****************************************************************************
112 *****************************************************************************
114 static int aic3262_hw_params(struct snd_pcm_substream *substream,
115 struct snd_pcm_hw_params *params,
116 struct snd_soc_dai *dai);
118 static int aic3262_mute(struct snd_soc_dai *dai, int mute);
120 static int aic3262_set_dai_sysclk(struct snd_soc_dai *codec_dai,
121 int clk_id, unsigned int freq, int dir);
123 static int aic3262_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt);
125 static int aic3262_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
126 unsigned int Fin, unsigned int Fout);
128 static int aic3262_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level);
130 unsigned int aic3262_codec_read(struct snd_soc_codec *codec, unsigned int reg);
133 static int __new_control_info(struct snd_kcontrol *kcontrol,
134 struct snd_ctl_elem_info *uinfo);
136 static int __new_control_get(struct snd_kcontrol *kcontrol,
137 struct snd_ctl_elem_value *ucontrol);
139 static int __new_control_put(struct snd_kcontrol *kcontrol,
140 struct snd_ctl_elem_value *ucontrol);
141 int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book);
144 void aic3262_firmware_load(const struct firmware *fw, void *context);
145 static int aic3262_test_get(struct snd_kcontrol *kcontrol,
146 struct snd_ctl_elem_value *ucontrol);
147 static int aic3262_test_put(struct snd_kcontrol *kcontrol,
148 struct snd_ctl_elem_value *ucontrol);
149 static int aic3262_set_mode_get(struct snd_kcontrol *kcontrol,
150 struct snd_ctl_elem_value *ucontrol);
151 static int aic3262_set_mode_put(struct snd_kcontrol *kcontrol,
152 struct snd_ctl_elem_value *ucontrol);
154 static int aic326x_adc_dsp_event(struct snd_soc_dapm_widget *w,struct snd_kcontrol *kcontrol, int event);
155 /*static int aic326x_adcl_event(struct snd_soc_dapm_widget *w,struct snd_kcontrol *kcontrol, int event);
156 static int aic326x_adcr_event(struct snd_soc_dapm_widget *w,struct snd_kcontrol *kcontrol, int event);*/
157 static int __new_control_info(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_info *uinfo)
159 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
161 uinfo->value.integer.min = 0;
162 uinfo->value.integer.max = 65535;
167 //static long debug_level = 0;
168 //module_param(debug_level, int, 0);
169 //MODULE_PARM_DESC(debug_level, "Debug level for printing");
172 *----------------------------------------------------------------------------
173 * Function : __new_control_get
174 * Purpose : This function is to read data of new control for
175 * program the AIC3262 registers.
177 *----------------------------------------------------------------------------
179 static int __new_control_get(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
182 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
184 val = snd_soc_read(codec, aic3262_reg_ctl);
185 ucontrol->value.integer.value[0] = val;
190 *----------------------------------------------------------------------------
191 * Function : __new_control_put
192 * Purpose : new_control_put is called to pass data from user/application to
195 *----------------------------------------------------------------------------
197 static int __new_control_put(struct snd_kcontrol *kcontrol,
198 struct snd_ctl_elem_value *ucontrol)
200 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
201 u32 data_from_user = ucontrol->value.integer.value[0];
202 u8 val = data_from_user & 0x00ff;
203 u32 reg = data_from_user >> 8;//MAKE_REG(book,page,offset)
204 snd_soc_write(codec, reg, val);
205 aic3262_reg_ctl = reg;
210 /*static ssize_t debug_level_show(struct device *dev,
211 struct device_attribute *attr,
212 char *buf, size_t count)
214 return sprintf(buf, "%ld\n", debug_level);
217 static ssize_t debug_level_set(struct device *dev,
218 struct device_attribute *attr,
219 const char *buf, size_t count)
222 ret = strict_strtol(buf, 10, &debug_level);
228 //static DEVICE_ATTR(debug_level,0644, debug_level_show, debug_level_set);
230 static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0);
231 static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1200, 50, 0);
232 static const DECLARE_TLV_DB_SCALE(spk_gain_tlv, 600, 600, 0);
233 static const DECLARE_TLV_DB_SCALE(output_gain_tlv, -600, 100, 1);
234 static const DECLARE_TLV_DB_SCALE(micpga_gain_tlv, 0, 50, 0);
235 static const DECLARE_TLV_DB_SCALE(adc_fine_gain_tlv, -40, 10, 0);
236 static const DECLARE_TLV_DB_SCALE(beep_gen_volume_tlv, -6300, 100, 0);
238 /* Chip-level Input and Output CM Mode Controls */
239 static const char *input_common_mode_text[] = {
242 static const char *output_common_mode_text[] = {
243 "Input CM", "1.25v", "1.5v", "1.65v" };
245 static const struct soc_enum input_cm_mode =
246 SOC_ENUM_SINGLE(AIC3262_CM_REG, 2, 2, input_common_mode_text);
248 static const struct soc_enum output_cm_mode =
249 SOC_ENUM_SINGLE(AIC3262_CM_REG, 0, 4, output_common_mode_text);
251 *****************************************************************************
252 * Structure Initialization
253 *****************************************************************************
255 static const struct snd_kcontrol_new aic3262_snd_controls[] = {
257 #ifndef DAC_INDEPENDENT_VOL
258 /* sound new kcontrol for PCM Playback volume control */
260 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
261 AIC3262_DAC_LVOL, AIC3262_DAC_RVOL, 8,0xffffff81, 0x30, dac_vol_tlv),
263 /*HP Driver Gain Control*/
264 SOC_DOUBLE_R_SX_TLV("HeadPhone Driver Amplifier Volume", AIC3262_HPL_VOL, AIC3262_HPR_VOL, 6, 0xffffffb9, 0xffffffce, output_gain_tlv),
265 SOC_DOUBLE_R_SX_TLV("Headphone Volume", AIC3262_HPL_VOL, AIC3262_HPR_VOL, 6, 0xffffffb9, 0xffffffce, output_gain_tlv),
266 /*LO Driver Gain Control*/
267 SOC_DOUBLE_TLV("Speaker Amplifier Volume", AIC3262_SPK_AMP_CNTL_R4, 4, 0, 5, 0, spk_gain_tlv),
268 SOC_DOUBLE_TLV("Speaker Volume", AIC3262_SPK_AMP_CNTL_R4, 4, 0, 5, 0, spk_gain_tlv),
270 SOC_DOUBLE_R_SX_TLV("Receiver Amplifier Volume", AIC3262_REC_AMP_CNTL_R5, AIC3262_RAMPR_VOL, 6, 0xffffffb9, 0xffffffd6, output_gain_tlv),
271 SOC_DOUBLE_R_SX_TLV("Earpiece Volume", AIC3262_REC_AMP_CNTL_R5, AIC3262_RAMPR_VOL, 6, 0xffffffb9, 0xffffffd6, output_gain_tlv),
273 SOC_DOUBLE_R_SX_TLV("PCM Capture Volume",
274 AIC3262_LADC_VOL, AIC3262_RADC_VOL, 7,0xffffff68, 0xffffffa8, adc_vol_tlv),
277 SOC_DOUBLE_R_TLV ("MicPGA Volume Control",
278 AIC3262_MICL_PGA, AIC3262_MICR_PGA, 0, 0x5F, 0, micpga_gain_tlv),
279 SOC_DOUBLE_TLV("PCM Capture Fine Gain Volume", AIC3262_ADC_FINE_GAIN, 4, 0, 5, 1, adc_fine_gain_tlv),
280 SOC_DOUBLE("ADC channel mute", AIC3262_ADC_FINE_GAIN, 7, 3, 1, 0),
282 SOC_DOUBLE("DAC MUTE", AIC3262_DAC_MVOL_CONF, 2, 3, 1, 1),
284 /* sound new kcontrol for Programming the registers from user space */
285 SOC_SINGLE_AIC3262("Program Registers"),
287 SOC_SINGLE("RESET", AIC3262_RESET_REG, 0,1,0),
289 SOC_SINGLE("DAC VOL SOFT STEPPING", AIC3262_DAC_MVOL_CONF, 0, 2, 0),
292 SOC_SINGLE("DAC AUTO MUTE CONTROL", AIC3262_DAC_MVOL_CONF, 4, 7, 0),
293 SOC_SINGLE("RIGHT MODULATOR SETUP", AIC3262_DAC_MVOL_CONF, 7, 1, 0),
295 SOC_SINGLE("ADC Volume soft stepping", AIC3262_ADC_CHANNEL_POW, 0, 3, 0),
297 SOC_SINGLE("Mic Bias ext independent enable", AIC3262_MIC_BIAS_CNTL, 7, 1, 0),
298 // SOC_SINGLE("MICBIAS_EXT ON", MIC_BIAS_CNTL, 6, 1, 0),
299 SOC_SINGLE("MICBIAS EXT Power Level", AIC3262_MIC_BIAS_CNTL, 4, 3, 0),
301 // SOC_SINGLE("MICBIAS_INT ON", MIC_BIAS_CNTL, 2, 1, 0),
302 SOC_SINGLE("MICBIAS INT Power Level", AIC3262_MIC_BIAS_CNTL, 0, 3, 0),
304 SOC_DOUBLE("DRC_EN_CTL", AIC3262_DRC_CNTL_R1, 6, 5, 1, 0),
305 SOC_SINGLE("DRC_THRESHOLD_LEVEL", AIC3262_DRC_CNTL_R1, 2, 7, 1),
306 SOC_SINGLE("DRC_HYSTERISIS_LEVEL", AIC3262_DRC_CNTL_R1, 0, 7, 0),
308 SOC_SINGLE("DRC_HOLD_LEVEL", AIC3262_DRC_CNTL_R2, 3, 0x0F, 0),
309 SOC_SINGLE("DRC_GAIN_RATE", AIC3262_DRC_CNTL_R2, 0, 4, 0),
310 SOC_SINGLE("DRC_ATTACK_RATE", AIC3262_DRC_CNTL_R3, 4, 0x0F, 1),
311 SOC_SINGLE("DRC_DECAY_RATE", AIC3262_DRC_CNTL_R3, 0, 0x0F, 1),
313 SOC_SINGLE("BEEP_GEN_EN", AIC3262_BEEP_CNTL_R1, 7, 1, 0),
314 SOC_DOUBLE_R("BEEP_VOL_CNTL", AIC3262_BEEP_CNTL_R1, AIC3262_BEEP_CNTL_R2, 0, 0x0F, 1),
315 SOC_SINGLE("BEEP_MAS_VOL", AIC3262_BEEP_CNTL_R2, 6, 3, 0),
317 SOC_DOUBLE_R("AGC_EN", AIC3262_LAGC_CNTL, AIC3262_RAGC_CNTL, 7, 1, 0),
318 SOC_DOUBLE_R("AGC_TARGET_LEVEL", AIC3262_LAGC_CNTL, AIC3262_RAGC_CNTL, 4, 7, 1),
320 SOC_DOUBLE_R("AGC_GAIN_HYSTERESIS", AIC3262_LAGC_CNTL, AIC3262_RAGC_CNTL, 0, 3, 0),
321 SOC_DOUBLE_R("AGC_HYSTERESIS", AIC3262_LAGC_CNTL_R2, AIC3262_RAGC_CNTL_R2, 6, 3, 0),
322 SOC_DOUBLE_R("AGC_NOISE_THRESHOLD", AIC3262_LAGC_CNTL_R2, AIC3262_RAGC_CNTL_R2, 1, 31, 1),
324 SOC_DOUBLE_R("AGC_MAX_GAIN", AIC3262_LAGC_CNTL_R3, AIC3262_RAGC_CNTL_R3, 0, 116, 0),
325 SOC_DOUBLE_R("AGC_ATCK_TIME", AIC3262_LAGC_CNTL_R4, AIC3262_RAGC_CNTL_R4, 3, 31, 0),
326 SOC_DOUBLE_R("AGC_ATCK_SCALE_FACTOR", AIC3262_LAGC_CNTL_R4, AIC3262_RAGC_CNTL_R4, 0, 7, 0),
328 SOC_DOUBLE_R("AGC_DECAY_TIME", AIC3262_LAGC_CNTL_R5, AIC3262_RAGC_CNTL_R5, 3, 31, 0),
329 SOC_DOUBLE_R("AGC_DECAY_SCALE_FACTOR", AIC3262_LAGC_CNTL_R5, AIC3262_RAGC_CNTL_R5, 0, 7, 0),
330 SOC_DOUBLE_R("AGC_NOISE_DEB_TIME", AIC3262_LAGC_CNTL_R6, AIC3262_RAGC_CNTL_R6, 0, 31, 0),
332 SOC_DOUBLE_R("AGC_SGL_DEB_TIME", AIC3262_LAGC_CNTL_R7, AIC3262_RAGC_CNTL_R7, 0, 0x0F, 0),
334 SOC_SINGLE("DAC PRB Selection",AIC3262_DAC_PRB, 0, 26, 0),
335 SOC_SINGLE("ADC PRB Selection",AIC3262_ADC_PRB, 0, 18, 0),
336 SOC_ENUM("Input CM mode", input_cm_mode),
337 SOC_ENUM("Output CM mode", output_cm_mode),
339 SOC_SINGLE_EXT("FIRMWARE LOAD",SND_SOC_NOPM,0,0,0,aic3262_test_get,aic3262_test_put),
340 SOC_SINGLE_EXT("FIRMWARE SET MODE",SND_SOC_NOPM,0,0xffff,0,aic3262_set_mode_get,aic3262_set_mode_put),
345 *----------------------------------------------------------------------------
346 * @struct snd_soc_codec_dai |
347 * It is SoC Codec DAI structure which has DAI capabilities viz.,
348 * playback and capture, DAI runtime information viz. state of DAI
349 * and pop wait state, and DAI private data.
350 * The AIC3262 rates ranges from 8k to 192k
351 * The PCM bit format supported are 16, 20, 24 and 32 bits
352 *----------------------------------------------------------------------------
354 struct snd_soc_dai_ops aic3262_asi1_dai_ops = {
355 .hw_params = aic3262_hw_params,
356 .digital_mute = aic3262_mute,
357 .set_sysclk = aic3262_set_dai_sysclk,
358 .set_fmt = aic3262_set_dai_fmt,
359 .set_pll = aic3262_dai_set_pll,
361 struct snd_soc_dai_ops aic3262_asi2_dai_ops = {
362 .hw_params = aic3262_hw_params,
363 .digital_mute = aic3262_mute,
364 .set_sysclk = aic3262_set_dai_sysclk,
365 .set_fmt = aic3262_set_dai_fmt,
366 .set_pll = aic3262_dai_set_pll,
368 struct snd_soc_dai_ops aic3262_asi3_dai_ops = {
369 .hw_params = aic3262_hw_params,
370 .digital_mute = aic3262_mute,
371 .set_sysclk = aic3262_set_dai_sysclk,
372 .set_fmt = aic3262_set_dai_fmt,
373 .set_pll = aic3262_dai_set_pll,
376 struct snd_soc_dai_driver aic326x_dai_driver[] = {
378 .name = "aic326x-asi1",
380 .stream_name = "ASI1 Playback",
383 .rates = AIC3262_RATES,
384 .formats = AIC3262_FORMATS,
387 .stream_name = "ASI1 Capture",
390 .rates = AIC3262_RATES,
391 .formats = AIC3262_FORMATS,
393 .ops = &aic3262_asi1_dai_ops,
396 .name = "aic326x-asi2",
398 .stream_name = "ASI2 Playback",
401 .rates = AIC3262_RATES,
402 .formats = AIC3262_FORMATS,
405 .stream_name = "ASI2 Capture",
408 .rates = AIC3262_RATES,
409 .formats = AIC3262_FORMATS,
411 .ops = &aic3262_asi2_dai_ops,
414 .name = "aic326x-asi3",
416 .stream_name = "ASI3 Playback",
419 .rates = AIC3262_RATES,
420 .formats = AIC3262_FORMATS,
423 .stream_name = "ASI3 Capture",
426 .rates = AIC3262_RATES,
427 .formats = AIC3262_FORMATS,
429 .ops = &aic3262_asi3_dai_ops,
435 *****************************************************************************
437 *****************************************************************************
440 * AIC3262 register cache
441 * We are caching the registers here.
442 * There is no point in caching the reset register.
444 * NOTE: In AIC3262, there are 127 registers supported in both page0 and page1
445 * The following table contains the page0 and page 1 and page 3
449 static const u8 aic3262_reg[AIC3262_CACHEREGNUM] = {
450 0x00, 0x00, 0x10, 0x00, /* 0 */
451 0x03, 0x40, 0x11, 0x08, /* 4 */
452 0x00, 0x00, 0x00, 0x82, /* 8 */
453 0x88, 0x00, 0x80, 0x02, /* 12 */
454 0x00, 0x08, 0x01, 0x01, /* 16 */
455 0x80, 0x01, 0x00, 0x04, /* 20 */
456 0x00, 0x00, 0x01, 0x00, /* 24 */
457 0x00, 0x00, 0x01, 0x00, /* 28 */
458 0x00, 0x00, 0x00, 0x00, /* 32 */
459 0x00, 0x00, 0x00, 0x00, /* 36 */
460 0x00, 0x00, 0x00, 0x00, /* 40 */
461 0x00, 0x00, 0x00, 0x00, /* 44 */
462 0x00, 0x00, 0x00, 0x00, /* 48 */
463 0x00, 0x42, 0x02, 0x02, /* 52 */
464 0x42, 0x02, 0x02, 0x02, /* 56 */
465 0x00, 0x00, 0x00, 0x01, /* 60 */
466 0x01, 0x00, 0x14, 0x00, /* 64 */
467 0x0C, 0x00, 0x00, 0x00, /* 68 */
468 0x00, 0x00, 0x00, 0xEE, /* 72 */
469 0x10, 0xD8, 0x10, 0xD8, /* 76 */
470 0x00, 0x00, 0x88, 0x00, /* 80 */
471 0x00, 0x00, 0x00, 0x00, /* 84 */
472 0x7F, 0x00, 0x00, 0x00, /* 88 */
473 0x00, 0x00, 0x00, 0x00, /* 92 */
474 0x7F, 0x00, 0x00, 0x00, /* 96 */
475 0x00, 0x00, 0x00, 0x00, /* 100 */
476 0x00, 0x00, 0x00, 0x00, /* 104 */
477 0x00, 0x00, 0x00, 0x00, /* 108 */
478 0x00, 0x00, 0x00, 0x00, /* 112 */
479 0x00, 0x00, 0x00, 0x00, /* 116 */
480 0x00, 0x00, 0x00, 0x00, /* 120 */
481 0x00, 0x00, 0x00, 0x00, /* 124 - PAGE0 Registers(127) ends here */
482 0x01, 0x00, 0x08, 0x00, /* 128, PAGE1-0 */
483 0x00, 0x00, 0x00, 0x00, /* 132, PAGE1-4 */
484 0x00, 0x00, 0x00, 0x10, /* 136, PAGE1-8 */
485 0x00, 0x00, 0x00, 0x00, /* 140, PAGE1-12 */
486 0x40, 0x40, 0x40, 0x40, /* 144, PAGE1-16 */
487 0x00, 0x00, 0x00, 0x00, /* 148, PAGE1-20 */
488 0x00, 0x00, 0x00, 0x00, /* 152, PAGE1-24 */
489 0x00, 0x00, 0x00, 0x00, /* 156, PAGE1-28 */
490 0x00, 0x00, 0x00, 0x00, /* 160, PAGE1-32 */
491 0x00, 0x00, 0x00, 0x00, /* 164, PAGE1-36 */
492 0x00, 0x00, 0x00, 0x00, /* 168, PAGE1-40 */
493 0x00, 0x00, 0x00, 0x00, /* 172, PAGE1-44 */
494 0x00, 0x00, 0x00, 0x00, /* 176, PAGE1-48 */
495 0x00, 0x00, 0x00, 0x00, /* 180, PAGE1-52 */
496 0x00, 0x00, 0x00, 0x80, /* 184, PAGE1-56 */
497 0x80, 0x00, 0x00, 0x00, /* 188, PAGE1-60 */
498 0x00, 0x00, 0x00, 0x00, /* 192, PAGE1-64 */
499 0x00, 0x00, 0x00, 0x00, /* 196, PAGE1-68 */
500 0x00, 0x00, 0x00, 0x00, /* 200, PAGE1-72 */
501 0x00, 0x00, 0x00, 0x00, /* 204, PAGE1-76 */
502 0x00, 0x00, 0x00, 0x00, /* 208, PAGE1-80 */
503 0x00, 0x00, 0x00, 0x00, /* 212, PAGE1-84 */
504 0x00, 0x00, 0x00, 0x00, /* 216, PAGE1-88 */
505 0x00, 0x00, 0x00, 0x00, /* 220, PAGE1-92 */
506 0x00, 0x00, 0x00, 0x00, /* 224, PAGE1-96 */
507 0x00, 0x00, 0x00, 0x00, /* 228, PAGE1-100 */
508 0x00, 0x00, 0x00, 0x00, /* 232, PAGE1-104 */
509 0x00, 0x00, 0x00, 0x00, /* 236, PAGE1-108 */
510 0x00, 0x00, 0x00, 0x00, /* 240, PAGE1-112 */
511 0x00, 0x00, 0x00, 0x00, /* 244, PAGE1-116 */
512 0x00, 0x00, 0x00, 0x00, /* 248, PAGE1-120 */
513 0x00, 0x00, 0x00, 0x00, /* 252, PAGE1-124 Page 1 Registers Ends Here */
514 0x00, 0x00, 0x00, 0x00, /* 256, PAGE2-0 */
515 0x00, 0x00, 0x00, 0x00, /* 260, PAGE2-4 */
516 0x00, 0x00, 0x00, 0x00, /* 264, PAGE2-8 */
517 0x00, 0x00, 0x00, 0x00, /* 268, PAGE2-12 */
518 0x00, 0x00, 0x00, 0x00, /* 272, PAGE2-16 */
519 0x00, 0x00, 0x00, 0x00, /* 276, PAGE2-20 */
520 0x00, 0x00, 0x00, 0x00, /* 280, PAGE2-24 */
521 0x00, 0x00, 0x00, 0x00, /* 284, PAGE2-28 */
522 0x00, 0x00, 0x00, 0x00, /* 288, PAGE2-32 */
523 0x00, 0x00, 0x00, 0x00, /* 292, PAGE2-36 */
524 0x00, 0x00, 0x00, 0x00, /* 296, PAGE2-40 */
525 0x00, 0x00, 0x00, 0x00, /* 300, PAGE2-44 */
526 0x00, 0x00, 0x00, 0x00, /* 304, PAGE2-48 */
527 0x00, 0x00, 0x00, 0x00, /* 308, PAGE2-52 */
528 0x00, 0x00, 0x00, 0x00, /* 312, PAGE2-56 */
529 0x00, 0x00, 0x00, 0x00, /* 316, PAGE2-60 */
530 0x00, 0x00, 0x00, 0x00, /* 320, PAGE2-64 */
531 0x00, 0x00, 0x00, 0x00, /* 324, PAGE2-68 */
532 0x00, 0x00, 0x00, 0x00, /* 328, PAGE2-72 */
533 0x00, 0x00, 0x00, 0x00, /* 332, PAGE2-76 */
534 0x00, 0x00, 0x00, 0x00, /* 336, PAGE2-80 */
535 0x00, 0x00, 0x00, 0x00, /* 340, PAGE2-84 */
536 0x00, 0x00, 0x00, 0x00, /* 344, PAGE2-88 */
537 0x00, 0x00, 0x00, 0x00, /* 348, PAGE2-92 */
538 0x00, 0x00, 0x00, 0x00, /* 352, PAGE2-96 */
539 0x00, 0x00, 0x00, 0x00, /* 356, PAGE2-100 */
540 0x00, 0x00, 0x00, 0x00, /* 360, PAGE2-104 */
541 0x00, 0x00, 0x00, 0x00, /* 364, PAGE2-108 */
542 0x00, 0x00, 0x00, 0x00, /* 368, PAGE2-112*/
543 0x00, 0x00, 0x00, 0x00, /* 372, PAGE2-116*/
544 0x00, 0x00, 0x00, 0x00, /* 376, PAGE2-120*/
545 0x00, 0x00, 0x00, 0x00, /* 380, PAGE2-124 Page 2 Registers Ends Here */
546 0x00, 0x00, 0x00, 0x00, /* 384, PAGE3-0 */
547 0x00, 0x00, 0x00, 0x00, /* 388, PAGE3-4 */
548 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-8 */
549 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-12 */
550 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-16 */
551 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-20 */
552 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-24 */
553 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-28 */
554 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-32 */
555 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-36 */
556 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-40 */
557 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-44 */
558 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-48 */
559 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-52 */
560 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-56 */
561 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-60 */
562 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-64 */
563 0x00, 0x00, 0x00, 0x00, /* 392, PAGE3-68 */
564 0x00, 0x00, 0x00, 0x00, /* 328, PAGE3-72 */
565 0x00, 0x00, 0x00, 0x00, /* 332, PAGE3-76 */
566 0x00, 0x00, 0x00, 0x00, /* 336, PAGE3-80 */
567 0x00, 0x00, 0x00, 0x00, /* 340, PAGE3-84 */
568 0x00, 0x00, 0x00, 0x00, /* 344, PAGE3-88 */
569 0x00, 0x00, 0x00, 0x00, /* 348, PAGE3-92 */
570 0x00, 0x00, 0x00, 0x00, /* 352, PAGE3-96 */
571 0x00, 0x00, 0x00, 0x00, /* 356, PAGE3-100 */
572 0x00, 0x00, 0x00, 0x00, /* 360, PAGE3-104 */
573 0x00, 0x00, 0x00, 0x00, /* 364, PAGE3-108 */
574 0x00, 0x00, 0x00, 0x00, /* 368, PAGE3-112*/
575 0x00, 0x00, 0x00, 0x00, /* 372, PAGE3-116*/
576 0x00, 0x00, 0x00, 0x00, /* 376, PAGE3-120*/
577 0x00, 0x00, 0x00, 0x00, /* 380, PAGE3-124 Page 3 Registers Ends Here */
578 0x00, 0x00, 0x00, 0x00, /* 384, PAGE4-0 */
579 0x00, 0x00, 0x00, 0x00, /* 388, PAGE4-4 */
580 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-8 */
581 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-12 */
582 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-16 */
583 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-20 */
584 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-24 */
585 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-28 */
586 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-32 */
587 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-36 */
588 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-40 */
589 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-44 */
590 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-48 */
591 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-52 */
592 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-56 */
593 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-60 */
594 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-64 */
595 0x00, 0x00, 0x00, 0x00, /* 392, PAGE4-68 */
596 0x00, 0x00, 0x00, 0x00, /* 328, PAGE4-72 */
597 0x00, 0x00, 0x00, 0x00, /* 332, PAGE4-76 */
598 0x00, 0x00, 0x00, 0x00, /* 336, PAGE4-80 */
599 0x00, 0x00, 0x00, 0x00, /* 340, PAGE4-84 */
600 0x00, 0x00, 0x00, 0x00, /* 344, PAGE4-88 */
601 0x00, 0x00, 0x00, 0x00, /* 348, PAGE4-92 */
602 0x00, 0x00, 0x00, 0x00, /* 352, PAGE4-96 */
603 0x00, 0x00, 0x00, 0x00, /* 356, PAGE4-100 */
604 0x00, 0x00, 0x00, 0x00, /* 360, PAGE4-104 */
605 0x00, 0x00, 0x00, 0x00, /* 364, PAGE4-108 */
606 0x00, 0x00, 0x00, 0x00, /* 368, PAGE4-112*/
607 0x00, 0x00, 0x00, 0x00, /* 372, PAGE4-116*/
608 0x00, 0x00, 0x00, 0x00, /* 376, PAGE4-120*/
609 0x00, 0x00, 0x00, 0x00, /* 380, PAGE4-124 Page 2 Registers Ends Here */
612 static const unsigned int adc_ma_tlv[] = {
613 TLV_DB_RANGE_HEAD(4),
614 0, 29, TLV_DB_SCALE_ITEM(-1450, 500, 0),
615 30, 35, TLV_DB_SCALE_ITEM(-2060, 1000, 0),
616 36, 38, TLV_DB_SCALE_ITEM(-2660, 2000, 0),
617 39, 40, TLV_DB_SCALE_ITEM(-3610, 5000, 0),
619 static const DECLARE_TLV_DB_SCALE(lo_hp_tlv, -7830, 50, 0);
620 static const struct snd_kcontrol_new mal_pga_mixer_controls[] = {
621 SOC_DAPM_SINGLE("IN1L Switch", AIC3262_MA_CNTL, 5, 1, 0),
622 SOC_DAPM_SINGLE_TLV("Left MicPGA Volume", AIC3262_LADC_PGA_MAL_VOL, 0, 0x3f, 1, adc_ma_tlv),
626 static const struct snd_kcontrol_new mar_pga_mixer_controls[] = {
627 SOC_DAPM_SINGLE("IN1R Switch", AIC3262_MA_CNTL, 4, 1, 0),
628 SOC_DAPM_SINGLE_TLV("Right MicPGA Volume", AIC3262_RADC_PGA_MAR_VOL, 0, 0x3f, 1, adc_ma_tlv),
632 static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
633 SOC_DAPM_SINGLE("MAL Switch", AIC3262_HP_AMP_CNTL_R1, 7, 1, 0),
634 SOC_DAPM_SINGLE("LDAC Switch", AIC3262_HP_AMP_CNTL_R1, 5, 1, 0),
635 SOC_DAPM_SINGLE_TLV("LOL-B1 Volume", AIC3262_HP_AMP_CNTL_R2, 0, 0x7f, 1, lo_hp_tlv),
638 /* Right HPR Mixer */
639 static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
640 SOC_DAPM_SINGLE_TLV("LOR-B1 Volume", AIC3262_HP_AMP_CNTL_R3, 0, 0x7f, 1, lo_hp_tlv),
641 SOC_DAPM_SINGLE("LDAC Switch", AIC3262_HP_AMP_CNTL_R1, 2, 1, 0),
642 SOC_DAPM_SINGLE("RDAC Switch", AIC3262_HP_AMP_CNTL_R1, 4, 1, 0),
643 SOC_DAPM_SINGLE("MAR Switch", AIC3262_HP_AMP_CNTL_R1, 6, 1, 0),
647 static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
648 SOC_DAPM_SINGLE("MAL Switch", AIC3262_LINE_AMP_CNTL_R2, 7, 1, 0),
649 SOC_DAPM_SINGLE("IN1L-B Switch", AIC3262_LINE_AMP_CNTL_R2, 3, 1,0),
650 SOC_DAPM_SINGLE("LDAC Switch", AIC3262_LINE_AMP_CNTL_R1, 7, 1, 0),
651 SOC_DAPM_SINGLE("RDAC Switch", AIC3262_LINE_AMP_CNTL_R1, 5, 1, 0),
654 /* Right LOR Mixer */
655 static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
656 SOC_DAPM_SINGLE("LOL Switch", AIC3262_LINE_AMP_CNTL_R1, 2, 1, 0),
657 SOC_DAPM_SINGLE("RDAC Switch", AIC3262_LINE_AMP_CNTL_R1, 6, 1, 0),
658 SOC_DAPM_SINGLE("MAR Switch", AIC3262_LINE_AMP_CNTL_R2, 6, 1, 0),
659 SOC_DAPM_SINGLE("IN1R-B Switch", AIC3262_LINE_AMP_CNTL_R2, 0, 1,0),
662 /* Left SPKL Mixer */
663 static const struct snd_kcontrol_new spkl_output_mixer_controls[] = {
664 SOC_DAPM_SINGLE("MAL Switch", AIC3262_SPK_AMP_CNTL_R1, 7, 1, 0),
665 SOC_DAPM_SINGLE_TLV("LOL Volume", AIC3262_SPK_AMP_CNTL_R2, 0, 0x7f,1, lo_hp_tlv),
666 SOC_DAPM_SINGLE("SPR_IN Switch", AIC3262_SPK_AMP_CNTL_R1, 2, 1, 0),
669 /* Right SPKR Mixer */
670 static const struct snd_kcontrol_new spkr_output_mixer_controls[] = {
671 SOC_DAPM_SINGLE_TLV("LOR Volume", AIC3262_SPK_AMP_CNTL_R3, 0, 0x7f, 1, lo_hp_tlv),
672 SOC_DAPM_SINGLE("MAR Switch", AIC3262_SPK_AMP_CNTL_R1, 6, 1, 0),
676 static const struct snd_kcontrol_new rec_output_mixer_controls[] = {
677 SOC_DAPM_SINGLE_TLV("LOL-B2 Volume", AIC3262_RAMP_CNTL_R1, 0, 0x7f,1, lo_hp_tlv),
678 SOC_DAPM_SINGLE_TLV("IN1L Volume", AIC3262_IN1L_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
679 SOC_DAPM_SINGLE_TLV("IN1R Volume", AIC3262_IN1R_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
680 SOC_DAPM_SINGLE_TLV("LOR-B2 Volume", AIC3262_RAMP_CNTL_R2, 0,0x7f, 1,lo_hp_tlv),
683 /* Left Input Mixer */
684 static const struct snd_kcontrol_new left_input_mixer_controls[] = {
685 SOC_DAPM_SINGLE("IN1L Switch", AIC3262_LMIC_PGA_PIN, 6, 3, 0),
686 SOC_DAPM_SINGLE("IN2L Switch", AIC3262_LMIC_PGA_PIN, 4, 3, 0),
687 SOC_DAPM_SINGLE("IN3L Switch", AIC3262_LMIC_PGA_PIN, 2, 3, 0),
688 SOC_DAPM_SINGLE("IN4L Switch", AIC3262_LMIC_PGA_PM_IN4, 5, 1, 0),
689 SOC_DAPM_SINGLE("IN1R Switch", AIC3262_LMIC_PGA_PIN, 0, 3, 0),
690 SOC_DAPM_SINGLE("IN2R Switch", AIC3262_LMIC_PGA_MIN, 4, 3, 0),
691 SOC_DAPM_SINGLE("IN3R Switch", AIC3262_LMIC_PGA_MIN, 2, 3, 0),
692 SOC_DAPM_SINGLE("IN4R Switch", AIC3262_LMIC_PGA_PM_IN4, 4, 1, 0),
693 SOC_DAPM_SINGLE("CM2L Switch", AIC3262_LMIC_PGA_MIN, 0, 3, 0),
694 SOC_DAPM_SINGLE("CM1L Switch", AIC3262_LMIC_PGA_MIN, 6, 3, 0),
697 /* Right Input Mixer */
698 static const struct snd_kcontrol_new right_input_mixer_controls[] = {
699 SOC_DAPM_SINGLE("IN1R Switch", AIC3262_RMIC_PGA_PIN, 6, 3, 0),
700 SOC_DAPM_SINGLE("IN2R Switch", AIC3262_RMIC_PGA_PIN, 4, 3, 0),
701 SOC_DAPM_SINGLE("IN3R Switch", AIC3262_RMIC_PGA_PIN, 2, 3, 0),
702 SOC_DAPM_SINGLE("IN4R Switch", AIC3262_RMIC_PGA_PM_IN4, 5, 1, 0),
703 SOC_DAPM_SINGLE("IN2L Switch", AIC3262_RMIC_PGA_PIN, 0, 3, 0),
704 SOC_DAPM_SINGLE("IN1L Switch", AIC3262_RMIC_PGA_MIN, 4, 3, 0),
705 SOC_DAPM_SINGLE("IN3L Switch", AIC3262_RMIC_PGA_MIN, 2, 3, 0),
706 SOC_DAPM_SINGLE("IN4L Switch", AIC3262_RMIC_PGA_PM_IN4, 4, 1, 0),
707 SOC_DAPM_SINGLE("CM1R Switch", AIC3262_RMIC_PGA_MIN, 6, 3, 0),
708 SOC_DAPM_SINGLE("CM2R Switch", AIC3262_RMIC_PGA_MIN, 0, 3, 0),
711 static const char *asi1lin_text[] = {
712 "Off", "ASI1 Left In","ASI1 Right In","ASI1 MonoMix In"
716 SOC_ENUM_SINGLE_DECL(asi1lin_enum, AIC3262_ASI1_DAC_OUT_CNTL, 6, asi1lin_text);
718 static const struct snd_kcontrol_new asi1lin_control =
719 SOC_DAPM_ENUM("ASI1LIN Route", asi1lin_enum);
722 static const char *asi1rin_text[] = {
723 "Off", "ASI1 Right In","ASI1 Left In","ASI1 MonoMix In"
726 SOC_ENUM_SINGLE_DECL(asi1rin_enum, AIC3262_ASI1_DAC_OUT_CNTL, 4, asi1rin_text);
728 static const struct snd_kcontrol_new asi1rin_control =
729 SOC_DAPM_ENUM("ASI1RIN Route", asi1rin_enum);
731 static const char *asi2lin_text[] = {
732 "Off", "ASI2 Left In","ASI2 Right In","ASI2 MonoMix In"
735 SOC_ENUM_SINGLE_DECL(asi2lin_enum, AIC3262_ASI2_DAC_OUT_CNTL, 6, asi2lin_text);
737 static const struct snd_kcontrol_new asi2lin_control =
738 SOC_DAPM_ENUM("ASI2LIN Route", asi2lin_enum);
740 static const char *asi2rin_text[] = {
741 "Off", "ASI2 Right In","ASI2 Left In","ASI2 MonoMix In"
744 SOC_ENUM_SINGLE_DECL(asi2rin_enum, AIC3262_ASI2_DAC_OUT_CNTL, 4, asi2rin_text);
746 static const struct snd_kcontrol_new asi2rin_control =
747 SOC_DAPM_ENUM("ASI2RIN Route", asi2rin_enum);
749 static const char *asi3lin_text[] = {
750 "Off", "ASI3 Left In","ASI3 Right In","ASI3 MonoMix In"
753 SOC_ENUM_SINGLE_DECL(asi3lin_enum, AIC3262_ASI3_DAC_OUT_CNTL, 6, asi3lin_text);
755 static const struct snd_kcontrol_new asi3lin_control = SOC_DAPM_ENUM("ASI3LIN Route", asi3lin_enum);
758 static const char *asi3rin_text[] = {
759 "Off", "ASI3 Right In","ASI3 Left In","ASI3 MonoMix In"
762 SOC_ENUM_SINGLE_DECL(asi3rin_enum, AIC3262_ASI3_DAC_OUT_CNTL, 4, asi3rin_text);
764 static const struct snd_kcontrol_new asi3rin_control =
765 SOC_DAPM_ENUM("ASI3RIN Route", asi3rin_enum);
768 static const char *dacminidspin1_text[] = {
769 "ASI1 In", "ASI2 In","ASI3 In","ADC MiniDSP Out"
772 SOC_ENUM_SINGLE_DECL(dacminidspin1_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 4, dacminidspin1_text);
774 static const struct snd_kcontrol_new dacminidspin1_control =
775 SOC_DAPM_ENUM("DAC MiniDSP IN1 Route", dacminidspin1_enum);
777 static const char *dacminidspin2_text[] = {
778 "ASI1 In", "ASI2 In","ASI3 In"
781 SOC_ENUM_SINGLE_DECL(dacminidspin2_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 2, dacminidspin2_text);
783 static const struct snd_kcontrol_new dacminidspin2_control =
784 SOC_DAPM_ENUM("DAC MiniDSP IN2 Route", dacminidspin2_enum);
786 static const char *dacminidspin3_text[] = {
787 "ASI1 In", "ASI2 In","ASI3 In"
790 SOC_ENUM_SINGLE_DECL(dacminidspin3_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 0, dacminidspin3_text);
792 static const struct snd_kcontrol_new dacminidspin3_control =
793 SOC_DAPM_ENUM("DAC MiniDSP IN3 Route", dacminidspin3_enum);
796 static const char *adcdac_route_text[] = {
801 SOC_ENUM_SINGLE_DECL(adcdac_enum, 0, 2, adcdac_route_text);
803 static const struct snd_kcontrol_new adcdacroute_control =
804 SOC_DAPM_ENUM_VIRT("ADC DAC Route", adcdac_enum);
806 static const char *dout1_text[] = {
812 SOC_ENUM_SINGLE_DECL(dout1_enum, AIC3262_ASI1_DOUT_CNTL, 0, dout1_text);
813 static const struct snd_kcontrol_new dout1_control =
814 SOC_DAPM_ENUM("DOUT1 Route", dout1_enum);
817 static const char *dout2_text[] = {
823 SOC_ENUM_SINGLE_DECL(dout2_enum, AIC3262_ASI2_DOUT_CNTL, 0, dout2_text);
824 static const struct snd_kcontrol_new dout2_control =
825 SOC_DAPM_ENUM("DOUT2 Route", dout2_enum);
828 static const char *dout3_text[] = {
834 SOC_ENUM_SINGLE_DECL(dout3_enum, AIC3262_ASI3_DOUT_CNTL, 0, dout3_text);
835 static const struct snd_kcontrol_new dout3_control =
836 SOC_DAPM_ENUM("DOUT3 Route", dout3_enum);
838 static const char *asi1out_text[] = {
845 SOC_ENUM_SINGLE_DECL(asi1out_enum, AIC3262_ASI1_ADC_INPUT_CNTL, 0, asi1out_text);
846 static const struct snd_kcontrol_new asi1out_control =
847 SOC_DAPM_ENUM("ASI1OUT Route", asi1out_enum);
849 static const char *asi2out_text[] = {
857 SOC_ENUM_SINGLE_DECL(asi2out_enum, AIC3262_ASI2_ADC_INPUT_CNTL, 0, asi2out_text);
858 static const struct snd_kcontrol_new asi2out_control =
859 SOC_DAPM_ENUM("ASI2OUT Route", asi2out_enum);
860 static const char *asi3out_text[] = {
869 SOC_ENUM_SINGLE_DECL(asi3out_enum, AIC3262_ASI3_ADC_INPUT_CNTL, 0, asi3out_text);
870 static const struct snd_kcontrol_new asi3out_control =
871 SOC_DAPM_ENUM("ASI3OUT Route", asi3out_enum);
872 static const char *asibclk_text[] = {
878 SOC_ENUM_SINGLE_DECL(asi1bclk_enum, AIC3262_ASI1_BCLK_N_CNTL, 0, asibclk_text);
879 static const struct snd_kcontrol_new asi1bclk_control =
880 SOC_DAPM_ENUM("ASI1_BCLK Route", asi1bclk_enum);
882 /*static const char *asi2bclk_text[] = {
888 SOC_ENUM_SINGLE_DECL(asi2bclk_enum, AIC3262_ASI2_BCLK_N_CNTL, 0, asibclk_text);
889 static const struct snd_kcontrol_new asi2bclk_control =
890 SOC_DAPM_ENUM("ASI2_BCLK Route", asi2bclk_enum);
891 /*static const char *asi3bclk_text[] = {
897 SOC_ENUM_SINGLE_DECL(asi3bclk_enum, AIC3262_ASI3_BCLK_N_CNTL, 0, asibclk_text);
898 static const struct snd_kcontrol_new asi3bclk_control =
899 SOC_DAPM_ENUM("ASI3_BCLK Route", asi3bclk_enum);
901 static const char *adc_mux_text[] = {
906 SOC_ENUM_SINGLE_DECL(adcl_enum, AIC3262_ADC_CHANNEL_POW, 4, adc_mux_text);
907 SOC_ENUM_SINGLE_DECL(adcr_enum, AIC3262_ADC_CHANNEL_POW, 2, adc_mux_text);
909 static const struct snd_kcontrol_new adcl_mux =
910 SOC_DAPM_ENUM("Left ADC Route", adcl_enum);
912 static const struct snd_kcontrol_new adcr_mux =
913 SOC_DAPM_ENUM("Right ADC Route", adcr_enum);
915 /*static const char *dmicinput_text[] = {
924 SOC_ENUM_SINGLE_DECL(dmicinput_enum, AIC3262_DMIC_INPUT_CNTL, 0, dmicinput_text);
926 static const struct snd_kcontrol_new dmicinput_control =
927 SOC_DAPM_ENUM("DMICDAT Input Route", dmicinput_enum);
929 static int aic326x_hp_event(struct snd_soc_dapm_widget *w,
930 struct snd_kcontrol *kcontrol, int event)
935 if(w->shift == 1) {// Left HPL
936 reg_mask = AIC3262_HPL_POWER_MASK;
938 if(w->shift == 0) { // Right HPR
939 reg_mask = AIC3262_HPR_POWER_MASK;
942 case SND_SOC_DAPM_POST_PMU:
945 status = snd_soc_read(w->codec,AIC3262_HP_FLAG);
948 }while(((status & reg_mask) == 0x00) && count != 0 ); //wait until hp powered up
950 case SND_SOC_DAPM_POST_PMD:
953 status = snd_soc_read(w->codec,AIC3262_HP_FLAG);
956 }while(((status & reg_mask) == reg_mask) && count != 0 ); //wait until hp powered down
965 /***********************************************************************
966 Arguments : pointer variable to dapm_widget,
967 pointer variable to sound control,
970 Purpose : Headset popup reduction and powering up dsps together
971 when they are in sync mode
972 ************************************************************************/
973 static int aic326x_dac_event(struct snd_soc_dapm_widget *w,
974 struct snd_kcontrol *kcontrol, int event)
980 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(w->codec);
981 int sync_needed = 0, non_sync_state =0;
982 int other_dsp = 0, run_state = 0;
985 if(w->shift == 7) {// Left DAC
986 reg_mask = AIC3262_LDAC_POWER_MASK;
987 run_state_mask = AIC3262_COPS_MDSP_D_L;
989 if (w->shift == 6) { // Right DAC
990 reg_mask = AIC3262_RDAC_POWER_MASK;
991 run_state_mask = AIC3262_COPS_MDSP_D_R;
994 case SND_SOC_DAPM_POST_PMU:
997 status = snd_soc_read(w->codec, AIC3262_DAC_FLAG);
999 } while(((status & reg_mask) == 0)&& count != 0);
1001 sync_needed = SYNC_STATE(aic3262);
1002 non_sync_state = DSP_NON_SYNC_MODE(aic3262->dsp_runstate);
1003 other_dsp = aic3262->dsp_runstate & AIC3262_COPS_MDSP_A;
1005 if( sync_needed && non_sync_state && other_dsp )
1007 run_state = get_runstate(aic3262->codec->control_data);
1008 aic3262_dsp_pwrdwn_status(aic3262);
1009 aic3262_dsp_pwrup(aic3262,run_state);
1011 aic3262->dsp_runstate |= run_state_mask;
1013 case SND_SOC_DAPM_POST_PMD:
1016 status = snd_soc_read(w->codec, AIC3262_DAC_FLAG);
1018 } while(((status & reg_mask) == reg_mask)&& count != 0);
1020 aic3262->dsp_runstate = (aic3262->dsp_runstate & ~run_state_mask);
1031 static int aic326x_spk_event(struct snd_soc_dapm_widget *w,
1032 struct snd_kcontrol *kcontrol, int event)
1038 if(w->shift == 1) {// Left SPK
1039 reg_mask = AIC3262_SPKL_POWER_MASK;
1041 if(w->shift == 0) { // Right SPK
1042 reg_mask = AIC3262_SPKR_POWER_MASK;
1045 case SND_SOC_DAPM_POST_PMU:
1048 status = snd_soc_read(w->codec,AIC3262_HP_FLAG);
1051 }while(((status & reg_mask) == 0x00) && count != 0 ); //wait until spk powered up
1053 case SND_SOC_DAPM_POST_PMD:
1056 status = snd_soc_read(w->codec,AIC3262_HP_FLAG);
1059 }while(((status & reg_mask) == reg_mask) && count != 0 ); //wait until spk powered up
1067 static int pll_power_on_event(struct snd_soc_dapm_widget *w,
1068 struct snd_kcontrol *kcontrol, int event)
1070 if(event == SND_SOC_DAPM_POST_PMU)
1076 static int aic3262_test_get(struct snd_kcontrol *kcontrol,
1077 struct snd_ctl_elem_value *ucontrol)
1083 static int aic3262_test_put(struct snd_kcontrol *kcontrol,
1084 struct snd_ctl_elem_value *ucontrol)
1086 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1088 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
1089 "tlv320aic3262_fw_v1.bin", codec->dev, GFP_KERNEL,
1090 codec, aic3262_firmware_load);
1095 static int aic3262_set_mode_get(struct snd_kcontrol *kcontrol,
1096 struct snd_ctl_elem_value *ucontrol)
1098 //struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1099 //struct aic3262_priv *priv_ds = snd_soc_codec_get_drvdata(codec);
1104 static int aic3262_set_mode_put(struct snd_kcontrol *kcontrol,
1105 struct snd_ctl_elem_value *ucontrol)
1107 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1108 struct aic3262_priv *priv_ds = snd_soc_codec_get_drvdata(codec);
1110 int next_mode=0,next_cfg=0;
1112 next_mode = (ucontrol->value.integer.value[0]>>8);
1113 next_cfg = (ucontrol->value.integer.value[0])&0xFF;
1116 dev_err(codec->dev,"\nFirmware not loaded, no mode switch can occur\n");
1120 mutex_lock(&priv_ds->cfw_mutex);
1121 aic3xxx_cfw_setmode_cfg(priv_ds->cfw_p,next_mode,next_cfg);
1122 mutex_unlock(&priv_ds->cfw_mutex);
1127 static int aic326x_adc_dsp_event(struct snd_soc_dapm_widget *w,struct snd_kcontrol *kcontrol, int event)
1130 int non_sync_state = 0,sync_needed = 0;
1132 int run_state_mask = 0;
1133 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(w->codec);
1135 if(w->shift == 7) {// Left ADC
1136 run_state_mask = AIC3262_COPS_MDSP_A_L;
1138 if (w->shift == 6) { // Right ADC
1139 run_state_mask = AIC3262_COPS_MDSP_A_R;
1142 case SND_SOC_DAPM_POST_PMU:
1143 sync_needed = SYNC_STATE(aic3262);
1144 non_sync_state = DSP_NON_SYNC_MODE(aic3262->dsp_runstate);
1145 other_dsp = aic3262->dsp_runstate & AIC3262_COPS_MDSP_D;
1146 if( sync_needed && non_sync_state && other_dsp ){
1147 run_state = get_runstate(aic3262->codec->control_data);
1148 aic3262_dsp_pwrdwn_status(aic3262);
1149 aic3262_dsp_pwrup(aic3262,run_state);
1151 aic3262->dsp_runstate |= run_state_mask;
1153 case SND_SOC_DAPM_POST_PMD:
1154 aic3262->dsp_runstate = (aic3262->dsp_runstate & ~run_state_mask) ;
1163 static const struct snd_soc_dapm_widget aic3262_dapm_widgets[] = {
1164 /* TODO: Can we switch these off ? */
1165 SND_SOC_DAPM_AIF_IN("DIN1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
1166 SND_SOC_DAPM_AIF_IN("DIN2", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0),
1167 SND_SOC_DAPM_AIF_IN("DIN3", "ASI3 Playback", 0, SND_SOC_NOPM, 0, 0),
1169 SND_SOC_DAPM_DAC_E("Left DAC", NULL, AIC3262_PASI_DAC_DP_SETUP, 7, 0,
1170 aic326x_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1171 SND_SOC_DAPM_DAC_E("Right DAC", NULL, AIC3262_PASI_DAC_DP_SETUP, 6, 0,
1172 aic326x_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1175 /* dapm widget (path domain) for HPL Output Mixer */
1176 SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
1177 &hpl_output_mixer_controls[0],
1178 ARRAY_SIZE(hpl_output_mixer_controls)),
1180 /* dapm widget (path domain) for HPR Output Mixer */
1181 SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
1182 &hpr_output_mixer_controls[0],
1183 ARRAY_SIZE(hpr_output_mixer_controls)),
1186 SND_SOC_DAPM_PGA_E("HPL Driver", AIC3262_HP_AMP_CNTL_R1, 1, 0, NULL, 0, aic326x_hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1187 SND_SOC_DAPM_PGA_E("HPR Driver", AIC3262_HP_AMP_CNTL_R1, 0, 0, NULL, 0, aic326x_hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1190 /* dapm widget (path domain) for LOL Output Mixer */
1191 SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
1192 &lol_output_mixer_controls[0],
1193 ARRAY_SIZE(lol_output_mixer_controls)),
1195 /* dapm widget (path domain) for LOR Output Mixer mixer */
1196 SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
1197 &lor_output_mixer_controls[0],
1198 ARRAY_SIZE(lor_output_mixer_controls)),
1200 SND_SOC_DAPM_PGA("LOL Driver", AIC3262_LINE_AMP_CNTL_R1, 1, 0, NULL, 0),
1201 SND_SOC_DAPM_PGA("LOR Driver", AIC3262_LINE_AMP_CNTL_R1, 0, 0, NULL, 0),
1204 /* dapm widget (path domain) for SPKL Output Mixer */
1205 SND_SOC_DAPM_MIXER("SPKL Output Mixer", SND_SOC_NOPM, 0, 0,
1206 &spkl_output_mixer_controls[0],
1207 ARRAY_SIZE(spkl_output_mixer_controls)),
1209 /* dapm widget (path domain) for SPKR Output Mixer */
1210 SND_SOC_DAPM_MIXER("SPKR Output Mixer", SND_SOC_NOPM, 0, 0,
1211 &spkr_output_mixer_controls[0],
1212 ARRAY_SIZE(spkr_output_mixer_controls)),
1214 SND_SOC_DAPM_PGA_E("SPKL Driver",AIC3262_SPK_AMP_CNTL_R1, 1, 0, NULL, 0,
1215 aic326x_spk_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
1216 SND_SOC_DAPM_PGA_E("SPKR Driver", AIC3262_SPK_AMP_CNTL_R1, 0, 0, NULL, 0,
1217 aic326x_spk_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
1220 /* dapm widget (path domain) for SPKR Output Mixer */
1221 SND_SOC_DAPM_MIXER("REC Output Mixer", SND_SOC_NOPM, 0, 0,
1222 &rec_output_mixer_controls[0],
1223 ARRAY_SIZE(rec_output_mixer_controls)),
1225 SND_SOC_DAPM_PGA("RECP Driver", AIC3262_REC_AMP_CNTL_R5, 7, 0, NULL, 0),
1226 SND_SOC_DAPM_PGA("RECM Driver", AIC3262_REC_AMP_CNTL_R5, 6, 0, NULL, 0),
1229 SND_SOC_DAPM_MUX("ASI1LIN Route",
1230 SND_SOC_NOPM, 0, 0, &asi1lin_control),
1231 SND_SOC_DAPM_MUX("ASI1RIN Route",
1232 SND_SOC_NOPM, 0, 0, &asi1rin_control),
1233 SND_SOC_DAPM_MUX("ASI2LIN Route",
1234 SND_SOC_NOPM, 0, 0, &asi2lin_control),
1235 SND_SOC_DAPM_MUX("ASI2RIN Route",
1236 SND_SOC_NOPM, 0, 0, &asi2rin_control),
1237 SND_SOC_DAPM_MUX("ASI3LIN Route",
1238 SND_SOC_NOPM, 0, 0, &asi3lin_control),
1239 SND_SOC_DAPM_MUX("ASI3RIN Route",
1240 SND_SOC_NOPM, 0, 0, &asi3rin_control),
1242 SND_SOC_DAPM_PGA("ASI1LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1243 SND_SOC_DAPM_PGA("ASI1RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1244 SND_SOC_DAPM_PGA("ASI2LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1245 SND_SOC_DAPM_PGA("ASI2RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1246 SND_SOC_DAPM_PGA("ASI3LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1247 SND_SOC_DAPM_PGA("ASI3RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1248 SND_SOC_DAPM_PGA("ASI1MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1249 SND_SOC_DAPM_PGA("ASI2MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1250 SND_SOC_DAPM_PGA("ASI3MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1251 /* TODO: Can we switch the ASIxIN off? */
1252 SND_SOC_DAPM_PGA("ASI1IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
1253 SND_SOC_DAPM_PGA("ASI2IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
1254 SND_SOC_DAPM_PGA("ASI3IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
1256 SND_SOC_DAPM_MUX("DAC MiniDSP IN1 Route",
1257 SND_SOC_NOPM, 0, 0, &dacminidspin1_control),
1258 SND_SOC_DAPM_MUX("DAC MiniDSP IN2 Route",
1259 SND_SOC_NOPM, 0, 0, &dacminidspin2_control),
1260 SND_SOC_DAPM_MUX("DAC MiniDSP IN3 Route",
1261 SND_SOC_NOPM, 0, 0, &dacminidspin3_control),
1263 SND_SOC_DAPM_VIRT_MUX("ADC DAC Route",
1264 SND_SOC_NOPM, 0, 0, &adcdacroute_control),
1266 SND_SOC_DAPM_PGA("CM", SND_SOC_NOPM, 0, 0, NULL, 0),
1267 SND_SOC_DAPM_PGA("CM1L", SND_SOC_NOPM, 0, 0, NULL, 0),
1268 SND_SOC_DAPM_PGA("CM2L", SND_SOC_NOPM, 0, 0, NULL, 0),
1269 SND_SOC_DAPM_PGA("CM1R", SND_SOC_NOPM, 0, 0, NULL, 0),
1270 SND_SOC_DAPM_PGA("CM2R", SND_SOC_NOPM, 0, 0, NULL, 0),
1272 /* TODO: Can we switch these off ? */
1273 SND_SOC_DAPM_AIF_OUT("DOUT1","ASI1 Capture", 0, SND_SOC_NOPM, 0, 0),
1274 SND_SOC_DAPM_AIF_OUT("DOUT2", "ASI2 Capture",0, SND_SOC_NOPM, 0, 0),
1275 SND_SOC_DAPM_AIF_OUT("DOUT3", "ASI3 Capture",0, SND_SOC_NOPM, 0, 0),
1277 SND_SOC_DAPM_MUX("DOUT1 Route",
1278 SND_SOC_NOPM, 0, 0, &dout1_control),
1279 SND_SOC_DAPM_MUX("DOUT2 Route",
1280 SND_SOC_NOPM, 0, 0, &dout2_control),
1281 SND_SOC_DAPM_MUX("DOUT3 Route",
1282 SND_SOC_NOPM, 0, 0, &dout3_control),
1284 SND_SOC_DAPM_PGA("ASI1OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
1285 SND_SOC_DAPM_PGA("ASI2OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
1286 SND_SOC_DAPM_PGA("ASI3OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
1289 SND_SOC_DAPM_MUX("ASI1OUT Route",
1290 SND_SOC_NOPM, 0, 0, &asi1out_control),
1291 SND_SOC_DAPM_MUX("ASI2OUT Route",
1292 SND_SOC_NOPM, 0, 0, &asi2out_control),
1293 SND_SOC_DAPM_MUX("ASI3OUT Route",
1294 SND_SOC_NOPM, 0, 0, &asi3out_control),
1296 /* TODO: Can we switch the ASI1 OUT1 off? */
1297 /* TODO: Can we switch them off? */
1298 SND_SOC_DAPM_PGA("ADC MiniDSP OUT1", SND_SOC_NOPM, 0, 0, NULL, 0),
1299 SND_SOC_DAPM_PGA("ADC MiniDSP OUT2", SND_SOC_NOPM, 0, 0, NULL, 0),
1300 SND_SOC_DAPM_PGA("ADC MiniDSP OUT3", SND_SOC_NOPM, 0, 0, NULL, 0),
1302 ///M SND_SOC_DAPM_PGA("GPI1 PIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1303 ///M SND_SOC_DAPM_PGA("GPI2 PIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1304 ///M SND_SOC_DAPM_PGA("DIN1 PIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1305 ///M SND_SOC_DAPM_PGA("DIN2 PIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1306 ///M SND_SOC_DAPM_PGA("GPIO1 PIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1307 ///M SND_SOC_DAPM_PGA("GPIO2 PIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1308 ///M SND_SOC_DAPM_PGA("MCLK2 PIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1310 // SND_SOC_DAPM_MUX("DMICDAT Input Route",
1311 // SND_SOC_NOPM, 0, 0, &dmicinput_control),
1313 SND_SOC_DAPM_MUX("Left ADC Route", SND_SOC_NOPM,0, 0, &adcl_mux),
1314 SND_SOC_DAPM_MUX("Right ADC Route", SND_SOC_NOPM,0, 0, &adcr_mux),
1316 SND_SOC_DAPM_ADC_E("Left ADC", NULL, AIC3262_ADC_CHANNEL_POW, 7, 0,
1317 aic326x_adc_dsp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1318 SND_SOC_DAPM_ADC_E("Right ADC", NULL, AIC3262_ADC_CHANNEL_POW, 6, 0,
1319 aic326x_adc_dsp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1321 SND_SOC_DAPM_PGA("Left MicPGA",AIC3262_MICL_PGA, 7, 1, NULL, 0),
1322 SND_SOC_DAPM_PGA("Right MicPGA",AIC3262_MICR_PGA, 7, 1, NULL, 0),
1324 SND_SOC_DAPM_PGA("MAL PGA", AIC3262_MA_CNTL, 3, 0, NULL, 0),
1325 SND_SOC_DAPM_PGA("MAR PGA", AIC3262_MA_CNTL, 2, 0, NULL, 0),
1327 /* dapm widget for MAL PGA Mixer*/
1328 SND_SOC_DAPM_MIXER("MAL PGA Mixer", SND_SOC_NOPM, 0, 0,
1329 &mal_pga_mixer_controls[0],
1330 ARRAY_SIZE(mal_pga_mixer_controls)),
1332 /* dapm widget for MAR PGA Mixer*/
1333 SND_SOC_DAPM_MIXER("MAR PGA Mixer", SND_SOC_NOPM, 0, 0,
1334 &mar_pga_mixer_controls[0],
1335 ARRAY_SIZE(mar_pga_mixer_controls)),
1337 /* dapm widget for Left Input Mixer*/
1338 SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
1339 &left_input_mixer_controls[0],
1340 ARRAY_SIZE(left_input_mixer_controls)),
1342 /* dapm widget for Right Input Mixer*/
1343 SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
1344 &right_input_mixer_controls[0],
1345 ARRAY_SIZE(right_input_mixer_controls)),
1347 SND_SOC_DAPM_OUTPUT("HPL"),
1348 SND_SOC_DAPM_OUTPUT("HPR"),
1349 SND_SOC_DAPM_OUTPUT("LOL"),
1350 SND_SOC_DAPM_OUTPUT("LOR"),
1351 SND_SOC_DAPM_OUTPUT("SPKL"),
1352 SND_SOC_DAPM_OUTPUT("SPKR"),
1353 SND_SOC_DAPM_OUTPUT("RECP"),
1354 SND_SOC_DAPM_OUTPUT("RECM"),
1356 SND_SOC_DAPM_INPUT("IN1L"),
1357 SND_SOC_DAPM_INPUT("IN2L"),
1358 SND_SOC_DAPM_INPUT("IN3L"),
1359 SND_SOC_DAPM_INPUT("IN4L"),
1360 SND_SOC_DAPM_INPUT("IN1R"),
1361 SND_SOC_DAPM_INPUT("IN2R"),
1362 SND_SOC_DAPM_INPUT("IN3R"),
1363 SND_SOC_DAPM_INPUT("IN4R"),
1364 // SND_SOC_DAPM_INPUT("DMICDAT"),
1365 SND_SOC_DAPM_INPUT("Left DMIC"),
1366 SND_SOC_DAPM_INPUT("Right DMIC"),
1369 SND_SOC_DAPM_MICBIAS("Mic Bias Ext", AIC3262_MIC_BIAS_CNTL, 6, 0),
1370 SND_SOC_DAPM_MICBIAS("Mic Bias Int", AIC3262_MIC_BIAS_CNTL, 2, 0),
1373 SND_SOC_DAPM_SUPPLY("PLLCLK",AIC3262_PLL_PR_POW_REG,7,0,pll_power_on_event,SND_SOC_DAPM_POST_PMU),
1374 SND_SOC_DAPM_SUPPLY("DACCLK",AIC3262_NDAC_DIV_POW_REG,7,0, NULL, 0),
1375 SND_SOC_DAPM_SUPPLY("CODEC_CLK_IN",SND_SOC_NOPM,0,0, NULL, 0),
1376 SND_SOC_DAPM_SUPPLY("DAC_MOD_CLK",AIC3262_MDAC_DIV_POW_REG,7,0, NULL, 0),
1377 SND_SOC_DAPM_SUPPLY("ADCCLK",AIC3262_NADC_DIV_POW_REG,7,0, NULL, 0),
1378 SND_SOC_DAPM_SUPPLY("ADC_MOD_CLK",AIC3262_MADC_DIV_POW_REG,7,0, NULL, 0),
1379 SND_SOC_DAPM_SUPPLY("ASI1_BCLK",AIC3262_ASI1_BCLK_N,7,0, NULL, 0),
1380 SND_SOC_DAPM_SUPPLY("ASI1_WCLK",AIC3262_ASI1_WCLK_N,7,0, NULL, 0),
1381 SND_SOC_DAPM_SUPPLY("ASI2_BCLK",AIC3262_ASI2_BCLK_N,7,0, NULL, 0),
1382 SND_SOC_DAPM_SUPPLY("ASI2_WCLK",AIC3262_ASI2_WCLK_N,7,0, NULL, 0),
1383 SND_SOC_DAPM_SUPPLY("ASI3_BCLK",AIC3262_ASI3_BCLK_N,7,0, NULL, 0),
1384 SND_SOC_DAPM_SUPPLY("ASI3_WCLK",AIC3262_ASI3_WCLK_N,7,0, NULL, 0),
1385 SND_SOC_DAPM_MUX("ASI1_BCLK Route",
1386 SND_SOC_NOPM, 0, 0, &asi1bclk_control),
1387 SND_SOC_DAPM_MUX("ASI2_BCLK Route",
1388 SND_SOC_NOPM, 0, 0, &asi2bclk_control),
1389 SND_SOC_DAPM_MUX("ASI3_BCLK Route",
1390 SND_SOC_NOPM, 0, 0, &asi3bclk_control),
1393 static const struct snd_soc_dapm_route aic3262_dapm_routes[] ={
1394 /* TODO: Do we need only DACCLK for ASIIN's and ADCCLK for ASIOUT??? */
1396 {"CODEC_CLK_IN", NULL, "PLLCLK"},
1397 {"DACCLK", NULL, "CODEC_CLK_IN"},
1398 {"ADCCLK", NULL, "CODEC_CLK_IN"},
1399 {"DAC_MOD_CLK", NULL, "DACCLK"},
1400 #ifdef AIC3262_SYNC_MODE
1401 {"ADC_MOD_CLK", NULL,"DACCLK"},
1403 {"ADC_MOD_CLK", NULL, "ADCCLK"},
1406 {"ASI1_BCLK Route","DAC_CLK","DACCLK"},
1407 {"ASI1_BCLK Route","DAC_MOD_CLK","DAC_MOD_CLK"},
1408 {"ASI1_BCLK Route","ADC_CLK","ADCCLK"},
1409 {"ASI1_BCLK Route","ADC_MOD_CLK","ADC_MOD_CLK"},
1411 {"ASI2_BCLK Route","DAC_CLK","DACCLK"},
1412 {"ASI2_BCLK Route","DAC_MOD_CLK","DAC_MOD_CLK"},
1413 {"ASI2_BCLK Route","ADC_CLK","ADCCLK"},
1414 {"ASI2_BCLK Route","ADC_MOD_CLK","ADC_MOD_CLK"},
1416 {"ASI3_BCLK Route","DAC_CLK","DACCLK"},
1417 {"ASI3_BCLK Route","DAC_MOD_CLK","DAC_MOD_CLK"},
1418 {"ASI3_BCLK Route","ADC_CLK","ADCCLK"},
1419 {"ASI3_BCLK Route","ADC_MOD_CLK","ADC_MOD_CLK"},
1421 {"ASI1_BCLK", NULL, "ASI1_BCLK Route"},
1422 {"ASI2_BCLK", NULL, "ASI2_BCLK Route"},
1423 {"ASI3_BCLK", NULL, "ASI3_BCLK Route"},
1426 {"DIN1", NULL , "PLLCLK"},
1427 {"DIN1", NULL , "DACCLK"},
1428 {"DIN1", NULL , "ADCCLK"},
1429 {"DIN1", NULL , "DAC_MOD_CLK"},
1430 {"DIN1", NULL , "ADC_MOD_CLK"},
1432 {"DOUT1", NULL , "PLLCLK"},
1433 {"DOUT1", NULL , "DACCLK"},
1434 {"DOUT1", NULL , "ADCCLK"},
1435 {"DOUT1", NULL , "DAC_MOD_CLK"},
1436 {"DOUT1", NULL , "ADC_MOD_CLK"},
1437 #ifdef AIC3262_ASI1_MASTER
1438 {"DIN1", NULL , "ASI1_BCLK"},
1439 {"DOUT1", NULL , "ASI1_BCLK"},
1440 {"DIN1", NULL , "ASI1_WCLK"},
1441 {"DOUT1", NULL , "ASI1_WCLK"},
1446 {"DIN2", NULL , "PLLCLK"},
1447 {"DIN2", NULL , "DACCLK"},
1448 {"DIN2", NULL , "ADCCLK"},
1449 {"DIN2", NULL , "DAC_MOD_CLK"},
1450 {"DIN2", NULL , "ADC_MOD_CLK"},
1452 {"DOUT2", NULL , "PLLCLK"},
1453 {"DOUT2", NULL , "DACCLK"},
1454 {"DOUT2", NULL , "ADCCLK"},
1455 {"DOUT2", NULL , "DAC_MOD_CLK"},
1456 {"DOUT2", NULL , "ADC_MOD_CLK"},
1458 #ifdef AIC3262_ASI2_MASTER
1459 {"DIN2", NULL , "ASI2_BCLK"},
1460 {"DOUT2", NULL , "ASI2_BCLK"},
1461 {"DIN2", NULL , "ASI2_WCLK"},
1462 {"DOUT2", NULL , "ASI2_WCLK"},
1466 {"DIN3", NULL , "PLLCLK"},
1467 {"DIN3", NULL , "DACCLK"},
1468 {"DIN3", NULL , "ADCCLK"},
1469 {"DIN3", NULL , "DAC_MOD_CLK"},
1470 {"DIN3", NULL , "ADC_MOD_CLK"},
1473 {"DOUT3", NULL , "PLLCLK"},
1474 {"DOUT3", NULL , "DACCLK"},
1475 {"DOUT3", NULL , "ADCCLK"},
1476 {"DOUT3", NULL , "DAC_MOD_CLK"},
1477 {"DOUT3", NULL , "ADC_MOD_CLK"},
1479 #ifdef AIC3262_ASI3_MASTER
1480 {"DIN3", NULL , "ASI3_BCLK"},
1481 {"DOUT3", NULL , "ASI3_BCLK"},
1482 {"DIN3", NULL , "ASI3_WCLK"},
1483 {"DOUT3", NULL , "ASI3_WCLK"},
1487 /* Playback (DAC) Portion */
1488 {"HPL Output Mixer","LDAC Switch","Left DAC"},
1489 {"HPL Output Mixer","MAL Switch","MAL PGA"},
1490 {"HPL Output Mixer","LOL-B1 Volume","LOL"},
1492 {"HPR Output Mixer","LOR-B1 Volume","LOR"},
1493 {"HPR Output Mixer","LDAC Switch","Left DAC"},
1494 {"HPR Output Mixer","RDAC Switch","Right DAC"},
1495 {"HPR Output Mixer","MAR Switch","MAR PGA"},
1497 {"HPL Driver",NULL,"HPL Output Mixer"},
1498 {"HPR Driver",NULL,"HPR Output Mixer"},
1500 {"HPL",NULL,"HPL Driver"},
1501 {"HPR",NULL,"HPR Driver"},
1503 {"LOL Output Mixer","MAL Switch","MAL PGA"},
1504 {"LOL Output Mixer","IN1L-B Switch","IN1L"},
1505 {"LOL Output Mixer","LDAC Switch","Left DAC"},
1506 {"LOL Output Mixer","RDAC Switch","Right DAC"},
1508 {"LOR Output Mixer","LOL Switch","LOL"},
1509 {"LOR Output Mixer","RDAC Switch","Right DAC"},
1510 {"LOR Output Mixer","MAR Switch","MAR PGA"},
1511 {"LOR Output Mixer","IN1R-B Switch","IN1R"},
1513 {"LOL Driver",NULL,"LOL Output Mixer"},
1514 {"LOR Driver",NULL,"LOR Output Mixer"},
1516 {"LOL",NULL,"LOL Driver"},
1517 {"LOR",NULL,"LOR Driver"},
1519 {"REC Output Mixer","LOL-B2 Volume","LOL"},
1520 {"REC Output Mixer","IN1L Volume","IN1L"},
1521 {"REC Output Mixer","IN1R Volume","IN1R"},
1522 {"REC Output Mixer","LOR-B2 Volume","LOR"},
1524 {"RECP Driver",NULL,"REC Output Mixer"},
1525 {"RECM Driver",NULL,"REC Output Mixer"},
1527 {"RECP",NULL,"RECP Driver"},
1528 {"RECM",NULL,"RECM Driver"},
1530 {"SPKL Output Mixer","MAL Switch","MAL PGA"},
1531 {"SPKL Output Mixer","LOL Volume","LOL"},
1532 {"SPKL Output Mixer","SPR_IN Switch","SPKR Output Mixer"},
1534 {"SPKR Output Mixer", "LOR Volume","LOR"},
1535 {"SPKR Output Mixer", "MAR Switch","MAR PGA"},
1538 {"SPKL Driver",NULL,"SPKL Output Mixer"},
1539 {"SPKR Driver",NULL,"SPKR Output Mixer"},
1541 {"SPKL",NULL,"SPKL Driver"},
1542 {"SPKR",NULL,"SPKR Driver"},
1543 /* ASI Input routing */
1544 {"ASI1LIN", NULL, "DIN1"},
1545 {"ASI1RIN", NULL, "DIN1"},
1546 {"ASI1MonoMixIN", NULL, "DIN1"},
1547 {"ASI2LIN", NULL, "DIN2"},
1548 {"ASI2RIN", NULL, "DIN2"},
1549 {"ASI2MonoMixIN", NULL, "DIN2"},
1550 {"ASI3LIN", NULL, "DIN3"},
1551 {"ASI3RIN", NULL, "DIN3"},
1552 {"ASI3MonoMixIN", NULL, "DIN3"},
1554 {"ASI1LIN Route","ASI1 Left In","ASI1LIN"},
1555 {"ASI1LIN Route","ASI1 Right In","ASI1RIN"},
1556 {"ASI1LIN Route","ASI1 MonoMix In","ASI1MonoMixIN"},
1558 {"ASI1RIN Route","ASI1 Right In","ASI1RIN"},
1559 {"ASI1RIN Route","ASI1 Left In","ASI1LIN"},
1560 {"ASI1RIN Route","ASI1 MonoMix In","ASI1MonoMixIN"},
1563 {"ASI2LIN Route","ASI2 Left In","ASI2LIN"},
1564 {"ASI2LIN Route","ASI2 Right In","ASI2RIN"},
1565 {"ASI2LIN Route","ASI2 MonoMix In","ASI2MonoMixIN"},
1567 {"ASI2RIN Route","ASI2 Right In","ASI2RIN"},
1568 {"ASI2RIN Route","ASI2 Left In","ASI2LIN"},
1569 {"ASI2RIN Route","ASI2 MonoMix In","ASI2MonoMixIN"},
1572 {"ASI3LIN Route","ASI3 Left In","ASI3LIN"},
1573 {"ASI3LIN Route","ASI3 Right In","ASI3RIN"},
1574 {"ASI3LIN Route","ASI3 MonoMix In","ASI3MonoMixIN"},
1576 {"ASI3RIN Route","ASI3 Right In","ASI3RIN"},
1577 {"ASI3RIN Route","ASI3 Left In","ASI3LIN"},
1578 {"ASI3RIN Route","ASI3 MonoMix In","ASI3MonoMixIN"},
1580 {"ASI1IN Port", NULL, "ASI1LIN Route"},
1581 {"ASI1IN Port", NULL, "ASI1RIN Route"},
1582 {"ASI2IN Port", NULL, "ASI2LIN Route"},
1583 {"ASI2IN Port", NULL, "ASI2RIN Route"},
1584 {"ASI3IN Port", NULL, "ASI3LIN Route"},
1585 {"ASI3IN Port", NULL, "ASI3RIN Route"},
1587 {"DAC MiniDSP IN1 Route","ASI1 In","ASI1IN Port"},
1588 {"DAC MiniDSP IN1 Route","ASI2 In","ASI2IN Port"},
1589 {"DAC MiniDSP IN1 Route","ASI3 In","ASI3IN Port"},
1590 {"DAC MiniDSP IN1 Route","ADC MiniDSP Out","ADC MiniDSP OUT1"},
1592 {"DAC MiniDSP IN2 Route","ASI1 In","ASI1IN Port"},
1593 {"DAC MiniDSP IN2 Route","ASI2 In","ASI2IN Port"},
1594 {"DAC MiniDSP IN2 Route","ASI3 In","ASI3IN Port"},
1596 {"DAC MiniDSP IN3 Route","ASI1 In","ASI1IN Port"},
1597 {"DAC MiniDSP IN3 Route","ASI2 In","ASI2IN Port"},
1598 {"DAC MiniDSP IN3 Route","ASI3 In","ASI3IN Port"},
1601 {"Left DAC", "NULL","DAC MiniDSP IN1 Route"},
1602 {"Right DAC", "NULL","DAC MiniDSP IN1 Route"},
1603 {"Left DAC", "NULL","DAC MiniDSP IN2 Route"},
1604 {"Right DAC", "NULL","DAC MiniDSP IN2 Route"},
1605 {"Left DAC", "NULL","DAC MiniDSP IN3 Route"},
1606 {"Right DAC", "NULL","DAC MiniDSP IN3 Route"},
1611 /* Mixer Amplifier */
1613 {"MAL PGA Mixer", "IN1L Switch","IN1L"},
1614 {"MAL PGA Mixer", "Left MicPGA Volume","Left MicPGA"},
1616 {"MAL PGA", NULL, "MAL PGA Mixer"},
1619 {"MAR PGA Mixer", "IN1R Switch","IN1R"},
1620 {"MAR PGA Mixer", "Right MicPGA Volume","Right MicPGA"},
1622 {"MAR PGA", NULL, "MAR PGA Mixer"},
1625 /* Virtual connection between DAC and ADC for miniDSP IPC */
1626 {"ADC DAC Route", "On", "Left ADC"},
1627 {"ADC DAC Route", "On", "Right ADC"},
1629 {"Left DAC", NULL, "ADC DAC Route"},
1630 {"Right DAC", NULL, "ADC DAC Route"},
1632 /* Capture (ADC) portions */
1633 /* Left Positive PGA input */
1634 {"Left Input Mixer","IN1L Switch","IN1L"},
1635 {"Left Input Mixer","IN2L Switch","IN2L"},
1636 {"Left Input Mixer","IN3L Switch","IN3L"},
1637 {"Left Input Mixer","IN4L Switch","IN4L"},
1638 {"Left Input Mixer","IN1R Switch","IN1R"},
1639 /* Left Negative PGA input */
1640 {"Left Input Mixer","IN2R Switch","IN2R"},
1641 {"Left Input Mixer","IN3R Switch","IN3R"},
1642 {"Left Input Mixer","IN4R Switch","IN4R"},
1643 {"Left Input Mixer","CM2L Switch","CM2L"},
1644 {"Left Input Mixer","CM1L Switch","CM1L"},
1647 /* Right Positive PGA Input */
1648 {"Right Input Mixer","IN1R Switch","IN1R"},
1649 {"Right Input Mixer","IN2R Switch","IN2R"},
1650 {"Right Input Mixer","IN3R Switch","IN3R"},
1651 {"Right Input Mixer","IN4R Switch","IN4R"},
1652 {"Right Input Mixer","IN2L Switch","IN2L"},
1653 /* Right Negative PGA Input */
1654 {"Right Input Mixer","IN1L Switch","IN1L"},
1655 {"Right Input Mixer","IN3L Switch","IN3L"},
1656 {"Right Input Mixer","IN4L Switch","IN4L"},
1657 {"Right Input Mixer","CM1R Switch","CM1R"},
1658 {"Right Input Mixer","CM2R Switch","CM2R"},
1661 {"CM1L", NULL, "CM"},
1662 {"CM2L", NULL, "CM"},
1663 {"CM1R", NULL, "CM"},
1664 {"CM1R", NULL, "CM"},
1666 {"Left MicPGA",NULL,"Left Input Mixer"},
1667 {"Right MicPGA",NULL,"Right Input Mixer"},
1669 /* {"DMICDAT Input Route","GPI1","GPI1 Pin"},
1670 {"DMICDAT Input Route","GPI2","GPI2 Pin"},
1671 {"DMICDAT Input Route","DIN1","DIN1 Pin"},
1672 {"DMICDAT Input Route","GPIO1","GPIO1 Pin"},
1673 {"DMICDAT Input Route","GPIO2","GPIO2 Pin"},
1674 {"DMICDAT Input Route","MCLK2","MCLK2 Pin"},
1676 {"DMICDAT", NULL, "DMICDAT Input Route"},
1677 {"DMICDAT", NULL, "ADC_MOD_CLK"},
1679 // {"Left DMIC", NULL, "DMICDAT"},
1680 // {"Right DMIC", NULL, "DMICDAT"},
1682 {"Left ADC Route", "Analog","Left MicPGA"},
1683 {"Left ADC Route", "Digital", "Left DMIC"},
1685 {"Right ADC Route", "Analog","Right MicPGA"},
1686 {"Right ADC Route", "Digital", "Right DMIC"},
1688 {"Left ADC", NULL, "Left ADC Route"},
1689 {"Right ADC", NULL, "Right ADC Route"},
1692 /* ASI Output Routing */
1693 {"ADC MiniDSP OUT1", NULL, "Left ADC"},
1694 {"ADC MiniDSP OUT1", NULL, "Right ADC"},
1695 {"ADC MiniDSP OUT2", NULL, "Left ADC"},
1696 {"ADC MiniDSP OUT2", NULL, "Right ADC"},
1697 {"ADC MiniDSP OUT3", NULL, "Left ADC"},
1698 {"ADC MiniDSP OUT3", NULL, "Right ADC"},
1701 {"ASI1OUT Route", "ADC MiniDSP Out1","ADC MiniDSP OUT1"},// Port 1
1702 {"ASI1OUT Route", "ASI1In Bypass","ASI1IN Port"},
1703 {"ASI1OUT Route", "ASI2In Bypass","ASI2IN Port"},
1704 {"ASI1OUT Route", "ASI3In Bypass","ASI3IN Port"},
1706 {"ASI2OUT Route", "ADC MiniDSP Out1","ADC MiniDSP OUT1"},// Port 1
1707 {"ASI2OUT Route", "ASI1In Bypass","ASI1IN Port"},
1708 {"ASI2OUT Route", "ASI2In Bypass","ASI2IN Port"},
1709 {"ASI2OUT Route", "ASI3In Bypass","ASI3IN Port"},
1710 {"ASI2OUT Route", "ADC MiniDSP Out2","ADC MiniDSP OUT2"},// Port 2
1712 {"ASI3OUT Route", "ADC MiniDSP Out1","ADC MiniDSP OUT1"},// Port 1
1713 {"ASI3OUT Route", "ASI1In Bypass","ASI1IN Port"},
1714 {"ASI3OUT Route", "ASI2In Bypass","ASI2IN Port"},
1715 {"ASI3OUT Route", "ASI3In Bypass","ASI3IN Port"},
1716 {"ASI3OUT Route", "ADC MiniDSP Out3","ADC MiniDSP OUT3"},// Port 3
1718 {"ASI1OUT",NULL,"ASI1OUT Route"},
1719 {"ASI2OUT",NULL,"ASI2OUT Route"},
1720 {"ASI3OUT",NULL,"ASI3OUT Route"},
1723 {"DOUT1 Route", "ASI1 Out", "ASI1OUT"},
1724 {"DOUT1 Route", "DIN1 Bypass", "DIN1"},
1725 {"DOUT1 Route", "DIN2 Bypass", "DIN2"},
1726 {"DOUT1 Route", "DIN3 Bypass", "DIN3"},
1728 {"DOUT2 Route", "ASI2 Out", "ASI2OUT"},
1729 {"DOUT2 Route", "DIN1 Bypass", "DIN1"},
1730 {"DOUT2 Route", "DIN2 Bypass", "DIN2"},
1731 {"DOUT2 Route", "DIN3 Bypass", "DIN3"},
1733 {"DOUT3 Route", "ASI3 Out", "ASI3OUT"},
1734 {"DOUT3 Route", "DIN1 Bypass", "DIN1"},
1735 {"DOUT3 Route", "DIN2 Bypass", "DIN2"},
1736 {"DOUT3 Route", "DIN3 Bypass", "DIN3"},
1738 {"DOUT1", NULL, "DOUT1 Route"},
1739 {"DOUT2", NULL, "DOUT2 Route"},
1740 {"DOUT3", NULL, "DOUT3 Route"},
1744 #define AIC3262_DAPM_ROUTE_NUM (sizeof(aic3262_dapm_routes)/sizeof(struct snd_soc_dapm_route))
1747 /* aic3262_firmware_load
1748 This function is called by the request_firmware_nowait function as soon
1749 as the firmware has been loaded from the file. The firmware structure
1750 contains the data and the size of the firmware loaded.
1753 void aic3262_firmware_load(const struct firmware *fw, void *context)
1755 struct snd_soc_codec *codec = context;
1756 struct aic3262_priv *private_ds = snd_soc_codec_get_drvdata(codec);
1758 mutex_lock(&private_ds->cfw_mutex);
1759 if(private_ds->cur_fw != NULL) release_firmware(private_ds->cur_fw);
1760 private_ds->cur_fw = NULL ;
1763 dev_dbg(codec->dev,"Default firmware load\n");
1764 /*Request firmware failed due to non availbility of firmware file. Hence,Default firmware is getting loaded */
1765 if(!private_ds->isdefault_fw) // default firmware is already loaded
1767 aic3xxx_cfw_reload( private_ds->cfw_p,default_firmware,sizeof(default_firmware) );
1768 private_ds->isdefault_fw = 1;
1769 //init function for transition
1770 aic3xxx_cfw_transition(private_ds->cfw_p,"INIT");
1775 dev_dbg(codec->dev,"Firmware load\n");
1776 private_ds->cur_fw = fw;
1777 aic3xxx_cfw_reload(private_ds->cfw_p,(void*)fw->data,fw->size);
1778 private_ds->isdefault_fw = 0;
1779 //init function for transition
1780 aic3xxx_cfw_transition(private_ds->cfw_p,"INIT");
1782 // when new firmware is loaded, mode is changed to zero and config is changed to zero
1783 aic3xxx_cfw_setmode_cfg(private_ds->cfw_p,0,0);
1784 mutex_unlock(&private_ds->cfw_mutex);
1788 *****************************************************************************
1789 * Function Definitions
1790 *****************************************************************************
1793 /* headset work and headphone/headset jack interrupt handlers */
1796 static void aic3262_hs_jack_report(struct snd_soc_codec *codec,
1797 struct snd_soc_jack *jack, int report)
1799 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1800 int status, state = 0;
1802 mutex_lock(&aic3262->mutex);
1805 status = snd_soc_read(codec, AIC3262_DAC_FLAG);
1806 // We will check only stereo MIC and headphone
1807 if(status & AIC3262_JACK_WITH_STEREO_HS)
1808 state |= SND_JACK_HEADPHONE;
1809 if(status & AIC3262_JACK_WITH_MIC)
1810 state |= SND_JACK_MICROPHONE;
1813 mutex_unlock(&aic3262->mutex);
1815 snd_soc_jack_report(jack, state, report);
1816 if (&aic3262->hs_jack.sdev)
1817 switch_set_state(&aic3262->hs_jack.sdev, !!state);
1820 void aic3262_hs_jack_detect(struct snd_soc_codec *codec,
1821 struct snd_soc_jack *jack, int report)
1823 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1824 struct aic3262_jack_data *hs_jack = &aic3262->hs_jack;
1826 hs_jack->jack = jack;
1827 hs_jack->report = report;
1829 aic3262_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
1831 EXPORT_SYMBOL_GPL(aic3262_hs_jack_detect);
1833 static void aic3262_accessory_work(struct work_struct *work)
1835 struct aic3262_priv *aic3262 = container_of(work,
1836 struct aic3262_priv, delayed_work.work);
1837 struct snd_soc_codec *codec = aic3262->codec;
1838 struct aic3262_jack_data *hs_jack = &aic3262->hs_jack;
1840 aic3262_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
1843 /* audio interrupt handler */
1844 /*static irqreturn_t aic3262_audio_handler(int irq, void *data)
1846 struct snd_soc_codec *codec = data;
1847 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1849 queue_delayed_work(aic3262->workqueue, &aic3262->delayed_work,
1850 msecs_to_jiffies(200));
1856 *----------------------------------------------------------------------------
1857 * Function : aic3262_write_reg_cache
1858 * Purpose : This function is to write aic3262 register cache
1860 *----------------------------------------------------------------------------
1862 void aic3262_write_reg_cache(struct snd_soc_codec *codec,
1865 u8 *cache = codec->reg_cache;
1867 if (reg >= AIC3262_CACHEREGNUM) {
1875 *----------------------------------------------------------------------------
1876 * Function : aic3262_codec_read
1877 * Purpose : This function is to read the aic3262 register space.
1879 *----------------------------------------------------------------------------
1881 unsigned int aic3262_codec_read(struct snd_soc_codec *codec, unsigned int reg)
1885 aic326x_reg_union *aic_reg = (aic326x_reg_union *)®
1886 value = aic3262_reg_read(codec->control_data, reg);
1887 dev_dbg(codec->dev,"p %d ,r 30 %x %x \n",aic_reg->aic326x_register.page,aic_reg->aic326x_register.offset,value);
1892 *----------------------------------------------------------------------------
1893 * Function : aic3262_write
1894 * Purpose : This function is to write to the aic3262 register space.
1896 *----------------------------------------------------------------------------
1898 int aic3262_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
1900 aic326x_reg_union *aic_reg = (aic326x_reg_union *)®
1901 dev_dbg(codec->dev,"p %d,w 30 %x %x \n",aic_reg->aic326x_register.page,aic_reg->aic326x_register.offset,value);
1902 return aic3262_reg_write(codec->control_data, reg, value);
1906 *----------------------------------------------------------------------------
1907 * Function : aic3262_reset_cache
1908 * Purpose : This function is to reset the cache.
1909 *----------------------------------------------------------------------------
1911 int aic3262_reset_cache (struct snd_soc_codec *codec)
1913 dev_dbg(codec->dev,KERN_ALERT "codec: %s : started\n", __func__);
1915 #if defined(EN_REG_CACHE)
1916 if (codec->reg_cache != NULL) {
1917 memcpy(codec->reg_cache, aic3262_reg, sizeof (aic3262_reg));
1921 codec->reg_cache = kmemdup (aic3262_reg, sizeof (aic3262_reg), GFP_KERNEL);
1922 if (codec->reg_cache == NULL) {
1923 dev_err(codec->dev,"aic32x4: kmemdup failed\n");
1927 dev_dbg(codec->dev,KERN_ALERT "codec: %s : ended\n", __func__);
1934 *----------------------------------------------------------------------------
1935 * Function : aic3262_add_widgets
1936 * Purpose : This function is to add the dapm widgets
1937 * The following are the main widgets supported
1938 * # Left DAC to Left Outputs
1939 * # Right DAC to Right Outputs
1940 * # Left Inputs to Left ADC
1941 * # Right Inputs to Right ADC
1943 *----------------------------------------------------------------------------
1945 static int aic3262_add_widgets(struct snd_soc_codec *codec)
1948 snd_soc_dapm_new_controls(&codec->dapm, aic3262_dapm_widgets,
1949 ARRAY_SIZE(aic3262_dapm_widgets));
1950 /* set up audio path interconnects */
1951 dev_dbg(codec->dev,"#Completed adding new dapm widget controls size=%d\n",ARRAY_SIZE(aic3262_dapm_widgets));
1953 snd_soc_dapm_add_routes(&codec->dapm, aic3262_dapm_routes, ARRAY_SIZE(aic3262_dapm_routes));
1954 dev_dbg(codec->dev,"#Completed adding DAPM routes\n");
1955 snd_soc_dapm_new_widgets(&codec->dapm);
1956 dev_dbg(codec->dev,"#Completed updating dapm\n");
1960 /*----------------------------------------------------------------------------
1961 * Function : aic3262_hw_params
1962 * Purpose : This function is to set the hardware parameters for AIC3262.
1963 * The functions set the sample rate and audio serial data word
1966 *----------------------------------------------------------------------------
1968 int aic3262_hw_params(struct snd_pcm_substream *substream,
1969 struct snd_pcm_hw_params *params,
1970 struct snd_soc_dai *dai)
1972 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1973 struct snd_soc_codec *codec = rtd->codec;
1974 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1975 int asi_reg, bclk_reg;
1979 if(substream->stream==SNDRV_PCM_STREAM_PLAYBACK)
1980 aic3262->stream_status=1;
1982 aic3262->stream_status=0;
1988 asi_reg = AIC3262_ASI1_BUS_FMT;
1989 bclk_reg = AIC3262_ASI1_BCLK_N;
1992 asi_reg = AIC3262_ASI2_BUS_FMT;
1993 bclk_reg = AIC3262_ASI2_BCLK_N;
1996 asi_reg = AIC3262_ASI3_BUS_FMT;
1997 bclk_reg = AIC3262_ASI3_BCLK_N;
2005 switch (params_format(params)) {
2006 case SNDRV_PCM_FORMAT_S16_LE:
2009 case SNDRV_PCM_FORMAT_S20_3LE:
2012 case SNDRV_PCM_FORMAT_S24_LE:
2015 case SNDRV_PCM_FORMAT_S32_LE:
2020 /* configure the respective Registers for the above configuration */
2021 snd_soc_update_bits(codec, asi_reg, AIC3262_ASI_DATA_WORD_LENGTH_MASK, data);
2025 *----------------------------------------------------------------------------
2026 * Function : aic3262_mute
2027 * Purpose : This function is to mute or unmute the left and right DAC
2029 *----------------------------------------------------------------------------
2031 static int aic3262_mute(struct snd_soc_dai *dai, int mute)
2033 struct snd_soc_codec *codec = dai->codec;
2036 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
2038 dev_dbg(codec->dev, "codec : %s : started\n", __FUNCTION__ );
2042 aic3262->mute_asi &= ~((0x1) << dai->id);
2043 if(aic3262->mute_asi == 0)// Mute only when all asi's are muted
2044 snd_soc_update_bits_locked(codec, AIC3262_DAC_MVOL_CONF, AIC3262_DAC_LR_MUTE_MASK,AIC3262_DAC_LR_MUTE);
2047 if(aic3262->mute_asi == 0)// Unmute for the first asi that need to unmute. rest unmute will pass
2048 snd_soc_update_bits_locked(codec, AIC3262_DAC_MVOL_CONF, AIC3262_DAC_LR_MUTE_MASK, 0x0);
2049 aic3262->mute_asi |= ((0x1) << dai->id);
2051 dev_dbg(codec->dev, "codec : %s : ended\n", __FUNCTION__ );
2056 *----------------------------------------------------------------------------
2057 * Function : aic3262_set_dai_sysclk
2058 * Purpose : This function is to set the DAI system clock
2060 *----------------------------------------------------------------------------
2062 static int aic3262_set_dai_sysclk(struct snd_soc_dai *codec_dai,
2063 int clk_id, unsigned int freq, int dir)
2065 struct aic3262_priv *aic3262;
2066 struct snd_soc_codec *codec;
2067 codec = codec_dai->codec;
2068 aic3262 = snd_soc_codec_get_drvdata(codec);
2070 case AIC3262_FREQ_11289600:
2071 aic3262->sysclk = freq;
2073 case AIC3262_FREQ_12000000:
2074 aic3262->sysclk = freq;
2076 case AIC3262_FREQ_24000000:
2077 aic3262->sysclk = freq;
2080 case AIC3262_FREQ_19200000:
2081 aic3262->sysclk = freq;
2084 case AIC3262_FREQ_38400000:
2085 aic3262->sysclk = freq;
2086 dev_dbg(codec->dev,"codec: sysclk = %d\n", aic3262->sysclk);
2091 dev_err(codec->dev,"Invalid frequency to set DAI system clock\n");
2097 *----------------------------------------------------------------------------
2098 * Function : aic3262_set_dai_fmt
2099 * Purpose : This function is to set the DAI format
2101 *----------------------------------------------------------------------------
2103 static int aic3262_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
2105 // struct aic3262_priv *aic3262 = aic3262_priv_data;
2106 struct aic3262_priv *aic3262;
2107 struct snd_soc_codec *codec;
2108 u8 iface_val, master,dsp_a_val ;
2109 int aif_bclk_wclk_reg;
2110 int aif_interface_reg;
2111 int aif_bclk_offset_reg;
2112 int iface_reg = 0; //must be init, not will lead to error
2113 codec = codec_dai->codec;
2114 aic3262 = snd_soc_codec_get_drvdata(codec);
2118 switch(codec_dai->id)
2121 aif_bclk_wclk_reg = AIC3262_ASI1_BWCLK_CNTL_REG;
2122 aif_interface_reg = AIC3262_ASI1_BUS_FMT;
2123 aif_bclk_offset_reg = AIC3262_ASI1_LCH_OFFSET;
2126 aif_bclk_wclk_reg = AIC3262_ASI2_BWCLK_CNTL_REG;
2127 aif_interface_reg = AIC3262_ASI2_BUS_FMT;
2128 aif_bclk_offset_reg = AIC3262_ASI2_LCH_OFFSET;
2131 aif_bclk_wclk_reg = AIC3262_ASI3_BWCLK_CNTL_REG;
2132 aif_interface_reg = AIC3262_ASI3_BUS_FMT;
2133 aif_bclk_offset_reg = AIC3262_ASI3_LCH_OFFSET;
2139 /* set master/slave audio interface */
2140 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2141 case SND_SOC_DAIFMT_CBM_CFM:
2142 dev_dbg(codec->dev, "setdai_fmt : SND_SOC_DAIFMT_CBM_CFM : master=1 \n");
2143 aic3262->master = 1;
2144 master |= (AIC3262_WCLK_OUT_MASK | AIC3262_BCLK_OUT_MASK);
2146 case SND_SOC_DAIFMT_CBS_CFS:
2147 dev_dbg(codec->dev, "setdai_fmt : SND_SOC_DAIFMT_CBS_CFS : master=0 \n");
2149 aic3262->master = 0;
2151 case SND_SOC_DAIFMT_CBS_CFM: //new case..just for debugging
2152 master |= (AIC3262_WCLK_OUT_MASK);
2153 dev_dbg(codec->dev,"%s: SND_SOC_DAIFMT_CBS_CFM\n", __FUNCTION__);
2154 aic3262->master = 0;
2156 case SND_SOC_DAIFMT_CBM_CFS:
2157 master |= (AIC3262_BCLK_OUT_MASK);
2158 aic3262->master = 0;
2162 dev_err(codec->dev, "Invalid DAI master/slave interface\n");
2167 /* interface format */
2168 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2169 case SND_SOC_DAIFMT_I2S:
2170 iface_val = (iface_reg & 0x1f);
2172 case SND_SOC_DAIFMT_DSP_A:
2173 dsp_a_val = 0x1; /* Intentionally falling back to following case */
2174 case SND_SOC_DAIFMT_DSP_B:
2175 iface_val = (iface_reg & 0x1f) | 0x20;
2177 case SND_SOC_DAIFMT_RIGHT_J:
2178 iface_val = (iface_reg & 0x1f) | 0x40;
2180 case SND_SOC_DAIFMT_LEFT_J:
2181 iface_val = (iface_reg & 0x1f) | 0x60;
2184 dev_err(codec->dev,"Invalid DAI interface format\n");
2188 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2189 case SND_SOC_DAIFMT_DSP_A:
2190 case SND_SOC_DAIFMT_DSP_B:
2191 switch(fmt & SND_SOC_DAIFMT_INV_MASK) {
2192 case SND_SOC_DAIFMT_NB_NF:
2194 case SND_SOC_DAIFMT_IB_NF:
2195 master |= AIC3262_BCLK_INV_MASK;
2201 case SND_SOC_DAIFMT_I2S:
2202 case SND_SOC_DAIFMT_RIGHT_J:
2203 case SND_SOC_DAIFMT_LEFT_J:
2204 switch(fmt & SND_SOC_DAIFMT_INV_MASK) {
2205 case SND_SOC_DAIFMT_NB_NF:
2207 case SND_SOC_DAIFMT_IB_NF:
2208 master |= AIC3262_BCLK_INV_MASK;
2217 snd_soc_update_bits(codec, aif_bclk_wclk_reg, AIC3262_WCLK_BCLK_MASTER_MASK ,master);
2218 snd_soc_update_bits(codec, aif_interface_reg, AIC3262_ASI_INTERFACE_MASK ,iface_val);
2219 snd_soc_update_bits(codec, aif_bclk_offset_reg, AIC3262_BCLK_OFFSET_MASK,dsp_a_val);
2224 static int aic3262_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2225 unsigned int Fin, unsigned int Fout)
2227 struct snd_soc_codec *codec = dai->codec;
2228 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
2230 dev_dbg(codec->dev,"In aic3262: dai_set_pll\n");
2231 dev_dbg(codec->dev,"%d,%s,dai->id = %d\n", __LINE__ , __FUNCTION__ ,dai->id);
2232 // select the PLL_CLKIN
2233 snd_soc_update_bits(codec, AIC3262_PLL_CLKIN_REG, AIC3262_PLL_CLKIN_MASK, source << AIC3262_PLL_CLKIN_SHIFT);
2234 // TODO: How to select low/high clock range?
2236 mutex_lock(&aic3262->cfw_mutex);
2237 aic3xxx_cfw_set_pll(aic3262->cfw_p,dai->id);
2238 mutex_unlock(&aic3262->cfw_mutex);
2245 *----------------------------------------------------------------------------
2246 * Function : aic3262_set_bias_level
2247 * Purpose : This function is to get triggered when dapm events occurs.
2249 *----------------------------------------------------------------------------
2251 static int aic3262_set_bias_level(struct snd_soc_codec *codec,
2252 enum snd_soc_bias_level level)
2257 case SND_SOC_BIAS_ON:
2259 dev_dbg(codec->dev, "set_bias_on \n");
2263 case SND_SOC_BIAS_PREPARE:
2264 dev_dbg(codec->dev, "set_bias_prepare \n");
2268 /* Off, with power */
2269 case SND_SOC_BIAS_STANDBY:
2271 * all power is driven by DAPM system,
2272 * so output power is safe if bypass was set
2274 dev_dbg(codec->dev, "set_bias_stby \n");
2275 if(codec->dapm.bias_level == SND_SOC_BIAS_OFF)
2277 snd_soc_update_bits(codec, AIC3262_POWER_CONF, (AIC3262_AVDD_TO_DVDD_MASK | AIC3262_EXT_ANALOG_SUPPLY_MASK), 0x0);
2280 snd_soc_update_bits(codec, AIC3262_REF_PWR_DLY, AIC3262_CHIP_REF_PWR_ON_MASK, AIC3262_CHIP_REF_PWR_ON);
2285 /* Off, without power */
2286 case SND_SOC_BIAS_OFF:
2287 dev_dbg(codec->dev, "set_bias_off \n");
2288 /* force all power off */
2289 snd_soc_update_bits(codec, AIC3262_REF_PWR_DLY, AIC3262_CHIP_REF_PWR_ON_MASK, 0x0);
2290 snd_soc_update_bits(codec, AIC3262_POWER_CONF, (AIC3262_AVDD_TO_DVDD_MASK | AIC3262_EXT_ANALOG_SUPPLY_MASK),
2291 (AIC3262_AVDD_TO_DVDD | AIC3262_EXT_ANALOG_SUPPLY_OFF));
2299 *----------------------------------------------------------------------------
2300 * Function : aic3262_suspend
2301 * Purpose : This function is to suspend the AIC3262 driver.
2303 *----------------------------------------------------------------------------
2305 static int aic3262_suspend(struct snd_soc_codec *codec)
2307 aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
2312 *----------------------------------------------------------------------------
2313 * Function : aic3262_resume
2314 * Purpose : This function is to resume the AIC3262 driver
2316 *----------------------------------------------------------------------------
2318 static int aic3262_resume(struct snd_soc_codec *codec)
2320 aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2326 *----------------------------------------------------------------------------
2327 * Function : aic3262_probe
2328 * Purpose : This is first driver function called by the SoC core driver.
2330 *----------------------------------------------------------------------------
2334 static int aic3262_proc_init(void);
2337 static int aic3262_codec_probe(struct snd_soc_codec *codec)
2340 struct aic3262 *control;
2341 struct aic3262_priv *aic3262;
2342 //struct aic3262_jack_data *jack;
2344 dev_err(codec->dev,"codec pointer is NULL. \n");
2347 aic3262_proc_init();
2350 codec->control_data = dev_get_drvdata(codec->dev->parent);
2351 control = codec->control_data;
2353 aic3262 = kzalloc(sizeof(struct aic3262_priv), GFP_KERNEL);
2357 snd_soc_codec_set_drvdata( codec, aic3262);
2359 aic3262->pdata = dev_get_platdata(codec->dev->parent);
2360 aic3262->codec = codec;
2362 aic3262->cur_fw = NULL;
2363 aic3262->isdefault_fw= 0;
2364 aic3262->cfw_p = &(aic3262->cfw_ps);
2365 aic3262->cfw_p->ops = &aic3262_cfw_codec_ops;
2366 aic3262->cfw_p->ops_obj = aic3262;
2368 aic3262->workqueue = create_singlethread_workqueue("aic3262-codec");
2369 if( !aic3262->workqueue) {
2373 /*ret = device_create_file(codec->dev, &dev_attr_debug_level);
2375 dev_info(codec->dev, "Failed to add debug_level sysfs \n");*/ //sxj
2376 INIT_DELAYED_WORK(&aic3262->delayed_work, aic3262_accessory_work);
2378 mutex_init(&aic3262->mutex);
2379 mutex_init(&aic3262->cfw_mutex);
2380 pm_runtime_enable(codec->dev);
2381 pm_runtime_resume(codec->dev);
2382 aic3262->dsp_runstate = 0;
2383 /* use switch-class based headset reporting if platform requires it */
2384 /*jack = &aic3262->hs_jack;
2385 jack->sdev.name = "h2w";
2386 ret = switch_dev_register(&jack->sdev);
2388 dev_err(codec->dev, "error registering switch device %d\n",ret);
2393 ret = aic3262_request_irq(codec->control_data, AIC3262_IRQ_HEADSET_DETECT,
2394 aic3262_audio_handler, IRQF_NO_SUSPEND,"aic3262_irq_headset",
2398 dev_err(codec->dev, "HEADSET detect irq request failed:%d\n",ret);
2403 aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2405 aic3262->mute_asi = 0;
2407 snd_soc_add_codec_controls(codec, aic3262_snd_controls,
2408 ARRAY_SIZE(aic3262_snd_controls));
2409 mutex_init(&codec->mutex);
2411 aic3262_add_widgets(codec);
2413 #ifdef AIC3262_TiLoad
2414 ret = aic3262_driver_init(codec);
2416 dev_err(codec->dev,"\nTiLoad Initialization failed\n");
2418 // force loading the default firmware
2419 aic3262_firmware_load(NULL,codec);
2420 dev_dbg(codec->dev,"%d,%s,Firmware test\n",__LINE__,__FUNCTION__);
2421 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,"tlv320aic3262_fw_v1.bin", codec->dev, GFP_KERNEL,codec, aic3262_firmware_load);
2423 aic3262_codec = codec;
2427 // switch_dev_unregister(&jack->sdev);
2435 *----------------------------------------------------------------------------
2436 * Function : aic3262_remove
2437 * Purpose : to remove aic3262 soc device
2439 *----------------------------------------------------------------------------
2441 static int aic3262_codec_remove(struct snd_soc_codec *codec)
2443 /* power down chip */
2444 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
2445 struct aic3262 *control = codec->control_data;
2446 //struct aic3262_jack_data *jack = &aic3262->hs_jack; //sxj
2448 aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
2450 pm_runtime_disable(codec->dev);
2451 /* free_irq if any */
2452 switch(control->type) {
2454 aic3262_free_irq(control, AIC3262_IRQ_HEADSET_DETECT, codec);
2457 /* release firmware if any */
2458 if(aic3262->cur_fw != NULL)
2460 release_firmware(aic3262->cur_fw);
2462 /* destroy workqueue for jac dev */
2463 //switch_dev_unregister(&jack->sdev); //sxj
2464 destroy_workqueue(aic3262->workqueue);
2471 static struct snd_soc_codec_driver soc_codec_driver_aic326x = {
2472 .probe = aic3262_codec_probe,
2473 .remove = aic3262_codec_remove,
2474 .suspend = aic3262_suspend,
2475 .resume = aic3262_resume,
2476 .read = aic3262_codec_read,
2477 .write = aic3262_codec_write,
2478 .set_bias_level = aic3262_set_bias_level,
2479 .reg_cache_size = ARRAY_SIZE(aic3262_reg),
2480 .reg_word_size = sizeof(u8),
2481 .reg_cache_default = aic3262_reg,
2483 static int aic326x_probe(struct platform_device *pdev)
2485 return snd_soc_register_codec(&pdev->dev, &soc_codec_driver_aic326x,
2486 aic326x_dai_driver, ARRAY_SIZE(aic326x_dai_driver));
2490 static int aic326x_remove(struct platform_device *pdev)
2492 snd_soc_unregister_codec(&pdev->dev);
2496 static struct platform_driver aic326x_codec_driver = {
2498 .name = "tlv320aic3262-codec",
2499 .owner = THIS_MODULE,
2501 .probe = aic326x_probe,
2502 .remove = aic326x_remove,
2505 *----------------------------------------------------------------------------
2506 * Function : tlv320aic3262_modinit
2507 * Purpose : module init function. First function to run.
2509 *----------------------------------------------------------------------------
2511 static int __init tlv320aic3262_modinit(void)
2513 return platform_driver_register(&aic326x_codec_driver);
2516 module_init(tlv320aic3262_modinit);
2519 *----------------------------------------------------------------------------
2520 * Function : tlv320aic3262_exit
2521 * Purpose : module init function. First function to run.
2523 *----------------------------------------------------------------------------
2525 static void __exit tlv320aic3262_exit(void)
2527 platform_driver_unregister(&aic326x_codec_driver);
2531 module_exit(tlv320aic3262_exit);
2532 MODULE_ALIAS("platform:tlv320aic3262-codec");
2533 MODULE_DESCRIPTION("ASoC TLV320AIC3262 codec driver");
2534 MODULE_AUTHOR("Y Preetam Sashank Reddy ");
2535 MODULE_AUTHOR("Barani Prashanth ");
2536 MODULE_AUTHOR("Mukund Navada K <navada@ti.com>");
2537 MODULE_AUTHOR("Naren Vasanad <naren.vasanad@ti.com>");
2538 MODULE_LICENSE("GPL");
2544 /*static void test_playback(void)
2547 printk("test palyback start\n");
2549 aic3262_write(aic3262_codec, 0x00, 0x00);
2550 ret = aic3262_read(aic3262_codec,0x00);
2551 printk("0x00 = %x\n",ret);
2552 aic3262_write(aic3262_codec, 0x7f, 0x00);
2553 ret = aic3262_read(aic3262_codec,0x7f);
2554 printk("0x7f = %x\n",ret);
2555 aic3262_write(aic3262_codec, 0x01, 0x01);
2556 ret = aic3262_read(aic3262_codec,0x01);
2557 printk("0x01 = %x\n",ret);
2559 aic3262_write(aic3262_codec, 0x04, 0x00);
2560 aic3262_write(aic3262_codec, 0x0b, 0x81);
2561 aic3262_write(aic3262_codec, 0x0c, 0x82);
2562 aic3262_write(aic3262_codec, 0x0d, 0x00);
2563 aic3262_write(aic3262_codec, 0x0e, 0x80);
2565 aic3262_write(aic3262_codec, 0x00, 0x01);
2566 aic3262_write(aic3262_codec, 0x01+1*128, 0x00);
2567 aic3262_write(aic3262_codec, 0x7a+1*128, 0x01);
2569 aic3262_write(aic3262_codec, 0x00, 0x04);
2570 aic3262_write(aic3262_codec, 0x01+4*128, 0x00);
2571 aic3262_write(aic3262_codec, 0x0a+4*128, 0x00);
2573 aic3262_write(aic3262_codec, 0x00, 0x00);
2574 aic3262_write(aic3262_codec, 0x3c, 0x01);
2576 aic3262_write(aic3262_codec, 0x00, 0x01);
2577 aic3262_write(aic3262_codec, 0x03+1*128, 0x00);
2578 aic3262_write(aic3262_codec, 0x04+1*128, 0x00);
2579 aic3262_write(aic3262_codec, 0x1f+1*128, 0x80);
2580 aic3262_write(aic3262_codec, 0x20+1*128, 0x00);
2581 aic3262_write(aic3262_codec, 0x21+1*128, 0x28);
2582 aic3262_write(aic3262_codec, 0x23+1*128, 0x10);
2583 aic3262_write(aic3262_codec, 0x1b+1*128, 0x33);
2584 aic3262_write(aic3262_codec, 0x00, 0x00);
2585 aic3262_write(aic3262_codec, 0x3f, 0xc0);
2586 aic3262_write(aic3262_codec, 0x40, 0x00);
2588 aic3262_write(aic3262_codec, 0x00, 0x01);
2589 aic3262_write(aic3262_codec, 0x16+1*128, 0xc3);
2590 ret = aic3262_read(aic3262_codec,0x16);
2591 printk("0x16 = %x\n",ret);
2592 aic3262_write(aic3262_codec, 0xae, 0x00);
2593 aic3262_write(aic3262_codec, 0x2f+1*128, 0x00);
2594 aic3262_write(aic3262_codec, 0x30+1*128, 0x11);
2595 aic3262_write(aic3262_codec, 0x52+1*128, 0x75);
2596 aic3262_write(aic3262_codec, 0x53+1*128, 0x03);
2597 aic3262_write(aic3262_codec, 0x2d+1*128, 0x03);
2598 aic3262_write(aic3262_codec, 0x00, 0x00);
2599 aic3262_write(aic3262_codec, 0x3f, 0xc0);
2600 aic3262_write(aic3262_codec, 0x40, 0x00);
2605 static void AP_to_speaker(void)
2607 printk("AP_to_speaker\n");
2609 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2610 aic3262_codec_write(aic3262_codec, MAKE_REG(0,0,127), 0x00);
2611 aic3262_codec_write(aic3262_codec, AIC3262_RESET_REG, 0x01);
2613 aic3262_codec_write(aic3262_codec, AIC3262_DAC_ADC_CLKIN_REG, 0x00);
2614 aic3262_codec_write(aic3262_codec, AIC3262_NDAC_DIV_POW_REG, 0x81);
2615 aic3262_codec_write(aic3262_codec, AIC3262_MDAC_DIV_POW_REG, 0x82);
2616 aic3262_codec_write(aic3262_codec, AIC3262_DOSR_MSB_REG, 0x00);
2617 aic3262_codec_write(aic3262_codec, AIC3262_DOSR_LSB_REG, 0x80);
2619 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x01);
2620 aic3262_codec_write(aic3262_codec, AIC3262_POWER_CONF, 0x00);
2621 aic3262_codec_write(aic3262_codec, AIC3262_REF_PWR_DLY, 0x01);
2623 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x04);
2624 aic3262_codec_write(aic3262_codec, AIC3262_ASI1_BUS_FMT, 0x00);
2625 aic3262_codec_write(aic3262_codec, AIC3262_ASI1_BWCLK_CNTL_REG, 0x00);
2627 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2628 aic3262_codec_write(aic3262_codec, AIC3262_DAC_PRB, 0x01);
2630 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x01);
2631 aic3262_codec_write(aic3262_codec, AIC3262_LDAC_PTM, 0x00);
2632 aic3262_codec_write(aic3262_codec, AIC3262_RDAC_PTM, 0x00);
2633 aic3262_codec_write(aic3262_codec, AIC3262_LINE_AMP_CNTL_R1, 0xC3);
2634 aic3262_codec_write(aic3262_codec, AIC3262_SPK_AMP_CNTL_R2, 0x00);
2635 aic3262_codec_write(aic3262_codec, AIC3262_SPK_AMP_CNTL_R3, 0x00);
2636 aic3262_codec_write(aic3262_codec, AIC3262_SPK_AMP_CNTL_R4, 0x11);
2637 aic3262_codec_write(aic3262_codec, MAKE_REG(0,1, 82), 0x75);
2638 aic3262_codec_write(aic3262_codec, MAKE_REG(0,1, 83), 0x03);
2639 aic3262_codec_write(aic3262_codec, AIC3262_SPK_AMP_CNTL_R1, 0x03);
2641 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2642 aic3262_codec_write(aic3262_codec, AIC3262_PASI_DAC_DP_SETUP, 0xc0);
2643 aic3262_codec_write(aic3262_codec, AIC3262_DAC_MVOL_CONF, 0x00);
2648 static void AP_to_headphone(void)
2650 printk("AP_to_headphone\n");
2652 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2653 aic3262_codec_write(aic3262_codec, MAKE_REG(0,0,127), 0x00);
2654 aic3262_codec_write(aic3262_codec, AIC3262_RESET_REG, 0x01);
2656 aic3262_codec_write(aic3262_codec, AIC3262_DAC_ADC_CLKIN_REG, 0x00);
2657 aic3262_codec_write(aic3262_codec, AIC3262_NDAC_DIV_POW_REG, 0x81);
2658 aic3262_codec_write(aic3262_codec, AIC3262_MDAC_DIV_POW_REG, 0x82);
2659 aic3262_codec_write(aic3262_codec, AIC3262_DOSR_MSB_REG, 0x00);
2660 aic3262_codec_write(aic3262_codec, AIC3262_DOSR_LSB_REG, 0x80);
2662 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x01);
2663 aic3262_codec_write(aic3262_codec, AIC3262_POWER_CONF, 0x00);
2664 aic3262_codec_write(aic3262_codec, AIC3262_REF_PWR_DLY, 0x01);
2666 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x04);
2667 aic3262_codec_write(aic3262_codec, AIC3262_ASI1_BUS_FMT, 0x00);
2668 aic3262_codec_write(aic3262_codec, AIC3262_ASI1_BWCLK_CNTL_REG, 0x00);
2670 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2671 aic3262_codec_write(aic3262_codec, AIC3262_DAC_PRB, 0x01);
2673 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x01);
2674 aic3262_codec_write(aic3262_codec, AIC3262_LDAC_PTM, 0x00);
2675 aic3262_codec_write(aic3262_codec, AIC3262_RDAC_PTM, 0x00);
2676 aic3262_codec_write(aic3262_codec, AIC3262_HPL_VOL, 0x80);
2677 aic3262_codec_write(aic3262_codec, AIC3262_HPR_VOL, 0x80);
2678 aic3262_codec_write(aic3262_codec, MAKE_REG(0,1, 33), 0x28);
2679 aic3262_codec_write(aic3262_codec, AIC3262_CHARGE_PUMP_CNTL, 0x10);
2680 aic3262_codec_write(aic3262_codec, AIC3262_HP_AMP_CNTL_R1, 0x33);
2681 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2682 aic3262_codec_write(aic3262_codec, AIC3262_PASI_DAC_DP_SETUP, 0xc0);
2683 aic3262_codec_write(aic3262_codec, AIC3262_DAC_MVOL_CONF, 0x00);
2687 /*static void record_in1lr(void)
2689 printk("record in1lr\n");
2691 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2692 aic3262_codec_write(aic3262_codec, MAKE_REG(0,0,127), 0x00);
2693 aic3262_codec_write(aic3262_codec, AIC3262_RESET_REG, 0x01);
2695 aic3262_codec_write(aic3262_codec, AIC3262_DAC_ADC_CLKIN_REG, 0x00);
2696 aic3262_codec_write(aic3262_codec, AIC3262_NADC_DIV_POW_REG, 0x81);
2697 aic3262_codec_write(aic3262_codec, AIC3262_MADC_DIV_POW_REG, 0x82);
2698 aic3262_codec_write(aic3262_codec, AIC3262_AOSR_REG, 0x80);
2700 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x01);
2701 aic3262_codec_write(aic3262_codec, AIC3262_POWER_CONF, 0x00);
2702 aic3262_codec_write(aic3262_codec, AIC3262_REF_PWR_DLY, 0x01);
2703 aic3262_codec_write(aic3262_codec, AIC3262_MIC_PWR_DLY, 0x33);
2705 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x04);
2706 aic3262_codec_write(aic3262_codec, AIC3262_ASI1_BUS_FMT, 0x00);
2707 aic3262_codec_write(aic3262_codec, AIC3262_ASI1_BWCLK_CNTL_REG, 0x00);
2709 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2710 aic3262_codec_write(aic3262_codec, AIC3262_ADC_PRB, 0x01);
2712 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x01);
2713 aic3262_codec_write(aic3262_codec, AIC3262_MIC_BIAS_CNTL, 0x40);
2714 aic3262_codec_write(aic3262_codec, AIC3262_LMIC_PGA_PIN, 0x80);
2715 aic3262_codec_write(aic3262_codec, AIC3262_LMIC_PGA_MIN, 0x80);
2716 aic3262_codec_write(aic3262_codec, AIC3262_RMIC_PGA_PIN, 0x80);
2717 aic3262_codec_write(aic3262_codec, AIC3262_RMIC_PGA_MIN, 0x80);
2719 aic3262_codec_write(aic3262_codec, AIC3262_MICL_PGA, 0x3c);
2720 aic3262_codec_write(aic3262_codec, AIC3262_MICR_PGA, 0x3c);
2721 aic3262_codec_write(aic3262_codec, MAKE_REG(0,1, 61), 0x00);
2723 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2724 aic3262_codec_write(aic3262_codec, AIC3262_PASI_DAC_DP_SETUP, 0xc0);
2725 aic3262_codec_write(aic3262_codec, AIC3262_DAC_MVOL_CONF, 0x00);
2728 static void record_in2lr(void)
2730 printk("record in2lr\n");
2732 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2733 aic3262_codec_write(aic3262_codec, MAKE_REG(0,0,127), 0x00);
2734 aic3262_codec_write(aic3262_codec, AIC3262_RESET_REG, 0x01);
2738 static void incall_mic(void)
2742 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2743 aic3262_codec_write(aic3262_codec, MAKE_REG(0,0,127), 0x00);
2745 // Clock Configuration
2746 //ret = aic3262_codec_read(aic3262_codec, AIC3262_DAC_ADC_CLKIN_REG);
2748 //aic3262_codec_write(aic3262_codec, AIC3262_DAC_ADC_CLKIN_REG, ret);
2749 //aic3262_codec_write(aic3262_codec, AIC3262_NADC_DIV_POW_REG, 0x81);
2750 //aic3262_codec_write(aic3262_codec, AIC3262_MADC_DIV_POW_REG, 0x8b);
2751 //aic3262_codec_write(aic3262_codec, AIC3262_AOSR_REG, 0x80);
2753 // Initialize the Codec
2754 //aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x01);
2755 //aic3262_codec_write(aic3262_codec, AIC3262_POWER_CONF, 0x00);
2756 //aic3262_codec_write(aic3262_codec, AIC3262_REF_PWR_DLY, 0x01);
2757 //aic3262_codec_write(aic3262_codec, AIC3262_MIC_PWR_DLY, 0x33);
2759 //ASI#3 configuration
2760 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x04);
2761 //aic3262_codec_write(aic3262_codec, AIC3262_ASI3_BUS_FMT, 0x00);
2762 //aic3262_codec_write(aic3262_codec, AIC3262_ASI3_ADC_INPUT_CNTL, 0x01);
2763 //aic3262_codec_write(aic3262_codec, AIC3262_ASI3_BWCLK_CNTL_REG, 0x00);
2764 aic3262_codec_write(aic3262_codec, AIC3262_ASI3_DOUT_CNTL, 0x00);
2767 //aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2768 //aic3262_codec_write(aic3262_codec, AIC3262_ADC_PRB, 0x01);
2771 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x01);
2772 aic3262_codec_write(aic3262_codec, AIC3262_MIC_BIAS_CNTL, 0x55);
2773 aic3262_codec_write(aic3262_codec, AIC3262_LMIC_PGA_PIN, 0x80);
2774 aic3262_codec_write(aic3262_codec, AIC3262_LMIC_PGA_MIN, 0x80);
2775 aic3262_codec_write(aic3262_codec, AIC3262_RMIC_PGA_PIN, 0x80);
2777 aic3262_codec_write(aic3262_codec, AIC3262_RMIC_PGA_MIN, 0x20);
2778 aic3262_codec_write(aic3262_codec, AIC3262_MICL_PGA, 0x3c);
2779 aic3262_codec_write(aic3262_codec, AIC3262_MICR_PGA, 0x3c);
2780 aic3262_codec_write(aic3262_codec, MAKE_REG(0,1, 61), 0x00);
2782 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2784 aic3262_codec_write(aic3262_codec, AIC3262_ADC_CHANNEL_POW, 0xc0);
2785 aic3262_codec_write(aic3262_codec, AIC3262_ADC_FINE_GAIN, 0x00);
2788 static void test(void)
2791 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x00);
2792 aic3262_codec_write(aic3262_codec, MAKE_REG(0,0,127), 0x00);
2794 aic3262_codec_write(aic3262_codec, AIC3262_PAGE_SEL_REG, 0x04);
2795 aic3262_codec_write(aic3262_codec, AIC3262_ASI3_BUS_FMT, 0x60);
2798 static void test_playback(void)
2808 static ssize_t aic3262_proc_write(struct file *file, const char __user *buffer,
2809 unsigned long len, void *data)
2816 cookie_pot = (char *)vmalloc( len );
2823 if (copy_from_user( cookie_pot, buffer, len ))
2827 switch(cookie_pot[0])
2831 debug_write_read ++;
2832 debug_write_read %= 2;
2833 if(debug_write_read != 0)
2834 printk("Debug read and write reg on\n");
2836 printk("Debug read and write reg off\n");
2840 printk("Read reg debug\n");
2841 if(cookie_pot[1] ==':')
2843 debug_write_read = 1;
2844 strsep(&cookie_pot,":");
2845 while((p=strsep(&cookie_pot,",")))
2847 reg = simple_strtol(p,NULL,16);
2848 value = aic3262_codec_read(aic3262_codec,reg);
2849 printk("aic3262_codec_read:0x%04x = 0x%04x\n",reg,value);
2851 debug_write_read = 0;
2856 printk("Error Read reg debug.\n");
2857 printk("For example: echo r:22,23,24,25>aic3262_ts\n");
2862 printk("Write reg debug\n");
2863 if(cookie_pot[1] ==':')
2865 debug_write_read = 1;
2866 strsep(&cookie_pot,":");
2867 while((p=strsep(&cookie_pot,"=")))
2869 reg = simple_strtol(p,NULL,16);
2870 p=strsep(&cookie_pot,",");
2871 value = simple_strtol(p,NULL,16);
2872 aic3262_codec_write(aic3262_codec,reg,value);
2873 printk("aic3262_codec_write:0x%04x = 0x%04x\n",reg,value);
2875 debug_write_read = 0;
2880 printk("Error Write reg debug.\n");
2881 printk("For example: w:22=0,23=0,24=0,25=0>aic3262_ts\n");
2889 printk("Dump reg \n");
2891 for(reg = 0; reg < 0x6e; reg+=2)
2893 value = aic3262_codec_read(aic3262_codec,reg);
2894 printk("aic3262_codec_read:0x%04x = 0x%04x\n",reg,value);
2899 printk("Help for aic3262_ts .\n-->The Cmd list: \n");
2900 printk("-->'d&&D' Open or Off the debug\n");
2901 printk("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>aic3262_ts\n");
2902 printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>aic3262_ts\n");
2909 static const struct file_operations aic3262_proc_fops = {
2910 .owner = THIS_MODULE,
2913 static int aic3262_proc_init(void)
2915 struct proc_dir_entry *aic3262_proc_entry;
2916 aic3262_proc_entry = create_proc_entry("driver/aic3262_ts", 0777, NULL);
2917 if(aic3262_proc_entry != NULL)
2919 aic3262_proc_entry->write_proc = aic3262_proc_write;
2924 printk("create proc error !\n");