aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/Kconfig3
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/alc5632.c1153
-rw-r--r--sound/soc/codecs/alc5632.h249
4 files changed, 1407 insertions, 0 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 4584514d93d4..684cc1570689 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -26,6 +26,7 @@ config SND_SOC_ALL_CODECS
26 select SND_SOC_AK4642 if I2C 26 select SND_SOC_AK4642 if I2C
27 select SND_SOC_AK4671 if I2C 27 select SND_SOC_AK4671 if I2C
28 select SND_SOC_ALC5623 if I2C 28 select SND_SOC_ALC5623 if I2C
29 select SND_SOC_ALC5632 if I2C
29 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 30 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
30 select SND_SOC_CS42L51 if I2C 31 select SND_SOC_CS42L51 if I2C
31 select SND_SOC_CS4270 if I2C 32 select SND_SOC_CS4270 if I2C
@@ -168,6 +169,8 @@ config SND_SOC_AK4671
168 169
169config SND_SOC_ALC5623 170config SND_SOC_ALC5623
170 tristate 171 tristate
172config SND_SOC_ALC5632
173 tristate
171 174
172config SND_SOC_CQ0093VC 175config SND_SOC_CQ0093VC
173 tristate 176 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index a7c415dc22fe..af64905f36ca 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -31,6 +31,7 @@ snd-soc-pcm3008-objs := pcm3008.o
31snd-soc-rt5631-objs := rt5631.o 31snd-soc-rt5631-objs := rt5631.o
32snd-soc-sgtl5000-objs := sgtl5000.o 32snd-soc-sgtl5000-objs := sgtl5000.o
33snd-soc-alc5623-objs := alc5623.o 33snd-soc-alc5623-objs := alc5623.o
34snd-soc-alc5632-objs := alc5632.o
34snd-soc-sn95031-objs := sn95031.o 35snd-soc-sn95031-objs := sn95031.o
35snd-soc-spdif-objs := spdif_transciever.o 36snd-soc-spdif-objs := spdif_transciever.o
36snd-soc-ssm2602-objs := ssm2602.o 37snd-soc-ssm2602-objs := ssm2602.o
@@ -113,6 +114,7 @@ obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
113obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 114obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
114obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 115obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
115obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 116obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
117obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
116obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 118obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
117obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 119obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
118obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 120obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
new file mode 100644
index 000000000000..ee6a497b5e71
--- /dev/null
+++ b/sound/soc/codecs/alc5632.c
@@ -0,0 +1,1153 @@
1/*
2* alc5632.c -- ALC5632 ALSA SoC Audio Codec
3*
4* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5*
6* Authors: Leon Romanovsky <leon@leon.nu>
7* Andrey Danin <danindrey@mail.ru>
8* Ilya Petrov <ilya.muromec@gmail.com>
9* Marc Dietrich <marvin24@gmx.de>
10*
11* Based on alc5623.c by Arnaud Patard
12*
13* This program is free software; you can redistribute it and/or modify
14* it under the terms of the GNU General Public License version 2 as
15* published by the Free Software Foundation.
16*/
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/pm.h>
23#include <linux/i2c.h>
24#include <linux/slab.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/tlv.h>
29#include <sound/soc.h>
30#include <sound/initval.h>
31
32#include "alc5632.h"
33
34/*
35 * ALC5632 register cache
36 */
37static const u16 alc5632_reg_defaults[] = {
38 0x59B4, 0x0000, 0x8080, 0x0000, /* 0 */
39 0x8080, 0x0000, 0x8080, 0x0000, /* 4 */
40 0xC800, 0x0000, 0xE808, 0x0000, /* 8 */
41 0x1010, 0x0000, 0x0808, 0x0000, /* 12 */
42 0xEE0F, 0x0000, 0xCBCB, 0x0000, /* 16 */
43 0x7F7F, 0x0000, 0x0000, 0x0000, /* 20 */
44 0xE010, 0x0000, 0x0000, 0x0000, /* 24 */
45 0x8008, 0x0000, 0x0000, 0x0000, /* 28 */
46 0x0000, 0x0000, 0x0000, 0x0000, /* 32 */
47 0x00C0, 0x0000, 0xEF00, 0x0000, /* 36 */
48 0x0000, 0x0000, 0x0000, 0x0000, /* 40 */
49 0x0000, 0x0000, 0x0000, 0x0000, /* 44 */
50 0x0000, 0x0000, 0x0000, 0x0000, /* 48 */
51 0x8000, 0x0000, 0x0000, 0x0000, /* 52 */
52 0x0000, 0x0000, 0x0000, 0x0000, /* 56 */
53 0x0000, 0x0000, 0x8000, 0x0000, /* 60 */
54 0x0C0A, 0x0000, 0x0000, 0x0000, /* 64 */
55 0x0000, 0x0000, 0x0000, 0x0000, /* 68 */
56 0x0000, 0x0000, 0x0000, 0x0000, /* 72 */
57 0xBE3E, 0x0000, 0xBE3E, 0x0000, /* 76 */
58 0x0000, 0x0000, 0x0000, 0x0000, /* 80 */
59 0x803A, 0x0000, 0x0000, 0x0000, /* 84 */
60 0x0000, 0x0000, 0x0009, 0x0000, /* 88 */
61 0x0000, 0x0000, 0x3000, 0x0000, /* 92 */
62 0x3075, 0x0000, 0x1010, 0x0000, /* 96 */
63 0x3110, 0x0000, 0x0000, 0x0000, /* 100 */
64 0x0553, 0x0000, 0x0000, 0x0000, /* 104 */
65 0x0000, 0x0000, 0x0000, 0x0000, /* 108 */
66};
67
68/* codec private data */
69struct alc5632_priv {
70 enum snd_soc_control_type control_type;
71 void *control_data;
72 struct mutex mutex;
73 u8 id;
74 unsigned int sysclk;
75};
76
77static int alc5632_volatile_register(struct snd_soc_codec *codec,
78 unsigned int reg)
79{
80 switch (reg) {
81 case ALC5632_RESET:
82 case ALC5632_PWR_DOWN_CTRL_STATUS:
83 case ALC5632_GPIO_PIN_STATUS:
84 case ALC5632_OVER_CURR_STATUS:
85 case ALC5632_HID_CTRL_DATA:
86 case ALC5632_EQ_CTRL:
87 return 1;
88
89 default:
90 break;
91 }
92
93 return 0;
94}
95
96static inline int alc5632_reset(struct snd_soc_codec *codec)
97{
98 snd_soc_write(codec, ALC5632_RESET, 0);
99 return snd_soc_read(codec, ALC5632_RESET);
100}
101
102static int amp_mixer_event(struct snd_soc_dapm_widget *w,
103 struct snd_kcontrol *kcontrol, int event)
104{
105 /* to power-on/off class-d amp generators/speaker */
106 /* need to write to 'index-46h' register : */
107 /* so write index num (here 0x46) to reg 0x6a */
108 /* and then 0xffff/0 to reg 0x6c */
109 snd_soc_write(w->codec, ALC5632_HID_CTRL_INDEX, 0x46);
110
111 switch (event) {
112 case SND_SOC_DAPM_PRE_PMU:
113 snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
114 break;
115 case SND_SOC_DAPM_POST_PMD:
116 snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0);
117 break;
118 }
119
120 return 0;
121}
122
123/*
124 * ALC5632 Controls
125 */
126
127/* -34.5db min scale, 1.5db steps, no mute */
128static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
129/* -46.5db min scale, 1.5db steps, no mute */
130static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
131/* -16.5db min scale, 1.5db steps, no mute */
132static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
133static const unsigned int boost_tlv[] = {
134 TLV_DB_RANGE_HEAD(3),
135 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
136 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
137 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
138};
139/* 0db min scale, 6 db steps, no mute */
140static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
141/* 0db min scalem 0.75db steps, no mute */
142static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0);
143
144static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
145 /* left starts at bit 8, right at bit 0 */
146 /* 31 steps (5 bit), -46.5db scale */
147 SOC_DOUBLE_TLV("Line Playback Volume",
148 ALC5632_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
149 /* bit 15 mutes left, bit 7 right */
150 SOC_DOUBLE("Line Playback Switch",
151 ALC5632_SPK_OUT_VOL, 15, 7, 1, 1),
152 SOC_DOUBLE_TLV("Headphone Playback Volume",
153 ALC5632_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
154 SOC_DOUBLE("Headphone Playback Switch",
155 ALC5632_HP_OUT_VOL, 15, 7, 1, 1),
156};
157
158static const struct snd_kcontrol_new alc5632_snd_controls[] = {
159 SOC_DOUBLE_TLV("Auxout Playback Volume",
160 ALC5632_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
161 SOC_DOUBLE("Auxout Playback Switch",
162 ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
163 SOC_SINGLE_TLV("Voice DAC Playback Volume",
164 ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
165 SOC_SINGLE_TLV("Phone Capture Volume",
166 ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
167 SOC_DOUBLE_TLV("LineIn Capture Volume",
168 ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
169 SOC_DOUBLE_TLV("Stereo DAC Playback Volume",
170 ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
171 SOC_DOUBLE("Stereo DAC Playback Switch",
172 ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
173 SOC_SINGLE_TLV("Mic1 Capture Volume",
174 ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
175 SOC_SINGLE_TLV("Mic2 Capture Volume",
176 ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
177 SOC_DOUBLE_TLV("Rec Capture Volume",
178 ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
179 SOC_SINGLE_TLV("Mic 1 Boost Volume",
180 ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv),
181 SOC_SINGLE_TLV("Mic 2 Boost Volume",
182 ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv),
183 SOC_SINGLE_TLV("Digital Boost Volume",
184 ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
185};
186
187/*
188 * DAPM Controls
189 */
190static const struct snd_kcontrol_new alc5632_hp_mixer_controls[] = {
191SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5632_LINE_IN_VOL, 15, 1, 1),
192SOC_DAPM_SINGLE("PHONE2HP Playback Switch", ALC5632_PHONE_IN_VOL, 15, 1, 1),
193SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 15, 1, 1),
194SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 11, 1, 1),
195SOC_DAPM_SINGLE("VOICE2HP Playback Switch", ALC5632_VOICE_DAC_VOL, 15, 1, 1),
196};
197
198static const struct snd_kcontrol_new alc5632_hpl_mixer_controls[] = {
199SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5632_ADC_REC_GAIN, 15, 1, 1),
200SOC_DAPM_SINGLE("DACL2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 3, 1, 1),
201};
202
203static const struct snd_kcontrol_new alc5632_hpr_mixer_controls[] = {
204SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5632_ADC_REC_GAIN, 7, 1, 1),
205SOC_DAPM_SINGLE("DACR2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 2, 1, 1),
206};
207
208static const struct snd_kcontrol_new alc5632_mono_mixer_controls[] = {
209SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5632_ADC_REC_GAIN, 14, 1, 1),
210SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5632_ADC_REC_GAIN, 6, 1, 1),
211SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5632_LINE_IN_VOL, 13, 1, 1),
212SOC_DAPM_SINGLE("MIC12MONO Playback Switch",
213 ALC5632_MIC_ROUTING_CTRL, 13, 1, 1),
214SOC_DAPM_SINGLE("MIC22MONO Playback Switch",
215 ALC5632_MIC_ROUTING_CTRL, 9, 1, 1),
216SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5632_MIC_ROUTING_CTRL, 0, 1, 1),
217SOC_DAPM_SINGLE("VOICE2MONO Playback Switch", ALC5632_VOICE_DAC_VOL, 13, 1, 1),
218};
219
220static const struct snd_kcontrol_new alc5632_speaker_mixer_controls[] = {
221SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5632_LINE_IN_VOL, 14, 1, 1),
222SOC_DAPM_SINGLE("PHONE2SPK Playback Switch", ALC5632_PHONE_IN_VOL, 14, 1, 1),
223SOC_DAPM_SINGLE("MIC12SPK Playback Switch",
224 ALC5632_MIC_ROUTING_CTRL, 14, 1, 1),
225SOC_DAPM_SINGLE("MIC22SPK Playback Switch",
226 ALC5632_MIC_ROUTING_CTRL, 10, 1, 1),
227SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5632_MIC_ROUTING_CTRL, 1, 1, 1),
228SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
229};
230
231/* Left Record Mixer */
232static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
233SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
234SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
235SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
236SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
237SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
238SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
239SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
240};
241
242/* Right Record Mixer */
243static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
244SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
245SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
246SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
247SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
248SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
249SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
250SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
251};
252
253static const char *alc5632_spk_n_sour_sel[] = {
254 "RN/-R", "RP/+R", "LN/-R", "Mute"};
255static const char *alc5632_hpl_out_input_sel[] = {
256 "Vmid", "HP Left Mix"};
257static const char *alc5632_hpr_out_input_sel[] = {
258 "Vmid", "HP Right Mix"};
259static const char *alc5632_spkout_input_sel[] = {
260 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
261static const char *alc5632_aux_out_input_sel[] = {
262 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
263
264/* auxout output mux */
265static const struct soc_enum alc5632_aux_out_input_enum =
266SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel);
267static const struct snd_kcontrol_new alc5632_auxout_mux_controls =
268SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum);
269
270/* speaker output mux */
271static const struct soc_enum alc5632_spkout_input_enum =
272SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel);
273static const struct snd_kcontrol_new alc5632_spkout_mux_controls =
274SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum);
275
276/* headphone left output mux */
277static const struct soc_enum alc5632_hpl_out_input_enum =
278SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel);
279static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls =
280SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum);
281
282/* headphone right output mux */
283static const struct soc_enum alc5632_hpr_out_input_enum =
284SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel);
285static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls =
286SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum);
287
288/* speaker output N select */
289static const struct soc_enum alc5632_spk_n_sour_enum =
290SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel);
291static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls =
292SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum);
293
294/* speaker amplifier */
295static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"};
296static const struct soc_enum alc5632_amp_enum =
297 SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names);
298static const struct snd_kcontrol_new alc5632_amp_mux_controls =
299 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
300
301
302static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
303/* Muxes */
304SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
305 &alc5632_auxout_mux_controls),
306SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
307 &alc5632_spkout_mux_controls),
308SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
309 &alc5632_hpl_out_mux_controls),
310SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
311 &alc5632_hpr_out_mux_controls),
312SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
313 &alc5632_spkoutn_mux_controls),
314
315/* output mixers */
316SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
317 &alc5632_hp_mixer_controls[0],
318 ARRAY_SIZE(alc5632_hp_mixer_controls)),
319SND_SOC_DAPM_MIXER("HPR Mix", ALC5632_PWR_MANAG_ADD2, 4, 0,
320 &alc5632_hpr_mixer_controls[0],
321 ARRAY_SIZE(alc5632_hpr_mixer_controls)),
322SND_SOC_DAPM_MIXER("HPL Mix", ALC5632_PWR_MANAG_ADD2, 5, 0,
323 &alc5632_hpl_mixer_controls[0],
324 ARRAY_SIZE(alc5632_hpl_mixer_controls)),
325SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
326SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
327 &alc5632_mono_mixer_controls[0],
328 ARRAY_SIZE(alc5632_mono_mixer_controls)),
329SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
330 &alc5632_speaker_mixer_controls[0],
331 ARRAY_SIZE(alc5632_speaker_mixer_controls)),
332
333/* input mixers */
334SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
335 &alc5632_captureL_mixer_controls[0],
336 ARRAY_SIZE(alc5632_captureL_mixer_controls)),
337SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
338 &alc5632_captureR_mixer_controls[0],
339 ARRAY_SIZE(alc5632_captureR_mixer_controls)),
340
341SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback",
342 ALC5632_PWR_MANAG_ADD2, 9, 0),
343SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback",
344 ALC5632_PWR_MANAG_ADD2, 8, 0),
345SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
346SND_SOC_DAPM_MIXER("DAC Right Channel",
347 ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
348SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
349SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
350SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
351SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture",
352 ALC5632_PWR_MANAG_ADD2, 7, 0),
353SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture",
354 ALC5632_PWR_MANAG_ADD2, 6, 0),
355SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
356SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
357SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
358SND_SOC_DAPM_PGA("Right Speaker", ALC5632_PWR_MANAG_ADD3, 12, 0, NULL, 0),
359SND_SOC_DAPM_PGA("Aux Out", ALC5632_PWR_MANAG_ADD3, 14, 0, NULL, 0),
360SND_SOC_DAPM_PGA("Left LineIn", ALC5632_PWR_MANAG_ADD3, 7, 0, NULL, 0),
361SND_SOC_DAPM_PGA("Right LineIn", ALC5632_PWR_MANAG_ADD3, 6, 0, NULL, 0),
362SND_SOC_DAPM_PGA("Phone", ALC5632_PWR_MANAG_ADD3, 5, 0, NULL, 0),
363SND_SOC_DAPM_PGA("Phone ADMix", ALC5632_PWR_MANAG_ADD3, 4, 0, NULL, 0),
364SND_SOC_DAPM_PGA("MIC1 PGA", ALC5632_PWR_MANAG_ADD3, 3, 0, NULL, 0),
365SND_SOC_DAPM_PGA("MIC2 PGA", ALC5632_PWR_MANAG_ADD3, 2, 0, NULL, 0),
366SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5632_PWR_MANAG_ADD3, 1, 0, NULL, 0),
367SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5632_PWR_MANAG_ADD3, 0, 0, NULL, 0),
368SND_SOC_DAPM_SUPPLY("Mic Bias1", ALC5632_PWR_MANAG_ADD1, 3, 0, NULL, 0),
369SND_SOC_DAPM_SUPPLY("Mic Bias2", ALC5632_PWR_MANAG_ADD1, 2, 0, NULL, 0),
370
371SND_SOC_DAPM_PGA_E("D Amp", ALC5632_PWR_MANAG_ADD2, 14, 0, NULL, 0,
372 amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
373SND_SOC_DAPM_PGA("AB Amp", ALC5632_PWR_MANAG_ADD2, 15, 0, NULL, 0),
374SND_SOC_DAPM_MUX("AB-D Amp Mux", ALC5632_PWR_MANAG_ADD1, 10, 0,
375 &alc5632_amp_mux_controls),
376
377SND_SOC_DAPM_OUTPUT("AUXOUT"),
378SND_SOC_DAPM_OUTPUT("HPL"),
379SND_SOC_DAPM_OUTPUT("HPR"),
380SND_SOC_DAPM_OUTPUT("SPKOUT"),
381SND_SOC_DAPM_OUTPUT("SPKOUTN"),
382SND_SOC_DAPM_INPUT("LINEINL"),
383SND_SOC_DAPM_INPUT("LINEINR"),
384SND_SOC_DAPM_INPUT("PHONEP"),
385SND_SOC_DAPM_INPUT("PHONEN"),
386SND_SOC_DAPM_INPUT("MIC1"),
387SND_SOC_DAPM_INPUT("MIC2"),
388SND_SOC_DAPM_VMID("Vmid"),
389};
390
391
392static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
393 /* virtual mixer - mixes left & right channels */
394 {"I2S Mix", NULL, "Left DAC"},
395 {"I2S Mix", NULL, "Right DAC"},
396 {"Line Mix", NULL, "Right LineIn"},
397 {"Line Mix", NULL, "Left LineIn"},
398 {"Phone Mix", NULL, "Phone"},
399 {"Phone Mix", NULL, "Phone ADMix"},
400 {"AUXOUT", NULL, "Aux Out"},
401
402 /* DAC */
403 {"DAC Right Channel", NULL, "I2S Mix"},
404 {"DAC Left Channel", NULL, "I2S Mix"},
405
406 /* HP mixer */
407 {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
408 {"HPL Mix", NULL, "HP Mix"},
409 {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
410 {"HPR Mix", NULL, "HP Mix"},
411 {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
412 {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},
413 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
414 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
415
416 {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},
417 {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},
418
419 /* speaker mixer */
420 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
421 {"Speaker Mix", "PHONE2SPK Playback Switch", "Phone Mix"},
422 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
423 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
424 {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},
425
426
427
428 /* mono mixer */
429 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
430 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
431 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
432 {"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"},
433 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
434 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
435 {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},
436
437 /* Left record mixer */
438 {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
439 {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"},
440 {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
441 {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
442 {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
443 {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
444 {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
445
446 /*Right record mixer */
447 {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
448 {"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"},
449 {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
450 {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
451 {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
452 {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
453 {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
454
455 /* headphone left mux */
456 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
457 {"Left Headphone Mux", "Vmid", "Vmid"},
458
459 /* headphone right mux */
460 {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
461 {"Right Headphone Mux", "Vmid", "Vmid"},
462
463 /* speaker out mux */
464 {"SpeakerOut Mux", "Vmid", "Vmid"},
465 {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
466 {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
467 {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
468
469 /* Mono/Aux Out mux */
470 {"AuxOut Mux", "Vmid", "Vmid"},
471 {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
472 {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
473 {"AuxOut Mux", "Mono Mix", "Mono Mix"},
474
475 /* output pga */
476 {"HPL", NULL, "Left Headphone"},
477 {"Left Headphone", NULL, "Left Headphone Mux"},
478 {"HPR", NULL, "Right Headphone"},
479 {"Right Headphone", NULL, "Right Headphone Mux"},
480 {"Aux Out", NULL, "AuxOut Mux"},
481
482 /* input pga */
483 {"Left LineIn", NULL, "LINEINL"},
484 {"Right LineIn", NULL, "LINEINR"},
485 {"Phone", NULL, "PHONEP"},
486 {"MIC1 Pre Amp", NULL, "MIC1"},
487 {"MIC2 Pre Amp", NULL, "MIC2"},
488 {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
489 {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
490
491 /* left ADC */
492 {"Left ADC", NULL, "Left Capture Mix"},
493
494 /* right ADC */
495 {"Right ADC", NULL, "Right Capture Mix"},
496
497 {"SpeakerOut N Mux", "RN/-R", "Left Speaker"},
498 {"SpeakerOut N Mux", "RP/+R", "Left Speaker"},
499 {"SpeakerOut N Mux", "LN/-R", "Left Speaker"},
500 {"SpeakerOut N Mux", "Mute", "Vmid"},
501
502 {"SpeakerOut N Mux", "RN/-R", "Right Speaker"},
503 {"SpeakerOut N Mux", "RP/+R", "Right Speaker"},
504 {"SpeakerOut N Mux", "LN/-R", "Right Speaker"},
505 {"SpeakerOut N Mux", "Mute", "Vmid"},
506
507 {"AB Amp", NULL, "SpeakerOut Mux"},
508 {"D Amp", NULL, "SpeakerOut Mux"},
509 {"AB-D Amp Mux", "AB Amp", "AB Amp"},
510 {"AB-D Amp Mux", "D Amp", "D Amp"},
511 {"Left Speaker", NULL, "AB-D Amp Mux"},
512 {"Right Speaker", NULL, "AB-D Amp Mux"},
513
514 {"SPKOUT", NULL, "Left Speaker"},
515 {"SPKOUT", NULL, "Right Speaker"},
516
517 {"SPKOUTN", NULL, "SpeakerOut N Mux"},
518
519};
520
521/* PLL divisors */
522struct _pll_div {
523 u32 pll_in;
524 u32 pll_out;
525 u16 regvalue;
526};
527
528/* Note : pll code from original alc5632 driver. Not sure of how good it is */
529/* usefull only for master mode */
530static const struct _pll_div codec_master_pll_div[] = {
531
532 { 2048000, 8192000, 0x0ea0},
533 { 3686400, 8192000, 0x4e27},
534 { 12000000, 8192000, 0x456b},
535 { 13000000, 8192000, 0x495f},
536 { 13100000, 8192000, 0x0320},
537 { 2048000, 11289600, 0xf637},
538 { 3686400, 11289600, 0x2f22},
539 { 12000000, 11289600, 0x3e2f},
540 { 13000000, 11289600, 0x4d5b},
541 { 13100000, 11289600, 0x363b},
542 { 2048000, 16384000, 0x1ea0},
543 { 3686400, 16384000, 0x9e27},
544 { 12000000, 16384000, 0x452b},
545 { 13000000, 16384000, 0x542f},
546 { 13100000, 16384000, 0x03a0},
547 { 2048000, 16934400, 0xe625},
548 { 3686400, 16934400, 0x9126},
549 { 12000000, 16934400, 0x4d2c},
550 { 13000000, 16934400, 0x742f},
551 { 13100000, 16934400, 0x3c27},
552 { 2048000, 22579200, 0x2aa0},
553 { 3686400, 22579200, 0x2f20},
554 { 12000000, 22579200, 0x7e2f},
555 { 13000000, 22579200, 0x742f},
556 { 13100000, 22579200, 0x3c27},
557 { 2048000, 24576000, 0x2ea0},
558 { 3686400, 24576000, 0xee27},
559 { 12000000, 24576000, 0x2915},
560 { 13000000, 24576000, 0x772e},
561 { 13100000, 24576000, 0x0d20},
562};
563
564/* FOUT = MCLK*(N+2)/((M+2)*(K+2))
565 N: bit 15:8 (div 2 .. div 257)
566 K: bit 6:4 typical 2
567 M: bit 3:0 (div 2 .. div 17)
568
569 same as for 5623 - thanks!
570*/
571
572static const struct _pll_div codec_slave_pll_div[] = {
573
574 { 1024000, 16384000, 0x3ea0},
575 { 1411200, 22579200, 0x3ea0},
576 { 1536000, 24576000, 0x3ea0},
577 { 2048000, 16384000, 0x1ea0},
578 { 2822400, 22579200, 0x1ea0},
579 { 3072000, 24576000, 0x1ea0},
580
581};
582
583static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
584 int source, unsigned int freq_in, unsigned int freq_out)
585{
586 int i;
587 struct snd_soc_codec *codec = codec_dai->codec;
588 int gbl_clk = 0, pll_div = 0;
589 u16 reg;
590
591 if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK)
592 return -EINVAL;
593
594 /* Disable PLL power */
595 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
596 ALC5632_PWR_ADD2_PLL1,
597 0);
598 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
599 ALC5632_PWR_ADD2_PLL2,
600 0);
601
602 /* pll is not used in slave mode */
603 reg = snd_soc_read(codec, ALC5632_DAI_CONTROL);
604 if (reg & ALC5632_DAI_SDP_SLAVE_MODE)
605 return 0;
606
607 if (!freq_in || !freq_out)
608 return 0;
609
610 switch (pll_id) {
611 case ALC5632_PLL_FR_MCLK:
612 for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
613 if (codec_master_pll_div[i].pll_in == freq_in
614 && codec_master_pll_div[i].pll_out == freq_out) {
615 /* PLL source from MCLK */
616 pll_div = codec_master_pll_div[i].regvalue;
617 break;
618 }
619 }
620 break;
621 case ALC5632_PLL_FR_BCLK:
622 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
623 if (codec_slave_pll_div[i].pll_in == freq_in
624 && codec_slave_pll_div[i].pll_out == freq_out) {
625 /* PLL source from Bitclk */
626 gbl_clk = ALC5632_PLL_FR_BCLK;
627 pll_div = codec_slave_pll_div[i].regvalue;
628 break;
629 }
630 }
631 break;
632 case ALC5632_PLL_FR_VBCLK:
633 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
634 if (codec_slave_pll_div[i].pll_in == freq_in
635 && codec_slave_pll_div[i].pll_out == freq_out) {
636 /* PLL source from voice clock */
637 gbl_clk = ALC5632_PLL_FR_VBCLK;
638 pll_div = codec_slave_pll_div[i].regvalue;
639 break;
640 }
641 }
642 break;
643 default:
644 return -EINVAL;
645 }
646
647 if (!pll_div)
648 return -EINVAL;
649
650 /* choose MCLK/BCLK/VBCLK */
651 snd_soc_write(codec, ALC5632_GPCR2, gbl_clk);
652 /* choose PLL1 clock rate */
653 snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div);
654 /* enable PLL1 */
655 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
656 ALC5632_PWR_ADD2_PLL1,
657 ALC5632_PWR_ADD2_PLL1);
658 /* enable PLL2 */
659 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
660 ALC5632_PWR_ADD2_PLL2,
661 ALC5632_PWR_ADD2_PLL2);
662 /* use PLL1 as main SYSCLK */
663 snd_soc_update_bits(codec, ALC5632_GPCR1,
664 ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,
665 ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);
666
667 return 0;
668}
669
670struct _coeff_div {
671 u16 fs;
672 u16 regvalue;
673};
674
675/* codec hifi mclk (after PLL) clock divider coefficients */
676/* values inspired from column BCLK=32Fs of Appendix A table */
677static const struct _coeff_div coeff_div[] = {
678 {512*1, 0x3075},
679};
680
681static int get_coeff(struct snd_soc_codec *codec, int rate)
682{
683 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
684 int i;
685
686 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
687 if (coeff_div[i].fs * rate == alc5632->sysclk)
688 return i;
689 }
690 return -EINVAL;
691}
692
693/*
694 * Clock after PLL and dividers
695 */
696static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
697 int clk_id, unsigned int freq, int dir)
698{
699 struct snd_soc_codec *codec = codec_dai->codec;
700 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
701
702 switch (freq) {
703 case 8192000:
704 case 11289600:
705 case 12288000:
706 case 16384000:
707 case 16934400:
708 case 18432000:
709 case 22579200:
710 case 24576000:
711 alc5632->sysclk = freq;
712 return 0;
713 }
714 return -EINVAL;
715}
716
717static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
718 unsigned int fmt)
719{
720 struct snd_soc_codec *codec = codec_dai->codec;
721 u16 iface = 0;
722
723 /* set master/slave audio interface */
724 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
725 case SND_SOC_DAIFMT_CBM_CFM:
726 iface = ALC5632_DAI_SDP_MASTER_MODE;
727 break;
728 case SND_SOC_DAIFMT_CBS_CFS:
729 iface = ALC5632_DAI_SDP_SLAVE_MODE;
730 break;
731 default:
732 return -EINVAL;
733 }
734
735 /* interface format */
736 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
737 case SND_SOC_DAIFMT_I2S:
738 iface |= ALC5632_DAI_I2S_DF_I2S;
739 break;
740 case SND_SOC_DAIFMT_LEFT_J:
741 iface |= ALC5632_DAI_I2S_DF_LEFT;
742 break;
743 case SND_SOC_DAIFMT_DSP_A:
744 iface |= ALC5632_DAI_I2S_DF_PCM_A;
745 break;
746 case SND_SOC_DAIFMT_DSP_B:
747 iface |= ALC5632_DAI_I2S_DF_PCM_B;
748 break;
749 default:
750 return -EINVAL;
751 }
752
753 /* clock inversion */
754 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
755 case SND_SOC_DAIFMT_NB_NF:
756 break;
757 case SND_SOC_DAIFMT_IB_IF:
758 iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
759 break;
760 case SND_SOC_DAIFMT_IB_NF:
761 iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
762 break;
763 case SND_SOC_DAIFMT_NB_IF:
764 break;
765 default:
766 return -EINVAL;
767 }
768
769 return snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
770}
771
772static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
773 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
774{
775 struct snd_soc_pcm_runtime *rtd = substream->private_data;
776 struct snd_soc_codec *codec = rtd->codec;
777 int coeff, rate;
778 u16 iface;
779
780 iface = snd_soc_read(codec, ALC5632_DAI_CONTROL);
781 iface &= ~ALC5632_DAI_I2S_DL_MASK;
782
783 /* bit size */
784 switch (params_format(params)) {
785 case SNDRV_PCM_FORMAT_S16_LE:
786 iface |= ALC5632_DAI_I2S_DL_16;
787 break;
788 case SNDRV_PCM_FORMAT_S20_3LE:
789 iface |= ALC5632_DAI_I2S_DL_20;
790 break;
791 case SNDRV_PCM_FORMAT_S24_LE:
792 iface |= ALC5632_DAI_I2S_DL_24;
793 break;
794 default:
795 return -EINVAL;
796 }
797
798 /* set iface & srate */
799 snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
800 rate = params_rate(params);
801 coeff = get_coeff(codec, rate);
802 if (coeff < 0)
803 return -EINVAL;
804
805 coeff = coeff_div[coeff].regvalue;
806 snd_soc_write(codec, ALC5632_DAC_CLK_CTRL1, coeff);
807
808 return 0;
809}
810
811static int alc5632_mute(struct snd_soc_dai *dai, int mute)
812{
813 struct snd_soc_codec *codec = dai->codec;
814 u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L \
815 |ALC5632_MISC_HP_DEPOP_MUTE_R;
816 u16 mute_reg = snd_soc_read(codec, ALC5632_MISC_CTRL) & ~hp_mute;
817
818 if (mute)
819 mute_reg |= hp_mute;
820
821 return snd_soc_write(codec, ALC5632_MISC_CTRL, mute_reg);
822}
823
824#define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)
825
826#define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD)
827
828#define ALC5632_ADD1_POWER_EN \
829 (ALC5632_PWR_ADD1_DAC_REF \
830 | ALC5632_PWR_ADD1_SOFTGEN_EN \
831 | ALC5632_PWR_ADD1_HP_OUT_AMP \
832 | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \
833 | ALC5632_PWR_ADD1_MAIN_BIAS)
834
835static void enable_power_depop(struct snd_soc_codec *codec)
836{
837 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
838 ALC5632_PWR_ADD1_SOFTGEN_EN,
839 ALC5632_PWR_ADD1_SOFTGEN_EN);
840
841 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
842 ALC5632_ADD3_POWER_EN,
843 ALC5632_ADD3_POWER_EN);
844
845 snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
846 ALC5632_MISC_HP_DEPOP_MODE2_EN,
847 ALC5632_MISC_HP_DEPOP_MODE2_EN);
848
849 /* "normal" mode: 0 @ 26 */
850 /* set all PR0-7 mixers to 0 */
851 snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
852 ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
853 0);
854
855 msleep(500);
856
857 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
858 ALC5632_ADD2_POWER_EN,
859 ALC5632_ADD2_POWER_EN);
860
861 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
862 ALC5632_ADD1_POWER_EN,
863 ALC5632_ADD1_POWER_EN);
864
865 /* disable HP Depop2 */
866 snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
867 ALC5632_MISC_HP_DEPOP_MODE2_EN,
868 0);
869
870}
871
872static int alc5632_set_bias_level(struct snd_soc_codec *codec,
873 enum snd_soc_bias_level level)
874{
875 switch (level) {
876 case SND_SOC_BIAS_ON:
877 enable_power_depop(codec);
878 break;
879 case SND_SOC_BIAS_PREPARE:
880 break;
881 case SND_SOC_BIAS_STANDBY:
882 /* everything off except vref/vmid, */
883 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
884 ALC5632_PWR_MANAG_ADD1_MASK,
885 ALC5632_PWR_ADD1_MAIN_BIAS);
886 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
887 ALC5632_PWR_MANAG_ADD2_MASK,
888 ALC5632_PWR_ADD2_VREF);
889 /* "normal" mode: 0 @ 26 */
890 snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
891 ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
892 0xffff ^ (ALC5632_PWR_VREF_PR3
893 | ALC5632_PWR_VREF_PR2));
894 break;
895 case SND_SOC_BIAS_OFF:
896 /* everything off, dac mute, inactive */
897 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
898 ALC5632_PWR_MANAG_ADD2_MASK, 0);
899 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
900 ALC5632_PWR_MANAG_ADD3_MASK, 0);
901 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
902 ALC5632_PWR_MANAG_ADD1_MASK, 0);
903 break;
904 }
905 codec->dapm.bias_level = level;
906 return 0;
907}
908
909#define ALC5632_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
910 | SNDRV_PCM_FMTBIT_S24_LE \
911 | SNDRV_PCM_FMTBIT_S32_LE)
912
913static struct snd_soc_dai_ops alc5632_dai_ops = {
914 .hw_params = alc5632_pcm_hw_params,
915 .digital_mute = alc5632_mute,
916 .set_fmt = alc5632_set_dai_fmt,
917 .set_sysclk = alc5632_set_dai_sysclk,
918 .set_pll = alc5632_set_dai_pll,
919};
920
921static struct snd_soc_dai_driver alc5632_dai = {
922 .name = "alc5632-hifi",
923 .playback = {
924 .stream_name = "HiFi Playback",
925 .channels_min = 1,
926 .channels_max = 2,
927 .rate_min = 8000,
928 .rate_max = 48000,
929 .rates = SNDRV_PCM_RATE_8000_48000,
930 .formats = ALC5632_FORMATS,},
931 .capture = {
932 .stream_name = "HiFi Capture",
933 .channels_min = 1,
934 .channels_max = 2,
935 .rate_min = 8000,
936 .rate_max = 48000,
937 .rates = SNDRV_PCM_RATE_8000_48000,
938 .formats = ALC5632_FORMATS,},
939
940 .ops = &alc5632_dai_ops,
941 .symmetric_rates = 1,
942};
943
944static int alc5632_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
945{
946 alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
947 return 0;
948}
949
950static int alc5632_resume(struct snd_soc_codec *codec)
951{
952 int ret;
953
954 /* mark cache as needed to sync */
955 codec->cache_sync = 1;
956
957 ret = snd_soc_cache_sync(codec);
958 if (ret != 0) {
959 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
960 return ret;
961 }
962
963 alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
964 return 0;
965}
966
967#define ALC5632_REC_UNMUTE (ALC5632_ADC_REC_MIC2 \
968 | ALC5632_ADC_REC_LINE_IN | ALC5632_ADC_REC_AUX \
969 | ALC5632_ADC_REC_HP | ALC5632_ADC_REC_SPK \
970 | ALC5632_ADC_REC_MONOMIX)
971
972#define ALC5632_MIC_ROUTE (ALC5632_MIC_ROUTE_HP \
973 | ALC5632_MIC_ROUTE_SPK \
974 | ALC5632_MIC_ROUTE_MONOMIX)
975
976#define ALC5632_PWR_DEFAULT (ALC5632_PWR_ADC_STATUS \
977 | ALC5632_PWR_DAC_STATUS \
978 | ALC5632_PWR_AMIX_STATUS \
979 | ALC5632_PWR_VREF_STATUS)
980
981#define ALC5632_ADC_REC_GAIN_COMP(x) (int)((x - ALC5632_ADC_REC_GAIN_BASE) \
982 / ALC5632_ADC_REC_GAIN_STEP)
983
984#define ALC5632_MIC_BOOST_COMP(x) (int)(x / ALC5632_MIC_BOOST_STEP)
985
986#define ALC5632_SPK_OUT_VOL_COMP(x) (int)(x / ALC5632_SPK_OUT_VOL_STEP)
987
988static int alc5632_probe(struct snd_soc_codec *codec)
989{
990 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
991 int ret;
992
993 ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5632->control_type);
994 if (ret < 0) {
995 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
996 return ret;
997 }
998
999 alc5632_reset(codec);
1000
1001 /* power on device */
1002 alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1003
1004 switch (alc5632->id) {
1005 case 0x5c:
1006 snd_soc_add_controls(codec, alc5632_vol_snd_controls,
1007 ARRAY_SIZE(alc5632_vol_snd_controls));
1008 break;
1009 default:
1010 return -EINVAL;
1011 }
1012
1013 return ret;
1014}
1015
1016/* power down chip */
1017static int alc5632_remove(struct snd_soc_codec *codec)
1018{
1019 alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
1020 return 0;
1021}
1022
1023static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
1024 .probe = alc5632_probe,
1025 .remove = alc5632_remove,
1026 .suspend = alc5632_suspend,
1027 .resume = alc5632_resume,
1028 .set_bias_level = alc5632_set_bias_level,
1029 .reg_word_size = sizeof(u16),
1030 .reg_cache_step = 2,
1031 .reg_cache_default = alc5632_reg_defaults,
1032 .reg_cache_size = ARRAY_SIZE(alc5632_reg_defaults),
1033 .volatile_register = alc5632_volatile_register,
1034 .controls = alc5632_snd_controls,
1035 .num_controls = ARRAY_SIZE(alc5632_snd_controls),
1036 .dapm_widgets = alc5632_dapm_widgets,
1037 .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets),
1038 .dapm_routes = alc5632_dapm_routes,
1039 .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
1040};
1041
1042/*
1043 * alc5632 2 wire address is determined by A1 pin
1044 * state during powerup.
1045 * low = 0x1a
1046 * high = 0x1b
1047 */
1048static int alc5632_i2c_probe(struct i2c_client *client,
1049 const struct i2c_device_id *id)
1050{
1051 struct alc5632_priv *alc5632;
1052 int ret, vid1, vid2;
1053
1054 vid1 = i2c_smbus_read_word_data(client, ALC5632_VENDOR_ID1);
1055 if (vid1 < 0) {
1056 dev_err(&client->dev, "failed to read I2C\n");
1057 return -EIO;
1058 } else {
1059 dev_info(&client->dev, "got vid1: %x\n", vid1);
1060 }
1061 vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
1062
1063 vid2 = i2c_smbus_read_word_data(client, ALC5632_VENDOR_ID2);
1064 if (vid2 < 0) {
1065 dev_err(&client->dev, "failed to read I2C\n");
1066 return -EIO;
1067 } else {
1068 dev_info(&client->dev, "got vid2: %x\n", vid2);
1069 }
1070 vid2 = (vid2 & 0xff);
1071
1072 if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
1073 dev_err(&client->dev, "unknown or wrong codec\n");
1074 dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n",
1075 0x10ec, id->driver_data,
1076 vid1, vid2);
1077 return -ENODEV;
1078 }
1079
1080 alc5632 = devm_kzalloc(&client->dev,
1081 sizeof(struct alc5632_priv), GFP_KERNEL);
1082 if (alc5632 == NULL)
1083 return -ENOMEM;
1084
1085 alc5632->id = vid2;
1086 switch (alc5632->id) {
1087 case 0x5c:
1088 alc5632_dai.name = "alc5632-hifi";
1089 break;
1090 default:
1091 return -EINVAL;
1092 }
1093
1094 i2c_set_clientdata(client, alc5632);
1095 alc5632->control_data = client;
1096 alc5632->control_type = SND_SOC_I2C;
1097 mutex_init(&alc5632->mutex);
1098
1099 ret = snd_soc_register_codec(&client->dev,
1100 &soc_codec_device_alc5632, &alc5632_dai, 1);
1101 if (ret != 0)
1102 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1103
1104 return ret;
1105}
1106
1107static int alc5632_i2c_remove(struct i2c_client *client)
1108{
1109 snd_soc_unregister_codec(&client->dev);
1110
1111 return 0;
1112}
1113
1114static const struct i2c_device_id alc5632_i2c_table[] = {
1115 {"alc5632", 0x5c},
1116 {}
1117};
1118MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);
1119
1120/* i2c codec control layer */
1121static struct i2c_driver alc5632_i2c_driver = {
1122 .driver = {
1123 .name = "alc5632",
1124 .owner = THIS_MODULE,
1125 },
1126 .probe = alc5632_i2c_probe,
1127 .remove = __devexit_p(alc5632_i2c_remove),
1128 .id_table = alc5632_i2c_table,
1129};
1130
1131static int __init alc5632_modinit(void)
1132{
1133 int ret;
1134
1135 ret = i2c_add_driver(&alc5632_i2c_driver);
1136 if (ret != 0) {
1137 printk(KERN_ERR "%s: can't add i2c driver", __func__);
1138 return ret;
1139 }
1140
1141 return ret;
1142}
1143module_init(alc5632_modinit);
1144
1145static void __exit alc5632_modexit(void)
1146{
1147 i2c_del_driver(&alc5632_i2c_driver);
1148}
1149module_exit(alc5632_modexit);
1150
1151MODULE_DESCRIPTION("ASoC ALC5632 driver");
1152MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
1153MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h
new file mode 100644
index 000000000000..ff4c0fd0d2ec
--- /dev/null
+++ b/sound/soc/codecs/alc5632.h
@@ -0,0 +1,249 @@
1/*
2* alc5632.h -- ALC5632 ALSA SoC Audio Codec
3*
4* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5*
6* Authors: Leon Romanovsky <leon@leon.nu>
7* Andrey Danin <danindrey@mail.ru>
8* Ilya Petrov <ilya.muromec@gmail.com>
9* Marc Dietrich <marvin24@gmx.de>
10*
11* Based on alc5623.h by Arnaud Patard
12*
13* This program is free software; you can redistribute it and/or modify
14* it under the terms of the GNU General Public License version 2 as
15* published by the Free Software Foundation.
16*/
17
18#ifndef _ALC5632_H
19#define _ALC5632_H
20
21#define ALC5632_RESET 0x00
22/* speaker output vol 2 2 */
23/* line output vol 4 2 */
24/* HP output vol 4 0 4 */
25#define ALC5632_SPK_OUT_VOL 0x02 /* spe out vol */
26#define ALC5632_SPK_OUT_VOL_STEP 1.5
27#define ALC5632_HP_OUT_VOL 0x04 /* hp out vol */
28#define ALC5632_AUX_OUT_VOL 0x06 /* aux out vol */
29#define ALC5632_PHONE_IN_VOL 0x08 /* phone in vol */
30#define ALC5632_LINE_IN_VOL 0x0A /* line in vol */
31#define ALC5632_STEREO_DAC_IN_VOL 0x0C /* stereo dac in vol */
32#define ALC5632_MIC_VOL 0x0E /* mic in vol */
33/* stero dac/mic routing */
34#define ALC5632_MIC_ROUTING_CTRL 0x10
35#define ALC5632_MIC_ROUTE_MONOMIX (1 << 0)
36#define ALC5632_MIC_ROUTE_SPK (1 << 1)
37#define ALC5632_MIC_ROUTE_HP (1 << 2)
38
39#define ALC5632_ADC_REC_GAIN 0x12 /* rec gain */
40#define ALC5632_ADC_REC_GAIN_RANGE 0x1F1F
41#define ALC5632_ADC_REC_GAIN_BASE (-16.5)
42#define ALC5632_ADC_REC_GAIN_STEP 1.5
43
44#define ALC5632_ADC_REC_MIXER 0x14 /* mixer control */
45#define ALC5632_ADC_REC_MIC1 (1 << 6)
46#define ALC5632_ADC_REC_MIC2 (1 << 5)
47#define ALC5632_ADC_REC_LINE_IN (1 << 4)
48#define ALC5632_ADC_REC_AUX (1 << 3)
49#define ALC5632_ADC_REC_HP (1 << 2)
50#define ALC5632_ADC_REC_SPK (1 << 1)
51#define ALC5632_ADC_REC_MONOMIX (1 << 0)
52
53#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */
54/* ALC5632_OUTPUT_MIXER_CTRL : */
55/* same remark as for reg 2 line vs speaker */
56#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */
57#define ALC5632_OUTPUT_MIXER_RP (1 << 14)
58#define ALC5632_OUTPUT_MIXER_WEEK (1 << 12)
59#define ALC5632_OUTPUT_MIXER_HP (1 << 10)
60#define ALC5632_OUTPUT_MIXER_AUX_SPK (2 << 6)
61#define ALC5632_OUTPUT_MIXER_AUX_HP_LR (1 << 6)
62#define ALC5632_OUTPUT_MIXER_HP_R (1 << 8)
63#define ALC5632_OUTPUT_MIXER_HP_L (1 << 9)
64
65#define ALC5632_MIC_CTRL 0x22 /* mic phone ctrl */
66#define ALC5632_MIC_BOOST_BYPASS 0
67#define ALC5632_MIC_BOOST_20DB 1
68#define ALC5632_MIC_BOOST_30DB 2
69#define ALC5632_MIC_BOOST_40DB 3
70
71#define ALC5632_DIGI_BOOST_CTRL 0x24 /* digi mic / bost ctl */
72#define ALC5632_MIC_BOOST_RANGE 7
73#define ALC5632_MIC_BOOST_STEP 6
74#define ALC5632_PWR_DOWN_CTRL_STATUS 0x26
75#define ALC5632_PWR_DOWN_CTRL_STATUS_MASK 0xEF00
76#define ALC5632_PWR_VREF_PR3 (1 << 11)
77#define ALC5632_PWR_VREF_PR2 (1 << 10)
78#define ALC5632_PWR_VREF_STATUS (1 << 3)
79#define ALC5632_PWR_AMIX_STATUS (1 << 2)
80#define ALC5632_PWR_DAC_STATUS (1 << 1)
81#define ALC5632_PWR_ADC_STATUS (1 << 0)
82/* stereo/voice DAC / stereo adc func ctrl */
83#define ALC5632_DAC_FUNC_SELECT 0x2E
84
85/* Main serial data port ctrl (i2s) */
86#define ALC5632_DAI_CONTROL 0x34
87
88#define ALC5632_DAI_SDP_MASTER_MODE (0 << 15)
89#define ALC5632_DAI_SDP_SLAVE_MODE (1 << 15)
90#define ALC5632_DAI_SADLRCK_MODE (1 << 14)
91/* 0:voice, 1:main */
92#define ALC5632_DAI_MAIN_I2S_SYSCLK_SEL (1 << 8)
93#define ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7)
94/* 0:normal, 1:invert */
95#define ALC5632_DAI_MAIN_I2S_LRCK_INV (1 << 6)
96#define ALC5632_DAI_I2S_DL_MASK (3 << 2)
97#define ALC5632_DAI_I2S_DL_8 (3 << 2)
98#define ALC5632_DAI_I2S_DL_24 (2 << 2)
99#define ALC5632_DAI_I2S_DL_20 (1 << 2)
100#define ALC5632_DAI_I2S_DL_16 (0 << 2)
101#define ALC5632_DAI_I2S_DF_MASK (3 << 0)
102#define ALC5632_DAI_I2S_DF_PCM_B (3 << 0)
103#define ALC5632_DAI_I2S_DF_PCM_A (2 << 0)
104#define ALC5632_DAI_I2S_DF_LEFT (1 << 0)
105#define ALC5632_DAI_I2S_DF_I2S (0 << 0)
106/* extend serial data port control (VoDAC_i2c/pcm) */
107#define ALC5632_DAI_CONTROL2 0x36
108/* 0:gpio func, 1:voice pcm */
109#define ALC5632_DAI_VOICE_PCM_ENABLE (1 << 15)
110/* 0:master, 1:slave */
111#define ALC5632_DAI_VOICE_MODE_SEL (1 << 14)
112/* 0:disable, 1:enable */
113#define ALC5632_DAI_HPF_CLK_CTRL (1 << 13)
114/* 0:main, 1:voice */
115#define ALC5632_DAI_VOICE_I2S_SYSCLK_SEL (1 << 8)
116/* 0:normal, 1:invert */
117#define ALC5632_DAI_VOICE_VBCLK_SYSCLK_SEL (1 << 7)
118/* 0:normal, 1:invert */
119#define ALC5632_DAI_VOICE_I2S_LR_INV (1 << 6)
120#define ALC5632_DAI_VOICE_DL_MASK (3 << 2)
121#define ALC5632_DAI_VOICE_DL_16 (0 << 2)
122#define ALC5632_DAI_VOICE_DL_20 (1 << 2)
123#define ALC5632_DAI_VOICE_DL_24 (2 << 2)
124#define ALC5632_DAI_VOICE_DL_8 (3 << 2)
125#define ALC5632_DAI_VOICE_DF_MASK (3 << 0)
126#define ALC5632_DAI_VOICE_DF_I2S (0 << 0)
127#define ALC5632_DAI_VOICE_DF_LEFT (1 << 0)
128#define ALC5632_DAI_VOICE_DF_PCM_A (2 << 0)
129#define ALC5632_DAI_VOICE_DF_PCM_B (3 << 0)
130
131#define ALC5632_PWR_MANAG_ADD1 0x3A
132#define ALC5632_PWR_MANAG_ADD1_MASK 0xEFFF
133#define ALC5632_PWR_ADD1_DAC_L_EN (1 << 15)
134#define ALC5632_PWR_ADD1_DAC_R_EN (1 << 14)
135#define ALC5632_PWR_ADD1_ZERO_CROSS (1 << 13)
136#define ALC5632_PWR_ADD1_MAIN_I2S_EN (1 << 11)
137#define ALC5632_PWR_ADD1_SPK_AMP_EN (1 << 10)
138#define ALC5632_PWR_ADD1_HP_OUT_AMP (1 << 9)
139#define ALC5632_PWR_ADD1_HP_OUT_ENH_AMP (1 << 8)
140#define ALC5632_PWR_ADD1_VOICE_DAC_MIX (1 << 7)
141#define ALC5632_PWR_ADD1_SOFTGEN_EN (1 << 6)
142#define ALC5632_PWR_ADD1_MIC1_SHORT_CURR (1 << 5)
143#define ALC5632_PWR_ADD1_MIC2_SHORT_CURR (1 << 4)
144#define ALC5632_PWR_ADD1_MIC1_EN (1 << 3)
145#define ALC5632_PWR_ADD1_MIC2_EN (1 << 2)
146#define ALC5632_PWR_ADD1_MAIN_BIAS (1 << 1)
147#define ALC5632_PWR_ADD1_DAC_REF (1 << 0)
148
149#define ALC5632_PWR_MANAG_ADD2 0x3C
150#define ALC5632_PWR_MANAG_ADD2_MASK 0x7FFF
151#define ALC5632_PWR_ADD2_PLL1 (1 << 15)
152#define ALC5632_PWR_ADD2_PLL2 (1 << 14)
153#define ALC5632_PWR_ADD2_VREF (1 << 13)
154#define ALC5632_PWR_ADD2_OVT_DET (1 << 12)
155#define ALC5632_PWR_ADD2_VOICE_DAC (1 << 10)
156#define ALC5632_PWR_ADD2_L_DAC_CLK (1 << 9)
157#define ALC5632_PWR_ADD2_R_DAC_CLK (1 << 8)
158#define ALC5632_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7)
159#define ALC5632_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6)
160#define ALC5632_PWR_ADD2_L_HP_MIXER (1 << 5)
161#define ALC5632_PWR_ADD2_R_HP_MIXER (1 << 4)
162#define ALC5632_PWR_ADD2_SPK_MIXER (1 << 3)
163#define ALC5632_PWR_ADD2_MONO_MIXER (1 << 2)
164#define ALC5632_PWR_ADD2_L_ADC_REC_MIXER (1 << 1)
165#define ALC5632_PWR_ADD2_R_ADC_REC_MIXER (1 << 0)
166
167#define ALC5632_PWR_MANAG_ADD3 0x3E
168#define ALC5632_PWR_MANAG_ADD3_MASK 0x7CFF
169#define ALC5632_PWR_ADD3_AUXOUT_VOL (1 << 14)
170#define ALC5632_PWR_ADD3_SPK_L_OUT (1 << 13)
171#define ALC5632_PWR_ADD3_SPK_R_OUT (1 << 12)
172#define ALC5632_PWR_ADD3_HP_L_OUT_VOL (1 << 11)
173#define ALC5632_PWR_ADD3_HP_R_OUT_VOL (1 << 10)
174#define ALC5632_PWR_ADD3_LINEIN_L_VOL (1 << 7)
175#define ALC5632_PWR_ADD3_LINEIN_R_VOL (1 << 6)
176#define ALC5632_PWR_ADD3_AUXIN_VOL (1 << 5)
177#define ALC5632_PWR_ADD3_AUXIN_MIX (1 << 4)
178#define ALC5632_PWR_ADD3_MIC1_VOL (1 << 3)
179#define ALC5632_PWR_ADD3_MIC2_VOL (1 << 2)
180#define ALC5632_PWR_ADD3_MIC1_BOOST_AD (1 << 1)
181#define ALC5632_PWR_ADD3_MIC2_BOOST_AD (1 << 0)
182
183#define ALC5632_GPCR1 0x40
184#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1 (1 << 15)
185#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_MCLK (0 << 15)
186#define ALC5632_GPCR1_DAC_HI_FLT_EN (1 << 10)
187#define ALC5632_GPCR1_SPK_AMP_CTRL (7 << 1)
188#define ALC5632_GPCR1_VDD_100 (5 << 1)
189#define ALC5632_GPCR1_VDD_125 (4 << 1)
190#define ALC5632_GPCR1_VDD_150 (3 << 1)
191#define ALC5632_GPCR1_VDD_175 (2 << 1)
192#define ALC5632_GPCR1_VDD_200 (1 << 1)
193#define ALC5632_GPCR1_VDD_225 (0 << 1)
194
195#define ALC5632_GPCR2 0x42
196#define ALC5632_GPCR2_PLL1_SOUR_SEL (3 << 12)
197#define ALC5632_PLL_FR_MCLK (0 << 12)
198#define ALC5632_PLL_FR_BCLK (2 << 12)
199#define ALC5632_PLL_FR_VBCLK (3 << 12)
200#define ALC5632_GPCR2_CLK_PLL_PRE_DIV1 (0 << 0)
201
202#define ALC5632_PLL1_CTRL 0x44
203#define ALC5632_PLL1_CTRL_N_VAL(n) (((n) & 0x0f) << 8)
204#define ALC5632_PLL1_M_BYPASS (1 << 7)
205#define ALC5632_PLL1_CTRL_K_VAL(k) (((k) & 0x07) << 4)
206#define ALC5632_PLL1_CTRL_M_VAL(m) (((m) & 0x0f) << 0)
207
208#define ALC5632_PLL2_CTRL 0x46
209#define ALC5632_PLL2_EN (1 << 15)
210#define ALC5632_PLL2_RATIO (0 << 15)
211
212#define ALC5632_GPIO_PIN_CONFIG 0x4C
213#define ALC5632_GPIO_PIN_POLARITY 0x4E
214#define ALC5632_GPIO_PIN_STICKY 0x50
215#define ALC5632_GPIO_PIN_WAKEUP 0x52
216#define ALC5632_GPIO_PIN_STATUS 0x54
217#define ALC5632_GPIO_PIN_SHARING 0x56
218#define ALC5632_OVER_CURR_STATUS 0x58
219#define ALC5632_SOFTVOL_CTRL 0x5A
220#define ALC5632_GPIO_OUPUT_PIN_CTRL 0x5C
221
222#define ALC5632_MISC_CTRL 0x5E
223#define ALC5632_MISC_DISABLE_FAST_VREG (1 << 15)
224#define ALC5632_MISC_AVC_TRGT_SEL (3 << 12)
225#define ALC5632_MISC_AVC_TRGT_RIGHT (1 << 12)
226#define ALC5632_MISC_AVC_TRGT_LEFT (2 << 12)
227#define ALC5632_MISC_AVC_TRGT_BOTH (3 << 12)
228#define ALC5632_MISC_HP_DEPOP_MODE1_EN (1 << 9)
229#define ALC5632_MISC_HP_DEPOP_MODE2_EN (1 << 8)
230#define ALC5632_MISC_HP_DEPOP_MUTE_L (1 << 7)
231#define ALC5632_MISC_HP_DEPOP_MUTE_R (1 << 6)
232#define ALC5632_MISC_HP_DEPOP_MUTE (1 << 5)
233#define ALC5632_MISC_GPIO_WAKEUP_CTRL (1 << 1)
234#define ALC5632_MISC_IRQOUT_INV_CTRL (1 << 0)
235
236#define ALC5632_DAC_CLK_CTRL1 0x60
237#define ALC5632_DAC_CLK_CTRL2 0x62
238#define ALC5632_DAC_CLK_CTRL2_DIV1_2 (1 << 0)
239#define ALC5632_VOICE_DAC_PCM_CLK_CTRL1 0x64
240#define ALC5632_PSEUDO_SPATIAL_CTRL 0x68
241#define ALC5632_HID_CTRL_INDEX 0x6A
242#define ALC5632_HID_CTRL_DATA 0x6C
243#define ALC5632_EQ_CTRL 0x6E
244
245/* undocumented */
246#define ALC5632_VENDOR_ID1 0x7C
247#define ALC5632_VENDOR_ID2 0x7E
248
249#endif