ALSA: Introduce common helper functions for jack-detection control
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>
This commit is contained in:
parent
3a93897ea3
commit
35be544af3
|
@ -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);
|
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 */
|
#endif /* __SOUND_CONTROL_H */
|
||||||
|
|
|
@ -207,6 +207,9 @@ config SND_PCM_XRUN_DEBUG
|
||||||
config SND_VMASTER
|
config SND_VMASTER
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config SND_KCTL_JACK
|
||||||
|
bool
|
||||||
|
|
||||||
config SND_DMA_SGBUF
|
config SND_DMA_SGBUF
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on X86
|
depends on X86
|
||||||
|
|
|
@ -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_ISA_DMA_API) += isadma.o
|
||||||
snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
|
snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
|
||||||
snd-$(CONFIG_SND_VMASTER) += vmaster.o
|
snd-$(CONFIG_SND_VMASTER) += vmaster.o
|
||||||
|
snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o
|
||||||
snd-$(CONFIG_SND_JACK) += jack.o
|
snd-$(CONFIG_SND_JACK) += jack.o
|
||||||
|
|
||||||
snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
|
snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
|
||||||
|
|
55
sound/core/ctljack.c
Normal file
55
sound/core/ctljack.c
Normal file
|
@ -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);
|
|
@ -2,6 +2,7 @@ menuconfig SND_HDA_INTEL
|
||||||
tristate "Intel HD Audio"
|
tristate "Intel HD Audio"
|
||||||
select SND_PCM
|
select SND_PCM
|
||||||
select SND_VMASTER
|
select SND_VMASTER
|
||||||
|
select SND_KCTL_JACK
|
||||||
help
|
help
|
||||||
Say Y here to include support for Intel "High Definition
|
Say Y here to include support for Intel "High Definition
|
||||||
Audio" (Azalia) and its compatible devices.
|
Audio" (Azalia) and its compatible devices.
|
||||||
|
|
|
@ -97,12 +97,8 @@ static void jack_detect_update(struct hda_codec *codec,
|
||||||
struct hda_jack_tbl *jack)
|
struct hda_jack_tbl *jack)
|
||||||
{
|
{
|
||||||
if (jack->jack_dirty || !jack->jack_detect) {
|
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;
|
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);
|
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
|
* snd_hda_jack_detect - query pin Presence Detect status
|
||||||
* @codec: the CODEC to sense
|
* @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)
|
int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
|
||||||
{
|
{
|
||||||
u32 sense = snd_hda_pin_sense(codec, 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);
|
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);
|
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
|
* 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)
|
void snd_hda_jack_report_sync(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct hda_jack_tbl *jack = codec->jacktbl.list;
|
struct hda_jack_tbl *jack = codec->jacktbl.list;
|
||||||
int i;
|
int i, state;
|
||||||
|
|
||||||
for (i = 0; i < codec->jacktbl.used; i++, jack++)
|
for (i = 0; i < codec->jacktbl.used; i++, jack++)
|
||||||
if (jack->nid) {
|
if (jack->nid) {
|
||||||
jack_detect_update(codec, jack);
|
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);
|
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
|
* 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;
|
return 0;
|
||||||
if (jack->kctl)
|
if (jack->kctl)
|
||||||
return 0; /* already created */
|
return 0; /* already created */
|
||||||
kctl = snd_ctl_new1(&jack_detect_kctl, codec);
|
kctl = snd_kctl_jack_new(name, idx, codec);
|
||||||
if (!kctl)
|
if (!kctl)
|
||||||
return -ENOMEM;
|
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)
|
if (snd_hda_ctl_add(codec, nid, kctl) < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
jack->kctl = kctl;
|
jack->kctl = kctl;
|
||||||
|
|
|
@ -21,7 +21,6 @@ struct hda_jack_tbl {
|
||||||
unsigned int pin_sense; /* cached pin-sense value */
|
unsigned int pin_sense; /* cached pin-sense value */
|
||||||
unsigned int jack_detect:1; /* capable of jack-detection? */
|
unsigned int jack_detect:1; /* capable of jack-detection? */
|
||||||
unsigned int jack_dirty:1; /* needs to update? */
|
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 */
|
struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue