1 /* 2 * Virtual master and slave controls 3 * 4 * Copyright (c) 2008 by Takashi Iwai <tiwai@suse.de> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation, version 2. 9 * 10 */ 11 12 #include <linux/slab.h> 13 #include <linux/export.h> 14 #include <sound/core.h> 15 #include <sound/control.h> 16 #include <sound/tlv.h> 17 18 /* 19 * a subset of information returned via ctl info callback 20 */ 21 struct link_ctl_info { 22 snd_ctl_elem_type_t type; /* value type */ 23 int count; /* item count */ 24 int min_val, max_val; /* min, max values */ 25 }; 26 27 /* 28 * link master - this contains a list of slave controls that are 29 * identical types, i.e. info returns the same value type and value 30 * ranges, but may have different number of counts. 31 * 32 * The master control is so far only mono volume/switch for simplicity. 33 * The same value will be applied to all slaves. 34 */ 35 struct link_master { 36 struct list_head slaves; 37 struct link_ctl_info info; 38 int val; /* the master value */ 39 unsigned int tlv[4]; 40 }; 41 42 /* 43 * link slave - this contains a slave control element 44 * 45 * It fakes the control callbacsk with additional attenuation by the 46 * master control. A slave may have either one or two channels. 47 */ 48 49 struct link_slave { 50 struct list_head list; 51 struct link_master *master; 52 struct link_ctl_info info; 53 int vals[2]; /* current values */ 54 unsigned int flags; 55 struct snd_kcontrol slave; /* the copy of original control entry */ 56 }; 57 58 static int slave_update(struct link_slave *slave) 59 { 60 struct snd_ctl_elem_value *uctl; 61 int err, ch; 62 63 uctl = kmalloc(sizeof(*uctl), GFP_KERNEL); 64 if (!uctl) 65 return -ENOMEM; 66 uctl->id = slave->slave.id; 67 err = slave->slave.get(&slave->slave, uctl); 68 for (ch = 0; ch < slave->info.count; ch++) 69 slave->vals[ch] = uctl->value.integer.value[ch]; 70 kfree(uctl); 71 return 0; 72 } 73 74 /* get the slave ctl info and save the initial values */ 75 static int slave_init(struct link_slave *slave) 76 { 77 struct snd_ctl_elem_info *uinfo; 78 int err; 79 80 if (slave->info.count) { 81 /* already initialized */ 82 if (slave->flags & SND_CTL_SLAVE_NEED_UPDATE) 83 return slave_update(slave); 84 return 0; 85 } 86 87 uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL); 88 if (!uinfo) 89 return -ENOMEM; 90 uinfo->id = slave->slave.id; 91 err = slave->slave.info(&slave->slave, uinfo); 92 if (err < 0) { 93 kfree(uinfo); 94 return err; 95 } 96 slave->info.type = uinfo->type; 97 slave->info.count = uinfo->count; 98 if (slave->info.count > 2 || 99 (slave->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER && 100 slave->info.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN)) { 101 snd_printk(KERN_ERR "invalid slave element\n"); 102 kfree(uinfo); 103 return -EINVAL; 104 } 105 slave->info.min_val = uinfo->value.integer.min; 106 slave->info.max_val = uinfo->value.integer.max; 107 kfree(uinfo); 108 109 return slave_update(slave); 110 } 111 112 /* initialize master volume */ 113 static int master_init(struct link_master *master) 114 { 115 struct link_slave *slave; 116 117 if (master->info.count) 118 return 0; /* already initialized */ 119 120 list_for_each_entry(slave, &master->slaves, list) { 121 int err = slave_init(slave); 122 if (err < 0) 123 return err; 124 master->info = slave->info; 125 master->info.count = 1; /* always mono */ 126 /* set full volume as default (= no attenuation) */ 127 master->val = master->info.max_val; 128 return 0; 129 } 130 return -ENOENT; 131 } 132 133 static int slave_get_val(struct link_slave *slave, 134 struct snd_ctl_elem_value *ucontrol) 135 { 136 int err, ch; 137 138 err = slave_init(slave); 139 if (err < 0) 140 return err; 141 for (ch = 0; ch < slave->info.count; ch++) 142 ucontrol->value.integer.value[ch] = slave->vals[ch]; 143 return 0; 144 } 145 146 static int slave_put_val(struct link_slave *slave, 147 struct snd_ctl_elem_value *ucontrol) 148 { 149 int err, ch, vol; 150 151 err = master_init(slave->master); 152 if (err < 0) 153 return err; 154 155 switch (slave->info.type) { 156 case SNDRV_CTL_ELEM_TYPE_BOOLEAN: 157 for (ch = 0; ch < slave->info.count; ch++) 158 ucontrol->value.integer.value[ch] &= 159 !!slave->master->val; 160 break; 161 case SNDRV_CTL_ELEM_TYPE_INTEGER: 162 for (ch = 0; ch < slave->info.count; ch++) { 163 /* max master volume is supposed to be 0 dB */ 164 vol = ucontrol->value.integer.value[ch]; 165 vol += slave->master->val - slave->master->info.max_val; 166 if (vol < slave->info.min_val) 167 vol = slave->info.min_val; 168 else if (vol > slave->info.max_val) 169 vol = slave->info.max_val; 170 ucontrol->value.integer.value[ch] = vol; 171 } 172 break; 173 } 174 return slave->slave.put(&slave->slave, ucontrol); 175 } 176 177 /* 178 * ctl callbacks for slaves 179 */ 180 static int slave_info(struct snd_kcontrol *kcontrol, 181 struct snd_ctl_elem_info *uinfo) 182 { 183 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 184 return slave->slave.info(&slave->slave, uinfo); 185 } 186 187 static int slave_get(struct snd_kcontrol *kcontrol, 188 struct snd_ctl_elem_value *ucontrol) 189 { 190 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 191 return slave_get_val(slave, ucontrol); 192 } 193 194 static int slave_put(struct snd_kcontrol *kcontrol, 195 struct snd_ctl_elem_value *ucontrol) 196 { 197 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 198 int err, ch, changed = 0; 199 200 err = slave_init(slave); 201 if (err < 0) 202 return err; 203 for (ch = 0; ch < slave->info.count; ch++) { 204 if (slave->vals[ch] != ucontrol->value.integer.value[ch]) { 205 changed = 1; 206 slave->vals[ch] = ucontrol->value.integer.value[ch]; 207 } 208 } 209 if (!changed) 210 return 0; 211 return slave_put_val(slave, ucontrol); 212 } 213 214 static int slave_tlv_cmd(struct snd_kcontrol *kcontrol, 215 int op_flag, unsigned int size, 216 unsigned int __user *tlv) 217 { 218 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 219 /* FIXME: this assumes that the max volume is 0 dB */ 220 return slave->slave.tlv.c(&slave->slave, op_flag, size, tlv); 221 } 222 223 static void slave_free(struct snd_kcontrol *kcontrol) 224 { 225 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 226 if (slave->slave.private_free) 227 slave->slave.private_free(&slave->slave); 228 if (slave->master) 229 list_del(&slave->list); 230 kfree(slave); 231 } 232 233 /* 234 * Add a slave control to the group with the given master control 235 * 236 * All slaves must be the same type (returning the same information 237 * via info callback). The function doesn't check it, so it's your 238 * responsibility. 239 * 240 * Also, some additional limitations: 241 * - at most two channels 242 * - logarithmic volume control (dB level), no linear volume 243 * - master can only attenuate the volume, no gain 244 */ 245 int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, 246 unsigned int flags) 247 { 248 struct link_master *master_link = snd_kcontrol_chip(master); 249 struct link_slave *srec; 250 251 srec = kzalloc(sizeof(*srec) + 252 slave->count * sizeof(*slave->vd), GFP_KERNEL); 253 if (!srec) 254 return -ENOMEM; 255 srec->slave = *slave; 256 memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); 257 srec->master = master_link; 258 srec->flags = flags; 259 260 /* override callbacks */ 261 slave->info = slave_info; 262 slave->get = slave_get; 263 slave->put = slave_put; 264 if (slave->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) 265 slave->tlv.c = slave_tlv_cmd; 266 slave->private_data = srec; 267 slave->private_free = slave_free; 268 269 list_add_tail(&srec->list, &master_link->slaves); 270 return 0; 271 } 272 EXPORT_SYMBOL(_snd_ctl_add_slave); 273 274 /* 275 * ctl callbacks for master controls 276 */ 277 static int master_info(struct snd_kcontrol *kcontrol, 278 struct snd_ctl_elem_info *uinfo) 279 { 280 struct link_master *master = snd_kcontrol_chip(kcontrol); 281 int ret; 282 283 ret = master_init(master); 284 if (ret < 0) 285 return ret; 286 uinfo->type = master->info.type; 287 uinfo->count = master->info.count; 288 uinfo->value.integer.min = master->info.min_val; 289 uinfo->value.integer.max = master->info.max_val; 290 return 0; 291 } 292 293 static int master_get(struct snd_kcontrol *kcontrol, 294 struct snd_ctl_elem_value *ucontrol) 295 { 296 struct link_master *master = snd_kcontrol_chip(kcontrol); 297 int err = master_init(master); 298 if (err < 0) 299 return err; 300 ucontrol->value.integer.value[0] = master->val; 301 return 0; 302 } 303 304 static int master_put(struct snd_kcontrol *kcontrol, 305 struct snd_ctl_elem_value *ucontrol) 306 { 307 struct link_master *master = snd_kcontrol_chip(kcontrol); 308 struct link_slave *slave; 309 struct snd_ctl_elem_value *uval; 310 int err, old_val; 311 312 err = master_init(master); 313 if (err < 0) 314 return err; 315 old_val = master->val; 316 if (ucontrol->value.integer.value[0] == old_val) 317 return 0; 318 319 uval = kmalloc(sizeof(*uval), GFP_KERNEL); 320 if (!uval) 321 return -ENOMEM; 322 list_for_each_entry(slave, &master->slaves, list) { 323 master->val = old_val; 324 uval->id = slave->slave.id; 325 slave_get_val(slave, uval); 326 master->val = ucontrol->value.integer.value[0]; 327 slave_put_val(slave, uval); 328 } 329 kfree(uval); 330 return 1; 331 } 332 333 static void master_free(struct snd_kcontrol *kcontrol) 334 { 335 struct link_master *master = snd_kcontrol_chip(kcontrol); 336 struct link_slave *slave; 337 338 list_for_each_entry(slave, &master->slaves, list) 339 slave->master = NULL; 340 kfree(master); 341 } 342 343 344 /** 345 * snd_ctl_make_virtual_master - Create a virtual master control 346 * @name: name string of the control element to create 347 * @tlv: optional TLV int array for dB information 348 * 349 * Creates a virtual matster control with the given name string. 350 * Returns the created control element, or NULL for errors (ENOMEM). 351 * 352 * After creating a vmaster element, you can add the slave controls 353 * via snd_ctl_add_slave() or snd_ctl_add_slave_uncached(). 354 * 355 * The optional argument @tlv can be used to specify the TLV information 356 * for dB scale of the master control. It should be a single element 357 * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or 358 * #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB. 359 */ 360 struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, 361 const unsigned int *tlv) 362 { 363 struct link_master *master; 364 struct snd_kcontrol *kctl; 365 struct snd_kcontrol_new knew; 366 367 memset(&knew, 0, sizeof(knew)); 368 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 369 knew.name = name; 370 knew.info = master_info; 371 372 master = kzalloc(sizeof(*master), GFP_KERNEL); 373 if (!master) 374 return NULL; 375 INIT_LIST_HEAD(&master->slaves); 376 377 kctl = snd_ctl_new1(&knew, master); 378 if (!kctl) { 379 kfree(master); 380 return NULL; 381 } 382 /* override some callbacks */ 383 kctl->info = master_info; 384 kctl->get = master_get; 385 kctl->put = master_put; 386 kctl->private_free = master_free; 387 388 /* additional (constant) TLV read */ 389 if (tlv && 390 (tlv[0] == SNDRV_CTL_TLVT_DB_SCALE || 391 tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX || 392 tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) { 393 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 394 memcpy(master->tlv, tlv, sizeof(master->tlv)); 395 kctl->tlv.p = master->tlv; 396 } 397 398 return kctl; 399 } 400 EXPORT_SYMBOL(snd_ctl_make_virtual_master); 401