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