0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/i2c.h>
0012 #include <linux/spi/spi.h>
0013 #include <linux/slab.h>
0014 #include <sound/core.h>
0015 #include <sound/pcm.h>
0016 #include <sound/pcm_params.h>
0017 #include <sound/soc.h>
0018 #include <sound/tlv.h>
0019 #include <linux/platform_data/adau17x1.h>
0020
0021 #include "adau17x1.h"
0022 #include "adau1761.h"
0023
0024 #define ADAU1761_DIGMIC_JACKDETECT 0x4008
0025 #define ADAU1761_REC_MIXER_LEFT0 0x400a
0026 #define ADAU1761_REC_MIXER_LEFT1 0x400b
0027 #define ADAU1761_REC_MIXER_RIGHT0 0x400c
0028 #define ADAU1761_REC_MIXER_RIGHT1 0x400d
0029 #define ADAU1761_LEFT_DIFF_INPUT_VOL 0x400e
0030 #define ADAU1761_RIGHT_DIFF_INPUT_VOL 0x400f
0031 #define ADAU1761_ALC_CTRL0 0x4011
0032 #define ADAU1761_ALC_CTRL1 0x4012
0033 #define ADAU1761_ALC_CTRL2 0x4013
0034 #define ADAU1761_ALC_CTRL3 0x4014
0035 #define ADAU1761_PLAY_LR_MIXER_LEFT 0x4020
0036 #define ADAU1761_PLAY_MIXER_LEFT0 0x401c
0037 #define ADAU1761_PLAY_MIXER_LEFT1 0x401d
0038 #define ADAU1761_PLAY_MIXER_RIGHT0 0x401e
0039 #define ADAU1761_PLAY_MIXER_RIGHT1 0x401f
0040 #define ADAU1761_PLAY_LR_MIXER_RIGHT 0x4021
0041 #define ADAU1761_PLAY_MIXER_MONO 0x4022
0042 #define ADAU1761_PLAY_HP_LEFT_VOL 0x4023
0043 #define ADAU1761_PLAY_HP_RIGHT_VOL 0x4024
0044 #define ADAU1761_PLAY_LINE_LEFT_VOL 0x4025
0045 #define ADAU1761_PLAY_LINE_RIGHT_VOL 0x4026
0046 #define ADAU1761_PLAY_MONO_OUTPUT_VOL 0x4027
0047 #define ADAU1761_POP_CLICK_SUPPRESS 0x4028
0048 #define ADAU1761_JACK_DETECT_PIN 0x4031
0049 #define ADAU1761_DEJITTER 0x4036
0050 #define ADAU1761_CLK_ENABLE0 0x40f9
0051 #define ADAU1761_CLK_ENABLE1 0x40fa
0052
0053 #define ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW BIT(0)
0054 #define ADAU1761_DIGMIC_JACKDETECT_DIGMIC BIT(5)
0055
0056 #define ADAU1761_DIFF_INPUT_VOL_LDEN BIT(0)
0057
0058 #define ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP BIT(0)
0059 #define ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE BIT(1)
0060
0061 #define ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP BIT(0)
0062
0063 #define ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP BIT(0)
0064
0065 #define ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP BIT(0)
0066
0067
0068 #define ADAU1761_FIRMWARE "adau1761.bin"
0069
0070 static const struct reg_default adau1761_reg_defaults[] = {
0071 { ADAU1761_DEJITTER, 0x03 },
0072 { ADAU1761_DIGMIC_JACKDETECT, 0x00 },
0073 { ADAU1761_REC_MIXER_LEFT0, 0x00 },
0074 { ADAU1761_REC_MIXER_LEFT1, 0x00 },
0075 { ADAU1761_REC_MIXER_RIGHT0, 0x00 },
0076 { ADAU1761_REC_MIXER_RIGHT1, 0x00 },
0077 { ADAU1761_LEFT_DIFF_INPUT_VOL, 0x00 },
0078 { ADAU1761_ALC_CTRL0, 0x00 },
0079 { ADAU1761_ALC_CTRL1, 0x00 },
0080 { ADAU1761_ALC_CTRL2, 0x00 },
0081 { ADAU1761_ALC_CTRL3, 0x00 },
0082 { ADAU1761_RIGHT_DIFF_INPUT_VOL, 0x00 },
0083 { ADAU1761_PLAY_LR_MIXER_LEFT, 0x00 },
0084 { ADAU1761_PLAY_MIXER_LEFT0, 0x00 },
0085 { ADAU1761_PLAY_MIXER_LEFT1, 0x00 },
0086 { ADAU1761_PLAY_MIXER_RIGHT0, 0x00 },
0087 { ADAU1761_PLAY_MIXER_RIGHT1, 0x00 },
0088 { ADAU1761_PLAY_LR_MIXER_RIGHT, 0x00 },
0089 { ADAU1761_PLAY_MIXER_MONO, 0x00 },
0090 { ADAU1761_PLAY_HP_LEFT_VOL, 0x00 },
0091 { ADAU1761_PLAY_HP_RIGHT_VOL, 0x00 },
0092 { ADAU1761_PLAY_LINE_LEFT_VOL, 0x00 },
0093 { ADAU1761_PLAY_LINE_RIGHT_VOL, 0x00 },
0094 { ADAU1761_PLAY_MONO_OUTPUT_VOL, 0x00 },
0095 { ADAU1761_POP_CLICK_SUPPRESS, 0x00 },
0096 { ADAU1761_JACK_DETECT_PIN, 0x00 },
0097 { ADAU1761_CLK_ENABLE0, 0x00 },
0098 { ADAU1761_CLK_ENABLE1, 0x00 },
0099 { ADAU17X1_CLOCK_CONTROL, 0x00 },
0100 { ADAU17X1_PLL_CONTROL, 0x00 },
0101 { ADAU17X1_REC_POWER_MGMT, 0x00 },
0102 { ADAU17X1_MICBIAS, 0x00 },
0103 { ADAU17X1_SERIAL_PORT0, 0x00 },
0104 { ADAU17X1_SERIAL_PORT1, 0x00 },
0105 { ADAU17X1_CONVERTER0, 0x00 },
0106 { ADAU17X1_CONVERTER1, 0x00 },
0107 { ADAU17X1_LEFT_INPUT_DIGITAL_VOL, 0x00 },
0108 { ADAU17X1_RIGHT_INPUT_DIGITAL_VOL, 0x00 },
0109 { ADAU17X1_ADC_CONTROL, 0x00 },
0110 { ADAU17X1_PLAY_POWER_MGMT, 0x00 },
0111 { ADAU17X1_DAC_CONTROL0, 0x00 },
0112 { ADAU17X1_DAC_CONTROL1, 0x00 },
0113 { ADAU17X1_DAC_CONTROL2, 0x00 },
0114 { ADAU17X1_SERIAL_PORT_PAD, 0xaa },
0115 { ADAU17X1_CONTROL_PORT_PAD0, 0xaa },
0116 { ADAU17X1_CONTROL_PORT_PAD1, 0x00 },
0117 { ADAU17X1_DSP_SAMPLING_RATE, 0x01 },
0118 { ADAU17X1_SERIAL_INPUT_ROUTE, 0x00 },
0119 { ADAU17X1_SERIAL_OUTPUT_ROUTE, 0x00 },
0120 { ADAU17X1_DSP_ENABLE, 0x00 },
0121 { ADAU17X1_DSP_RUN, 0x00 },
0122 { ADAU17X1_SERIAL_SAMPLING_RATE, 0x00 },
0123 };
0124
0125 static const DECLARE_TLV_DB_SCALE(adau1761_sing_in_tlv, -1500, 300, 1);
0126 static const DECLARE_TLV_DB_SCALE(adau1761_diff_in_tlv, -1200, 75, 0);
0127 static const DECLARE_TLV_DB_SCALE(adau1761_out_tlv, -5700, 100, 0);
0128 static const DECLARE_TLV_DB_SCALE(adau1761_sidetone_tlv, -1800, 300, 1);
0129 static const DECLARE_TLV_DB_SCALE(adau1761_boost_tlv, -600, 600, 1);
0130 static const DECLARE_TLV_DB_SCALE(adau1761_pga_boost_tlv, -2000, 2000, 1);
0131
0132 static const DECLARE_TLV_DB_SCALE(adau1761_alc_max_gain_tlv, -1200, 600, 0);
0133 static const DECLARE_TLV_DB_SCALE(adau1761_alc_target_tlv, -2850, 150, 0);
0134 static const DECLARE_TLV_DB_SCALE(adau1761_alc_ng_threshold_tlv, -7650, 150, 0);
0135
0136 static const unsigned int adau1761_bias_select_values[] = {
0137 0, 2, 3,
0138 };
0139
0140 static const char * const adau1761_bias_select_text[] = {
0141 "Normal operation", "Enhanced performance", "Power saving",
0142 };
0143
0144 static const char * const adau1761_bias_select_extreme_text[] = {
0145 "Normal operation", "Extreme power saving", "Enhanced performance",
0146 "Power saving",
0147 };
0148
0149 static SOC_ENUM_SINGLE_DECL(adau1761_adc_bias_enum,
0150 ADAU17X1_REC_POWER_MGMT, 3, adau1761_bias_select_extreme_text);
0151 static SOC_ENUM_SINGLE_DECL(adau1761_hp_bias_enum,
0152 ADAU17X1_PLAY_POWER_MGMT, 6, adau1761_bias_select_extreme_text);
0153 static SOC_ENUM_SINGLE_DECL(adau1761_dac_bias_enum,
0154 ADAU17X1_PLAY_POWER_MGMT, 4, adau1761_bias_select_extreme_text);
0155 static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_playback_bias_enum,
0156 ADAU17X1_PLAY_POWER_MGMT, 2, 0x3, adau1761_bias_select_text,
0157 adau1761_bias_select_values);
0158 static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_capture_bias_enum,
0159 ADAU17X1_REC_POWER_MGMT, 1, 0x3, adau1761_bias_select_text,
0160 adau1761_bias_select_values);
0161
0162 static const unsigned int adau1761_pga_slew_time_values[] = {
0163 3, 0, 1, 2,
0164 };
0165
0166 static const char * const adau1761_pga_slew_time_text[] = {
0167 "Off",
0168 "24 ms",
0169 "48 ms",
0170 "96 ms",
0171 };
0172
0173 static const char * const adau1761_alc_function_text[] = {
0174 "Off",
0175 "Right",
0176 "Left",
0177 "Stereo",
0178 "DSP control",
0179 };
0180
0181 static const char * const adau1761_alc_hold_time_text[] = {
0182 "2.67 ms",
0183 "5.34 ms",
0184 "10.68 ms",
0185 "21.36 ms",
0186 "42.72 ms",
0187 "85.44 ms",
0188 "170.88 ms",
0189 "341.76 ms",
0190 "683.52 ms",
0191 "1367 ms",
0192 "2734.1 ms",
0193 "5468.2 ms",
0194 "10936 ms",
0195 "21873 ms",
0196 "43745 ms",
0197 "87491 ms",
0198 };
0199
0200 static const char * const adau1761_alc_attack_time_text[] = {
0201 "6 ms",
0202 "12 ms",
0203 "24 ms",
0204 "48 ms",
0205 "96 ms",
0206 "192 ms",
0207 "384 ms",
0208 "768 ms",
0209 "1540 ms",
0210 "3070 ms",
0211 "6140 ms",
0212 "12290 ms",
0213 "24580 ms",
0214 "49150 ms",
0215 "98300 ms",
0216 "196610 ms",
0217 };
0218
0219 static const char * const adau1761_alc_decay_time_text[] = {
0220 "24 ms",
0221 "48 ms",
0222 "96 ms",
0223 "192 ms",
0224 "384 ms",
0225 "768 ms",
0226 "15400 ms",
0227 "30700 ms",
0228 "61400 ms",
0229 "12290 ms",
0230 "24580 ms",
0231 "49150 ms",
0232 "98300 ms",
0233 "196610 ms",
0234 "393220 ms",
0235 "786430 ms",
0236 };
0237
0238 static const char * const adau1761_alc_ng_type_text[] = {
0239 "Hold",
0240 "Mute",
0241 "Fade",
0242 "Fade + Mute",
0243 };
0244
0245 static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_pga_slew_time_enum,
0246 ADAU1761_ALC_CTRL0, 6, 0x3, adau1761_pga_slew_time_text,
0247 adau1761_pga_slew_time_values);
0248 static SOC_ENUM_SINGLE_DECL(adau1761_alc_function_enum,
0249 ADAU1761_ALC_CTRL0, 0, adau1761_alc_function_text);
0250 static SOC_ENUM_SINGLE_DECL(adau1761_alc_hold_time_enum,
0251 ADAU1761_ALC_CTRL1, 4, adau1761_alc_hold_time_text);
0252 static SOC_ENUM_SINGLE_DECL(adau1761_alc_attack_time_enum,
0253 ADAU1761_ALC_CTRL2, 4, adau1761_alc_attack_time_text);
0254 static SOC_ENUM_SINGLE_DECL(adau1761_alc_decay_time_enum,
0255 ADAU1761_ALC_CTRL2, 0, adau1761_alc_decay_time_text);
0256 static SOC_ENUM_SINGLE_DECL(adau1761_alc_ng_type_enum,
0257 ADAU1761_ALC_CTRL3, 6, adau1761_alc_ng_type_text);
0258
0259 static const struct snd_kcontrol_new adau1761_jack_detect_controls[] = {
0260 SOC_SINGLE("Speaker Auto-mute Switch", ADAU1761_DIGMIC_JACKDETECT,
0261 4, 1, 0),
0262 };
0263
0264 static const struct snd_kcontrol_new adau1761_differential_mode_controls[] = {
0265 SOC_DOUBLE_R_TLV("Capture Volume", ADAU1761_LEFT_DIFF_INPUT_VOL,
0266 ADAU1761_RIGHT_DIFF_INPUT_VOL, 2, 0x3f, 0,
0267 adau1761_diff_in_tlv),
0268 SOC_DOUBLE_R("Capture Switch", ADAU1761_LEFT_DIFF_INPUT_VOL,
0269 ADAU1761_RIGHT_DIFF_INPUT_VOL, 1, 1, 0),
0270
0271 SOC_DOUBLE_R_TLV("PGA Boost Capture Volume", ADAU1761_REC_MIXER_LEFT1,
0272 ADAU1761_REC_MIXER_RIGHT1, 3, 2, 0, adau1761_pga_boost_tlv),
0273
0274 SOC_ENUM("PGA Capture Slew Time", adau1761_pga_slew_time_enum),
0275
0276 SOC_SINGLE_TLV("ALC Capture Max Gain Volume", ADAU1761_ALC_CTRL0,
0277 3, 7, 0, adau1761_alc_max_gain_tlv),
0278 SOC_ENUM("ALC Capture Function", adau1761_alc_function_enum),
0279 SOC_ENUM("ALC Capture Hold Time", adau1761_alc_hold_time_enum),
0280 SOC_SINGLE_TLV("ALC Capture Target Volume", ADAU1761_ALC_CTRL1,
0281 0, 15, 0, adau1761_alc_target_tlv),
0282 SOC_ENUM("ALC Capture Attack Time", adau1761_alc_decay_time_enum),
0283 SOC_ENUM("ALC Capture Decay Time", adau1761_alc_attack_time_enum),
0284 SOC_ENUM("ALC Capture Noise Gate Type", adau1761_alc_ng_type_enum),
0285 SOC_SINGLE("ALC Capture Noise Gate Switch",
0286 ADAU1761_ALC_CTRL3, 5, 1, 0),
0287 SOC_SINGLE_TLV("ALC Capture Noise Gate Threshold Volume",
0288 ADAU1761_ALC_CTRL3, 0, 31, 0, adau1761_alc_ng_threshold_tlv),
0289 };
0290
0291 static const struct snd_kcontrol_new adau1761_single_mode_controls[] = {
0292 SOC_SINGLE_TLV("Input 1 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
0293 4, 7, 0, adau1761_sing_in_tlv),
0294 SOC_SINGLE_TLV("Input 2 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
0295 1, 7, 0, adau1761_sing_in_tlv),
0296 SOC_SINGLE_TLV("Input 3 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
0297 4, 7, 0, adau1761_sing_in_tlv),
0298 SOC_SINGLE_TLV("Input 4 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
0299 1, 7, 0, adau1761_sing_in_tlv),
0300 };
0301
0302 static const struct snd_kcontrol_new adau1761_controls[] = {
0303 SOC_DOUBLE_R_TLV("Aux Capture Volume", ADAU1761_REC_MIXER_LEFT1,
0304 ADAU1761_REC_MIXER_RIGHT1, 0, 7, 0, adau1761_sing_in_tlv),
0305
0306 SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1761_PLAY_HP_LEFT_VOL,
0307 ADAU1761_PLAY_HP_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
0308 SOC_DOUBLE_R("Headphone Playback Switch", ADAU1761_PLAY_HP_LEFT_VOL,
0309 ADAU1761_PLAY_HP_RIGHT_VOL, 1, 1, 0),
0310 SOC_DOUBLE_R_TLV("Lineout Playback Volume", ADAU1761_PLAY_LINE_LEFT_VOL,
0311 ADAU1761_PLAY_LINE_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
0312 SOC_DOUBLE_R("Lineout Playback Switch", ADAU1761_PLAY_LINE_LEFT_VOL,
0313 ADAU1761_PLAY_LINE_RIGHT_VOL, 1, 1, 0),
0314
0315 SOC_ENUM("ADC Bias", adau1761_adc_bias_enum),
0316 SOC_ENUM("DAC Bias", adau1761_dac_bias_enum),
0317 SOC_ENUM("Capture Bias", adau1761_capture_bias_enum),
0318 SOC_ENUM("Playback Bias", adau1761_playback_bias_enum),
0319 SOC_ENUM("Headphone Bias", adau1761_hp_bias_enum),
0320 };
0321
0322 static const struct snd_kcontrol_new adau1761_mono_controls[] = {
0323 SOC_SINGLE_TLV("Mono Playback Volume", ADAU1761_PLAY_MONO_OUTPUT_VOL,
0324 2, 0x3f, 0, adau1761_out_tlv),
0325 SOC_SINGLE("Mono Playback Switch", ADAU1761_PLAY_MONO_OUTPUT_VOL,
0326 1, 1, 0),
0327 };
0328
0329 static const struct snd_kcontrol_new adau1761_left_mixer_controls[] = {
0330 SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
0331 ADAU1761_PLAY_MIXER_LEFT0, 5, 1, 0),
0332 SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
0333 ADAU1761_PLAY_MIXER_LEFT0, 6, 1, 0),
0334 SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
0335 ADAU1761_PLAY_MIXER_LEFT0, 1, 8, 0, adau1761_sidetone_tlv),
0336 SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
0337 ADAU1761_PLAY_MIXER_LEFT1, 4, 8, 0, adau1761_sidetone_tlv),
0338 SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
0339 ADAU1761_PLAY_MIXER_LEFT1, 0, 8, 0, adau1761_sidetone_tlv),
0340 };
0341
0342 static const struct snd_kcontrol_new adau1761_right_mixer_controls[] = {
0343 SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
0344 ADAU1761_PLAY_MIXER_RIGHT0, 5, 1, 0),
0345 SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
0346 ADAU1761_PLAY_MIXER_RIGHT0, 6, 1, 0),
0347 SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
0348 ADAU1761_PLAY_MIXER_RIGHT0, 1, 8, 0, adau1761_sidetone_tlv),
0349 SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
0350 ADAU1761_PLAY_MIXER_RIGHT1, 4, 8, 0, adau1761_sidetone_tlv),
0351 SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
0352 ADAU1761_PLAY_MIXER_RIGHT1, 0, 8, 0, adau1761_sidetone_tlv),
0353 };
0354
0355 static const struct snd_kcontrol_new adau1761_left_lr_mixer_controls[] = {
0356 SOC_DAPM_SINGLE_TLV("Left Volume",
0357 ADAU1761_PLAY_LR_MIXER_LEFT, 1, 2, 0, adau1761_boost_tlv),
0358 SOC_DAPM_SINGLE_TLV("Right Volume",
0359 ADAU1761_PLAY_LR_MIXER_LEFT, 3, 2, 0, adau1761_boost_tlv),
0360 };
0361
0362 static const struct snd_kcontrol_new adau1761_right_lr_mixer_controls[] = {
0363 SOC_DAPM_SINGLE_TLV("Left Volume",
0364 ADAU1761_PLAY_LR_MIXER_RIGHT, 1, 2, 0, adau1761_boost_tlv),
0365 SOC_DAPM_SINGLE_TLV("Right Volume",
0366 ADAU1761_PLAY_LR_MIXER_RIGHT, 3, 2, 0, adau1761_boost_tlv),
0367 };
0368
0369 static const char * const adau1761_input_mux_text[] = {
0370 "ADC", "DMIC",
0371 };
0372
0373 static SOC_ENUM_SINGLE_DECL(adau1761_input_mux_enum,
0374 ADAU17X1_ADC_CONTROL, 2, adau1761_input_mux_text);
0375
0376 static const struct snd_kcontrol_new adau1761_input_mux_control =
0377 SOC_DAPM_ENUM("Input Select", adau1761_input_mux_enum);
0378
0379 static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w,
0380 struct snd_kcontrol *kcontrol, int event)
0381 {
0382 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0383 struct adau *adau = snd_soc_component_get_drvdata(component);
0384
0385
0386
0387 regmap_write(adau->regmap, ADAU1761_DEJITTER, 0);
0388 if (!adau->master)
0389 regmap_write(adau->regmap, ADAU1761_DEJITTER, 3);
0390
0391 return 0;
0392 }
0393
0394 static const struct snd_soc_dapm_widget adau1x61_dapm_widgets[] = {
0395 SND_SOC_DAPM_MIXER("Left Input Mixer", ADAU1761_REC_MIXER_LEFT0, 0, 0,
0396 NULL, 0),
0397 SND_SOC_DAPM_MIXER("Right Input Mixer", ADAU1761_REC_MIXER_RIGHT0, 0, 0,
0398 NULL, 0),
0399
0400 SOC_MIXER_ARRAY("Left Playback Mixer", ADAU1761_PLAY_MIXER_LEFT0,
0401 0, 0, adau1761_left_mixer_controls),
0402 SOC_MIXER_ARRAY("Right Playback Mixer", ADAU1761_PLAY_MIXER_RIGHT0,
0403 0, 0, adau1761_right_mixer_controls),
0404 SOC_MIXER_ARRAY("Left LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_LEFT,
0405 0, 0, adau1761_left_lr_mixer_controls),
0406 SOC_MIXER_ARRAY("Right LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_RIGHT,
0407 0, 0, adau1761_right_lr_mixer_controls),
0408
0409 SND_SOC_DAPM_SUPPLY("Headphone", ADAU1761_PLAY_HP_LEFT_VOL,
0410 0, 0, NULL, 0),
0411
0412 SND_SOC_DAPM_SUPPLY_S("SYSCLK", 2, SND_SOC_NOPM, 0, 0, NULL, 0),
0413
0414 SND_SOC_DAPM_POST("Dejitter fixup", adau1761_dejitter_fixup),
0415
0416 SND_SOC_DAPM_INPUT("LAUX"),
0417 SND_SOC_DAPM_INPUT("RAUX"),
0418 SND_SOC_DAPM_INPUT("LINP"),
0419 SND_SOC_DAPM_INPUT("LINN"),
0420 SND_SOC_DAPM_INPUT("RINP"),
0421 SND_SOC_DAPM_INPUT("RINN"),
0422
0423 SND_SOC_DAPM_OUTPUT("LOUT"),
0424 SND_SOC_DAPM_OUTPUT("ROUT"),
0425 SND_SOC_DAPM_OUTPUT("LHP"),
0426 SND_SOC_DAPM_OUTPUT("RHP"),
0427 };
0428
0429 static const struct snd_soc_dapm_widget adau1761_mono_dapm_widgets[] = {
0430 SND_SOC_DAPM_MIXER("Mono Playback Mixer", ADAU1761_PLAY_MIXER_MONO,
0431 0, 0, NULL, 0),
0432
0433 SND_SOC_DAPM_OUTPUT("MONOOUT"),
0434 };
0435
0436 static const struct snd_soc_dapm_widget adau1761_capless_dapm_widgets[] = {
0437 SND_SOC_DAPM_SUPPLY_S("Headphone VGND", 1, ADAU1761_PLAY_MIXER_MONO,
0438 0, 0, NULL, 0),
0439 };
0440
0441 static const struct snd_soc_dapm_route adau1x61_dapm_routes[] = {
0442 { "Left Input Mixer", NULL, "LINP" },
0443 { "Left Input Mixer", NULL, "LINN" },
0444 { "Left Input Mixer", NULL, "LAUX" },
0445
0446 { "Right Input Mixer", NULL, "RINP" },
0447 { "Right Input Mixer", NULL, "RINN" },
0448 { "Right Input Mixer", NULL, "RAUX" },
0449
0450 { "Left Playback Mixer", NULL, "Left Playback Enable"},
0451 { "Right Playback Mixer", NULL, "Right Playback Enable"},
0452 { "Left LR Playback Mixer", NULL, "Left Playback Enable"},
0453 { "Right LR Playback Mixer", NULL, "Right Playback Enable"},
0454
0455 { "Left Playback Mixer", "Left DAC Switch", "Left DAC" },
0456 { "Left Playback Mixer", "Right DAC Switch", "Right DAC" },
0457
0458 { "Right Playback Mixer", "Left DAC Switch", "Left DAC" },
0459 { "Right Playback Mixer", "Right DAC Switch", "Right DAC" },
0460
0461 { "Left LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
0462 { "Left LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
0463
0464 { "Right LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
0465 { "Right LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
0466
0467 { "LHP", NULL, "Left Playback Mixer" },
0468 { "RHP", NULL, "Right Playback Mixer" },
0469
0470 { "LHP", NULL, "Headphone" },
0471 { "RHP", NULL, "Headphone" },
0472
0473 { "LOUT", NULL, "Left LR Playback Mixer" },
0474 { "ROUT", NULL, "Right LR Playback Mixer" },
0475
0476 { "Left Playback Mixer", "Aux Bypass Volume", "LAUX" },
0477 { "Left Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
0478 { "Left Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
0479 { "Right Playback Mixer", "Aux Bypass Volume", "RAUX" },
0480 { "Right Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
0481 { "Right Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
0482 };
0483
0484 static const struct snd_soc_dapm_route adau1761_mono_dapm_routes[] = {
0485 { "Mono Playback Mixer", NULL, "Left Playback Mixer" },
0486 { "Mono Playback Mixer", NULL, "Right Playback Mixer" },
0487
0488 { "MONOOUT", NULL, "Mono Playback Mixer" },
0489 };
0490
0491 static const struct snd_soc_dapm_route adau1761_capless_dapm_routes[] = {
0492 { "Headphone", NULL, "Headphone VGND" },
0493 };
0494
0495 static const struct snd_soc_dapm_widget adau1761_dmic_widgets[] = {
0496 SND_SOC_DAPM_MUX("Left Decimator Mux", SND_SOC_NOPM, 0, 0,
0497 &adau1761_input_mux_control),
0498 SND_SOC_DAPM_MUX("Right Decimator Mux", SND_SOC_NOPM, 0, 0,
0499 &adau1761_input_mux_control),
0500
0501 SND_SOC_DAPM_INPUT("DMIC"),
0502 };
0503
0504 static const struct snd_soc_dapm_route adau1761_dmic_routes[] = {
0505 { "Left Decimator Mux", "ADC", "Left Input Mixer" },
0506 { "Left Decimator Mux", "DMIC", "DMIC" },
0507 { "Right Decimator Mux", "ADC", "Right Input Mixer" },
0508 { "Right Decimator Mux", "DMIC", "DMIC" },
0509
0510 { "Left Decimator", NULL, "Left Decimator Mux" },
0511 { "Right Decimator", NULL, "Right Decimator Mux" },
0512 };
0513
0514 static const struct snd_soc_dapm_route adau1761_no_dmic_routes[] = {
0515 { "Left Decimator", NULL, "Left Input Mixer" },
0516 { "Right Decimator", NULL, "Right Input Mixer" },
0517 };
0518
0519 static const struct snd_soc_dapm_widget adau1761_dapm_widgets[] = {
0520 SND_SOC_DAPM_SUPPLY("Serial Port Clock", ADAU1761_CLK_ENABLE0,
0521 0, 0, NULL, 0),
0522 SND_SOC_DAPM_SUPPLY("Serial Input Routing Clock", ADAU1761_CLK_ENABLE0,
0523 1, 0, NULL, 0),
0524 SND_SOC_DAPM_SUPPLY("Serial Output Routing Clock", ADAU1761_CLK_ENABLE0,
0525 3, 0, NULL, 0),
0526
0527 SND_SOC_DAPM_SUPPLY("Decimator Resync Clock", ADAU1761_CLK_ENABLE0,
0528 4, 0, NULL, 0),
0529 SND_SOC_DAPM_SUPPLY("Interpolator Resync Clock", ADAU1761_CLK_ENABLE0,
0530 2, 0, NULL, 0),
0531
0532 SND_SOC_DAPM_SUPPLY("Slew Clock", ADAU1761_CLK_ENABLE0, 6, 0, NULL, 0),
0533 SND_SOC_DAPM_SUPPLY("ALC Clock", ADAU1761_CLK_ENABLE0, 5, 0, NULL, 0),
0534
0535 SND_SOC_DAPM_SUPPLY_S("Digital Clock 0", 1, ADAU1761_CLK_ENABLE1,
0536 0, 0, NULL, 0),
0537 SND_SOC_DAPM_SUPPLY_S("Digital Clock 1", 1, ADAU1761_CLK_ENABLE1,
0538 1, 0, NULL, 0),
0539 };
0540
0541 static const struct snd_soc_dapm_route adau1761_dapm_routes[] = {
0542 { "Left Decimator", NULL, "Digital Clock 0", },
0543 { "Right Decimator", NULL, "Digital Clock 0", },
0544 { "Left DAC", NULL, "Digital Clock 0", },
0545 { "Right DAC", NULL, "Digital Clock 0", },
0546
0547 { "AIFCLK", NULL, "Digital Clock 1" },
0548
0549 { "Playback", NULL, "Serial Port Clock" },
0550 { "Capture", NULL, "Serial Port Clock" },
0551 { "Playback", NULL, "Serial Input Routing Clock" },
0552 { "Capture", NULL, "Serial Output Routing Clock" },
0553
0554 { "Left Decimator", NULL, "Decimator Resync Clock" },
0555 { "Right Decimator", NULL, "Decimator Resync Clock" },
0556 { "Left DAC", NULL, "Interpolator Resync Clock" },
0557 { "Right DAC", NULL, "Interpolator Resync Clock" },
0558
0559 { "Slew Clock", NULL, "Digital Clock 0" },
0560 { "Right Playback Mixer", NULL, "Slew Clock" },
0561 { "Left Playback Mixer", NULL, "Slew Clock" },
0562
0563 { "Left Input Mixer", NULL, "ALC Clock" },
0564 { "Right Input Mixer", NULL, "ALC Clock" },
0565
0566 { "Digital Clock 0", NULL, "SYSCLK" },
0567 { "Digital Clock 1", NULL, "SYSCLK" },
0568 };
0569
0570 static const struct snd_soc_dapm_route adau1761_dapm_dsp_routes[] = {
0571 { "DSP", NULL, "Digital Clock 0" },
0572 };
0573
0574 static int adau1761_compatibility_probe(struct device *dev)
0575 {
0576 struct adau *adau = dev_get_drvdata(dev);
0577 struct regmap *regmap = adau->regmap;
0578 int val, ret = 0;
0579
0580
0581 if (adau->type != ADAU1361)
0582 return 0;
0583
0584 regcache_cache_bypass(regmap, true);
0585
0586
0587
0588
0589
0590
0591 regmap_write(regmap, ADAU17X1_CLOCK_CONTROL,
0592 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
0593
0594
0595
0596
0597
0598
0599 regmap_write(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, 1);
0600 ret = regmap_read(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, &val);
0601 if (ret)
0602 goto exit;
0603 if (val != 1)
0604 goto exit;
0605 regmap_write(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, 0);
0606 ret = regmap_read(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, &val);
0607 if (ret)
0608 goto exit;
0609 if (val != 0)
0610 goto exit;
0611
0612 adau->type = ADAU1761_AS_1361;
0613 exit:
0614
0615 regmap_write(regmap, ADAU17X1_CLOCK_CONTROL, 0);
0616 regcache_cache_bypass(regmap, false);
0617 return ret;
0618 }
0619
0620 static int adau1761_set_bias_level(struct snd_soc_component *component,
0621 enum snd_soc_bias_level level)
0622 {
0623 struct adau *adau = snd_soc_component_get_drvdata(component);
0624
0625 switch (level) {
0626 case SND_SOC_BIAS_ON:
0627 break;
0628 case SND_SOC_BIAS_PREPARE:
0629 break;
0630 case SND_SOC_BIAS_STANDBY:
0631 regcache_cache_only(adau->regmap, false);
0632 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
0633 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
0634 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
0635 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
0636 regcache_sync(adau->regmap);
0637 break;
0638 case SND_SOC_BIAS_OFF:
0639 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
0640 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);
0641 regcache_cache_only(adau->regmap, true);
0642 break;
0643
0644 }
0645 return 0;
0646 }
0647
0648 static enum adau1761_output_mode adau1761_get_lineout_mode(
0649 struct snd_soc_component *component)
0650 {
0651 struct adau1761_platform_data *pdata = component->dev->platform_data;
0652
0653 if (pdata)
0654 return pdata->lineout_mode;
0655
0656 return ADAU1761_OUTPUT_MODE_LINE;
0657 }
0658
0659 static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component)
0660 {
0661 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0662 struct adau1761_platform_data *pdata = component->dev->platform_data;
0663 struct adau *adau = snd_soc_component_get_drvdata(component);
0664 enum adau1761_digmic_jackdet_pin_mode mode;
0665 unsigned int val = 0;
0666 int ret;
0667
0668 if (pdata)
0669 mode = pdata->digmic_jackdetect_pin_mode;
0670 else
0671 mode = ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE;
0672
0673 switch (mode) {
0674 case ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT:
0675 switch (pdata->jackdetect_debounce_time) {
0676 case ADAU1761_JACKDETECT_DEBOUNCE_5MS:
0677 case ADAU1761_JACKDETECT_DEBOUNCE_10MS:
0678 case ADAU1761_JACKDETECT_DEBOUNCE_20MS:
0679 case ADAU1761_JACKDETECT_DEBOUNCE_40MS:
0680 val |= pdata->jackdetect_debounce_time << 6;
0681 break;
0682 default:
0683 return -EINVAL;
0684 }
0685 if (pdata->jackdetect_active_low)
0686 val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW;
0687
0688 ret = snd_soc_add_component_controls(component,
0689 adau1761_jack_detect_controls,
0690 ARRAY_SIZE(adau1761_jack_detect_controls));
0691 if (ret)
0692 return ret;
0693 fallthrough;
0694 case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE:
0695 ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes,
0696 ARRAY_SIZE(adau1761_no_dmic_routes));
0697 if (ret)
0698 return ret;
0699 break;
0700 case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
0701 ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets,
0702 ARRAY_SIZE(adau1761_dmic_widgets));
0703 if (ret)
0704 return ret;
0705
0706 ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes,
0707 ARRAY_SIZE(adau1761_dmic_routes));
0708 if (ret)
0709 return ret;
0710
0711 val |= ADAU1761_DIGMIC_JACKDETECT_DIGMIC;
0712 break;
0713 default:
0714 return -EINVAL;
0715 }
0716
0717 regmap_write(adau->regmap, ADAU1761_DIGMIC_JACKDETECT, val);
0718
0719 return 0;
0720 }
0721
0722 static int adau1761_setup_headphone_mode(struct snd_soc_component *component)
0723 {
0724 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0725 struct adau *adau = snd_soc_component_get_drvdata(component);
0726 struct adau1761_platform_data *pdata = component->dev->platform_data;
0727 enum adau1761_output_mode mode;
0728 int ret;
0729
0730 if (pdata)
0731 mode = pdata->headphone_mode;
0732 else
0733 mode = ADAU1761_OUTPUT_MODE_HEADPHONE;
0734
0735 switch (mode) {
0736 case ADAU1761_OUTPUT_MODE_LINE:
0737 break;
0738 case ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS:
0739 regmap_update_bits(adau->regmap, ADAU1761_PLAY_MONO_OUTPUT_VOL,
0740 ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
0741 ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE,
0742 ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
0743 ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE);
0744 fallthrough;
0745 case ADAU1761_OUTPUT_MODE_HEADPHONE:
0746 regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL,
0747 ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP,
0748 ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP);
0749 break;
0750 default:
0751 return -EINVAL;
0752 }
0753
0754 if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
0755 ret = snd_soc_dapm_new_controls(dapm,
0756 adau1761_capless_dapm_widgets,
0757 ARRAY_SIZE(adau1761_capless_dapm_widgets));
0758 if (ret)
0759 return ret;
0760 ret = snd_soc_dapm_add_routes(dapm,
0761 adau1761_capless_dapm_routes,
0762 ARRAY_SIZE(adau1761_capless_dapm_routes));
0763 } else {
0764 ret = snd_soc_add_component_controls(component, adau1761_mono_controls,
0765 ARRAY_SIZE(adau1761_mono_controls));
0766 if (ret)
0767 return ret;
0768 ret = snd_soc_dapm_new_controls(dapm,
0769 adau1761_mono_dapm_widgets,
0770 ARRAY_SIZE(adau1761_mono_dapm_widgets));
0771 if (ret)
0772 return ret;
0773 ret = snd_soc_dapm_add_routes(dapm,
0774 adau1761_mono_dapm_routes,
0775 ARRAY_SIZE(adau1761_mono_dapm_routes));
0776 }
0777
0778 return ret;
0779 }
0780
0781 static bool adau1761_readable_register(struct device *dev, unsigned int reg)
0782 {
0783 switch (reg) {
0784 case ADAU1761_DIGMIC_JACKDETECT:
0785 case ADAU1761_REC_MIXER_LEFT0:
0786 case ADAU1761_REC_MIXER_LEFT1:
0787 case ADAU1761_REC_MIXER_RIGHT0:
0788 case ADAU1761_REC_MIXER_RIGHT1:
0789 case ADAU1761_LEFT_DIFF_INPUT_VOL:
0790 case ADAU1761_RIGHT_DIFF_INPUT_VOL:
0791 case ADAU1761_PLAY_LR_MIXER_LEFT:
0792 case ADAU1761_PLAY_MIXER_LEFT0:
0793 case ADAU1761_PLAY_MIXER_LEFT1:
0794 case ADAU1761_PLAY_MIXER_RIGHT0:
0795 case ADAU1761_PLAY_MIXER_RIGHT1:
0796 case ADAU1761_PLAY_LR_MIXER_RIGHT:
0797 case ADAU1761_PLAY_MIXER_MONO:
0798 case ADAU1761_PLAY_HP_LEFT_VOL:
0799 case ADAU1761_PLAY_HP_RIGHT_VOL:
0800 case ADAU1761_PLAY_LINE_LEFT_VOL:
0801 case ADAU1761_PLAY_LINE_RIGHT_VOL:
0802 case ADAU1761_PLAY_MONO_OUTPUT_VOL:
0803 case ADAU1761_POP_CLICK_SUPPRESS:
0804 case ADAU1761_JACK_DETECT_PIN:
0805 case ADAU1761_DEJITTER:
0806 case ADAU1761_CLK_ENABLE0:
0807 case ADAU1761_CLK_ENABLE1:
0808 case ADAU1761_ALC_CTRL0:
0809 case ADAU1761_ALC_CTRL1:
0810 case ADAU1761_ALC_CTRL2:
0811 case ADAU1761_ALC_CTRL3:
0812 return true;
0813 default:
0814 break;
0815 }
0816
0817 return adau17x1_readable_register(dev, reg);
0818 }
0819
0820 static int adau1761_component_probe(struct snd_soc_component *component)
0821 {
0822 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0823 struct adau1761_platform_data *pdata = component->dev->platform_data;
0824 struct adau *adau = snd_soc_component_get_drvdata(component);
0825 int ret;
0826
0827 ret = adau17x1_add_widgets(component);
0828 if (ret < 0)
0829 return ret;
0830
0831 if (pdata && pdata->input_differential) {
0832 regmap_update_bits(adau->regmap, ADAU1761_LEFT_DIFF_INPUT_VOL,
0833 ADAU1761_DIFF_INPUT_VOL_LDEN,
0834 ADAU1761_DIFF_INPUT_VOL_LDEN);
0835 regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
0836 ADAU1761_DIFF_INPUT_VOL_LDEN,
0837 ADAU1761_DIFF_INPUT_VOL_LDEN);
0838 ret = snd_soc_add_component_controls(component,
0839 adau1761_differential_mode_controls,
0840 ARRAY_SIZE(adau1761_differential_mode_controls));
0841 if (ret)
0842 return ret;
0843 } else {
0844 ret = snd_soc_add_component_controls(component,
0845 adau1761_single_mode_controls,
0846 ARRAY_SIZE(adau1761_single_mode_controls));
0847 if (ret)
0848 return ret;
0849 }
0850
0851 switch (adau1761_get_lineout_mode(component)) {
0852 case ADAU1761_OUTPUT_MODE_LINE:
0853 break;
0854 case ADAU1761_OUTPUT_MODE_HEADPHONE:
0855 regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_LEFT_VOL,
0856 ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP,
0857 ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP);
0858 regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_RIGHT_VOL,
0859 ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP,
0860 ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP);
0861 break;
0862 default:
0863 return -EINVAL;
0864 }
0865
0866 ret = adau1761_setup_headphone_mode(component);
0867 if (ret)
0868 return ret;
0869
0870 ret = adau1761_setup_digmic_jackdetect(component);
0871 if (ret)
0872 return ret;
0873
0874
0875
0876
0877
0878 if (adau->type == ADAU1761 || adau->type == ADAU1761_AS_1361) {
0879 ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets,
0880 ARRAY_SIZE(adau1761_dapm_widgets));
0881 if (ret)
0882 return ret;
0883
0884 ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes,
0885 ARRAY_SIZE(adau1761_dapm_routes));
0886 if (ret)
0887 return ret;
0888 }
0889
0890
0891
0892
0893 if (adau->type == ADAU1761) {
0894 ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_dsp_routes,
0895 ARRAY_SIZE(adau1761_dapm_dsp_routes));
0896 if (ret)
0897 return ret;
0898 }
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908 if (adau->type == ADAU1761_AS_1361) {
0909 regmap_write(adau->regmap, ADAU17X1_SERIAL_INPUT_ROUTE, 0x01);
0910 regmap_write(adau->regmap, ADAU17X1_SERIAL_OUTPUT_ROUTE, 0x01);
0911 }
0912 ret = adau17x1_add_routes(component);
0913 if (ret < 0)
0914 return ret;
0915
0916 return 0;
0917 }
0918
0919 static const struct snd_soc_component_driver adau1761_component_driver = {
0920 .probe = adau1761_component_probe,
0921 .resume = adau17x1_resume,
0922 .set_bias_level = adau1761_set_bias_level,
0923 .controls = adau1761_controls,
0924 .num_controls = ARRAY_SIZE(adau1761_controls),
0925 .dapm_widgets = adau1x61_dapm_widgets,
0926 .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets),
0927 .dapm_routes = adau1x61_dapm_routes,
0928 .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes),
0929 .suspend_bias_off = 1,
0930 .idle_bias_on = 1,
0931 .use_pmdown_time = 1,
0932 .endianness = 1,
0933 };
0934
0935 #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
0936 SNDRV_PCM_FMTBIT_S32_LE)
0937
0938 static struct snd_soc_dai_driver adau1361_dai_driver = {
0939 .name = "adau-hifi",
0940 .playback = {
0941 .stream_name = "Playback",
0942 .channels_min = 2,
0943 .channels_max = 4,
0944 .rates = SNDRV_PCM_RATE_8000_96000,
0945 .formats = ADAU1761_FORMATS,
0946 },
0947 .capture = {
0948 .stream_name = "Capture",
0949 .channels_min = 2,
0950 .channels_max = 4,
0951 .rates = SNDRV_PCM_RATE_8000_96000,
0952 .formats = ADAU1761_FORMATS,
0953 },
0954 .ops = &adau17x1_dai_ops,
0955 };
0956
0957 static struct snd_soc_dai_driver adau1761_dai_driver = {
0958 .name = "adau-hifi",
0959 .playback = {
0960 .stream_name = "Playback",
0961 .channels_min = 2,
0962 .channels_max = 8,
0963 .rates = SNDRV_PCM_RATE_8000_96000,
0964 .formats = ADAU1761_FORMATS,
0965 },
0966 .capture = {
0967 .stream_name = "Capture",
0968 .channels_min = 2,
0969 .channels_max = 8,
0970 .rates = SNDRV_PCM_RATE_8000_96000,
0971 .formats = ADAU1761_FORMATS,
0972 },
0973 .ops = &adau17x1_dai_ops,
0974 };
0975
0976 int adau1761_probe(struct device *dev, struct regmap *regmap,
0977 enum adau17x1_type type, void (*switch_mode)(struct device *dev))
0978 {
0979 struct snd_soc_dai_driver *dai_drv;
0980 const char *firmware_name;
0981 int ret;
0982
0983 if (type == ADAU1361) {
0984 dai_drv = &adau1361_dai_driver;
0985 firmware_name = NULL;
0986 } else {
0987 dai_drv = &adau1761_dai_driver;
0988 firmware_name = ADAU1761_FIRMWARE;
0989 }
0990
0991 ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name);
0992 if (ret)
0993 return ret;
0994
0995 ret = adau1761_compatibility_probe(dev);
0996 if (ret)
0997 return ret;
0998
0999
1000
1001 regcache_cache_only(regmap, true);
1002
1003 return devm_snd_soc_register_component(dev, &adau1761_component_driver,
1004 dai_drv, 1);
1005 }
1006 EXPORT_SYMBOL_GPL(adau1761_probe);
1007
1008 const struct regmap_config adau1761_regmap_config = {
1009 .val_bits = 8,
1010 .reg_bits = 16,
1011 .max_register = 0x40fa,
1012 .reg_defaults = adau1761_reg_defaults,
1013 .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults),
1014 .readable_reg = adau1761_readable_register,
1015 .volatile_reg = adau17x1_volatile_register,
1016 .precious_reg = adau17x1_precious_register,
1017 .cache_type = REGCACHE_RBTREE,
1018 };
1019 EXPORT_SYMBOL_GPL(adau1761_regmap_config);
1020
1021 MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver");
1022 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1023 MODULE_LICENSE("GPL");