|
@@ -441,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static inline void ad198x_shutup(struct hda_codec *codec)
|
|
|
+{
|
|
|
+ snd_hda_shutup_pins(codec);
|
|
|
+}
|
|
|
+
|
|
|
static void ad198x_free_kctls(struct hda_codec *codec)
|
|
|
{
|
|
|
struct ad198x_spec *spec = codec->spec;
|
|
@@ -454,6 +459,46 @@ static void ad198x_free_kctls(struct hda_codec *codec)
|
|
|
snd_array_free(&spec->kctls);
|
|
|
}
|
|
|
|
|
|
+static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
|
|
|
+ hda_nid_t hp)
|
|
|
+{
|
|
|
+ struct ad198x_spec *spec = codec->spec;
|
|
|
+ snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
|
|
|
+ !spec->inv_eapd ? 0x00 : 0x02);
|
|
|
+ snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
|
|
|
+ !spec->inv_eapd ? 0x00 : 0x02);
|
|
|
+}
|
|
|
+
|
|
|
+static void ad198x_power_eapd(struct hda_codec *codec)
|
|
|
+{
|
|
|
+ /* We currently only handle front, HP */
|
|
|
+ switch (codec->vendor_id) {
|
|
|
+ case 0x11d41882:
|
|
|
+ case 0x11d4882a:
|
|
|
+ case 0x11d41884:
|
|
|
+ case 0x11d41984:
|
|
|
+ case 0x11d41883:
|
|
|
+ case 0x11d4184a:
|
|
|
+ case 0x11d4194a:
|
|
|
+ case 0x11d4194b:
|
|
|
+ ad198x_power_eapd_write(codec, 0x12, 0x11);
|
|
|
+ break;
|
|
|
+ case 0x11d41981:
|
|
|
+ case 0x11d41983:
|
|
|
+ ad198x_power_eapd_write(codec, 0x05, 0x06);
|
|
|
+ break;
|
|
|
+ case 0x11d41986:
|
|
|
+ ad198x_power_eapd_write(codec, 0x1b, 0x1a);
|
|
|
+ break;
|
|
|
+ case 0x11d41988:
|
|
|
+ case 0x11d4198b:
|
|
|
+ case 0x11d4989a:
|
|
|
+ case 0x11d4989b:
|
|
|
+ ad198x_power_eapd_write(codec, 0x29, 0x22);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void ad198x_free(struct hda_codec *codec)
|
|
|
{
|
|
|
struct ad198x_spec *spec = codec->spec;
|
|
@@ -461,11 +506,29 @@ static void ad198x_free(struct hda_codec *codec)
|
|
|
if (!spec)
|
|
|
return;
|
|
|
|
|
|
+ ad198x_shutup(codec);
|
|
|
ad198x_free_kctls(codec);
|
|
|
kfree(spec);
|
|
|
snd_hda_detach_beep_device(codec);
|
|
|
}
|
|
|
|
|
|
+#ifdef SND_HDA_NEEDS_RESUME
|
|
|
+static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
|
|
|
+{
|
|
|
+ ad198x_shutup(codec);
|
|
|
+ ad198x_power_eapd(codec);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int ad198x_resume(struct hda_codec *codec)
|
|
|
+{
|
|
|
+ ad198x_init(codec);
|
|
|
+ snd_hda_codec_resume_amp(codec);
|
|
|
+ snd_hda_codec_resume_cache(codec);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static struct hda_codec_ops ad198x_patch_ops = {
|
|
|
.build_controls = ad198x_build_controls,
|
|
|
.build_pcms = ad198x_build_pcms,
|
|
@@ -474,6 +537,11 @@ static struct hda_codec_ops ad198x_patch_ops = {
|
|
|
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
|
|
.check_power_status = ad198x_check_power_status,
|
|
|
#endif
|
|
|
+#ifdef SND_HDA_NEEDS_RESUME
|
|
|
+ .suspend = ad198x_suspend,
|
|
|
+ .resume = ad198x_resume,
|
|
|
+#endif
|
|
|
+ .reboot_notify = ad198x_shutup,
|
|
|
};
|
|
|
|
|
|
|