Merge tag 'drm-vc4-fixes-2016-09-14' of https://github.com/anholt/linux into drm...
[linux-2.6-block.git] / sound / soc / codecs / cs42l56.c
CommitLineData
272b5edd
BA
1/*
2 * cs42l56.c -- CS42L56 ALSA SoC audio driver
3 *
4 * Copyright 2014 CirrusLogic, Inc.
5 *
6 * Author: Brian Austin <brian.austin@cirrus.com>
7 *
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.
11 *
12 */
13
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"
38
39#define CS42L56_NUM_SUPPLIES 3
40static const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = {
41 "VA",
42 "VCP",
43 "VLDO",
44};
45
46struct 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;
de06f22f 59#if IS_ENABLED(CONFIG_INPUT)
272b5edd
BA
60 struct input_dev *beep;
61 struct work_struct beep_work;
62 int beep_rate;
63#endif
64};
65
66static 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 */
113};
114
115static bool cs42l56_readable_register(struct device *dev, unsigned int reg)
116{
117 switch (reg) {
7f325bfc 118 case CS42L56_CHIP_ID_1 ... CS42L56_LIM_ATTACK_RATE:
272b5edd
BA
119 return true;
120 default:
121 return false;
122 }
123}
124
125static bool cs42l56_volatile_register(struct device *dev, unsigned int reg)
126{
127 switch (reg) {
128 case CS42L56_INT_STATUS:
c2b49ae6 129 return true;
272b5edd 130 default:
c2b49ae6 131 return false;
272b5edd
BA
132 }
133}
134
135static DECLARE_TLV_DB_SCALE(beep_tlv, -5000, 200, 0);
136static DECLARE_TLV_DB_SCALE(hl_tlv, -6000, 50, 0);
137static DECLARE_TLV_DB_SCALE(adv_tlv, -10200, 50, 0);
138static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, 0);
139static DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
140static DECLARE_TLV_DB_SCALE(preamp_tlv, 0, 1000, 0);
141static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
142
37879baf 143static const DECLARE_TLV_DB_RANGE(ngnb_tlv,
272b5edd 144 0, 1, TLV_DB_SCALE_ITEM(-8200, 600, 0),
37879baf
LPC
145 2, 5, TLV_DB_SCALE_ITEM(-7600, 300, 0)
146);
147static const DECLARE_TLV_DB_RANGE(ngb_tlv,
272b5edd 148 0, 2, TLV_DB_SCALE_ITEM(-6400, 600, 0),
37879baf
LPC
149 3, 7, TLV_DB_SCALE_ITEM(-4600, 300, 0)
150);
151static const DECLARE_TLV_DB_RANGE(alc_tlv,
272b5edd 152 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
37879baf
LPC
153 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0)
154);
272b5edd
BA
155
156static const char * const beep_config_text[] = {
157 "Off", "Single", "Multiple", "Continuous"
158};
159
160static 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);
163
164static const char * const beep_pitch_text[] = {
165 "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
166 "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
167};
168
169static 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);
172
173static 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"
177};
178
179static 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);
182
183static 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"
186};
187
188static 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);
191
192static const char * const beep_treble_text[] = {
193 "5kHz", "7kHz", "10kHz", "15kHz"
194};
195
196static 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);
199
200static const char * const beep_bass_text[] = {
201 "50Hz", "100Hz", "200Hz", "250Hz"
202};
203
204static 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);
207
208static const char * const adc_swap_text[] = {
209 "None", "A+B/2", "A-B/2", "Swap"
210};
211
212static 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);
215
216static const char * const pgaa_mux_text[] = {
217 "AIN1A", "AIN2A", "AIN3A"};
218
219static 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);
223
224static const struct snd_kcontrol_new pgaa_mux =
225 SOC_DAPM_ENUM("Route", pgaa_mux_enum);
226
227static const char * const pgab_mux_text[] = {
228 "AIN1B", "AIN2B", "AIN3B"};
229
230static 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);
234
235static const struct snd_kcontrol_new pgab_mux =
236 SOC_DAPM_ENUM("Route", pgab_mux_enum);
237
238static const char * const adca_mux_text[] = {
239 "PGAA", "AIN1A", "AIN2A", "AIN3A"};
240
241static 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);
245
246static const struct snd_kcontrol_new adca_mux =
247 SOC_DAPM_ENUM("Route", adca_mux_enum);
248
249static const char * const adcb_mux_text[] = {
250 "PGAB", "AIN1B", "AIN2B", "AIN3B"};
251
252static 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);
256
257static const struct snd_kcontrol_new adcb_mux =
258 SOC_DAPM_ENUM("Route", adcb_mux_enum);
259
260static const char * const left_swap_text[] = {
261 "Left", "LR 2", "Right"};
262
263static const char * const right_swap_text[] = {
264 "Right", "LR 2", "Left"};
265
266static const unsigned int swap_values[] = { 0, 1, 3 };
267
268static 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);
c4324bfa
BA
273static const struct snd_kcontrol_new adca_swap_mux =
274 SOC_DAPM_ENUM("Route", adca_swap_enum);
272b5edd
BA
275
276static 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);
c4324bfa
BA
281static const struct snd_kcontrol_new pcma_swap_mux =
282 SOC_DAPM_ENUM("Route", pcma_swap_enum);
272b5edd
BA
283
284static 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);
c4324bfa
BA
289static const struct snd_kcontrol_new adcb_swap_mux =
290 SOC_DAPM_ENUM("Route", adcb_swap_enum);
272b5edd
BA
291
292static 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);
c4324bfa
BA
297static const struct snd_kcontrol_new pcmb_swap_mux =
298 SOC_DAPM_ENUM("Route", pcmb_swap_enum);
272b5edd
BA
299
300static const struct snd_kcontrol_new hpa_switch =
301 SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1);
302
303static const struct snd_kcontrol_new hpb_switch =
304 SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 4, 1, 1);
305
306static const struct snd_kcontrol_new loa_switch =
307 SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 2, 1, 1);
308
309static const struct snd_kcontrol_new lob_switch =
310 SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 0, 1, 1);
311
312static const char * const hploa_input_text[] = {
313 "DACA", "PGAA"};
314
315static 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);
319
320static const struct snd_kcontrol_new lineouta_input =
321 SOC_DAPM_ENUM("Route", lineouta_input_enum);
322
323static 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);
327
328static const struct snd_kcontrol_new hpa_input =
329 SOC_DAPM_ENUM("Route", hpa_input_enum);
330
331static const char * const hplob_input_text[] = {
332 "DACB", "PGAB"};
333
334static 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);
338
339static const struct snd_kcontrol_new lineoutb_input =
340 SOC_DAPM_ENUM("Route", lineoutb_input_enum);
341
342static 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);
346
347static const struct snd_kcontrol_new hpb_input =
348 SOC_DAPM_ENUM("Route", hpb_input_enum);
349
350static const char * const dig_mux_text[] = {
351 "ADC", "DSP"};
352
353static 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);
357
358static const struct snd_kcontrol_new dig_mux =
359 SOC_DAPM_ENUM("Route", dig_mux_enum);
360
361static const char * const hpf_freq_text[] = {
362 "1.8Hz", "119Hz", "236Hz", "464Hz"
363};
364
365static const struct soc_enum hpfa_freq_enum =
366 SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 0,
367 ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
368
369static const struct soc_enum hpfb_freq_enum =
370 SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 2,
371 ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
372
373static const char * const ng_delay_text[] = {
374 "50ms", "100ms", "150ms", "200ms"
375};
376
377static 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);
380
381static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
382
383 SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L56_MASTER_A_VOLUME,
a0465587 384 CS42L56_MASTER_B_VOLUME, 0, 0x34, 0xE4, adv_tlv),
272b5edd
BA
385 SOC_DOUBLE("Master Mute Switch", CS42L56_DSP_MUTE_CTL, 0, 1, 1, 1),
386
387 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L56_ADCA_MIX_VOLUME,
a0465587 388 CS42L56_ADCB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
272b5edd
BA
389 SOC_DOUBLE("ADC Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 6, 7, 1, 1),
390
391 SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", CS42L56_PCMA_MIX_VOLUME,
a0465587 392 CS42L56_PCMB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
272b5edd
BA
393 SOC_DOUBLE("PCM Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 4, 5, 1, 1),
394
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),
399
400 SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L56_PGAA_MUX_VOLUME,
a0465587 401 CS42L56_PGAB_MUX_VOLUME, 0, 0x34, 0x24, pga_tlv),
272b5edd
BA
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),
406
407 SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
a0465587 408 CS42L56_HPB_VOLUME, 0, 0x84, 0x48, hl_tlv),
272b5edd 409 SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
a0465587 410 CS42L56_LOB_VOLUME, 0, 0x84, 0x48, hl_tlv),
272b5edd
BA
411
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),
416
417 SOC_DOUBLE_TLV("PGA Preamp Volume", CS42L56_GAIN_BIAS_CTL,
418 4, 6, 0x02, 1, preamp_tlv),
419
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),
424
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),
429
272b5edd
BA
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),
434
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),
444
445 SOC_SINGLE("HL Deemphasis", CS42L56_PLAYBACK_CTL, 6, 1, 1),
446
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),
457
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),
468
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),
477
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),
487
488};
489
490static const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = {
491
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),
496
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"),
503
504 SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0,
505 SND_SOC_NOPM, 0, 0),
506
507 SND_SOC_DAPM_AIF_IN("SDIN", NULL, 0,
508 SND_SOC_NOPM, 0, 0),
509
510 SND_SOC_DAPM_MUX("Digital Output Mux", SND_SOC_NOPM,
511 0, 0, &dig_mux),
512
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),
519
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),
524
525 SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1),
526 SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1),
527
c4324bfa
BA
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),
532
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),
537
272b5edd
BA
538 SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0),
539 SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0),
540
541 SND_SOC_DAPM_OUTPUT("HPA"),
542 SND_SOC_DAPM_OUTPUT("LOA"),
543 SND_SOC_DAPM_OUTPUT("HPB"),
544 SND_SOC_DAPM_OUTPUT("LOB"),
545
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),
550
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),
555
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),
564
565};
566
567static const struct snd_soc_dapm_route cs42l56_audio_map[] = {
568
569 {"HiFi Capture", "DSP", "Digital Output Mux"},
570 {"HiFi Capture", "ADC", "Digital Output Mux"},
571
572 {"Digital Output Mux", NULL, "ADCA"},
573 {"Digital Output Mux", NULL, "ADCB"},
574
c4324bfa
BA
575 {"ADCB", NULL, "ADCB Swap Mux"},
576 {"ADCA", NULL, "ADCA Swap Mux"},
577
578 {"ADCA Swap Mux", NULL, "ADCA"},
579 {"ADCB Swap Mux", NULL, "ADCB"},
580
581 {"DACA", "Left", "ADCA Swap Mux"},
582 {"DACA", "LR 2", "ADCA Swap Mux"},
583 {"DACA", "Right", "ADCA Swap Mux"},
584
585 {"DACB", "Left", "ADCB Swap Mux"},
586 {"DACB", "LR 2", "ADCB Swap Mux"},
587 {"DACB", "Right", "ADCB Swap Mux"},
272b5edd
BA
588
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"},
597
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"},
604
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"},
611
c4324bfa
BA
612 {"LOB", "Switch", "LINEOUTB Input Mux"},
613 {"LOA", "Switch", "LINEOUTA Input Mux"},
272b5edd
BA
614
615 {"LINEOUTA Input Mux", "PGAA", "PGAA"},
616 {"LINEOUTB Input Mux", "PGAB", "PGAB"},
617 {"LINEOUTA Input Mux", "DACA", "DACA"},
618 {"LINEOUTB Input Mux", "DACB", "DACB"},
619
c4324bfa
BA
620 {"HPA", "Switch", "HPB Input Mux"},
621 {"HPB", "Switch", "HPA Input Mux"},
272b5edd
BA
622
623 {"HPA Input Mux", "PGAA", "PGAA"},
624 {"HPB Input Mux", "PGAB", "PGAB"},
625 {"HPA Input Mux", "DACA", "DACA"},
626 {"HPB Input Mux", "DACB", "DACB"},
627
c4324bfa
BA
628 {"DACA", NULL, "PCMA Swap Mux"},
629 {"DACB", NULL, "PCMB Swap Mux"},
630
631 {"PCMB Swap Mux", "Left", "HiFi Playback"},
632 {"PCMB Swap Mux", "LR 2", "HiFi Playback"},
633 {"PCMB Swap Mux", "Right", "HiFi Playback"},
634
635 {"PCMA Swap Mux", "Left", "HiFi Playback"},
636 {"PCMA Swap Mux", "LR 2", "HiFi Playback"},
637 {"PCMA Swap Mux", "Right", "HiFi Playback"},
272b5edd
BA
638
639};
640
641struct cs42l56_clk_para {
642 u32 mclk;
643 u32 srate;
644 u8 ratio;
645};
646
647static 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 },
714};
715
716static int cs42l56_get_mclk_ratio(int mclk, int rate)
717{
718 int i;
719
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;
724 }
725 return -EINVAL;
726}
727
728static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
729 int clk_id, unsigned int freq, int dir)
730{
731 struct snd_soc_codec *codec = codec_dai->codec;
732 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
733
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:
4641c771 744 cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
272b5edd
BA
745 cs42l56->mclk_prediv = 0;
746 break;
747 case CS42L56_MCLK_22P5792MHZ:
748 case CS42L56_MCLK_24MHZ:
749 case CS42L56_MCLK_24P576MHZ:
4641c771
AL
750 cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
751 cs42l56->mclk_prediv = CS42L56_MCLK_PREDIV;
272b5edd
BA
752 break;
753 default:
754 return -EINVAL;
755 }
756 cs42l56->mclk = freq;
757
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);
764
765 return 0;
766}
767
768static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
769{
770 struct snd_soc_codec *codec = codec_dai->codec;
771 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
772
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;
782 }
783
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;
794 }
795
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;
806 }
807
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;
815}
816
817static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
818{
819 struct snd_soc_codec *codec = dai->codec;
820
821 if (mute) {
822 /* Hit the DSP Mixer first */
823 snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL,
824 CS42L56_ADCAMIX_MUTE_MASK |
4641c771
AL
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);
272b5edd
BA
831 /* Mute ADC's */
832 snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL,
4641c771
AL
833 CS42L56_ADCA_MUTE_MASK |
834 CS42L56_ADCB_MUTE_MASK,
835 CS42L56_MUTE_ALL);
272b5edd
BA
836 /* HP And LO */
837 snd_soc_update_bits(codec, CS42L56_HPA_VOLUME,
4641c771 838 CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
272b5edd 839 snd_soc_update_bits(codec, CS42L56_HPB_VOLUME,
4641c771 840 CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
272b5edd 841 snd_soc_update_bits(codec, CS42L56_LOA_VOLUME,
4641c771 842 CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
272b5edd 843 snd_soc_update_bits(codec, CS42L56_LOB_VOLUME,
4641c771 844 CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
272b5edd
BA
845 } else {
846 snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL,
847 CS42L56_ADCAMIX_MUTE_MASK |
4641c771
AL
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);
854
272b5edd 855 snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL,
4641c771
AL
856 CS42L56_ADCA_MUTE_MASK |
857 CS42L56_ADCB_MUTE_MASK,
858 CS42L56_UNMUTE);
859
272b5edd 860 snd_soc_update_bits(codec, CS42L56_HPA_VOLUME,
4641c771 861 CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
272b5edd 862 snd_soc_update_bits(codec, CS42L56_HPB_VOLUME,
4641c771 863 CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
272b5edd 864 snd_soc_update_bits(codec, CS42L56_LOA_VOLUME,
4641c771 865 CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
272b5edd 866 snd_soc_update_bits(codec, CS42L56_LOB_VOLUME,
4641c771 867 CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
272b5edd
BA
868 }
869 return 0;
870}
871
872static int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream,
873 struct snd_pcm_hw_params *params,
874 struct snd_soc_dai *dai)
875{
876 struct snd_soc_codec *codec = dai->codec;
877 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
878 int ratio;
879
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;
887 }
888
889 return 0;
890}
891
892static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
893 enum snd_soc_bias_level level)
894{
895 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
896 int ret;
897
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:
46a35b0d 908 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
272b5edd
BA
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;
918 }
919 }
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;
932 }
272b5edd
BA
933
934 return 0;
935}
936
937#define CS42L56_RATES (SNDRV_PCM_RATE_8000_48000)
938
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)
942
943
64793047 944static const struct snd_soc_dai_ops cs42l56_ops = {
272b5edd
BA
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,
949};
950
951static 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,
959 },
960 .capture = {
961 .stream_name = "HiFi Capture",
962 .channels_min = 1,
963 .channels_max = 2,
964 .rates = CS42L56_RATES,
965 .formats = CS42L56_FORMATS,
966 },
967 .ops = &cs42l56_ops,
968};
969
272b5edd
BA
970static int beep_freq[] = {
971 261, 522, 585, 667, 706, 774, 889, 1000,
972 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
973};
974
975static void cs42l56_beep_work(struct work_struct *work)
976{
977 struct cs42l56_private *cs42l56 =
978 container_of(work, struct cs42l56_private, beep_work);
979 struct snd_soc_codec *codec = cs42l56->codec;
46a35b0d 980 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
272b5edd
BA
981 int i;
982 int val = 0;
983 int best = 0;
984
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;
990 }
991
992 dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
993 beep_freq[best], cs42l56->beep_rate);
994
995 val = (best << CS42L56_BEEP_RATE_SHIFT);
996
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");
1001 }
1002
1003 snd_soc_update_bits(codec, CS42L56_BEEP_FREQ_ONTIME,
1004 CS42L56_BEEP_FREQ_MASK, val);
1005
1006 snd_soc_dapm_sync(dapm);
1007}
1008
1009/* For usability define a way of injecting beep events for the device -
1010 * many systems will not have a keyboard.
1011 */
1012static int cs42l56_beep_event(struct input_dev *dev, unsigned int type,
1013 unsigned int code, int hz)
1014{
1015 struct snd_soc_codec *codec = input_get_drvdata(dev);
1016 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
1017
1018 dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
1019
1020 switch (code) {
1021 case SND_BELL:
1022 if (hz)
1023 hz = 261;
1024 case SND_TONE:
1025 break;
1026 default:
1027 return -1;
1028 }
1029
1030 /* Kick the beep from a workqueue */
1031 cs42l56->beep_rate = hz;
1032 schedule_work(&cs42l56->beep_work);
1033 return 0;
1034}
1035
1036static ssize_t cs42l56_beep_set(struct device *dev,
1037 struct device_attribute *attr,
1038 const char *buf, size_t count)
1039{
1040 struct cs42l56_private *cs42l56 = dev_get_drvdata(dev);
1041 long int time;
1042 int ret;
1043
1044 ret = kstrtol(buf, 10, &time);
1045 if (ret != 0)
1046 return ret;
1047
1048 input_event(cs42l56->beep, EV_SND, SND_TONE, time);
1049
1050 return count;
1051}
1052
1053static DEVICE_ATTR(beep, 0200, NULL, cs42l56_beep_set);
1054
1055static void cs42l56_init_beep(struct snd_soc_codec *codec)
1056{
1057 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
1058 int ret;
1059
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;
1064 }
1065
1066 INIT_WORK(&cs42l56->beep_work, cs42l56_beep_work);
1067 cs42l56->beep_rate = 0;
1068
1069 cs42l56->beep->name = "CS42L56 Beep Generator";
1070 cs42l56->beep->phys = dev_name(codec->dev);
1071 cs42l56->beep->id.bustype = BUS_I2C;
1072
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);
1078
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");
1083 }
1084
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);
1089 }
1090}
1091
1092static void cs42l56_free_beep(struct snd_soc_codec *codec)
1093{
1094 struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
1095
1096 device_remove_file(codec->dev, &dev_attr_beep);
1097 cancel_work_sync(&cs42l56->beep_work);
1098 cs42l56->beep = NULL;
1099
1100 snd_soc_update_bits(codec, CS42L56_BEEP_TONE_CFG,
1101 CS42L56_BEEP_EN_MASK, 0);
1102}
1103
1104static int cs42l56_probe(struct snd_soc_codec *codec)
1105{
1106 cs42l56_init_beep(codec);
1107
272b5edd
BA
1108 return 0;
1109}
1110
1111static int cs42l56_remove(struct snd_soc_codec *codec)
1112{
272b5edd 1113 cs42l56_free_beep(codec);
272b5edd
BA
1114
1115 return 0;
1116}
1117
cf0efa1c 1118static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
272b5edd
BA
1119 .probe = cs42l56_probe,
1120 .remove = cs42l56_remove,
272b5edd 1121 .set_bias_level = cs42l56_set_bias_level,
2a4bc751 1122 .suspend_bias_off = true,
272b5edd
BA
1123
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),
1128
1129 .controls = cs42l56_snd_controls,
1130 .num_controls = ARRAY_SIZE(cs42l56_snd_controls),
1131};
1132
cf0efa1c 1133static const struct regmap_config cs42l56_regmap = {
272b5edd
BA
1134 .reg_bits = 8,
1135 .val_bits = 8,
1136
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,
1143};
1144
1145static int cs42l56_handle_of_data(struct i2c_client *i2c_client,
1146 struct cs42l56_platform_data *pdata)
1147{
1148 struct device_node *np = i2c_client->dev.of_node;
1149 u32 val32;
1150
1151 if (of_property_read_bool(np, "cirrus,ain1a-reference-cfg"))
1152 pdata->ain1a_ref_cfg = true;
1153
1154 if (of_property_read_bool(np, "cirrus,ain2a-reference-cfg"))
1155 pdata->ain2a_ref_cfg = true;
1156
1157 if (of_property_read_bool(np, "cirrus,ain1b-reference-cfg"))
1158 pdata->ain1b_ref_cfg = true;
1159
1160 if (of_property_read_bool(np, "cirrus,ain2b-reference-cfg"))
1161 pdata->ain2b_ref_cfg = true;
1162
1163 if (of_property_read_u32(np, "cirrus,micbias-lvl", &val32) >= 0)
1164 pdata->micbias_lvl = val32;
1165
1166 if (of_property_read_u32(np, "cirrus,chgfreq-divisor", &val32) >= 0)
1167 pdata->chgfreq = val32;
1168
1169 if (of_property_read_u32(np, "cirrus,adaptive-pwr-cfg", &val32) >= 0)
1170 pdata->adaptive_pwr = val32;
1171
1172 if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1173 pdata->hpfa_freq = val32;
1174
1175 if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1176 pdata->hpfb_freq = val32;
1177
1178 pdata->gpio_nreset = of_get_named_gpio(np, "cirrus,gpio-nreset", 0);
1179
1180 return 0;
1181}
1182
1183static int cs42l56_i2c_probe(struct i2c_client *i2c_client,
1184 const struct i2c_device_id *id)
1185{
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;
1193
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;
1200
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;
1206 }
1207
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;
1218 }
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;
1224 }
1225 cs42l56->pdata = *pdata;
1226 }
1227
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;
1236 }
1237 gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 0);
1238 gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 1);
1239 }
1240
1241
1242 i2c_set_clientdata(i2c_client, cs42l56);
1243
1244 for (i = 0; i < ARRAY_SIZE(cs42l56->supplies); i++)
1245 cs42l56->supplies[i].supply = cs42l56_supply_names[i];
1246
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;
1254 }
1255
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;
1262 }
1263
1264 regcache_cache_bypass(cs42l56->regmap, true);
1265
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;
1273 }
1274 alpha_rev = reg & CS42L56_AREV_MASK;
1275 metal_rev = reg & CS42L56_MTLREV_MASK;
1276
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);
1280
1281 regcache_cache_bypass(cs42l56->regmap, false);
1282
1283 if (cs42l56->pdata.ain1a_ref_cfg)
1284 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1285 CS42L56_AIN1A_REF_MASK, 1);
1286
1287 if (cs42l56->pdata.ain1b_ref_cfg)
1288 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1289 CS42L56_AIN1B_REF_MASK, 1);
1290
1291 if (cs42l56->pdata.ain2a_ref_cfg)
1292 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1293 CS42L56_AIN2A_REF_MASK, 1);
1294
1295 if (cs42l56->pdata.ain2b_ref_cfg)
1296 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1297 CS42L56_AIN2B_REF_MASK, 1);
1298
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);
1303
1304 if (cs42l56->pdata.chgfreq)
1305 regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1306 CS42L56_CHRG_FREQ_MASK,
1307 cs42l56->pdata.chgfreq);
1308
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);
1313
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);
1318
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);
1323
1324 ret = snd_soc_register_codec(&i2c_client->dev,
1325 &soc_codec_dev_cs42l56, &cs42l56_dai, 1);
1326 if (ret < 0)
1327 return ret;
1328
1329 return 0;
1330
1331err_enable:
1332 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1333 cs42l56->supplies);
1334 return ret;
1335}
1336
1337static int cs42l56_i2c_remove(struct i2c_client *client)
1338{
1339 struct cs42l56_private *cs42l56 = i2c_get_clientdata(client);
1340
1341 snd_soc_unregister_codec(&client->dev);
1342 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1343 cs42l56->supplies);
1344 return 0;
1345}
1346
1347static const struct of_device_id cs42l56_of_match[] = {
1348 { .compatible = "cirrus,cs42l56", },
1349 { }
1350};
1351MODULE_DEVICE_TABLE(of, cs42l56_of_match);
1352
1353
1354static const struct i2c_device_id cs42l56_id[] = {
1355 { "cs42l56", 0 },
1356 { }
1357};
1358MODULE_DEVICE_TABLE(i2c, cs42l56_id);
1359
1360static struct i2c_driver cs42l56_i2c_driver = {
1361 .driver = {
1362 .name = "cs42l56",
272b5edd
BA
1363 .of_match_table = cs42l56_of_match,
1364 },
1365 .id_table = cs42l56_id,
1366 .probe = cs42l56_i2c_probe,
1367 .remove = cs42l56_i2c_remove,
1368};
1369
1370module_i2c_driver(cs42l56_i2c_driver);
1371
1372MODULE_DESCRIPTION("ASoC CS42L56 driver");
1373MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1374MODULE_LICENSE("GPL");