Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: add support for alc562[123] codecs

This patch is adding support for alc562[123] codecs. It's based
on the source code available in HP source code and other places.

Signed-off-by: Arnaud Patard <arnaud.patard@rtp-net.org>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Arnaud Patard (Rtp) and committed by
Mark Brown
6f4bc952 4428bc09

+1301
+15
include/sound/alc5623.h
··· 1 + #ifndef _INCLUDE_SOUND_ALC5623_H 2 + #define _INCLUDE_SOUND_ALC5623_H 3 + struct alc5623_platform_data { 4 + /* configure : */ 5 + /* Lineout/Speaker Amps Vmid ratio control */ 6 + /* enable/disable adc/dac high pass filters */ 7 + unsigned int add_ctrl; 8 + /* configure : */ 9 + /* output to enable when jack is low */ 10 + /* output to enable when jack is high */ 11 + /* jack detect (gpio/nc/jack detect [12] */ 12 + unsigned int jack_det_ctrl; 13 + }; 14 + #endif 15 +
+5
sound/soc/codecs/Kconfig
··· 22 22 select SND_SOC_AK4535 if I2C 23 23 select SND_SOC_AK4642 if I2C 24 24 select SND_SOC_AK4671 if I2C 25 + select SND_SOC_ALC562 if I2C 25 26 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 26 27 select SND_SOC_CS42L51 if I2C 27 28 select SND_SOC_CS4270 if I2C ··· 129 128 130 129 config SND_SOC_AK4671 131 130 tristate 131 + 132 + config SND_SOC_ALC5623 133 + tristate 132 134 133 135 config SND_SOC_CQ0093VC 134 136 tristate ··· 321 317 322 318 config SND_SOC_WM9090 323 319 tristate 320 +
+2
sound/soc/codecs/Makefile
··· 17 17 snd-soc-l3-objs := l3.o 18 18 snd-soc-max98088-objs := max98088.o 19 19 snd-soc-pcm3008-objs := pcm3008.o 20 + snd-soc-alc5623-objs := alc5623.o 20 21 snd-soc-spdif-objs := spdif_transciever.o 21 22 snd-soc-ssm2602-objs := ssm2602.o 22 23 snd-soc-stac9766-objs := stac9766.o ··· 93 92 obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 94 93 obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 95 94 obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 95 + obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 96 96 obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 97 97 obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 98 98 obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
+1118
sound/soc/codecs/alc5623.c
··· 1 + /* 2 + * alc5623.c -- alc562[123] ALSA Soc Audio driver 3 + * 4 + * Copyright 2008 Realtek Microelectronics 5 + * Author: flove <flove@realtek.com> Ethan <eku@marvell.com> 6 + * 7 + * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org> 8 + * 9 + * 10 + * Based on WM8753.c 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License version 2 as 14 + * published by the Free Software Foundation. 15 + * 16 + */ 17 + 18 + #include <linux/module.h> 19 + #include <linux/kernel.h> 20 + #include <linux/init.h> 21 + #include <linux/delay.h> 22 + #include <linux/pm.h> 23 + #include <linux/i2c.h> 24 + #include <linux/slab.h> 25 + #include <linux/platform_device.h> 26 + #include <sound/core.h> 27 + #include <sound/pcm.h> 28 + #include <sound/pcm_params.h> 29 + #include <sound/tlv.h> 30 + #include <sound/soc.h> 31 + #include <sound/soc-dapm.h> 32 + #include <sound/initval.h> 33 + #include <sound/alc5623.h> 34 + 35 + #include "alc5623.h" 36 + 37 + static int caps_charge = 2000; 38 + module_param(caps_charge, int, 0); 39 + MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)"); 40 + 41 + /* codec private data */ 42 + struct alc5623_priv { 43 + enum snd_soc_control_type control_type; 44 + void *control_data; 45 + struct mutex mutex; 46 + u8 id; 47 + unsigned int sysclk; 48 + u16 reg_cache[ALC5623_VENDOR_ID2+2]; 49 + unsigned int add_ctrl; 50 + unsigned int jack_det_ctrl; 51 + }; 52 + 53 + static void alc5623_fill_cache(struct snd_soc_codec *codec) 54 + { 55 + int i, step = codec->driver->reg_cache_step; 56 + u16 *cache = codec->reg_cache; 57 + 58 + /* not really efficient ... */ 59 + for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) 60 + cache[i] = codec->hw_read(codec, i); 61 + } 62 + 63 + static inline int alc5623_reset(struct snd_soc_codec *codec) 64 + { 65 + return snd_soc_write(codec, ALC5623_RESET, 0); 66 + } 67 + 68 + static int amp_mixer_event(struct snd_soc_dapm_widget *w, 69 + struct snd_kcontrol *kcontrol, int event) 70 + { 71 + /* to power-on/off class-d amp generators/speaker */ 72 + /* need to write to 'index-46h' register : */ 73 + /* so write index num (here 0x46) to reg 0x6a */ 74 + /* and then 0xffff/0 to reg 0x6c */ 75 + snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46); 76 + 77 + switch (event) { 78 + case SND_SOC_DAPM_PRE_PMU: 79 + snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF); 80 + break; 81 + case SND_SOC_DAPM_POST_PMD: 82 + snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0); 83 + break; 84 + } 85 + 86 + return 0; 87 + } 88 + 89 + /* 90 + * ALC5623 Controls 91 + */ 92 + 93 + static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0); 94 + static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0); 95 + static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); 96 + static const unsigned int boost_tlv[] = { 97 + TLV_DB_RANGE_HEAD(3), 98 + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 99 + 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 100 + 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), 101 + }; 102 + static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); 103 + 104 + static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = { 105 + SOC_DOUBLE_TLV("Speaker Playback Volume", 106 + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), 107 + SOC_DOUBLE("Speaker Playback Switch", 108 + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), 109 + SOC_DOUBLE_TLV("Headphone Playback Volume", 110 + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), 111 + SOC_DOUBLE("Headphone Playback Switch", 112 + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), 113 + }; 114 + 115 + static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = { 116 + SOC_DOUBLE_TLV("Speaker Playback Volume", 117 + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), 118 + SOC_DOUBLE("Speaker Playback Switch", 119 + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), 120 + SOC_DOUBLE_TLV("Line Playback Volume", 121 + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), 122 + SOC_DOUBLE("Line Playback Switch", 123 + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), 124 + }; 125 + 126 + static const struct snd_kcontrol_new alc5623_vol_snd_controls[] = { 127 + SOC_DOUBLE_TLV("Line Playback Volume", 128 + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), 129 + SOC_DOUBLE("Line Playback Switch", 130 + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), 131 + SOC_DOUBLE_TLV("Headphone Playback Volume", 132 + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), 133 + SOC_DOUBLE("Headphone Playback Switch", 134 + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), 135 + }; 136 + 137 + static const struct snd_kcontrol_new alc5623_snd_controls[] = { 138 + SOC_DOUBLE_TLV("Auxout Playback Volume", 139 + ALC5623_MONO_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv), 140 + SOC_DOUBLE("Auxout Playback Switch", 141 + ALC5623_MONO_AUX_OUT_VOL, 15, 7, 1, 1), 142 + SOC_DOUBLE_TLV("PCM Playback Volume", 143 + ALC5623_STEREO_DAC_VOL, 8, 0, 31, 1, vol_tlv), 144 + SOC_DOUBLE_TLV("AuxI Capture Volume", 145 + ALC5623_AUXIN_VOL, 8, 0, 31, 1, vol_tlv), 146 + SOC_DOUBLE_TLV("LineIn Capture Volume", 147 + ALC5623_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), 148 + SOC_SINGLE_TLV("Mic1 Capture Volume", 149 + ALC5623_MIC_VOL, 8, 31, 1, vol_tlv), 150 + SOC_SINGLE_TLV("Mic2 Capture Volume", 151 + ALC5623_MIC_VOL, 0, 31, 1, vol_tlv), 152 + SOC_DOUBLE_TLV("Rec Capture Volume", 153 + ALC5623_ADC_REC_GAIN, 7, 0, 31, 0, adc_rec_tlv), 154 + SOC_SINGLE_TLV("Mic 1 Boost Volume", 155 + ALC5623_MIC_CTRL, 10, 2, 0, boost_tlv), 156 + SOC_SINGLE_TLV("Mic 2 Boost Volume", 157 + ALC5623_MIC_CTRL, 8, 2, 0, boost_tlv), 158 + SOC_SINGLE_TLV("Digital Boost Volume", 159 + ALC5623_ADD_CTRL_REG, 4, 3, 0, dig_tlv), 160 + }; 161 + 162 + /* 163 + * DAPM Controls 164 + */ 165 + static const struct snd_kcontrol_new alc5623_hp_mixer_controls[] = { 166 + SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5623_LINE_IN_VOL, 15, 1, 1), 167 + SOC_DAPM_SINGLE("AUXI2HP Playback Switch", ALC5623_AUXIN_VOL, 15, 1, 1), 168 + SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 15, 1, 1), 169 + SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 7, 1, 1), 170 + SOC_DAPM_SINGLE("DAC2HP Playback Switch", ALC5623_STEREO_DAC_VOL, 15, 1, 1), 171 + }; 172 + 173 + static const struct snd_kcontrol_new alc5623_hpl_mixer_controls[] = { 174 + SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5623_ADC_REC_GAIN, 15, 1, 1), 175 + }; 176 + 177 + static const struct snd_kcontrol_new alc5623_hpr_mixer_controls[] = { 178 + SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5623_ADC_REC_GAIN, 14, 1, 1), 179 + }; 180 + 181 + static const struct snd_kcontrol_new alc5623_mono_mixer_controls[] = { 182 + SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5623_ADC_REC_GAIN, 13, 1, 1), 183 + SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5623_ADC_REC_GAIN, 12, 1, 1), 184 + SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5623_LINE_IN_VOL, 13, 1, 1), 185 + SOC_DAPM_SINGLE("AUXI2MONO Playback Switch", ALC5623_AUXIN_VOL, 13, 1, 1), 186 + SOC_DAPM_SINGLE("MIC12MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 13, 1, 1), 187 + SOC_DAPM_SINGLE("MIC22MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 5, 1, 1), 188 + SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5623_STEREO_DAC_VOL, 13, 1, 1), 189 + }; 190 + 191 + static const struct snd_kcontrol_new alc5623_speaker_mixer_controls[] = { 192 + SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5623_LINE_IN_VOL, 14, 1, 1), 193 + SOC_DAPM_SINGLE("AUXI2SPK Playback Switch", ALC5623_AUXIN_VOL, 14, 1, 1), 194 + SOC_DAPM_SINGLE("MIC12SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 14, 1, 1), 195 + SOC_DAPM_SINGLE("MIC22SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 6, 1, 1), 196 + SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5623_STEREO_DAC_VOL, 14, 1, 1), 197 + }; 198 + 199 + /* Left Record Mixer */ 200 + static const struct snd_kcontrol_new alc5623_captureL_mixer_controls[] = { 201 + SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 14, 1, 1), 202 + SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 13, 1, 1), 203 + SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5623_ADC_REC_MIXER, 12, 1, 1), 204 + SOC_DAPM_SINGLE("Left AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 11, 1, 1), 205 + SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5623_ADC_REC_MIXER, 10, 1, 1), 206 + SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 9, 1, 1), 207 + SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 8, 1, 1), 208 + }; 209 + 210 + /* Right Record Mixer */ 211 + static const struct snd_kcontrol_new alc5623_captureR_mixer_controls[] = { 212 + SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 6, 1, 1), 213 + SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 5, 1, 1), 214 + SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5623_ADC_REC_MIXER, 4, 1, 1), 215 + SOC_DAPM_SINGLE("Right AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 3, 1, 1), 216 + SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5623_ADC_REC_MIXER, 2, 1, 1), 217 + SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 1, 1, 1), 218 + SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 0, 1, 1), 219 + }; 220 + 221 + static const char *alc5623_spk_n_sour_sel[] = { 222 + "RN/-R", "RP/+R", "LN/-R", "Vmid" }; 223 + static const char *alc5623_hpl_out_input_sel[] = { 224 + "Vmid", "HP Left Mix"}; 225 + static const char *alc5623_hpr_out_input_sel[] = { 226 + "Vmid", "HP Right Mix"}; 227 + static const char *alc5623_spkout_input_sel[] = { 228 + "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 229 + static const char *alc5623_aux_out_input_sel[] = { 230 + "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 231 + 232 + /* auxout output mux */ 233 + static const struct soc_enum alc5623_aux_out_input_enum = 234 + SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel); 235 + static const struct snd_kcontrol_new alc5623_auxout_mux_controls = 236 + SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); 237 + 238 + /* speaker output mux */ 239 + static const struct soc_enum alc5623_spkout_input_enum = 240 + SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel); 241 + static const struct snd_kcontrol_new alc5623_spkout_mux_controls = 242 + SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); 243 + 244 + /* headphone left output mux */ 245 + static const struct soc_enum alc5623_hpl_out_input_enum = 246 + SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel); 247 + static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = 248 + SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); 249 + 250 + /* headphone right output mux */ 251 + static const struct soc_enum alc5623_hpr_out_input_enum = 252 + SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel); 253 + static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = 254 + SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); 255 + 256 + /* speaker output N select */ 257 + static const struct soc_enum alc5623_spk_n_sour_enum = 258 + SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel); 259 + static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = 260 + SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); 261 + 262 + static const struct snd_soc_dapm_widget alc5623_dapm_widgets[] = { 263 + /* Muxes */ 264 + SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0, 265 + &alc5623_auxout_mux_controls), 266 + SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0, 267 + &alc5623_spkout_mux_controls), 268 + SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, 269 + &alc5623_hpl_out_mux_controls), 270 + SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, 271 + &alc5623_hpr_out_mux_controls), 272 + SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, 273 + &alc5623_spkoutn_mux_controls), 274 + 275 + /* output mixers */ 276 + SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, 277 + &alc5623_hp_mixer_controls[0], 278 + ARRAY_SIZE(alc5623_hp_mixer_controls)), 279 + SND_SOC_DAPM_MIXER("HPR Mix", ALC5623_PWR_MANAG_ADD2, 4, 0, 280 + &alc5623_hpr_mixer_controls[0], 281 + ARRAY_SIZE(alc5623_hpr_mixer_controls)), 282 + SND_SOC_DAPM_MIXER("HPL Mix", ALC5623_PWR_MANAG_ADD2, 5, 0, 283 + &alc5623_hpl_mixer_controls[0], 284 + ARRAY_SIZE(alc5623_hpl_mixer_controls)), 285 + SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 286 + SND_SOC_DAPM_MIXER("Mono Mix", ALC5623_PWR_MANAG_ADD2, 2, 0, 287 + &alc5623_mono_mixer_controls[0], 288 + ARRAY_SIZE(alc5623_mono_mixer_controls)), 289 + SND_SOC_DAPM_MIXER("Speaker Mix", ALC5623_PWR_MANAG_ADD2, 3, 0, 290 + &alc5623_speaker_mixer_controls[0], 291 + ARRAY_SIZE(alc5623_speaker_mixer_controls)), 292 + 293 + /* input mixers */ 294 + SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5623_PWR_MANAG_ADD2, 1, 0, 295 + &alc5623_captureL_mixer_controls[0], 296 + ARRAY_SIZE(alc5623_captureL_mixer_controls)), 297 + SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5623_PWR_MANAG_ADD2, 0, 0, 298 + &alc5623_captureR_mixer_controls[0], 299 + ARRAY_SIZE(alc5623_captureR_mixer_controls)), 300 + 301 + SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", 302 + ALC5623_PWR_MANAG_ADD2, 9, 0), 303 + SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", 304 + ALC5623_PWR_MANAG_ADD2, 8, 0), 305 + SND_SOC_DAPM_MIXER("I2S Mix", ALC5623_PWR_MANAG_ADD1, 15, 0, NULL, 0), 306 + SND_SOC_DAPM_MIXER("AuxI Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 307 + SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 308 + SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", 309 + ALC5623_PWR_MANAG_ADD2, 7, 0), 310 + SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", 311 + ALC5623_PWR_MANAG_ADD2, 6, 0), 312 + SND_SOC_DAPM_PGA("Left Headphone", ALC5623_PWR_MANAG_ADD3, 10, 0, NULL, 0), 313 + SND_SOC_DAPM_PGA("Right Headphone", ALC5623_PWR_MANAG_ADD3, 9, 0, NULL, 0), 314 + SND_SOC_DAPM_PGA("SpeakerOut", ALC5623_PWR_MANAG_ADD3, 12, 0, NULL, 0), 315 + SND_SOC_DAPM_PGA("Left AuxOut", ALC5623_PWR_MANAG_ADD3, 14, 0, NULL, 0), 316 + SND_SOC_DAPM_PGA("Right AuxOut", ALC5623_PWR_MANAG_ADD3, 13, 0, NULL, 0), 317 + SND_SOC_DAPM_PGA("Left LineIn", ALC5623_PWR_MANAG_ADD3, 7, 0, NULL, 0), 318 + SND_SOC_DAPM_PGA("Right LineIn", ALC5623_PWR_MANAG_ADD3, 6, 0, NULL, 0), 319 + SND_SOC_DAPM_PGA("Left AuxI", ALC5623_PWR_MANAG_ADD3, 5, 0, NULL, 0), 320 + SND_SOC_DAPM_PGA("Right AuxI", ALC5623_PWR_MANAG_ADD3, 4, 0, NULL, 0), 321 + SND_SOC_DAPM_PGA("MIC1 PGA", ALC5623_PWR_MANAG_ADD3, 3, 0, NULL, 0), 322 + SND_SOC_DAPM_PGA("MIC2 PGA", ALC5623_PWR_MANAG_ADD3, 2, 0, NULL, 0), 323 + SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5623_PWR_MANAG_ADD3, 1, 0, NULL, 0), 324 + SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5623_PWR_MANAG_ADD3, 0, 0, NULL, 0), 325 + SND_SOC_DAPM_MICBIAS("Mic Bias1", ALC5623_PWR_MANAG_ADD1, 11, 0), 326 + 327 + SND_SOC_DAPM_OUTPUT("AUXOUTL"), 328 + SND_SOC_DAPM_OUTPUT("AUXOUTR"), 329 + SND_SOC_DAPM_OUTPUT("HPL"), 330 + SND_SOC_DAPM_OUTPUT("HPR"), 331 + SND_SOC_DAPM_OUTPUT("SPKOUT"), 332 + SND_SOC_DAPM_OUTPUT("SPKOUTN"), 333 + SND_SOC_DAPM_INPUT("LINEINL"), 334 + SND_SOC_DAPM_INPUT("LINEINR"), 335 + SND_SOC_DAPM_INPUT("AUXINL"), 336 + SND_SOC_DAPM_INPUT("AUXINR"), 337 + SND_SOC_DAPM_INPUT("MIC1"), 338 + SND_SOC_DAPM_INPUT("MIC2"), 339 + SND_SOC_DAPM_VMID("Vmid"), 340 + }; 341 + 342 + static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; 343 + static const struct soc_enum alc5623_amp_enum = 344 + SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names); 345 + static const struct snd_kcontrol_new alc5623_amp_mux_controls = 346 + SOC_DAPM_ENUM("Route", alc5623_amp_enum); 347 + 348 + static const struct snd_soc_dapm_widget alc5623_dapm_amp_widgets[] = { 349 + SND_SOC_DAPM_PGA_E("D Amp", ALC5623_PWR_MANAG_ADD2, 14, 0, NULL, 0, 350 + amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 351 + SND_SOC_DAPM_PGA("AB Amp", ALC5623_PWR_MANAG_ADD2, 15, 0, NULL, 0), 352 + SND_SOC_DAPM_MUX("AB-D Amp Mux", SND_SOC_NOPM, 0, 0, 353 + &alc5623_amp_mux_controls), 354 + }; 355 + 356 + static const struct snd_soc_dapm_route intercon[] = { 357 + /* virtual mixer - mixes left & right channels */ 358 + {"I2S Mix", NULL, "Left DAC"}, 359 + {"I2S Mix", NULL, "Right DAC"}, 360 + {"Line Mix", NULL, "Right LineIn"}, 361 + {"Line Mix", NULL, "Left LineIn"}, 362 + {"AuxI Mix", NULL, "Left AuxI"}, 363 + {"AuxI Mix", NULL, "Right AuxI"}, 364 + {"AUXOUTL", NULL, "Left AuxOut"}, 365 + {"AUXOUTR", NULL, "Right AuxOut"}, 366 + 367 + /* HP mixer */ 368 + {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"}, 369 + {"HPL Mix", NULL, "HP Mix"}, 370 + {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"}, 371 + {"HPR Mix", NULL, "HP Mix"}, 372 + {"HP Mix", "LI2HP Playback Switch", "Line Mix"}, 373 + {"HP Mix", "AUXI2HP Playback Switch", "AuxI Mix"}, 374 + {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, 375 + {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, 376 + {"HP Mix", "DAC2HP Playback Switch", "I2S Mix"}, 377 + 378 + /* speaker mixer */ 379 + {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, 380 + {"Speaker Mix", "AUXI2SPK Playback Switch", "AuxI Mix"}, 381 + {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, 382 + {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, 383 + {"Speaker Mix", "DAC2SPK Playback Switch", "I2S Mix"}, 384 + 385 + /* mono mixer */ 386 + {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, 387 + {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, 388 + {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, 389 + {"Mono Mix", "AUXI2MONO Playback Switch", "AuxI Mix"}, 390 + {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, 391 + {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, 392 + {"Mono Mix", "DAC2MONO Playback Switch", "I2S Mix"}, 393 + 394 + /* Left record mixer */ 395 + {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, 396 + {"Left Capture Mix", "Left AuxI Capture Switch", "AUXINL"}, 397 + {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, 398 + {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, 399 + {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, 400 + {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, 401 + {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, 402 + 403 + /*Right record mixer */ 404 + {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, 405 + {"Right Capture Mix", "Right AuxI Capture Switch", "AUXINR"}, 406 + {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, 407 + {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, 408 + {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, 409 + {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, 410 + {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, 411 + 412 + /* headphone left mux */ 413 + {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, 414 + {"Left Headphone Mux", "Vmid", "Vmid"}, 415 + 416 + /* headphone right mux */ 417 + {"Right Headphone Mux", "HP Right Mix", "HPR Mix"}, 418 + {"Right Headphone Mux", "Vmid", "Vmid"}, 419 + 420 + /* speaker out mux */ 421 + {"SpeakerOut Mux", "Vmid", "Vmid"}, 422 + {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"}, 423 + {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"}, 424 + {"SpeakerOut Mux", "Mono Mix", "Mono Mix"}, 425 + 426 + /* Mono/Aux Out mux */ 427 + {"AuxOut Mux", "Vmid", "Vmid"}, 428 + {"AuxOut Mux", "HPOut Mix", "HPOut Mix"}, 429 + {"AuxOut Mux", "Speaker Mix", "Speaker Mix"}, 430 + {"AuxOut Mux", "Mono Mix", "Mono Mix"}, 431 + 432 + /* output pga */ 433 + {"HPL", NULL, "Left Headphone"}, 434 + {"Left Headphone", NULL, "Left Headphone Mux"}, 435 + {"HPR", NULL, "Right Headphone"}, 436 + {"Right Headphone", NULL, "Right Headphone Mux"}, 437 + {"Left AuxOut", NULL, "AuxOut Mux"}, 438 + {"Right AuxOut", NULL, "AuxOut Mux"}, 439 + 440 + /* input pga */ 441 + {"Left LineIn", NULL, "LINEINL"}, 442 + {"Right LineIn", NULL, "LINEINR"}, 443 + {"Left AuxI", NULL, "AUXINL"}, 444 + {"Right AuxI", NULL, "AUXINR"}, 445 + {"MIC1 Pre Amp", NULL, "MIC1"}, 446 + {"MIC2 Pre Amp", NULL, "MIC2"}, 447 + {"MIC1 PGA", NULL, "MIC1 Pre Amp"}, 448 + {"MIC2 PGA", NULL, "MIC2 Pre Amp"}, 449 + 450 + /* left ADC */ 451 + {"Left ADC", NULL, "Left Capture Mix"}, 452 + 453 + /* right ADC */ 454 + {"Right ADC", NULL, "Right Capture Mix"}, 455 + 456 + {"SpeakerOut N Mux", "RN/-R", "SpeakerOut"}, 457 + {"SpeakerOut N Mux", "RP/+R", "SpeakerOut"}, 458 + {"SpeakerOut N Mux", "LN/-R", "SpeakerOut"}, 459 + {"SpeakerOut N Mux", "Vmid", "Vmid"}, 460 + 461 + {"SPKOUT", NULL, "SpeakerOut"}, 462 + {"SPKOUTN", NULL, "SpeakerOut N Mux"}, 463 + }; 464 + 465 + static const struct snd_soc_dapm_route intercon_spk[] = { 466 + {"SpeakerOut", NULL, "SpeakerOut Mux"}, 467 + }; 468 + 469 + static const struct snd_soc_dapm_route intercon_amp_spk[] = { 470 + {"AB Amp", NULL, "SpeakerOut Mux"}, 471 + {"D Amp", NULL, "SpeakerOut Mux"}, 472 + {"AB-D Amp Mux", "AB Amp", "AB Amp"}, 473 + {"AB-D Amp Mux", "D Amp", "D Amp"}, 474 + {"SpeakerOut", NULL, "AB-D Amp Mux"}, 475 + }; 476 + 477 + /* PLL divisors */ 478 + struct _pll_div { 479 + u32 pll_in; 480 + u32 pll_out; 481 + u16 regvalue; 482 + }; 483 + 484 + /* Note : pll code from original alc5623 driver. Not sure of how good it is */ 485 + /* usefull only for master mode */ 486 + static const struct _pll_div codec_master_pll_div[] = { 487 + 488 + { 2048000, 8192000, 0x0ea0}, 489 + { 3686400, 8192000, 0x4e27}, 490 + { 12000000, 8192000, 0x456b}, 491 + { 13000000, 8192000, 0x495f}, 492 + { 13100000, 8192000, 0x0320}, 493 + { 2048000, 11289600, 0xf637}, 494 + { 3686400, 11289600, 0x2f22}, 495 + { 12000000, 11289600, 0x3e2f}, 496 + { 13000000, 11289600, 0x4d5b}, 497 + { 13100000, 11289600, 0x363b}, 498 + { 2048000, 16384000, 0x1ea0}, 499 + { 3686400, 16384000, 0x9e27}, 500 + { 12000000, 16384000, 0x452b}, 501 + { 13000000, 16384000, 0x542f}, 502 + { 13100000, 16384000, 0x03a0}, 503 + { 2048000, 16934400, 0xe625}, 504 + { 3686400, 16934400, 0x9126}, 505 + { 12000000, 16934400, 0x4d2c}, 506 + { 13000000, 16934400, 0x742f}, 507 + { 13100000, 16934400, 0x3c27}, 508 + { 2048000, 22579200, 0x2aa0}, 509 + { 3686400, 22579200, 0x2f20}, 510 + { 12000000, 22579200, 0x7e2f}, 511 + { 13000000, 22579200, 0x742f}, 512 + { 13100000, 22579200, 0x3c27}, 513 + { 2048000, 24576000, 0x2ea0}, 514 + { 3686400, 24576000, 0xee27}, 515 + { 12000000, 24576000, 0x2915}, 516 + { 13000000, 24576000, 0x772e}, 517 + { 13100000, 24576000, 0x0d20}, 518 + }; 519 + 520 + static const struct _pll_div codec_slave_pll_div[] = { 521 + 522 + { 1024000, 16384000, 0x3ea0}, 523 + { 1411200, 22579200, 0x3ea0}, 524 + { 1536000, 24576000, 0x3ea0}, 525 + { 2048000, 16384000, 0x1ea0}, 526 + { 2822400, 22579200, 0x1ea0}, 527 + { 3072000, 24576000, 0x1ea0}, 528 + 529 + }; 530 + 531 + static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 532 + int source, unsigned int freq_in, unsigned int freq_out) 533 + { 534 + int i; 535 + struct snd_soc_codec *codec = codec_dai->codec; 536 + int gbl_clk = 0, pll_div = 0; 537 + u16 reg; 538 + 539 + if (pll_id < ALC5623_PLL_FR_MCLK || pll_id > ALC5623_PLL_FR_BCK) 540 + return -ENODEV; 541 + 542 + /* Disable PLL power */ 543 + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2, 544 + ALC5623_PWR_ADD2_PLL, 545 + 0); 546 + 547 + /* pll is not used in slave mode */ 548 + reg = snd_soc_read(codec, ALC5623_DAI_CONTROL); 549 + if (reg & ALC5623_DAI_SDP_SLAVE_MODE) 550 + return 0; 551 + 552 + if (!freq_in || !freq_out) 553 + return 0; 554 + 555 + switch (pll_id) { 556 + case ALC5623_PLL_FR_MCLK: 557 + for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) { 558 + if (codec_master_pll_div[i].pll_in == freq_in 559 + && codec_master_pll_div[i].pll_out == freq_out) { 560 + /* PLL source from MCLK */ 561 + pll_div = codec_master_pll_div[i].regvalue; 562 + break; 563 + } 564 + } 565 + break; 566 + case ALC5623_PLL_FR_BCK: 567 + for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) { 568 + if (codec_slave_pll_div[i].pll_in == freq_in 569 + && codec_slave_pll_div[i].pll_out == freq_out) { 570 + /* PLL source from Bitclk */ 571 + gbl_clk = ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK; 572 + pll_div = codec_slave_pll_div[i].regvalue; 573 + break; 574 + } 575 + } 576 + break; 577 + default: 578 + return -EINVAL; 579 + } 580 + 581 + if (!pll_div) 582 + return -EINVAL; 583 + 584 + snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk); 585 + snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div); 586 + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2, 587 + ALC5623_PWR_ADD2_PLL, 588 + ALC5623_PWR_ADD2_PLL); 589 + gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL; 590 + snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk); 591 + 592 + return 0; 593 + } 594 + 595 + struct _coeff_div { 596 + u16 fs; 597 + u16 regvalue; 598 + }; 599 + 600 + /* codec hifi mclk (after PLL) clock divider coefficients */ 601 + /* values inspired from column BCLK=32Fs of Appendix A table */ 602 + static const struct _coeff_div coeff_div[] = { 603 + {256*8, 0x3a69}, 604 + {384*8, 0x3c6b}, 605 + {256*4, 0x2a69}, 606 + {384*4, 0x2c6b}, 607 + {256*2, 0x1a69}, 608 + {384*2, 0x1c6b}, 609 + {256*1, 0x0a69}, 610 + {384*1, 0x0c6b}, 611 + }; 612 + 613 + static int get_coeff(struct snd_soc_codec *codec, int rate) 614 + { 615 + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); 616 + int i; 617 + 618 + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 619 + if (coeff_div[i].fs * rate == alc5623->sysclk) 620 + return i; 621 + } 622 + return -EINVAL; 623 + } 624 + 625 + /* 626 + * Clock after PLL and dividers 627 + */ 628 + static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai, 629 + int clk_id, unsigned int freq, int dir) 630 + { 631 + struct snd_soc_codec *codec = codec_dai->codec; 632 + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); 633 + 634 + switch (freq) { 635 + case 8192000: 636 + case 11289600: 637 + case 12288000: 638 + case 16384000: 639 + case 16934400: 640 + case 18432000: 641 + case 22579200: 642 + case 24576000: 643 + alc5623->sysclk = freq; 644 + return 0; 645 + } 646 + return -EINVAL; 647 + } 648 + 649 + static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai, 650 + unsigned int fmt) 651 + { 652 + struct snd_soc_codec *codec = codec_dai->codec; 653 + u16 iface = 0; 654 + 655 + /* set master/slave audio interface */ 656 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 657 + case SND_SOC_DAIFMT_CBM_CFM: 658 + iface = ALC5623_DAI_SDP_MASTER_MODE; 659 + break; 660 + case SND_SOC_DAIFMT_CBS_CFS: 661 + iface = ALC5623_DAI_SDP_SLAVE_MODE; 662 + break; 663 + default: 664 + return -EINVAL; 665 + } 666 + 667 + /* interface format */ 668 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 669 + case SND_SOC_DAIFMT_I2S: 670 + iface |= ALC5623_DAI_I2S_DF_I2S; 671 + break; 672 + case SND_SOC_DAIFMT_RIGHT_J: 673 + iface |= ALC5623_DAI_I2S_DF_RIGHT; 674 + break; 675 + case SND_SOC_DAIFMT_LEFT_J: 676 + iface |= ALC5623_DAI_I2S_DF_LEFT; 677 + break; 678 + case SND_SOC_DAIFMT_DSP_A: 679 + iface |= ALC5623_DAI_I2S_DF_PCM; 680 + break; 681 + case SND_SOC_DAIFMT_DSP_B: 682 + iface |= ALC5623_DAI_I2S_DF_PCM | ALC5623_DAI_I2S_PCM_MODE; 683 + break; 684 + default: 685 + return -EINVAL; 686 + } 687 + 688 + /* clock inversion */ 689 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 690 + case SND_SOC_DAIFMT_NB_NF: 691 + break; 692 + case SND_SOC_DAIFMT_IB_IF: 693 + iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL; 694 + break; 695 + case SND_SOC_DAIFMT_IB_NF: 696 + iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL; 697 + break; 698 + case SND_SOC_DAIFMT_NB_IF: 699 + break; 700 + default: 701 + return -EINVAL; 702 + } 703 + 704 + return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface); 705 + } 706 + 707 + static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream, 708 + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 709 + { 710 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 711 + struct snd_soc_codec *codec = rtd->codec; 712 + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); 713 + int coeff, rate; 714 + u16 iface; 715 + 716 + iface = snd_soc_read(codec, ALC5623_DAI_CONTROL); 717 + iface &= ~ALC5623_DAI_I2S_DL_MASK; 718 + 719 + /* bit size */ 720 + switch (params_format(params)) { 721 + case SNDRV_PCM_FORMAT_S16_LE: 722 + iface |= ALC5623_DAI_I2S_DL_16; 723 + break; 724 + case SNDRV_PCM_FORMAT_S20_3LE: 725 + iface |= ALC5623_DAI_I2S_DL_20; 726 + break; 727 + case SNDRV_PCM_FORMAT_S24_LE: 728 + iface |= ALC5623_DAI_I2S_DL_24; 729 + break; 730 + case SNDRV_PCM_FORMAT_S32_LE: 731 + iface |= ALC5623_DAI_I2S_DL_32; 732 + break; 733 + default: 734 + return -EINVAL; 735 + } 736 + 737 + /* set iface & srate */ 738 + snd_soc_write(codec, ALC5623_DAI_CONTROL, iface); 739 + rate = params_rate(params); 740 + coeff = get_coeff(codec, rate); 741 + if (coeff < 0) 742 + return -EINVAL; 743 + 744 + coeff = coeff_div[coeff].regvalue; 745 + dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n", 746 + __func__, alc5623->sysclk, rate, coeff); 747 + snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff); 748 + 749 + return 0; 750 + } 751 + 752 + static int alc5623_mute(struct snd_soc_dai *dai, int mute) 753 + { 754 + struct snd_soc_codec *codec = dai->codec; 755 + u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT; 756 + u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute; 757 + 758 + if (mute) 759 + mute_reg |= hp_mute; 760 + 761 + return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg); 762 + } 763 + 764 + #define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \ 765 + | ALC5623_PWR_ADD2_DAC_REF_CIR) 766 + 767 + #define ALC5623_ADD3_POWER_EN (ALC5623_PWR_ADD3_MAIN_BIAS \ 768 + | ALC5623_PWR_ADD3_MIC1_BOOST_AD) 769 + 770 + #define ALC5623_ADD1_POWER_EN \ 771 + (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN | ALC5623_PWR_ADD1_SOFTGEN_EN \ 772 + | ALC5623_PWR_ADD1_DEPOP_BUF_HP | ALC5623_PWR_ADD1_HP_OUT_AMP \ 773 + | ALC5623_PWR_ADD1_HP_OUT_ENH_AMP) 774 + 775 + #define ALC5623_ADD1_POWER_EN_5622 \ 776 + (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \ 777 + | ALC5623_PWR_ADD1_HP_OUT_AMP) 778 + 779 + static void enable_power_depop(struct snd_soc_codec *codec) 780 + { 781 + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); 782 + 783 + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1, 784 + ALC5623_PWR_ADD1_SOFTGEN_EN, 785 + ALC5623_PWR_ADD1_SOFTGEN_EN); 786 + 787 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN); 788 + 789 + snd_soc_update_bits(codec, ALC5623_MISC_CTRL, 790 + ALC5623_MISC_HP_DEPOP_MODE2_EN, 791 + ALC5623_MISC_HP_DEPOP_MODE2_EN); 792 + 793 + msleep(500); 794 + 795 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN); 796 + 797 + /* avoid writing '1' into 5622 reserved bits */ 798 + if (alc5623->id == 0x22) 799 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 800 + ALC5623_ADD1_POWER_EN_5622); 801 + else 802 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 803 + ALC5623_ADD1_POWER_EN); 804 + 805 + /* disable HP Depop2 */ 806 + snd_soc_update_bits(codec, ALC5623_MISC_CTRL, 807 + ALC5623_MISC_HP_DEPOP_MODE2_EN, 808 + 0); 809 + 810 + } 811 + 812 + static int alc5623_set_bias_level(struct snd_soc_codec *codec, 813 + enum snd_soc_bias_level level) 814 + { 815 + switch (level) { 816 + case SND_SOC_BIAS_ON: 817 + enable_power_depop(codec); 818 + break; 819 + case SND_SOC_BIAS_PREPARE: 820 + break; 821 + case SND_SOC_BIAS_STANDBY: 822 + /* everything off except vref/vmid, */ 823 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 824 + ALC5623_PWR_ADD2_VREF); 825 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 826 + ALC5623_PWR_ADD3_MAIN_BIAS); 827 + break; 828 + case SND_SOC_BIAS_OFF: 829 + /* everything off, dac mute, inactive */ 830 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0); 831 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0); 832 + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0); 833 + break; 834 + } 835 + codec->bias_level = level; 836 + return 0; 837 + } 838 + 839 + #define ALC5623_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \ 840 + | SNDRV_PCM_FMTBIT_S24_LE \ 841 + | SNDRV_PCM_FMTBIT_S32_LE) 842 + 843 + static struct snd_soc_dai_ops alc5623_dai_ops = { 844 + .hw_params = alc5623_pcm_hw_params, 845 + .digital_mute = alc5623_mute, 846 + .set_fmt = alc5623_set_dai_fmt, 847 + .set_sysclk = alc5623_set_dai_sysclk, 848 + .set_pll = alc5623_set_dai_pll, 849 + }; 850 + 851 + static struct snd_soc_dai_driver alc5623_dai = { 852 + .name = "alc5623-hifi", 853 + .playback = { 854 + .stream_name = "Playback", 855 + .channels_min = 1, 856 + .channels_max = 2, 857 + .rate_min = 8000, 858 + .rate_max = 48000, 859 + .rates = SNDRV_PCM_RATE_8000_48000, 860 + .formats = ALC5623_FORMATS,}, 861 + .capture = { 862 + .stream_name = "Capture", 863 + .channels_min = 1, 864 + .channels_max = 2, 865 + .rate_min = 8000, 866 + .rate_max = 48000, 867 + .rates = SNDRV_PCM_RATE_8000_48000, 868 + .formats = ALC5623_FORMATS,}, 869 + 870 + .ops = &alc5623_dai_ops, 871 + }; 872 + 873 + static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg) 874 + { 875 + alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); 876 + return 0; 877 + } 878 + 879 + static int alc5623_resume(struct snd_soc_codec *codec) 880 + { 881 + int i, step = codec->driver->reg_cache_step; 882 + u16 *cache = codec->reg_cache; 883 + 884 + /* Sync reg_cache with the hardware */ 885 + for (i = 2 ; i < codec->driver->reg_cache_size ; i += step) 886 + snd_soc_write(codec, i, cache[i]); 887 + 888 + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 889 + 890 + /* charge alc5623 caps */ 891 + if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 892 + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 893 + codec->bias_level = SND_SOC_BIAS_ON; 894 + alc5623_set_bias_level(codec, codec->bias_level); 895 + } 896 + 897 + return 0; 898 + } 899 + 900 + static int alc5623_probe(struct snd_soc_codec *codec) 901 + { 902 + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); 903 + int ret; 904 + 905 + ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type); 906 + if (ret < 0) { 907 + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 908 + return ret; 909 + } 910 + 911 + alc5623_reset(codec); 912 + alc5623_fill_cache(codec); 913 + 914 + /* power on device */ 915 + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 916 + 917 + if (alc5623->add_ctrl) { 918 + snd_soc_write(codec, ALC5623_ADD_CTRL_REG, 919 + alc5623->add_ctrl); 920 + } 921 + 922 + if (alc5623->jack_det_ctrl) { 923 + snd_soc_write(codec, ALC5623_JACK_DET_CTRL, 924 + alc5623->jack_det_ctrl); 925 + } 926 + 927 + switch (alc5623->id) { 928 + default: 929 + case 0x21: 930 + snd_soc_add_controls(codec, rt5621_vol_snd_controls, 931 + ARRAY_SIZE(rt5621_vol_snd_controls)); 932 + break; 933 + case 0x22: 934 + snd_soc_add_controls(codec, rt5622_vol_snd_controls, 935 + ARRAY_SIZE(rt5622_vol_snd_controls)); 936 + break; 937 + case 0x23: 938 + snd_soc_add_controls(codec, alc5623_vol_snd_controls, 939 + ARRAY_SIZE(alc5623_vol_snd_controls)); 940 + break; 941 + } 942 + 943 + snd_soc_add_controls(codec, alc5623_snd_controls, 944 + ARRAY_SIZE(alc5623_snd_controls)); 945 + 946 + snd_soc_dapm_new_controls(codec, alc5623_dapm_widgets, 947 + ARRAY_SIZE(alc5623_dapm_widgets)); 948 + 949 + /* set up audio path interconnects */ 950 + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 951 + 952 + switch (alc5623->id) { 953 + default: 954 + case 0x21: 955 + case 0x22: 956 + snd_soc_dapm_new_controls(codec, alc5623_dapm_amp_widgets, 957 + ARRAY_SIZE(alc5623_dapm_amp_widgets)); 958 + snd_soc_dapm_add_routes(codec, intercon_amp_spk, 959 + ARRAY_SIZE(intercon_amp_spk)); 960 + break; 961 + case 0x23: 962 + snd_soc_dapm_add_routes(codec, intercon_spk, 963 + ARRAY_SIZE(intercon_spk)); 964 + break; 965 + } 966 + 967 + return ret; 968 + } 969 + 970 + /* power down chip */ 971 + static int alc5623_remove(struct snd_soc_codec *codec) 972 + { 973 + alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); 974 + return 0; 975 + } 976 + 977 + static struct snd_soc_codec_driver soc_codec_device_alc5623 = { 978 + .probe = alc5623_probe, 979 + .remove = alc5623_remove, 980 + .suspend = alc5623_suspend, 981 + .resume = alc5623_resume, 982 + .set_bias_level = alc5623_set_bias_level, 983 + .reg_cache_size = ALC5623_VENDOR_ID2+2, 984 + .reg_word_size = sizeof(u16), 985 + .reg_cache_step = 2, 986 + }; 987 + 988 + /* 989 + * ALC5623 2 wire address is determined by A1 pin 990 + * state during powerup. 991 + * low = 0x1a 992 + * high = 0x1b 993 + */ 994 + static int alc5623_i2c_probe(struct i2c_client *client, 995 + const struct i2c_device_id *id) 996 + { 997 + struct alc5623_platform_data *pdata; 998 + struct alc5623_priv *alc5623; 999 + int ret, vid1, vid2; 1000 + 1001 + vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1); 1002 + if (vid1 < 0) { 1003 + dev_err(&client->dev, "failed to read I2C\n"); 1004 + return -EIO; 1005 + } 1006 + vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); 1007 + 1008 + vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2); 1009 + if (vid2 < 0) { 1010 + dev_err(&client->dev, "failed to read I2C\n"); 1011 + return -EIO; 1012 + } 1013 + 1014 + if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { 1015 + dev_err(&client->dev, "unknown or wrong codec\n"); 1016 + dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n", 1017 + 0x10ec, id->driver_data, 1018 + vid1, vid2); 1019 + return -ENODEV; 1020 + } 1021 + 1022 + dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); 1023 + 1024 + alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL); 1025 + if (alc5623 == NULL) { 1026 + ret = -ENOMEM; 1027 + goto err; 1028 + } 1029 + 1030 + pdata = client->dev.platform_data; 1031 + if (pdata) { 1032 + alc5623->add_ctrl = pdata->add_ctrl; 1033 + alc5623->jack_det_ctrl = pdata->jack_det_ctrl; 1034 + } 1035 + 1036 + alc5623->id = vid2; 1037 + switch (alc5623->id) { 1038 + case 0x21: 1039 + alc5623_dai.name = "alc5621-hifi"; 1040 + break; 1041 + case 0x22: 1042 + alc5623_dai.name = "alc5622-hifi"; 1043 + break; 1044 + default: 1045 + case 0x23: 1046 + alc5623_dai.name = "alc5623-hifi"; 1047 + break; 1048 + } 1049 + 1050 + i2c_set_clientdata(client, alc5623); 1051 + alc5623->control_data = client; 1052 + alc5623->control_type = SND_SOC_I2C; 1053 + mutex_init(&alc5623->mutex); 1054 + 1055 + ret = snd_soc_register_codec(&client->dev, 1056 + &soc_codec_device_alc5623, &alc5623_dai, 1); 1057 + if (ret != 0) { 1058 + dev_err(&client->dev, "Failed to register codec: %d\n", ret); 1059 + goto err; 1060 + } 1061 + 1062 + return 0; 1063 + 1064 + err: 1065 + return ret; 1066 + } 1067 + 1068 + static int alc5623_i2c_remove(struct i2c_client *client) 1069 + { 1070 + struct alc5623_priv *alc5623 = i2c_get_clientdata(client); 1071 + 1072 + snd_soc_unregister_codec(&client->dev); 1073 + kfree(alc5623); 1074 + return 0; 1075 + } 1076 + 1077 + static const struct i2c_device_id alc5623_i2c_table[] = { 1078 + {"alc5621", 0x21}, 1079 + {"alc5622", 0x22}, 1080 + {"alc5623", 0x23}, 1081 + {} 1082 + }; 1083 + MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table); 1084 + 1085 + /* i2c codec control layer */ 1086 + static struct i2c_driver alc5623_i2c_driver = { 1087 + .driver = { 1088 + .name = "alc562x-codec", 1089 + .owner = THIS_MODULE, 1090 + }, 1091 + .probe = alc5623_i2c_probe, 1092 + .remove = __devexit_p(alc5623_i2c_remove), 1093 + .id_table = alc5623_i2c_table, 1094 + }; 1095 + 1096 + static int __init alc5623_modinit(void) 1097 + { 1098 + int ret; 1099 + 1100 + ret = i2c_add_driver(&alc5623_i2c_driver); 1101 + if (ret != 0) { 1102 + printk(KERN_ERR "%s: can't add i2c driver", __func__); 1103 + return ret; 1104 + } 1105 + 1106 + return ret; 1107 + } 1108 + module_init(alc5623_modinit); 1109 + 1110 + static void __exit alc5623_modexit(void) 1111 + { 1112 + i2c_del_driver(&alc5623_i2c_driver); 1113 + } 1114 + module_exit(alc5623_modexit); 1115 + 1116 + MODULE_DESCRIPTION("ASoC alc5621/2/3 driver"); 1117 + MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 1118 + MODULE_LICENSE("GPL");
+161
sound/soc/codecs/alc5623.h
··· 1 + /* 2 + * alc5623.h -- alc562[123] ALSA Soc Audio driver 3 + * 4 + * Copyright 2008 Realtek Microelectronics 5 + * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org> 6 + * 7 + * Author: flove <flove@realtek.com> 8 + * Arnaud Patard <arnaud.patard@rtp-net.org> 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + * 14 + */ 15 + 16 + #ifndef _ALC5623_H 17 + #define _ALC5623_H 18 + 19 + #define ALC5623_RESET 0x00 20 + /* 5621 5622 5623 */ 21 + /* speaker output vol 2 2 */ 22 + /* line output vol 4 2 */ 23 + /* HP output vol 4 0 4 */ 24 + #define ALC5623_SPK_OUT_VOL 0x02 25 + #define ALC5623_HP_OUT_VOL 0x04 26 + #define ALC5623_MONO_AUX_OUT_VOL 0x06 27 + #define ALC5623_AUXIN_VOL 0x08 28 + #define ALC5623_LINE_IN_VOL 0x0A 29 + #define ALC5623_STEREO_DAC_VOL 0x0C 30 + #define ALC5623_MIC_VOL 0x0E 31 + #define ALC5623_MIC_ROUTING_CTRL 0x10 32 + #define ALC5623_ADC_REC_GAIN 0x12 33 + #define ALC5623_ADC_REC_MIXER 0x14 34 + #define ALC5623_SOFT_VOL_CTRL_TIME 0x16 35 + /* ALC5623_OUTPUT_MIXER_CTRL : */ 36 + /* same remark as for reg 2 line vs speaker */ 37 + #define ALC5623_OUTPUT_MIXER_CTRL 0x1C 38 + #define ALC5623_MIC_CTRL 0x22 39 + 40 + #define ALC5623_DAI_CONTROL 0x34 41 + #define ALC5623_DAI_SDP_MASTER_MODE (0 << 15) 42 + #define ALC5623_DAI_SDP_SLAVE_MODE (1 << 15) 43 + #define ALC5623_DAI_I2S_PCM_MODE (1 << 14) 44 + #define ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7) 45 + #define ALC5623_DAI_ADC_DATA_L_R_SWAP (1 << 5) 46 + #define ALC5623_DAI_DAC_DATA_L_R_SWAP (1 << 4) 47 + #define ALC5623_DAI_I2S_DL_MASK (3 << 2) 48 + #define ALC5623_DAI_I2S_DL_32 (3 << 2) 49 + #define ALC5623_DAI_I2S_DL_24 (2 << 2) 50 + #define ALC5623_DAI_I2S_DL_20 (1 << 2) 51 + #define ALC5623_DAI_I2S_DL_16 (0 << 2) 52 + #define ALC5623_DAI_I2S_DF_PCM (3 << 0) 53 + #define ALC5623_DAI_I2S_DF_LEFT (2 << 0) 54 + #define ALC5623_DAI_I2S_DF_RIGHT (1 << 0) 55 + #define ALC5623_DAI_I2S_DF_I2S (0 << 0) 56 + 57 + #define ALC5623_STEREO_AD_DA_CLK_CTRL 0x36 58 + #define ALC5623_COMPANDING_CTRL 0x38 59 + 60 + #define ALC5623_PWR_MANAG_ADD1 0x3A 61 + #define ALC5623_PWR_ADD1_MAIN_I2S_EN (1 << 15) 62 + #define ALC5623_PWR_ADD1_ZC_DET_PD_EN (1 << 14) 63 + #define ALC5623_PWR_ADD1_MIC1_BIAS_EN (1 << 11) 64 + #define ALC5623_PWR_ADD1_SHORT_CURR_DET_EN (1 << 10) 65 + #define ALC5623_PWR_ADD1_SOFTGEN_EN (1 << 8) /* rsvd on 5622 */ 66 + #define ALC5623_PWR_ADD1_DEPOP_BUF_HP (1 << 6) /* rsvd on 5622 */ 67 + #define ALC5623_PWR_ADD1_HP_OUT_AMP (1 << 5) 68 + #define ALC5623_PWR_ADD1_HP_OUT_ENH_AMP (1 << 4) /* rsvd on 5622 */ 69 + #define ALC5623_PWR_ADD1_DEPOP_BUF_AUX (1 << 2) 70 + #define ALC5623_PWR_ADD1_AUX_OUT_AMP (1 << 1) 71 + #define ALC5623_PWR_ADD1_AUX_OUT_ENH_AMP (1 << 0) /* rsvd on 5622 */ 72 + 73 + #define ALC5623_PWR_MANAG_ADD2 0x3C 74 + #define ALC5623_PWR_ADD2_LINEOUT (1 << 15) /* rt5623 */ 75 + #define ALC5623_PWR_ADD2_CLASS_AB (1 << 15) /* rt5621 */ 76 + #define ALC5623_PWR_ADD2_CLASS_D (1 << 14) /* rt5621 */ 77 + #define ALC5623_PWR_ADD2_VREF (1 << 13) 78 + #define ALC5623_PWR_ADD2_PLL (1 << 12) 79 + #define ALC5623_PWR_ADD2_DAC_REF_CIR (1 << 10) 80 + #define ALC5623_PWR_ADD2_L_DAC_CLK (1 << 9) 81 + #define ALC5623_PWR_ADD2_R_DAC_CLK (1 << 8) 82 + #define ALC5623_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7) 83 + #define ALC5623_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6) 84 + #define ALC5623_PWR_ADD2_L_HP_MIXER (1 << 5) 85 + #define ALC5623_PWR_ADD2_R_HP_MIXER (1 << 4) 86 + #define ALC5623_PWR_ADD2_SPK_MIXER (1 << 3) 87 + #define ALC5623_PWR_ADD2_MONO_MIXER (1 << 2) 88 + #define ALC5623_PWR_ADD2_L_ADC_REC_MIXER (1 << 1) 89 + #define ALC5623_PWR_ADD2_R_ADC_REC_MIXER (1 << 0) 90 + 91 + #define ALC5623_PWR_MANAG_ADD3 0x3E 92 + #define ALC5623_PWR_ADD3_MAIN_BIAS (1 << 15) 93 + #define ALC5623_PWR_ADD3_AUXOUT_L_VOL_AMP (1 << 14) 94 + #define ALC5623_PWR_ADD3_AUXOUT_R_VOL_AMP (1 << 13) 95 + #define ALC5623_PWR_ADD3_SPK_OUT (1 << 12) 96 + #define ALC5623_PWR_ADD3_HP_L_OUT_VOL (1 << 10) 97 + #define ALC5623_PWR_ADD3_HP_R_OUT_VOL (1 << 9) 98 + #define ALC5623_PWR_ADD3_LINEIN_L_VOL (1 << 7) 99 + #define ALC5623_PWR_ADD3_LINEIN_R_VOL (1 << 6) 100 + #define ALC5623_PWR_ADD3_AUXIN_L_VOL (1 << 5) 101 + #define ALC5623_PWR_ADD3_AUXIN_R_VOL (1 << 4) 102 + #define ALC5623_PWR_ADD3_MIC1_FUN_CTRL (1 << 3) 103 + #define ALC5623_PWR_ADD3_MIC2_FUN_CTRL (1 << 2) 104 + #define ALC5623_PWR_ADD3_MIC1_BOOST_AD (1 << 1) 105 + #define ALC5623_PWR_ADD3_MIC2_BOOST_AD (1 << 0) 106 + 107 + #define ALC5623_ADD_CTRL_REG 0x40 108 + 109 + #define ALC5623_GLOBAL_CLK_CTRL_REG 0x42 110 + #define ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL (1 << 15) 111 + #define ALC5623_GBL_CLK_SYS_SOUR_SEL_MCLK (0 << 15) 112 + #define ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK (1 << 14) 113 + #define ALC5623_GBL_CLK_PLL_SOUR_SEL_MCLK (0 << 14) 114 + #define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV8 (3 << 1) 115 + #define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV4 (2 << 1) 116 + #define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV2 (1 << 1) 117 + #define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV1 (0 << 1) 118 + #define ALC5623_GBL_CLK_PLL_PRE_DIV2 (1 << 0) 119 + #define ALC5623_GBL_CLK_PLL_PRE_DIV1 (0 << 0) 120 + 121 + #define ALC5623_PLL_CTRL 0x44 122 + #define ALC5623_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8) 123 + #define ALC5623_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4) 124 + #define ALC5623_PLL_CTRL_M_VAL(m) ((m)&0xf) 125 + 126 + #define ALC5623_GPIO_OUTPUT_PIN_CTRL 0x4A 127 + #define ALC5623_GPIO_PIN_CONFIG 0x4C 128 + #define ALC5623_GPIO_PIN_POLARITY 0x4E 129 + #define ALC5623_GPIO_PIN_STICKY 0x50 130 + #define ALC5623_GPIO_PIN_WAKEUP 0x52 131 + #define ALC5623_GPIO_PIN_STATUS 0x54 132 + #define ALC5623_GPIO_PIN_SHARING 0x56 133 + #define ALC5623_OVER_CURR_STATUS 0x58 134 + #define ALC5623_JACK_DET_CTRL 0x5A 135 + 136 + #define ALC5623_MISC_CTRL 0x5E 137 + #define ALC5623_MISC_DISABLE_FAST_VREG (1 << 15) 138 + #define ALC5623_MISC_SPK_CLASS_AB_OC_PD (1 << 13) /* 5621 */ 139 + #define ALC5623_MISC_SPK_CLASS_AB_OC_DET (1 << 12) /* 5621 */ 140 + #define ALC5623_MISC_HP_DEPOP_MODE3_EN (1 << 10) 141 + #define ALC5623_MISC_HP_DEPOP_MODE2_EN (1 << 9) 142 + #define ALC5623_MISC_HP_DEPOP_MODE1_EN (1 << 8) 143 + #define ALC5623_MISC_AUXOUT_DEPOP_MODE3_EN (1 << 6) 144 + #define ALC5623_MISC_AUXOUT_DEPOP_MODE2_EN (1 << 5) 145 + #define ALC5623_MISC_AUXOUT_DEPOP_MODE1_EN (1 << 4) 146 + #define ALC5623_MISC_M_DAC_L_INPUT (1 << 3) 147 + #define ALC5623_MISC_M_DAC_R_INPUT (1 << 2) 148 + #define ALC5623_MISC_IRQOUT_INV_CTRL (1 << 0) 149 + 150 + #define ALC5623_PSEDUEO_SPATIAL_CTRL 0x60 151 + #define ALC5623_EQ_CTRL 0x62 152 + #define ALC5623_EQ_MODE_ENABLE 0x66 153 + #define ALC5623_AVC_CTRL 0x68 154 + #define ALC5623_HID_CTRL_INDEX 0x6A 155 + #define ALC5623_HID_CTRL_DATA 0x6C 156 + #define ALC5623_VENDOR_ID1 0x7C 157 + #define ALC5623_VENDOR_ID2 0x7E 158 + 159 + #define ALC5623_PLL_FR_MCLK 0 160 + #define ALC5623_PLL_FR_BCK 1 161 + #endif