ALSA: Introduce common helper functions for jack-detection control
authorTakashi Iwai <tiwai@suse.de>
Wed, 2 Nov 2011 07:36:06 +0000 (08:36 +0100)
committerLeann Ogasawara <leann.ogasawara@canonical.com>
Mon, 2 Apr 2012 20:18:13 +0000 (13:18 -0700)
Now move the helper function for creating and reporting the jack-detection
to the common place.  The driver that needs this functionality should
select CONFIG_SND_KCTL_JACK kconfig.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

(cherry picked from commit 35be544af367170a9c6bf63adcf9d0cb2d569dbb)
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>

include/sound/control.h
sound/core/Kconfig
sound/core/Makefile
sound/core/ctljack.c [new file with mode: 0644]
sound/pci/hda/Kconfig
sound/pci/hda/hda_jack.c
sound/pci/hda/hda_jack.h

index 1a94a21..b2796e8 100644 (file)
@@ -227,4 +227,12 @@ snd_ctl_add_slave_uncached(struct snd_kcontrol *master,
        return _snd_ctl_add_slave(master, slave, SND_CTL_SLAVE_NEED_UPDATE);
 }
 
+/*
+ * Helper functions for jack-detection controls
+ */
+struct snd_kcontrol *
+snd_kctl_jack_new(const char *name, int idx, void *private_data);
+void snd_kctl_jack_report(struct snd_card *card,
+                         struct snd_kcontrol *kctl, bool status);
+
 #endif /* __SOUND_CONTROL_H */
index 475455c..66f287f 100644 (file)
@@ -207,6 +207,9 @@ config SND_PCM_XRUN_DEBUG
 config SND_VMASTER
        bool
 
+config SND_KCTL_JACK
+       bool
+
 config SND_DMA_SGBUF
        def_bool y
        depends on X86
index 350a08d..b4637c3 100644 (file)
@@ -7,6 +7,7 @@ snd-y     := sound.o init.o memory.o info.o control.o misc.o device.o
 snd-$(CONFIG_ISA_DMA_API) += isadma.o
 snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
 snd-$(CONFIG_SND_VMASTER) += vmaster.o
+snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o
 snd-$(CONFIG_SND_JACK)   += jack.o
 
 snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
diff --git a/sound/core/ctljack.c b/sound/core/ctljack.c
new file mode 100644 (file)
index 0000000..af0e78a
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Helper functions for jack-detection kcontrols
+ *
+ * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/kernel.h>
+#include <sound/core.h>
+#include <sound/control.h>
+
+#define jack_detect_kctl_info  snd_ctl_boolean_mono_info
+
+static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_value *ucontrol)
+{
+       ucontrol->value.integer.value[0] = kcontrol->private_value;
+       return 0;
+}
+
+static struct snd_kcontrol_new jack_detect_kctl = {
+       /* name is filled later */
+       .iface = SNDRV_CTL_ELEM_IFACE_CARD,
+       .access = SNDRV_CTL_ELEM_ACCESS_READ,
+       .info = jack_detect_kctl_info,
+       .get = jack_detect_kctl_get,
+};
+
+struct snd_kcontrol *
+snd_kctl_jack_new(const char *name, int idx, void *private_data)
+{
+       struct snd_kcontrol *kctl;
+       kctl = snd_ctl_new1(&jack_detect_kctl, private_data);
+       if (!kctl)
+               return NULL;
+       snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name);
+       kctl->id.index = idx;
+       kctl->private_value = 0;
+       return kctl;
+}
+EXPORT_SYMBOL_GPL(snd_kctl_jack_new);
+
+void snd_kctl_jack_report(struct snd_card *card,
+                         struct snd_kcontrol *kctl, bool status)
+{
+       if (kctl->private_value == status)
+               return;
+       kctl->private_value = status;
+       snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
+}
+EXPORT_SYMBOL_GPL(snd_kctl_jack_report);
index bb7e102..163b6b5 100644 (file)
@@ -2,6 +2,7 @@ menuconfig SND_HDA_INTEL
        tristate "Intel HD Audio"
        select SND_PCM
        select SND_VMASTER
+       select SND_KCTL_JACK
        help
          Say Y here to include support for Intel "High Definition
          Audio" (Azalia) and its compatible devices.
index 8829d5c..a2ab52b 100644 (file)
@@ -97,12 +97,8 @@ static void jack_detect_update(struct hda_codec *codec,
                               struct hda_jack_tbl *jack)
 {
        if (jack->jack_dirty || !jack->jack_detect) {
-               unsigned int val = read_pin_sense(codec, jack->nid);
+               jack->pin_sense = read_pin_sense(codec, jack->nid);
                jack->jack_dirty = 0;
-               if (val != jack->pin_sense) {
-                       jack->need_notify = 1;
-                       jack->pin_sense = val;
-               }
        }
 }
 
@@ -142,6 +138,8 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
 }
 EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
 
+#define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)
+
 /**
  * snd_hda_jack_detect - query pin Presence Detect status
  * @codec: the CODEC to sense
@@ -152,7 +150,7 @@ EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
 int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
 {
        u32 sense = snd_hda_pin_sense(codec, nid);
-       return !!(sense & AC_PINSENSE_PRESENCE);
+       return get_jack_plug_state(sense);
 }
 EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
 
@@ -176,58 +174,23 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
 }
 EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
 
-/* queue the notification when needed */
-static void jack_detect_report(struct hda_codec *codec,
-                              struct hda_jack_tbl *jack)
-{
-       jack_detect_update(codec, jack);
-       if (jack->need_notify) {
-               snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
-                              &jack->kctl->id);
-               jack->need_notify = 0;
-       }
-}
-
 /**
  * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
  */
 void snd_hda_jack_report_sync(struct hda_codec *codec)
 {
        struct hda_jack_tbl *jack = codec->jacktbl.list;
-       int i;
+       int i, state;
 
        for (i = 0; i < codec->jacktbl.used; i++, jack++)
                if (jack->nid) {
                        jack_detect_update(codec, jack);
-                       jack_detect_report(codec, jack);
+                       state = get_jack_plug_state(jack->pin_sense);
+                       snd_kctl_jack_notify(codec->bus->card, jack->kctl, state);
                }
 }
 EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync);
 
-/*
- * jack-detection kcontrols
- */
-
-#define jack_detect_kctl_info  snd_ctl_boolean_mono_info
-
-static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol,
-                               struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value;
-
-       ucontrol->value.integer.value[0] = snd_hda_jack_detect(codec, nid);
-       return 0;
-}
-
-static struct snd_kcontrol_new jack_detect_kctl = {
-       /* name is filled later */
-       .iface = SNDRV_CTL_ELEM_IFACE_CARD,
-       .access = SNDRV_CTL_ELEM_ACCESS_READ,
-       .info = jack_detect_kctl_info,
-       .get = jack_detect_kctl_get,
-};
-
 /**
  * snd_hda_jack_add_kctl - Add a kctl for the given pin
  *
@@ -245,12 +208,9 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
                return 0;
        if (jack->kctl)
                return 0; /* already created */
-       kctl = snd_ctl_new1(&jack_detect_kctl, codec);
+       kctl = snd_kctl_jack_new(name, idx, codec);
        if (!kctl)
                return -ENOMEM;
-       snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name);
-       kctl->id.index = idx;
-       kctl->private_value = nid;
        if (snd_hda_ctl_add(codec, nid, kctl) < 0)
                return -ENOMEM;
        jack->kctl = kctl;
index 69a67f8..4bb75ee 100644 (file)
@@ -21,7 +21,6 @@ struct hda_jack_tbl {
        unsigned int pin_sense;         /* cached pin-sense value */
        unsigned int jack_detect:1;     /* capable of jack-detection? */
        unsigned int jack_dirty:1;      /* needs to update? */
-       unsigned int need_notify:1;     /* to be notified? */
        struct snd_kcontrol *kctl;      /* assigned kctl for jack-detection */
 };