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 (at) 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 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 pid_t owner_pid; 60 unsigned int access; /* access rights */ 61 }; 62 63 struct snd_kcontrol { 64 struct list_head list; /* list of controls */ 65 struct snd_ctl_elem_id id; 66 unsigned int count; /* count of same elements */ 67 snd_kcontrol_info_t *info; 68 snd_kcontrol_get_t *get; 69 snd_kcontrol_put_t *put; 70 union { 71 snd_kcontrol_tlv_rw_t *c; 72 const unsigned int *p; 73 } tlv; 74 unsigned long private_value; 75 void *private_data; 76 void (*private_free)(struct snd_kcontrol *kcontrol); 77 struct snd_kcontrol_volatile vd[0]; /* volatile data */ 78 }; 79 80 #define snd_kcontrol(n) list_entry(n, struct snd_kcontrol, list) 81 82 struct snd_kctl_event { 83 struct list_head list; /* list of events */ 84 struct snd_ctl_elem_id id; 85 unsigned int mask; 86 }; 87 88 #define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list) 89 90 struct snd_ctl_file { 91 struct list_head list; /* list of all control files */ 92 struct snd_card *card; 93 pid_t pid; 94 int prefer_pcm_subdevice; 95 int prefer_rawmidi_subdevice; 96 wait_queue_head_t change_sleep; 97 spinlock_t read_lock; 98 struct fasync_struct *fasync; 99 int subscribed; /* read interface is activated */ 100 struct list_head events; /* waiting events for read */ 101 }; 102 103 #define snd_ctl_file(n) list_entry(n, struct snd_ctl_file, list) 104 105 typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card, 106 struct snd_ctl_file * control, 107 unsigned int cmd, unsigned long arg); 108 109 void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id); 110 111 struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data); 112 void snd_ctl_free_one(struct snd_kcontrol * kcontrol); 113 int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol); 114 int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol); 115 int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id); 116 int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id); 117 struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid); 118 struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id); 119 120 int snd_ctl_create(struct snd_card *card); 121 122 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn); 123 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn); 124 #ifdef CONFIG_COMPAT 125 int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn); 126 int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn); 127 #else 128 #define snd_ctl_register_ioctl_compat(fcn) 129 #define snd_ctl_unregister_ioctl_compat(fcn) 130 #endif 131 132 int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control); 133 int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, struct snd_ctl_elem_value *control); 134 135 static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) 136 { 137 return id->numid - kctl->id.numid; 138 } 139 140 static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) 141 { 142 return id->index - kctl->id.index; 143 } 144 145 static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) 146 { 147 if (id->numid) { 148 return snd_ctl_get_ioffnum(kctl, id); 149 } else { 150 return snd_ctl_get_ioffidx(kctl, id); 151 } 152 } 153 154 static inline struct snd_ctl_elem_id *snd_ctl_build_ioff(struct snd_ctl_elem_id *dst_id, 155 struct snd_kcontrol *src_kctl, 156 unsigned int offset) 157 { 158 *dst_id = src_kctl->id; 159 dst_id->index += offset; 160 dst_id->numid += offset; 161 return dst_id; 162 } 163 164 /* 165 * Frequently used control callbacks 166 */ 167 int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, 168 struct snd_ctl_elem_info *uinfo); 169 int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, 170 struct snd_ctl_elem_info *uinfo); 171 172 #endif /* __SOUND_CONTROL_H */ 173