aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/twl4030.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index abf691493f43..731534c19b7f 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -814,6 +814,48 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
814 return err; 814 return err;
815} 815}
816 816
817/* Codec operation modes */
818static const char *twl4030_op_modes_texts[] = {
819 "Option 2 (voice/audio)", "Option 1 (audio)"
820};
821
822static const struct soc_enum twl4030_op_modes_enum =
823 SOC_ENUM_SINGLE(TWL4030_REG_CODEC_MODE, 0,
824 ARRAY_SIZE(twl4030_op_modes_texts),
825 twl4030_op_modes_texts);
826
827int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
828 struct snd_ctl_elem_value *ucontrol)
829{
830 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
831 struct twl4030_priv *twl4030 = codec->private_data;
832 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
833 unsigned short val;
834 unsigned short mask, bitmask;
835
836 if (twl4030->configured) {
837 printk(KERN_ERR "twl4030 operation mode cannot be "
838 "changed on-the-fly\n");
839 return -EBUSY;
840 }
841
842 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
843 ;
844 if (ucontrol->value.enumerated.item[0] > e->max - 1)
845 return -EINVAL;
846
847 val = ucontrol->value.enumerated.item[0] << e->shift_l;
848 mask = (bitmask - 1) << e->shift_l;
849 if (e->shift_l != e->shift_r) {
850 if (ucontrol->value.enumerated.item[1] > e->max - 1)
851 return -EINVAL;
852 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
853 mask |= (bitmask - 1) << e->shift_r;
854 }
855
856 return snd_soc_update_bits(codec, e->reg, mask, val);
857}
858
817/* 859/*
818 * FGAIN volume control: 860 * FGAIN volume control:
819 * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB) 861 * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
@@ -895,6 +937,11 @@ static const struct soc_enum twl4030_vibradir_enum =
895 twl4030_vibradir_texts); 937 twl4030_vibradir_texts);
896 938
897static const struct snd_kcontrol_new twl4030_snd_controls[] = { 939static const struct snd_kcontrol_new twl4030_snd_controls[] = {
940 /* Codec operation mode control */
941 SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum,
942 snd_soc_get_enum_double,
943 snd_soc_put_twl4030_opmode_enum_double),
944
898 /* Common playback gain controls */ 945 /* Common playback gain controls */
899 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume", 946 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
900 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA, 947 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,