0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/init.h>
0015 #include <linux/slab.h>
0016 #include <linux/mfd/wm97xx.h>
0017 #include <linux/module.h>
0018 #include <linux/device.h>
0019 #include <linux/regmap.h>
0020 #include <sound/core.h>
0021 #include <sound/pcm.h>
0022 #include <sound/ac97_codec.h>
0023 #include <sound/ac97/codec.h>
0024 #include <sound/ac97/compat.h>
0025 #include <sound/initval.h>
0026 #include <sound/pcm_params.h>
0027 #include <sound/tlv.h>
0028 #include <sound/soc.h>
0029
0030 #include "wm9713.h"
0031
0032 #define WM9713_VENDOR_ID 0x574d4c13
0033 #define WM9713_VENDOR_ID_MASK 0xffffffff
0034
0035 struct wm9713_priv {
0036 struct snd_ac97 *ac97;
0037 u32 pll_in;
0038 unsigned int hp_mixer[2];
0039 struct mutex lock;
0040 struct wm97xx_platform_data *mfd_pdata;
0041 };
0042
0043 #define HPL_MIXER 0
0044 #define HPR_MIXER 1
0045
0046 static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
0047 static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
0048 static const char *wm9713_rec_src[] =
0049 {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone", "Speaker",
0050 "Mono Out", "Zh"};
0051 static const char *wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
0052 static const char *wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"};
0053 static const char *wm9713_mono_pga[] = {"Vmid", "Zh", "Mono", "Inv"};
0054 static const char *wm9713_spk_pga[] =
0055 {"Vmid", "Zh", "Headphone", "Speaker", "Inv", "Headphone Vmid",
0056 "Speaker Vmid", "Inv Vmid"};
0057 static const char *wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone",
0058 "Headphone Vmid"};
0059 static const char *wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "Inv 1 Vmid"};
0060 static const char *wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "Inv 2 Vmid"};
0061 static const char *wm9713_dac_inv[] =
0062 {"Off", "Mono", "Speaker", "Left Headphone", "Right Headphone",
0063 "Headphone Mono", "NC", "Vmid"};
0064 static const char *wm9713_bass[] = {"Linear Control", "Adaptive Boost"};
0065 static const char *wm9713_ng_type[] = {"Constant Gain", "Mute"};
0066 static const char *wm9713_mic_select[] = {"Mic 1", "Mic 2 A", "Mic 2 B"};
0067 static const char *wm9713_micb_select[] = {"MPB", "MPA"};
0068
0069 static const struct soc_enum wm9713_enum[] = {
0070 SOC_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer),
0071 SOC_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux),
0072 SOC_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux),
0073 SOC_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src),
0074 SOC_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src),
0075 SOC_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain),
0076 SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select),
0077 SOC_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga),
0078 SOC_ENUM_SINGLE(AC97_REC_GAIN, 11, 8, wm9713_spk_pga),
0079 SOC_ENUM_SINGLE(AC97_REC_GAIN, 8, 8, wm9713_spk_pga),
0080 SOC_ENUM_SINGLE(AC97_REC_GAIN, 6, 3, wm9713_hp_pga),
0081 SOC_ENUM_SINGLE(AC97_REC_GAIN, 4, 3, wm9713_hp_pga),
0082 SOC_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga),
0083 SOC_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga),
0084 SOC_ENUM_SINGLE(AC97_REC_GAIN_MIC, 13, 8, wm9713_dac_inv),
0085 SOC_ENUM_SINGLE(AC97_REC_GAIN_MIC, 10, 8, wm9713_dac_inv),
0086 SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_bass),
0087 SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type),
0088 SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select),
0089 SOC_ENUM_SINGLE_VIRT(2, wm9713_micb_select),
0090 };
0091
0092 static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
0093 static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
0094 static const DECLARE_TLV_DB_SCALE(misc_tlv, -1500, 300, 0);
0095 static const DECLARE_TLV_DB_RANGE(mic_tlv,
0096 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
0097 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0)
0098 );
0099
0100 static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = {
0101 SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, out_tlv),
0102 SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1),
0103 SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1,
0104 out_tlv),
0105 SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1),
0106 SOC_DOUBLE_TLV("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1, main_tlv),
0107 SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1, main_tlv),
0108 SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
0109 SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
0110 SOC_SINGLE_TLV("Mic 1 Preamp Volume", AC97_3D_CONTROL, 10, 3, 0, mic_tlv),
0111 SOC_SINGLE_TLV("Mic 2 Preamp Volume", AC97_3D_CONTROL, 12, 3, 0, mic_tlv),
0112
0113 SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
0114 SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
0115
0116 SOC_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
0117 SOC_ENUM("Capture Volume Steps", wm9713_enum[5]),
0118 SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0),
0119 SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
0120
0121 SOC_SINGLE_TLV("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1, misc_tlv),
0122 SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
0123 SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
0124
0125 SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
0126 SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
0127 SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
0128 SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
0129 SOC_ENUM("ALC Function", wm9713_enum[6]),
0130 SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
0131 SOC_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0),
0132 SOC_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
0133 SOC_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
0134 SOC_ENUM("ALC NG Type", wm9713_enum[17]),
0135 SOC_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0),
0136
0137 SOC_DOUBLE("Speaker Playback ZC Switch", AC97_MASTER, 14, 6, 1, 0),
0138 SOC_DOUBLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
0139
0140 SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
0141 SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0),
0142 SOC_SINGLE_TLV("Out4 Playback Volume", AC97_MASTER_MONO, 8, 31, 1, out_tlv),
0143
0144 SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1),
0145 SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0),
0146 SOC_SINGLE_TLV("Out3 Playback Volume", AC97_MASTER_MONO, 0, 31, 1, out_tlv),
0147
0148 SOC_SINGLE_TLV("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1, main_tlv),
0149 SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
0150 SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
0151 SOC_SINGLE_TLV("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1, out_tlv),
0152
0153 SOC_SINGLE_TLV("Headphone Mixer Beep Playback Volume", AC97_AUX, 12, 7, 1,
0154 misc_tlv),
0155 SOC_SINGLE_TLV("Speaker Mixer Beep Playback Volume", AC97_AUX, 8, 7, 1,
0156 misc_tlv),
0157 SOC_SINGLE_TLV("Mono Mixer Beep Playback Volume", AC97_AUX, 4, 7, 1, misc_tlv),
0158
0159 SOC_SINGLE_TLV("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1,
0160 misc_tlv),
0161 SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
0162 SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1),
0163
0164 SOC_SINGLE_TLV("Headphone Mixer Aux Playback Volume", AC97_REC_SEL, 12, 7, 1,
0165 misc_tlv),
0166
0167 SOC_SINGLE_TLV("Speaker Mixer Voice Playback Volume", AC97_PCM, 8, 7, 1,
0168 misc_tlv),
0169 SOC_SINGLE_TLV("Speaker Mixer Aux Playback Volume", AC97_REC_SEL, 8, 7, 1,
0170 misc_tlv),
0171
0172 SOC_SINGLE_TLV("Mono Mixer Voice Playback Volume", AC97_PCM, 4, 7, 1,
0173 misc_tlv),
0174 SOC_SINGLE_TLV("Mono Mixer Aux Playback Volume", AC97_REC_SEL, 4, 7, 1,
0175 misc_tlv),
0176
0177 SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1),
0178 SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1),
0179
0180 SOC_ENUM("Bass Control", wm9713_enum[16]),
0181 SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
0182 SOC_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1),
0183 SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0),
0184 SOC_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1),
0185 SOC_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1),
0186
0187 SOC_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
0188 SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
0189 SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
0190 };
0191
0192 static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
0193 struct snd_kcontrol *kcontrol, int event)
0194 {
0195 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0196
0197 if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD))
0198 return -EINVAL;
0199
0200
0201 snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, 0x0200);
0202 schedule_timeout_interruptible(msecs_to_jiffies(1));
0203 snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, 0x0f00);
0204 snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x1000, 0x1000);
0205
0206 return 0;
0207 }
0208
0209 static const unsigned int wm9713_mixer_mute_regs[] = {
0210 AC97_PC_BEEP,
0211 AC97_MASTER_TONE,
0212 AC97_PHONE,
0213 AC97_REC_SEL,
0214 AC97_PCM,
0215 AC97_AUX,
0216 };
0217
0218
0219
0220
0221
0222
0223
0224 static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
0225 struct snd_ctl_elem_value *ucontrol)
0226 {
0227 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
0228 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
0229 struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
0230 unsigned int val = ucontrol->value.integer.value[0];
0231 struct soc_mixer_control *mc =
0232 (struct soc_mixer_control *)kcontrol->private_value;
0233 unsigned int mixer, mask, shift, old;
0234 struct snd_soc_dapm_update update = {};
0235 bool change;
0236
0237 mixer = mc->shift >> 8;
0238 shift = mc->shift & 0xff;
0239 mask = (1 << shift);
0240
0241 mutex_lock(&wm9713->lock);
0242 old = wm9713->hp_mixer[mixer];
0243 if (ucontrol->value.integer.value[0])
0244 wm9713->hp_mixer[mixer] |= mask;
0245 else
0246 wm9713->hp_mixer[mixer] &= ~mask;
0247
0248 change = old != wm9713->hp_mixer[mixer];
0249 if (change) {
0250 update.kcontrol = kcontrol;
0251 update.reg = wm9713_mixer_mute_regs[shift];
0252 update.mask = 0x8000;
0253 if ((wm9713->hp_mixer[0] & mask) ||
0254 (wm9713->hp_mixer[1] & mask))
0255 update.val = 0x0;
0256 else
0257 update.val = 0x8000;
0258
0259 snd_soc_dapm_mixer_update_power(dapm, kcontrol, val,
0260 &update);
0261 }
0262
0263 mutex_unlock(&wm9713->lock);
0264
0265 return change;
0266 }
0267
0268 static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol,
0269 struct snd_ctl_elem_value *ucontrol)
0270 {
0271 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
0272 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
0273 struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
0274 struct soc_mixer_control *mc =
0275 (struct soc_mixer_control *)kcontrol->private_value;
0276 unsigned int mixer, shift;
0277
0278 mixer = mc->shift >> 8;
0279 shift = mc->shift & 0xff;
0280
0281 ucontrol->value.integer.value[0] =
0282 (wm9713->hp_mixer[mixer] >> shift) & 1;
0283
0284 return 0;
0285 }
0286
0287 #define WM9713_HP_MIXER_CTRL(xname, xmixer, xshift) { \
0288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0289 .info = snd_soc_info_volsw, \
0290 .get = wm9713_hp_mixer_get, .put = wm9713_hp_mixer_put, \
0291 .private_value = SOC_DOUBLE_VALUE(SND_SOC_NOPM, \
0292 xshift, xmixer, 1, 0, 0) \
0293 }
0294
0295
0296 static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = {
0297 WM9713_HP_MIXER_CTRL("Beep Playback Switch", HPL_MIXER, 5),
0298 WM9713_HP_MIXER_CTRL("Voice Playback Switch", HPL_MIXER, 4),
0299 WM9713_HP_MIXER_CTRL("Aux Playback Switch", HPL_MIXER, 3),
0300 WM9713_HP_MIXER_CTRL("PCM Playback Switch", HPL_MIXER, 2),
0301 WM9713_HP_MIXER_CTRL("MonoIn Playback Switch", HPL_MIXER, 1),
0302 WM9713_HP_MIXER_CTRL("Bypass Playback Switch", HPL_MIXER, 0),
0303 };
0304
0305
0306 static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = {
0307 WM9713_HP_MIXER_CTRL("Beep Playback Switch", HPR_MIXER, 5),
0308 WM9713_HP_MIXER_CTRL("Voice Playback Switch", HPR_MIXER, 4),
0309 WM9713_HP_MIXER_CTRL("Aux Playback Switch", HPR_MIXER, 3),
0310 WM9713_HP_MIXER_CTRL("PCM Playback Switch", HPR_MIXER, 2),
0311 WM9713_HP_MIXER_CTRL("MonoIn Playback Switch", HPR_MIXER, 1),
0312 WM9713_HP_MIXER_CTRL("Bypass Playback Switch", HPR_MIXER, 0),
0313 };
0314
0315
0316 static const struct snd_kcontrol_new wm9713_hp_rec_mux_controls =
0317 SOC_DAPM_ENUM("Route", wm9713_enum[1]);
0318
0319
0320 static const struct snd_kcontrol_new wm9713_hp_mic_mux_controls =
0321 SOC_DAPM_ENUM("Route", wm9713_enum[0]);
0322
0323
0324 static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = {
0325 SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 11, 1, 1),
0326 SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1),
0327 SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1),
0328 SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1),
0329 SOC_DAPM_SINGLE("MonoIn Playback Switch", AC97_MASTER_TONE, 14, 1, 1),
0330 SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 14, 1, 1),
0331 };
0332
0333
0334 static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = {
0335 SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 7, 1, 1),
0336 SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1),
0337 SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1),
0338 SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1),
0339 SOC_DAPM_SINGLE("MonoIn Playback Switch", AC97_MASTER_TONE, 13, 1, 1),
0340 SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 13, 1, 1),
0341 SOC_DAPM_SINGLE("Mic 1 Sidetone Switch", AC97_LINE, 7, 1, 1),
0342 SOC_DAPM_SINGLE("Mic 2 Sidetone Switch", AC97_LINE, 6, 1, 1),
0343 };
0344
0345
0346 static const struct snd_kcontrol_new wm9713_mono_mic_mux_controls =
0347 SOC_DAPM_ENUM("Route", wm9713_enum[2]);
0348
0349
0350 static const struct snd_kcontrol_new wm9713_mono_mux_controls =
0351 SOC_DAPM_ENUM("Route", wm9713_enum[7]);
0352
0353
0354 static const struct snd_kcontrol_new wm9713_hp_spkl_mux_controls =
0355 SOC_DAPM_ENUM("Route", wm9713_enum[8]);
0356
0357
0358 static const struct snd_kcontrol_new wm9713_hp_spkr_mux_controls =
0359 SOC_DAPM_ENUM("Route", wm9713_enum[9]);
0360
0361
0362 static const struct snd_kcontrol_new wm9713_hpl_out_mux_controls =
0363 SOC_DAPM_ENUM("Route", wm9713_enum[10]);
0364
0365
0366 static const struct snd_kcontrol_new wm9713_hpr_out_mux_controls =
0367 SOC_DAPM_ENUM("Route", wm9713_enum[11]);
0368
0369
0370 static const struct snd_kcontrol_new wm9713_out3_mux_controls =
0371 SOC_DAPM_ENUM("Route", wm9713_enum[12]);
0372
0373
0374 static const struct snd_kcontrol_new wm9713_out4_mux_controls =
0375 SOC_DAPM_ENUM("Route", wm9713_enum[13]);
0376
0377
0378 static const struct snd_kcontrol_new wm9713_dac_inv1_mux_controls =
0379 SOC_DAPM_ENUM("Route", wm9713_enum[14]);
0380
0381
0382 static const struct snd_kcontrol_new wm9713_dac_inv2_mux_controls =
0383 SOC_DAPM_ENUM("Route", wm9713_enum[15]);
0384
0385
0386 static const struct snd_kcontrol_new wm9713_rec_srcl_mux_controls =
0387 SOC_DAPM_ENUM("Route", wm9713_enum[3]);
0388
0389
0390 static const struct snd_kcontrol_new wm9713_rec_srcr_mux_controls =
0391 SOC_DAPM_ENUM("Route", wm9713_enum[4]);
0392
0393
0394 static const struct snd_kcontrol_new wm9713_mic_sel_mux_controls =
0395 SOC_DAPM_ENUM("Route", wm9713_enum[18]);
0396
0397
0398 static const struct snd_kcontrol_new wm9713_micb_sel_mux_controls =
0399 SOC_DAPM_ENUM("Route", wm9713_enum[19]);
0400
0401 static const struct snd_soc_dapm_widget wm9713_dapm_widgets[] = {
0402 SND_SOC_DAPM_MUX("Capture Headphone Mux", SND_SOC_NOPM, 0, 0,
0403 &wm9713_hp_rec_mux_controls),
0404 SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,
0405 &wm9713_hp_mic_mux_controls),
0406 SND_SOC_DAPM_MUX("Capture Mono Mux", SND_SOC_NOPM, 0, 0,
0407 &wm9713_mono_mic_mux_controls),
0408 SND_SOC_DAPM_MUX("Mono Out Mux", SND_SOC_NOPM, 0, 0,
0409 &wm9713_mono_mux_controls),
0410 SND_SOC_DAPM_MUX("Left Speaker Out Mux", SND_SOC_NOPM, 0, 0,
0411 &wm9713_hp_spkl_mux_controls),
0412 SND_SOC_DAPM_MUX("Right Speaker Out Mux", SND_SOC_NOPM, 0, 0,
0413 &wm9713_hp_spkr_mux_controls),
0414 SND_SOC_DAPM_MUX("Left Headphone Out Mux", SND_SOC_NOPM, 0, 0,
0415 &wm9713_hpl_out_mux_controls),
0416 SND_SOC_DAPM_MUX("Right Headphone Out Mux", SND_SOC_NOPM, 0, 0,
0417 &wm9713_hpr_out_mux_controls),
0418 SND_SOC_DAPM_MUX("Out 3 Mux", SND_SOC_NOPM, 0, 0,
0419 &wm9713_out3_mux_controls),
0420 SND_SOC_DAPM_MUX("Out 4 Mux", SND_SOC_NOPM, 0, 0,
0421 &wm9713_out4_mux_controls),
0422 SND_SOC_DAPM_MUX("DAC Inv Mux 1", SND_SOC_NOPM, 0, 0,
0423 &wm9713_dac_inv1_mux_controls),
0424 SND_SOC_DAPM_MUX("DAC Inv Mux 2", SND_SOC_NOPM, 0, 0,
0425 &wm9713_dac_inv2_mux_controls),
0426 SND_SOC_DAPM_MUX("Left Capture Source", SND_SOC_NOPM, 0, 0,
0427 &wm9713_rec_srcl_mux_controls),
0428 SND_SOC_DAPM_MUX("Right Capture Source", SND_SOC_NOPM, 0, 0,
0429 &wm9713_rec_srcr_mux_controls),
0430 SND_SOC_DAPM_MUX("Mic A Source", SND_SOC_NOPM, 0, 0,
0431 &wm9713_mic_sel_mux_controls),
0432 SND_SOC_DAPM_MUX("Mic B Source", SND_SOC_NOPM, 0, 0,
0433 &wm9713_micb_sel_mux_controls),
0434 SND_SOC_DAPM_MIXER("Left HP Mixer", AC97_EXTENDED_MID, 3, 1,
0435 &wm9713_hpl_mixer_controls[0], ARRAY_SIZE(wm9713_hpl_mixer_controls)),
0436 SND_SOC_DAPM_MIXER("Right HP Mixer", AC97_EXTENDED_MID, 2, 1,
0437 &wm9713_hpr_mixer_controls[0], ARRAY_SIZE(wm9713_hpr_mixer_controls)),
0438 SND_SOC_DAPM_MIXER("Mono Mixer", AC97_EXTENDED_MID, 0, 1,
0439 &wm9713_mono_mixer_controls[0], ARRAY_SIZE(wm9713_mono_mixer_controls)),
0440 SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_EXTENDED_MID, 1, 1,
0441 &wm9713_speaker_mixer_controls[0],
0442 ARRAY_SIZE(wm9713_speaker_mixer_controls)),
0443 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", AC97_EXTENDED_MID, 7, 1),
0444 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", AC97_EXTENDED_MID, 6, 1),
0445 SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
0446 SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
0447 SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
0448 SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
0449 SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1,
0450 wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD),
0451 SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
0452 SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
0453 SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
0454 SND_SOC_DAPM_ADC("Left HiFi ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0),
0455 SND_SOC_DAPM_ADC("Right HiFi ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0),
0456 SND_SOC_DAPM_ADC("Left Voice ADC", "Left Voice Capture", SND_SOC_NOPM, 0, 0),
0457 SND_SOC_DAPM_ADC("Right Voice ADC", "Right Voice Capture", SND_SOC_NOPM, 0, 0),
0458 SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0),
0459 SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0),
0460 SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0),
0461 SND_SOC_DAPM_PGA("Right Speaker", AC97_EXTENDED_MSTATUS, 7, 1, NULL, 0),
0462 SND_SOC_DAPM_PGA("Out 3", AC97_EXTENDED_MSTATUS, 11, 1, NULL, 0),
0463 SND_SOC_DAPM_PGA("Out 4", AC97_EXTENDED_MSTATUS, 12, 1, NULL, 0),
0464 SND_SOC_DAPM_PGA("Mono Out", AC97_EXTENDED_MSTATUS, 13, 1, NULL, 0),
0465 SND_SOC_DAPM_PGA("Left Line In", AC97_EXTENDED_MSTATUS, 6, 1, NULL, 0),
0466 SND_SOC_DAPM_PGA("Right Line In", AC97_EXTENDED_MSTATUS, 5, 1, NULL, 0),
0467 SND_SOC_DAPM_PGA("Mono In", AC97_EXTENDED_MSTATUS, 4, 1, NULL, 0),
0468 SND_SOC_DAPM_PGA("Mic A PGA", AC97_EXTENDED_MSTATUS, 3, 1, NULL, 0),
0469 SND_SOC_DAPM_PGA("Mic B PGA", AC97_EXTENDED_MSTATUS, 2, 1, NULL, 0),
0470 SND_SOC_DAPM_PGA("Mic A Pre Amp", AC97_EXTENDED_MSTATUS, 1, 1, NULL, 0),
0471 SND_SOC_DAPM_PGA("Mic B Pre Amp", AC97_EXTENDED_MSTATUS, 0, 1, NULL, 0),
0472 SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_EXTENDED_MSTATUS, 14, 1),
0473 SND_SOC_DAPM_OUTPUT("MONO"),
0474 SND_SOC_DAPM_OUTPUT("HPL"),
0475 SND_SOC_DAPM_OUTPUT("HPR"),
0476 SND_SOC_DAPM_OUTPUT("SPKL"),
0477 SND_SOC_DAPM_OUTPUT("SPKR"),
0478 SND_SOC_DAPM_OUTPUT("OUT3"),
0479 SND_SOC_DAPM_OUTPUT("OUT4"),
0480 SND_SOC_DAPM_INPUT("LINEL"),
0481 SND_SOC_DAPM_INPUT("LINER"),
0482 SND_SOC_DAPM_INPUT("MONOIN"),
0483 SND_SOC_DAPM_INPUT("PCBEEP"),
0484 SND_SOC_DAPM_INPUT("MIC1"),
0485 SND_SOC_DAPM_INPUT("MIC2A"),
0486 SND_SOC_DAPM_INPUT("MIC2B"),
0487 SND_SOC_DAPM_VMID("VMID"),
0488 };
0489
0490 static const struct snd_soc_dapm_route wm9713_audio_map[] = {
0491
0492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
0493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
0494 {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"},
0495 {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"},
0496 {"Left HP Mixer", "PCM Playback Switch", "Left DAC"},
0497 {"Left HP Mixer", "MonoIn Playback Switch", "Mono In"},
0498 {"Left HP Mixer", NULL, "Capture Headphone Mux"},
0499
0500
0501 {"Right HP Mixer", "Beep Playback Switch", "PCBEEP"},
0502 {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"},
0503 {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"},
0504 {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"},
0505 {"Right HP Mixer", "PCM Playback Switch", "Right DAC"},
0506 {"Right HP Mixer", "MonoIn Playback Switch", "Mono In"},
0507 {"Right HP Mixer", NULL, "Capture Headphone Mux"},
0508
0509
0510 {"AC97 Mixer", NULL, "Left DAC"},
0511 {"AC97 Mixer", NULL, "Right DAC"},
0512 {"Line Mixer", NULL, "Right Line In"},
0513 {"Line Mixer", NULL, "Left Line In"},
0514 {"HP Mixer", NULL, "Left HP Mixer"},
0515 {"HP Mixer", NULL, "Right HP Mixer"},
0516 {"Capture Mixer", NULL, "Left Capture Source"},
0517 {"Capture Mixer", NULL, "Right Capture Source"},
0518
0519
0520 {"Speaker Mixer", "Beep Playback Switch", "PCBEEP"},
0521 {"Speaker Mixer", "Voice Playback Switch", "Voice DAC"},
0522 {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"},
0523 {"Speaker Mixer", "Bypass Playback Switch", "Line Mixer"},
0524 {"Speaker Mixer", "PCM Playback Switch", "AC97 Mixer"},
0525 {"Speaker Mixer", "MonoIn Playback Switch", "Mono In"},
0526
0527
0528 {"Mono Mixer", "Beep Playback Switch", "PCBEEP"},
0529 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
0530 {"Mono Mixer", "Aux Playback Switch", "Aux DAC"},
0531 {"Mono Mixer", "Bypass Playback Switch", "Line Mixer"},
0532 {"Mono Mixer", "PCM Playback Switch", "AC97 Mixer"},
0533 {"Mono Mixer", "Mic 1 Sidetone Switch", "Mic A PGA"},
0534 {"Mono Mixer", "Mic 2 Sidetone Switch", "Mic B PGA"},
0535 {"Mono Mixer", NULL, "Capture Mono Mux"},
0536
0537
0538 {"DAC Inv Mux 1", "Mono", "Mono Mixer"},
0539 {"DAC Inv Mux 1", "Speaker", "Speaker Mixer"},
0540 {"DAC Inv Mux 1", "Left Headphone", "Left HP Mixer"},
0541 {"DAC Inv Mux 1", "Right Headphone", "Right HP Mixer"},
0542 {"DAC Inv Mux 1", "Headphone Mono", "HP Mixer"},
0543
0544
0545 {"DAC Inv Mux 2", "Mono", "Mono Mixer"},
0546 {"DAC Inv Mux 2", "Speaker", "Speaker Mixer"},
0547 {"DAC Inv Mux 2", "Left Headphone", "Left HP Mixer"},
0548 {"DAC Inv Mux 2", "Right Headphone", "Right HP Mixer"},
0549 {"DAC Inv Mux 2", "Headphone Mono", "HP Mixer"},
0550
0551
0552 {"Left Headphone Out Mux", "Headphone", "Left HP Mixer"},
0553
0554
0555 {"Right Headphone Out Mux", "Headphone", "Right HP Mixer"},
0556
0557
0558 {"Left Speaker Out Mux", "Headphone", "Left HP Mixer"},
0559 {"Left Speaker Out Mux", "Speaker", "Speaker Mixer"},
0560 {"Left Speaker Out Mux", "Inv", "DAC Inv Mux 1"},
0561
0562
0563 {"Right Speaker Out Mux", "Headphone", "Right HP Mixer"},
0564 {"Right Speaker Out Mux", "Speaker", "Speaker Mixer"},
0565 {"Right Speaker Out Mux", "Inv", "DAC Inv Mux 2"},
0566
0567
0568 {"Mono Out Mux", "Mono", "Mono Mixer"},
0569 {"Mono Out Mux", "Inv", "DAC Inv Mux 1"},
0570
0571
0572 {"Out 3 Mux", "Inv 1", "DAC Inv Mux 1"},
0573
0574
0575 {"Out 4 Mux", "Inv 2", "DAC Inv Mux 2"},
0576
0577
0578 {"HPL", NULL, "Left Headphone"},
0579 {"Left Headphone", NULL, "Left Headphone Out Mux"},
0580 {"HPR", NULL, "Right Headphone"},
0581 {"Right Headphone", NULL, "Right Headphone Out Mux"},
0582 {"OUT3", NULL, "Out 3"},
0583 {"Out 3", NULL, "Out 3 Mux"},
0584 {"OUT4", NULL, "Out 4"},
0585 {"Out 4", NULL, "Out 4 Mux"},
0586 {"SPKL", NULL, "Left Speaker"},
0587 {"Left Speaker", NULL, "Left Speaker Out Mux"},
0588 {"SPKR", NULL, "Right Speaker"},
0589 {"Right Speaker", NULL, "Right Speaker Out Mux"},
0590 {"MONO", NULL, "Mono Out"},
0591 {"Mono Out", NULL, "Mono Out Mux"},
0592
0593
0594 {"Left Line In", NULL, "LINEL"},
0595 {"Right Line In", NULL, "LINER"},
0596 {"Mono In", NULL, "MONOIN"},
0597 {"Mic A PGA", NULL, "Mic A Pre Amp"},
0598 {"Mic B PGA", NULL, "Mic B Pre Amp"},
0599
0600
0601 {"Left Capture Source", "Mic 1", "Mic A Pre Amp"},
0602 {"Left Capture Source", "Mic 2", "Mic B Pre Amp"},
0603 {"Left Capture Source", "Line", "LINEL"},
0604 {"Left Capture Source", "Mono In", "MONOIN"},
0605 {"Left Capture Source", "Headphone", "Left HP Mixer"},
0606 {"Left Capture Source", "Speaker", "Speaker Mixer"},
0607 {"Left Capture Source", "Mono Out", "Mono Mixer"},
0608
0609
0610 {"Right Capture Source", "Mic 1", "Mic A Pre Amp"},
0611 {"Right Capture Source", "Mic 2", "Mic B Pre Amp"},
0612 {"Right Capture Source", "Line", "LINER"},
0613 {"Right Capture Source", "Mono In", "MONOIN"},
0614 {"Right Capture Source", "Headphone", "Right HP Mixer"},
0615 {"Right Capture Source", "Speaker", "Speaker Mixer"},
0616 {"Right Capture Source", "Mono Out", "Mono Mixer"},
0617
0618
0619 {"Left ADC", NULL, "Left Capture Source"},
0620 {"Left Voice ADC", NULL, "Left ADC"},
0621 {"Left HiFi ADC", NULL, "Left ADC"},
0622
0623
0624 {"Right ADC", NULL, "Right Capture Source"},
0625 {"Right Voice ADC", NULL, "Right ADC"},
0626 {"Right HiFi ADC", NULL, "Right ADC"},
0627
0628
0629 {"Mic A Pre Amp", NULL, "Mic A Source"},
0630 {"Mic A Source", "Mic 1", "MIC1"},
0631 {"Mic A Source", "Mic 2 A", "MIC2A"},
0632 {"Mic A Source", "Mic 2 B", "Mic B Source"},
0633 {"Mic B Pre Amp", "MPB", "Mic B Source"},
0634 {"Mic B Source", NULL, "MIC2B"},
0635
0636
0637 {"Capture Headphone Mux", "Stereo", "Capture Mixer"},
0638 {"Capture Headphone Mux", "Left", "Left Capture Source"},
0639 {"Capture Headphone Mux", "Right", "Right Capture Source"},
0640
0641
0642 {"Capture Mono Mux", "Stereo", "Capture Mixer"},
0643 {"Capture Mono Mux", "Left", "Left Capture Source"},
0644 {"Capture Mono Mux", "Right", "Right Capture Source"},
0645 };
0646
0647 static bool wm9713_readable_reg(struct device *dev, unsigned int reg)
0648 {
0649 switch (reg) {
0650 case AC97_RESET ... AC97_PCM_SURR_DAC_RATE:
0651 case AC97_PCM_LR_ADC_RATE:
0652 case AC97_CENTER_LFE_MASTER:
0653 case AC97_SPDIF ... AC97_LINE1_LEVEL:
0654 case AC97_GPIO_CFG ... 0x5c:
0655 case AC97_CODEC_CLASS_REV ... AC97_PCI_SID:
0656 case 0x74 ... AC97_VENDOR_ID2:
0657 return true;
0658 default:
0659 return false;
0660 }
0661 }
0662
0663 static bool wm9713_writeable_reg(struct device *dev, unsigned int reg)
0664 {
0665 switch (reg) {
0666 case AC97_VENDOR_ID1:
0667 case AC97_VENDOR_ID2:
0668 return false;
0669 default:
0670 return wm9713_readable_reg(dev, reg);
0671 }
0672 }
0673
0674 static const struct reg_default wm9713_reg_defaults[] = {
0675 { 0x02, 0x8080 },
0676 { 0x04, 0x8080 },
0677 { 0x06, 0x8080 },
0678 { 0x08, 0xc880 },
0679 { 0x0a, 0xe808 },
0680 { 0x0c, 0xe808 },
0681 { 0x0e, 0x0808 },
0682 { 0x10, 0x00da },
0683 { 0x12, 0x8000 },
0684 { 0x14, 0xd600 },
0685 { 0x16, 0xaaa0 },
0686 { 0x18, 0xaaa0 },
0687 { 0x1a, 0xaaa0 },
0688 { 0x1c, 0x0000 },
0689 { 0x1e, 0x0000 },
0690 { 0x20, 0x0f0f },
0691 { 0x22, 0x0040 },
0692 { 0x24, 0x0000 },
0693 { 0x26, 0x7f00 },
0694 { 0x28, 0x0405 },
0695 { 0x2a, 0x0410 },
0696 { 0x2c, 0xbb80 },
0697 { 0x2e, 0xbb80 },
0698 { 0x32, 0xbb80 },
0699 { 0x36, 0x4523 },
0700 { 0x3a, 0x2000 },
0701 { 0x3c, 0xfdff },
0702 { 0x3e, 0xffff },
0703 { 0x40, 0x0000 },
0704 { 0x42, 0x0000 },
0705 { 0x44, 0x0080 },
0706 { 0x46, 0x0000 },
0707 { 0x4c, 0xfffe },
0708 { 0x4e, 0xffff },
0709 { 0x50, 0x0000 },
0710 { 0x52, 0x0000 },
0711
0712 { 0x56, 0xfffe },
0713 { 0x58, 0x4000 },
0714 { 0x5a, 0x0000 },
0715 { 0x5c, 0x0000 },
0716 { 0x60, 0xb032 },
0717 { 0x62, 0x3e00 },
0718 { 0x64, 0x0000 },
0719 { 0x74, 0x0000 },
0720 { 0x76, 0x0006 },
0721 { 0x78, 0x0001 },
0722 { 0x7a, 0x0000 },
0723 };
0724
0725 static const struct regmap_config wm9713_regmap_config = {
0726 .reg_bits = 16,
0727 .reg_stride = 2,
0728 .val_bits = 16,
0729 .max_register = 0x7e,
0730 .cache_type = REGCACHE_RBTREE,
0731
0732 .reg_defaults = wm9713_reg_defaults,
0733 .num_reg_defaults = ARRAY_SIZE(wm9713_reg_defaults),
0734 .volatile_reg = regmap_ac97_default_volatile,
0735 .readable_reg = wm9713_readable_reg,
0736 .writeable_reg = wm9713_writeable_reg,
0737 };
0738
0739
0740 struct _pll_div {
0741 u32 divsel:1;
0742 u32 divctl:1;
0743 u32 lf:1;
0744 u32 n:4;
0745 u32 k:24;
0746 };
0747
0748
0749
0750 #define FIXED_PLL_SIZE ((1 << 22) * 10)
0751
0752 static void pll_factors(struct snd_soc_component *component,
0753 struct _pll_div *pll_div, unsigned int source)
0754 {
0755 u64 Kpart;
0756 unsigned int K, Ndiv, Nmod, target;
0757
0758
0759 target = 98304000;
0760
0761
0762 if (source > 14400000) {
0763 source >>= 1;
0764 pll_div->divsel = 1;
0765
0766 if (source > 14400000) {
0767 source >>= 1;
0768 pll_div->divctl = 1;
0769 } else
0770 pll_div->divctl = 0;
0771
0772 } else {
0773 pll_div->divsel = 0;
0774 pll_div->divctl = 0;
0775 }
0776
0777
0778
0779
0780 if (source < 8192000) {
0781 pll_div->lf = 1;
0782 target >>= 2;
0783 } else
0784 pll_div->lf = 0;
0785
0786 Ndiv = target / source;
0787 if ((Ndiv < 5) || (Ndiv > 12))
0788 dev_warn(component->dev,
0789 "WM9713 PLL N value %u out of recommended range!\n",
0790 Ndiv);
0791
0792 pll_div->n = Ndiv;
0793 Nmod = target % source;
0794 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
0795
0796 do_div(Kpart, source);
0797
0798 K = Kpart & 0xFFFFFFFF;
0799
0800
0801 if ((K % 10) >= 5)
0802 K += 5;
0803
0804
0805 K /= 10;
0806
0807 pll_div->k = K;
0808 }
0809
0810
0811
0812
0813
0814 static int wm9713_set_pll(struct snd_soc_component *component,
0815 int pll_id, unsigned int freq_in, unsigned int freq_out)
0816 {
0817 struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
0818 u16 reg, reg2;
0819 struct _pll_div pll_div;
0820
0821
0822 if (freq_in == 0) {
0823
0824 snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0080, 0x0080);
0825 snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x0200, 0x0200);
0826 wm9713->pll_in = 0;
0827 return 0;
0828 }
0829
0830 pll_factors(component, &pll_div, freq_in);
0831
0832 if (pll_div.k == 0) {
0833 reg = (pll_div.n << 12) | (pll_div.lf << 11) |
0834 (pll_div.divsel << 9) | (pll_div.divctl << 8);
0835 snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
0836 } else {
0837
0838 reg2 = (pll_div.n << 12) | (pll_div.lf << 11) | (1 << 10) |
0839 (pll_div.divsel << 9) | (pll_div.divctl << 8);
0840
0841
0842 reg = reg2 | (0x5 << 4) | (pll_div.k >> 20);
0843 snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
0844
0845
0846 reg = reg2 | (0x4 << 4) | ((pll_div.k >> 16) & 0xf);
0847 snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
0848
0849
0850 reg = reg2 | (0x3 << 4) | ((pll_div.k >> 12) & 0xf);
0851 snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
0852
0853
0854 reg = reg2 | (0x2 << 4) | ((pll_div.k >> 8) & 0xf);
0855 snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
0856
0857
0858 reg = reg2 | (0x1 << 4) | ((pll_div.k >> 4) & 0xf);
0859 snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
0860
0861 reg = reg2 | (0x0 << 4) | (pll_div.k & 0xf);
0862 snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
0863 }
0864
0865
0866 snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x0200, 0x0000);
0867 snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0080, 0x0000);
0868 wm9713->pll_in = freq_in;
0869
0870
0871 schedule_timeout_interruptible(msecs_to_jiffies(10));
0872 return 0;
0873 }
0874
0875 static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
0876 int source, unsigned int freq_in, unsigned int freq_out)
0877 {
0878 struct snd_soc_component *component = codec_dai->component;
0879 return wm9713_set_pll(component, pll_id, freq_in, freq_out);
0880 }
0881
0882
0883
0884
0885
0886 static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
0887 int tristate)
0888 {
0889 struct snd_soc_component *component = codec_dai->component;
0890
0891 if (tristate)
0892 snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
0893 0x6000, 0x0000);
0894
0895 return 0;
0896 }
0897
0898
0899
0900
0901
0902 static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
0903 int div_id, int div)
0904 {
0905 struct snd_soc_component *component = codec_dai->component;
0906
0907 switch (div_id) {
0908 case WM9713_PCMCLK_DIV:
0909 snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, div);
0910 break;
0911 case WM9713_CLKA_MULT:
0912 snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0002, div);
0913 break;
0914 case WM9713_CLKB_MULT:
0915 snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0004, div);
0916 break;
0917 case WM9713_HIFI_DIV:
0918 snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x7000, div);
0919 break;
0920 case WM9713_PCMBCLK_DIV:
0921 snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER, 0x0e00, div);
0922 break;
0923 case WM9713_PCMCLK_PLL_DIV:
0924 snd_soc_component_update_bits(component, AC97_LINE1_LEVEL,
0925 0x007f, div | 0x60);
0926 break;
0927 case WM9713_HIFI_PLL_DIV:
0928 snd_soc_component_update_bits(component, AC97_LINE1_LEVEL,
0929 0x007f, div | 0x70);
0930 break;
0931 default:
0932 return -EINVAL;
0933 }
0934
0935 return 0;
0936 }
0937
0938 static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
0939 unsigned int fmt)
0940 {
0941 struct snd_soc_component *component = codec_dai->component;
0942 u16 gpio = snd_soc_component_read(component, AC97_GPIO_CFG) & 0xffc5;
0943 u16 reg = 0x8000;
0944
0945
0946 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
0947 case SND_SOC_DAIFMT_CBM_CFM:
0948 reg |= 0x4000;
0949 gpio |= 0x0010;
0950 break;
0951 case SND_SOC_DAIFMT_CBM_CFS:
0952 reg |= 0x6000;
0953 gpio |= 0x0018;
0954 break;
0955 case SND_SOC_DAIFMT_CBS_CFS:
0956 reg |= 0x2000;
0957 gpio |= 0x001a;
0958 break;
0959 case SND_SOC_DAIFMT_CBS_CFM:
0960 gpio |= 0x0012;
0961 break;
0962 }
0963
0964
0965 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0966 case SND_SOC_DAIFMT_IB_IF:
0967 reg |= 0x00c0;
0968 break;
0969 case SND_SOC_DAIFMT_IB_NF:
0970 reg |= 0x0080;
0971 break;
0972 case SND_SOC_DAIFMT_NB_IF:
0973 reg |= 0x0040;
0974 break;
0975 }
0976
0977
0978 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0979 case SND_SOC_DAIFMT_I2S:
0980 reg |= 0x0002;
0981 break;
0982 case SND_SOC_DAIFMT_RIGHT_J:
0983 break;
0984 case SND_SOC_DAIFMT_LEFT_J:
0985 reg |= 0x0001;
0986 break;
0987 case SND_SOC_DAIFMT_DSP_A:
0988 reg |= 0x0003;
0989 break;
0990 case SND_SOC_DAIFMT_DSP_B:
0991 reg |= 0x0043;
0992 break;
0993 }
0994
0995 snd_soc_component_write(component, AC97_GPIO_CFG, gpio);
0996 snd_soc_component_write(component, AC97_CENTER_LFE_MASTER, reg);
0997 return 0;
0998 }
0999
1000 static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
1001 struct snd_pcm_hw_params *params,
1002 struct snd_soc_dai *dai)
1003 {
1004 struct snd_soc_component *component = dai->component;
1005
1006
1007 switch (params_width(params)) {
1008 case 16:
1009 break;
1010 case 20:
1011 snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
1012 0x000c, 0x0004);
1013 break;
1014 case 24:
1015 snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
1016 0x000c, 0x0008);
1017 break;
1018 case 32:
1019 snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
1020 0x000c, 0x000c);
1021 break;
1022 }
1023 return 0;
1024 }
1025
1026 static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
1027 struct snd_soc_dai *dai)
1028 {
1029 struct snd_soc_component *component = dai->component;
1030 struct snd_pcm_runtime *runtime = substream->runtime;
1031 int reg;
1032
1033 snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
1034
1035 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1036 reg = AC97_PCM_FRONT_DAC_RATE;
1037 else
1038 reg = AC97_PCM_LR_ADC_RATE;
1039
1040 return snd_soc_component_write(component, reg, runtime->rate);
1041 }
1042
1043 static int ac97_aux_prepare(struct snd_pcm_substream *substream,
1044 struct snd_soc_dai *dai)
1045 {
1046 struct snd_soc_component *component = dai->component;
1047 struct snd_pcm_runtime *runtime = substream->runtime;
1048
1049 snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
1050 snd_soc_component_update_bits(component, AC97_PCI_SID, 0x8000, 0x8000);
1051
1052 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
1053 return -ENODEV;
1054
1055 return snd_soc_component_write(component, AC97_PCM_SURR_DAC_RATE, runtime->rate);
1056 }
1057
1058 #define WM9713_RATES (SNDRV_PCM_RATE_8000 | \
1059 SNDRV_PCM_RATE_11025 | \
1060 SNDRV_PCM_RATE_22050 | \
1061 SNDRV_PCM_RATE_44100 | \
1062 SNDRV_PCM_RATE_48000)
1063
1064 #define WM9713_PCM_RATES (SNDRV_PCM_RATE_8000 | \
1065 SNDRV_PCM_RATE_11025 | \
1066 SNDRV_PCM_RATE_16000 | \
1067 SNDRV_PCM_RATE_22050 | \
1068 SNDRV_PCM_RATE_44100 | \
1069 SNDRV_PCM_RATE_48000)
1070
1071 #define WM9713_PCM_FORMATS \
1072 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1073 SNDRV_PCM_FMTBIT_S24_LE)
1074
1075 static const struct snd_soc_dai_ops wm9713_dai_ops_hifi = {
1076 .prepare = ac97_hifi_prepare,
1077 .set_clkdiv = wm9713_set_dai_clkdiv,
1078 .set_pll = wm9713_set_dai_pll,
1079 };
1080
1081 static const struct snd_soc_dai_ops wm9713_dai_ops_aux = {
1082 .prepare = ac97_aux_prepare,
1083 .set_clkdiv = wm9713_set_dai_clkdiv,
1084 .set_pll = wm9713_set_dai_pll,
1085 };
1086
1087 static const struct snd_soc_dai_ops wm9713_dai_ops_voice = {
1088 .hw_params = wm9713_pcm_hw_params,
1089 .set_clkdiv = wm9713_set_dai_clkdiv,
1090 .set_pll = wm9713_set_dai_pll,
1091 .set_fmt = wm9713_set_dai_fmt,
1092 .set_tristate = wm9713_set_dai_tristate,
1093 };
1094
1095 static struct snd_soc_dai_driver wm9713_dai[] = {
1096 {
1097 .name = "wm9713-hifi",
1098 .playback = {
1099 .stream_name = "HiFi Playback",
1100 .channels_min = 1,
1101 .channels_max = 2,
1102 .rates = WM9713_RATES,
1103 .formats = SND_SOC_STD_AC97_FMTS,},
1104 .capture = {
1105 .stream_name = "HiFi Capture",
1106 .channels_min = 1,
1107 .channels_max = 2,
1108 .rates = WM9713_RATES,
1109 .formats = SND_SOC_STD_AC97_FMTS,},
1110 .ops = &wm9713_dai_ops_hifi,
1111 },
1112 {
1113 .name = "wm9713-aux",
1114 .playback = {
1115 .stream_name = "Aux Playback",
1116 .channels_min = 1,
1117 .channels_max = 1,
1118 .rates = WM9713_RATES,
1119 .formats = SND_SOC_STD_AC97_FMTS,},
1120 .ops = &wm9713_dai_ops_aux,
1121 },
1122 {
1123 .name = "wm9713-voice",
1124 .playback = {
1125 .stream_name = "Voice Playback",
1126 .channels_min = 1,
1127 .channels_max = 1,
1128 .rates = WM9713_PCM_RATES,
1129 .formats = WM9713_PCM_FORMATS,},
1130 .capture = {
1131 .stream_name = "Voice Capture",
1132 .channels_min = 1,
1133 .channels_max = 2,
1134 .rates = WM9713_PCM_RATES,
1135 .formats = WM9713_PCM_FORMATS,},
1136 .ops = &wm9713_dai_ops_voice,
1137 .symmetric_rate = 1,
1138 },
1139 };
1140
1141 static int wm9713_set_bias_level(struct snd_soc_component *component,
1142 enum snd_soc_bias_level level)
1143 {
1144 switch (level) {
1145 case SND_SOC_BIAS_ON:
1146
1147 snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0xe400, 0x0000);
1148 break;
1149 case SND_SOC_BIAS_PREPARE:
1150 break;
1151 case SND_SOC_BIAS_STANDBY:
1152
1153 snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0xc400, 0x0000);
1154 snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
1155 break;
1156 case SND_SOC_BIAS_OFF:
1157
1158 snd_soc_component_write(component, AC97_EXTENDED_MID, 0xffff);
1159 snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
1160 snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
1161 break;
1162 }
1163 return 0;
1164 }
1165
1166 static int wm9713_soc_suspend(struct snd_soc_component *component)
1167 {
1168
1169
1170
1171 snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x7fff,
1172 0x7fff);
1173 snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
1174 snd_soc_component_write(component, AC97_POWERDOWN, 0x6f00);
1175 snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
1176
1177 return 0;
1178 }
1179
1180 static int wm9713_soc_resume(struct snd_soc_component *component)
1181 {
1182 struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
1183 int ret;
1184
1185 ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID,
1186 WM9713_VENDOR_ID_MASK);
1187 if (ret < 0)
1188 return ret;
1189
1190 snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
1191
1192
1193 if (wm9713->pll_in)
1194 wm9713_set_pll(component, 0, wm9713->pll_in, 0);
1195
1196
1197 if (ret == 0) {
1198 regcache_mark_dirty(component->regmap);
1199 snd_soc_component_cache_sync(component);
1200 }
1201
1202 return ret;
1203 }
1204
1205 static int wm9713_soc_probe(struct snd_soc_component *component)
1206 {
1207 struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
1208 struct regmap *regmap = NULL;
1209
1210 if (wm9713->mfd_pdata) {
1211 wm9713->ac97 = wm9713->mfd_pdata->ac97;
1212 regmap = wm9713->mfd_pdata->regmap;
1213 } else if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS)) {
1214 wm9713->ac97 = snd_soc_new_ac97_component(component, WM9713_VENDOR_ID,
1215 WM9713_VENDOR_ID_MASK);
1216 if (IS_ERR(wm9713->ac97))
1217 return PTR_ERR(wm9713->ac97);
1218 regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
1219 if (IS_ERR(regmap)) {
1220 snd_soc_free_ac97_component(wm9713->ac97);
1221 return PTR_ERR(regmap);
1222 }
1223 } else {
1224 return -ENXIO;
1225 }
1226
1227 snd_soc_component_init_regmap(component, regmap);
1228
1229
1230 snd_soc_component_update_bits(component, AC97_CD, 0x7fff, 0x0000);
1231
1232 return 0;
1233 }
1234
1235 static void wm9713_soc_remove(struct snd_soc_component *component)
1236 {
1237 struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
1238
1239 if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS) && !wm9713->mfd_pdata) {
1240 snd_soc_component_exit_regmap(component);
1241 snd_soc_free_ac97_component(wm9713->ac97);
1242 }
1243 }
1244
1245 static const struct snd_soc_component_driver soc_component_dev_wm9713 = {
1246 .probe = wm9713_soc_probe,
1247 .remove = wm9713_soc_remove,
1248 .suspend = wm9713_soc_suspend,
1249 .resume = wm9713_soc_resume,
1250 .set_bias_level = wm9713_set_bias_level,
1251 .controls = wm9713_snd_ac97_controls,
1252 .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls),
1253 .dapm_widgets = wm9713_dapm_widgets,
1254 .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
1255 .dapm_routes = wm9713_audio_map,
1256 .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
1257 .idle_bias_on = 1,
1258 .use_pmdown_time = 1,
1259 .endianness = 1,
1260 };
1261
1262 static int wm9713_probe(struct platform_device *pdev)
1263 {
1264 struct wm9713_priv *wm9713;
1265
1266 wm9713 = devm_kzalloc(&pdev->dev, sizeof(*wm9713), GFP_KERNEL);
1267 if (wm9713 == NULL)
1268 return -ENOMEM;
1269
1270 mutex_init(&wm9713->lock);
1271
1272 wm9713->mfd_pdata = dev_get_platdata(&pdev->dev);
1273 platform_set_drvdata(pdev, wm9713);
1274
1275 return devm_snd_soc_register_component(&pdev->dev,
1276 &soc_component_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
1277 }
1278
1279 static struct platform_driver wm9713_codec_driver = {
1280 .driver = {
1281 .name = "wm9713-codec",
1282 },
1283
1284 .probe = wm9713_probe,
1285 };
1286
1287 module_platform_driver(wm9713_codec_driver);
1288
1289 MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
1290 MODULE_AUTHOR("Liam Girdwood");
1291 MODULE_LICENSE("GPL");