Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #ifndef __SOUND_CONTROL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #define __SOUND_CONTROL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Header file for control interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <sound/asound.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) struct snd_kcontrol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_info * uinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 				    int op_flag, /* SNDRV_CTL_TLV_OP_XXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 				    unsigned int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 				    unsigned int __user *tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /* internal flag for skipping validations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #ifdef CONFIG_SND_CTL_VALIDATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK	(1 << 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define snd_ctl_skip_validation(info) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	((info)->access & SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define snd_ctl_skip_validation(info)		true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	SNDRV_CTL_TLV_OP_READ = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	SNDRV_CTL_TLV_OP_WRITE = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	SNDRV_CTL_TLV_OP_CMD = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) struct snd_kcontrol_new {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	snd_ctl_elem_iface_t iface;	/* interface identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	unsigned int device;		/* device/client number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	unsigned int subdevice;		/* subdevice (substream) number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	const char *name;		/* ASCII name of item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	unsigned int index;		/* index of item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	unsigned int access;		/* access rights */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	unsigned int count;		/* count of same elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	snd_kcontrol_info_t *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	snd_kcontrol_get_t *get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	snd_kcontrol_put_t *put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		snd_kcontrol_tlv_rw_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		const unsigned int *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	} tlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	unsigned long private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) struct snd_kcontrol_volatile {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct snd_ctl_file *owner;	/* locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned int access;	/* access rights */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) struct snd_kcontrol {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct list_head list;		/* list of controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct snd_ctl_elem_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	unsigned int count;		/* count of same elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	snd_kcontrol_info_t *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	snd_kcontrol_get_t *get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	snd_kcontrol_put_t *put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		snd_kcontrol_tlv_rw_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		const unsigned int *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	} tlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	unsigned long private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	void *private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	void (*private_free)(struct snd_kcontrol *kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct snd_kcontrol_volatile vd[];	/* volatile data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define snd_kcontrol(n) list_entry(n, struct snd_kcontrol, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) struct snd_kctl_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct list_head list;	/* list of events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct snd_ctl_elem_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) struct pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	SND_CTL_SUBDEV_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	SND_CTL_SUBDEV_RAWMIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	SND_CTL_SUBDEV_ITEMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) struct snd_ctl_file {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct list_head list;		/* list of all control files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	struct pid *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	int preferred_subdevice[SND_CTL_SUBDEV_ITEMS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	wait_queue_head_t change_sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	spinlock_t read_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	struct fasync_struct *fasync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	int subscribed;			/* read interface is activated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	struct list_head events;	/* waiting events for read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define snd_ctl_file(n) list_entry(n, struct snd_ctl_file, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 				      struct snd_ctl_file * control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 				      unsigned int cmd, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			int active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int snd_ctl_create(struct snd_card *card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define snd_ctl_register_ioctl_compat(fcn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define snd_ctl_unregister_ioctl_compat(fcn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	unsigned int ioff = id->numid - kctl->id.numid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	return array_index_nospec(ioff, kctl->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	unsigned int ioff = id->index - kctl->id.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	return array_index_nospec(ioff, kctl->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (id->numid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		return snd_ctl_get_ioffnum(kctl, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		return snd_ctl_get_ioffidx(kctl, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline struct snd_ctl_elem_id *snd_ctl_build_ioff(struct snd_ctl_elem_id *dst_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 						    struct snd_kcontrol *src_kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 						    unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	*dst_id = src_kctl->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	dst_id->index += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	dst_id->numid += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	return dst_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * Frequently used control callbacks/helpers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			      struct snd_ctl_elem_info *uinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 				struct snd_ctl_elem_info *uinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		      unsigned int items, const char *const names[]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * virtual master control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 						 const unsigned int *tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int _snd_ctl_add_follower(struct snd_kcontrol *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			  struct snd_kcontrol *follower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			  unsigned int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* optional flags for follower */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define SND_CTL_FOLLOWER_NEED_UPDATE	(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * snd_ctl_add_follower - Add a virtual follower control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * @master: vmaster element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  * @follower: follower element to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  * Add a virtual follower control to the given master element created via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * snd_ctl_create_virtual_master() beforehand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * All followers must be the same type (returning the same information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  * via info callback).  The function doesn't check it, so it's your
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * responsibility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * Also, some additional limitations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * at most two channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * logarithmic volume control (dB level) thus no linear volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * master can only attenuate the volume without gain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * Return: Zero if successful or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) snd_ctl_add_follower(struct snd_kcontrol *master, struct snd_kcontrol *follower)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	return _snd_ctl_add_follower(master, follower, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * snd_ctl_add_follower_uncached - Add a virtual follower control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * @master: vmaster element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * @follower: follower element to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * Add a virtual follower control to the given master.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * Unlike snd_ctl_add_follower(), the element added via this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * is supposed to have volatile values, and get callback is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  * at each time queried from the master.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  * When the control peeks the hardware values directly and the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  * can be changed by other means than the put callback of the element,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  * this function should be used to keep the value always up-to-date.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  * Return: Zero if successful or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) snd_ctl_add_follower_uncached(struct snd_kcontrol *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			      struct snd_kcontrol *follower)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	return _snd_ctl_add_follower(master, follower, SND_CTL_FOLLOWER_NEED_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			     void (*hook)(void *private_data, int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			     void *private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define snd_ctl_sync_vmaster_hook(kctl)	snd_ctl_sync_vmaster(kctl, true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int snd_ctl_apply_vmaster_followers(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				    int (*func)(struct snd_kcontrol *vfollower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 						struct snd_kcontrol *follower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 						void *arg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 				    void *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  * Helper functions for jack-detection controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct snd_kcontrol *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) snd_kctl_jack_new(const char *name, struct snd_card *card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) void snd_kctl_jack_report(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			  struct snd_kcontrol *kctl, bool status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #endif	/* __SOUND_CONTROL_H */