Branch data Line data Source code
1 : : #ifndef __SOUND_CONTROL_H
2 : : #define __SOUND_CONTROL_H
3 : :
4 : : /*
5 : : * Header file for control interface
6 : : * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
7 : : *
8 : : *
9 : : * This program is free software; you can redistribute it and/or modify
10 : : * it under the terms of the GNU General Public License as published by
11 : : * the Free Software Foundation; either version 2 of the License, or
12 : : * (at your option) any later version.
13 : : *
14 : : * This program is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : : * GNU General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU General Public License
20 : : * along with this program; if not, write to the Free Software
21 : : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : : *
23 : : */
24 : :
25 : : #include <sound/asound.h>
26 : :
27 : : #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
28 : :
29 : : struct snd_kcontrol;
30 : : typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_info * uinfo);
31 : : typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
32 : : typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
33 : : typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
34 : : int op_flag, /* 0=read,1=write,-1=command */
35 : : unsigned int size,
36 : : unsigned int __user *tlv);
37 : :
38 : :
39 : : struct snd_kcontrol_new {
40 : : snd_ctl_elem_iface_t iface; /* interface identifier */
41 : : unsigned int device; /* device/client number */
42 : : unsigned int subdevice; /* subdevice (substream) number */
43 : : const unsigned char *name; /* ASCII name of item */
44 : : unsigned int index; /* index of item */
45 : : unsigned int access; /* access rights */
46 : : unsigned int count; /* count of same elements */
47 : : snd_kcontrol_info_t *info;
48 : : snd_kcontrol_get_t *get;
49 : : snd_kcontrol_put_t *put;
50 : : union {
51 : : snd_kcontrol_tlv_rw_t *c;
52 : : const unsigned int *p;
53 : : } tlv;
54 : : unsigned long private_value;
55 : : };
56 : :
57 : : struct snd_kcontrol_volatile {
58 : : struct snd_ctl_file *owner; /* locked */
59 : : unsigned int access; /* access rights */
60 : : };
61 : :
62 : : struct snd_kcontrol {
63 : : struct list_head list; /* list of controls */
64 : : struct snd_ctl_elem_id id;
65 : : unsigned int count; /* count of same elements */
66 : : snd_kcontrol_info_t *info;
67 : : snd_kcontrol_get_t *get;
68 : : snd_kcontrol_put_t *put;
69 : : union {
70 : : snd_kcontrol_tlv_rw_t *c;
71 : : const unsigned int *p;
72 : : } tlv;
73 : : unsigned long private_value;
74 : : void *private_data;
75 : : void (*private_free)(struct snd_kcontrol *kcontrol);
76 : : struct snd_kcontrol_volatile vd[0]; /* volatile data */
77 : : };
78 : :
79 : : #define snd_kcontrol(n) list_entry(n, struct snd_kcontrol, list)
80 : :
81 : : struct snd_kctl_event {
82 : : struct list_head list; /* list of events */
83 : : struct snd_ctl_elem_id id;
84 : : unsigned int mask;
85 : : };
86 : :
87 : : #define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list)
88 : :
89 : : struct pid;
90 : :
91 : : struct snd_ctl_file {
92 : : struct list_head list; /* list of all control files */
93 : : struct snd_card *card;
94 : : struct pid *pid;
95 : : int prefer_pcm_subdevice;
96 : : int prefer_rawmidi_subdevice;
97 : : wait_queue_head_t change_sleep;
98 : : spinlock_t read_lock;
99 : : struct fasync_struct *fasync;
100 : : int subscribed; /* read interface is activated */
101 : : struct list_head events; /* waiting events for read */
102 : : };
103 : :
104 : : #define snd_ctl_file(n) list_entry(n, struct snd_ctl_file, list)
105 : :
106 : : typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card,
107 : : struct snd_ctl_file * control,
108 : : unsigned int cmd, unsigned long arg);
109 : :
110 : : void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id);
111 : :
112 : : struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data);
113 : : void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
114 : : int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
115 : : int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
116 : : int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
117 : : int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
118 : : int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
119 : : int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
120 : : int active);
121 : : struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
122 : : struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
123 : :
124 : : int snd_ctl_create(struct snd_card *card);
125 : :
126 : : int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
127 : : int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
128 : : #ifdef CONFIG_COMPAT
129 : : int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn);
130 : : int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn);
131 : : #else
132 : : #define snd_ctl_register_ioctl_compat(fcn)
133 : : #define snd_ctl_unregister_ioctl_compat(fcn)
134 : : #endif
135 : :
136 : : static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
137 : : {
138 : 0 : return id->numid - kctl->id.numid;
139 : : }
140 : :
141 : : static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
142 : : {
143 : 0 : return id->index - kctl->id.index;
144 : : }
145 : :
146 : 0 : static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
147 : : {
148 [ # # ][ # # ]: 0 : if (id->numid) {
[ # # ][ # # ]
[ # # ]
149 : : return snd_ctl_get_ioffnum(kctl, id);
150 : : } else {
151 : : return snd_ctl_get_ioffidx(kctl, id);
152 : : }
153 : : }
154 : :
155 : : static inline struct snd_ctl_elem_id *snd_ctl_build_ioff(struct snd_ctl_elem_id *dst_id,
156 : : struct snd_kcontrol *src_kctl,
157 : : unsigned int offset)
158 : : {
159 : 0 : *dst_id = src_kctl->id;
160 : 0 : dst_id->index += offset;
161 : 0 : dst_id->numid += offset;
162 : : return dst_id;
163 : : }
164 : :
165 : : /*
166 : : * Frequently used control callbacks/helpers
167 : : */
168 : : int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
169 : : struct snd_ctl_elem_info *uinfo);
170 : : int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
171 : : struct snd_ctl_elem_info *uinfo);
172 : : int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
173 : : unsigned int items, const char *const names[]);
174 : :
175 : : /*
176 : : * virtual master control
177 : : */
178 : : struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
179 : : const unsigned int *tlv);
180 : : int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave,
181 : : unsigned int flags);
182 : : /* optional flags for slave */
183 : : #define SND_CTL_SLAVE_NEED_UPDATE (1 << 0)
184 : :
185 : : /**
186 : : * snd_ctl_add_slave - Add a virtual slave control
187 : : * @master: vmaster element
188 : : * @slave: slave element to add
189 : : *
190 : : * Add a virtual slave control to the given master element created via
191 : : * snd_ctl_create_virtual_master() beforehand.
192 : : *
193 : : * All slaves must be the same type (returning the same information
194 : : * via info callback). The function doesn't check it, so it's your
195 : : * responsibility.
196 : : *
197 : : * Also, some additional limitations:
198 : : * at most two channels,
199 : : * logarithmic volume control (dB level) thus no linear volume,
200 : : * master can only attenuate the volume without gain
201 : : *
202 : : * Return: Zero if successful or a negative error code.
203 : : */
204 : : static inline int
205 : : snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave)
206 : : {
207 : 0 : return _snd_ctl_add_slave(master, slave, 0);
208 : : }
209 : :
210 : : /**
211 : : * snd_ctl_add_slave_uncached - Add a virtual slave control
212 : : * @master: vmaster element
213 : : * @slave: slave element to add
214 : : *
215 : : * Add a virtual slave control to the given master.
216 : : * Unlike snd_ctl_add_slave(), the element added via this function
217 : : * is supposed to have volatile values, and get callback is called
218 : : * at each time quried from the master.
219 : : *
220 : : * When the control peeks the hardware values directly and the value
221 : : * can be changed by other means than the put callback of the element,
222 : : * this function should be used to keep the value always up-to-date.
223 : : *
224 : : * Return: Zero if successful or a negative error code.
225 : : */
226 : : static inline int
227 : : snd_ctl_add_slave_uncached(struct snd_kcontrol *master,
228 : : struct snd_kcontrol *slave)
229 : : {
230 : : return _snd_ctl_add_slave(master, slave, SND_CTL_SLAVE_NEED_UPDATE);
231 : : }
232 : :
233 : : int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
234 : : void (*hook)(void *private_data, int),
235 : : void *private_data);
236 : : void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
237 : : #define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true)
238 : :
239 : : /*
240 : : * Helper functions for jack-detection controls
241 : : */
242 : : struct snd_kcontrol *
243 : : snd_kctl_jack_new(const char *name, int idx, void *private_data);
244 : : void snd_kctl_jack_report(struct snd_card *card,
245 : : struct snd_kcontrol *kctl, bool status);
246 : :
247 : : #endif /* __SOUND_CONTROL_H */
|