0001
0002 #ifndef __SOUND_CONTROL_H
0003 #define __SOUND_CONTROL_H
0004
0005
0006
0007
0008
0009
0010 #include <linux/wait.h>
0011 #include <linux/nospec.h>
0012 #include <sound/asound.h>
0013
0014 #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
0015
0016 struct snd_kcontrol;
0017 typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_info * uinfo);
0018 typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
0019 typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
0020 typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
0021 int op_flag,
0022 unsigned int size,
0023 unsigned int __user *tlv);
0024
0025
0026 #ifdef CONFIG_SND_CTL_DEBUG
0027 #define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK (1 << 24)
0028 #define snd_ctl_skip_validation(info) \
0029 ((info)->access & SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK)
0030 #else
0031 #define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK 0
0032 #define snd_ctl_skip_validation(info) true
0033 #endif
0034
0035
0036 #define SNDRV_CTL_ELEM_ACCESS_LED_SHIFT 25
0037 #define SNDRV_CTL_ELEM_ACCESS_LED_MASK (7<<25)
0038 #define SNDRV_CTL_ELEM_ACCESS_SPK_LED (1<<25)
0039 #define SNDRV_CTL_ELEM_ACCESS_MIC_LED (2<<25)
0040
0041 enum {
0042 SNDRV_CTL_TLV_OP_READ = 0,
0043 SNDRV_CTL_TLV_OP_WRITE = 1,
0044 SNDRV_CTL_TLV_OP_CMD = -1,
0045 };
0046
0047 struct snd_kcontrol_new {
0048 snd_ctl_elem_iface_t iface;
0049 unsigned int device;
0050 unsigned int subdevice;
0051 const char *name;
0052 unsigned int index;
0053 unsigned int access;
0054 unsigned int count;
0055 snd_kcontrol_info_t *info;
0056 snd_kcontrol_get_t *get;
0057 snd_kcontrol_put_t *put;
0058 union {
0059 snd_kcontrol_tlv_rw_t *c;
0060 const unsigned int *p;
0061 } tlv;
0062 unsigned long private_value;
0063 };
0064
0065 struct snd_kcontrol_volatile {
0066 struct snd_ctl_file *owner;
0067 unsigned int access;
0068 };
0069
0070 struct snd_kcontrol {
0071 struct list_head list;
0072 struct snd_ctl_elem_id id;
0073 unsigned int count;
0074 snd_kcontrol_info_t *info;
0075 snd_kcontrol_get_t *get;
0076 snd_kcontrol_put_t *put;
0077 union {
0078 snd_kcontrol_tlv_rw_t *c;
0079 const unsigned int *p;
0080 } tlv;
0081 unsigned long private_value;
0082 void *private_data;
0083 void (*private_free)(struct snd_kcontrol *kcontrol);
0084 struct snd_kcontrol_volatile vd[];
0085 };
0086
0087 #define snd_kcontrol(n) list_entry(n, struct snd_kcontrol, list)
0088
0089 struct snd_kctl_event {
0090 struct list_head list;
0091 struct snd_ctl_elem_id id;
0092 unsigned int mask;
0093 };
0094
0095 #define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list)
0096
0097 struct pid;
0098
0099 enum {
0100 SND_CTL_SUBDEV_PCM,
0101 SND_CTL_SUBDEV_RAWMIDI,
0102 SND_CTL_SUBDEV_ITEMS,
0103 };
0104
0105 struct snd_ctl_file {
0106 struct list_head list;
0107 struct snd_card *card;
0108 struct pid *pid;
0109 int preferred_subdevice[SND_CTL_SUBDEV_ITEMS];
0110 wait_queue_head_t change_sleep;
0111 spinlock_t read_lock;
0112 struct snd_fasync *fasync;
0113 int subscribed;
0114 struct list_head events;
0115 };
0116
0117 struct snd_ctl_layer_ops {
0118 struct snd_ctl_layer_ops *next;
0119 const char *module_name;
0120 void (*lregister)(struct snd_card *card);
0121 void (*ldisconnect)(struct snd_card *card);
0122 void (*lnotify)(struct snd_card *card, unsigned int mask, struct snd_kcontrol *kctl, unsigned int ioff);
0123 };
0124
0125 #define snd_ctl_file(n) list_entry(n, struct snd_ctl_file, list)
0126
0127 typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card,
0128 struct snd_ctl_file * control,
0129 unsigned int cmd, unsigned long arg);
0130
0131 void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id);
0132 void snd_ctl_notify_one(struct snd_card * card, unsigned int mask, struct snd_kcontrol * kctl, unsigned int ioff);
0133
0134 struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data);
0135 void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
0136 int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
0137 int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
0138 int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
0139 int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
0140 int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
0141 int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);
0142 struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
0143 struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
0144
0145 int snd_ctl_create(struct snd_card *card);
0146
0147 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
0148 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
0149 #ifdef CONFIG_COMPAT
0150 int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn);
0151 int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn);
0152 #else
0153 #define snd_ctl_register_ioctl_compat(fcn)
0154 #define snd_ctl_unregister_ioctl_compat(fcn)
0155 #endif
0156
0157 int snd_ctl_request_layer(const char *module_name);
0158 void snd_ctl_register_layer(struct snd_ctl_layer_ops *lops);
0159 void snd_ctl_disconnect_layer(struct snd_ctl_layer_ops *lops);
0160
0161 int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
0162
0163 static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
0164 {
0165 unsigned int ioff = id->numid - kctl->id.numid;
0166 return array_index_nospec(ioff, kctl->count);
0167 }
0168
0169 static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
0170 {
0171 unsigned int ioff = id->index - kctl->id.index;
0172 return array_index_nospec(ioff, kctl->count);
0173 }
0174
0175 static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
0176 {
0177 if (id->numid) {
0178 return snd_ctl_get_ioffnum(kctl, id);
0179 } else {
0180 return snd_ctl_get_ioffidx(kctl, id);
0181 }
0182 }
0183
0184 static inline struct snd_ctl_elem_id *snd_ctl_build_ioff(struct snd_ctl_elem_id *dst_id,
0185 struct snd_kcontrol *src_kctl,
0186 unsigned int offset)
0187 {
0188 *dst_id = src_kctl->id;
0189 dst_id->index += offset;
0190 dst_id->numid += offset;
0191 return dst_id;
0192 }
0193
0194
0195
0196
0197 int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
0198 struct snd_ctl_elem_info *uinfo);
0199 int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
0200 struct snd_ctl_elem_info *uinfo);
0201 int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
0202 unsigned int items, const char *const names[]);
0203
0204
0205
0206
0207 struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
0208 const unsigned int *tlv);
0209 int _snd_ctl_add_follower(struct snd_kcontrol *master,
0210 struct snd_kcontrol *follower,
0211 unsigned int flags);
0212
0213 #define SND_CTL_FOLLOWER_NEED_UPDATE (1 << 0)
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 static inline int
0235 snd_ctl_add_follower(struct snd_kcontrol *master, struct snd_kcontrol *follower)
0236 {
0237 return _snd_ctl_add_follower(master, follower, 0);
0238 }
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 static inline int
0257 snd_ctl_add_follower_uncached(struct snd_kcontrol *master,
0258 struct snd_kcontrol *follower)
0259 {
0260 return _snd_ctl_add_follower(master, follower, SND_CTL_FOLLOWER_NEED_UPDATE);
0261 }
0262
0263 int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
0264 void (*hook)(void *private_data, int),
0265 void *private_data);
0266 void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
0267 #define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true)
0268 int snd_ctl_apply_vmaster_followers(struct snd_kcontrol *kctl,
0269 int (*func)(struct snd_kcontrol *vfollower,
0270 struct snd_kcontrol *follower,
0271 void *arg),
0272 void *arg);
0273
0274
0275
0276
0277 #define SND_CTL_LAYER_MODULE_LED "snd-ctl-led"
0278
0279 #if IS_MODULE(CONFIG_SND_CTL_LED)
0280 static inline int snd_ctl_led_request(void) { return snd_ctl_request_layer(SND_CTL_LAYER_MODULE_LED); }
0281 #else
0282 static inline int snd_ctl_led_request(void) { return 0; }
0283 #endif
0284
0285
0286
0287
0288 struct snd_kcontrol *
0289 snd_kctl_jack_new(const char *name, struct snd_card *card);
0290 void snd_kctl_jack_report(struct snd_card *card,
0291 struct snd_kcontrol *kctl, bool status);
0292
0293 #endif