mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-09 07:54:00 +00:00
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,
|
int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
|
||||||
void (*hook)(void *private_data, int),
|
void (*hook)(void *private_data, int),
|
||||||
void *private_data);
|
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
|
* Helper functions for jack-detection controls
|
||||||
|
|
|
@ -310,20 +310,10 @@ static int master_get(struct snd_kcontrol *kcontrol,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int master_put(struct snd_kcontrol *kcontrol,
|
static int sync_slaves(struct link_master *master, int old_val, int new_val)
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
|
||||||
{
|
{
|
||||||
struct link_master *master = snd_kcontrol_chip(kcontrol);
|
|
||||||
struct link_slave *slave;
|
struct link_slave *slave;
|
||||||
struct snd_ctl_elem_value *uval;
|
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);
|
uval = kmalloc(sizeof(*uval), GFP_KERNEL);
|
||||||
if (!uval)
|
if (!uval)
|
||||||
|
@ -332,11 +322,33 @@ static int master_put(struct snd_kcontrol *kcontrol,
|
||||||
master->val = old_val;
|
master->val = old_val;
|
||||||
uval->id = slave->slave.id;
|
uval->id = slave->slave.id;
|
||||||
slave_get_val(slave, uval);
|
slave_get_val(slave, uval);
|
||||||
master->val = ucontrol->value.integer.value[0];
|
master->val = new_val;
|
||||||
slave_put_val(slave, uval);
|
slave_put_val(slave, uval);
|
||||||
}
|
}
|
||||||
kfree(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);
|
master->hook(master->hook_private_data, master->val);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -442,20 +454,33 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol,
|
||||||
EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook);
|
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
|
* @kcontrol: vmaster kctl element
|
||||||
|
* @hook_only: sync only the hook
|
||||||
*
|
*
|
||||||
* Call the hook function to synchronize with the current value of the given
|
* Forcibly call the put callback of each slave and call the hook function
|
||||||
* vmaster element. NOP when NULL is passed to @kcontrol or the hook doesn't
|
* to synchronize with the current value of the given vmaster element.
|
||||||
* exist.
|
* 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;
|
struct link_master *master;
|
||||||
|
bool first_init = false;
|
||||||
|
|
||||||
if (!kcontrol)
|
if (!kcontrol)
|
||||||
return;
|
return;
|
||||||
master = snd_kcontrol_chip(kcontrol);
|
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);
|
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
Reference in a new issue