aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2008-05-28 12:58:05 -0400
committerTakashi Iwai <tiwai@suse.de>2008-05-29 02:10:49 -0400
commite13ac2e9b18bde51cf32c69c2209df25791ab3e5 (patch)
tree67d308f63015d0da00998c7e1c1d12c55df7c6f9
parenta93bbaa77ea61c6bad684263a65f812b31bf9791 (diff)
[ALSA] ASoC: Add SOC_DOUBLE_S8_TLV control type
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>
-rw-r--r--include/sound/soc.h15
-rw-r--r--sound/soc/soc-core.c72
2 files changed, 87 insertions, 0 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index bca9538d9e50..9fa2093e74eb 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -73,6 +73,15 @@
73 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 73 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
74 .private_value = (reg_left) | ((shift) << 8) | \ 74 .private_value = (reg_left) | ((shift) << 8) | \
75 ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) } 75 ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
76#define SOC_DOUBLE_S8_TLV(xname, reg, min, max, tlv_array) \
77{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
78 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
79 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
80 .tlv.p = (tlv_array), \
81 .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
82 .put = snd_soc_put_volsw_s8, \
83 .private_value = (reg) | (((signed char)max) << 16) | \
84 (((signed char)min) << 24) }
76#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ 85#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
77{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ 86{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
78 .mask = xmask, .texts = xtexts } 87 .mask = xmask, .texts = xtexts }
@@ -267,6 +276,12 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
267 struct snd_ctl_elem_value *ucontrol); 276 struct snd_ctl_elem_value *ucontrol);
268int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, 277int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol); 278 struct snd_ctl_elem_value *ucontrol);
279int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_info *uinfo);
281int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
282 struct snd_ctl_elem_value *ucontrol);
283int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
284 struct snd_ctl_elem_value *ucontrol);
270 285
271/* SoC PCM stream information */ 286/* SoC PCM stream information */
272struct snd_soc_pcm_stream { 287struct snd_soc_pcm_stream {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a3f091e0843a..f594ab888e17 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1589,6 +1589,78 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1589} 1589}
1590EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); 1590EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
1591 1591
1592/**
1593 * snd_soc_info_volsw_s8 - signed mixer info callback
1594 * @kcontrol: mixer control
1595 * @uinfo: control element information
1596 *
1597 * Callback to provide information about a signed mixer control.
1598 *
1599 * Returns 0 for success.
1600 */
1601int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
1602 struct snd_ctl_elem_info *uinfo)
1603{
1604 int max = (signed char)((kcontrol->private_value >> 16) & 0xff);
1605 int min = (signed char)((kcontrol->private_value >> 24) & 0xff);
1606
1607 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1608 uinfo->count = 2;
1609 uinfo->value.integer.min = 0;
1610 uinfo->value.integer.max = max-min;
1611 return 0;
1612}
1613EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
1614
1615/**
1616 * snd_soc_get_volsw_s8 - signed mixer get callback
1617 * @kcontrol: mixer control
1618 * @uinfo: control element information
1619 *
1620 * Callback to get the value of a signed mixer control.
1621 *
1622 * Returns 0 for success.
1623 */
1624int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
1625 struct snd_ctl_elem_value *ucontrol)
1626{
1627 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1628 int reg = kcontrol->private_value & 0xff;
1629 int min = (signed char)((kcontrol->private_value >> 24) & 0xff);
1630 int val = snd_soc_read(codec, reg);
1631
1632 ucontrol->value.integer.value[0] =
1633 ((signed char)(val & 0xff))-min;
1634 ucontrol->value.integer.value[1] =
1635 ((signed char)((val >> 8) & 0xff))-min;
1636 return 0;
1637}
1638EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8);
1639
1640/**
1641 * snd_soc_put_volsw_sgn - signed mixer put callback
1642 * @kcontrol: mixer control
1643 * @uinfo: control element information
1644 *
1645 * Callback to set the value of a signed mixer control.
1646 *
1647 * Returns 0 for success.
1648 */
1649int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
1650 struct snd_ctl_elem_value *ucontrol)
1651{
1652 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1653 int reg = kcontrol->private_value & 0xff;
1654 int min = (signed char)((kcontrol->private_value >> 24) & 0xff);
1655 unsigned short val;
1656
1657 val = (ucontrol->value.integer.value[0]+min) & 0xff;
1658 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
1659
1660 return snd_soc_update_bits(codec, reg, 0xffff, val);
1661}
1662EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
1663
1592static int __devinit snd_soc_init(void) 1664static int __devinit snd_soc_init(void)
1593{ 1665{
1594 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); 1666 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION);