Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
0004  *
0005  * Copyright 2011-2013 Analog Devices Inc.
0006  * Author: Lars-Peter Clausen <lars@metafoo.de>
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     /* After any power changes have been made the dejitter circuit
0386      * has to be reinitialized. */
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     /* Only consider compatibility mode when ADAU1361 was specified. */
0581     if (adau->type != ADAU1361)
0582         return 0;
0583 
0584     regcache_cache_bypass(regmap, true);
0585 
0586     /*
0587      * This will enable the core clock and bypass the PLL,
0588      * so that we can access the registers for probing purposes
0589      * (without having to set up the PLL).
0590      */
0591     regmap_write(regmap, ADAU17X1_CLOCK_CONTROL,
0592         ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
0593 
0594     /*
0595      * ADAU17X1_SERIAL_SAMPLING_RATE doesn't exist in non-DSP chips;
0596      * reading it results in zero at all times, and write is a no-op.
0597      * Use this register to probe for ADAU1761.
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     /* Disable core clock after probing. */
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      * If we've got an ADAU1761, or an ADAU1761 operating as an
0876      * ADAU1361, we need these non-DSP related DAPM widgets and routes.
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      * These routes are DSP related and only used when we have a
0891      * bona fide ADAU1761.
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      * In the ADAU1761, by default, the AIF is routed to the DSP, whereas
0901      * for the ADAU1361, the AIF is permanently routed to the ADC and DAC.
0902      * Thus, if we have an ADAU1761 masquerading as an ADAU1361,
0903      * we need to explicitly route the AIF to the ADC and DAC.
0904      * For the ADAU1761, this is normally done by set_tdm_slot, but this
0905      * function is not necessarily called during stream setup, so set up
0906      * the compatible AIF routings here from the start.
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     /* Enable cache only mode as we could miss writes before bias level
1000      * reaches standby and the core clock is enabled */
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");