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