2d670ea2bd
This change adds audio jack injection feature through debugfs, with this feature, we could validate alsa userspace changes by injecting plugin or plugout events to the non-phantom audio jacks. With this change, the sound core will build the folders $debugfs_mount_dir/sound/cardN if SND_DEBUG and DEBUG_FS are enabled. And if users also enable the SND_JACK_INJECTION_DEBUG, the jack injection nodes will be built in the folder cardN like below: $tree $debugfs_mount_dir/sound $debugfs_mount_dir/sound ├── card0 │ ├── HDMI_DP_pcm_10_Jack │ │ ├── jackin_inject │ │ ├── kctl_id │ │ ├── mask_bits │ │ ├── status │ │ ├── sw_inject_enable │ │ └── type ... │ └── HDMI_DP_pcm_9_Jack │ ├── jackin_inject │ ├── kctl_id │ ├── mask_bits │ ├── status │ ├── sw_inject_enable │ └── type └── card1 ├── HDMI_DP_pcm_5_Jack │ ├── jackin_inject │ ├── kctl_id │ ├── mask_bits │ ├── status │ ├── sw_inject_enable │ └── type ... ├── Headphone_Jack │ ├── jackin_inject │ ├── kctl_id │ ├── mask_bits │ ├── status │ ├── sw_inject_enable │ └── type └── Headset_Mic_Jack ├── jackin_inject ├── kctl_id ├── mask_bits ├── status ├── sw_inject_enable └── type The nodes kctl_id, mask_bits, status and type are read-only, users could check jack or jack_kctl's information through them. The nodes sw_inject_enable and jackin_inject are directly used for injection. The sw_inject_enable is read-write, users could check if software injection is enabled or not on this jack, and users could echo 1 or 0 to enable or disable software injection on this jack. Once the injection is enabled, the jack will not change by hardware events anymore, once the injection is disabled, the jack will restore the last reported hardware events to the jack. The jackin_inject is write-only, if the injection is enabled, users could echo 1 or 0 to this node to inject plugin or plugout events to this jack. For the detailed usage information on these nodes, please refer to Documentation/sound/designs/jack-injection.rst. Reviewed-by: Takashi Iwai <tiwai@suse.de> Reviewed-by: Jaroslav Kysela <perex@perex.cz> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Hui Wang <hui.wang@canonical.com> Link: https://lore.kernel.org/r/20210127085639.74954-2-hui.wang@canonical.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
120 lines
3.1 KiB
C
120 lines
3.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
#ifndef __SOUND_JACK_H
|
|
#define __SOUND_JACK_H
|
|
|
|
/*
|
|
* Jack abstraction layer
|
|
*
|
|
* Copyright 2008 Wolfson Microelectronics plc
|
|
*/
|
|
|
|
#include <sound/core.h>
|
|
|
|
struct input_dev;
|
|
|
|
/**
|
|
* enum snd_jack_types - Jack types which can be reported
|
|
* @SND_JACK_HEADPHONE: Headphone
|
|
* @SND_JACK_MICROPHONE: Microphone
|
|
* @SND_JACK_HEADSET: Headset
|
|
* @SND_JACK_LINEOUT: Line out
|
|
* @SND_JACK_MECHANICAL: Mechanical switch
|
|
* @SND_JACK_VIDEOOUT: Video out
|
|
* @SND_JACK_AVOUT: AV (Audio Video) out
|
|
* @SND_JACK_LINEIN: Line in
|
|
* @SND_JACK_BTN_0: Button 0
|
|
* @SND_JACK_BTN_1: Button 1
|
|
* @SND_JACK_BTN_2: Button 2
|
|
* @SND_JACK_BTN_3: Button 3
|
|
* @SND_JACK_BTN_4: Button 4
|
|
* @SND_JACK_BTN_5: Button 5
|
|
*
|
|
* These values are used as a bitmask.
|
|
*
|
|
* Note that this must be kept in sync with the lookup table in
|
|
* sound/core/jack.c.
|
|
*/
|
|
enum snd_jack_types {
|
|
SND_JACK_HEADPHONE = 0x0001,
|
|
SND_JACK_MICROPHONE = 0x0002,
|
|
SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
|
|
SND_JACK_LINEOUT = 0x0004,
|
|
SND_JACK_MECHANICAL = 0x0008, /* If detected separately */
|
|
SND_JACK_VIDEOOUT = 0x0010,
|
|
SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
|
|
SND_JACK_LINEIN = 0x0020,
|
|
|
|
/* Kept separate from switches to facilitate implementation */
|
|
SND_JACK_BTN_0 = 0x4000,
|
|
SND_JACK_BTN_1 = 0x2000,
|
|
SND_JACK_BTN_2 = 0x1000,
|
|
SND_JACK_BTN_3 = 0x0800,
|
|
SND_JACK_BTN_4 = 0x0400,
|
|
SND_JACK_BTN_5 = 0x0200,
|
|
};
|
|
|
|
/* Keep in sync with definitions above */
|
|
#define SND_JACK_SWITCH_TYPES 6
|
|
|
|
struct snd_jack {
|
|
struct list_head kctl_list;
|
|
struct snd_card *card;
|
|
const char *id;
|
|
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
|
struct input_dev *input_dev;
|
|
int registered;
|
|
int type;
|
|
char name[100];
|
|
unsigned int key[6]; /* Keep in sync with definitions above */
|
|
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
|
int hw_status_cache;
|
|
void *private_data;
|
|
void (*private_free)(struct snd_jack *);
|
|
};
|
|
|
|
#ifdef CONFIG_SND_JACK
|
|
|
|
int snd_jack_new(struct snd_card *card, const char *id, int type,
|
|
struct snd_jack **jack, bool initial_kctl, bool phantom_jack);
|
|
int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask);
|
|
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
|
void snd_jack_set_parent(struct snd_jack *jack, struct device *parent);
|
|
int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
|
|
int keytype);
|
|
#endif
|
|
void snd_jack_report(struct snd_jack *jack, int status);
|
|
|
|
#else
|
|
static inline int snd_jack_new(struct snd_card *card, const char *id, int type,
|
|
struct snd_jack **jack, bool initial_kctl, bool phantom_jack)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void snd_jack_report(struct snd_jack *jack, int status)
|
|
{
|
|
}
|
|
|
|
#endif
|
|
|
|
#if !defined(CONFIG_SND_JACK) || !defined(CONFIG_SND_JACK_INPUT_DEV)
|
|
static inline void snd_jack_set_parent(struct snd_jack *jack,
|
|
struct device *parent)
|
|
{
|
|
}
|
|
|
|
static inline int snd_jack_set_key(struct snd_jack *jack,
|
|
enum snd_jack_types type,
|
|
int keytype)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif /* !CONFIG_SND_JACK || !CONFIG_SND_JACK_INPUT_DEV */
|
|
|
|
#endif
|