2 * rt5631.c -- RT5631 ALSA Soc Audio driver
\r
4 * Copyright 2011 Realtek Microelectronics
\r
6 * Author: flove <flove@realtek.com>
\r
10 * This program is free software; you can redistribute it and/or modify
\r
11 * it under the terms of the GNU General Public License version 2 as
\r
12 * published by the Free Software Foundation.
\r
15 #include <linux/module.h>
\r
16 #include <linux/moduleparam.h>
\r
17 #include <linux/init.h>
\r
18 #include <linux/delay.h>
\r
19 #include <linux/pm.h>
\r
20 #include <linux/i2c.h>
\r
21 #include <linux/platform_device.h>
\r
22 #include <linux/spi/spi.h>
\r
23 #include <sound/core.h>
\r
24 #include <sound/pcm.h>
\r
25 #include <sound/pcm_params.h>
\r
26 #include <sound/soc.h>
\r
27 #include <sound/soc-dapm.h>
\r
28 #include <sound/initval.h>
\r
31 #include <linux/timer.h>
\r
34 #define DBG(x...) printk(x)
\r
38 #define RT5631_VERSION "0.01 alsa 1.0.24"
\r
40 #define RT5631_ALC_DAC_FUNC_ENA 1 //ALC functio for DAC
\r
41 #define RT5631_ALC_ADC_FUNC_ENA 1 //ALC function for ADC
\r
42 #define RT5631_SPK_TIMER 0 //if enable this, MUST enable RT5631_EQ_FUNC_ENA first!
\r
44 struct rt5631_priv {
\r
52 #if (RT5631_SPK_TIMER == 1)
\r
53 static struct timer_list spk_timer;
\r
54 struct work_struct spk_work;
\r
55 static bool last_is_spk = false; // need modify.
\r
58 static struct snd_soc_codec *rt5631_codec;
\r
59 static const u16 rt5631_reg[0x80];
\r
60 static int timesofbclk = 32;
\r
61 bool isPlaybackon = false, isCaptureon = false;
\r
63 module_param(timesofbclk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
\r
64 MODULE_PARM_DESC(timeofbclk, "relationship between bclk and fs");
\r
67 static inline int rt5631_write(struct snd_soc_codec *codec,
\r
68 unsigned int reg, unsigned int val)
\r
70 return snd_soc_write(codec, reg, val);
\r
73 static inline unsigned int rt5631_read(struct snd_soc_codec *codec,
\r
76 return snd_soc_read(codec, reg);
\r
79 static int rt5631_write_mask(struct snd_soc_codec *codec,
\r
80 unsigned int reg, unsigned int value, unsigned int mask)
\r
82 unsigned int reg_val;
\r
88 if (mask != 0xffff) {
\r
89 reg_val = rt5631_read(codec, reg);
\r
91 reg_val |= (value & mask);
\r
92 ret = rt5631_write(codec, reg, reg_val);
\r
94 ret = rt5631_write(codec, reg, value);
\r
100 static void rt5631_write_index(struct snd_soc_codec *codec,
\r
101 unsigned int reg, unsigned int value)
\r
103 rt5631_write(codec, RT5631_INDEX_ADD, reg);
\r
104 rt5631_write(codec, RT5631_INDEX_DATA, value);
\r
108 static unsigned int rt5631_read_index(struct snd_soc_codec *codec,
\r
111 unsigned int value;
\r
113 rt5631_write(codec, RT5631_INDEX_ADD, reg);
\r
114 value = rt5631_read(codec, RT5631_INDEX_DATA);
\r
119 static void rt5631_write_index_mask(struct snd_soc_codec *codec,
\r
120 unsigned int reg, unsigned int value, unsigned int mask)
\r
122 unsigned int reg_val;
\r
127 if (mask != 0xffff) {
\r
128 reg_val = rt5631_read_index(codec, reg);
\r
130 reg_val |= (value & mask);
\r
131 rt5631_write_index(codec, reg, reg_val);
\r
133 rt5631_write_index(codec, reg, value);
\r
139 static inline int rt5631_reset(struct snd_soc_codec *codec)
\r
141 return snd_soc_write(codec, RT5631_RESET, 0);
\r
144 struct rt5631_init_reg {
\r
150 #define DEF_VOL 0xc0
\r
152 #ifndef DEF_VOL_SPK
\r
153 #define DEF_VOL_SPK 0xc0
\r
157 * speaker channel volume select SPKMIXER, 0DB by default
\r
158 * Headphone channel volume select OUTMIXER,0DB by default
\r
159 * AXO1/AXO2 channel volume select OUTMIXER,0DB by default
\r
160 * Record Mixer source from Mic1/Mic2 by default
\r
161 * Mic1/Mic2 boost 40dB by default
\r
162 * DAC_L-->OutMixer_L by default
\r
163 * DAC_R-->OutMixer_R by default
\r
164 * DAC-->SpeakerMixer
\r
165 * Speaker volume-->SPOMixer(L-->L,R-->R)
\r
166 * Speaker AMP ratio gain is 1.44X
\r
167 * HP from OutMixer,speaker out from SpeakerOut Mixer
\r
168 * enable HP zero cross
\r
169 * change Mic1 & mic2 to differential mode
\r
171 static struct rt5631_init_reg init_list[] = {
\r
173 {RT5631_SPK_OUT_VOL , (DEF_VOL_SPK<<8) | DEF_VOL_SPK}, //speaker channel volume select SPKMIXER,0DB by default
\r
174 {RT5631_HP_OUT_VOL , (DEF_VOL<<8) | DEF_VOL}, //Headphone channel volume select OUTMIXER,0DB by default
\r
175 {RT5631_MONO_AXO_1_2_VOL , 0xf0c0}, //AXO1/AXO2 channel volume select OUTMIXER,0DB by default
\r
176 {RT5631_ADC_REC_MIXER , 0xb0f0}, //Record Mixer source from Mic1 by default
\r
177 {RT5631_ADC_CTRL_1 , 0x0006},//STEREO ADC CONTROL 1
\r
178 {RT5631_MIC_CTRL_2 , 0x6600},//0x8800},//0x5500}, //Mic1/Mic2 boost 40DB by default
\r
180 #if RT5631_ALC_ADC_FUNC_ENA
\r
182 {RT5631_ALC_CTRL_1 , 0x0a0f},//ALC CONTROL 1
\r
183 {RT5631_ALC_CTRL_2 , 0x0005},//ALC CONTROL 2
\r
184 {RT5631_ALC_CTRL_3 , 0xe080},//ALC CONTROL 3
\r
187 {RT5631_OUTMIXER_L_CTRL , 0xdfC0}, //DAC_L-->OutMixer_L by default
\r
188 {RT5631_OUTMIXER_R_CTRL , 0xdfC0}, //DAC_R-->OutMixer_R by default
\r
189 {RT5631_AXO1MIXER_CTRL , 0x8840}, //OutMixer_L-->AXO1Mixer by default
\r
190 {RT5631_AXO2MIXER_CTRL , 0x8880}, //OutMixer_R-->AXO2Mixer by default
\r
191 {RT5631_SPK_MIXER_CTRL , 0xd8d8}, //DAC-->SpeakerMixer
\r
192 {RT5631_SPK_MONO_OUT_CTRL , 0x6c00}, //Speaker volume-->SPOMixer(L-->L,R-->R)
\r
193 {RT5631_GEN_PUR_CTRL_REG , 0x2e00}, //Speaker AMP ratio gain is 1.27x
\r
194 #if defined(CONFIG_ADJUST_VOL_BY_CODEC)
\r
195 {RT5631_SPK_MONO_HP_OUT_CTRL, 0x0000}, //HP from outputmixer,speaker out from SpeakerOut Mixer
\r
197 {RT5631_SPK_MONO_HP_OUT_CTRL, 0x000c}, //HP from DAC,speaker out from SpeakerOut Mixer
\r
199 {RT5631_DEPOP_FUN_CTRL_2 , 0x8000}, //HP depop by register control
\r
200 {RT5631_INT_ST_IRQ_CTRL_2 , 0x0f18}, //enable HP zero cross
\r
201 {RT5631_MIC_CTRL_1 , 0x8000}, //set mic 1 to differnetial mode
\r
202 {RT5631_GPIO_CTRL , 0x0000}, //set GPIO to input pin
\r
203 // {RT5631_JACK_DET_CTRL , 0x4e80}, //Jack detect for GPIO,high is HP,low is speaker
\r
204 {RT5631_JACK_DET_CTRL , 0x4bc0}, //Jack detect for GPIO,high is speaker,low is hp
\r
206 #define RT5631_INIT_REG_LEN ARRAY_SIZE(init_list)
\r
225 struct hw_eq_preset {
\r
232 * EQ param reg : 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
\r
233 * 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
\r
234 * EQ control reg : 0x6e
\r
236 struct hw_eq_preset hweq_preset[] = {
\r
237 {NORMAL , {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
\r
238 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
\r
239 0x0000, 0x0000, 0x0000, 0x0000}, 0x0000},
\r
240 {CLUB , {0x1C10, 0x0000, 0xC1CC, 0x1E5D, 0x0699, 0xCD48,
\r
241 0x188D, 0x0699, 0xC3B6, 0x1CD0, 0x0699, 0x0436,
\r
242 0x0000, 0x0000, 0x0000, 0x0000}, 0x000E},
\r
243 {DANCE , {0x1F2C, 0x095B, 0xC071, 0x1F95, 0x0616, 0xC96E,
\r
244 0x1B11, 0xFC91, 0xDCF2, 0x1194, 0xFAF2, 0x0436,
\r
245 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
\r
246 {LIVE , {0x1EB5, 0xFCB6, 0xC24A, 0x1DF8, 0x0E7C, 0xC883,
\r
247 0x1C10, 0x0699, 0xDA41, 0x1561, 0x0295, 0x0436,
\r
248 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
\r
249 {POP , {0x1EB5, 0xFCB6, 0xC1D4, 0x1E5D, 0x0E23, 0xD92E,
\r
250 0x16E6, 0xFCB6, 0x0000, 0x0969, 0xF988, 0x0436,
\r
251 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
\r
252 {ROCK , {0x1EB5, 0xFCB6, 0xC071, 0x1F95, 0x0424, 0xC30A,
\r
253 0x1D27, 0xF900, 0x0C5D, 0x0FC7, 0x0E23, 0x0436,
\r
254 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
\r
255 {OPPO , {0x0000, 0x0000, 0xCA4A, 0x17F8, 0x0FEC, 0xCA4A,
\r
256 0x17F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
\r
257 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
\r
258 {TREBLE , {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
\r
259 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x188D,
\r
260 0x1699, 0x0000, 0x0000, 0x0000}, 0x0010},
\r
261 {BASS , {0x1A43, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000,
\r
262 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
\r
263 0x0000, 0x0000, 0x0000, 0x0000}, 0x0001},
\r
266 static int rt5631_reg_init(struct snd_soc_codec *codec)
\r
270 for (i = 0; i < RT5631_INIT_REG_LEN; i++)
\r
271 rt5631_write(codec, init_list[i].reg, init_list[i].val);
\r
276 static const char *rt5631_spol_source_sel[] = {
\r
277 "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"};
\r
278 static const char *rt5631_spor_source_sel[] = {
\r
279 "SPORMIX", "MONOIN_RX", "VDAC", "DACR"};
\r
280 static const char *rt5631_mono_source_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"};
\r
281 static const char *rt5631_input_mode_source_sel[] = {
\r
282 "Single-end", "Differential"};
\r
283 static const char *rt5631_mic_boost[] = {"Bypass", "+20db", "+24db", "+30db",
\r
284 "+35db", "+40db", "+44db", "+50db", "+52db"};
\r
285 static const char *rt5631_hpl_source_sel[] = {"LEFT HPVOL", "LEFT DAC"};
\r
286 static const char *rt5631_hpr_source_sel[] = {"RIGHT HPVOL", "RIGHT DAC"};
\r
287 static const char *rt5631_eq_sel[] = {"NORMAL", "CLUB", "DANCE", "LIVE", "POP",
\r
288 "ROCK", "OPPO", "TREBLE", "BASS"};
\r
291 static const struct soc_enum rt5631_enum[] = {
\r
292 SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 14, 4, rt5631_spol_source_sel),
\r
293 SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 10, 4, rt5631_spor_source_sel),
\r
294 SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 6, 3, rt5631_mono_source_sel),
\r
295 SOC_ENUM_SINGLE(RT5631_MIC_CTRL_1, 15, 2, rt5631_input_mode_source_sel),
\r
296 SOC_ENUM_SINGLE(RT5631_MIC_CTRL_1, 7, 2, rt5631_input_mode_source_sel),
\r
297 SOC_ENUM_SINGLE(RT5631_MONO_INPUT_VOL, 15, 2, rt5631_input_mode_source_sel),
\r
298 SOC_ENUM_SINGLE(RT5631_MIC_CTRL_2, 12, 9, rt5631_mic_boost),
\r
299 SOC_ENUM_SINGLE(RT5631_MIC_CTRL_2, 8, 9, rt5631_mic_boost),
\r
300 SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 3, 2, rt5631_hpl_source_sel),
\r
301 SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 2, 2, rt5631_hpr_source_sel),
\r
302 SOC_ENUM_SINGLE(0, 4, 9, rt5631_eq_sel),
\r
305 static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
\r
306 struct snd_ctl_elem_value *ucontrol)
\r
308 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
\r
309 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
311 ucontrol->value.integer.value[0] = rt5631->dmic_used_flag;
\r
316 static void rt5631_close_dmic(struct snd_soc_codec *codec)
\r
318 rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
\r
319 DMIC_L_CH_MUTE | DMIC_R_CH_MUTE,
\r
320 DMIC_L_CH_MUTE_MASK | DMIC_R_CH_MUTE_MASK);
\r
321 rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
\r
322 DMIC_DIS, DMIC_ENA_MASK);
\r
326 static int rt5631_dmic_put(struct snd_kcontrol *kcontrol,
\r
327 struct snd_ctl_elem_value *ucontrol)
\r
329 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
\r
330 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
332 if (rt5631->dmic_used_flag == ucontrol->value.integer.value[0])
\r
335 if (ucontrol->value.integer.value[0]) {
\r
336 rt5631->dmic_used_flag = 1;
\r
338 rt5631_close_dmic(codec);
\r
339 rt5631->dmic_used_flag = 0;
\r
345 static int rt5631_eq_sel_get(struct snd_kcontrol *kcontrol,
\r
346 struct snd_ctl_elem_value *ucontrol)
\r
348 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
\r
349 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
351 ucontrol->value.integer.value[0] = rt5631->eq_mode;
\r
356 static void rt5631_update_eqmode(struct snd_soc_codec *codec, int mode)
\r
360 if (NORMAL == mode) {
\r
361 /* In Normal mode, the EQ parameter is cleared,
\r
362 * and hardware LP, BP1, BP2, BP3, HP1, HP2
\r
363 * block control and EQ block are disabled.
\r
365 for (i = RT5631_EQ_BW_LOP; i <= RT5631_EQ_HPF_GAIN; i++)
\r
366 rt5631_write_index(codec, i,
\r
367 hweq_preset[mode].value[i]);
\r
368 rt5631_write_mask(codec, RT5631_EQ_CTRL, 0x0000, 0x003f);
\r
369 rt5631_write_index_mask(codec, RT5631_EQ_PRE_VOL_CTRL
\r
372 /* Fill and update EQ parameter,
\r
373 * and EQ block are enabled.
\r
375 rt5631_write_index_mask(codec, RT5631_EQ_PRE_VOL_CTRL
\r
377 rt5631_write(codec, RT5631_EQ_CTRL,
\r
378 hweq_preset[mode].ctrl);
\r
379 for (i = RT5631_EQ_BW_LOP; i <= RT5631_EQ_HPF_GAIN; i++)
\r
380 rt5631_write_index(codec, i,
\r
381 hweq_preset[mode].value[i]);
\r
382 rt5631_write_mask(codec, RT5631_EQ_CTRL, 0x4000, 0x4000);
\r
388 static int rt5631_eq_sel_put(struct snd_kcontrol *kcontrol,
\r
389 struct snd_ctl_elem_value *ucontrol)
\r
391 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
\r
392 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
394 if (rt5631->eq_mode == ucontrol->value.integer.value[0])
\r
397 rt5631_update_eqmode(codec, ucontrol->value.enumerated.item[0]);
\r
398 rt5631->eq_mode = ucontrol->value.integer.value[0];
\r
403 #if (RT5631_SPK_TIMER == 1)
\r
404 static void spk_work_handler(struct work_struct *work)
\r
406 struct snd_soc_codec *codec = rt5631_codec;
\r
407 bool is_spk = (rt5631_read(codec, 0x4a)) & 0x04; //detect rt5631 reg4a[3], 1'b:SPK, 0'b:HP ;
\r
408 if(last_is_spk != is_spk)
\r
409 printk("%s---%s is in use.last is %s in use\n", __FUNCTION__,is_spk?"speaker":"headphone",last_is_spk?"speaker":"headphone");
\r
411 if(is_spk && !last_is_spk){
\r
412 rt5631_write_index_mask(codec,0x11,0x0000,0x0007); //0db
\r
413 rt5631_write_index(codec,0x12,0x0003); //0db
\r
414 rt5631_update_eqmode(codec, SPK_FR); // SPK is in use, enable EQ mode of SPK_FR.
\r
415 }else if(!is_spk && last_is_spk){
\r
416 //flove071311 rt5631_update_eqmode(codec, NORMAL); // HP is in use, enable EQ mode of NORMAL.
\r
417 rt5631_write_index_mask(codec,0x11,0x0001,0x0003);
\r
418 rt5631_write_index(codec,0x12,0x0001);
\r
419 rt5631_update_eqmode(codec,HFREQ);
\r
421 last_is_spk = is_spk;
\r
424 /* timer to judge SPK or HP in use, and handle EQ issues accordingly. */
\r
425 void spk_timer_callback(unsigned long data )
\r
429 schedule_work(&spk_work);
\r
431 //DBG("Starting timer to fire in 1000ms (%ld)\n", jiffies );
\r
432 ret = mod_timer(&spk_timer, jiffies + msecs_to_jiffies(1000));
\r
433 if (ret) printk("Error in mod_timer\n");
\r
437 static const struct snd_kcontrol_new rt5631_snd_controls[] = {
\r
438 SOC_ENUM("MIC1 Mode Control", rt5631_enum[3]),
\r
439 SOC_ENUM("MIC1 Boost", rt5631_enum[6]),
\r
440 SOC_ENUM("MIC2 Mode Control", rt5631_enum[4]),
\r
441 SOC_ENUM("MIC2 Boost", rt5631_enum[7]),
\r
442 SOC_ENUM("MONOIN Mode Control", rt5631_enum[5]),
\r
443 SOC_DOUBLE("PCM Playback Volume", RT5631_STEREO_DAC_VOL_2, 8, 0, 255, 1),
\r
444 SOC_DOUBLE("PCM Playback Switch", RT5631_STEREO_DAC_VOL_1, 15, 7, 1, 1),
\r
445 SOC_DOUBLE("MONOIN_RX Capture Volume", RT5631_MONO_INPUT_VOL, 8, 0, 31, 1),
\r
446 SOC_DOUBLE("AXI Capture Volume", RT5631_AUX_IN_VOL, 8, 0, 31, 1),
\r
447 SOC_SINGLE("AXO1 Playback Switch", RT5631_MONO_AXO_1_2_VOL, 15, 1, 1),
\r
448 SOC_SINGLE("AXO2 Playback Switch", RT5631_MONO_AXO_1_2_VOL, 7, 1, 1),
\r
449 SOC_DOUBLE("OUTVOL Playback Volume", RT5631_MONO_AXO_1_2_VOL, 8, 0, 31, 1),
\r
450 SOC_DOUBLE("Speaker Playback Switch", RT5631_SPK_OUT_VOL, 15, 7, 1, 1),
\r
451 SOC_DOUBLE("Speaker Playback Volume", RT5631_SPK_OUT_VOL, 8, 0, 63, 1),
\r
452 SOC_SINGLE("MONO Playback Switch", RT5631_MONO_AXO_1_2_VOL, 13, 1, 1),
\r
453 SOC_DOUBLE("HP Playback Switch", RT5631_HP_OUT_VOL, 15, 7, 1, 1),
\r
454 SOC_DOUBLE("HP Playback Volume", RT5631_HP_OUT_VOL, 8, 0, 63, 1),
\r
455 SOC_SINGLE_EXT("DMIC Capture Switch", 0, 2, 1, 0,
\r
456 rt5631_dmic_get, rt5631_dmic_put),
\r
457 SOC_ENUM_EXT("EQ Mode", rt5631_enum[10], rt5631_eq_sel_get, rt5631_eq_sel_put),
\r
460 static const struct snd_kcontrol_new rt5631_recmixl_mixer_controls[] = {
\r
461 SOC_DAPM_SINGLE("OUTMIXL Capture Switch", RT5631_ADC_REC_MIXER, 15, 1, 1),
\r
462 SOC_DAPM_SINGLE("MIC1_BST1 Capture Switch", RT5631_ADC_REC_MIXER, 14, 1, 1),
\r
463 SOC_DAPM_SINGLE("AXILVOL Capture Switch", RT5631_ADC_REC_MIXER, 13, 1, 1),
\r
464 SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER, 12, 1, 1),
\r
467 static const struct snd_kcontrol_new rt5631_recmixr_mixer_controls[] = {
\r
468 SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER, 4, 1, 1),
\r
469 SOC_DAPM_SINGLE("AXIRVOL Capture Switch", RT5631_ADC_REC_MIXER, 5, 1, 1),
\r
470 SOC_DAPM_SINGLE("MIC2_BST2 Capture Switch", RT5631_ADC_REC_MIXER, 6, 1, 1),
\r
471 SOC_DAPM_SINGLE("OUTMIXR Capture Switch", RT5631_ADC_REC_MIXER, 7, 1, 1),
\r
474 static const struct snd_kcontrol_new rt5631_spkmixl_mixer_controls[] = {
\r
475 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_SPK_MIXER_CTRL, 15, 1, 1),
\r
476 SOC_DAPM_SINGLE("MIC1_P Playback Switch", RT5631_SPK_MIXER_CTRL, 14, 1, 1),
\r
477 SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_SPK_MIXER_CTRL, 13, 1, 1),
\r
478 SOC_DAPM_SINGLE("OUTMIXL Playback Switch", RT5631_SPK_MIXER_CTRL, 12, 1, 1),
\r
481 static const struct snd_kcontrol_new rt5631_spkmixr_mixer_controls[] = {
\r
482 SOC_DAPM_SINGLE("OUTMIXR Playback Switch", RT5631_SPK_MIXER_CTRL, 4, 1, 1),
\r
483 SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_SPK_MIXER_CTRL, 5, 1, 1),
\r
484 SOC_DAPM_SINGLE("MIC2_P Playback Switch", RT5631_SPK_MIXER_CTRL, 6, 1, 1),
\r
485 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_SPK_MIXER_CTRL, 7, 1, 1),
\r
488 static const struct snd_kcontrol_new rt5631_outmixl_mixer_controls[] = {
\r
489 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_L_CTRL, 15, 1, 1),
\r
490 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_L_CTRL, 14, 1, 1),
\r
491 SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_OUTMIXER_L_CTRL, 13, 1, 1),
\r
492 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_L_CTRL, 12, 1, 1),
\r
493 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_L_CTRL, 11, 1, 1),
\r
494 SOC_DAPM_SINGLE("MONOIN_RXP Playback Switch", RT5631_OUTMIXER_L_CTRL, 10, 1, 1),
\r
495 SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_L_CTRL, 9, 1, 1),
\r
496 SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_L_CTRL, 8, 1, 1),
\r
497 SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_L_CTRL, 7, 1, 1),
\r
500 static const struct snd_kcontrol_new rt5631_outmixr_mixer_controls[] = {
\r
501 SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_R_CTRL, 7, 1, 1),
\r
502 SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_R_CTRL, 8, 1, 1),
\r
503 SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_R_CTRL, 9, 1, 1),
\r
504 SOC_DAPM_SINGLE("MONOIN_RXN Playback Switch", RT5631_OUTMIXER_R_CTRL, 10, 1, 1),
\r
505 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_R_CTRL, 11, 1, 1),
\r
506 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_R_CTRL, 12, 1, 1),
\r
507 SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_OUTMIXER_R_CTRL, 13, 1, 1),
\r
508 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_R_CTRL, 14, 1, 1),
\r
509 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_R_CTRL, 15, 1, 1),
\r
512 static const struct snd_kcontrol_new rt5631_AXO1MIX_mixer_controls[] = {
\r
513 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO1MIXER_CTRL, 15 , 1, 1),
\r
514 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO1MIXER_CTRL, 11, 1, 1),
\r
515 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO1MIXER_CTRL, 7 , 1 , 1),
\r
516 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO1MIXER_CTRL, 6, 1, 1),
\r
519 static const struct snd_kcontrol_new rt5631_AXO2MIX_mixer_controls[] = {
\r
520 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO2MIXER_CTRL, 15, 1, 1),
\r
521 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO2MIXER_CTRL, 11, 1, 1),
\r
522 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO2MIXER_CTRL, 7, 1, 1),
\r
523 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO2MIXER_CTRL, 6, 1 , 1),
\r
526 static const struct snd_kcontrol_new rt5631_spolmix_mixer_controls[] = {
\r
527 SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 15, 1, 1),
\r
528 SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 14, 1, 1),
\r
531 static const struct snd_kcontrol_new rt5631_spormix_mixer_controls[] = {
\r
532 SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 13, 1, 1),
\r
533 SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 12, 1, 1),
\r
536 static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = {
\r
537 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 11, 1, 1),
\r
538 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 10, 1, 1),
\r
541 static const struct snd_kcontrol_new rt5631_spol_mux_control =
\r
542 SOC_DAPM_ENUM("Route", rt5631_enum[0]);
\r
543 static const struct snd_kcontrol_new rt5631_spor_mux_control =
\r
544 SOC_DAPM_ENUM("Route", rt5631_enum[1]);
\r
545 static const struct snd_kcontrol_new rt5631_mono_mux_control =
\r
546 SOC_DAPM_ENUM("Route", rt5631_enum[2]);
\r
548 static const struct snd_kcontrol_new rt5631_hpl_mux_control =
\r
549 SOC_DAPM_ENUM("Route", rt5631_enum[8]);
\r
550 static const struct snd_kcontrol_new rt5631_hpr_mux_control =
\r
551 SOC_DAPM_ENUM("Route", rt5631_enum[9]);
\r
553 //ALC for DAC function
\r
554 #if (RT5631_ALC_DAC_FUNC_ENA == 1)
\r
555 static void rt5631_alc_enable(struct snd_soc_codec *codec,unsigned int EnableALC)
\r
559 rt5631_write(codec, 0x64,0x0206);
\r
560 rt5631_write(codec, 0x65,0x0003);
\r
561 rt5631_write_index(codec, 0x21,0x5000);
\r
562 rt5631_write_index(codec, 0x22,0xa480);
\r
563 rt5631_write_index(codec, 0x23,0x0a08);
\r
564 rt5631_write(codec, 0x0c,0x0010);
\r
565 rt5631_write(codec, 0x66,0x650a);
\r
570 rt5631_write(codec, 0x66,0x250A);
\r
571 rt5631_write(codec, 0x0c,0x0000);
\r
577 static int spk_event(struct snd_soc_dapm_widget *w,
\r
578 struct snd_kcontrol *kcontrol, int event)
\r
580 struct snd_soc_codec *codec = w->codec;
\r
581 static int spkl_out_enable, spkr_out_enable;
\r
584 case SND_SOC_DAPM_POST_PMU:
\r
586 #if (RT5631_ALC_DAC_FUNC_ENA == 1)
\r
587 rt5631_alc_enable(codec, 1);
\r
590 if (!spkl_out_enable && !strcmp(w->name, "SPKL Amp")) {
\r
591 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD4,
\r
592 PWR_SPK_L_VOL, PWR_SPK_L_VOL);
\r
593 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
\r
594 PWR_CLASS_D, PWR_CLASS_D);
\r
595 rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
\r
597 spkl_out_enable = 1;
\r
599 if (!spkr_out_enable && !strcmp(w->name, "SPKR Amp")) {
\r
600 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD4,
\r
601 PWR_SPK_R_VOL, PWR_SPK_R_VOL);
\r
602 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
\r
603 PWR_CLASS_D, PWR_CLASS_D);
\r
604 rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
\r
606 spkr_out_enable = 1;
\r
610 case SND_SOC_DAPM_POST_PMD:
\r
611 if (spkl_out_enable && !strcmp(w->name, "SPKL Amp")) {
\r
612 rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
\r
613 RT_L_MUTE, RT_L_MUTE);
\r
614 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD4,
\r
616 spkl_out_enable = 0;
\r
618 if (spkr_out_enable && !strcmp(w->name, "SPKR Amp")) {
\r
619 rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
\r
620 RT_R_MUTE, RT_R_MUTE);
\r
621 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD4,
\r
623 spkr_out_enable = 0;
\r
625 if (0 == spkl_out_enable && 0 == spkr_out_enable)
\r
626 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
\r
629 #if (RT5631_ALC_DAC_FUNC_ENA == 1)
\r
630 rt5631_alc_enable(codec, 0);
\r
643 static void hp_depop_mode2_onebit(struct snd_soc_codec *codec, int enable)
\r
645 unsigned int soft_vol, hp_zc;
\r
647 rt5631_write_mask(codec, RT5631_DEPOP_FUN_CTRL_2, 0, EN_ONE_BIT_DEPOP);
\r
649 soft_vol = rt5631_read(codec, RT5631_SOFT_VOL_CTRL);
\r
650 rt5631_write(codec, RT5631_SOFT_VOL_CTRL, 0);
\r
651 hp_zc = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
\r
652 rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
\r
654 rt5631_write_index(codec, RT5631_TEST_MODE_CTRL, 0x84c0);
\r
655 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x309f);
\r
656 rt5631_write_index(codec, RT5631_CP_INTL_REG2, 0x6530);
\r
657 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_2,
\r
658 EN_CAP_FREE_DEPOP);
\r
660 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0);
\r
661 schedule_timeout_uninterruptible(msecs_to_jiffies(100));
\r
664 rt5631_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
\r
665 rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
\r
670 static void hp_mute_unmute_depop_onebit(struct snd_soc_codec *codec, int enable)
\r
672 unsigned int soft_vol, hp_zc;
\r
674 rt5631_write_mask(codec, RT5631_DEPOP_FUN_CTRL_2, 0, EN_ONE_BIT_DEPOP);
\r
675 soft_vol = rt5631_read(codec, RT5631_SOFT_VOL_CTRL);
\r
676 rt5631_write(codec, RT5631_SOFT_VOL_CTRL, 0);
\r
677 hp_zc = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
\r
678 rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
\r
680 schedule_timeout_uninterruptible(msecs_to_jiffies(10));
\r
681 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f);
\r
682 rt5631_write_mask(codec, RT5631_HP_OUT_VOL, 0,
\r
683 RT_L_MUTE | RT_R_MUTE);
\r
684 schedule_timeout_uninterruptible(msecs_to_jiffies(300));
\r
687 rt5631_write_mask(codec, RT5631_HP_OUT_VOL,
\r
688 RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE);
\r
689 schedule_timeout_uninterruptible(msecs_to_jiffies(100));
\r
691 rt5631_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
\r
692 rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
\r
697 static void hp_depop2(struct snd_soc_codec *codec, int enable)
\r
699 unsigned int soft_vol, hp_zc;
\r
701 rt5631_write_mask(codec, RT5631_DEPOP_FUN_CTRL_2,
\r
702 EN_ONE_BIT_DEPOP, EN_ONE_BIT_DEPOP);
\r
703 soft_vol = rt5631_read(codec, RT5631_SOFT_VOL_CTRL);
\r
704 rt5631_write(codec, RT5631_SOFT_VOL_CTRL, 0);
\r
705 hp_zc = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
\r
706 rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
\r
708 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303e);
\r
709 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
\r
710 PWR_CHARGE_PUMP | PWR_HP_L_AMP | PWR_HP_R_AMP,
\r
711 PWR_CHARGE_PUMP | PWR_HP_L_AMP | PWR_HP_R_AMP);
\r
712 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
\r
713 POW_ON_SOFT_GEN | EN_DEPOP2_FOR_HP);
\r
714 schedule_timeout_uninterruptible(msecs_to_jiffies(100));
\r
715 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
\r
716 PWR_HP_DEPOP_DIS, PWR_HP_DEPOP_DIS);
\r
718 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303F);
\r
719 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
\r
720 POW_ON_SOFT_GEN | EN_MUTE_UNMUTE_DEPOP |
\r
721 PD_HPAMP_L_ST_UP | PD_HPAMP_R_ST_UP);
\r
722 schedule_timeout_uninterruptible(msecs_to_jiffies(75));
\r
723 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
\r
724 POW_ON_SOFT_GEN | PD_HPAMP_L_ST_UP | PD_HPAMP_R_ST_UP);
\r
725 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3, 0,
\r
727 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
\r
728 POW_ON_SOFT_GEN | EN_DEPOP2_FOR_HP |
\r
729 PD_HPAMP_L_ST_UP | PD_HPAMP_R_ST_UP);
\r
730 schedule_timeout_uninterruptible(msecs_to_jiffies(80));
\r
731 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1, POW_ON_SOFT_GEN);
\r
732 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3, 0,
\r
733 PWR_CHARGE_PUMP | PWR_HP_L_AMP | PWR_HP_R_AMP);
\r
736 rt5631_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
\r
737 rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
\r
742 static void hp_mute_unmute_depop(struct snd_soc_codec *codec, int enable)
\r
744 unsigned int soft_vol, hp_zc;
\r
746 rt5631_write_mask(codec, RT5631_DEPOP_FUN_CTRL_2,
\r
747 EN_ONE_BIT_DEPOP, EN_ONE_BIT_DEPOP);
\r
748 soft_vol = rt5631_read(codec, RT5631_SOFT_VOL_CTRL);
\r
749 rt5631_write(codec, RT5631_SOFT_VOL_CTRL, 0);
\r
750 hp_zc = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
\r
751 rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
\r
753 schedule_timeout_uninterruptible(msecs_to_jiffies(10));
\r
754 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
\r
755 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
\r
756 POW_ON_SOFT_GEN | EN_MUTE_UNMUTE_DEPOP |
\r
757 EN_HP_R_M_UN_MUTE_DEPOP | EN_HP_L_M_UN_MUTE_DEPOP);
\r
758 rt5631_write_mask(codec, RT5631_HP_OUT_VOL, 0,
\r
759 RT_L_MUTE | RT_R_MUTE);
\r
760 schedule_timeout_uninterruptible(msecs_to_jiffies(160));
\r
762 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
\r
763 rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
\r
764 POW_ON_SOFT_GEN | EN_MUTE_UNMUTE_DEPOP |
\r
765 EN_HP_R_M_UN_MUTE_DEPOP | EN_HP_L_M_UN_MUTE_DEPOP);
\r
766 rt5631_write_mask(codec, RT5631_HP_OUT_VOL,
\r
767 RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE);
\r
768 schedule_timeout_uninterruptible(msecs_to_jiffies(150));
\r
771 rt5631_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
\r
772 rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
\r
777 static int hp_event(struct snd_soc_dapm_widget *w,
\r
778 struct snd_kcontrol *kcontrol, int event)
\r
780 struct snd_soc_codec *codec = w->codec;
\r
781 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
785 pu_l = rt5631_read(codec, RT5631_PWR_MANAG_ADD4) & PWR_HP_L_OUT_VOL;
\r
786 pu_r = rt5631_read(codec, RT5631_PWR_MANAG_ADD4) & PWR_HP_R_OUT_VOL;
\r
788 case SND_SOC_DAPM_PRE_PMD:
\r
789 if ((pu_l && pu_r) && hp_en) {
\r
790 if (rt5631->codec_version) {
\r
791 hp_mute_unmute_depop_onebit(codec, 0);
\r
792 hp_depop_mode2_onebit(codec, 0);
\r
794 hp_mute_unmute_depop(codec, 0);
\r
795 hp_depop2(codec, 0);
\r
801 case SND_SOC_DAPM_POST_PMU:
\r
802 if ((pu_l && pu_r) && !hp_en) {
\r
803 if (rt5631->codec_version) {
\r
804 hp_depop_mode2_onebit(codec, 1);
\r
805 hp_mute_unmute_depop_onebit(codec, 1);
\r
807 hp_depop2(codec, 1);
\r
808 hp_mute_unmute_depop(codec, 1);
\r
821 static int dac_to_hp_event(struct snd_soc_dapm_widget *w,
\r
822 struct snd_kcontrol *kcontrol, int event)
\r
824 struct snd_soc_codec *codec = w->codec;
\r
825 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
829 case SND_SOC_DAPM_PRE_PMD:
\r
831 if (rt5631->codec_version) {
\r
832 hp_mute_unmute_depop_onebit(codec, 0);
\r
833 hp_depop_mode2_onebit(codec, 0);
\r
835 hp_mute_unmute_depop(codec, 0);
\r
836 hp_depop2(codec, 0);
\r
842 case SND_SOC_DAPM_POST_PMU:
\r
844 if (rt5631->codec_version) {
\r
845 hp_depop_mode2_onebit(codec, 1);
\r
846 hp_mute_unmute_depop_onebit(codec, 1);
\r
848 hp_depop2(codec, 1);
\r
849 hp_mute_unmute_depop(codec, 1);
\r
862 static int mic_event(struct snd_soc_dapm_widget *w,
\r
863 struct snd_kcontrol *kcontrol, int event)
\r
865 struct snd_soc_codec *codec = w->codec;
\r
866 int val_mic1, val_mic2;
\r
868 val_mic1 = rt5631_read(codec, RT5631_PWR_MANAG_ADD2) &
\r
869 PWR_MIC1_BOOT_GAIN;
\r
870 val_mic2 = rt5631_read(codec, RT5631_PWR_MANAG_ADD2) &
\r
871 PWR_MIC2_BOOT_GAIN;
\r
873 case SND_SOC_DAPM_POST_PMU:
\r
875 * If microphone is stereo, need not copy ADC channel
\r
876 * If mic1 is used, copy ADC left to right
\r
877 * If mic2 is used, copy ADC right to left
\r
879 if (val_mic1 && val_mic2)
\r
880 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
\r
883 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
\r
886 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
\r
889 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
\r
900 static int auxo1_event(struct snd_soc_dapm_widget *w,
\r
901 struct snd_kcontrol *kcontrol, int event)
\r
903 struct snd_soc_codec *codec = w->codec;
\r
904 static bool aux1_en;
\r
907 case SND_SOC_DAPM_PRE_PMD:
\r
909 rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
\r
910 RT_L_MUTE, RT_L_MUTE);
\r
915 case SND_SOC_DAPM_POST_PMU:
\r
917 rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
\r
930 static int auxo2_event(struct snd_soc_dapm_widget *w,
\r
931 struct snd_kcontrol *kcontrol, int event)
\r
933 struct snd_soc_codec *codec = w->codec;
\r
934 static bool aux2_en;
\r
937 case SND_SOC_DAPM_PRE_PMD:
\r
939 rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
\r
940 RT_R_MUTE, RT_R_MUTE);
\r
945 case SND_SOC_DAPM_POST_PMU:
\r
947 rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
\r
960 static int mono_event(struct snd_soc_dapm_widget *w,
\r
961 struct snd_kcontrol *kcontrol, int event)
\r
963 struct snd_soc_codec *codec = w->codec;
\r
964 static bool mono_en;
\r
967 case SND_SOC_DAPM_PRE_PMD:
\r
969 rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
\r
970 MUTE_MONO, MUTE_MONO);
\r
971 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
\r
972 0, PWR_MONO_DEPOP_DIS);
\r
977 case SND_SOC_DAPM_POST_PMU:
\r
979 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
\r
980 PWR_MONO_DEPOP_DIS, PWR_MONO_DEPOP_DIS);
\r
981 rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
\r
995 * config_common_power - control all common power of codec system
\r
996 * @pmu: power up or not
\r
998 static int config_common_power(struct snd_soc_codec *codec, bool pmu)
\r
1000 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
1001 unsigned int mux_val;
\r
1004 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
\r
1005 PWR_MAIN_I2S_EN | PWR_DAC_REF,
\r
1006 PWR_MAIN_I2S_EN | PWR_DAC_REF);
\r
1007 mux_val = rt5631_read(codec, RT5631_SPK_MONO_HP_OUT_CTRL);
\r
1008 if (!(mux_val & HP_L_MUX_SEL_DAC_L))
\r
1009 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
\r
1010 PWR_DAC_L_TO_MIXER, PWR_DAC_L_TO_MIXER);
\r
1011 if (!(mux_val & HP_R_MUX_SEL_DAC_R))
\r
1012 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
\r
1013 PWR_DAC_R_TO_MIXER, PWR_DAC_R_TO_MIXER);
\r
1014 if (rt5631->pll_used_flag)
\r
1015 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD2,
\r
1016 PWR_PLL, PWR_PLL);
\r
1017 } else if (isPlaybackon == false && isCaptureon == false){
\r
1018 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1, 0,
\r
1019 PWR_MAIN_I2S_EN | PWR_DAC_REF |
\r
1020 PWR_DAC_L_TO_MIXER | PWR_DAC_R_TO_MIXER);
\r
1021 if (rt5631->pll_used_flag)
\r
1022 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD2,
\r
1029 static int adc_event(struct snd_soc_dapm_widget *w,
\r
1030 struct snd_kcontrol *kcontrol, int event)
\r
1032 struct snd_soc_codec *codec = w->codec;
\r
1036 case SND_SOC_DAPM_POST_PMD:
\r
1038 isPlaybackon = false;
\r
1039 config_common_power(codec, false);
\r
1044 case SND_SOC_DAPM_PRE_PMU:
\r
1046 isPlaybackon = true;
\r
1047 config_common_power(codec, true);
\r
1059 static int dac_event(struct snd_soc_dapm_widget *w,
\r
1060 struct snd_kcontrol *kcontrol, int event)
\r
1062 struct snd_soc_codec *codec = w->codec;
\r
1066 case SND_SOC_DAPM_POST_PMD:
\r
1068 isCaptureon = false;
\r
1069 config_common_power(codec, false);
\r
1074 case SND_SOC_DAPM_PRE_PMU:
\r
1076 isCaptureon = true;
\r
1077 config_common_power(codec, true);
\r
1089 static const struct snd_soc_dapm_widget rt5631_dapm_widgets[] = {
\r
1090 SND_SOC_DAPM_INPUT("MIC1"),
\r
1091 SND_SOC_DAPM_INPUT("MIC2"),
\r
1092 SND_SOC_DAPM_INPUT("AXIL"),
\r
1093 SND_SOC_DAPM_INPUT("AXIR"),
\r
1094 SND_SOC_DAPM_INPUT("MONOIN_RXN"),
\r
1095 SND_SOC_DAPM_INPUT("MONOIN_RXP"),
\r
1097 SND_SOC_DAPM_MICBIAS("Mic Bias1", RT5631_PWR_MANAG_ADD2, 3, 0),
\r
1098 SND_SOC_DAPM_MICBIAS("Mic Bias2", RT5631_PWR_MANAG_ADD2, 2, 0),
\r
1100 SND_SOC_DAPM_PGA_E("Mic1 Boost", RT5631_PWR_MANAG_ADD2, 5, 0, NULL, 0,
\r
1101 mic_event, SND_SOC_DAPM_POST_PMU),
\r
1102 SND_SOC_DAPM_PGA_E("Mic2 Boost", RT5631_PWR_MANAG_ADD2, 4, 0, NULL, 0,
\r
1103 mic_event, SND_SOC_DAPM_POST_PMU),
\r
1104 SND_SOC_DAPM_PGA("MONOIN_RXP Boost", RT5631_PWR_MANAG_ADD4, 7, 0, NULL, 0),
\r
1105 SND_SOC_DAPM_PGA("MONOIN_RXN Boost", RT5631_PWR_MANAG_ADD4, 6, 0, NULL, 0),
\r
1106 SND_SOC_DAPM_PGA("AXIL Boost", RT5631_PWR_MANAG_ADD4, 9, 0, NULL, 0),
\r
1107 SND_SOC_DAPM_PGA("AXIR Boost", RT5631_PWR_MANAG_ADD4, 8, 0, NULL, 0),
\r
1108 SND_SOC_DAPM_MIXER("MONO_IN", SND_SOC_NOPM, 0, 0, NULL, 0),
\r
1110 SND_SOC_DAPM_MIXER("RECMIXL Mixer", RT5631_PWR_MANAG_ADD2, 11, 0,
\r
1111 &rt5631_recmixl_mixer_controls[0],
\r
1112 ARRAY_SIZE(rt5631_recmixl_mixer_controls)),
\r
1113 SND_SOC_DAPM_MIXER("RECMIXR Mixer", RT5631_PWR_MANAG_ADD2, 10, 0,
\r
1114 &rt5631_recmixr_mixer_controls[0],
\r
1115 ARRAY_SIZE(rt5631_recmixr_mixer_controls)),
\r
1116 SND_SOC_DAPM_MIXER("ADC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
\r
1118 SND_SOC_DAPM_ADC_E("Left ADC", "Left ADC HIFI Capture",
\r
1119 RT5631_PWR_MANAG_ADD1, 11, 0,
\r
1120 adc_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
\r
1121 SND_SOC_DAPM_ADC_E("Right ADC", "Right ADC HIFI Capture",
\r
1122 RT5631_PWR_MANAG_ADD1, 10, 0,
\r
1123 adc_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
\r
1124 SND_SOC_DAPM_DAC_E("Left DAC", "Left DAC HIFI Playback",
\r
1125 RT5631_PWR_MANAG_ADD1, 9, 0,
\r
1126 dac_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
\r
1127 SND_SOC_DAPM_DAC_E("Right DAC", "Right DAC HIFI Playback",
\r
1128 RT5631_PWR_MANAG_ADD1, 8, 0,
\r
1129 dac_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
\r
1130 SND_SOC_DAPM_DAC("Voice DAC", "Voice DAC Mono Playback", SND_SOC_NOPM, 0, 0),
\r
1131 SND_SOC_DAPM_PGA("Voice DAC Boost", SND_SOC_NOPM, 0, 0, NULL, 0),
\r
1133 SND_SOC_DAPM_MIXER("SPKMIXL Mixer", RT5631_PWR_MANAG_ADD2, 13, 0,
\r
1134 &rt5631_spkmixl_mixer_controls[0],
\r
1135 ARRAY_SIZE(rt5631_spkmixl_mixer_controls)),
\r
1136 SND_SOC_DAPM_MIXER("OUTMIXL Mixer", RT5631_PWR_MANAG_ADD2, 15, 0,
\r
1137 &rt5631_outmixl_mixer_controls[0],
\r
1138 ARRAY_SIZE(rt5631_outmixl_mixer_controls)),
\r
1139 SND_SOC_DAPM_MIXER("OUTMIXR Mixer", RT5631_PWR_MANAG_ADD2, 14, 0,
\r
1140 &rt5631_outmixr_mixer_controls[0],
\r
1141 ARRAY_SIZE(rt5631_outmixr_mixer_controls)),
\r
1142 SND_SOC_DAPM_MIXER("SPKMIXR Mixer", RT5631_PWR_MANAG_ADD2, 12, 0,
\r
1143 &rt5631_spkmixr_mixer_controls[0],
\r
1144 ARRAY_SIZE(rt5631_spkmixr_mixer_controls)),
\r
1146 SND_SOC_DAPM_PGA("Left SPK Vol", RT5631_PWR_MANAG_ADD4, 15, 0, NULL, 0),
\r
1147 SND_SOC_DAPM_PGA("Right SPK Vol", RT5631_PWR_MANAG_ADD4, 14, 0, NULL, 0),
\r
1148 SND_SOC_DAPM_PGA_E("Left HP Vol", RT5631_PWR_MANAG_ADD4, 11, 0, NULL, 0,
\r
1149 hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
\r
1150 SND_SOC_DAPM_PGA_E("Right HP Vol", RT5631_PWR_MANAG_ADD4, 10, 0, NULL, 0,
\r
1151 hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
\r
1153 SND_SOC_DAPM_PGA_E("Left DAC_HP", SND_SOC_NOPM, 0, 0, NULL, 0,
\r
1154 dac_to_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
\r
1155 SND_SOC_DAPM_PGA_E("Right DAC_HP", SND_SOC_NOPM, 0, 0, NULL, 0,
\r
1156 dac_to_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
\r
1158 SND_SOC_DAPM_PGA("Left Out Vol", RT5631_PWR_MANAG_ADD4, 13, 0, NULL, 0),
\r
1159 SND_SOC_DAPM_PGA("Right Out Vol", RT5631_PWR_MANAG_ADD4, 12, 0, NULL, 0),
\r
1161 SND_SOC_DAPM_MIXER_E("AXO1MIX Mixer", RT5631_PWR_MANAG_ADD3, 11, 0,
\r
1162 &rt5631_AXO1MIX_mixer_controls[0],
\r
1163 ARRAY_SIZE(rt5631_AXO1MIX_mixer_controls),
\r
1164 auxo1_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
\r
1165 SND_SOC_DAPM_MIXER("SPOLMIX Mixer", SND_SOC_NOPM, 0, 0,
\r
1166 &rt5631_spolmix_mixer_controls[0],
\r
1167 ARRAY_SIZE(rt5631_spolmix_mixer_controls)),
\r
1168 SND_SOC_DAPM_MIXER("MONOMIX Mixer", RT5631_PWR_MANAG_ADD3, 9, 0,
\r
1169 &rt5631_monomix_mixer_controls[0],
\r
1170 ARRAY_SIZE(rt5631_monomix_mixer_controls)),
\r
1171 SND_SOC_DAPM_MIXER("SPORMIX Mixer", SND_SOC_NOPM, 0, 0,
\r
1172 &rt5631_spormix_mixer_controls[0],
\r
1173 ARRAY_SIZE(rt5631_spormix_mixer_controls)),
\r
1174 SND_SOC_DAPM_MIXER_E("AXO2MIX Mixer", RT5631_PWR_MANAG_ADD3, 10, 0,
\r
1175 &rt5631_AXO2MIX_mixer_controls[0],
\r
1176 ARRAY_SIZE(rt5631_AXO2MIX_mixer_controls),
\r
1177 auxo2_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
\r
1179 SND_SOC_DAPM_MUX("SPOL Mux", SND_SOC_NOPM, 0, 0, &rt5631_spol_mux_control),
\r
1180 SND_SOC_DAPM_MUX("SPOR Mux", SND_SOC_NOPM, 0, 0, &rt5631_spor_mux_control),
\r
1181 SND_SOC_DAPM_MUX("Mono Mux", SND_SOC_NOPM, 0, 0, &rt5631_mono_mux_control),
\r
1182 SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &rt5631_hpl_mux_control),
\r
1183 SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &rt5631_hpr_mux_control),
\r
1185 SND_SOC_DAPM_PGA_E("Mono Amp", RT5631_PWR_MANAG_ADD3, 7, 0, NULL, 0,
\r
1186 mono_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
\r
1187 SND_SOC_DAPM_PGA_E("SPKL Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
\r
1188 spk_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
\r
1189 SND_SOC_DAPM_PGA_E("SPKR Amp", SND_SOC_NOPM, 1, 0, NULL, 0,
\r
1190 spk_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
\r
1192 SND_SOC_DAPM_OUTPUT("AUXO1"),
\r
1193 SND_SOC_DAPM_OUTPUT("AUXO2"),
\r
1194 SND_SOC_DAPM_OUTPUT("SPOL"),
\r
1195 SND_SOC_DAPM_OUTPUT("SPOR"),
\r
1196 SND_SOC_DAPM_OUTPUT("HPOL"),
\r
1197 SND_SOC_DAPM_OUTPUT("HPOR"),
\r
1198 SND_SOC_DAPM_OUTPUT("MONO"),
\r
1202 static const struct snd_soc_dapm_route audio_map[] = {
\r
1203 {"Mic1 Boost", NULL, "MIC1"},
\r
1204 {"Mic2 Boost", NULL, "MIC2"},
\r
1205 {"MONOIN_RXP Boost", NULL, "MONOIN_RXP"},
\r
1206 {"MONOIN_RXN Boost", NULL, "MONOIN_RXN"},
\r
1207 {"AXIL Boost", NULL, "AXIL"},
\r
1208 {"AXIR Boost", NULL, "AXIR"},
\r
1210 {"MONO_IN", NULL, "MONOIN_RXP Boost"},
\r
1211 {"MONO_IN", NULL, "MONOIN_RXN Boost"},
\r
1213 {"RECMIXL Mixer", "OUTMIXL Capture Switch", "OUTMIXL Mixer"},
\r
1214 {"RECMIXL Mixer", "MIC1_BST1 Capture Switch", "Mic1 Boost"},
\r
1215 {"RECMIXL Mixer", "AXILVOL Capture Switch", "AXIL Boost"},
\r
1216 {"RECMIXL Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
\r
1218 {"RECMIXR Mixer", "OUTMIXR Capture Switch", "OUTMIXR Mixer"},
\r
1219 {"RECMIXR Mixer", "MIC2_BST2 Capture Switch", "Mic2 Boost"},
\r
1220 {"RECMIXR Mixer", "AXIRVOL Capture Switch", "AXIR Boost"},
\r
1221 {"RECMIXR Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
\r
1223 {"ADC Mixer", NULL, "RECMIXL Mixer"},
\r
1224 {"ADC Mixer", NULL, "RECMIXR Mixer"},
\r
1225 {"Left ADC", NULL, "ADC Mixer"},
\r
1226 {"Right ADC", NULL, "ADC Mixer"},
\r
1228 {"Voice DAC Boost", NULL, "Voice DAC"},
\r
1230 {"SPKMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
\r
1231 {"SPKMIXL Mixer", "MIC1_P Playback Switch", "MIC1"},
\r
1232 {"SPKMIXL Mixer", "DACL Playback Switch", "Left DAC"},
\r
1233 {"SPKMIXL Mixer", "OUTMIXL Playback Switch", "OUTMIXL Mixer"},
\r
1235 {"SPKMIXR Mixer", "OUTMIXR Playback Switch", "OUTMIXR Mixer"},
\r
1236 {"SPKMIXR Mixer", "DACR Playback Switch", "Right DAC"},
\r
1237 {"SPKMIXR Mixer", "MIC2_P Playback Switch", "MIC2"},
\r
1238 {"SPKMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
\r
1240 {"OUTMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
\r
1241 {"OUTMIXL Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
\r
1242 {"OUTMIXL Mixer", "DACL Playback Switch", "Left DAC"},
\r
1243 {"OUTMIXL Mixer", "MIC1_BST1 Playback Switch", "Mic1 Boost"},
\r
1244 {"OUTMIXL Mixer", "MIC2_BST2 Playback Switch", "Mic2 Boost"},
\r
1245 {"OUTMIXL Mixer", "MONOIN_RXP Playback Switch", "MONOIN_RXP Boost"},
\r
1246 {"OUTMIXL Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
\r
1247 {"OUTMIXL Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
\r
1248 {"OUTMIXL Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
\r
1250 {"OUTMIXR Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
\r
1251 {"OUTMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
\r
1252 {"OUTMIXR Mixer", "DACR Playback Switch", "Right DAC"},
\r
1253 {"OUTMIXR Mixer", "MIC1_BST1 Playback Switch", "Mic1 Boost"},
\r
1254 {"OUTMIXR Mixer", "MIC2_BST2 Playback Switch", "Mic2 Boost"},
\r
1255 {"OUTMIXR Mixer", "MONOIN_RXN Playback Switch", "MONOIN_RXN Boost"},
\r
1256 {"OUTMIXR Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
\r
1257 {"OUTMIXR Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
\r
1258 {"OUTMIXR Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
\r
1260 {"Left SPK Vol", NULL, "SPKMIXL Mixer"},
\r
1261 {"Right SPK Vol", NULL, "SPKMIXR Mixer"},
\r
1262 {"Left HP Vol", NULL, "OUTMIXL Mixer"},
\r
1263 {"Left Out Vol", NULL, "OUTMIXL Mixer"},
\r
1264 {"Right Out Vol", NULL, "OUTMIXR Mixer"},
\r
1265 {"Right HP Vol", NULL, "OUTMIXR Mixer"},
\r
1267 {"AXO1MIX Mixer", "MIC1_BST1 Playback Switch", "Mic1 Boost"},
\r
1268 {"AXO1MIX Mixer", "OUTVOLL Playback Switch", "Left Out Vol"},
\r
1269 {"AXO1MIX Mixer", "OUTVOLR Playback Switch", "Right Out Vol"},
\r
1270 {"AXO1MIX Mixer", "MIC2_BST2 Playback Switch", "Mic2 Boost"},
\r
1272 {"AXO2MIX Mixer", "MIC1_BST1 Playback Switch", "Mic1 Boost"},
\r
1273 {"AXO2MIX Mixer", "OUTVOLL Playback Switch", "Left Out Vol"},
\r
1274 {"AXO2MIX Mixer", "OUTVOLR Playback Switch", "Right Out Vol"},
\r
1275 {"AXO2MIX Mixer", "MIC2_BST2 Playback Switch", "Mic2 Boost"},
\r
1277 {"SPOLMIX Mixer", "SPKVOLL Playback Switch", "Left SPK Vol"},
\r
1278 {"SPOLMIX Mixer", "SPKVOLR Playback Switch", "Right SPK Vol"},
\r
1280 {"SPORMIX Mixer", "SPKVOLL Playback Switch", "Left SPK Vol"},
\r
1281 {"SPORMIX Mixer", "SPKVOLR Playback Switch", "Right SPK Vol"},
\r
1283 {"MONOMIX Mixer", "OUTVOLL Playback Switch", "Left Out Vol"},
\r
1284 {"MONOMIX Mixer", "OUTVOLR Playback Switch", "Right Out Vol"},
\r
1286 {"SPOL Mux", "SPOLMIX", "SPOLMIX Mixer"},
\r
1287 {"SPOL Mux", "MONOIN_RX", "MONO_IN"},
\r
1288 {"SPOL Mux", "VDAC", "Voice DAC Boost"},
\r
1289 {"SPOL Mux", "DACL", "Left DAC"},
\r
1291 {"SPOR Mux", "SPORMIX", "SPORMIX Mixer"},
\r
1292 {"SPOR Mux", "MONOIN_RX", "MONO_IN"},
\r
1293 {"SPOR Mux", "VDAC", "Voice DAC Boost"},
\r
1294 {"SPOR Mux", "DACR", "Right DAC"},
\r
1296 {"Mono Mux", "MONOMIX", "MONOMIX Mixer"},
\r
1297 {"Mono Mux", "MONOIN_RX", "MONO_IN"},
\r
1298 {"Mono Mux", "VDAC", "Voice DAC Boost"},
\r
1300 {"Right DAC_HP", "NULL", "Right DAC"},
\r
1301 {"Left DAC_HP", "NULL", "Left DAC"},
\r
1303 {"HPL Mux", "LEFT HPVOL", "Left HP Vol"},
\r
1304 {"HPL Mux", "LEFT DAC", "Left DAC_HP"},
\r
1305 {"HPR Mux", "RIGHT HPVOL", "Right HP Vol"},
\r
1306 {"HPR Mux", "RIGHT DAC", "Right DAC_HP"},
\r
1308 {"SPKL Amp", NULL, "SPOL Mux"},
\r
1309 {"SPKR Amp", NULL, "SPOR Mux"},
\r
1310 {"Mono Amp", NULL, "Mono Mux"},
\r
1312 {"AUXO1", NULL, "AXO1MIX Mixer"},
\r
1313 {"AUXO2", NULL, "AXO2MIX Mixer"},
\r
1314 {"SPOL", NULL, "SPKL Amp"},
\r
1315 {"SPOR", NULL, "SPKR Amp"},
\r
1317 {"HPOL", NULL, "HPL Mux"},
\r
1318 {"HPOR", NULL, "HPR Mux"},
\r
1320 {"MONO", NULL, "Mono Amp"}
\r
1323 static int rt5631_add_widgets(struct snd_soc_codec *codec)
\r
1325 struct snd_soc_dapm_context *dapm = &codec->dapm;
\r
1327 snd_soc_dapm_new_controls(dapm, rt5631_dapm_widgets,
\r
1328 ARRAY_SIZE(rt5631_dapm_widgets));
\r
1329 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
\r
1334 static int gvolume = 0;
\r
1337 static int get_vol(int max, int min, int stage_num, int stage)
\r
1339 int ret, step=((max-min)<<8)/(stage_num-1);
\r
1340 if(stage==stage_num-1)
\r
1345 ret=(stage_num-stage-1) * step;
\r
1349 DBG("%s(): ret=%02x, max=0x%02x, min=0x%02x, stage_num=%d, stage=%d\n",
\r
1359 static void rt5631_set_volume(int vollevel)
\r
1361 struct snd_soc_codec *codec = rt5631_codec;
\r
1362 int tmpvol1, tmpvol2;
\r
1364 //DBG("rt5631_set_volume = %d\n", vollevel);
\r
1366 if (vollevel > 15) vollevel = 8;
\r
1367 gvolume = vollevel;
\r
1369 // tmpvol1 = voltab[0][vollevel];
\r
1370 // tmpvol2 = voltab[1][vollevel];
\r
1371 tmpvol1=get_vol(0x27, DEF_VOL_SPK&0x3f, 16, vollevel);
\r
1372 tmpvol2=get_vol(0x1f, DEF_VOL&0x1f, 16, vollevel);
\r
1374 if(vollevel == 0){
\r
1375 rt5631_write_mask(codec, RT5631_SPK_OUT_VOL, 0x8080, 0x8080);
\r
1376 rt5631_write_mask(codec, RT5631_HP_OUT_VOL, 0x8080, 0x8080);
\r
1379 // rt5631_write_mask(codec, RT5631_SPK_OUT_VOL, 0x00, 0x8080);
\r
1380 // rt5631_write_mask(codec, RT5631_HP_OUT_VOL, 0x00, 0x8080);
\r
1383 rt5631_write_mask(codec, RT5631_SPK_OUT_VOL, ((tmpvol1<<8)|tmpvol1), 0x3f3f);
\r
1384 rt5631_write_mask(codec, RT5631_HP_OUT_VOL, ((tmpvol2<<8)|tmpvol2), 0x3f3f);
\r
1387 static void rt5631_set_eq(int on)
\r
1389 struct snd_soc_codec *codec = rt5631_codec;
\r
1390 unsigned int Reg0C;
\r
1392 Reg0C = rt5631_read(codec, RT5631_STEREO_DAC_VOL_1);
\r
1393 DBG("------- rt5631_set_eq: read Reg0C = 0x%04x\n", Reg0C);
\r
1402 DBG("------- rt5631_set_eq: write Reg0C = 0x%04x\n", Reg0C);
\r
1403 rt5631_write(codec, RT5631_STEREO_DAC_VOL_1, Reg0C);
\r
1408 static int voltab[2][16] =
\r
1411 {0x27, 0x1b, 0x18, 0x15, 0x13, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06},
\r
1413 {0x1f, 0x1c, 0x1a, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
\r
1416 static void rt5631_set_volume(int vollevel)
\r
1418 struct snd_soc_codec *codec = rt5631_codec;
\r
1419 u8 tmpvol1, tmpvol2;
\r
1420 u16 spk_vol, hp_vol;
\r
1422 DBG("rt5631_set_volume = %d\n", vollevel);
\r
1424 if (vollevel > 15) vollevel = 8;
\r
1425 gvolume = vollevel;
\r
1427 tmpvol1 = voltab[0][vollevel];
\r
1428 tmpvol2 = voltab[1][vollevel];
\r
1430 spk_vol = snd_soc_read(codec, RT5631_SPK_OUT_VOL);
\r
1431 hp_vol = snd_soc_read(codec, RT5631_HP_OUT_VOL);
\r
1433 DBG("\n\nold value: 0x%04x, 0x%04x\n", spk_vol & 0x3F3F, hp_vol & 0x3F3F);
\r
1434 DBG("new value: 0x%04x\n", (tmpvol1<<8)|tmpvol1, (tmpvol2<<8)|tmpvol2);
\r
1436 spk_vol &= 0x3C3C;
\r
1437 spk_vol |= (tmpvol1<<8)|tmpvol1;
\r
1439 hp_vol |= (tmpvol2<<8)|tmpvol2;
\r
1441 snd_soc_write(codec, RT5631_SPK_OUT_VOL, spk_vol);
\r
1442 snd_soc_write(codec, RT5631_HP_OUT_VOL , hp_vol);
\r
1446 struct coeff_clk_div {
\r
1453 /* PLL divisors yes*/
\r
1460 static const struct pll_div codec_master_pll_div[] = {
\r
1461 {2048000, 8192000, 0x0ea0},
\r
1462 {3686400, 8192000, 0x4e27},
\r
1463 {12000000, 8192000, 0x456b},
\r
1464 {13000000, 8192000, 0x495f},
\r
1465 {13100000, 8192000, 0x0320},
\r
1466 {2048000, 11289600, 0xf637},
\r
1467 {3686400, 11289600, 0x2f22},
\r
1468 {12000000, 11289600, 0x3e2f},
\r
1469 {13000000, 11289600, 0x4d5b},
\r
1470 {13100000, 11289600, 0x363b},
\r
1471 {2048000, 16384000, 0x1ea0},
\r
1472 {3686400, 16384000, 0x9e27},
\r
1473 {12000000, 16384000, 0x452b},
\r
1474 {13000000, 16384000, 0x542f},
\r
1475 {13100000, 16384000, 0x03a0},
\r
1476 {2048000, 16934400, 0xe625},
\r
1477 {3686400, 16934400, 0x9126},
\r
1478 {12000000, 16934400, 0x4d2c},
\r
1479 {13000000, 16934400, 0x742f},
\r
1480 {13100000, 16934400, 0x3c27},
\r
1481 {2048000, 22579200, 0x2aa0},
\r
1482 {3686400, 22579200, 0x2f20},
\r
1483 {12000000, 22579200, 0x7e2f},
\r
1484 {13000000, 22579200, 0x742f},
\r
1485 {13100000, 22579200, 0x3c27},
\r
1486 {2048000, 24576000, 0x2ea0},
\r
1487 {3686400, 24576000, 0xee27},
\r
1488 {12000000, 24576000, 0x2915},
\r
1489 {13000000, 24576000, 0x772e},
\r
1490 {13100000, 24576000, 0x0d20},
\r
1491 {26000000, 24576000, 0x2027},
\r
1492 {26000000, 22579200, 0x392f},
\r
1493 {24576000, 22579200, 0x0921},
\r
1494 {24576000, 24576000, 0x02a0},
\r
1497 static const struct pll_div codec_slave_pll_div[] = {
\r
1498 {256000, 2048000, 0x46f0},
\r
1499 {256000, 4096000, 0x3ea0},
\r
1500 {352800, 5644800, 0x3ea0},
\r
1501 {512000, 8192000, 0x3ea0},
\r
1502 {1024000, 8192000, 0x46f0},
\r
1503 {705600, 11289600, 0x3ea0},
\r
1504 {1024000, 16384000, 0x3ea0},
\r
1505 {1411200, 22579200, 0x3ea0},
\r
1506 {1536000, 24576000, 0x3ea0},
\r
1507 {2048000, 16384000, 0x1ea0},
\r
1508 {2822400, 22579200, 0x1ea0},
\r
1509 {2822400, 45158400, 0x5ec0},
\r
1510 {5644800, 45158400, 0x46f0},
\r
1511 {3072000, 24576000, 0x1ea0},
\r
1512 {3072000, 49152000, 0x5ec0},
\r
1513 {6144000, 49152000, 0x46f0},
\r
1514 {705600, 11289600, 0x3ea0},
\r
1515 {705600, 8467200, 0x3ab0},
\r
1516 {24576000, 24576000, 0x02a0},
\r
1517 {1411200, 11289600, 0x1690},
\r
1518 {2822400, 11289600, 0x0a90},
\r
1519 {1536000, 12288000, 0x1690},
\r
1520 {3072000, 12288000, 0x0a90},
\r
1523 struct coeff_clk_div coeff_div[] = {
\r
1524 /* sysclk is 256fs */
\r
1525 {2048000, 8000 * 32, 8000, 0x1000},
\r
1526 {2048000, 8000 * 64, 8000, 0x0000},
\r
1527 {2822400, 11025 * 32, 11025, 0x1000},
\r
1528 {2822400, 11025 * 64, 11025, 0x0000},
\r
1529 {4096000, 16000 * 32, 16000, 0x1000},
\r
1530 {4096000, 16000 * 64, 16000, 0x0000},
\r
1531 {5644800, 22050 * 32, 22050, 0x1000},
\r
1532 {5644800, 22050 * 64, 22050, 0x0000},
\r
1533 {8192000, 32000 * 32, 32000, 0x1000},
\r
1534 {8192000, 32000 * 64, 32000, 0x0000},
\r
1535 {11289600, 44100 * 32, 44100, 0x1000},
\r
1536 {11289600, 44100 * 64, 44100, 0x0000},
\r
1537 {12288000, 48000 * 32, 48000, 0x1000},
\r
1538 {12288000, 48000 * 64, 48000, 0x0000},
\r
1539 {22579200, 88200 * 32, 88200, 0x1000},
\r
1540 {22579200, 88200 * 64, 88200, 0x0000},
\r
1541 {24576000, 96000 * 32, 96000, 0x1000},
\r
1542 {24576000, 96000 * 64, 96000, 0x0000},
\r
1543 /* sysclk is 512fs */
\r
1544 {4096000, 8000 * 32, 8000, 0x3000},
\r
1545 {4096000, 8000 * 64, 8000, 0x2000},
\r
1546 {5644800, 11025 * 32, 11025, 0x3000},
\r
1547 {5644800, 11025 * 64, 11025, 0x2000},
\r
1548 {8192000, 16000 * 32, 16000, 0x3000},
\r
1549 {8192000, 16000 * 64, 16000, 0x2000},
\r
1550 {11289600, 22050 * 32, 22050, 0x3000},
\r
1551 {11289600, 22050 * 64, 22050, 0x2000},
\r
1552 {16384000, 32000 * 32, 32000, 0x3000},
\r
1553 {16384000, 32000 * 64, 32000, 0x2000},
\r
1554 {22579200, 44100 * 32, 44100, 0x3000},
\r
1555 {22579200, 44100 * 64, 44100, 0x2000},
\r
1556 {24576000, 48000 * 32, 48000, 0x3000},
\r
1557 {24576000, 48000 * 64, 48000, 0x2000},
\r
1558 {45158400, 88200 * 32, 88200, 0x3000},
\r
1559 {45158400, 88200 * 64, 88200, 0x2000},
\r
1560 {49152000, 96000 * 32, 96000, 0x3000},
\r
1561 {49152000, 96000 * 64, 96000, 0x2000},
\r
1562 /* sysclk is 24.576Mhz or 22.5792Mhz */
\r
1563 {24576000, 8000 * 32, 8000, 0x7080},
\r
1564 {24576000, 8000 * 64, 8000, 0x6080},
\r
1565 {24576000, 16000 * 32, 16000, 0x5080},
\r
1566 {24576000, 16000 * 64, 16000, 0x4080},
\r
1567 {24576000, 24000 * 32, 24000, 0x5000},
\r
1568 {24576000, 24000 * 64, 24000, 0x4000},
\r
1569 {24576000, 32000 * 32, 32000, 0x3080},
\r
1570 {24576000, 32000 * 64, 32000, 0x2080},
\r
1571 {22579200, 11025 * 32, 11025, 0x7000},
\r
1572 {22579200, 11025 * 64, 11025, 0x6000},
\r
1573 {22579200, 22050 * 32, 22050, 0x5000},
\r
1574 {22579200, 22050 * 64, 22050, 0x4000},
\r
1577 static int get_coeff(int mclk, int rate, int timesofbclk)
\r
1581 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
\r
1582 if (coeff_div[i].mclk == mclk && coeff_div[i].rate == rate &&
\r
1583 (coeff_div[i].bclk / coeff_div[i].rate) == timesofbclk)
\r
1589 static int get_coeff_in_slave_mode(int mclk, int rate)
\r
1591 return get_coeff(mclk, rate, timesofbclk);
\r
1594 static int get_coeff_in_master_mode(int mclk, int rate, int bclk)
\r
1596 return get_coeff(mclk, rate, (bclk / rate));
\r
1599 static void rt5631_set_dmic_params(struct snd_soc_codec *codec,
\r
1600 struct snd_pcm_hw_params *params)
\r
1604 rt5631_write_mask(codec, RT5631_GPIO_CTRL,
\r
1605 GPIO_PIN_FUN_SEL_GPIO_DIMC | GPIO_DMIC_FUN_SEL_DIMC,
\r
1606 GPIO_PIN_FUN_SEL_MASK | GPIO_DMIC_FUN_SEL_MASK);
\r
1607 rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL, DMIC_ENA, DMIC_ENA_MASK);
\r
1608 rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
\r
1609 DMIC_L_CH_LATCH_FALLING | DMIC_R_CH_LATCH_RISING,
\r
1610 DMIC_L_CH_LATCH_MASK|DMIC_R_CH_LATCH_MASK);
\r
1612 rate = params_rate(params);
\r
1616 rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
\r
1617 DMIC_CLK_CTRL_TO_32FS, DMIC_CLK_CTRL_MASK);
\r
1622 rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
\r
1623 DMIC_CLK_CTRL_TO_64FS, DMIC_CLK_CTRL_MASK);
\r
1629 rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
\r
1630 DMIC_CLK_CTRL_TO_128FS, DMIC_CLK_CTRL_MASK);
\r
1637 rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
\r
1638 DMIC_L_CH_UNMUTE | DMIC_R_CH_UNMUTE,
\r
1639 DMIC_L_CH_MUTE_MASK | DMIC_R_CH_MUTE_MASK);
\r
1644 static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
\r
1645 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
\r
1647 struct snd_soc_pcm_runtime *rtd = substream->private_data;
\r
1648 struct snd_soc_codec *codec = rtd->codec;
\r
1649 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
1650 int stream = substream->stream, rate = params_rate(params), coeff;
\r
1651 unsigned int iface = 0;
\r
1653 pr_debug("enter %s\n", __func__);
\r
1655 if (!rt5631->master)
\r
1656 coeff = get_coeff_in_slave_mode(rt5631->sysclk, rate);
\r
1658 coeff = get_coeff_in_master_mode(rt5631->sysclk, rate,
\r
1659 rate * timesofbclk);
\r
1661 pr_err("%s: get coeff err!\n", __func__);
\r
1663 switch (params_format(params)) {
\r
1664 case SNDRV_PCM_FORMAT_S16_LE:
\r
1666 case SNDRV_PCM_FORMAT_S20_3LE:
\r
1667 iface |= SDP_I2S_DL_20;
\r
1669 case SNDRV_PCM_FORMAT_S24_LE:
\r
1670 iface |= SDP_I2S_DL_24;
\r
1672 case SNDRV_PCM_FORMAT_S8:
\r
1673 iface |= SDP_I2S_DL_8;
\r
1679 if (SNDRV_PCM_STREAM_CAPTURE == stream) {
\r
1680 if (rt5631->dmic_used_flag)
\r
1681 rt5631_set_dmic_params(codec, params);
\r
1684 rt5631_write_mask(codec, RT5631_SDP_CTRL, iface, SDP_I2S_DL_MASK);
\r
1687 rt5631_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL,
\r
1688 coeff_div[coeff].reg_val);
\r
1693 static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
\r
1696 struct snd_soc_codec *codec = codec_dai->codec;
\r
1697 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
1698 unsigned int iface = 0;
\r
1700 pr_debug("enter %s\n", __func__);
\r
1702 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
\r
1703 case SND_SOC_DAIFMT_CBM_CFM:
\r
1704 rt5631->master = 1;
\r
1706 case SND_SOC_DAIFMT_CBS_CFS:
\r
1707 iface |= SDP_MODE_SEL_SLAVE;
\r
1708 rt5631->master = 0;
\r
1714 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
\r
1715 case SND_SOC_DAIFMT_I2S:
\r
1717 case SND_SOC_DAIFMT_LEFT_J:
\r
1718 iface |= SDP_I2S_DF_LEFT;
\r
1720 case SND_SOC_DAIFMT_DSP_A:
\r
1721 iface |= SDP_I2S_DF_PCM_A;
\r
1723 case SND_SOC_DAIFMT_DSP_B:
\r
1724 iface |= SDP_I2S_DF_PCM_B;
\r
1730 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
\r
1731 case SND_SOC_DAIFMT_NB_NF:
\r
1733 case SND_SOC_DAIFMT_IB_NF:
\r
1734 iface |= SDP_I2S_BCLK_POL_CTRL;
\r
1740 rt5631_write(codec, RT5631_SDP_CTRL, iface);
\r
1745 static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
\r
1746 int clk_id, unsigned int freq, int dir)
\r
1748 struct snd_soc_codec *codec = codec_dai->codec;
\r
1749 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
1751 pr_info("enter %s, syclk=%d\n", __func__, freq);
\r
1752 if ((freq >= (256 * 8000)) && (freq <= (512 * 96000))) {
\r
1753 rt5631->sysclk = freq;
\r
1757 pr_info("unsupported sysclk freq %u for audio i2s\n", freq);
\r
1758 pr_info("set sysclk to 24.576Mhz by default\n");
\r
1760 rt5631->sysclk = 24576000;
\r
1764 static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
\r
1765 int source, unsigned int freq_in, unsigned int freq_out)
\r
1767 struct snd_soc_codec *codec = codec_dai->codec;
\r
1768 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
1769 int i, ret = -EINVAL;
\r
1771 printk(KERN_DEBUG "enter %s\n", __func__);
\r
1773 if (!freq_in || !freq_out)
\r
1776 if (rt5631->master) {
\r
1777 for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++)
\r
1778 if (freq_in == codec_master_pll_div[i].pll_in &&
\r
1779 freq_out == codec_master_pll_div[i].pll_out) {
\r
1780 rt5631_write(codec, RT5631_PLL_CTRL,
\r
1781 codec_master_pll_div[i].reg_val);
\r
1782 schedule_timeout_uninterruptible(
\r
1783 msecs_to_jiffies(20));
\r
1784 rt5631_write(codec, RT5631_GLOBAL_CLK_CTRL,
\r
1785 SYSCLK_SOUR_SEL_PLL);
\r
1786 rt5631->pll_used_flag = 1;
\r
1791 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++)
\r
1792 if (freq_in == codec_slave_pll_div[i].pll_in &&
\r
1793 freq_out == codec_slave_pll_div[i].pll_out) {
\r
1794 rt5631_write(codec, RT5631_PLL_CTRL,
\r
1795 codec_slave_pll_div[i].reg_val);
\r
1796 schedule_timeout_uninterruptible(
\r
1797 msecs_to_jiffies(20));
\r
1798 rt5631_write(codec, RT5631_GLOBAL_CLK_CTRL,
\r
1799 SYSCLK_SOUR_SEL_PLL |
\r
1800 PLLCLK_SOUR_SEL_BITCLK);
\r
1801 rt5631->pll_used_flag = 1;
\r
1810 #if defined(CONFIG_ADJUST_VOL_BY_CODEC)
\r
1811 static int rt5631_trigger(struct snd_pcm_substream *substream, int status, struct snd_soc_dai *dai)
\r
1813 //DBG("rt5631_trigger\n");
\r
1814 if(status == SNDRV_PCM_TRIGGER_VOLUME){
\r
1815 //DBG("rt5631_trigger: vol = %d\n", substream->number);
\r
1816 if(substream->number < 100){
\r
1817 rt5631_set_volume(substream->number);
\r
1819 if(substream->number == 100) { // eq off
\r
1820 DBG("---------- eq off\n");
\r
1822 } else { // eq on +6dB
\r
1823 DBG("---------- eq on\n");
\r
1833 static ssize_t rt5631_index_reg_show(struct device *dev,
\r
1834 struct device_attribute *attr, char *buf)
\r
1836 #define IDX_REG_FMT "%02x: %04x\n"
\r
1837 #define IDX_REG_LEN 9
\r
1841 cnt += sprintf(buf, "RT5631 index register\n");
\r
1842 for (i = 0; i < 0x55; i++) {
\r
1843 if (cnt + IDX_REG_LEN >= PAGE_SIZE - 1)
\r
1845 val = rt5631_read_index(rt5631_codec, i);
\r
1848 cnt += sprintf(buf + cnt, IDX_REG_FMT, i, val);
\r
1851 if (cnt >= PAGE_SIZE)
\r
1852 cnt = PAGE_SIZE - 1;
\r
1856 static DEVICE_ATTR(index_reg, 0444, rt5631_index_reg_show, NULL);
\r
1858 #define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_96000
\r
1859 #define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \
\r
1860 SNDRV_PCM_FMTBIT_S20_3LE | \
\r
1861 SNDRV_PCM_FMTBIT_S24_LE | \
\r
1862 SNDRV_PCM_FMTBIT_S8)
\r
1864 struct snd_soc_dai_ops rt5631_ops = {
\r
1865 .hw_params = rt5631_hifi_pcm_params,
\r
1866 .set_fmt = rt5631_hifi_codec_set_dai_fmt,
\r
1867 .set_sysclk = rt5631_hifi_codec_set_dai_sysclk,
\r
1868 .set_pll = rt5631_codec_set_dai_pll,
\r
1869 #if defined(CONFIG_ADJUST_VOL_BY_CODEC)
\r
1870 .trigger = rt5631_trigger,
\r
1874 struct snd_soc_dai_driver rt5631_dai[] = {
\r
1876 .name = "RT5631 HiFi",
\r
1878 .stream_name = "HIFI Playback",
\r
1879 .channels_min = 1,
\r
1880 .channels_max = 2,
\r
1881 .rates = RT5631_STEREO_RATES,
\r
1882 .formats = RT5631_FORMAT,
\r
1885 .stream_name = "HIFI Capture",
\r
1886 .channels_min = 1,
\r
1887 .channels_max = 2,
\r
1888 .rates = RT5631_STEREO_RATES,
\r
1889 .formats = RT5631_FORMAT,
\r
1891 .ops = &rt5631_ops,
\r
1894 EXPORT_SYMBOL_GPL(rt5631_dai);
\r
1896 static int rt5631_set_bias_level(struct snd_soc_codec *codec,
\r
1897 enum snd_soc_bias_level level)
\r
1900 case SND_SOC_BIAS_ON:
\r
1903 case SND_SOC_BIAS_PREPARE:
\r
1904 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
\r
1905 PWR_VREF | PWR_MAIN_BIAS, PWR_VREF | PWR_MAIN_BIAS);
\r
1906 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD2,
\r
1907 PWR_MICBIAS1_VOL | PWR_MICBIAS2_VOL,
\r
1908 PWR_MICBIAS1_VOL | PWR_MICBIAS2_VOL);
\r
1911 case SND_SOC_BIAS_STANDBY:
\r
1912 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD2, 0,
\r
1913 PWR_MICBIAS1_VOL | PWR_MICBIAS2_VOL);
\r
1916 case SND_SOC_BIAS_OFF:
\r
1917 rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
\r
1918 RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE);
\r
1919 rt5631_write_mask(codec, RT5631_HP_OUT_VOL,
\r
1920 RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE);
\r
1921 rt5631_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
\r
1922 rt5631_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
\r
1923 rt5631_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
\r
1924 rt5631_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
\r
1930 codec->dapm.bias_level = level;
\r
1935 static int rt5631_probe(struct snd_soc_codec *codec)
\r
1937 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
1940 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
\r
1942 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
\r
1945 codec->cache_bypass = 1;
\r
1947 val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
\r
1949 rt5631->codec_version = 1;
\r
1951 rt5631->codec_version = 0;
\r
1953 rt5631_reset(codec);
\r
1954 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
\r
1955 PWR_VREF | PWR_MAIN_BIAS, PWR_VREF | PWR_MAIN_BIAS);
\r
1956 schedule_timeout_uninterruptible(msecs_to_jiffies(80));
\r
1957 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3, PWR_FAST_VREF_CTRL,
\r
1958 PWR_FAST_VREF_CTRL);
\r
1959 rt5631_reg_init(codec);
\r
1961 /* power off ClassD auto Recovery */
\r
1962 if (rt5631->codec_version)
\r
1963 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
\r
1966 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
\r
1969 codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
\r
1970 rt5631_codec = codec;
\r
1972 #if (RT5631_SPK_TIMER == 1)
\r
1973 /* Timer module installing */
\r
1974 setup_timer( &spk_timer, spk_timer_callback, 0 );
\r
1975 DBG( "Starting timer to fire in 5s (%ld)\n", jiffies );
\r
1976 ret = mod_timer( &spk_timer, jiffies + msecs_to_jiffies(5000) );
\r
1977 if (ret) printk("Error in mod_timer\n");
\r
1979 INIT_WORK(&spk_work, spk_work_handler);
\r
1982 snd_soc_add_controls(codec, rt5631_snd_controls,
\r
1983 ARRAY_SIZE(rt5631_snd_controls));
\r
1984 rt5631_add_widgets(codec);
\r
1986 ret = device_create_file(codec->dev, &dev_attr_index_reg);
\r
1988 dev_err(codec->dev,
\r
1989 "Failed to create index_reg sysfs files: %d\n", ret);
\r
1993 pr_info("RT5631 initial ok!\n");
\r
1998 static int rt5631_remove(struct snd_soc_codec *codec)
\r
2002 #if (RT5631_SPK_TIMER == 1)
\r
2003 /* Timer¡¡module¡¡uninstalling */
\r
2005 ret = del_timer(&spk_timer);
\r
2006 if(ret) printk("The timer is still in use...\n");
\r
2007 DBG("Timer module uninstalling\n");
\r
2011 rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
\r
2015 static int rt5631_suspend(struct snd_soc_codec *codec, pm_message_t state)
\r
2017 rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
\r
2021 static int rt5631_resume(struct snd_soc_codec *codec)
\r
2023 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
\r
2025 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
\r
2026 PWR_VREF | PWR_MAIN_BIAS, PWR_VREF | PWR_MAIN_BIAS);
\r
2027 schedule_timeout_uninterruptible(msecs_to_jiffies(110));
\r
2028 rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
\r
2029 PWR_FAST_VREF_CTRL, PWR_FAST_VREF_CTRL);
\r
2030 rt5631_reg_init(codec);
\r
2032 /* power off ClassD auto Recovery */
\r
2033 if (rt5631->codec_version)
\r
2034 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
\r
2037 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
\r
2040 #if (RT5631_SPK_TIMER == 1)
\r
2041 last_is_spk = !last_is_spk; //wired~, update eqmode right here by spk_timer.
\r
2047 void codec_set_spk(bool on)
\r
2049 struct snd_soc_codec *codec = rt5631_codec;
\r
2051 DBG("%s: %d\n", __func__, on);
\r
2057 DBG("snd_soc_dapm_enable_pin\n");
\r
2058 snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack");
\r
2059 snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk");
\r
2063 DBG("snd_soc_dapm_disable_pin\n");
\r
2064 snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack");
\r
2065 snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk");
\r
2068 snd_soc_dapm_sync(&codec->dapm);
\r
2074 * detect short current for mic1
\r
2076 int rt5631_ext_mic_detect(void)
\r
2078 struct snd_soc_codec *codec = rt5631_codec;
\r
2081 rt5631_write_mask(codec, RT5631_MIC_CTRL_2, MICBIAS1_S_C_DET_ENA,
\r
2082 MICBIAS1_S_C_DET_MASK);
\r
2083 det = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2) & 0x0001;
\r
2084 rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0001, 0x00001);
\r
2088 EXPORT_SYMBOL_GPL(rt5631_ext_mic_detect);
\r
2090 static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
\r
2091 .probe = rt5631_probe,
\r
2092 .remove = rt5631_remove,
\r
2093 .suspend = rt5631_suspend,
\r
2094 .resume = rt5631_resume,
\r
2095 .set_bias_level = rt5631_set_bias_level,
\r
2096 .reg_cache_size = ARRAY_SIZE(rt5631_reg),
\r
2097 .reg_word_size = sizeof(u16),
\r
2098 .reg_cache_default = rt5631_reg,
\r
2099 .reg_cache_step = 1,
\r
2102 static const struct i2c_device_id rt5631_i2c_id[] = {
\r
2106 MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
\r
2108 static int rt5631_i2c_probe(struct i2c_client *i2c,
\r
2109 const struct i2c_device_id *id)
\r
2111 struct rt5631_priv *rt5631;
\r
2114 pr_info("RT5631 Audio Codec %s\n", RT5631_VERSION);
\r
2116 rt5631 = kzalloc(sizeof(struct rt5631_priv), GFP_KERNEL);
\r
2117 if (NULL == rt5631)
\r
2120 i2c_set_clientdata(i2c, rt5631);
\r
2122 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
\r
2123 rt5631_dai, ARRAY_SIZE(rt5631_dai));
\r
2130 static __devexit int rt5631_i2c_remove(struct i2c_client *client)
\r
2132 snd_soc_unregister_codec(&client->dev);
\r
2133 kfree(i2c_get_clientdata(client));
\r
2137 struct i2c_driver rt5631_i2c_driver = {
\r
2140 .owner = THIS_MODULE,
\r
2142 .probe = rt5631_i2c_probe,
\r
2143 .remove = __devexit_p(rt5631_i2c_remove),
\r
2144 .id_table = rt5631_i2c_id,
\r
2147 static int __init rt5631_modinit(void)
\r
2149 return i2c_add_driver(&rt5631_i2c_driver);
\r
2151 module_init(rt5631_modinit);
\r
2153 static void __exit rt5631_modexit(void)
\r
2155 i2c_del_driver(&rt5631_i2c_driver);
\r
2157 module_exit(rt5631_modexit);
\r
2159 MODULE_DESCRIPTION("ASoC RT5631 driver");
\r
2160 MODULE_AUTHOR("flove <flove@realtek.com>");
\r
2161 MODULE_LICENSE("GPL");
\r