forked from luck/tmp_suning_uos_patched
ASoC: core: Add strobe control
Added support for a control that strobes a bit in a register to high then back to low (or the inverse). This is typically useful for hardware that requires strobing a singe bit to trigger some functionality and where exposing the bit in a normal single control would require the user to first manually set then again unset the bit again for the strobe to trigger. Added convenience macro. SOC_SINGLE_STROBE Added accessor implementations. snd_soc_get_strobe snd_soc_put_strobe Signed-off-by: Kristoffer KARLSSON <kristoffer.karlsson@stericsson.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
4183eed288
commit
dd7b10b30c
@ -219,6 +219,10 @@
|
||||
{.regbase = xregbase, .regcount = xregcount, .nbits = xnbits, \
|
||||
.invert = xinvert, .min = xmin, .max = xmax} }
|
||||
|
||||
#define SOC_SINGLE_STROBE(xname, xreg, xshift, xinvert) \
|
||||
SOC_SINGLE_EXT(xname, xreg, xshift, 1, xinvert, \
|
||||
snd_soc_get_strobe, snd_soc_put_strobe)
|
||||
|
||||
/*
|
||||
* Simplified versions of above macros, declaring a struct and calculating
|
||||
* ARRAY_SIZE internally
|
||||
@ -461,6 +465,10 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
/**
|
||||
* struct snd_soc_reg_access - Describes whether a given register is
|
||||
|
@ -3009,6 +3009,69 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx);
|
||||
|
||||
/**
|
||||
* snd_soc_get_strobe - strobe get callback
|
||||
* @kcontrol: mixer control
|
||||
* @ucontrol: control element information
|
||||
*
|
||||
* Callback get the value of a strobe mixer control.
|
||||
*
|
||||
* Returns 0 for success.
|
||||
*/
|
||||
int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
unsigned int reg = mc->reg;
|
||||
unsigned int shift = mc->shift;
|
||||
unsigned int mask = 1 << shift;
|
||||
unsigned int invert = mc->invert != 0;
|
||||
unsigned int val = snd_soc_read(codec, reg) & mask;
|
||||
|
||||
if (shift != 0 && val != 0)
|
||||
val = val >> shift;
|
||||
ucontrol->value.enumerated.item[0] = val ^ invert;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_get_strobe);
|
||||
|
||||
/**
|
||||
* snd_soc_put_strobe - strobe put callback
|
||||
* @kcontrol: mixer control
|
||||
* @ucontrol: control element information
|
||||
*
|
||||
* Callback strobe a register bit to high then low (or the inverse)
|
||||
* in one pass of a single mixer enum control.
|
||||
*
|
||||
* Returns 1 for success.
|
||||
*/
|
||||
int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
unsigned int reg = mc->reg;
|
||||
unsigned int shift = mc->shift;
|
||||
unsigned int mask = 1 << shift;
|
||||
unsigned int invert = mc->invert != 0;
|
||||
unsigned int strobe = ucontrol->value.enumerated.item[0] != 0;
|
||||
unsigned int val1 = (strobe ^ invert) ? mask : 0;
|
||||
unsigned int val2 = (strobe ^ invert) ? 0 : mask;
|
||||
int err;
|
||||
|
||||
err = snd_soc_update_bits_locked(codec, reg, mask, val1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_soc_update_bits_locked(codec, reg, mask, val2);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_put_strobe);
|
||||
|
||||
/**
|
||||
* snd_soc_dai_set_sysclk - configure DAI system or master clock.
|
||||
* @dai: DAI
|
||||
|
Loading…
Reference in New Issue
Block a user