vmaster.c 13 KB

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