ALSA: vmaster: Add snd_ctl_sync_vmaster() helper function
Introduce a new helper function, snd_ctl_sync_vmaster(), which updates the slave put callbacks forcibly as well as calling the hook. This will be used in the upcoming patch in HD-audio codec driver for toggling the mute in vmaster slaves. Along with the new function, the old snd_ctl_sync_vmaster_hook() is replaced as a macro calling with the argument hook_only=true. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
					parent
					
						
							
								e1a4dca671
							
						
					
				
			
			
				commit
				
					
						1ca2f2ec9e
					
				
			
		
					 2 changed files with 47 additions and 21 deletions
				
			
		|  | @ -233,7 +233,8 @@ snd_ctl_add_slave_uncached(struct snd_kcontrol *master, | |||
| int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl, | ||||
| 			     void (*hook)(void *private_data, int), | ||||
| 			     void *private_data); | ||||
| void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kctl); | ||||
| void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only); | ||||
| #define snd_ctl_sync_vmaster_hook(kctl)	snd_ctl_sync_vmaster(kctl, true) | ||||
| 
 | ||||
| /*
 | ||||
|  * Helper functions for jack-detection controls | ||||
|  |  | |||
|  | @ -310,20 +310,10 @@ static int master_get(struct snd_kcontrol *kcontrol, | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int master_put(struct snd_kcontrol *kcontrol, | ||||
| 		      struct snd_ctl_elem_value *ucontrol) | ||||
| static int sync_slaves(struct link_master *master, int old_val, int new_val) | ||||
| { | ||||
| 	struct link_master *master = snd_kcontrol_chip(kcontrol); | ||||
| 	struct link_slave *slave; | ||||
| 	struct snd_ctl_elem_value *uval; | ||||
| 	int err, old_val; | ||||
| 
 | ||||
| 	err = master_init(master); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	old_val = master->val; | ||||
| 	if (ucontrol->value.integer.value[0] == old_val) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	uval = kmalloc(sizeof(*uval), GFP_KERNEL); | ||||
| 	if (!uval) | ||||
|  | @ -332,11 +322,33 @@ static int master_put(struct snd_kcontrol *kcontrol, | |||
| 		master->val = old_val; | ||||
| 		uval->id = slave->slave.id; | ||||
| 		slave_get_val(slave, uval); | ||||
| 		master->val = ucontrol->value.integer.value[0]; | ||||
| 		master->val = new_val; | ||||
| 		slave_put_val(slave, uval); | ||||
| 	} | ||||
| 	kfree(uval); | ||||
| 	if (master->hook && !err) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int master_put(struct snd_kcontrol *kcontrol, | ||||
| 		      struct snd_ctl_elem_value *ucontrol) | ||||
| { | ||||
| 	struct link_master *master = snd_kcontrol_chip(kcontrol); | ||||
| 	int err, new_val, old_val; | ||||
| 	bool first_init; | ||||
| 
 | ||||
| 	err = master_init(master); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	first_init = err; | ||||
| 	old_val = master->val; | ||||
| 	new_val = ucontrol->value.integer.value[0]; | ||||
| 	if (new_val == old_val) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	err = sync_slaves(master, old_val, new_val); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	if (master->hook && first_init) | ||||
| 		master->hook(master->hook_private_data, master->val); | ||||
| 	return 1; | ||||
| } | ||||
|  | @ -442,20 +454,33 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol, | |||
| EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook); | ||||
| 
 | ||||
| /**
 | ||||
|  * snd_ctl_sync_vmaster_hook - Sync the vmaster hook | ||||
|  * snd_ctl_sync_vmaster - Sync the vmaster slaves and hook | ||||
|  * @kcontrol: vmaster kctl element | ||||
|  * @hook_only: sync only the hook | ||||
|  * | ||||
|  * Call the hook function to synchronize with the current value of the given | ||||
|  * vmaster element.  NOP when NULL is passed to @kcontrol or the hook doesn't | ||||
|  * exist. | ||||
|  * Forcibly call the put callback of each slave and call the hook function | ||||
|  * to synchronize with the current value of the given vmaster element. | ||||
|  * NOP when NULL is passed to @kcontrol. | ||||
|  */ | ||||
| void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kcontrol) | ||||
| void snd_ctl_sync_vmaster(struct snd_kcontrol *kcontrol, bool hook_only) | ||||
| { | ||||
| 	struct link_master *master; | ||||
| 	bool first_init = false; | ||||
| 
 | ||||
| 	if (!kcontrol) | ||||
| 		return; | ||||
| 	master = snd_kcontrol_chip(kcontrol); | ||||
| 	if (master->hook) | ||||
| 	if (!hook_only) { | ||||
| 		int err = master_init(master); | ||||
| 		if (err < 0) | ||||
| 			return; | ||||
| 		first_init = err; | ||||
| 		err = sync_slaves(master, master->val, master->val); | ||||
| 		if (err < 0) | ||||
| 			return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (master->hook && !first_init) | ||||
| 		master->hook(master->hook_private_data, master->val); | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook); | ||||
| EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Takashi Iwai
				Takashi Iwai