Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux...
[linux/fpc-iii.git] / sound / soc / codecs / cs42l56.c
blob7cd5f769bb614d207daaf26ca24efb51156d3aca
1 /*
2 * cs42l56.c -- CS42L56 ALSA SoC audio driver
4 * Copyright 2014 CirrusLogic, Inc.
6 * Author: Brian Austin <brian.austin@cirrus.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/delay.h>
19 #include <linux/pm.h>
20 #include <linux/i2c.h>
21 #include <linux/input.h>
22 #include <linux/regmap.h>
23 #include <linux/slab.h>
24 #include <linux/workqueue.h>
25 #include <linux/platform_device.h>
26 #include <linux/regulator/consumer.h>
27 #include <linux/of_device.h>
28 #include <linux/of_gpio.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/cs42l56.h>
37 #include "cs42l56.h"
39 #define CS42L56_NUM_SUPPLIES 3
40 static const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = {
41 "VA",
42 "VCP",
43 "VLDO",
46 struct cs42l56_private {
47 struct regmap *regmap;
48 struct snd_soc_codec *codec;
49 struct device *dev;
50 struct cs42l56_platform_data pdata;
51 struct regulator_bulk_data supplies[CS42L56_NUM_SUPPLIES];
52 u32 mclk;
53 u8 mclk_prediv;
54 u8 mclk_div2;
55 u8 mclk_ratio;
56 u8 iface;
57 u8 iface_fmt;
58 u8 iface_inv;
59 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
60 struct input_dev *beep;
61 struct work_struct beep_work;
62 int beep_rate;
63 #endif
66 static const struct reg_default cs42l56_reg_defaults[] = {
67 { 1, 0x56 }, /* r01 - ID 1 */
68 { 2, 0x04 }, /* r02 - ID 2 */
69 { 3, 0x7f }, /* r03 - Power Ctl 1 */
70 { 4, 0xff }, /* r04 - Power Ctl 2 */
71 { 5, 0x00 }, /* ro5 - Clocking Ctl 1 */
72 { 6, 0x0b }, /* r06 - Clocking Ctl 2 */
73 { 7, 0x00 }, /* r07 - Serial Format */
74 { 8, 0x05 }, /* r08 - Class H Ctl */
75 { 9, 0x0c }, /* r09 - Misc Ctl */
76 { 10, 0x80 }, /* r0a - INT Status */
77 { 11, 0x00 }, /* r0b - Playback Ctl */
78 { 12, 0x0c }, /* r0c - DSP Mute Ctl */
79 { 13, 0x00 }, /* r0d - ADCA Mixer Volume */
80 { 14, 0x00 }, /* r0e - ADCB Mixer Volume */
81 { 15, 0x00 }, /* r0f - PCMA Mixer Volume */
82 { 16, 0x00 }, /* r10 - PCMB Mixer Volume */
83 { 17, 0x00 }, /* r11 - Analog Input Advisory Volume */
84 { 18, 0x00 }, /* r12 - Digital Input Advisory Volume */
85 { 19, 0x00 }, /* r13 - Master A Volume */
86 { 20, 0x00 }, /* r14 - Master B Volume */
87 { 21, 0x00 }, /* r15 - Beep Freq / On Time */
88 { 22, 0x00 }, /* r16 - Beep Volume / Off Time */
89 { 23, 0x00 }, /* r17 - Beep Tone Ctl */
90 { 24, 0x88 }, /* r18 - Tone Ctl */
91 { 25, 0x00 }, /* r19 - Channel Mixer & Swap */
92 { 26, 0x00 }, /* r1a - AIN Ref Config / ADC Mux */
93 { 27, 0xa0 }, /* r1b - High-Pass Filter Ctl */
94 { 28, 0x00 }, /* r1c - Misc ADC Ctl */
95 { 29, 0x00 }, /* r1d - Gain & Bias Ctl */
96 { 30, 0x00 }, /* r1e - PGAA Mux & Volume */
97 { 31, 0x00 }, /* r1f - PGAB Mux & Volume */
98 { 32, 0x00 }, /* r20 - ADCA Attenuator */
99 { 33, 0x00 }, /* r21 - ADCB Attenuator */
100 { 34, 0x00 }, /* r22 - ALC Enable & Attack Rate */
101 { 35, 0xbf }, /* r23 - ALC Release Rate */
102 { 36, 0x00 }, /* r24 - ALC Threshold */
103 { 37, 0x00 }, /* r25 - Noise Gate Ctl */
104 { 38, 0x00 }, /* r26 - ALC, Limiter, SFT, ZeroCross */
105 { 39, 0x00 }, /* r27 - Analog Mute, LO & HP Mux */
106 { 40, 0x00 }, /* r28 - HP A Volume */
107 { 41, 0x00 }, /* r29 - HP B Volume */
108 { 42, 0x00 }, /* r2a - LINEOUT A Volume */
109 { 43, 0x00 }, /* r2b - LINEOUT B Volume */
110 { 44, 0x00 }, /* r2c - Limit Threshold Ctl */
111 { 45, 0x7f }, /* r2d - Limiter Ctl & Release Rate */
112 { 46, 0x00 }, /* r2e - Limiter Attack Rate */
115 static bool cs42l56_readable_register(struct device *dev, unsigned int reg)
117 switch (reg) {
118 case CS42L56_CHIP_ID_1 ... CS42L56_LIM_ATTACK_RATE:
119 return true;
120 default:
121 return false;
125 static bool cs42l56_volatile_register(struct device *dev, unsigned int reg)
127 switch (reg) {
128 case CS42L56_INT_STATUS:
129 return true;
130 default:
131 return false;
135 static DECLARE_TLV_DB_SCALE(beep_tlv, -5000, 200, 0);
136 static DECLARE_TLV_DB_SCALE(hl_tlv, -6000, 50, 0);
137 static DECLARE_TLV_DB_SCALE(adv_tlv, -10200, 50, 0);
138 static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, 0);
139 static DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
140 static DECLARE_TLV_DB_SCALE(preamp_tlv, 0, 1000, 0);
141 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
143 static const DECLARE_TLV_DB_RANGE(ngnb_tlv,
144 0, 1, TLV_DB_SCALE_ITEM(-8200, 600, 0),
145 2, 5, TLV_DB_SCALE_ITEM(-7600, 300, 0)
147 static const DECLARE_TLV_DB_RANGE(ngb_tlv,
148 0, 2, TLV_DB_SCALE_ITEM(-6400, 600, 0),
149 3, 7, TLV_DB_SCALE_ITEM(-4600, 300, 0)
151 static const DECLARE_TLV_DB_RANGE(alc_tlv,
152 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
153 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0)
156 static const char * const beep_config_text[] = {
157 "Off", "Single", "Multiple", "Continuous"
160 static const struct soc_enum beep_config_enum =
161 SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 6,
162 ARRAY_SIZE(beep_config_text), beep_config_text);
164 static const char * const beep_pitch_text[] = {
165 "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
166 "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
169 static const struct soc_enum beep_pitch_enum =
170 SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 4,
171 ARRAY_SIZE(beep_pitch_text), beep_pitch_text);
173 static const char * const beep_ontime_text[] = {
174 "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
175 "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s",
176 "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
179 static const struct soc_enum beep_ontime_enum =
180 SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 0,
181 ARRAY_SIZE(beep_ontime_text), beep_ontime_text);
183 static const char * const beep_offtime_text[] = {
184 "1.23 s", "2.58 s", "3.90 s", "5.20 s",
185 "6.60 s", "8.05 s", "9.35 s", "10.80 s"
188 static const struct soc_enum beep_offtime_enum =
189 SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_OFFTIME, 5,
190 ARRAY_SIZE(beep_offtime_text), beep_offtime_text);
192 static const char * const beep_treble_text[] = {
193 "5kHz", "7kHz", "10kHz", "15kHz"
196 static const struct soc_enum beep_treble_enum =
197 SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 3,
198 ARRAY_SIZE(beep_treble_text), beep_treble_text);
200 static const char * const beep_bass_text[] = {
201 "50Hz", "100Hz", "200Hz", "250Hz"
204 static const struct soc_enum beep_bass_enum =
205 SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1,
206 ARRAY_SIZE(beep_bass_text), beep_bass_text);
208 static const char * const adc_swap_text[] = {
209 "None", "A+B/2", "A-B/2", "Swap"
212 static const struct soc_enum adc_swap_enum =
213 SOC_ENUM_SINGLE(CS42L56_MISC_ADC_CTL, 3,
214 ARRAY_SIZE(adc_swap_text), adc_swap_text);
216 static const char * const pgaa_mux_text[] = {
217 "AIN1A", "AIN2A", "AIN3A"};
219 static const struct soc_enum pgaa_mux_enum =
220 SOC_ENUM_SINGLE(CS42L56_PGAA_MUX_VOLUME, 0,
221 ARRAY_SIZE(pgaa_mux_text),
222 pgaa_mux_text);
224 static const struct snd_kcontrol_new pgaa_mux =
225 SOC_DAPM_ENUM("Route", pgaa_mux_enum);
227 static const char * const pgab_mux_text[] = {
228 "AIN1B", "AIN2B", "AIN3B"};
230 static const struct soc_enum pgab_mux_enum =
231 SOC_ENUM_SINGLE(CS42L56_PGAB_MUX_VOLUME, 0,
232 ARRAY_SIZE(pgab_mux_text),
233 pgab_mux_text);
235 static const struct snd_kcontrol_new pgab_mux =
236 SOC_DAPM_ENUM("Route", pgab_mux_enum);
238 static const char * const adca_mux_text[] = {
239 "PGAA", "AIN1A", "AIN2A", "AIN3A"};
241 static const struct soc_enum adca_mux_enum =
242 SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 0,
243 ARRAY_SIZE(adca_mux_text),
244 adca_mux_text);
246 static const struct snd_kcontrol_new adca_mux =
247 SOC_DAPM_ENUM("Route", adca_mux_enum);
249 static const char * const adcb_mux_text[] = {
250 "PGAB", "AIN1B", "AIN2B", "AIN3B"};
252 static const struct soc_enum adcb_mux_enum =
253 SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 2,
254 ARRAY_SIZE(adcb_mux_text),
255 adcb_mux_text);
257 static const struct snd_kcontrol_new adcb_mux =
258 SOC_DAPM_ENUM("Route", adcb_mux_enum);
260 static const char * const left_swap_text[] = {
261 "Left", "LR 2", "Right"};
263 static const char * const right_swap_text[] = {
264 "Right", "LR 2", "Left"};
266 static const unsigned int swap_values[] = { 0, 1, 3 };
268 static const struct soc_enum adca_swap_enum =
269 SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 0, 3,
270 ARRAY_SIZE(left_swap_text),
271 left_swap_text,
272 swap_values);
273 static const struct snd_kcontrol_new adca_swap_mux =
274 SOC_DAPM_ENUM("Route", adca_swap_enum);
276 static const struct soc_enum pcma_swap_enum =
277 SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 4, 3,
278 ARRAY_SIZE(left_swap_text),
279 left_swap_text,
280 swap_values);
281 static const struct snd_kcontrol_new pcma_swap_mux =
282 SOC_DAPM_ENUM("Route", pcma_swap_enum);
284 static const struct soc_enum adcb_swap_enum =
285 SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 2, 3,
286 ARRAY_SIZE(right_swap_text),
287 right_swap_text,
288 swap_values);
289 static const struct snd_kcontrol_new adcb_swap_mux =
290 SOC_DAPM_ENUM("Route", adcb_swap_enum);
292 static const struct soc_enum pcmb_swap_enum =
293 SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 6, 3,
294 ARRAY_SIZE(right_swap_text),
295 right_swap_text,
296 swap_values);
297 static const struct snd_kcontrol_new pcmb_swap_mux =
298 SOC_DAPM_ENUM("Route", pcmb_swap_enum);
300 static const struct snd_kcontrol_new hpa_switch =
301 SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1);
303 static const struct snd_kcontrol_new hpb_switch =
304 SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 4, 1, 1);
306 static const struct snd_kcontrol_new loa_switch =
307 SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 2, 1, 1);
309 static const struct snd_kcontrol_new lob_switch =
310 SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 0, 1, 1);
312 static const char * const hploa_input_text[] = {
313 "DACA", "PGAA"};
315 static const struct soc_enum lineouta_input_enum =
316 SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 2,
317 ARRAY_SIZE(hploa_input_text),
318 hploa_input_text);
320 static const struct snd_kcontrol_new lineouta_input =
321 SOC_DAPM_ENUM("Route", lineouta_input_enum);
323 static const struct soc_enum hpa_input_enum =
324 SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 0,
325 ARRAY_SIZE(hploa_input_text),
326 hploa_input_text);
328 static const struct snd_kcontrol_new hpa_input =
329 SOC_DAPM_ENUM("Route", hpa_input_enum);
331 static const char * const hplob_input_text[] = {
332 "DACB", "PGAB"};
334 static const struct soc_enum lineoutb_input_enum =
335 SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 3,
336 ARRAY_SIZE(hplob_input_text),
337 hplob_input_text);
339 static const struct snd_kcontrol_new lineoutb_input =
340 SOC_DAPM_ENUM("Route", lineoutb_input_enum);
342 static const struct soc_enum hpb_input_enum =
343 SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 1,
344 ARRAY_SIZE(hplob_input_text),
345 hplob_input_text);
347 static const struct snd_kcontrol_new hpb_input =
348 SOC_DAPM_ENUM("Route", hpb_input_enum);
350 static const char * const dig_mux_text[] = {
351 "ADC", "DSP"};
353 static const struct soc_enum dig_mux_enum =
354 SOC_ENUM_SINGLE(CS42L56_MISC_CTL, 7,
355 ARRAY_SIZE(dig_mux_text),
356 dig_mux_text);
358 static const struct snd_kcontrol_new dig_mux =
359 SOC_DAPM_ENUM("Route", dig_mux_enum);
361 static const char * const hpf_freq_text[] = {
362 "1.8Hz", "119Hz", "236Hz", "464Hz"
365 static const struct soc_enum hpfa_freq_enum =
366 SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 0,
367 ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
369 static const struct soc_enum hpfb_freq_enum =
370 SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 2,
371 ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
373 static const char * const ng_delay_text[] = {
374 "50ms", "100ms", "150ms", "200ms"
377 static const struct soc_enum ng_delay_enum =
378 SOC_ENUM_SINGLE(CS42L56_NOISE_GATE_CTL, 0,
379 ARRAY_SIZE(ng_delay_text), ng_delay_text);
381 static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
383 SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L56_MASTER_A_VOLUME,
384 CS42L56_MASTER_B_VOLUME, 0, 0x34, 0xE4, adv_tlv),
385 SOC_DOUBLE("Master Mute Switch", CS42L56_DSP_MUTE_CTL, 0, 1, 1, 1),
387 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L56_ADCA_MIX_VOLUME,
388 CS42L56_ADCB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
389 SOC_DOUBLE("ADC Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 6, 7, 1, 1),
391 SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", CS42L56_PCMA_MIX_VOLUME,
392 CS42L56_PCMB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
393 SOC_DOUBLE("PCM Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 4, 5, 1, 1),
395 SOC_SINGLE_TLV("Analog Advisory Volume",
396 CS42L56_ANAINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv),
397 SOC_SINGLE_TLV("Digital Advisory Volume",
398 CS42L56_DIGINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv),
400 SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L56_PGAA_MUX_VOLUME,
401 CS42L56_PGAB_MUX_VOLUME, 0, 0x34, 0x24, pga_tlv),
402 SOC_DOUBLE_R_TLV("ADC Volume", CS42L56_ADCA_ATTENUATOR,
403 CS42L56_ADCB_ATTENUATOR, 0, 0x00, 1, adc_tlv),
404 SOC_DOUBLE("ADC Mute Switch", CS42L56_MISC_ADC_CTL, 2, 3, 1, 1),
405 SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1),
407 SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
408 CS42L56_HPB_VOLUME, 0, 0x84, 0x48, hl_tlv),
409 SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
410 CS42L56_LOB_VOLUME, 0, 0x84, 0x48, hl_tlv),
412 SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL,
413 0, 0x00, 1, tone_tlv),
414 SOC_SINGLE_TLV("Treble Shelving Volume", CS42L56_TONE_CTL,
415 4, 0x00, 1, tone_tlv),
417 SOC_DOUBLE_TLV("PGA Preamp Volume", CS42L56_GAIN_BIAS_CTL,
418 4, 6, 0x02, 1, preamp_tlv),
420 SOC_SINGLE("DSP Switch", CS42L56_PLAYBACK_CTL, 7, 1, 1),
421 SOC_SINGLE("Gang Playback Switch", CS42L56_PLAYBACK_CTL, 4, 1, 1),
422 SOC_SINGLE("Gang ADC Switch", CS42L56_MISC_ADC_CTL, 7, 1, 1),
423 SOC_SINGLE("Gang PGA Switch", CS42L56_MISC_ADC_CTL, 6, 1, 1),
425 SOC_SINGLE("PCMA Invert", CS42L56_PLAYBACK_CTL, 2, 1, 1),
426 SOC_SINGLE("PCMB Invert", CS42L56_PLAYBACK_CTL, 3, 1, 1),
427 SOC_SINGLE("ADCA Invert", CS42L56_MISC_ADC_CTL, 2, 1, 1),
428 SOC_SINGLE("ADCB Invert", CS42L56_MISC_ADC_CTL, 3, 1, 1),
430 SOC_DOUBLE("HPF Switch", CS42L56_HPF_CTL, 5, 7, 1, 1),
431 SOC_DOUBLE("HPF Freeze Switch", CS42L56_HPF_CTL, 4, 6, 1, 1),
432 SOC_ENUM("HPFA Corner Freq", hpfa_freq_enum),
433 SOC_ENUM("HPFB Corner Freq", hpfb_freq_enum),
435 SOC_SINGLE("Analog Soft Ramp", CS42L56_MISC_CTL, 4, 1, 1),
436 SOC_DOUBLE("Analog Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC,
437 7, 5, 1, 1),
438 SOC_SINGLE("Analog Zero Cross", CS42L56_MISC_CTL, 3, 1, 1),
439 SOC_DOUBLE("Analog Zero Cross Disable", CS42L56_ALC_LIM_SFT_ZC,
440 6, 4, 1, 1),
441 SOC_SINGLE("Digital Soft Ramp", CS42L56_MISC_CTL, 2, 1, 1),
442 SOC_SINGLE("Digital Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC,
443 3, 1, 1),
445 SOC_SINGLE("HL Deemphasis", CS42L56_PLAYBACK_CTL, 6, 1, 1),
447 SOC_SINGLE("ALC Switch", CS42L56_ALC_EN_ATTACK_RATE, 6, 1, 1),
448 SOC_SINGLE("ALC Limit All Switch", CS42L56_ALC_RELEASE_RATE, 7, 1, 1),
449 SOC_SINGLE_RANGE("ALC Attack", CS42L56_ALC_EN_ATTACK_RATE,
450 0, 0, 0x3f, 0),
451 SOC_SINGLE_RANGE("ALC Release", CS42L56_ALC_RELEASE_RATE,
452 0, 0x3f, 0, 0),
453 SOC_SINGLE_TLV("ALC MAX", CS42L56_ALC_THRESHOLD,
454 5, 0x07, 1, alc_tlv),
455 SOC_SINGLE_TLV("ALC MIN", CS42L56_ALC_THRESHOLD,
456 2, 0x07, 1, alc_tlv),
458 SOC_SINGLE("Limiter Switch", CS42L56_LIM_CTL_RELEASE_RATE, 7, 1, 1),
459 SOC_SINGLE("Limit All Switch", CS42L56_LIM_CTL_RELEASE_RATE, 6, 1, 1),
460 SOC_SINGLE_RANGE("Limiter Attack", CS42L56_LIM_ATTACK_RATE,
461 0, 0, 0x3f, 0),
462 SOC_SINGLE_RANGE("Limiter Release", CS42L56_LIM_CTL_RELEASE_RATE,
463 0, 0x3f, 0, 0),
464 SOC_SINGLE_TLV("Limiter MAX", CS42L56_LIM_THRESHOLD_CTL,
465 5, 0x07, 1, alc_tlv),
466 SOC_SINGLE_TLV("Limiter Cushion", CS42L56_ALC_THRESHOLD,
467 2, 0x07, 1, alc_tlv),
469 SOC_SINGLE("NG Switch", CS42L56_NOISE_GATE_CTL, 6, 1, 1),
470 SOC_SINGLE("NG All Switch", CS42L56_NOISE_GATE_CTL, 7, 1, 1),
471 SOC_SINGLE("NG Boost Switch", CS42L56_NOISE_GATE_CTL, 5, 1, 1),
472 SOC_SINGLE_TLV("NG Unboost Threshold", CS42L56_NOISE_GATE_CTL,
473 2, 0x07, 1, ngnb_tlv),
474 SOC_SINGLE_TLV("NG Boost Threshold", CS42L56_NOISE_GATE_CTL,
475 2, 0x07, 1, ngb_tlv),
476 SOC_ENUM("NG Delay", ng_delay_enum),
478 SOC_ENUM("Beep Config", beep_config_enum),
479 SOC_ENUM("Beep Pitch", beep_pitch_enum),
480 SOC_ENUM("Beep on Time", beep_ontime_enum),
481 SOC_ENUM("Beep off Time", beep_offtime_enum),
482 SOC_SINGLE_SX_TLV("Beep Volume", CS42L56_BEEP_FREQ_OFFTIME,
483 0, 0x07, 0x23, beep_tlv),
484 SOC_SINGLE("Beep Tone Ctl Switch", CS42L56_BEEP_TONE_CFG, 0, 1, 1),
485 SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
486 SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
490 static const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = {
492 SND_SOC_DAPM_SIGGEN("Beep"),
493 SND_SOC_DAPM_SUPPLY("VBUF", CS42L56_PWRCTL_1, 5, 1, NULL, 0),
494 SND_SOC_DAPM_MICBIAS("MIC1 Bias", CS42L56_PWRCTL_1, 4, 1),
495 SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L56_PWRCTL_1, 3, 1, NULL, 0),
497 SND_SOC_DAPM_INPUT("AIN1A"),
498 SND_SOC_DAPM_INPUT("AIN2A"),
499 SND_SOC_DAPM_INPUT("AIN1B"),
500 SND_SOC_DAPM_INPUT("AIN2B"),
501 SND_SOC_DAPM_INPUT("AIN3A"),
502 SND_SOC_DAPM_INPUT("AIN3B"),
504 SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0,
505 SND_SOC_NOPM, 0, 0),
507 SND_SOC_DAPM_AIF_IN("SDIN", NULL, 0,
508 SND_SOC_NOPM, 0, 0),
510 SND_SOC_DAPM_MUX("Digital Output Mux", SND_SOC_NOPM,
511 0, 0, &dig_mux),
513 SND_SOC_DAPM_PGA("PGAA", SND_SOC_NOPM, 0, 0, NULL, 0),
514 SND_SOC_DAPM_PGA("PGAB", SND_SOC_NOPM, 0, 0, NULL, 0),
515 SND_SOC_DAPM_MUX("PGAA Input Mux",
516 SND_SOC_NOPM, 0, 0, &pgaa_mux),
517 SND_SOC_DAPM_MUX("PGAB Input Mux",
518 SND_SOC_NOPM, 0, 0, &pgab_mux),
520 SND_SOC_DAPM_MUX("ADCA Mux", SND_SOC_NOPM,
521 0, 0, &adca_mux),
522 SND_SOC_DAPM_MUX("ADCB Mux", SND_SOC_NOPM,
523 0, 0, &adcb_mux),
525 SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1),
526 SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1),
528 SND_SOC_DAPM_MUX("ADCA Swap Mux", SND_SOC_NOPM, 0, 0,
529 &adca_swap_mux),
530 SND_SOC_DAPM_MUX("ADCB Swap Mux", SND_SOC_NOPM, 0, 0,
531 &adcb_swap_mux),
533 SND_SOC_DAPM_MUX("PCMA Swap Mux", SND_SOC_NOPM, 0, 0,
534 &pcma_swap_mux),
535 SND_SOC_DAPM_MUX("PCMB Swap Mux", SND_SOC_NOPM, 0, 0,
536 &pcmb_swap_mux),
538 SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0),
539 SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0),
541 SND_SOC_DAPM_OUTPUT("HPA"),
542 SND_SOC_DAPM_OUTPUT("LOA"),
543 SND_SOC_DAPM_OUTPUT("HPB"),
544 SND_SOC_DAPM_OUTPUT("LOB"),
546 SND_SOC_DAPM_SWITCH("Headphone Right",
547 CS42L56_PWRCTL_2, 4, 1, &hpb_switch),
548 SND_SOC_DAPM_SWITCH("Headphone Left",
549 CS42L56_PWRCTL_2, 6, 1, &hpa_switch),
551 SND_SOC_DAPM_SWITCH("Lineout Right",
552 CS42L56_PWRCTL_2, 0, 1, &lob_switch),
553 SND_SOC_DAPM_SWITCH("Lineout Left",
554 CS42L56_PWRCTL_2, 2, 1, &loa_switch),
556 SND_SOC_DAPM_MUX("LINEOUTA Input Mux", SND_SOC_NOPM,
557 0, 0, &lineouta_input),
558 SND_SOC_DAPM_MUX("LINEOUTB Input Mux", SND_SOC_NOPM,
559 0, 0, &lineoutb_input),
560 SND_SOC_DAPM_MUX("HPA Input Mux", SND_SOC_NOPM,
561 0, 0, &hpa_input),
562 SND_SOC_DAPM_MUX("HPB Input Mux", SND_SOC_NOPM,
563 0, 0, &hpb_input),
567 static const struct snd_soc_dapm_route cs42l56_audio_map[] = {
569 {"HiFi Capture", "DSP", "Digital Output Mux"},
570 {"HiFi Capture", "ADC", "Digital Output Mux"},
572 {"Digital Output Mux", NULL, "ADCA"},
573 {"Digital Output Mux", NULL, "ADCB"},
575 {"ADCB", NULL, "ADCB Swap Mux"},
576 {"ADCA", NULL, "ADCA Swap Mux"},
578 {"ADCA Swap Mux", NULL, "ADCA"},
579 {"ADCB Swap Mux", NULL, "ADCB"},
581 {"DACA", "Left", "ADCA Swap Mux"},
582 {"DACA", "LR 2", "ADCA Swap Mux"},
583 {"DACA", "Right", "ADCA Swap Mux"},
585 {"DACB", "Left", "ADCB Swap Mux"},
586 {"DACB", "LR 2", "ADCB Swap Mux"},
587 {"DACB", "Right", "ADCB Swap Mux"},
589 {"ADCA Mux", NULL, "AIN3A"},
590 {"ADCA Mux", NULL, "AIN2A"},
591 {"ADCA Mux", NULL, "AIN1A"},
592 {"ADCA Mux", NULL, "PGAA"},
593 {"ADCB Mux", NULL, "AIN3B"},
594 {"ADCB Mux", NULL, "AIN2B"},
595 {"ADCB Mux", NULL, "AIN1B"},
596 {"ADCB Mux", NULL, "PGAB"},
598 {"PGAA", "AIN1A", "PGAA Input Mux"},
599 {"PGAA", "AIN2A", "PGAA Input Mux"},
600 {"PGAA", "AIN3A", "PGAA Input Mux"},
601 {"PGAB", "AIN1B", "PGAB Input Mux"},
602 {"PGAB", "AIN2B", "PGAB Input Mux"},
603 {"PGAB", "AIN3B", "PGAB Input Mux"},
605 {"PGAA Input Mux", NULL, "AIN1A"},
606 {"PGAA Input Mux", NULL, "AIN2A"},
607 {"PGAA Input Mux", NULL, "AIN3A"},
608 {"PGAB Input Mux", NULL, "AIN1B"},
609 {"PGAB Input Mux", NULL, "AIN2B"},
610 {"PGAB Input Mux", NULL, "AIN3B"},
612 {"LOB", "Switch", "LINEOUTB Input Mux"},
613 {"LOA", "Switch", "LINEOUTA Input Mux"},
615 {"LINEOUTA Input Mux", "PGAA", "PGAA"},
616 {"LINEOUTB Input Mux", "PGAB", "PGAB"},
617 {"LINEOUTA Input Mux", "DACA", "DACA"},
618 {"LINEOUTB Input Mux", "DACB", "DACB"},
620 {"HPA", "Switch", "HPB Input Mux"},
621 {"HPB", "Switch", "HPA Input Mux"},
623 {"HPA Input Mux", "PGAA", "PGAA"},
624 {"HPB Input Mux", "PGAB", "PGAB"},
625 {"HPA Input Mux", "DACA", "DACA"},
626 {"HPB Input Mux", "DACB", "DACB"},
628 {"DACA", NULL, "PCMA Swap Mux"},
629 {"DACB", NULL, "PCMB Swap Mux"},
631 {"PCMB Swap Mux", "Left", "HiFi Playback"},
632 {"PCMB Swap Mux", "LR 2", "HiFi Playback"},
633 {"PCMB Swap Mux", "Right", "HiFi Playback"},
635 {"PCMA Swap Mux", "Left", "HiFi Playback"},
636 {"PCMA Swap Mux", "LR 2", "HiFi Playback"},
637 {"PCMA Swap Mux", "Right", "HiFi Playback"},
641 struct cs42l56_clk_para {
642 u32 mclk;
643 u32 srate;
644 u8 ratio;
647 static const struct cs42l56_clk_para clk_ratio_table[] = {
648 /* 8k */
649 { 6000000, 8000, CS42L56_MCLK_LRCLK_768 },
650 { 6144000, 8000, CS42L56_MCLK_LRCLK_750 },
651 { 12000000, 8000, CS42L56_MCLK_LRCLK_768 },
652 { 12288000, 8000, CS42L56_MCLK_LRCLK_750 },
653 { 24000000, 8000, CS42L56_MCLK_LRCLK_768 },
654 { 24576000, 8000, CS42L56_MCLK_LRCLK_750 },
655 /* 11.025k */
656 { 5644800, 11025, CS42L56_MCLK_LRCLK_512},
657 { 11289600, 11025, CS42L56_MCLK_LRCLK_512},
658 { 22579200, 11025, CS42L56_MCLK_LRCLK_512 },
659 /* 11.0294k */
660 { 6000000, 110294, CS42L56_MCLK_LRCLK_544 },
661 { 12000000, 110294, CS42L56_MCLK_LRCLK_544 },
662 { 24000000, 110294, CS42L56_MCLK_LRCLK_544 },
663 /* 12k */
664 { 6000000, 12000, CS42L56_MCLK_LRCLK_500 },
665 { 6144000, 12000, CS42L56_MCLK_LRCLK_512 },
666 { 12000000, 12000, CS42L56_MCLK_LRCLK_500 },
667 { 12288000, 12000, CS42L56_MCLK_LRCLK_512 },
668 { 24000000, 12000, CS42L56_MCLK_LRCLK_500 },
669 { 24576000, 12000, CS42L56_MCLK_LRCLK_512 },
670 /* 16k */
671 { 6000000, 16000, CS42L56_MCLK_LRCLK_375 },
672 { 6144000, 16000, CS42L56_MCLK_LRCLK_384 },
673 { 12000000, 16000, CS42L56_MCLK_LRCLK_375 },
674 { 12288000, 16000, CS42L56_MCLK_LRCLK_384 },
675 { 24000000, 16000, CS42L56_MCLK_LRCLK_375 },
676 { 24576000, 16000, CS42L56_MCLK_LRCLK_384 },
677 /* 22.050k */
678 { 5644800, 22050, CS42L56_MCLK_LRCLK_256 },
679 { 11289600, 22050, CS42L56_MCLK_LRCLK_256 },
680 { 22579200, 22050, CS42L56_MCLK_LRCLK_256 },
681 /* 22.0588k */
682 { 6000000, 220588, CS42L56_MCLK_LRCLK_272 },
683 { 12000000, 220588, CS42L56_MCLK_LRCLK_272 },
684 { 24000000, 220588, CS42L56_MCLK_LRCLK_272 },
685 /* 24k */
686 { 6000000, 24000, CS42L56_MCLK_LRCLK_250 },
687 { 6144000, 24000, CS42L56_MCLK_LRCLK_256 },
688 { 12000000, 24000, CS42L56_MCLK_LRCLK_250 },
689 { 12288000, 24000, CS42L56_MCLK_LRCLK_256 },
690 { 24000000, 24000, CS42L56_MCLK_LRCLK_250 },
691 { 24576000, 24000, CS42L56_MCLK_LRCLK_256 },
692 /* 32k */
693 { 6000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
694 { 6144000, 32000, CS42L56_MCLK_LRCLK_192 },
695 { 12000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
696 { 12288000, 32000, CS42L56_MCLK_LRCLK_192 },
697 { 24000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
698 { 24576000, 32000, CS42L56_MCLK_LRCLK_192 },
699 /* 44.118k */
700 { 6000000, 44118, CS42L56_MCLK_LRCLK_136 },
701 { 12000000, 44118, CS42L56_MCLK_LRCLK_136 },
702 { 24000000, 44118, CS42L56_MCLK_LRCLK_136 },
703 /* 44.1k */
704 { 5644800, 44100, CS42L56_MCLK_LRCLK_128 },
705 { 11289600, 44100, CS42L56_MCLK_LRCLK_128 },
706 { 22579200, 44100, CS42L56_MCLK_LRCLK_128 },
707 /* 48k */
708 { 6000000, 48000, CS42L56_MCLK_LRCLK_125 },
709 { 6144000, 48000, CS42L56_MCLK_LRCLK_128 },
710 { 12000000, 48000, CS42L56_MCLK_LRCLK_125 },
711 { 12288000, 48000, CS42L56_MCLK_LRCLK_128 },
712 { 24000000, 48000, CS42L56_MCLK_LRCLK_125 },
713 { 24576000, 48000, CS42L56_MCLK_LRCLK_128 },
716 static int cs42l56_get_mclk_ratio(int mclk, int rate)
718 int i;
720 for (i = 0; i < ARRAY_SIZE(clk_ratio_table); i++) {
721 if (clk_ratio_table[i].mclk == mclk &&
722 clk_ratio_table[i].srate == rate)
723 return clk_ratio_table[i].ratio;
725 return -EINVAL;
728 static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
729 int clk_id, unsigned int freq, int dir)
731 struct snd_soc_codec *codec = codec_dai->codec;
732 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
734 switch (freq) {
735 case CS42L56_MCLK_5P6448MHZ:
736 case CS42L56_MCLK_6MHZ:
737 case CS42L56_MCLK_6P144MHZ:
738 cs42l56->mclk_div2 = 0;
739 cs42l56->mclk_prediv = 0;
740 break;
741 case CS42L56_MCLK_11P2896MHZ:
742 case CS42L56_MCLK_12MHZ:
743 case CS42L56_MCLK_12P288MHZ:
744 cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
745 cs42l56->mclk_prediv = 0;
746 break;
747 case CS42L56_MCLK_22P5792MHZ:
748 case CS42L56_MCLK_24MHZ:
749 case CS42L56_MCLK_24P576MHZ:
750 cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
751 cs42l56->mclk_prediv = CS42L56_MCLK_PREDIV;
752 break;
753 default:
754 return -EINVAL;
756 cs42l56->mclk = freq;
758 snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
759 CS42L56_MCLK_PREDIV_MASK,
760 cs42l56->mclk_prediv);
761 snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
762 CS42L56_MCLK_DIV2_MASK,
763 cs42l56->mclk_div2);
765 return 0;
768 static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
770 struct snd_soc_codec *codec = codec_dai->codec;
771 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
773 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
774 case SND_SOC_DAIFMT_CBM_CFM:
775 cs42l56->iface = CS42L56_MASTER_MODE;
776 break;
777 case SND_SOC_DAIFMT_CBS_CFS:
778 cs42l56->iface = CS42L56_SLAVE_MODE;
779 break;
780 default:
781 return -EINVAL;
784 /* interface format */
785 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
786 case SND_SOC_DAIFMT_I2S:
787 cs42l56->iface_fmt = CS42L56_DIG_FMT_I2S;
788 break;
789 case SND_SOC_DAIFMT_LEFT_J:
790 cs42l56->iface_fmt = CS42L56_DIG_FMT_LEFT_J;
791 break;
792 default:
793 return -EINVAL;
796 /* sclk inversion */
797 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
798 case SND_SOC_DAIFMT_NB_NF:
799 cs42l56->iface_inv = 0;
800 break;
801 case SND_SOC_DAIFMT_IB_NF:
802 cs42l56->iface_inv = CS42L56_SCLK_INV;
803 break;
804 default:
805 return -EINVAL;
808 snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
809 CS42L56_MS_MODE_MASK, cs42l56->iface);
810 snd_soc_update_bits(codec, CS42L56_SERIAL_FMT,
811 CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt);
812 snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
813 CS42L56_SCLK_INV_MASK, cs42l56->iface_inv);
814 return 0;
817 static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
819 struct snd_soc_codec *codec = dai->codec;
821 if (mute) {
822 /* Hit the DSP Mixer first */
823 snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL,
824 CS42L56_ADCAMIX_MUTE_MASK |
825 CS42L56_ADCBMIX_MUTE_MASK |
826 CS42L56_PCMAMIX_MUTE_MASK |
827 CS42L56_PCMBMIX_MUTE_MASK |
828 CS42L56_MSTB_MUTE_MASK |
829 CS42L56_MSTA_MUTE_MASK,
830 CS42L56_MUTE_ALL);
831 /* Mute ADC's */
832 snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL,
833 CS42L56_ADCA_MUTE_MASK |
834 CS42L56_ADCB_MUTE_MASK,
835 CS42L56_MUTE_ALL);
836 /* HP And LO */
837 snd_soc_update_bits(codec, CS42L56_HPA_VOLUME,
838 CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
839 snd_soc_update_bits(codec, CS42L56_HPB_VOLUME,
840 CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
841 snd_soc_update_bits(codec, CS42L56_LOA_VOLUME,
842 CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
843 snd_soc_update_bits(codec, CS42L56_LOB_VOLUME,
844 CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
845 } else {
846 snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL,
847 CS42L56_ADCAMIX_MUTE_MASK |
848 CS42L56_ADCBMIX_MUTE_MASK |
849 CS42L56_PCMAMIX_MUTE_MASK |
850 CS42L56_PCMBMIX_MUTE_MASK |
851 CS42L56_MSTB_MUTE_MASK |
852 CS42L56_MSTA_MUTE_MASK,
853 CS42L56_UNMUTE);
855 snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL,
856 CS42L56_ADCA_MUTE_MASK |
857 CS42L56_ADCB_MUTE_MASK,
858 CS42L56_UNMUTE);
860 snd_soc_update_bits(codec, CS42L56_HPA_VOLUME,
861 CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
862 snd_soc_update_bits(codec, CS42L56_HPB_VOLUME,
863 CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
864 snd_soc_update_bits(codec, CS42L56_LOA_VOLUME,
865 CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
866 snd_soc_update_bits(codec, CS42L56_LOB_VOLUME,
867 CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
869 return 0;
872 static int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream,
873 struct snd_pcm_hw_params *params,
874 struct snd_soc_dai *dai)
876 struct snd_soc_codec *codec = dai->codec;
877 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
878 int ratio;
880 ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params));
881 if (ratio >= 0) {
882 snd_soc_update_bits(codec, CS42L56_CLKCTL_2,
883 CS42L56_CLK_RATIO_MASK, ratio);
884 } else {
885 dev_err(codec->dev, "unsupported mclk/sclk/lrclk ratio\n");
886 return -EINVAL;
889 return 0;
892 static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
893 enum snd_soc_bias_level level)
895 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
896 int ret;
898 switch (level) {
899 case SND_SOC_BIAS_ON:
900 break;
901 case SND_SOC_BIAS_PREPARE:
902 snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
903 CS42L56_MCLK_DIS_MASK, 0);
904 snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
905 CS42L56_PDN_ALL_MASK, 0);
906 break;
907 case SND_SOC_BIAS_STANDBY:
908 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
909 regcache_cache_only(cs42l56->regmap, false);
910 regcache_sync(cs42l56->regmap);
911 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
912 cs42l56->supplies);
913 if (ret != 0) {
914 dev_err(cs42l56->dev,
915 "Failed to enable regulators: %d\n",
916 ret);
917 return ret;
920 snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
921 CS42L56_PDN_ALL_MASK, 1);
922 break;
923 case SND_SOC_BIAS_OFF:
924 snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
925 CS42L56_PDN_ALL_MASK, 1);
926 snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
927 CS42L56_MCLK_DIS_MASK, 1);
928 regcache_cache_only(cs42l56->regmap, true);
929 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
930 cs42l56->supplies);
931 break;
934 return 0;
937 #define CS42L56_RATES (SNDRV_PCM_RATE_8000_48000)
939 #define CS42L56_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \
940 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | \
941 SNDRV_PCM_FMTBIT_S32_LE)
944 static const struct snd_soc_dai_ops cs42l56_ops = {
945 .hw_params = cs42l56_pcm_hw_params,
946 .digital_mute = cs42l56_digital_mute,
947 .set_fmt = cs42l56_set_dai_fmt,
948 .set_sysclk = cs42l56_set_sysclk,
951 static struct snd_soc_dai_driver cs42l56_dai = {
952 .name = "cs42l56",
953 .playback = {
954 .stream_name = "HiFi Playback",
955 .channels_min = 1,
956 .channels_max = 2,
957 .rates = CS42L56_RATES,
958 .formats = CS42L56_FORMATS,
960 .capture = {
961 .stream_name = "HiFi Capture",
962 .channels_min = 1,
963 .channels_max = 2,
964 .rates = CS42L56_RATES,
965 .formats = CS42L56_FORMATS,
967 .ops = &cs42l56_ops,
970 static int beep_freq[] = {
971 261, 522, 585, 667, 706, 774, 889, 1000,
972 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
975 static void cs42l56_beep_work(struct work_struct *work)
977 struct cs42l56_private *cs42l56 =
978 container_of(work, struct cs42l56_private, beep_work);
979 struct snd_soc_codec *codec = cs42l56->codec;
980 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
981 int i;
982 int val = 0;
983 int best = 0;
985 if (cs42l56->beep_rate) {
986 for (i = 0; i < ARRAY_SIZE(beep_freq); i++) {
987 if (abs(cs42l56->beep_rate - beep_freq[i]) <
988 abs(cs42l56->beep_rate - beep_freq[best]))
989 best = i;
992 dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
993 beep_freq[best], cs42l56->beep_rate);
995 val = (best << CS42L56_BEEP_RATE_SHIFT);
997 snd_soc_dapm_enable_pin(dapm, "Beep");
998 } else {
999 dev_dbg(codec->dev, "Disabling beep\n");
1000 snd_soc_dapm_disable_pin(dapm, "Beep");
1003 snd_soc_update_bits(codec, CS42L56_BEEP_FREQ_ONTIME,
1004 CS42L56_BEEP_FREQ_MASK, val);
1006 snd_soc_dapm_sync(dapm);
1009 /* For usability define a way of injecting beep events for the device -
1010 * many systems will not have a keyboard.
1012 static int cs42l56_beep_event(struct input_dev *dev, unsigned int type,
1013 unsigned int code, int hz)
1015 struct snd_soc_codec *codec = input_get_drvdata(dev);
1016 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
1018 dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
1020 switch (code) {
1021 case SND_BELL:
1022 if (hz)
1023 hz = 261;
1024 case SND_TONE:
1025 break;
1026 default:
1027 return -1;
1030 /* Kick the beep from a workqueue */
1031 cs42l56->beep_rate = hz;
1032 schedule_work(&cs42l56->beep_work);
1033 return 0;
1036 static ssize_t cs42l56_beep_set(struct device *dev,
1037 struct device_attribute *attr,
1038 const char *buf, size_t count)
1040 struct cs42l56_private *cs42l56 = dev_get_drvdata(dev);
1041 long int time;
1042 int ret;
1044 ret = kstrtol(buf, 10, &time);
1045 if (ret != 0)
1046 return ret;
1048 input_event(cs42l56->beep, EV_SND, SND_TONE, time);
1050 return count;
1053 static DEVICE_ATTR(beep, 0200, NULL, cs42l56_beep_set);
1055 static void cs42l56_init_beep(struct snd_soc_codec *codec)
1057 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
1058 int ret;
1060 cs42l56->beep = devm_input_allocate_device(codec->dev);
1061 if (!cs42l56->beep) {
1062 dev_err(codec->dev, "Failed to allocate beep device\n");
1063 return;
1066 INIT_WORK(&cs42l56->beep_work, cs42l56_beep_work);
1067 cs42l56->beep_rate = 0;
1069 cs42l56->beep->name = "CS42L56 Beep Generator";
1070 cs42l56->beep->phys = dev_name(codec->dev);
1071 cs42l56->beep->id.bustype = BUS_I2C;
1073 cs42l56->beep->evbit[0] = BIT_MASK(EV_SND);
1074 cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
1075 cs42l56->beep->event = cs42l56_beep_event;
1076 cs42l56->beep->dev.parent = codec->dev;
1077 input_set_drvdata(cs42l56->beep, codec);
1079 ret = input_register_device(cs42l56->beep);
1080 if (ret != 0) {
1081 cs42l56->beep = NULL;
1082 dev_err(codec->dev, "Failed to register beep device\n");
1085 ret = device_create_file(codec->dev, &dev_attr_beep);
1086 if (ret != 0) {
1087 dev_err(codec->dev, "Failed to create keyclick file: %d\n",
1088 ret);
1092 static void cs42l56_free_beep(struct snd_soc_codec *codec)
1094 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
1096 device_remove_file(codec->dev, &dev_attr_beep);
1097 cancel_work_sync(&cs42l56->beep_work);
1098 cs42l56->beep = NULL;
1100 snd_soc_update_bits(codec, CS42L56_BEEP_TONE_CFG,
1101 CS42L56_BEEP_EN_MASK, 0);
1104 static int cs42l56_probe(struct snd_soc_codec *codec)
1106 cs42l56_init_beep(codec);
1108 return 0;
1111 static int cs42l56_remove(struct snd_soc_codec *codec)
1113 cs42l56_free_beep(codec);
1115 return 0;
1118 static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
1119 .probe = cs42l56_probe,
1120 .remove = cs42l56_remove,
1121 .set_bias_level = cs42l56_set_bias_level,
1122 .suspend_bias_off = true,
1124 .dapm_widgets = cs42l56_dapm_widgets,
1125 .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets),
1126 .dapm_routes = cs42l56_audio_map,
1127 .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map),
1129 .controls = cs42l56_snd_controls,
1130 .num_controls = ARRAY_SIZE(cs42l56_snd_controls),
1133 static const struct regmap_config cs42l56_regmap = {
1134 .reg_bits = 8,
1135 .val_bits = 8,
1137 .max_register = CS42L56_MAX_REGISTER,
1138 .reg_defaults = cs42l56_reg_defaults,
1139 .num_reg_defaults = ARRAY_SIZE(cs42l56_reg_defaults),
1140 .readable_reg = cs42l56_readable_register,
1141 .volatile_reg = cs42l56_volatile_register,
1142 .cache_type = REGCACHE_RBTREE,
1145 static int cs42l56_handle_of_data(struct i2c_client *i2c_client,
1146 struct cs42l56_platform_data *pdata)
1148 struct device_node *np = i2c_client->dev.of_node;
1149 u32 val32;
1151 if (of_property_read_bool(np, "cirrus,ain1a-reference-cfg"))
1152 pdata->ain1a_ref_cfg = true;
1154 if (of_property_read_bool(np, "cirrus,ain2a-reference-cfg"))
1155 pdata->ain2a_ref_cfg = true;
1157 if (of_property_read_bool(np, "cirrus,ain1b-reference-cfg"))
1158 pdata->ain1b_ref_cfg = true;
1160 if (of_property_read_bool(np, "cirrus,ain2b-reference-cfg"))
1161 pdata->ain2b_ref_cfg = true;
1163 if (of_property_read_u32(np, "cirrus,micbias-lvl", &val32) >= 0)
1164 pdata->micbias_lvl = val32;
1166 if (of_property_read_u32(np, "cirrus,chgfreq-divisor", &val32) >= 0)
1167 pdata->chgfreq = val32;
1169 if (of_property_read_u32(np, "cirrus,adaptive-pwr-cfg", &val32) >= 0)
1170 pdata->adaptive_pwr = val32;
1172 if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1173 pdata->hpfa_freq = val32;
1175 if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1176 pdata->hpfb_freq = val32;
1178 pdata->gpio_nreset = of_get_named_gpio(np, "cirrus,gpio-nreset", 0);
1180 return 0;
1183 static int cs42l56_i2c_probe(struct i2c_client *i2c_client,
1184 const struct i2c_device_id *id)
1186 struct cs42l56_private *cs42l56;
1187 struct cs42l56_platform_data *pdata =
1188 dev_get_platdata(&i2c_client->dev);
1189 int ret, i;
1190 unsigned int devid = 0;
1191 unsigned int alpha_rev, metal_rev;
1192 unsigned int reg;
1194 cs42l56 = devm_kzalloc(&i2c_client->dev,
1195 sizeof(struct cs42l56_private),
1196 GFP_KERNEL);
1197 if (cs42l56 == NULL)
1198 return -ENOMEM;
1199 cs42l56->dev = &i2c_client->dev;
1201 cs42l56->regmap = devm_regmap_init_i2c(i2c_client, &cs42l56_regmap);
1202 if (IS_ERR(cs42l56->regmap)) {
1203 ret = PTR_ERR(cs42l56->regmap);
1204 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1205 return ret;
1208 if (pdata) {
1209 cs42l56->pdata = *pdata;
1210 } else {
1211 pdata = devm_kzalloc(&i2c_client->dev,
1212 sizeof(struct cs42l56_platform_data),
1213 GFP_KERNEL);
1214 if (!pdata) {
1215 dev_err(&i2c_client->dev,
1216 "could not allocate pdata\n");
1217 return -ENOMEM;
1219 if (i2c_client->dev.of_node) {
1220 ret = cs42l56_handle_of_data(i2c_client,
1221 &cs42l56->pdata);
1222 if (ret != 0)
1223 return ret;
1225 cs42l56->pdata = *pdata;
1228 if (cs42l56->pdata.gpio_nreset) {
1229 ret = gpio_request_one(cs42l56->pdata.gpio_nreset,
1230 GPIOF_OUT_INIT_HIGH, "CS42L56 /RST");
1231 if (ret < 0) {
1232 dev_err(&i2c_client->dev,
1233 "Failed to request /RST %d: %d\n",
1234 cs42l56->pdata.gpio_nreset, ret);
1235 return ret;
1237 gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 0);
1238 gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 1);
1242 i2c_set_clientdata(i2c_client, cs42l56);
1244 for (i = 0; i < ARRAY_SIZE(cs42l56->supplies); i++)
1245 cs42l56->supplies[i].supply = cs42l56_supply_names[i];
1247 ret = devm_regulator_bulk_get(&i2c_client->dev,
1248 ARRAY_SIZE(cs42l56->supplies),
1249 cs42l56->supplies);
1250 if (ret != 0) {
1251 dev_err(&i2c_client->dev,
1252 "Failed to request supplies: %d\n", ret);
1253 return ret;
1256 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
1257 cs42l56->supplies);
1258 if (ret != 0) {
1259 dev_err(&i2c_client->dev,
1260 "Failed to enable supplies: %d\n", ret);
1261 return ret;
1264 regcache_cache_bypass(cs42l56->regmap, true);
1266 ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, &reg);
1267 devid = reg & CS42L56_CHIP_ID_MASK;
1268 if (devid != CS42L56_DEVID) {
1269 dev_err(&i2c_client->dev,
1270 "CS42L56 Device ID (%X). Expected %X\n",
1271 devid, CS42L56_DEVID);
1272 goto err_enable;
1274 alpha_rev = reg & CS42L56_AREV_MASK;
1275 metal_rev = reg & CS42L56_MTLREV_MASK;
1277 dev_info(&i2c_client->dev, "Cirrus Logic CS42L56 ");
1278 dev_info(&i2c_client->dev, "Alpha Rev %X Metal Rev %X\n",
1279 alpha_rev, metal_rev);
1281 regcache_cache_bypass(cs42l56->regmap, false);
1283 if (cs42l56->pdata.ain1a_ref_cfg)
1284 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1285 CS42L56_AIN1A_REF_MASK, 1);
1287 if (cs42l56->pdata.ain1b_ref_cfg)
1288 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1289 CS42L56_AIN1B_REF_MASK, 1);
1291 if (cs42l56->pdata.ain2a_ref_cfg)
1292 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1293 CS42L56_AIN2A_REF_MASK, 1);
1295 if (cs42l56->pdata.ain2b_ref_cfg)
1296 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1297 CS42L56_AIN2B_REF_MASK, 1);
1299 if (cs42l56->pdata.micbias_lvl)
1300 regmap_update_bits(cs42l56->regmap, CS42L56_GAIN_BIAS_CTL,
1301 CS42L56_MIC_BIAS_MASK,
1302 cs42l56->pdata.micbias_lvl);
1304 if (cs42l56->pdata.chgfreq)
1305 regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1306 CS42L56_CHRG_FREQ_MASK,
1307 cs42l56->pdata.chgfreq);
1309 if (cs42l56->pdata.hpfb_freq)
1310 regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL,
1311 CS42L56_HPFB_FREQ_MASK,
1312 cs42l56->pdata.hpfb_freq);
1314 if (cs42l56->pdata.hpfa_freq)
1315 regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL,
1316 CS42L56_HPFA_FREQ_MASK,
1317 cs42l56->pdata.hpfa_freq);
1319 if (cs42l56->pdata.adaptive_pwr)
1320 regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1321 CS42L56_ADAPT_PWR_MASK,
1322 cs42l56->pdata.adaptive_pwr);
1324 ret = snd_soc_register_codec(&i2c_client->dev,
1325 &soc_codec_dev_cs42l56, &cs42l56_dai, 1);
1326 if (ret < 0)
1327 return ret;
1329 return 0;
1331 err_enable:
1332 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1333 cs42l56->supplies);
1334 return ret;
1337 static int cs42l56_i2c_remove(struct i2c_client *client)
1339 struct cs42l56_private *cs42l56 = i2c_get_clientdata(client);
1341 snd_soc_unregister_codec(&client->dev);
1342 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1343 cs42l56->supplies);
1344 return 0;
1347 static const struct of_device_id cs42l56_of_match[] = {
1348 { .compatible = "cirrus,cs42l56", },
1351 MODULE_DEVICE_TABLE(of, cs42l56_of_match);
1354 static const struct i2c_device_id cs42l56_id[] = {
1355 { "cs42l56", 0 },
1358 MODULE_DEVICE_TABLE(i2c, cs42l56_id);
1360 static struct i2c_driver cs42l56_i2c_driver = {
1361 .driver = {
1362 .name = "cs42l56",
1363 .of_match_table = cs42l56_of_match,
1365 .id_table = cs42l56_id,
1366 .probe = cs42l56_i2c_probe,
1367 .remove = cs42l56_i2c_remove,
1370 module_i2c_driver(cs42l56_i2c_driver);
1372 MODULE_DESCRIPTION("ASoC CS42L56 driver");
1373 MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1374 MODULE_LICENSE("GPL");