vmaster.c 13 KB

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