提交 1ca2f2ec 编写于 作者: T Takashi Iwai

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: NTakashi Iwai <tiwai@suse.de>
上级 e1a4dca6
...@@ -233,7 +233,8 @@ snd_ctl_add_slave_uncached(struct snd_kcontrol *master, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册