aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/vmaster.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 130cfe677d60..14a286a7bf2b 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -37,6 +37,8 @@ struct link_master {
37 struct link_ctl_info info; 37 struct link_ctl_info info;
38 int val; /* the master value */ 38 int val; /* the master value */
39 unsigned int tlv[4]; 39 unsigned int tlv[4];
40 void (*hook)(void *private_data, int);
41 void *hook_private_data;
40}; 42};
41 43
42/* 44/*
@@ -126,7 +128,9 @@ static int master_init(struct link_master *master)
126 master->info.count = 1; /* always mono */ 128 master->info.count = 1; /* always mono */
127 /* set full volume as default (= no attenuation) */ 129 /* set full volume as default (= no attenuation) */
128 master->val = master->info.max_val; 130 master->val = master->info.max_val;
129 return 0; 131 if (master->hook)
132 master->hook(master->hook_private_data, master->val);
133 return 1;
130 } 134 }
131 return -ENOENT; 135 return -ENOENT;
132} 136}
@@ -329,6 +333,8 @@ static int master_put(struct snd_kcontrol *kcontrol,
329 slave_put_val(slave, uval); 333 slave_put_val(slave, uval);
330 } 334 }
331 kfree(uval); 335 kfree(uval);
336 if (master->hook && !err)
337 master->hook(master->hook_private_data, master->val);
332 return 1; 338 return 1;
333} 339}
334 340
@@ -408,3 +414,41 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
408 return kctl; 414 return kctl;
409} 415}
410EXPORT_SYMBOL(snd_ctl_make_virtual_master); 416EXPORT_SYMBOL(snd_ctl_make_virtual_master);
417
418/**
419 * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control
420 * @kcontrol: vmaster kctl element
421 * @hook: the hook function
422 *
423 * Adds the given hook to the vmaster control element so that it's called
424 * at each time when the value is changed.
425 */
426int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol,
427 void (*hook)(void *private_data, int),
428 void *private_data)
429{
430 struct link_master *master = snd_kcontrol_chip(kcontrol);
431 master->hook = hook;
432 master->hook_private_data = private_data;
433 return 0;
434}
435EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook);
436
437/**
438 * snd_ctl_sync_vmaster_hook - Sync the vmaster hook
439 * @kcontrol: vmaster kctl element
440 *
441 * Call the hook function to synchronize with the current value of the given
442 * vmaster element. NOP when NULL is passed to @kcontrol or the hook doesn't
443 * exist.
444 */
445void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kcontrol)
446{
447 struct link_master *master;
448 if (!kcontrol)
449 return;
450 master = snd_kcontrol_chip(kcontrol);
451 if (master->hook)
452 master->hook(master->hook_private_data, master->val);
453}
454EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook);