diff options
author | Brian Austin <brian.austin@cirrus.com> | 2012-04-27 16:45:52 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-04-30 18:36:20 -0400 |
commit | dfe0f98b8d2e114ae25f06f2a4384a2f886818b4 (patch) | |
tree | c1c2382952eb1f93f290c44a777a937ee40fc5e2 | |
parent | cd0f8911c5d0cc04763f87cf118c66b867e2e6d2 (diff) |
ASoC: Add support for CS42L52 Codec
This patch adds support for Cirrus Logic CS42L52 Low Power Stereo Codec
Signed-off-by: Brian Austin <brian.austin@cirrus.com>
Signed-off-by: Georgi Vlaev <joe@nucleusys.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | include/sound/cs42l52.h | 36 | ||||
-rw-r--r-- | sound/soc/codecs/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/codecs/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l52.c | 1302 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l52.h | 274 |
5 files changed, 1618 insertions, 0 deletions
diff --git a/include/sound/cs42l52.h b/include/sound/cs42l52.h new file mode 100644 index 000000000000..4c68955f7330 --- /dev/null +++ b/include/sound/cs42l52.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * linux/sound/cs42l52.h -- Platform data for CS42L52 | ||
3 | * | ||
4 | * Copyright (c) 2012 Cirrus Logic Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __CS42L52_H | ||
12 | #define __CS42L52_H | ||
13 | |||
14 | struct cs42l52_platform_data { | ||
15 | |||
16 | /* MICBIAS Level. Check datasheet Pg48 */ | ||
17 | unsigned int micbias_lvl; | ||
18 | |||
19 | /* MICA mode selection 0=Single 1=Differential */ | ||
20 | unsigned int mica_cfg; | ||
21 | |||
22 | /* MICB mode selection 0=Single 1=Differential */ | ||
23 | unsigned int micb_cfg; | ||
24 | |||
25 | /* MICA Select 0=MIC1A 1=MIC2A */ | ||
26 | unsigned int mica_sel; | ||
27 | |||
28 | /* MICB Select 0=MIC2A 1=MIC2B */ | ||
29 | unsigned int micb_sel; | ||
30 | |||
31 | /* Charge Pump Freq. Check datasheet Pg73 */ | ||
32 | unsigned int chgfreq; | ||
33 | |||
34 | }; | ||
35 | |||
36 | #endif /* __CS42L52_H */ | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 2e51eb08b303..0235532a94ed 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -29,6 +29,7 @@ config SND_SOC_ALL_CODECS | |||
29 | select SND_SOC_ALC5632 if I2C | 29 | select SND_SOC_ALC5632 if I2C |
30 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC | 30 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC |
31 | select SND_SOC_CS42L51 if I2C | 31 | select SND_SOC_CS42L51 if I2C |
32 | select SND_SOC_CS42L52 if I2C | ||
32 | select SND_SOC_CS42L73 if I2C | 33 | select SND_SOC_CS42L73 if I2C |
33 | select SND_SOC_CS4270 if I2C | 34 | select SND_SOC_CS4270 if I2C |
34 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI | 35 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI |
@@ -183,6 +184,9 @@ config SND_SOC_CQ0093VC | |||
183 | config SND_SOC_CS42L51 | 184 | config SND_SOC_CS42L51 |
184 | tristate | 185 | tristate |
185 | 186 | ||
187 | config SND_SOC_CS42L52 | ||
188 | tristate | ||
189 | |||
186 | config SND_SOC_CS42L73 | 190 | config SND_SOC_CS42L73 |
187 | tristate | 191 | tristate |
188 | 192 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index db61c4499715..d11ab901b075 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -15,6 +15,7 @@ snd-soc-ak4642-objs := ak4642.o | |||
15 | snd-soc-ak4671-objs := ak4671.o | 15 | snd-soc-ak4671-objs := ak4671.o |
16 | snd-soc-cq93vc-objs := cq93vc.o | 16 | snd-soc-cq93vc-objs := cq93vc.o |
17 | snd-soc-cs42l51-objs := cs42l51.o | 17 | snd-soc-cs42l51-objs := cs42l51.o |
18 | snd-soc-cs42l52-objs := cs42l52.o | ||
18 | snd-soc-cs42l73-objs := cs42l73.o | 19 | snd-soc-cs42l73-objs := cs42l73.o |
19 | snd-soc-cs4270-objs := cs4270.o | 20 | snd-soc-cs4270-objs := cs4270.o |
20 | snd-soc-cs4271-objs := cs4271.o | 21 | snd-soc-cs4271-objs := cs4271.o |
@@ -123,6 +124,7 @@ obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o | |||
123 | obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o | 124 | obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o |
124 | obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o | 125 | obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o |
125 | obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o | 126 | obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o |
127 | obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o | ||
126 | obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o | 128 | obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o |
127 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o | 129 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o |
128 | obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o | 130 | obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c new file mode 100644 index 000000000000..e7fefbd26008 --- /dev/null +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -0,0 +1,1302 @@ | |||
1 | /* | ||
2 | * cs42l52.c -- CS42L52 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2012 CirrusLogic, Inc. | ||
5 | * | ||
6 | * Author: Georgi Vlaev <joe@nucleusys.com> | ||
7 | * Author: Brian Austin <brian.austin@cirrus.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/version.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/pm.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/regmap.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/workqueue.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <sound/core.h> | ||
30 | #include <sound/pcm.h> | ||
31 | #include <sound/pcm_params.h> | ||
32 | #include <sound/soc.h> | ||
33 | #include <sound/soc-dapm.h> | ||
34 | #include <sound/initval.h> | ||
35 | #include <sound/tlv.h> | ||
36 | #include <sound/cs42l52.h> | ||
37 | #include "cs42l52.h" | ||
38 | |||
39 | struct sp_config { | ||
40 | u8 spc, format, spfs; | ||
41 | u32 srate; | ||
42 | }; | ||
43 | |||
44 | struct cs42l52_private { | ||
45 | struct regmap *regmap; | ||
46 | struct snd_soc_codec *codec; | ||
47 | struct device *dev; | ||
48 | struct sp_config config; | ||
49 | struct cs42l52_platform_data pdata; | ||
50 | u32 sysclk; | ||
51 | u8 mclksel; | ||
52 | u32 mclk; | ||
53 | u8 flags; | ||
54 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
55 | struct input_dev *beep; | ||
56 | struct work_struct beep_work; | ||
57 | int beep_rate; | ||
58 | #endif | ||
59 | }; | ||
60 | |||
61 | static const struct reg_default cs42l52_reg_defaults[] = { | ||
62 | { CS42L52_PWRCTL1, 0x9F }, /* r02 PWRCTL 1 */ | ||
63 | { CS42L52_PWRCTL2, 0x07 }, /* r03 PWRCTL 2 */ | ||
64 | { CS42L52_PWRCTL3, 0xFF }, /* r04 PWRCTL 3 */ | ||
65 | { CS42L52_CLK_CTL, 0xA0 }, /* r05 Clocking Ctl */ | ||
66 | { CS42L52_IFACE_CTL1, 0x00 }, /* r06 Interface Ctl 1 */ | ||
67 | { CS42L52_ADC_PGA_A, 0x80 }, /* r08 Input A Select */ | ||
68 | { CS42L52_ADC_PGA_B, 0x80 }, /* r09 Input B Select */ | ||
69 | { CS42L52_ANALOG_HPF_CTL, 0xA5 }, /* r0A Analog HPF Ctl */ | ||
70 | { CS42L52_ADC_HPF_FREQ, 0x00 }, /* r0B ADC HPF Corner Freq */ | ||
71 | { CS42L52_ADC_MISC_CTL, 0x00 }, /* r0C Misc. ADC Ctl */ | ||
72 | { CS42L52_PB_CTL1, 0x60 }, /* r0D Playback Ctl 1 */ | ||
73 | { CS42L52_MISC_CTL, 0x02 }, /* r0E Misc. Ctl */ | ||
74 | { CS42L52_PB_CTL2, 0x00 }, /* r0F Playback Ctl 2 */ | ||
75 | { CS42L52_MICA_CTL, 0x00 }, /* r10 MICA Amp Ctl */ | ||
76 | { CS42L52_MICB_CTL, 0x00 }, /* r11 MICB Amp Ctl */ | ||
77 | { CS42L52_PGAA_CTL, 0x00 }, /* r12 PGAA Vol, Misc. */ | ||
78 | { CS42L52_PGAB_CTL, 0x00 }, /* r13 PGAB Vol, Misc. */ | ||
79 | { CS42L52_PASSTHRUA_VOL, 0x00 }, /* r14 Bypass A Vol */ | ||
80 | { CS42L52_PASSTHRUB_VOL, 0x00 }, /* r15 Bypass B Vol */ | ||
81 | { CS42L52_ADCA_VOL, 0x00 }, /* r16 ADCA Volume */ | ||
82 | { CS42L52_ADCB_VOL, 0x00 }, /* r17 ADCB Volume */ | ||
83 | { CS42L52_ADCA_MIXER_VOL, 0x80 }, /* r18 ADCA Mixer Volume */ | ||
84 | { CS42L52_ADCB_MIXER_VOL, 0x80 }, /* r19 ADCB Mixer Volume */ | ||
85 | { CS42L52_PCMA_MIXER_VOL, 0x00 }, /* r1A PCMA Mixer Volume */ | ||
86 | { CS42L52_PCMB_MIXER_VOL, 0x00 }, /* r1B PCMB Mixer Volume */ | ||
87 | { CS42L52_BEEP_FREQ, 0x00 }, /* r1C Beep Freq on Time */ | ||
88 | { CS42L52_BEEP_VOL, 0x00 }, /* r1D Beep Volume off Time */ | ||
89 | { CS42L52_BEEP_TONE_CTL, 0x00 }, /* r1E Beep Tone Cfg. */ | ||
90 | { CS42L52_TONE_CTL, 0x00 }, /* r1F Tone Ctl */ | ||
91 | { CS42L52_MASTERA_VOL, 0x88 }, /* r20 Master A Volume */ | ||
92 | { CS42L52_MASTERB_VOL, 0x00 }, /* r21 Master B Volume */ | ||
93 | { CS42L52_HPA_VOL, 0x00 }, /* r22 Headphone A Volume */ | ||
94 | { CS42L52_HPB_VOL, 0x00 }, /* r23 Headphone B Volume */ | ||
95 | { CS42L52_SPKA_VOL, 0x00 }, /* r24 Speaker A Volume */ | ||
96 | { CS42L52_SPKB_VOL, 0x00 }, /* r25 Speaker B Volume */ | ||
97 | { CS42L52_ADC_PCM_MIXER, 0x00 }, /* r26 Channel Mixer and Swap */ | ||
98 | { CS42L52_LIMITER_CTL1, 0x00 }, /* r27 Limit Ctl 1 Thresholds */ | ||
99 | { CS42L52_LIMITER_CTL2, 0x7F }, /* r28 Limit Ctl 2 Release Rate */ | ||
100 | { CS42L52_LIMITER_AT_RATE, 0xC0 }, /* r29 Limiter Attack Rate */ | ||
101 | { CS42L52_ALC_CTL, 0x00 }, /* r2A ALC Ctl 1 Attack Rate */ | ||
102 | { CS42L52_ALC_RATE, 0x3F }, /* r2B ALC Release Rate */ | ||
103 | { CS42L52_ALC_THRESHOLD, 0x3f }, /* r2C ALC Thresholds */ | ||
104 | { CS42L52_NOISE_GATE_CTL, 0x00 }, /* r2D Noise Gate Ctl */ | ||
105 | { CS42L52_CLK_STATUS, 0x00 }, /* r2E Overflow and Clock Status */ | ||
106 | { CS42L52_BATT_COMPEN, 0x00 }, /* r2F battery Compensation */ | ||
107 | { CS42L52_BATT_LEVEL, 0x00 }, /* r30 VP Battery Level */ | ||
108 | { CS42L52_SPK_STATUS, 0x00 }, /* r31 Speaker Status */ | ||
109 | { CS42L52_TEM_CTL, 0x3B }, /* r32 Temp Ctl */ | ||
110 | { CS42L52_THE_FOLDBACK, 0x00 }, /* r33 Foldback */ | ||
111 | }; | ||
112 | |||
113 | static bool cs42l52_readable_register(struct device *dev, unsigned int reg) | ||
114 | { | ||
115 | switch (reg) { | ||
116 | case CS42L52_CHIP: | ||
117 | case CS42L52_PWRCTL1: | ||
118 | case CS42L52_PWRCTL2: | ||
119 | case CS42L52_PWRCTL3: | ||
120 | case CS42L52_CLK_CTL: | ||
121 | case CS42L52_IFACE_CTL1: | ||
122 | case CS42L52_IFACE_CTL2: | ||
123 | case CS42L52_ADC_PGA_A: | ||
124 | case CS42L52_ADC_PGA_B: | ||
125 | case CS42L52_ANALOG_HPF_CTL: | ||
126 | case CS42L52_ADC_HPF_FREQ: | ||
127 | case CS42L52_ADC_MISC_CTL: | ||
128 | case CS42L52_PB_CTL1: | ||
129 | case CS42L52_MISC_CTL: | ||
130 | case CS42L52_PB_CTL2: | ||
131 | case CS42L52_MICA_CTL: | ||
132 | case CS42L52_MICB_CTL: | ||
133 | case CS42L52_PGAA_CTL: | ||
134 | case CS42L52_PGAB_CTL: | ||
135 | case CS42L52_PASSTHRUA_VOL: | ||
136 | case CS42L52_PASSTHRUB_VOL: | ||
137 | case CS42L52_ADCA_VOL: | ||
138 | case CS42L52_ADCB_VOL: | ||
139 | case CS42L52_ADCA_MIXER_VOL: | ||
140 | case CS42L52_ADCB_MIXER_VOL: | ||
141 | case CS42L52_PCMA_MIXER_VOL: | ||
142 | case CS42L52_PCMB_MIXER_VOL: | ||
143 | case CS42L52_BEEP_FREQ: | ||
144 | case CS42L52_BEEP_VOL: | ||
145 | case CS42L52_BEEP_TONE_CTL: | ||
146 | case CS42L52_TONE_CTL: | ||
147 | case CS42L52_MASTERA_VOL: | ||
148 | case CS42L52_MASTERB_VOL: | ||
149 | case CS42L52_HPA_VOL: | ||
150 | case CS42L52_HPB_VOL: | ||
151 | case CS42L52_SPKA_VOL: | ||
152 | case CS42L52_SPKB_VOL: | ||
153 | case CS42L52_ADC_PCM_MIXER: | ||
154 | case CS42L52_LIMITER_CTL1: | ||
155 | case CS42L52_LIMITER_CTL2: | ||
156 | case CS42L52_LIMITER_AT_RATE: | ||
157 | case CS42L52_ALC_CTL: | ||
158 | case CS42L52_ALC_RATE: | ||
159 | case CS42L52_ALC_THRESHOLD: | ||
160 | case CS42L52_NOISE_GATE_CTL: | ||
161 | case CS42L52_CLK_STATUS: | ||
162 | case CS42L52_BATT_COMPEN: | ||
163 | case CS42L52_BATT_LEVEL: | ||
164 | case CS42L52_SPK_STATUS: | ||
165 | case CS42L52_TEM_CTL: | ||
166 | case CS42L52_THE_FOLDBACK: | ||
167 | case CS42L52_CHARGE_PUMP: | ||
168 | return true; | ||
169 | default: | ||
170 | return false; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | static bool cs42l52_volatile_register(struct device *dev, unsigned int reg) | ||
175 | { | ||
176 | switch (reg) { | ||
177 | case CS42L52_IFACE_CTL2: | ||
178 | case CS42L52_CLK_STATUS: | ||
179 | case CS42L52_BATT_LEVEL: | ||
180 | case CS42L52_SPK_STATUS: | ||
181 | case CS42L52_CHARGE_PUMP: | ||
182 | return 1; | ||
183 | default: | ||
184 | return 0; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0); | ||
189 | |||
190 | static DECLARE_TLV_DB_SCALE(hpd_tlv, -9600, 50, 1); | ||
191 | |||
192 | static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0); | ||
193 | |||
194 | static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0); | ||
195 | |||
196 | static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0); | ||
197 | |||
198 | static const unsigned int limiter_tlv[] = { | ||
199 | TLV_DB_RANGE_HEAD(2), | ||
200 | 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0), | ||
201 | 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0), | ||
202 | }; | ||
203 | |||
204 | static const char * const cs42l52_adca_text[] = { | ||
205 | "Input1A", "Input2A", "Input3A", "Input4A", "PGA Input Left"}; | ||
206 | |||
207 | static const char * const cs42l52_adcb_text[] = { | ||
208 | "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"}; | ||
209 | |||
210 | static const struct soc_enum adca_enum = | ||
211 | SOC_ENUM_SINGLE(CS42L52_ADC_PGA_A, 5, | ||
212 | ARRAY_SIZE(cs42l52_adca_text), cs42l52_adca_text); | ||
213 | |||
214 | static const struct soc_enum adcb_enum = | ||
215 | SOC_ENUM_SINGLE(CS42L52_ADC_PGA_B, 5, | ||
216 | ARRAY_SIZE(cs42l52_adcb_text), cs42l52_adcb_text); | ||
217 | |||
218 | static const struct snd_kcontrol_new adca_mux = | ||
219 | SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum); | ||
220 | |||
221 | static const struct snd_kcontrol_new adcb_mux = | ||
222 | SOC_DAPM_ENUM("Right ADC Input Capture Mux", adcb_enum); | ||
223 | |||
224 | static const char * const mic_bias_level_text[] = { | ||
225 | "0.5 +VA", "0.6 +VA", "0.7 +VA", | ||
226 | "0.8 +VA", "0.83 +VA", "0.91 +VA" | ||
227 | }; | ||
228 | |||
229 | static const struct soc_enum mic_bias_level_enum = | ||
230 | SOC_ENUM_SINGLE(CS42L52_IFACE_CTL1, 0, | ||
231 | ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text); | ||
232 | |||
233 | static const char * const cs42l52_mic_text[] = { "Single", "Differential" }; | ||
234 | |||
235 | static const struct soc_enum mica_enum = | ||
236 | SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5, | ||
237 | ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text); | ||
238 | |||
239 | static const struct soc_enum micb_enum = | ||
240 | SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5, | ||
241 | ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text); | ||
242 | |||
243 | static const struct snd_kcontrol_new mica_mux = | ||
244 | SOC_DAPM_ENUM("Left Mic Input Capture Mux", mica_enum); | ||
245 | |||
246 | static const struct snd_kcontrol_new micb_mux = | ||
247 | SOC_DAPM_ENUM("Right Mic Input Capture Mux", micb_enum); | ||
248 | |||
249 | static const char * const digital_output_mux_text[] = {"ADC", "DSP"}; | ||
250 | |||
251 | static const struct soc_enum digital_output_mux_enum = | ||
252 | SOC_ENUM_SINGLE(CS42L52_ADC_MISC_CTL, 6, | ||
253 | ARRAY_SIZE(digital_output_mux_text), | ||
254 | digital_output_mux_text); | ||
255 | |||
256 | static const struct snd_kcontrol_new digital_output_mux = | ||
257 | SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum); | ||
258 | |||
259 | static const char * const hp_gain_num_text[] = { | ||
260 | "0.3959", "0.4571", "0.5111", "0.6047", | ||
261 | "0.7099", "0.8399", "1.000", "1.1430" | ||
262 | }; | ||
263 | |||
264 | static const struct soc_enum hp_gain_enum = | ||
265 | SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 4, | ||
266 | ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text); | ||
267 | |||
268 | static const char * const beep_pitch_text[] = { | ||
269 | "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5", | ||
270 | "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7" | ||
271 | }; | ||
272 | |||
273 | static const struct soc_enum beep_pitch_enum = | ||
274 | SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 4, | ||
275 | ARRAY_SIZE(beep_pitch_text), beep_pitch_text); | ||
276 | |||
277 | static const char * const beep_ontime_text[] = { | ||
278 | "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s", | ||
279 | "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s", | ||
280 | "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s" | ||
281 | }; | ||
282 | |||
283 | static const struct soc_enum beep_ontime_enum = | ||
284 | SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 0, | ||
285 | ARRAY_SIZE(beep_ontime_text), beep_ontime_text); | ||
286 | |||
287 | static const char * const beep_offtime_text[] = { | ||
288 | "1.23 s", "2.58 s", "3.90 s", "5.20 s", | ||
289 | "6.60 s", "8.05 s", "9.35 s", "10.80 s" | ||
290 | }; | ||
291 | |||
292 | static const struct soc_enum beep_offtime_enum = | ||
293 | SOC_ENUM_SINGLE(CS42L52_BEEP_VOL, 5, | ||
294 | ARRAY_SIZE(beep_offtime_text), beep_offtime_text); | ||
295 | |||
296 | static const char * const beep_config_text[] = { | ||
297 | "Off", "Single", "Multiple", "Continuous" | ||
298 | }; | ||
299 | |||
300 | static const struct soc_enum beep_config_enum = | ||
301 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 6, | ||
302 | ARRAY_SIZE(beep_config_text), beep_config_text); | ||
303 | |||
304 | static const char * const beep_bass_text[] = { | ||
305 | "50 Hz", "100 Hz", "200 Hz", "250 Hz" | ||
306 | }; | ||
307 | |||
308 | static const struct soc_enum beep_bass_enum = | ||
309 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 1, | ||
310 | ARRAY_SIZE(beep_bass_text), beep_bass_text); | ||
311 | |||
312 | static const char * const beep_treble_text[] = { | ||
313 | "5 kHz", "7 kHz", "10 kHz", " 15 kHz" | ||
314 | }; | ||
315 | |||
316 | static const struct soc_enum beep_treble_enum = | ||
317 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 3, | ||
318 | ARRAY_SIZE(beep_treble_text), beep_treble_text); | ||
319 | |||
320 | static const char * const ng_threshold_text[] = { | ||
321 | "-34dB", "-37dB", "-40dB", "-43dB", | ||
322 | "-46dB", "-52dB", "-58dB", "-64dB" | ||
323 | }; | ||
324 | |||
325 | static const struct soc_enum ng_threshold_enum = | ||
326 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 2, | ||
327 | ARRAY_SIZE(ng_threshold_text), ng_threshold_text); | ||
328 | |||
329 | static const char * const cs42l52_ng_delay_text[] = { | ||
330 | "50ms", "100ms", "150ms", "200ms"}; | ||
331 | |||
332 | static const struct soc_enum ng_delay_enum = | ||
333 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 0, | ||
334 | ARRAY_SIZE(cs42l52_ng_delay_text), cs42l52_ng_delay_text); | ||
335 | |||
336 | static const char * const cs42l52_ng_type_text[] = { | ||
337 | "Apply Specific", "Apply All" | ||
338 | }; | ||
339 | |||
340 | static const struct soc_enum ng_type_enum = | ||
341 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 6, | ||
342 | ARRAY_SIZE(cs42l52_ng_type_text), cs42l52_ng_type_text); | ||
343 | |||
344 | static const char * const left_swap_text[] = { | ||
345 | "Left", "LR 2", "Right"}; | ||
346 | |||
347 | static const char * const right_swap_text[] = { | ||
348 | "Right", "LR 2", "Left"}; | ||
349 | |||
350 | static const unsigned int swap_values[] = { 0, 1, 3 }; | ||
351 | |||
352 | static const struct soc_enum adca_swap_enum = | ||
353 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 1, | ||
354 | ARRAY_SIZE(left_swap_text), | ||
355 | left_swap_text, | ||
356 | swap_values); | ||
357 | |||
358 | static const struct snd_kcontrol_new adca_mixer = | ||
359 | SOC_DAPM_ENUM("Route", adca_swap_enum); | ||
360 | |||
361 | static const struct soc_enum pcma_swap_enum = | ||
362 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 1, | ||
363 | ARRAY_SIZE(left_swap_text), | ||
364 | left_swap_text, | ||
365 | swap_values); | ||
366 | |||
367 | static const struct snd_kcontrol_new pcma_mixer = | ||
368 | SOC_DAPM_ENUM("Route", pcma_swap_enum); | ||
369 | |||
370 | static const struct soc_enum adcb_swap_enum = | ||
371 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 1, | ||
372 | ARRAY_SIZE(right_swap_text), | ||
373 | right_swap_text, | ||
374 | swap_values); | ||
375 | |||
376 | static const struct snd_kcontrol_new adcb_mixer = | ||
377 | SOC_DAPM_ENUM("Route", adcb_swap_enum); | ||
378 | |||
379 | static const struct soc_enum pcmb_swap_enum = | ||
380 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 1, | ||
381 | ARRAY_SIZE(right_swap_text), | ||
382 | right_swap_text, | ||
383 | swap_values); | ||
384 | |||
385 | static const struct snd_kcontrol_new pcmb_mixer = | ||
386 | SOC_DAPM_ENUM("Route", pcmb_swap_enum); | ||
387 | |||
388 | |||
389 | static const struct snd_kcontrol_new passthrul_ctl = | ||
390 | SOC_DAPM_SINGLE("Switch", CS42L52_MISC_CTL, 6, 1, 0); | ||
391 | |||
392 | static const struct snd_kcontrol_new passthrur_ctl = | ||
393 | SOC_DAPM_SINGLE("Switch", CS42L52_MISC_CTL, 7, 1, 0); | ||
394 | |||
395 | static const struct snd_kcontrol_new spkl_ctl = | ||
396 | SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 0, 1, 1); | ||
397 | |||
398 | static const struct snd_kcontrol_new spkr_ctl = | ||
399 | SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 2, 1, 1); | ||
400 | |||
401 | static const struct snd_kcontrol_new hpl_ctl = | ||
402 | SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 4, 1, 1); | ||
403 | |||
404 | static const struct snd_kcontrol_new hpr_ctl = | ||
405 | SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 6, 1, 1); | ||
406 | |||
407 | static const struct snd_kcontrol_new cs42l52_snd_controls[] = { | ||
408 | |||
409 | SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L52_MASTERA_VOL, | ||
410 | CS42L52_MASTERB_VOL, 0, 0x34, 0xE4, hl_tlv), | ||
411 | |||
412 | SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L52_HPA_VOL, | ||
413 | CS42L52_HPB_VOL, 0, 0x34, 0xCC, hpd_tlv), | ||
414 | |||
415 | SOC_ENUM("Headphone Analog Gain", hp_gain_enum), | ||
416 | |||
417 | SOC_DOUBLE_R_SX_TLV("Speaker Volume", CS42L52_SPKA_VOL, | ||
418 | CS42L52_SPKB_VOL, 7, 0x1, 0xff, hl_tlv), | ||
419 | |||
420 | SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL, | ||
421 | CS42L52_PASSTHRUB_VOL, 6, 0x18, 0x90, pga_tlv), | ||
422 | |||
423 | SOC_DOUBLE("Bypass Mute", CS42L52_MISC_CTL, 4, 5, 1, 0), | ||
424 | |||
425 | SOC_DOUBLE_R_TLV("MIC Gain Volume", CS42L52_MICA_CTL, | ||
426 | CS42L52_MICB_CTL, 0, 0x10, 0, mic_tlv), | ||
427 | |||
428 | SOC_ENUM("MIC Bias Level", mic_bias_level_enum), | ||
429 | |||
430 | SOC_DOUBLE_R_SX_TLV("ADC Volume", CS42L52_ADCA_VOL, | ||
431 | CS42L52_ADCB_VOL, 7, 0x80, 0xA0, ipd_tlv), | ||
432 | SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", | ||
433 | CS42L52_ADCA_MIXER_VOL, CS42L52_ADCB_MIXER_VOL, | ||
434 | 6, 0x7f, 0x19, ipd_tlv), | ||
435 | |||
436 | SOC_DOUBLE("ADC Switch", CS42L52_ADC_MISC_CTL, 0, 1, 1, 0), | ||
437 | |||
438 | SOC_DOUBLE_R("ADC Mixer Switch", CS42L52_ADCA_MIXER_VOL, | ||
439 | CS42L52_ADCB_MIXER_VOL, 7, 1, 1), | ||
440 | |||
441 | SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L52_PGAA_CTL, | ||
442 | CS42L52_PGAB_CTL, 0, 0x28, 0x30, pga_tlv), | ||
443 | |||
444 | SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", | ||
445 | CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, | ||
446 | 6, 0x7f, 0x19, hl_tlv), | ||
447 | SOC_DOUBLE_R("PCM Mixer Switch", | ||
448 | CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, 7, 1, 1), | ||
449 | |||
450 | SOC_ENUM("Beep Config", beep_config_enum), | ||
451 | SOC_ENUM("Beep Pitch", beep_pitch_enum), | ||
452 | SOC_ENUM("Beep on Time", beep_ontime_enum), | ||
453 | SOC_ENUM("Beep off Time", beep_offtime_enum), | ||
454 | SOC_SINGLE_TLV("Beep Volume", CS42L52_BEEP_VOL, 0, 0x1f, 0x07, hl_tlv), | ||
455 | SOC_SINGLE("Beep Mixer Switch", CS42L52_BEEP_TONE_CTL, 5, 1, 1), | ||
456 | SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum), | ||
457 | SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum), | ||
458 | |||
459 | SOC_SINGLE("Tone Control Switch", CS42L52_BEEP_TONE_CTL, 0, 1, 1), | ||
460 | SOC_SINGLE_TLV("Treble Gain Volume", | ||
461 | CS42L52_TONE_CTL, 4, 15, 1, hl_tlv), | ||
462 | SOC_SINGLE_TLV("Bass Gain Volume", | ||
463 | CS42L52_TONE_CTL, 0, 15, 1, hl_tlv), | ||
464 | |||
465 | /* Limiter */ | ||
466 | SOC_SINGLE_TLV("Limiter Max Threshold Volume", | ||
467 | CS42L52_LIMITER_CTL1, 5, 7, 0, limiter_tlv), | ||
468 | SOC_SINGLE_TLV("Limiter Cushion Threshold Volume", | ||
469 | CS42L52_LIMITER_CTL1, 2, 7, 0, limiter_tlv), | ||
470 | SOC_SINGLE_TLV("Limiter Release Rate Volume", | ||
471 | CS42L52_LIMITER_CTL2, 0, 63, 0, limiter_tlv), | ||
472 | SOC_SINGLE_TLV("Limiter Attack Rate Volume", | ||
473 | CS42L52_LIMITER_AT_RATE, 0, 63, 0, limiter_tlv), | ||
474 | |||
475 | SOC_SINGLE("Limiter SR Switch", CS42L52_LIMITER_CTL1, 1, 1, 0), | ||
476 | SOC_SINGLE("Limiter ZC Switch", CS42L52_LIMITER_CTL1, 0, 1, 0), | ||
477 | SOC_SINGLE("Limiter Switch", CS42L52_LIMITER_CTL2, 7, 1, 0), | ||
478 | |||
479 | /* ALC */ | ||
480 | SOC_SINGLE_TLV("ALC Attack Rate Volume", CS42L52_ALC_CTL, | ||
481 | 0, 63, 0, limiter_tlv), | ||
482 | SOC_SINGLE_TLV("ALC Release Rate Volume", CS42L52_ALC_RATE, | ||
483 | 0, 63, 0, limiter_tlv), | ||
484 | SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L52_ALC_THRESHOLD, | ||
485 | 5, 7, 0, limiter_tlv), | ||
486 | SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L52_ALC_THRESHOLD, | ||
487 | 2, 7, 0, limiter_tlv), | ||
488 | |||
489 | SOC_DOUBLE_R("ALC SR Capture Switch", CS42L52_PGAA_CTL, | ||
490 | CS42L52_PGAB_CTL, 7, 1, 1), | ||
491 | SOC_DOUBLE_R("ALC ZC Capture Switch", CS42L52_PGAA_CTL, | ||
492 | CS42L52_PGAB_CTL, 6, 1, 1), | ||
493 | SOC_DOUBLE("ALC Capture Switch", CS42L52_ALC_CTL, 6, 7, 1, 0), | ||
494 | |||
495 | /* Noise gate */ | ||
496 | SOC_ENUM("NG Type Switch", ng_type_enum), | ||
497 | SOC_SINGLE("NG Enable Switch", CS42L52_NOISE_GATE_CTL, 6, 1, 0), | ||
498 | SOC_SINGLE("NG Boost Switch", CS42L52_NOISE_GATE_CTL, 5, 1, 1), | ||
499 | SOC_ENUM("NG Threshold", ng_threshold_enum), | ||
500 | SOC_ENUM("NG Delay", ng_delay_enum), | ||
501 | |||
502 | SOC_DOUBLE("HPF Switch", CS42L52_ANALOG_HPF_CTL, 5, 7, 1, 0), | ||
503 | |||
504 | SOC_DOUBLE("Analog SR Switch", CS42L52_ANALOG_HPF_CTL, 1, 3, 1, 1), | ||
505 | SOC_DOUBLE("Analog ZC Switch", CS42L52_ANALOG_HPF_CTL, 0, 2, 1, 1), | ||
506 | SOC_SINGLE("Digital SR Switch", CS42L52_MISC_CTL, 1, 1, 0), | ||
507 | SOC_SINGLE("Digital ZC Switch", CS42L52_MISC_CTL, 0, 1, 0), | ||
508 | SOC_SINGLE("Deemphasis Switch", CS42L52_MISC_CTL, 2, 1, 0), | ||
509 | |||
510 | SOC_SINGLE("Batt Compensation Switch", CS42L52_BATT_COMPEN, 7, 1, 0), | ||
511 | SOC_SINGLE("Batt VP Monitor Switch", CS42L52_BATT_COMPEN, 6, 1, 0), | ||
512 | SOC_SINGLE("Batt VP ref", CS42L52_BATT_COMPEN, 0, 0x0f, 0), | ||
513 | |||
514 | SOC_SINGLE("PGA AIN1L Switch", CS42L52_ADC_PGA_A, 0, 1, 0), | ||
515 | SOC_SINGLE("PGA AIN1R Switch", CS42L52_ADC_PGA_B, 0, 1, 0), | ||
516 | SOC_SINGLE("PGA AIN2L Switch", CS42L52_ADC_PGA_A, 1, 1, 0), | ||
517 | SOC_SINGLE("PGA AIN2R Switch", CS42L52_ADC_PGA_B, 1, 1, 0), | ||
518 | |||
519 | SOC_SINGLE("PGA AIN3L Switch", CS42L52_ADC_PGA_A, 2, 1, 0), | ||
520 | SOC_SINGLE("PGA AIN3R Switch", CS42L52_ADC_PGA_B, 2, 1, 0), | ||
521 | |||
522 | SOC_SINGLE("PGA AIN4L Switch", CS42L52_ADC_PGA_A, 3, 1, 0), | ||
523 | SOC_SINGLE("PGA AIN4R Switch", CS42L52_ADC_PGA_B, 3, 1, 0), | ||
524 | |||
525 | SOC_SINGLE("PGA MICA Switch", CS42L52_ADC_PGA_A, 4, 1, 0), | ||
526 | SOC_SINGLE("PGA MICB Switch", CS42L52_ADC_PGA_B, 4, 1, 0), | ||
527 | |||
528 | }; | ||
529 | |||
530 | static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = { | ||
531 | |||
532 | SND_SOC_DAPM_INPUT("AIN1L"), | ||
533 | SND_SOC_DAPM_INPUT("AIN1R"), | ||
534 | SND_SOC_DAPM_INPUT("AIN2L"), | ||
535 | SND_SOC_DAPM_INPUT("AIN2R"), | ||
536 | SND_SOC_DAPM_INPUT("AIN3L"), | ||
537 | SND_SOC_DAPM_INPUT("AIN3R"), | ||
538 | SND_SOC_DAPM_INPUT("AIN4L"), | ||
539 | SND_SOC_DAPM_INPUT("AIN4R"), | ||
540 | SND_SOC_DAPM_INPUT("MICA"), | ||
541 | SND_SOC_DAPM_INPUT("MICB"), | ||
542 | SND_SOC_DAPM_SIGGEN("Beep"), | ||
543 | |||
544 | SND_SOC_DAPM_AIF_OUT("AIFOUTL", NULL, 0, | ||
545 | SND_SOC_NOPM, 0, 0), | ||
546 | SND_SOC_DAPM_AIF_OUT("AIFOUTR", NULL, 0, | ||
547 | SND_SOC_NOPM, 0, 0), | ||
548 | |||
549 | SND_SOC_DAPM_MUX("MICA Mux", SND_SOC_NOPM, 0, 0, &mica_mux), | ||
550 | SND_SOC_DAPM_MUX("MICB Mux", SND_SOC_NOPM, 0, 0, &micb_mux), | ||
551 | |||
552 | SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L52_PWRCTL1, 1, 1), | ||
553 | SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L52_PWRCTL1, 2, 1), | ||
554 | SND_SOC_DAPM_PGA("PGA Left", CS42L52_PWRCTL1, 3, 1, NULL, 0), | ||
555 | SND_SOC_DAPM_PGA("PGA Right", CS42L52_PWRCTL1, 4, 1, NULL, 0), | ||
556 | |||
557 | SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adca_mux), | ||
558 | SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcb_mux), | ||
559 | |||
560 | SND_SOC_DAPM_MUX("ADC Left Swap", SND_SOC_NOPM, | ||
561 | 0, 0, &adca_mixer), | ||
562 | SND_SOC_DAPM_MUX("ADC Right Swap", SND_SOC_NOPM, | ||
563 | 0, 0, &adcb_mixer), | ||
564 | |||
565 | SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, | ||
566 | 0, 0, &digital_output_mux), | ||
567 | |||
568 | SND_SOC_DAPM_PGA("PGA MICA", CS42L52_PWRCTL2, 1, 1, NULL, 0), | ||
569 | SND_SOC_DAPM_PGA("PGA MICB", CS42L52_PWRCTL2, 2, 1, NULL, 0), | ||
570 | |||
571 | SND_SOC_DAPM_SUPPLY("Mic Bias", CS42L52_PWRCTL2, 0, 1, NULL, 0), | ||
572 | SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L52_PWRCTL1, 7, 1, NULL, 0), | ||
573 | |||
574 | SND_SOC_DAPM_AIF_IN("AIFINL", NULL, 0, | ||
575 | SND_SOC_NOPM, 0, 0), | ||
576 | SND_SOC_DAPM_AIF_IN("AIFINR", NULL, 0, | ||
577 | SND_SOC_NOPM, 0, 0), | ||
578 | |||
579 | SND_SOC_DAPM_DAC("DAC Left", NULL, SND_SOC_NOPM, 0, 0), | ||
580 | SND_SOC_DAPM_DAC("DAC Right", NULL, SND_SOC_NOPM, 0, 0), | ||
581 | |||
582 | SND_SOC_DAPM_SWITCH("Bypass Left", CS42L52_MISC_CTL, | ||
583 | 6, 0, &passthrul_ctl), | ||
584 | SND_SOC_DAPM_SWITCH("Bypass Right", CS42L52_MISC_CTL, | ||
585 | 7, 0, &passthrur_ctl), | ||
586 | |||
587 | SND_SOC_DAPM_MUX("PCM Left Swap", SND_SOC_NOPM, | ||
588 | 0, 0, &pcma_mixer), | ||
589 | SND_SOC_DAPM_MUX("PCM Right Swap", SND_SOC_NOPM, | ||
590 | 0, 0, &pcmb_mixer), | ||
591 | |||
592 | SND_SOC_DAPM_SWITCH("HP Left Amp", SND_SOC_NOPM, 0, 0, &hpl_ctl), | ||
593 | SND_SOC_DAPM_SWITCH("HP Right Amp", SND_SOC_NOPM, 0, 0, &hpr_ctl), | ||
594 | |||
595 | SND_SOC_DAPM_SWITCH("SPK Left Amp", SND_SOC_NOPM, 0, 0, &spkl_ctl), | ||
596 | SND_SOC_DAPM_SWITCH("SPK Right Amp", SND_SOC_NOPM, 0, 0, &spkr_ctl), | ||
597 | |||
598 | SND_SOC_DAPM_OUTPUT("HPOUTA"), | ||
599 | SND_SOC_DAPM_OUTPUT("HPOUTB"), | ||
600 | SND_SOC_DAPM_OUTPUT("SPKOUTA"), | ||
601 | SND_SOC_DAPM_OUTPUT("SPKOUTB"), | ||
602 | |||
603 | }; | ||
604 | |||
605 | static const struct snd_soc_dapm_route cs42l52_audio_map[] = { | ||
606 | |||
607 | {"Capture", NULL, "AIFOUTL"}, | ||
608 | {"Capture", NULL, "AIFOUTL"}, | ||
609 | |||
610 | {"AIFOUTL", NULL, "Output Mux"}, | ||
611 | {"AIFOUTR", NULL, "Output Mux"}, | ||
612 | |||
613 | {"Output Mux", "ADC", "ADC Left"}, | ||
614 | {"Output Mux", "ADC", "ADC Right"}, | ||
615 | |||
616 | {"ADC Left", NULL, "Charge Pump"}, | ||
617 | {"ADC Right", NULL, "Charge Pump"}, | ||
618 | |||
619 | {"Charge Pump", NULL, "ADC Left Mux"}, | ||
620 | {"Charge Pump", NULL, "ADC Right Mux"}, | ||
621 | |||
622 | {"ADC Left Mux", "Input1A", "AIN1L"}, | ||
623 | {"ADC Right Mux", "Input1B", "AIN1R"}, | ||
624 | {"ADC Left Mux", "Input2A", "AIN2L"}, | ||
625 | {"ADC Right Mux", "Input2B", "AIN2R"}, | ||
626 | {"ADC Left Mux", "Input3A", "AIN3L"}, | ||
627 | {"ADC Right Mux", "Input3B", "AIN3R"}, | ||
628 | {"ADC Left Mux", "Input4A", "AIN4L"}, | ||
629 | {"ADC Right Mux", "Input4B", "AIN4R"}, | ||
630 | {"ADC Left Mux", "PGA Input Left", "PGA Left"}, | ||
631 | {"ADC Right Mux", "PGA Input Right" , "PGA Right"}, | ||
632 | |||
633 | {"PGA Left", "Switch", "AIN1L"}, | ||
634 | {"PGA Right", "Switch", "AIN1R"}, | ||
635 | {"PGA Left", "Switch", "AIN2L"}, | ||
636 | {"PGA Right", "Switch", "AIN2R"}, | ||
637 | {"PGA Left", "Switch", "AIN3L"}, | ||
638 | {"PGA Right", "Switch", "AIN3R"}, | ||
639 | {"PGA Left", "Switch", "AIN4L"}, | ||
640 | {"PGA Right", "Switch", "AIN4R"}, | ||
641 | |||
642 | {"PGA Left", "Switch", "PGA MICA"}, | ||
643 | {"PGA MICA", NULL, "MICA"}, | ||
644 | |||
645 | {"PGA Right", "Switch", "PGA MICB"}, | ||
646 | {"PGA MICB", NULL, "MICB"}, | ||
647 | |||
648 | {"HPOUTA", NULL, "HP Left Amp"}, | ||
649 | {"HPOUTB", NULL, "HP Right Amp"}, | ||
650 | {"HP Left Amp", NULL, "Bypass Left"}, | ||
651 | {"HP Right Amp", NULL, "Bypass Right"}, | ||
652 | {"Bypass Left", "Switch", "PGA Left"}, | ||
653 | {"Bypass Right", "Switch", "PGA Right"}, | ||
654 | {"HP Left Amp", "Switch", "DAC Left"}, | ||
655 | {"HP Right Amp", "Switch", "DAC Right"}, | ||
656 | |||
657 | {"SPKOUTA", NULL, "SPK Left Amp"}, | ||
658 | {"SPKOUTB", NULL, "SPK Right Amp"}, | ||
659 | |||
660 | {"SPK Left Amp", NULL, "Beep"}, | ||
661 | {"SPK Right Amp", NULL, "Beep"}, | ||
662 | {"SPK Left Amp", "Switch", "Playback"}, | ||
663 | {"SPK Right Amp", "Switch", "Playback"}, | ||
664 | |||
665 | {"DAC Left", NULL, "Beep"}, | ||
666 | {"DAC Right", NULL, "Beep"}, | ||
667 | {"DAC Left", NULL, "Playback"}, | ||
668 | {"DAC Right", NULL, "Playback"}, | ||
669 | |||
670 | {"Output Mux", "DSP", "Playback"}, | ||
671 | {"Output Mux", "DSP", "Playback"}, | ||
672 | |||
673 | {"AIFINL", NULL, "Playback"}, | ||
674 | {"AIFINR", NULL, "Playback"}, | ||
675 | |||
676 | }; | ||
677 | |||
678 | struct cs42l52_clk_para { | ||
679 | u32 mclk; | ||
680 | u32 rate; | ||
681 | u8 speed; | ||
682 | u8 group; | ||
683 | u8 videoclk; | ||
684 | u8 ratio; | ||
685 | u8 mclkdiv2; | ||
686 | }; | ||
687 | |||
688 | static const struct cs42l52_clk_para clk_map_table[] = { | ||
689 | /*8k*/ | ||
690 | {12288000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
691 | {18432000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
692 | {12000000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0}, | ||
693 | {24000000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1}, | ||
694 | {27000000, 8000, CLK_QS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 0}, | ||
695 | |||
696 | /*11.025k*/ | ||
697 | {11289600, 11025, CLK_QS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
698 | {16934400, 11025, CLK_QS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
699 | |||
700 | /*16k*/ | ||
701 | {12288000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
702 | {18432000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
703 | {12000000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0}, | ||
704 | {24000000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1}, | ||
705 | {27000000, 16000, CLK_HS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 1}, | ||
706 | |||
707 | /*22.05k*/ | ||
708 | {11289600, 22050, CLK_HS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
709 | {16934400, 22050, CLK_HS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
710 | |||
711 | /* 32k */ | ||
712 | {12288000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
713 | {18432000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
714 | {12000000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0}, | ||
715 | {24000000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1}, | ||
716 | {27000000, 32000, CLK_SS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 0}, | ||
717 | |||
718 | /* 44.1k */ | ||
719 | {11289600, 44100, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
720 | {16934400, 44100, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
721 | |||
722 | /* 48k */ | ||
723 | {12288000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
724 | {18432000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
725 | {12000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 0}, | ||
726 | {24000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 1}, | ||
727 | {27000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_27M_MCLK, CLK_R_125, 1}, | ||
728 | |||
729 | /* 88.2k */ | ||
730 | {11289600, 88200, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
731 | {16934400, 88200, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
732 | |||
733 | /* 96k */ | ||
734 | {12288000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
735 | {18432000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0}, | ||
736 | {12000000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 0}, | ||
737 | {24000000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 1}, | ||
738 | }; | ||
739 | |||
740 | static int cs42l52_get_clk(int mclk, int rate) | ||
741 | { | ||
742 | int i, ret = 0; | ||
743 | u_int mclk1, mclk2 = 0; | ||
744 | |||
745 | for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) { | ||
746 | if (clk_map_table[i].rate == rate) { | ||
747 | mclk1 = clk_map_table[i].mclk; | ||
748 | if (abs(mclk - mclk1) < abs(mclk - mclk2)) { | ||
749 | mclk2 = mclk1; | ||
750 | ret = i; | ||
751 | } | ||
752 | } | ||
753 | } | ||
754 | if (ret > ARRAY_SIZE(clk_map_table)) | ||
755 | return -EINVAL; | ||
756 | return ret; | ||
757 | } | ||
758 | |||
759 | static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai, | ||
760 | int clk_id, unsigned int freq, int dir) | ||
761 | { | ||
762 | struct snd_soc_codec *codec = codec_dai->codec; | ||
763 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | ||
764 | |||
765 | if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) { | ||
766 | cs42l52->sysclk = freq; | ||
767 | } else { | ||
768 | dev_err(codec->dev, "Invalid freq paramter\n"); | ||
769 | return -EINVAL; | ||
770 | } | ||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | ||
775 | { | ||
776 | struct snd_soc_codec *codec = codec_dai->codec; | ||
777 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | ||
778 | int ret = 0; | ||
779 | u8 iface = 0; | ||
780 | |||
781 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
782 | case SND_SOC_DAIFMT_CBM_CFM: | ||
783 | iface = CS42L52_IFACE_CTL1_MASTER; | ||
784 | break; | ||
785 | case SND_SOC_DAIFMT_CBS_CFS: | ||
786 | iface = CS42L52_IFACE_CTL1_SLAVE; | ||
787 | break; | ||
788 | default: | ||
789 | return -EINVAL; | ||
790 | } | ||
791 | |||
792 | /* interface format */ | ||
793 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
794 | case SND_SOC_DAIFMT_I2S: | ||
795 | iface |= CS42L52_IFACE_CTL1_ADC_FMT_I2S | | ||
796 | CS42L52_IFACE_CTL1_DAC_FMT_I2S; | ||
797 | break; | ||
798 | case SND_SOC_DAIFMT_RIGHT_J: | ||
799 | iface |= CS42L52_IFACE_CTL1_DAC_FMT_RIGHT_J; | ||
800 | break; | ||
801 | case SND_SOC_DAIFMT_LEFT_J: | ||
802 | iface |= CS42L52_IFACE_CTL1_ADC_FMT_LEFT_J | | ||
803 | CS42L52_IFACE_CTL1_DAC_FMT_LEFT_J; | ||
804 | break; | ||
805 | case SND_SOC_DAIFMT_DSP_A: | ||
806 | iface |= CS42L52_IFACE_CTL1_DSP_MODE_EN; | ||
807 | break; | ||
808 | case SND_SOC_DAIFMT_DSP_B: | ||
809 | break; | ||
810 | default: | ||
811 | return -EINVAL; | ||
812 | } | ||
813 | |||
814 | /* clock inversion */ | ||
815 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
816 | case SND_SOC_DAIFMT_NB_NF: | ||
817 | break; | ||
818 | case SND_SOC_DAIFMT_IB_IF: | ||
819 | iface |= CS42L52_IFACE_CTL1_INV_SCLK; | ||
820 | break; | ||
821 | case SND_SOC_DAIFMT_IB_NF: | ||
822 | iface |= CS42L52_IFACE_CTL1_INV_SCLK; | ||
823 | break; | ||
824 | case SND_SOC_DAIFMT_NB_IF: | ||
825 | break; | ||
826 | default: | ||
827 | ret = -EINVAL; | ||
828 | } | ||
829 | cs42l52->config.format = iface; | ||
830 | snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format); | ||
831 | |||
832 | return 0; | ||
833 | } | ||
834 | |||
835 | static int cs42l52_digital_mute(struct snd_soc_dai *dai, int mute) | ||
836 | { | ||
837 | struct snd_soc_codec *codec = dai->codec; | ||
838 | |||
839 | if (mute) | ||
840 | snd_soc_update_bits(codec, CS42L52_PB_CTL1, | ||
841 | CS42L52_PB_CTL1_MUTE_MASK, | ||
842 | CS42L52_PB_CTL1_MUTE); | ||
843 | else | ||
844 | snd_soc_update_bits(codec, CS42L52_PB_CTL1, | ||
845 | CS42L52_PB_CTL1_MUTE_MASK, | ||
846 | CS42L52_PB_CTL1_UNMUTE); | ||
847 | |||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | static int cs42l52_pcm_hw_params(struct snd_pcm_substream *substream, | ||
852 | struct snd_pcm_hw_params *params, | ||
853 | struct snd_soc_dai *dai) | ||
854 | { | ||
855 | struct snd_soc_codec *codec = dai->codec; | ||
856 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | ||
857 | u32 clk = 0; | ||
858 | int index; | ||
859 | |||
860 | index = cs42l52_get_clk(cs42l52->sysclk, params_rate(params)); | ||
861 | if (index >= 0) { | ||
862 | cs42l52->sysclk = clk_map_table[index].mclk; | ||
863 | |||
864 | clk |= (clk_map_table[index].speed << CLK_SPEED_SHIFT) | | ||
865 | (clk_map_table[index].group << CLK_32K_SR_SHIFT) | | ||
866 | (clk_map_table[index].videoclk << CLK_27M_MCLK_SHIFT) | | ||
867 | (clk_map_table[index].ratio << CLK_RATIO_SHIFT) | | ||
868 | clk_map_table[index].mclkdiv2; | ||
869 | |||
870 | snd_soc_write(codec, CS42L52_CLK_CTL, clk); | ||
871 | } else { | ||
872 | dev_err(codec->dev, "can't get correct mclk\n"); | ||
873 | return -EINVAL; | ||
874 | } | ||
875 | |||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | static int cs42l52_set_bias_level(struct snd_soc_codec *codec, | ||
880 | enum snd_soc_bias_level level) | ||
881 | { | ||
882 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | ||
883 | |||
884 | switch (level) { | ||
885 | case SND_SOC_BIAS_ON: | ||
886 | break; | ||
887 | case SND_SOC_BIAS_PREPARE: | ||
888 | snd_soc_update_bits(codec, CS42L52_PWRCTL1, | ||
889 | CS42L52_PWRCTL1_PDN_CODEC, 0); | ||
890 | break; | ||
891 | case SND_SOC_BIAS_STANDBY: | ||
892 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
893 | regcache_cache_only(cs42l52->regmap, false); | ||
894 | regcache_sync(cs42l52->regmap); | ||
895 | } | ||
896 | snd_soc_write(codec, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL); | ||
897 | break; | ||
898 | case SND_SOC_BIAS_OFF: | ||
899 | snd_soc_write(codec, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL); | ||
900 | regcache_cache_only(cs42l52->regmap, true); | ||
901 | break; | ||
902 | } | ||
903 | codec->dapm.bias_level = level; | ||
904 | |||
905 | return 0; | ||
906 | } | ||
907 | |||
908 | #define CS42L52_RATES (SNDRV_PCM_RATE_8000_96000) | ||
909 | |||
910 | #define CS42L52_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ | ||
911 | SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \ | ||
912 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ | ||
913 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE) | ||
914 | |||
915 | static struct snd_soc_dai_ops cs42l52_ops = { | ||
916 | .hw_params = cs42l52_pcm_hw_params, | ||
917 | .digital_mute = cs42l52_digital_mute, | ||
918 | .set_fmt = cs42l52_set_fmt, | ||
919 | .set_sysclk = cs42l52_set_sysclk, | ||
920 | }; | ||
921 | |||
922 | struct snd_soc_dai_driver cs42l52_dai = { | ||
923 | .name = "cs42l52", | ||
924 | .playback = { | ||
925 | .stream_name = "Playback", | ||
926 | .channels_min = 1, | ||
927 | .channels_max = 2, | ||
928 | .rates = CS42L52_RATES, | ||
929 | .formats = CS42L52_FORMATS, | ||
930 | }, | ||
931 | .capture = { | ||
932 | .stream_name = "Capture", | ||
933 | .channels_min = 1, | ||
934 | .channels_max = 2, | ||
935 | .rates = CS42L52_RATES, | ||
936 | .formats = CS42L52_FORMATS, | ||
937 | }, | ||
938 | .ops = &cs42l52_ops, | ||
939 | }; | ||
940 | |||
941 | static int cs42l52_suspend(struct snd_soc_codec *codec) | ||
942 | { | ||
943 | cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
944 | |||
945 | return 0; | ||
946 | } | ||
947 | |||
948 | static int cs42l52_resume(struct snd_soc_codec *codec) | ||
949 | { | ||
950 | cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
951 | |||
952 | return 0; | ||
953 | } | ||
954 | |||
955 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
956 | static int beep_rates[] = { | ||
957 | 261, 522, 585, 667, 706, 774, 889, 1000, | ||
958 | 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 | ||
959 | }; | ||
960 | |||
961 | static void cs42l52_beep_work(struct work_struct *work) | ||
962 | { | ||
963 | struct cs42l52_private *cs42l52 = | ||
964 | container_of(work, struct cs42l52_private, beep_work); | ||
965 | struct snd_soc_codec *codec = cs42l52->codec; | ||
966 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
967 | int i; | ||
968 | int val = 0; | ||
969 | int best = 0; | ||
970 | |||
971 | if (cs42l52->beep_rate) { | ||
972 | for (i = 0; i < ARRAY_SIZE(beep_rates); i++) { | ||
973 | if (abs(cs42l52->beep_rate - beep_rates[i]) < | ||
974 | abs(cs42l52->beep_rate - beep_rates[best])) | ||
975 | best = i; | ||
976 | } | ||
977 | |||
978 | dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n", | ||
979 | beep_rates[best], cs42l52->beep_rate); | ||
980 | |||
981 | val = (best << CS42L52_BEEP_RATE_SHIFT); | ||
982 | |||
983 | snd_soc_dapm_enable_pin(dapm, "Beep"); | ||
984 | } else { | ||
985 | dev_dbg(codec->dev, "Disabling beep\n"); | ||
986 | snd_soc_dapm_disable_pin(dapm, "Beep"); | ||
987 | } | ||
988 | |||
989 | snd_soc_update_bits(codec, CS42L52_BEEP_FREQ, | ||
990 | CS42L52_BEEP_RATE_MASK, val); | ||
991 | |||
992 | snd_soc_dapm_sync(dapm); | ||
993 | } | ||
994 | |||
995 | /* For usability define a way of injecting beep events for the device - | ||
996 | * many systems will not have a keyboard. | ||
997 | */ | ||
998 | static int cs42l52_beep_event(struct input_dev *dev, unsigned int type, | ||
999 | unsigned int code, int hz) | ||
1000 | { | ||
1001 | struct snd_soc_codec *codec = input_get_drvdata(dev); | ||
1002 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | ||
1003 | |||
1004 | dev_dbg(codec->dev, "Beep event %x %x\n", code, hz); | ||
1005 | |||
1006 | switch (code) { | ||
1007 | case SND_BELL: | ||
1008 | if (hz) | ||
1009 | hz = 261; | ||
1010 | case SND_TONE: | ||
1011 | break; | ||
1012 | default: | ||
1013 | return -1; | ||
1014 | } | ||
1015 | |||
1016 | /* Kick the beep from a workqueue */ | ||
1017 | cs42l52->beep_rate = hz; | ||
1018 | schedule_work(&cs42l52->beep_work); | ||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | static ssize_t cs42l52_beep_set(struct device *dev, | ||
1023 | struct device_attribute *attr, | ||
1024 | const char *buf, size_t count) | ||
1025 | { | ||
1026 | struct cs42l52_private *cs42l52 = dev_get_drvdata(dev); | ||
1027 | long int time; | ||
1028 | int ret; | ||
1029 | |||
1030 | ret = kstrtol(buf, 10, &time); | ||
1031 | if (ret != 0) | ||
1032 | return ret; | ||
1033 | |||
1034 | input_event(cs42l52->beep, EV_SND, SND_TONE, time); | ||
1035 | |||
1036 | return count; | ||
1037 | } | ||
1038 | |||
1039 | static DEVICE_ATTR(beep, 0200, NULL, cs42l52_beep_set); | ||
1040 | |||
1041 | static void cs42l52_init_beep(struct snd_soc_codec *codec) | ||
1042 | { | ||
1043 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | ||
1044 | int ret; | ||
1045 | |||
1046 | cs42l52->beep = input_allocate_device(); | ||
1047 | if (!cs42l52->beep) { | ||
1048 | dev_err(codec->dev, "Failed to allocate beep device\n"); | ||
1049 | return; | ||
1050 | } | ||
1051 | |||
1052 | INIT_WORK(&cs42l52->beep_work, cs42l52_beep_work); | ||
1053 | cs42l52->beep_rate = 0; | ||
1054 | |||
1055 | cs42l52->beep->name = "CS42L52 Beep Generator"; | ||
1056 | cs42l52->beep->phys = dev_name(codec->dev); | ||
1057 | cs42l52->beep->id.bustype = BUS_I2C; | ||
1058 | |||
1059 | cs42l52->beep->evbit[0] = BIT_MASK(EV_SND); | ||
1060 | cs42l52->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); | ||
1061 | cs42l52->beep->event = cs42l52_beep_event; | ||
1062 | cs42l52->beep->dev.parent = codec->dev; | ||
1063 | input_set_drvdata(cs42l52->beep, codec); | ||
1064 | |||
1065 | ret = input_register_device(cs42l52->beep); | ||
1066 | if (ret != 0) { | ||
1067 | input_free_device(cs42l52->beep); | ||
1068 | cs42l52->beep = NULL; | ||
1069 | dev_err(codec->dev, "Failed to register beep device\n"); | ||
1070 | } | ||
1071 | |||
1072 | ret = device_create_file(codec->dev, &dev_attr_beep); | ||
1073 | if (ret != 0) { | ||
1074 | dev_err(codec->dev, "Failed to create keyclick file: %d\n", | ||
1075 | ret); | ||
1076 | } | ||
1077 | } | ||
1078 | |||
1079 | static void cs42l52_free_beep(struct snd_soc_codec *codec) | ||
1080 | { | ||
1081 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | ||
1082 | |||
1083 | device_remove_file(codec->dev, &dev_attr_beep); | ||
1084 | input_unregister_device(cs42l52->beep); | ||
1085 | cancel_work_sync(&cs42l52->beep_work); | ||
1086 | cs42l52->beep = NULL; | ||
1087 | |||
1088 | snd_soc_update_bits(codec, CS42L52_BEEP_TONE_CTL, | ||
1089 | CS42L52_BEEP_EN_MASK, 0); | ||
1090 | } | ||
1091 | #else | ||
1092 | static void cs42l52_init_beep(struct snd_soc_codec *codec) | ||
1093 | { | ||
1094 | } | ||
1095 | |||
1096 | static void cs42l52_free_beep(struct snd_soc_codec *codec) | ||
1097 | { | ||
1098 | } | ||
1099 | #endif | ||
1100 | |||
1101 | static int cs42l52_probe(struct snd_soc_codec *codec) | ||
1102 | { | ||
1103 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | ||
1104 | int ret; | ||
1105 | |||
1106 | codec->control_data = cs42l52->regmap; | ||
1107 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1108 | if (ret < 0) { | ||
1109 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1110 | return ret; | ||
1111 | } | ||
1112 | regcache_cache_only(cs42l52->regmap, true); | ||
1113 | |||
1114 | cs42l52_init_beep(codec); | ||
1115 | |||
1116 | cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1117 | |||
1118 | cs42l52->sysclk = CS42L52_DEFAULT_CLK; | ||
1119 | cs42l52->config.format = CS42L52_DEFAULT_FORMAT; | ||
1120 | |||
1121 | /* Set Platform MICx CFG */ | ||
1122 | snd_soc_update_bits(codec, CS42L52_MICA_CTL, | ||
1123 | CS42L52_MIC_CTL_TYPE_MASK, | ||
1124 | cs42l52->pdata.mica_cfg << | ||
1125 | CS42L52_MIC_CTL_TYPE_SHIFT); | ||
1126 | |||
1127 | snd_soc_update_bits(codec, CS42L52_MICB_CTL, | ||
1128 | CS42L52_MIC_CTL_TYPE_MASK, | ||
1129 | cs42l52->pdata.micb_cfg << | ||
1130 | CS42L52_MIC_CTL_TYPE_SHIFT); | ||
1131 | |||
1132 | /* if Single Ended, Get Mic_Select */ | ||
1133 | if (cs42l52->pdata.mica_cfg) | ||
1134 | snd_soc_update_bits(codec, CS42L52_MICA_CTL, | ||
1135 | CS42L52_MIC_CTL_MIC_SEL_MASK, | ||
1136 | cs42l52->pdata.mica_sel << | ||
1137 | CS42L52_MIC_CTL_MIC_SEL_SHIFT); | ||
1138 | if (cs42l52->pdata.micb_cfg) | ||
1139 | snd_soc_update_bits(codec, CS42L52_MICB_CTL, | ||
1140 | CS42L52_MIC_CTL_MIC_SEL_MASK, | ||
1141 | cs42l52->pdata.micb_sel << | ||
1142 | CS42L52_MIC_CTL_MIC_SEL_SHIFT); | ||
1143 | |||
1144 | /* Set Platform Charge Pump Freq */ | ||
1145 | snd_soc_update_bits(codec, CS42L52_CHARGE_PUMP, | ||
1146 | CS42L52_CHARGE_PUMP_MASK, | ||
1147 | cs42l52->pdata.chgfreq << | ||
1148 | CS42L52_CHARGE_PUMP_SHIFT); | ||
1149 | |||
1150 | /* Set Platform Bias Level */ | ||
1151 | snd_soc_update_bits(codec, CS42L52_IFACE_CTL2, | ||
1152 | CS42L52_IFACE_CTL2_BIAS_LVL, | ||
1153 | cs42l52->pdata.micbias_lvl); | ||
1154 | |||
1155 | return ret; | ||
1156 | } | ||
1157 | |||
1158 | static int cs42l52_remove(struct snd_soc_codec *codec) | ||
1159 | { | ||
1160 | cs42l52_free_beep(codec); | ||
1161 | cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1162 | |||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | struct snd_soc_codec_driver soc_codec_dev_cs42l52 = { | ||
1167 | .probe = cs42l52_probe, | ||
1168 | .remove = cs42l52_remove, | ||
1169 | .suspend = cs42l52_suspend, | ||
1170 | .resume = cs42l52_resume, | ||
1171 | .set_bias_level = cs42l52_set_bias_level, | ||
1172 | |||
1173 | .dapm_widgets = cs42l52_dapm_widgets, | ||
1174 | .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets), | ||
1175 | .dapm_routes = cs42l52_audio_map, | ||
1176 | .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map), | ||
1177 | |||
1178 | .controls = cs42l52_snd_controls, | ||
1179 | .num_controls = ARRAY_SIZE(cs42l52_snd_controls), | ||
1180 | }; | ||
1181 | |||
1182 | /* Current and threshold powerup sequence Pg37 */ | ||
1183 | static const struct reg_default cs42l52_threshold_patch[] = { | ||
1184 | |||
1185 | { 0x00, 0x99 }, | ||
1186 | { 0x3E, 0xBA }, | ||
1187 | { 0x47, 0x80 }, | ||
1188 | { 0x32, 0xBB }, | ||
1189 | { 0x32, 0x3B }, | ||
1190 | { 0x00, 0x00 }, | ||
1191 | |||
1192 | }; | ||
1193 | |||
1194 | static struct regmap_config cs42l52_regmap = { | ||
1195 | .reg_bits = 8, | ||
1196 | .val_bits = 8, | ||
1197 | |||
1198 | .max_register = CS42L52_MAX_REGISTER, | ||
1199 | .reg_defaults = cs42l52_reg_defaults, | ||
1200 | .num_reg_defaults = ARRAY_SIZE(cs42l52_reg_defaults), | ||
1201 | .readable_reg = cs42l52_readable_register, | ||
1202 | .volatile_reg = cs42l52_volatile_register, | ||
1203 | .cache_type = REGCACHE_RBTREE, | ||
1204 | }; | ||
1205 | |||
1206 | static int cs42l52_i2c_probe(struct i2c_client *i2c_client, | ||
1207 | const struct i2c_device_id *id) | ||
1208 | { | ||
1209 | struct cs42l52_private *cs42l52; | ||
1210 | int ret; | ||
1211 | unsigned int devid = 0; | ||
1212 | unsigned int reg; | ||
1213 | |||
1214 | cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l52_private), | ||
1215 | GFP_KERNEL); | ||
1216 | if (cs42l52 == NULL) | ||
1217 | return -ENOMEM; | ||
1218 | cs42l52->dev = &i2c_client->dev; | ||
1219 | |||
1220 | cs42l52->regmap = regmap_init_i2c(i2c_client, &cs42l52_regmap); | ||
1221 | if (IS_ERR(cs42l52->regmap)) { | ||
1222 | ret = PTR_ERR(cs42l52->regmap); | ||
1223 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); | ||
1224 | goto err; | ||
1225 | } | ||
1226 | |||
1227 | i2c_set_clientdata(i2c_client, cs42l52); | ||
1228 | |||
1229 | if (dev_get_platdata(&i2c_client->dev)) | ||
1230 | memcpy(&cs42l52->pdata, dev_get_platdata(&i2c_client->dev), | ||
1231 | sizeof(cs42l52->pdata)); | ||
1232 | |||
1233 | ret = regmap_register_patch(cs42l52->regmap, cs42l52_threshold_patch, | ||
1234 | ARRAY_SIZE(cs42l52_threshold_patch)); | ||
1235 | if (ret != 0) | ||
1236 | dev_warn(cs42l52->dev, "Failed to apply regmap patch: %d\n", | ||
1237 | ret); | ||
1238 | |||
1239 | ret = regmap_read(cs42l52->regmap, CS42L52_CHIP, ®); | ||
1240 | devid = reg & CS42L52_CHIP_ID_MASK; | ||
1241 | if (devid != CS42L52_CHIP_ID) { | ||
1242 | ret = -ENODEV; | ||
1243 | dev_err(&i2c_client->dev, | ||
1244 | "CS42L52 Device ID (%X). Expected %X\n", | ||
1245 | devid, CS42L52_CHIP_ID); | ||
1246 | goto err_regmap; | ||
1247 | } | ||
1248 | |||
1249 | regcache_cache_only(cs42l52->regmap, true); | ||
1250 | |||
1251 | ret = snd_soc_register_codec(&i2c_client->dev, | ||
1252 | &soc_codec_dev_cs42l52, &cs42l52_dai, 1); | ||
1253 | if (ret < 0) | ||
1254 | goto err_regmap; | ||
1255 | return 0; | ||
1256 | |||
1257 | err_regmap: | ||
1258 | regmap_exit(cs42l52->regmap); | ||
1259 | |||
1260 | err: | ||
1261 | return ret; | ||
1262 | } | ||
1263 | |||
1264 | static int cs42l52_i2c_remove(struct i2c_client *client) | ||
1265 | { | ||
1266 | struct cs42l52_private *cs42l52 = i2c_get_clientdata(client); | ||
1267 | |||
1268 | snd_soc_unregister_codec(&client->dev); | ||
1269 | regmap_exit(cs42l52->regmap); | ||
1270 | |||
1271 | return 0; | ||
1272 | } | ||
1273 | |||
1274 | static const struct i2c_device_id cs42l52_id[] = { | ||
1275 | { "cs42l52", 0 }, | ||
1276 | { } | ||
1277 | }; | ||
1278 | MODULE_DEVICE_TABLE(i2c, cs42l52_id); | ||
1279 | |||
1280 | static struct i2c_driver cs42l52_i2c_driver = { | ||
1281 | .driver = { | ||
1282 | .name = "cs42l52", | ||
1283 | .owner = THIS_MODULE, | ||
1284 | }, | ||
1285 | .id_table = cs42l52_id, | ||
1286 | .probe = cs42l52_i2c_probe, | ||
1287 | .remove = __devexit_p(cs42l52_i2c_remove), | ||
1288 | }; | ||
1289 | |||
1290 | static void __exit cs42l52_exit(void) | ||
1291 | { | ||
1292 | i2c_del_driver(&cs42l52_i2c_driver); | ||
1293 | } | ||
1294 | |||
1295 | module_exit(cs42l52_exit); | ||
1296 | |||
1297 | module_i2c_driver(cs42l52_i2c_driver); | ||
1298 | |||
1299 | MODULE_DESCRIPTION("ASoC CS42L52 driver"); | ||
1300 | MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>"); | ||
1301 | MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); | ||
1302 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/cs42l52.h b/sound/soc/codecs/cs42l52.h new file mode 100644 index 000000000000..60985c059071 --- /dev/null +++ b/sound/soc/codecs/cs42l52.h | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * cs42l52.h -- CS42L52 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2012 CirrusLogic, Inc. | ||
5 | * | ||
6 | * Author: Georgi Vlaev <joe@nucleusys.com> | ||
7 | * Author: Brian Austin <brian.austin@cirrus.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #ifndef __CS42L52_H__ | ||
16 | #define __CS42L52_H__ | ||
17 | |||
18 | #define CS42L52_NAME "CS42L52" | ||
19 | #define CS42L52_DEFAULT_CLK 12000000 | ||
20 | #define CS42L52_MIN_CLK 11000000 | ||
21 | #define CS42L52_MAX_CLK 27000000 | ||
22 | #define CS42L52_DEFAULT_FORMAT SNDRV_PCM_FMTBIT_S16_LE | ||
23 | #define CS42L52_DEFAULT_MAX_CHANS 2 | ||
24 | #define CS42L52_SYSCLK 1 | ||
25 | |||
26 | #define CS42L52_CHIP_SWICTH (1 << 17) | ||
27 | #define CS42L52_ALL_IN_ONE (1 << 16) | ||
28 | #define CS42L52_CHIP_ONE 0x00 | ||
29 | #define CS42L52_CHIP_TWO 0x01 | ||
30 | #define CS42L52_CHIP_THR 0x02 | ||
31 | #define CS42L52_CHIP_MASK 0x0f | ||
32 | |||
33 | #define CS42L52_FIX_BITS_CTL 0x00 | ||
34 | #define CS42L52_CHIP 0x01 | ||
35 | #define CS42L52_CHIP_ID 0xE0 | ||
36 | #define CS42L52_CHIP_ID_MASK 0xF8 | ||
37 | #define CS42L52_CHIP_REV_A0 0x00 | ||
38 | #define CS42L52_CHIP_REV_A1 0x01 | ||
39 | #define CS42L52_CHIP_REV_B0 0x02 | ||
40 | #define CS42L52_CHIP_REV_MASK 0x03 | ||
41 | |||
42 | #define CS42L52_PWRCTL1 0x02 | ||
43 | #define CS42L52_PWRCTL1_PDN_ALL 0x9F | ||
44 | #define CS42L52_PWRCTL1_PDN_CHRG 0x80 | ||
45 | #define CS42L52_PWRCTL1_PDN_PGAB 0x10 | ||
46 | #define CS42L52_PWRCTL1_PDN_PGAA 0x08 | ||
47 | #define CS42L52_PWRCTL1_PDN_ADCB 0x04 | ||
48 | #define CS42L52_PWRCTL1_PDN_ADCA 0x02 | ||
49 | #define CS42L52_PWRCTL1_PDN_CODEC 0x01 | ||
50 | |||
51 | #define CS42L52_PWRCTL2 0x03 | ||
52 | #define CS42L52_PWRCTL2_OVRDB (1 << 4) | ||
53 | #define CS42L52_PWRCTL2_OVRDA (1 << 3) | ||
54 | #define CS42L52_PWRCTL2_PDN_MICB (1 << 2) | ||
55 | #define CS42L52_PWRCTL2_PDN_MICB_SHIFT 2 | ||
56 | #define CS42L52_PWRCTL2_PDN_MICA (1 << 1) | ||
57 | #define CS42L52_PWRCTL2_PDN_MICA_SHIFT 1 | ||
58 | #define CS42L52_PWRCTL2_PDN_MICBIAS (1 << 0) | ||
59 | #define CS42L52_PWRCTL2_PDN_MICBIAS_SHIFT 0 | ||
60 | |||
61 | #define CS42L52_PWRCTL3 0x04 | ||
62 | #define CS42L52_PWRCTL3_HPB_PDN_SHIFT 6 | ||
63 | #define CS42L52_PWRCTL3_HPB_ON_LOW 0x00 | ||
64 | #define CS42L52_PWRCTL3_HPB_ON_HIGH 0x01 | ||
65 | #define CS42L52_PWRCTL3_HPB_ALWAYS_ON 0x02 | ||
66 | #define CS42L52_PWRCTL3_HPB_ALWAYS_OFF 0x03 | ||
67 | #define CS42L52_PWRCTL3_HPA_PDN_SHIFT 4 | ||
68 | #define CS42L52_PWRCTL3_HPA_ON_LOW 0x00 | ||
69 | #define CS42L52_PWRCTL3_HPA_ON_HIGH 0x01 | ||
70 | #define CS42L52_PWRCTL3_HPA_ALWAYS_ON 0x02 | ||
71 | #define CS42L52_PWRCTL3_HPA_ALWAYS_OFF 0x03 | ||
72 | #define CS42L52_PWRCTL3_SPKB_PDN_SHIFT 2 | ||
73 | #define CS42L52_PWRCTL3_SPKB_ON_LOW 0x00 | ||
74 | #define CS42L52_PWRCTL3_SPKB_ON_HIGH 0x01 | ||
75 | #define CS42L52_PWRCTL3_SPKB_ALWAYS_ON 0x02 | ||
76 | #define CS42L52_PWRCTL3_PDN_SPKB (1 << 2) | ||
77 | #define CS42L52_PWRCTL3_PDN_SPKA (1 << 0) | ||
78 | #define CS42L52_PWRCTL3_SPKA_PDN_SHIFT 0 | ||
79 | #define CS42L52_PWRCTL3_SPKA_ON_LOW 0x00 | ||
80 | #define CS42L52_PWRCTL3_SPKA_ON_HIGH 0x01 | ||
81 | #define CS42L52_PWRCTL3_SPKA_ALWAYS_ON 0x02 | ||
82 | |||
83 | #define CS42L52_DEFAULT_OUTPUT_STATE 0x05 | ||
84 | #define CS42L52_PWRCTL3_CONF_MASK 0x03 | ||
85 | |||
86 | #define CS42L52_CLK_CTL 0x05 | ||
87 | #define CLK_AUTODECT_ENABLE (1 << 7) | ||
88 | #define CLK_SPEED_SHIFT 5 | ||
89 | #define CLK_DS_MODE 0x00 | ||
90 | #define CLK_SS_MODE 0x01 | ||
91 | #define CLK_HS_MODE 0x02 | ||
92 | #define CLK_QS_MODE 0x03 | ||
93 | #define CLK_32K_SR_SHIFT 4 | ||
94 | #define CLK_32K 0x01 | ||
95 | #define CLK_NO_32K 0x00 | ||
96 | #define CLK_27M_MCLK_SHIFT 3 | ||
97 | #define CLK_27M_MCLK 0x01 | ||
98 | #define CLK_NO_27M 0x00 | ||
99 | #define CLK_RATIO_SHIFT 1 | ||
100 | #define CLK_R_128 0x00 | ||
101 | #define CLK_R_125 0x01 | ||
102 | #define CLK_R_132 0x02 | ||
103 | #define CLK_R_136 0x03 | ||
104 | |||
105 | #define CS42L52_IFACE_CTL1 0x06 | ||
106 | #define CS42L52_IFACE_CTL1_MASTER (1 << 7) | ||
107 | #define CS42L52_IFACE_CTL1_SLAVE (0 << 7) | ||
108 | #define CS42L52_IFACE_CTL1_INV_SCLK (1 << 6) | ||
109 | #define CS42L52_IFACE_CTL1_ADC_FMT_I2S (1 << 5) | ||
110 | #define CS42L52_IFACE_CTL1_ADC_FMT_LEFT_J (0 << 5) | ||
111 | #define CS42L52_IFACE_CTL1_DSP_MODE_EN (1 << 4) | ||
112 | #define CS42L52_IFACE_CTL1_DAC_FMT_LEFT_J (0 << 2) | ||
113 | #define CS42L52_IFACE_CTL1_DAC_FMT_I2S (1 << 2) | ||
114 | #define CS42L52_IFACE_CTL1_DAC_FMT_RIGHT_J (2 << 2) | ||
115 | #define CS42L52_IFACE_CTL1_WL_32BIT (0x00) | ||
116 | #define CS42L52_IFACE_CTL1_WL_24BIT (0x01) | ||
117 | #define CS42L52_IFACE_CTL1_WL_20BIT (0x02) | ||
118 | #define CS42L52_IFACE_CTL1_WL_16BIT (0x03) | ||
119 | #define CS42L52_IFACE_CTL1_WL_MASK 0xFFFF | ||
120 | |||
121 | #define CS42L52_IFACE_CTL2 0x07 | ||
122 | #define CS42L52_IFACE_CTL2_SC_MC_EQ (1 << 6) | ||
123 | #define CS42L52_IFACE_CTL2_LOOPBACK (1 << 5) | ||
124 | #define CS42L52_IFACE_CTL2_S_MODE_OUTPUT_EN (0 << 4) | ||
125 | #define CS42L52_IFACE_CTL2_S_MODE_OUTPUT_HIZ (1 << 4) | ||
126 | #define CS42L52_IFACE_CTL2_HP_SW_INV (1 << 3) | ||
127 | #define CS42L52_IFACE_CTL2_BIAS_LVL 0x07 | ||
128 | |||
129 | #define CS42L52_ADC_PGA_A 0x08 | ||
130 | #define CS42L52_ADC_PGA_B 0x09 | ||
131 | #define CS42L52_ADC_SEL_SHIFT 5 | ||
132 | #define CS42L52_ADC_SEL_AIN1 0x00 | ||
133 | #define CS42L52_ADC_SEL_AIN2 0x01 | ||
134 | #define CS42L52_ADC_SEL_AIN3 0x02 | ||
135 | #define CS42L52_ADC_SEL_AIN4 0x03 | ||
136 | #define CS42L52_ADC_SEL_PGA 0x04 | ||
137 | |||
138 | #define CS42L52_ANALOG_HPF_CTL 0x0A | ||
139 | #define CS42L52_HPF_CTL_ANLGSFTB (1 << 3) | ||
140 | #define CS42L52_HPF_CTL_ANLGSFTA (1 << 0) | ||
141 | |||
142 | #define CS42L52_ADC_HPF_FREQ 0x0B | ||
143 | #define CS42L52_ADC_MISC_CTL 0x0C | ||
144 | #define CS42L52_ADC_MISC_CTL_SOURCE_DSP (1 << 6) | ||
145 | |||
146 | #define CS42L52_PB_CTL1 0x0D | ||
147 | #define CS42L52_PB_CTL1_HP_GAIN_SHIFT 5 | ||
148 | #define CS42L52_PB_CTL1_HP_GAIN_03959 0x00 | ||
149 | #define CS42L52_PB_CTL1_HP_GAIN_04571 0x01 | ||
150 | #define CS42L52_PB_CTL1_HP_GAIN_05111 0x02 | ||
151 | #define CS42L52_PB_CTL1_HP_GAIN_06047 0x03 | ||
152 | #define CS42L52_PB_CTL1_HP_GAIN_07099 0x04 | ||
153 | #define CS42L52_PB_CTL1_HP_GAIN_08399 0x05 | ||
154 | #define CS42L52_PB_CTL1_HP_GAIN_10000 0x06 | ||
155 | #define CS42L52_PB_CTL1_HP_GAIN_11430 0x07 | ||
156 | #define CS42L52_PB_CTL1_INV_PCMB (1 << 3) | ||
157 | #define CS42L52_PB_CTL1_INV_PCMA (1 << 2) | ||
158 | #define CS42L52_PB_CTL1_MSTB_MUTE (1 << 1) | ||
159 | #define CS42L52_PB_CTL1_MSTA_MUTE (1 << 0) | ||
160 | #define CS42L52_PB_CTL1_MUTE_MASK 0xFFFD | ||
161 | #define CS42L52_PB_CTL1_MUTE 3 | ||
162 | #define CS42L52_PB_CTL1_UNMUTE 0 | ||
163 | |||
164 | #define CS42L52_MISC_CTL 0x0E | ||
165 | #define CS42L52_MISC_CTL_DEEMPH (1 << 2) | ||
166 | #define CS42L52_MISC_CTL_DIGSFT (1 << 1) | ||
167 | #define CS42L52_MISC_CTL_DIGZC (1 << 0) | ||
168 | |||
169 | #define CS42L52_PB_CTL2 0x0F | ||
170 | #define CS42L52_PB_CTL2_HPB_MUTE (1 << 7) | ||
171 | #define CS42L52_PB_CTL2_HPA_MUTE (1 << 6) | ||
172 | #define CS42L52_PB_CTL2_SPKB_MUTE (1 << 5) | ||
173 | #define CS42L52_PB_CTL2_SPKA_MUTE (1 << 4) | ||
174 | #define CS42L52_PB_CTL2_SPK_SWAP (1 << 2) | ||
175 | #define CS42L52_PB_CTL2_SPK_MONO (1 << 1) | ||
176 | #define CS42L52_PB_CTL2_SPK_MUTE50 (1 << 0) | ||
177 | |||
178 | #define CS42L52_MICA_CTL 0x10 | ||
179 | #define CS42L52_MICB_CTL 0x11 | ||
180 | #define CS42L52_MIC_CTL_MIC_SEL_MASK 0xBF | ||
181 | #define CS42L52_MIC_CTL_MIC_SEL_SHIFT 6 | ||
182 | #define CS42L52_MIC_CTL_TYPE_MASK 0xDF | ||
183 | #define CS42L52_MIC_CTL_TYPE_SHIFT 5 | ||
184 | |||
185 | |||
186 | #define CS42L52_PGAA_CTL 0x12 | ||
187 | #define CS42L52_PGAB_CTL 0x13 | ||
188 | #define CS42L52_PGAX_CTL_VOL_12DB 24 | ||
189 | #define CS42L52_PGAX_CTL_VOL_6DB 12 /*step size 0.5db*/ | ||
190 | |||
191 | #define CS42L52_PASSTHRUA_VOL 0x14 | ||
192 | #define CS42L52_PASSTHRUB_VOL 0x15 | ||
193 | |||
194 | #define CS42L52_ADCA_VOL 0x16 | ||
195 | #define CS42L52_ADCB_VOL 0x17 | ||
196 | #define CS42L52_ADCX_VOL_24DB 24 /*step size 1db*/ | ||
197 | #define CS42L52_ADCX_VOL_12DB 12 | ||
198 | #define CS42L52_ADCX_VOL_6DB 6 | ||
199 | |||
200 | #define CS42L52_ADCA_MIXER_VOL 0x18 | ||
201 | #define CS42L52_ADCB_MIXER_VOL 0x19 | ||
202 | #define CS42L52_ADC_MIXER_VOL_12DB 0x18 | ||
203 | |||
204 | #define CS42L52_PCMA_MIXER_VOL 0x1A | ||
205 | #define CS42L52_PCMB_MIXER_VOL 0x1B | ||
206 | |||
207 | #define CS42L52_BEEP_FREQ 0x1C | ||
208 | #define CS42L52_BEEP_VOL 0x1D | ||
209 | #define CS42L52_BEEP_TONE_CTL 0x1E | ||
210 | #define CS42L52_BEEP_RATE_SHIFT 4 | ||
211 | #define CS42L52_BEEP_RATE_MASK 0x0F | ||
212 | |||
213 | #define CS42L52_TONE_CTL 0x1F | ||
214 | #define CS42L52_BEEP_EN_MASK 0x3F | ||
215 | |||
216 | #define CS42L52_MASTERA_VOL 0x20 | ||
217 | #define CS42L52_MASTERB_VOL 0x21 | ||
218 | |||
219 | #define CS42L52_HPA_VOL 0x22 | ||
220 | #define CS42L52_HPB_VOL 0x23 | ||
221 | #define CS42L52_DEFAULT_HP_VOL 0xF0 | ||
222 | |||
223 | #define CS42L52_SPKA_VOL 0x24 | ||
224 | #define CS42L52_SPKB_VOL 0x25 | ||
225 | #define CS42L52_DEFAULT_SPK_VOL 0xF0 | ||
226 | |||
227 | #define CS42L52_ADC_PCM_MIXER 0x26 | ||
228 | |||
229 | #define CS42L52_LIMITER_CTL1 0x27 | ||
230 | #define CS42L52_LIMITER_CTL2 0x28 | ||
231 | #define CS42L52_LIMITER_AT_RATE 0x29 | ||
232 | |||
233 | #define CS42L52_ALC_CTL 0x2A | ||
234 | #define CS42L52_ALC_CTL_ALCB_ENABLE_SHIFT 7 | ||
235 | #define CS42L52_ALC_CTL_ALCA_ENABLE_SHIFT 6 | ||
236 | #define CS42L52_ALC_CTL_FASTEST_ATTACK 0 | ||
237 | |||
238 | #define CS42L52_ALC_RATE 0x2B | ||
239 | #define CS42L52_ALC_SLOWEST_RELEASE 0x3F | ||
240 | |||
241 | #define CS42L52_ALC_THRESHOLD 0x2C | ||
242 | #define CS42L52_ALC_MAX_RATE_SHIFT 5 | ||
243 | #define CS42L52_ALC_MIN_RATE_SHIFT 2 | ||
244 | #define CS42L52_ALC_RATE_0DB 0 | ||
245 | #define CS42L52_ALC_RATE_3DB 1 | ||
246 | #define CS42L52_ALC_RATE_6DB 2 | ||
247 | |||
248 | #define CS42L52_NOISE_GATE_CTL 0x2D | ||
249 | #define CS42L52_NG_ENABLE_SHIFT 6 | ||
250 | #define CS42L52_NG_THRESHOLD_SHIFT 2 | ||
251 | #define CS42L52_NG_MIN_70DB 2 | ||
252 | #define CS42L52_NG_DELAY_SHIFT 0 | ||
253 | #define CS42L52_NG_DELAY_100MS 1 | ||
254 | |||
255 | #define CS42L52_CLK_STATUS 0x2E | ||
256 | #define CS42L52_BATT_COMPEN 0x2F | ||
257 | |||
258 | #define CS42L52_BATT_LEVEL 0x30 | ||
259 | #define CS42L52_SPK_STATUS 0x31 | ||
260 | #define CS42L52_SPK_STATUS_PIN_SHIFT 3 | ||
261 | #define CS42L52_SPK_STATUS_PIN_HIGH 1 | ||
262 | |||
263 | #define CS42L52_TEM_CTL 0x32 | ||
264 | #define CS42L52_TEM_CTL_SET 0x80 | ||
265 | #define CS42L52_THE_FOLDBACK 0x33 | ||
266 | #define CS42L52_CHARGE_PUMP 0x34 | ||
267 | #define CS42L52_CHARGE_PUMP_MASK 0xF0 | ||
268 | #define CS42L52_CHARGE_PUMP_SHIFT 4 | ||
269 | #define CS42L52_FIX_BITS1 0x3E | ||
270 | #define CS42L52_FIX_BITS2 0x47 | ||
271 | |||
272 | #define CS42L52_MAX_REGISTER 0x34 | ||
273 | |||
274 | #endif | ||