Skip to content

Commit

Permalink
[ALSA] ASoC: Add SOC_DOUBLE_S8_TLV control type
Browse files Browse the repository at this point in the history
The SOC_DOUBLE_S8_TLV control type was originally implemented in the
UDA1380 driver by Philipp Zabel and was moved into the core by me.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Mark Brown authored and Takashi Iwai committed May 29, 2008
1 parent a93bbaa commit e13ac2e
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
15 changes: 15 additions & 0 deletions include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@
.get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
.private_value = (reg_left) | ((shift) << 8) | \
((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
#define SOC_DOUBLE_S8_TLV(xname, reg, min, max, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
SNDRV_CTL_ELEM_ACCESS_READWRITE, \
.tlv.p = (tlv_array), \
.info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
.put = snd_soc_put_volsw_s8, \
.private_value = (reg) | (((signed char)max) << 16) | \
(((signed char)min) << 24) }
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
.mask = xmask, .texts = xtexts }
Expand Down Expand Up @@ -267,6 +276,12 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);

/* SoC PCM stream information */
struct snd_soc_pcm_stream {
Expand Down
72 changes: 72 additions & 0 deletions sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,78 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);

/**
* snd_soc_info_volsw_s8 - signed mixer info callback
* @kcontrol: mixer control
* @uinfo: control element information
*
* Callback to provide information about a signed mixer control.
*
* Returns 0 for success.
*/
int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
int max = (signed char)((kcontrol->private_value >> 16) & 0xff);
int min = (signed char)((kcontrol->private_value >> 24) & 0xff);

uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = max-min;
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);

/**
* snd_soc_get_volsw_s8 - signed mixer get callback
* @kcontrol: mixer control
* @uinfo: control element information
*
* Callback to get the value of a signed mixer control.
*
* Returns 0 for success.
*/
int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
int min = (signed char)((kcontrol->private_value >> 24) & 0xff);
int val = snd_soc_read(codec, reg);

ucontrol->value.integer.value[0] =
((signed char)(val & 0xff))-min;
ucontrol->value.integer.value[1] =
((signed char)((val >> 8) & 0xff))-min;
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8);

/**
* snd_soc_put_volsw_sgn - signed mixer put callback
* @kcontrol: mixer control
* @uinfo: control element information
*
* Callback to set the value of a signed mixer control.
*
* Returns 0 for success.
*/
int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
int min = (signed char)((kcontrol->private_value >> 24) & 0xff);
unsigned short val;

val = (ucontrol->value.integer.value[0]+min) & 0xff;
val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;

return snd_soc_update_bits(codec, reg, 0xffff, val);
}
EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);

static int __devinit snd_soc_init(void)
{
printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION);
Expand Down

0 comments on commit e13ac2e

Please sign in to comment.