[alsa-devel] [PATCH 14/31] HDA patch_via.c: Add Jack detect feature for VT1708.
Li Bo
liboat at gmail.com
Mon Oct 5 16:27:20 CEST 2009
[ALSA] HDA VIA: Add Jack detect feature for VT1708.
Signed-off-by: Lydia Wang <lydiawang at viatech.com.cn>
Index: sound-2.6/sound/pci/hda/patch_via.c
===================================================================
--- sound-2.6.orig/sound/pci/hda/patch_via.c 2009-10-05 15:10:22.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_via.c 2009-10-05 15:10:36.000000000 +0800
@@ -257,6 +257,11 @@
unsigned int smart51_enabled;
enum VIA_HDA_CODEC codec_type;
+ /* work to check hp jack state */
+ struct hda_codec *codec;
+ struct delayed_work hp_jack_work;
+ int vt1708_jack_detectect;
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
struct hda_loopback_check loopback;
#endif
@@ -966,6 +971,8 @@
{0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
/* PW9 Output enable */
{0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+ /* power down jack detect function */
+ {0x1, 0xf81, 0x1},
{ }
};
@@ -1340,6 +1347,10 @@
return;
via_free_kctls(codec);
+ if (spec->codec_type == VT1708) {
+ cancel_delayed_work(&spec->hp_jack_work);
+ flush_scheduled_work();
+ }
kfree(codec->spec);
}
@@ -1724,6 +1735,52 @@
return;
}
+static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct via_spec *spec = codec->spec;
+
+ if (spec->codec_type != VT1708)
+ return 0;
+ spec->vt1708_jack_detectect =
+ !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
+ ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
+ return 0;
+}
+
+static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct via_spec *spec = codec->spec;
+ int change;
+
+ if (spec->codec_type != VT1708)
+ return 0;
+ spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
+ snd_hda_codec_write(codec, 0x1, 0, 0xf81, !spec->vt1708_jack_detectect);
+ change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
+ == !spec->vt1708_jack_detectect;
+ if (spec->vt1708_jack_detectect) {
+ mute_aa_path(codec, 1);
+ notify_aa_path_ctls(codec);
+ }
+ return change;
+}
+
+static struct snd_kcontrol_new vt1708_jack_detectect[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Jack Detect",
+ .count = 1,
+ .info = snd_ctl_boolean_mono_info,
+ .get = vt1708_jack_detectect_get,
+ .put = vt1708_jack_detectect_put,
+ },
+ {} /* end */
+};
+
static int vt1708_parse_auto_config(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
@@ -1751,6 +1808,10 @@
err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
if (err < 0)
return err;
+ /* add jack detect on/off control */
+ err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
+ if (err < 0)
+ return err;
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -1784,6 +1845,24 @@
return 0;
}
+static void update_hp_jack_state(struct work_struct *work)
+{
+ struct via_spec *spec = container_of(work, struct via_spec,
+ hp_jack_work.work);
+ static int present = 1;
+
+ if (spec->codec_type != VT1708)
+ return;
+ /* if jack state toggled */
+ if (present
+ != (snd_hda_codec_read(spec->codec, spec->autocfg.hp_pins[0], 0,
+ AC_VERB_GET_PIN_SENSE, 0) >> 31)) {
+ present ^= 1;
+ via_hp_automute(spec->codec);
+ }
+ schedule_delayed_work(&spec->hp_jack_work, msecs_to_jiffies(100));
+}
+
static int get_mux_nids(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
@@ -1860,7 +1939,9 @@
#ifdef CONFIG_SND_HDA_POWER_SAVE
spec->loopback.amplist = vt1708_loopbacks;
#endif
-
+ spec->codec = codec;
+ INIT_DELAYED_WORK(&spec->hp_jack_work, update_hp_jack_state);
+ schedule_delayed_work(&spec->hp_jack_work, msecs_to_jiffies(100));
return 0;
}
More information about the Alsa-devel
mailing list