ASoC: adau1761: Add ALC controls
[linux-2.6-block.git] / sound / soc / codecs / adau1761.c
CommitLineData
80503b23 1// SPDX-License-Identifier: GPL-2.0-or-later
dab464b6 2/*
d6dde63e 3 * Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
dab464b6
LPC
4 *
5 * Copyright 2011-2013 Analog Devices Inc.
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
dab464b6
LPC
7 */
8
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/i2c.h>
12#include <linux/spi/spi.h>
13#include <linux/slab.h>
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/pcm_params.h>
17#include <sound/soc.h>
18#include <sound/tlv.h>
19#include <linux/platform_data/adau17x1.h>
20
21#include "adau17x1.h"
22#include "adau1761.h"
23
24#define ADAU1761_DIGMIC_JACKDETECT 0x4008
25#define ADAU1761_REC_MIXER_LEFT0 0x400a
26#define ADAU1761_REC_MIXER_LEFT1 0x400b
27#define ADAU1761_REC_MIXER_RIGHT0 0x400c
28#define ADAU1761_REC_MIXER_RIGHT1 0x400d
29#define ADAU1761_LEFT_DIFF_INPUT_VOL 0x400e
30#define ADAU1761_RIGHT_DIFF_INPUT_VOL 0x400f
83078521 31#define ADAU1761_ALC_CTRL0 0x4011
54227371
LPC
32#define ADAU1761_ALC_CTRL1 0x4012
33#define ADAU1761_ALC_CTRL2 0x4013
34#define ADAU1761_ALC_CTRL3 0x4014
dab464b6
LPC
35#define ADAU1761_PLAY_LR_MIXER_LEFT 0x4020
36#define ADAU1761_PLAY_MIXER_LEFT0 0x401c
37#define ADAU1761_PLAY_MIXER_LEFT1 0x401d
38#define ADAU1761_PLAY_MIXER_RIGHT0 0x401e
39#define ADAU1761_PLAY_MIXER_RIGHT1 0x401f
40#define ADAU1761_PLAY_LR_MIXER_RIGHT 0x4021
41#define ADAU1761_PLAY_MIXER_MONO 0x4022
42#define ADAU1761_PLAY_HP_LEFT_VOL 0x4023
43#define ADAU1761_PLAY_HP_RIGHT_VOL 0x4024
44#define ADAU1761_PLAY_LINE_LEFT_VOL 0x4025
45#define ADAU1761_PLAY_LINE_RIGHT_VOL 0x4026
46#define ADAU1761_PLAY_MONO_OUTPUT_VOL 0x4027
47#define ADAU1761_POP_CLICK_SUPPRESS 0x4028
48#define ADAU1761_JACK_DETECT_PIN 0x4031
49#define ADAU1761_DEJITTER 0x4036
50#define ADAU1761_CLK_ENABLE0 0x40f9
51#define ADAU1761_CLK_ENABLE1 0x40fa
52
53#define ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW BIT(0)
54#define ADAU1761_DIGMIC_JACKDETECT_DIGMIC BIT(5)
55
56#define ADAU1761_DIFF_INPUT_VOL_LDEN BIT(0)
57
58#define ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP BIT(0)
59#define ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE BIT(1)
60
61#define ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP BIT(0)
62
63#define ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP BIT(0)
64
65#define ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP BIT(0)
66
67
68#define ADAU1761_FIRMWARE "adau1761.bin"
69
70static const struct reg_default adau1761_reg_defaults[] = {
71 { ADAU1761_DEJITTER, 0x03 },
72 { ADAU1761_DIGMIC_JACKDETECT, 0x00 },
73 { ADAU1761_REC_MIXER_LEFT0, 0x00 },
74 { ADAU1761_REC_MIXER_LEFT1, 0x00 },
75 { ADAU1761_REC_MIXER_RIGHT0, 0x00 },
76 { ADAU1761_REC_MIXER_RIGHT1, 0x00 },
77 { ADAU1761_LEFT_DIFF_INPUT_VOL, 0x00 },
83078521 78 { ADAU1761_ALC_CTRL0, 0x00 },
54227371
LPC
79 { ADAU1761_ALC_CTRL1, 0x00 },
80 { ADAU1761_ALC_CTRL2, 0x00 },
81 { ADAU1761_ALC_CTRL3, 0x00 },
dab464b6
LPC
82 { ADAU1761_RIGHT_DIFF_INPUT_VOL, 0x00 },
83 { ADAU1761_PLAY_LR_MIXER_LEFT, 0x00 },
84 { ADAU1761_PLAY_MIXER_LEFT0, 0x00 },
85 { ADAU1761_PLAY_MIXER_LEFT1, 0x00 },
86 { ADAU1761_PLAY_MIXER_RIGHT0, 0x00 },
87 { ADAU1761_PLAY_MIXER_RIGHT1, 0x00 },
88 { ADAU1761_PLAY_LR_MIXER_RIGHT, 0x00 },
89 { ADAU1761_PLAY_MIXER_MONO, 0x00 },
90 { ADAU1761_PLAY_HP_LEFT_VOL, 0x00 },
91 { ADAU1761_PLAY_HP_RIGHT_VOL, 0x00 },
92 { ADAU1761_PLAY_LINE_LEFT_VOL, 0x00 },
93 { ADAU1761_PLAY_LINE_RIGHT_VOL, 0x00 },
94 { ADAU1761_PLAY_MONO_OUTPUT_VOL, 0x00 },
95 { ADAU1761_POP_CLICK_SUPPRESS, 0x00 },
96 { ADAU1761_JACK_DETECT_PIN, 0x00 },
97 { ADAU1761_CLK_ENABLE0, 0x00 },
98 { ADAU1761_CLK_ENABLE1, 0x00 },
99 { ADAU17X1_CLOCK_CONTROL, 0x00 },
100 { ADAU17X1_PLL_CONTROL, 0x00 },
101 { ADAU17X1_REC_POWER_MGMT, 0x00 },
102 { ADAU17X1_MICBIAS, 0x00 },
103 { ADAU17X1_SERIAL_PORT0, 0x00 },
104 { ADAU17X1_SERIAL_PORT1, 0x00 },
105 { ADAU17X1_CONVERTER0, 0x00 },
106 { ADAU17X1_CONVERTER1, 0x00 },
107 { ADAU17X1_LEFT_INPUT_DIGITAL_VOL, 0x00 },
108 { ADAU17X1_RIGHT_INPUT_DIGITAL_VOL, 0x00 },
109 { ADAU17X1_ADC_CONTROL, 0x00 },
110 { ADAU17X1_PLAY_POWER_MGMT, 0x00 },
111 { ADAU17X1_DAC_CONTROL0, 0x00 },
112 { ADAU17X1_DAC_CONTROL1, 0x00 },
113 { ADAU17X1_DAC_CONTROL2, 0x00 },
114 { ADAU17X1_SERIAL_PORT_PAD, 0xaa },
115 { ADAU17X1_CONTROL_PORT_PAD0, 0xaa },
116 { ADAU17X1_CONTROL_PORT_PAD1, 0x00 },
117 { ADAU17X1_DSP_SAMPLING_RATE, 0x01 },
118 { ADAU17X1_SERIAL_INPUT_ROUTE, 0x00 },
119 { ADAU17X1_SERIAL_OUTPUT_ROUTE, 0x00 },
120 { ADAU17X1_DSP_ENABLE, 0x00 },
121 { ADAU17X1_DSP_RUN, 0x00 },
122 { ADAU17X1_SERIAL_SAMPLING_RATE, 0x00 },
123};
124
125static const DECLARE_TLV_DB_SCALE(adau1761_sing_in_tlv, -1500, 300, 1);
126static const DECLARE_TLV_DB_SCALE(adau1761_diff_in_tlv, -1200, 75, 0);
127static const DECLARE_TLV_DB_SCALE(adau1761_out_tlv, -5700, 100, 0);
128static const DECLARE_TLV_DB_SCALE(adau1761_sidetone_tlv, -1800, 300, 1);
129static const DECLARE_TLV_DB_SCALE(adau1761_boost_tlv, -600, 600, 1);
130static const DECLARE_TLV_DB_SCALE(adau1761_pga_boost_tlv, -2000, 2000, 1);
131
54227371
LPC
132static const DECLARE_TLV_DB_SCALE(adau1761_alc_max_gain_tlv, -1200, 600, 0);
133static const DECLARE_TLV_DB_SCALE(adau1761_alc_target_tlv, -2850, 150, 0);
134static const DECLARE_TLV_DB_SCALE(adau1761_alc_ng_threshold_tlv, -7650, 150, 0);
135
dab464b6
LPC
136static const unsigned int adau1761_bias_select_values[] = {
137 0, 2, 3,
138};
139
140static const char * const adau1761_bias_select_text[] = {
141 "Normal operation", "Enhanced performance", "Power saving",
142};
143
144static const char * const adau1761_bias_select_extreme_text[] = {
145 "Normal operation", "Extreme power saving", "Enhanced performance",
146 "Power saving",
147};
148
149static SOC_ENUM_SINGLE_DECL(adau1761_adc_bias_enum,
150 ADAU17X1_REC_POWER_MGMT, 3, adau1761_bias_select_extreme_text);
151static SOC_ENUM_SINGLE_DECL(adau1761_hp_bias_enum,
152 ADAU17X1_PLAY_POWER_MGMT, 6, adau1761_bias_select_extreme_text);
153static SOC_ENUM_SINGLE_DECL(adau1761_dac_bias_enum,
154 ADAU17X1_PLAY_POWER_MGMT, 4, adau1761_bias_select_extreme_text);
155static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_playback_bias_enum,
156 ADAU17X1_PLAY_POWER_MGMT, 2, 0x3, adau1761_bias_select_text,
157 adau1761_bias_select_values);
158static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_capture_bias_enum,
159 ADAU17X1_REC_POWER_MGMT, 1, 0x3, adau1761_bias_select_text,
160 adau1761_bias_select_values);
161
83078521
LPC
162static const unsigned int adau1761_pga_slew_time_values[] = {
163 3, 0, 1, 2,
164};
165
166static const char * const adau1761_pga_slew_time_text[] = {
167 "Off",
168 "24 ms",
169 "48 ms",
170 "96 ms",
171};
172
54227371
LPC
173static const char * const adau1761_alc_function_text[] = {
174 "Off",
175 "Right",
176 "Left",
177 "Stereo",
178 "DSP control",
179};
180
181static const char * const adau1761_alc_hold_time_text[] = {
182 "2.67 ms",
183 "5.34 ms",
184 "10.68 ms",
185 "21.36 ms",
186 "42.72 ms",
187 "85.44 ms",
188 "170.88 ms",
189 "341.76 ms",
190 "683.52 ms",
191 "1367 ms",
192 "2734.1 ms",
193 "5468.2 ms",
194 "10936 ms",
195 "21873 ms",
196 "43745 ms",
197 "87491 ms",
198};
199
200static const char * const adau1761_alc_attack_time_text[] = {
201 "6 ms",
202 "12 ms",
203 "24 ms",
204 "48 ms",
205 "96 ms",
206 "192 ms",
207 "384 ms",
208 "768 ms",
209 "1540 ms",
210 "3070 ms",
211 "6140 ms",
212 "12290 ms",
213 "24580 ms",
214 "49150 ms",
215 "98300 ms",
216 "196610 ms",
217};
218
219static const char * const adau1761_alc_decay_time_text[] = {
220 "24 ms",
221 "48 ms",
222 "96 ms",
223 "192 ms",
224 "384 ms",
225 "768 ms",
226 "15400 ms",
227 "30700 ms",
228 "61400 ms",
229 "12290 ms",
230 "24580 ms",
231 "49150 ms",
232 "98300 ms",
233 "196610 ms",
234 "393220 ms",
235 "786430 ms",
236};
237
238static const char * const adau1761_alc_ng_type_text[] = {
239 "Hold",
240 "Mute",
241 "Fade",
242 "Fade + Mute",
243};
244
83078521
LPC
245static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_pga_slew_time_enum,
246 ADAU1761_ALC_CTRL0, 6, 0x3, adau1761_pga_slew_time_text,
247 adau1761_pga_slew_time_values);
54227371
LPC
248static SOC_ENUM_SINGLE_DECL(adau1761_alc_function_enum,
249 ADAU1761_ALC_CTRL0, 0, adau1761_alc_function_text);
250static SOC_ENUM_SINGLE_DECL(adau1761_alc_hold_time_enum,
251 ADAU1761_ALC_CTRL1, 4, adau1761_alc_hold_time_text);
252static SOC_ENUM_SINGLE_DECL(adau1761_alc_attack_time_enum,
253 ADAU1761_ALC_CTRL2, 4, adau1761_alc_attack_time_text);
254static SOC_ENUM_SINGLE_DECL(adau1761_alc_decay_time_enum,
255 ADAU1761_ALC_CTRL2, 0, adau1761_alc_decay_time_text);
256static SOC_ENUM_SINGLE_DECL(adau1761_alc_ng_type_enum,
257 ADAU1761_ALC_CTRL3, 6, adau1761_alc_ng_type_text);
83078521 258
dab464b6
LPC
259static const struct snd_kcontrol_new adau1761_jack_detect_controls[] = {
260 SOC_SINGLE("Speaker Auto-mute Switch", ADAU1761_DIGMIC_JACKDETECT,
261 4, 1, 0),
262};
263
264static const struct snd_kcontrol_new adau1761_differential_mode_controls[] = {
265 SOC_DOUBLE_R_TLV("Capture Volume", ADAU1761_LEFT_DIFF_INPUT_VOL,
266 ADAU1761_RIGHT_DIFF_INPUT_VOL, 2, 0x3f, 0,
267 adau1761_diff_in_tlv),
268 SOC_DOUBLE_R("Capture Switch", ADAU1761_LEFT_DIFF_INPUT_VOL,
269 ADAU1761_RIGHT_DIFF_INPUT_VOL, 1, 1, 0),
270
271 SOC_DOUBLE_R_TLV("PGA Boost Capture Volume", ADAU1761_REC_MIXER_LEFT1,
272 ADAU1761_REC_MIXER_RIGHT1, 3, 2, 0, adau1761_pga_boost_tlv),
83078521
LPC
273
274 SOC_ENUM("PGA Capture Slew Time", adau1761_pga_slew_time_enum),
54227371
LPC
275
276 SOC_SINGLE_TLV("ALC Capture Max Gain Volume", ADAU1761_ALC_CTRL0,
277 3, 7, 0, adau1761_alc_max_gain_tlv),
278 SOC_ENUM("ALC Capture Function", adau1761_alc_function_enum),
279 SOC_ENUM("ALC Capture Hold Time", adau1761_alc_hold_time_enum),
280 SOC_SINGLE_TLV("ALC Capture Target Volume", ADAU1761_ALC_CTRL1,
281 0, 15, 0, adau1761_alc_target_tlv),
282 SOC_ENUM("ALC Capture Attack Time", adau1761_alc_decay_time_enum),
283 SOC_ENUM("ALC Capture Decay Time", adau1761_alc_attack_time_enum),
284 SOC_ENUM("ALC Capture Noise Gate Type", adau1761_alc_ng_type_enum),
285 SOC_SINGLE("ALC Capture Noise Gate Switch",
286 ADAU1761_ALC_CTRL3, 5, 1, 0),
287 SOC_SINGLE_TLV("ALC Capture Noise Gate Threshold Volume",
288 ADAU1761_ALC_CTRL3, 0, 31, 0, adau1761_alc_ng_threshold_tlv),
dab464b6
LPC
289};
290
291static const struct snd_kcontrol_new adau1761_single_mode_controls[] = {
292 SOC_SINGLE_TLV("Input 1 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
293 4, 7, 0, adau1761_sing_in_tlv),
294 SOC_SINGLE_TLV("Input 2 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
295 1, 7, 0, adau1761_sing_in_tlv),
296 SOC_SINGLE_TLV("Input 3 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
297 4, 7, 0, adau1761_sing_in_tlv),
298 SOC_SINGLE_TLV("Input 4 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
299 1, 7, 0, adau1761_sing_in_tlv),
300};
301
302static const struct snd_kcontrol_new adau1761_controls[] = {
303 SOC_DOUBLE_R_TLV("Aux Capture Volume", ADAU1761_REC_MIXER_LEFT1,
304 ADAU1761_REC_MIXER_RIGHT1, 0, 7, 0, adau1761_sing_in_tlv),
305
306 SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1761_PLAY_HP_LEFT_VOL,
307 ADAU1761_PLAY_HP_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
308 SOC_DOUBLE_R("Headphone Playback Switch", ADAU1761_PLAY_HP_LEFT_VOL,
309 ADAU1761_PLAY_HP_RIGHT_VOL, 1, 1, 0),
310 SOC_DOUBLE_R_TLV("Lineout Playback Volume", ADAU1761_PLAY_LINE_LEFT_VOL,
311 ADAU1761_PLAY_LINE_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
312 SOC_DOUBLE_R("Lineout Playback Switch", ADAU1761_PLAY_LINE_LEFT_VOL,
313 ADAU1761_PLAY_LINE_RIGHT_VOL, 1, 1, 0),
314
315 SOC_ENUM("ADC Bias", adau1761_adc_bias_enum),
316 SOC_ENUM("DAC Bias", adau1761_dac_bias_enum),
317 SOC_ENUM("Capture Bias", adau1761_capture_bias_enum),
318 SOC_ENUM("Playback Bias", adau1761_playback_bias_enum),
319 SOC_ENUM("Headphone Bias", adau1761_hp_bias_enum),
320};
321
322static const struct snd_kcontrol_new adau1761_mono_controls[] = {
323 SOC_SINGLE_TLV("Mono Playback Volume", ADAU1761_PLAY_MONO_OUTPUT_VOL,
324 2, 0x3f, 0, adau1761_out_tlv),
325 SOC_SINGLE("Mono Playback Switch", ADAU1761_PLAY_MONO_OUTPUT_VOL,
326 1, 1, 0),
327};
328
329static const struct snd_kcontrol_new adau1761_left_mixer_controls[] = {
330 SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
331 ADAU1761_PLAY_MIXER_LEFT0, 5, 1, 0),
332 SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
333 ADAU1761_PLAY_MIXER_LEFT0, 6, 1, 0),
334 SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
335 ADAU1761_PLAY_MIXER_LEFT0, 1, 8, 0, adau1761_sidetone_tlv),
336 SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
337 ADAU1761_PLAY_MIXER_LEFT1, 4, 8, 0, adau1761_sidetone_tlv),
338 SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
339 ADAU1761_PLAY_MIXER_LEFT1, 0, 8, 0, adau1761_sidetone_tlv),
340};
341
342static const struct snd_kcontrol_new adau1761_right_mixer_controls[] = {
343 SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
344 ADAU1761_PLAY_MIXER_RIGHT0, 5, 1, 0),
345 SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
346 ADAU1761_PLAY_MIXER_RIGHT0, 6, 1, 0),
347 SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
348 ADAU1761_PLAY_MIXER_RIGHT0, 1, 8, 0, adau1761_sidetone_tlv),
349 SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
350 ADAU1761_PLAY_MIXER_RIGHT1, 4, 8, 0, adau1761_sidetone_tlv),
351 SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
352 ADAU1761_PLAY_MIXER_RIGHT1, 0, 8, 0, adau1761_sidetone_tlv),
353};
354
355static const struct snd_kcontrol_new adau1761_left_lr_mixer_controls[] = {
356 SOC_DAPM_SINGLE_TLV("Left Volume",
357 ADAU1761_PLAY_LR_MIXER_LEFT, 1, 2, 0, adau1761_boost_tlv),
358 SOC_DAPM_SINGLE_TLV("Right Volume",
359 ADAU1761_PLAY_LR_MIXER_LEFT, 3, 2, 0, adau1761_boost_tlv),
360};
361
362static const struct snd_kcontrol_new adau1761_right_lr_mixer_controls[] = {
363 SOC_DAPM_SINGLE_TLV("Left Volume",
364 ADAU1761_PLAY_LR_MIXER_RIGHT, 1, 2, 0, adau1761_boost_tlv),
365 SOC_DAPM_SINGLE_TLV("Right Volume",
366 ADAU1761_PLAY_LR_MIXER_RIGHT, 3, 2, 0, adau1761_boost_tlv),
367};
368
369static const char * const adau1761_input_mux_text[] = {
370 "ADC", "DMIC",
371};
372
373static SOC_ENUM_SINGLE_DECL(adau1761_input_mux_enum,
374 ADAU17X1_ADC_CONTROL, 2, adau1761_input_mux_text);
375
376static const struct snd_kcontrol_new adau1761_input_mux_control =
377 SOC_DAPM_ENUM("Input Select", adau1761_input_mux_enum);
378
379static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w,
380 struct snd_kcontrol *kcontrol, int event)
381{
dd08102a
KM
382 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
383 struct adau *adau = snd_soc_component_get_drvdata(component);
dab464b6
LPC
384
385 /* After any power changes have been made the dejitter circuit
386 * has to be reinitialized. */
387 regmap_write(adau->regmap, ADAU1761_DEJITTER, 0);
388 if (!adau->master)
389 regmap_write(adau->regmap, ADAU1761_DEJITTER, 3);
390
391 return 0;
392}
393
394static const struct snd_soc_dapm_widget adau1x61_dapm_widgets[] = {
395 SND_SOC_DAPM_MIXER("Left Input Mixer", ADAU1761_REC_MIXER_LEFT0, 0, 0,
396 NULL, 0),
397 SND_SOC_DAPM_MIXER("Right Input Mixer", ADAU1761_REC_MIXER_RIGHT0, 0, 0,
398 NULL, 0),
399
400 SOC_MIXER_ARRAY("Left Playback Mixer", ADAU1761_PLAY_MIXER_LEFT0,
401 0, 0, adau1761_left_mixer_controls),
402 SOC_MIXER_ARRAY("Right Playback Mixer", ADAU1761_PLAY_MIXER_RIGHT0,
403 0, 0, adau1761_right_mixer_controls),
404 SOC_MIXER_ARRAY("Left LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_LEFT,
405 0, 0, adau1761_left_lr_mixer_controls),
406 SOC_MIXER_ARRAY("Right LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_RIGHT,
407 0, 0, adau1761_right_lr_mixer_controls),
408
409 SND_SOC_DAPM_SUPPLY("Headphone", ADAU1761_PLAY_HP_LEFT_VOL,
410 0, 0, NULL, 0),
411
412 SND_SOC_DAPM_SUPPLY_S("SYSCLK", 2, SND_SOC_NOPM, 0, 0, NULL, 0),
413
414 SND_SOC_DAPM_POST("Dejitter fixup", adau1761_dejitter_fixup),
415
416 SND_SOC_DAPM_INPUT("LAUX"),
417 SND_SOC_DAPM_INPUT("RAUX"),
418 SND_SOC_DAPM_INPUT("LINP"),
419 SND_SOC_DAPM_INPUT("LINN"),
420 SND_SOC_DAPM_INPUT("RINP"),
421 SND_SOC_DAPM_INPUT("RINN"),
422
423 SND_SOC_DAPM_OUTPUT("LOUT"),
424 SND_SOC_DAPM_OUTPUT("ROUT"),
425 SND_SOC_DAPM_OUTPUT("LHP"),
426 SND_SOC_DAPM_OUTPUT("RHP"),
427};
428
429static const struct snd_soc_dapm_widget adau1761_mono_dapm_widgets[] = {
430 SND_SOC_DAPM_MIXER("Mono Playback Mixer", ADAU1761_PLAY_MIXER_MONO,
431 0, 0, NULL, 0),
432
433 SND_SOC_DAPM_OUTPUT("MONOOUT"),
434};
435
436static const struct snd_soc_dapm_widget adau1761_capless_dapm_widgets[] = {
437 SND_SOC_DAPM_SUPPLY_S("Headphone VGND", 1, ADAU1761_PLAY_MIXER_MONO,
438 0, 0, NULL, 0),
439};
440
441static const struct snd_soc_dapm_route adau1x61_dapm_routes[] = {
442 { "Left Input Mixer", NULL, "LINP" },
443 { "Left Input Mixer", NULL, "LINN" },
444 { "Left Input Mixer", NULL, "LAUX" },
445
446 { "Right Input Mixer", NULL, "RINP" },
447 { "Right Input Mixer", NULL, "RINN" },
448 { "Right Input Mixer", NULL, "RAUX" },
449
450 { "Left Playback Mixer", NULL, "Left Playback Enable"},
451 { "Right Playback Mixer", NULL, "Right Playback Enable"},
452 { "Left LR Playback Mixer", NULL, "Left Playback Enable"},
453 { "Right LR Playback Mixer", NULL, "Right Playback Enable"},
454
455 { "Left Playback Mixer", "Left DAC Switch", "Left DAC" },
456 { "Left Playback Mixer", "Right DAC Switch", "Right DAC" },
457
458 { "Right Playback Mixer", "Left DAC Switch", "Left DAC" },
459 { "Right Playback Mixer", "Right DAC Switch", "Right DAC" },
460
461 { "Left LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
462 { "Left LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
463
464 { "Right LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
465 { "Right LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
466
467 { "LHP", NULL, "Left Playback Mixer" },
468 { "RHP", NULL, "Right Playback Mixer" },
469
470 { "LHP", NULL, "Headphone" },
471 { "RHP", NULL, "Headphone" },
472
473 { "LOUT", NULL, "Left LR Playback Mixer" },
474 { "ROUT", NULL, "Right LR Playback Mixer" },
475
476 { "Left Playback Mixer", "Aux Bypass Volume", "LAUX" },
477 { "Left Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
478 { "Left Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
479 { "Right Playback Mixer", "Aux Bypass Volume", "RAUX" },
480 { "Right Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
481 { "Right Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
482};
483
484static const struct snd_soc_dapm_route adau1761_mono_dapm_routes[] = {
485 { "Mono Playback Mixer", NULL, "Left Playback Mixer" },
486 { "Mono Playback Mixer", NULL, "Right Playback Mixer" },
487
488 { "MONOOUT", NULL, "Mono Playback Mixer" },
489};
490
491static const struct snd_soc_dapm_route adau1761_capless_dapm_routes[] = {
492 { "Headphone", NULL, "Headphone VGND" },
493};
494
495static const struct snd_soc_dapm_widget adau1761_dmic_widgets[] = {
496 SND_SOC_DAPM_MUX("Left Decimator Mux", SND_SOC_NOPM, 0, 0,
497 &adau1761_input_mux_control),
498 SND_SOC_DAPM_MUX("Right Decimator Mux", SND_SOC_NOPM, 0, 0,
499 &adau1761_input_mux_control),
500
501 SND_SOC_DAPM_INPUT("DMIC"),
502};
503
504static const struct snd_soc_dapm_route adau1761_dmic_routes[] = {
505 { "Left Decimator Mux", "ADC", "Left Input Mixer" },
506 { "Left Decimator Mux", "DMIC", "DMIC" },
507 { "Right Decimator Mux", "ADC", "Right Input Mixer" },
508 { "Right Decimator Mux", "DMIC", "DMIC" },
509
510 { "Left Decimator", NULL, "Left Decimator Mux" },
511 { "Right Decimator", NULL, "Right Decimator Mux" },
512};
513
514static const struct snd_soc_dapm_route adau1761_no_dmic_routes[] = {
515 { "Left Decimator", NULL, "Left Input Mixer" },
516 { "Right Decimator", NULL, "Right Input Mixer" },
517};
518
519static const struct snd_soc_dapm_widget adau1761_dapm_widgets[] = {
520 SND_SOC_DAPM_SUPPLY("Serial Port Clock", ADAU1761_CLK_ENABLE0,
521 0, 0, NULL, 0),
522 SND_SOC_DAPM_SUPPLY("Serial Input Routing Clock", ADAU1761_CLK_ENABLE0,
523 1, 0, NULL, 0),
524 SND_SOC_DAPM_SUPPLY("Serial Output Routing Clock", ADAU1761_CLK_ENABLE0,
525 3, 0, NULL, 0),
526
527 SND_SOC_DAPM_SUPPLY("Decimator Resync Clock", ADAU1761_CLK_ENABLE0,
528 4, 0, NULL, 0),
529 SND_SOC_DAPM_SUPPLY("Interpolator Resync Clock", ADAU1761_CLK_ENABLE0,
530 2, 0, NULL, 0),
531
532 SND_SOC_DAPM_SUPPLY("Slew Clock", ADAU1761_CLK_ENABLE0, 6, 0, NULL, 0),
3b283f08 533 SND_SOC_DAPM_SUPPLY("ALC Clock", ADAU1761_CLK_ENABLE0, 5, 0, NULL, 0),
dab464b6
LPC
534
535 SND_SOC_DAPM_SUPPLY_S("Digital Clock 0", 1, ADAU1761_CLK_ENABLE1,
536 0, 0, NULL, 0),
537 SND_SOC_DAPM_SUPPLY_S("Digital Clock 1", 1, ADAU1761_CLK_ENABLE1,
538 1, 0, NULL, 0),
539};
540
541static const struct snd_soc_dapm_route adau1761_dapm_routes[] = {
542 { "Left Decimator", NULL, "Digital Clock 0", },
543 { "Right Decimator", NULL, "Digital Clock 0", },
544 { "Left DAC", NULL, "Digital Clock 0", },
545 { "Right DAC", NULL, "Digital Clock 0", },
546
547 { "AIFCLK", NULL, "Digital Clock 1" },
548
549 { "Playback", NULL, "Serial Port Clock" },
550 { "Capture", NULL, "Serial Port Clock" },
551 { "Playback", NULL, "Serial Input Routing Clock" },
552 { "Capture", NULL, "Serial Output Routing Clock" },
553
554 { "Left Decimator", NULL, "Decimator Resync Clock" },
555 { "Right Decimator", NULL, "Decimator Resync Clock" },
556 { "Left DAC", NULL, "Interpolator Resync Clock" },
557 { "Right DAC", NULL, "Interpolator Resync Clock" },
558
559 { "DSP", NULL, "Digital Clock 0" },
560
561 { "Slew Clock", NULL, "Digital Clock 0" },
562 { "Right Playback Mixer", NULL, "Slew Clock" },
563 { "Left Playback Mixer", NULL, "Slew Clock" },
564
3b283f08
LPC
565 { "Left Input Mixer", NULL, "ALC Clock" },
566 { "Right Input Mixer", NULL, "ALC Clock" },
567
dab464b6
LPC
568 { "Digital Clock 0", NULL, "SYSCLK" },
569 { "Digital Clock 1", NULL, "SYSCLK" },
570};
571
dd08102a 572static int adau1761_set_bias_level(struct snd_soc_component *component,
dab464b6
LPC
573 enum snd_soc_bias_level level)
574{
dd08102a 575 struct adau *adau = snd_soc_component_get_drvdata(component);
dab464b6
LPC
576
577 switch (level) {
578 case SND_SOC_BIAS_ON:
579 break;
580 case SND_SOC_BIAS_PREPARE:
581 break;
582 case SND_SOC_BIAS_STANDBY:
27d6e7d1 583 regcache_cache_only(adau->regmap, false);
dab464b6
LPC
584 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
585 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
586 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
dd08102a 587 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
27d6e7d1 588 regcache_sync(adau->regmap);
dab464b6
LPC
589 break;
590 case SND_SOC_BIAS_OFF:
591 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
592 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);
27d6e7d1 593 regcache_cache_only(adau->regmap, true);
dab464b6
LPC
594 break;
595
596 }
dab464b6
LPC
597 return 0;
598}
599
600static enum adau1761_output_mode adau1761_get_lineout_mode(
dd08102a 601 struct snd_soc_component *component)
dab464b6 602{
dd08102a 603 struct adau1761_platform_data *pdata = component->dev->platform_data;
dab464b6
LPC
604
605 if (pdata)
606 return pdata->lineout_mode;
607
608 return ADAU1761_OUTPUT_MODE_LINE;
609}
610
dd08102a 611static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component)
dab464b6 612{
dd08102a
KM
613 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
614 struct adau1761_platform_data *pdata = component->dev->platform_data;
615 struct adau *adau = snd_soc_component_get_drvdata(component);
dab464b6
LPC
616 enum adau1761_digmic_jackdet_pin_mode mode;
617 unsigned int val = 0;
618 int ret;
619
620 if (pdata)
621 mode = pdata->digmic_jackdetect_pin_mode;
622 else
623 mode = ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE;
624
625 switch (mode) {
626 case ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT:
627 switch (pdata->jackdetect_debounce_time) {
628 case ADAU1761_JACKDETECT_DEBOUNCE_5MS:
629 case ADAU1761_JACKDETECT_DEBOUNCE_10MS:
630 case ADAU1761_JACKDETECT_DEBOUNCE_20MS:
631 case ADAU1761_JACKDETECT_DEBOUNCE_40MS:
632 val |= pdata->jackdetect_debounce_time << 6;
633 break;
634 default:
635 return -EINVAL;
636 }
637 if (pdata->jackdetect_active_low)
638 val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW;
639
dd08102a 640 ret = snd_soc_add_component_controls(component,
dab464b6
LPC
641 adau1761_jack_detect_controls,
642 ARRAY_SIZE(adau1761_jack_detect_controls));
643 if (ret)
644 return ret;
7e293179
TI
645 /* fall through */
646 case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE:
33c7b140 647 ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes,
dab464b6
LPC
648 ARRAY_SIZE(adau1761_no_dmic_routes));
649 if (ret)
650 return ret;
651 break;
652 case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
33c7b140 653 ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets,
dab464b6
LPC
654 ARRAY_SIZE(adau1761_dmic_widgets));
655 if (ret)
656 return ret;
657
33c7b140 658 ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes,
dab464b6
LPC
659 ARRAY_SIZE(adau1761_dmic_routes));
660 if (ret)
661 return ret;
662
663 val |= ADAU1761_DIGMIC_JACKDETECT_DIGMIC;
664 break;
665 default:
666 return -EINVAL;
667 }
668
669 regmap_write(adau->regmap, ADAU1761_DIGMIC_JACKDETECT, val);
670
671 return 0;
672}
673
dd08102a 674static int adau1761_setup_headphone_mode(struct snd_soc_component *component)
dab464b6 675{
dd08102a
KM
676 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
677 struct adau *adau = snd_soc_component_get_drvdata(component);
678 struct adau1761_platform_data *pdata = component->dev->platform_data;
dab464b6
LPC
679 enum adau1761_output_mode mode;
680 int ret;
681
682 if (pdata)
683 mode = pdata->headphone_mode;
684 else
685 mode = ADAU1761_OUTPUT_MODE_HEADPHONE;
686
687 switch (mode) {
688 case ADAU1761_OUTPUT_MODE_LINE:
689 break;
690 case ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS:
691 regmap_update_bits(adau->regmap, ADAU1761_PLAY_MONO_OUTPUT_VOL,
692 ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
693 ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE,
694 ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
695 ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE);
696 /* fallthrough */
697 case ADAU1761_OUTPUT_MODE_HEADPHONE:
698 regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL,
699 ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP,
700 ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP);
701 break;
702 default:
703 return -EINVAL;
704 }
705
706 if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
33c7b140 707 ret = snd_soc_dapm_new_controls(dapm,
dab464b6
LPC
708 adau1761_capless_dapm_widgets,
709 ARRAY_SIZE(adau1761_capless_dapm_widgets));
710 if (ret)
711 return ret;
33c7b140 712 ret = snd_soc_dapm_add_routes(dapm,
dab464b6
LPC
713 adau1761_capless_dapm_routes,
714 ARRAY_SIZE(adau1761_capless_dapm_routes));
715 } else {
dd08102a 716 ret = snd_soc_add_component_controls(component, adau1761_mono_controls,
dab464b6
LPC
717 ARRAY_SIZE(adau1761_mono_controls));
718 if (ret)
719 return ret;
33c7b140 720 ret = snd_soc_dapm_new_controls(dapm,
dab464b6
LPC
721 adau1761_mono_dapm_widgets,
722 ARRAY_SIZE(adau1761_mono_dapm_widgets));
723 if (ret)
724 return ret;
33c7b140 725 ret = snd_soc_dapm_add_routes(dapm,
dab464b6
LPC
726 adau1761_mono_dapm_routes,
727 ARRAY_SIZE(adau1761_mono_dapm_routes));
728 }
729
730 return ret;
731}
732
733static bool adau1761_readable_register(struct device *dev, unsigned int reg)
734{
735 switch (reg) {
736 case ADAU1761_DIGMIC_JACKDETECT:
737 case ADAU1761_REC_MIXER_LEFT0:
738 case ADAU1761_REC_MIXER_LEFT1:
739 case ADAU1761_REC_MIXER_RIGHT0:
740 case ADAU1761_REC_MIXER_RIGHT1:
741 case ADAU1761_LEFT_DIFF_INPUT_VOL:
742 case ADAU1761_RIGHT_DIFF_INPUT_VOL:
743 case ADAU1761_PLAY_LR_MIXER_LEFT:
744 case ADAU1761_PLAY_MIXER_LEFT0:
745 case ADAU1761_PLAY_MIXER_LEFT1:
746 case ADAU1761_PLAY_MIXER_RIGHT0:
747 case ADAU1761_PLAY_MIXER_RIGHT1:
748 case ADAU1761_PLAY_LR_MIXER_RIGHT:
749 case ADAU1761_PLAY_MIXER_MONO:
750 case ADAU1761_PLAY_HP_LEFT_VOL:
751 case ADAU1761_PLAY_HP_RIGHT_VOL:
752 case ADAU1761_PLAY_LINE_LEFT_VOL:
753 case ADAU1761_PLAY_LINE_RIGHT_VOL:
754 case ADAU1761_PLAY_MONO_OUTPUT_VOL:
755 case ADAU1761_POP_CLICK_SUPPRESS:
756 case ADAU1761_JACK_DETECT_PIN:
757 case ADAU1761_DEJITTER:
758 case ADAU1761_CLK_ENABLE0:
759 case ADAU1761_CLK_ENABLE1:
83078521 760 case ADAU1761_ALC_CTRL0:
54227371
LPC
761 case ADAU1761_ALC_CTRL1:
762 case ADAU1761_ALC_CTRL2:
763 case ADAU1761_ALC_CTRL3:
dab464b6
LPC
764 return true;
765 default:
766 break;
767 }
768
769 return adau17x1_readable_register(dev, reg);
770}
771
dd08102a 772static int adau1761_component_probe(struct snd_soc_component *component)
dab464b6 773{
dd08102a
KM
774 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
775 struct adau1761_platform_data *pdata = component->dev->platform_data;
776 struct adau *adau = snd_soc_component_get_drvdata(component);
dab464b6
LPC
777 int ret;
778
dd08102a 779 ret = adau17x1_add_widgets(component);
dab464b6
LPC
780 if (ret < 0)
781 return ret;
782
783 if (pdata && pdata->input_differential) {
784 regmap_update_bits(adau->regmap, ADAU1761_LEFT_DIFF_INPUT_VOL,
785 ADAU1761_DIFF_INPUT_VOL_LDEN,
786 ADAU1761_DIFF_INPUT_VOL_LDEN);
787 regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
788 ADAU1761_DIFF_INPUT_VOL_LDEN,
789 ADAU1761_DIFF_INPUT_VOL_LDEN);
dd08102a 790 ret = snd_soc_add_component_controls(component,
dab464b6
LPC
791 adau1761_differential_mode_controls,
792 ARRAY_SIZE(adau1761_differential_mode_controls));
793 if (ret)
794 return ret;
795 } else {
dd08102a 796 ret = snd_soc_add_component_controls(component,
dab464b6
LPC
797 adau1761_single_mode_controls,
798 ARRAY_SIZE(adau1761_single_mode_controls));
799 if (ret)
800 return ret;
801 }
802
dd08102a 803 switch (adau1761_get_lineout_mode(component)) {
dab464b6
LPC
804 case ADAU1761_OUTPUT_MODE_LINE:
805 break;
806 case ADAU1761_OUTPUT_MODE_HEADPHONE:
807 regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_LEFT_VOL,
808 ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP,
809 ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP);
810 regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_RIGHT_VOL,
811 ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP,
812 ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP);
813 break;
814 default:
815 return -EINVAL;
816 }
817
dd08102a 818 ret = adau1761_setup_headphone_mode(component);
dab464b6
LPC
819 if (ret)
820 return ret;
821
dd08102a 822 ret = adau1761_setup_digmic_jackdetect(component);
dab464b6
LPC
823 if (ret)
824 return ret;
825
826 if (adau->type == ADAU1761) {
33c7b140 827 ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets,
dab464b6
LPC
828 ARRAY_SIZE(adau1761_dapm_widgets));
829 if (ret)
830 return ret;
831
33c7b140 832 ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes,
dab464b6
LPC
833 ARRAY_SIZE(adau1761_dapm_routes));
834 if (ret)
835 return ret;
dab464b6
LPC
836 }
837
dd08102a 838 ret = adau17x1_add_routes(component);
dab464b6
LPC
839 if (ret < 0)
840 return ret;
841
842 return 0;
843}
844
dd08102a
KM
845static const struct snd_soc_component_driver adau1761_component_driver = {
846 .probe = adau1761_component_probe,
847 .resume = adau17x1_resume,
848 .set_bias_level = adau1761_set_bias_level,
849 .controls = adau1761_controls,
850 .num_controls = ARRAY_SIZE(adau1761_controls),
851 .dapm_widgets = adau1x61_dapm_widgets,
852 .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets),
853 .dapm_routes = adau1x61_dapm_routes,
854 .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes),
855 .suspend_bias_off = 1,
856 .idle_bias_on = 1,
857 .use_pmdown_time = 1,
858 .endianness = 1,
859 .non_legacy_dai_naming = 1,
dab464b6
LPC
860};
861
862#define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
863 SNDRV_PCM_FMTBIT_S32_LE)
864
865static struct snd_soc_dai_driver adau1361_dai_driver = {
866 .name = "adau-hifi",
867 .playback = {
868 .stream_name = "Playback",
869 .channels_min = 2,
870 .channels_max = 4,
871 .rates = SNDRV_PCM_RATE_8000_96000,
872 .formats = ADAU1761_FORMATS,
873 },
874 .capture = {
875 .stream_name = "Capture",
876 .channels_min = 2,
877 .channels_max = 4,
878 .rates = SNDRV_PCM_RATE_8000_96000,
879 .formats = ADAU1761_FORMATS,
880 },
881 .ops = &adau17x1_dai_ops,
882};
883
884static struct snd_soc_dai_driver adau1761_dai_driver = {
885 .name = "adau-hifi",
886 .playback = {
887 .stream_name = "Playback",
888 .channels_min = 2,
889 .channels_max = 8,
890 .rates = SNDRV_PCM_RATE_8000_96000,
891 .formats = ADAU1761_FORMATS,
892 },
893 .capture = {
894 .stream_name = "Capture",
895 .channels_min = 2,
896 .channels_max = 8,
897 .rates = SNDRV_PCM_RATE_8000_96000,
898 .formats = ADAU1761_FORMATS,
899 },
900 .ops = &adau17x1_dai_ops,
901};
902
903int adau1761_probe(struct device *dev, struct regmap *regmap,
904 enum adau17x1_type type, void (*switch_mode)(struct device *dev))
905{
906 struct snd_soc_dai_driver *dai_drv;
d48b088e 907 const char *firmware_name;
dab464b6
LPC
908 int ret;
909
d48b088e 910 if (type == ADAU1361) {
dab464b6 911 dai_drv = &adau1361_dai_driver;
d48b088e
LPC
912 firmware_name = NULL;
913 } else {
dab464b6 914 dai_drv = &adau1761_dai_driver;
d48b088e
LPC
915 firmware_name = ADAU1761_FIRMWARE;
916 }
917
918 ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name);
919 if (ret)
920 return ret;
dab464b6 921
27d6e7d1
AI
922 /* Enable cache only mode as we could miss writes before bias level
923 * reaches standby and the core clock is enabled */
924 regcache_cache_only(regmap, true);
925
dd08102a
KM
926 return devm_snd_soc_register_component(dev, &adau1761_component_driver,
927 dai_drv, 1);
dab464b6
LPC
928}
929EXPORT_SYMBOL_GPL(adau1761_probe);
930
931const struct regmap_config adau1761_regmap_config = {
932 .val_bits = 8,
933 .reg_bits = 16,
934 .max_register = 0x40fa,
935 .reg_defaults = adau1761_reg_defaults,
936 .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults),
937 .readable_reg = adau1761_readable_register,
938 .volatile_reg = adau17x1_volatile_register,
dee9cec4 939 .precious_reg = adau17x1_precious_register,
dab464b6
LPC
940 .cache_type = REGCACHE_RBTREE,
941};
942EXPORT_SYMBOL_GPL(adau1761_regmap_config);
943
944MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver");
945MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
946MODULE_LICENSE("GPL");