diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/vmaster.c | 46 |
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 | } |
410 | EXPORT_SYMBOL(snd_ctl_make_virtual_master); | 416 | EXPORT_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 | */ | ||
426 | int 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 | } | ||
435 | EXPORT_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 | */ | ||
445 | void 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 | } | ||
454 | EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook); | ||