@@ -0,0 +1,134 @@
+/*
+ * This file is only included exactly once!
+ *
+ * The tables here are derived from the tas3004 datasheet,
+ * modulo typo corrections and some smoothing...
+ */
+
+#define TAS3004_TREBLE_MIN 0
+#define TAS3004_TREBLE_MAX 72
+#define TAS3004_BASS_MIN 0
+#define TAS3004_BASS_MAX 72
+#define TAS3004_TREBLE_ZERO 36
+#define TAS3004_BASS_ZERO 36
+
+static u8 tas3004_treble_table[] = {
+ 150, /* -18 dB */
+ 149,
+ 148,
+ 147,
+ 146,
+ 145,
+ 144,
+ 143,
+ 142,
+ 141,
+ 140,
+ 139,
+ 138,
+ 137,
+ 136,
+ 135,
+ 134,
+ 133,
+ 132,
+ 131,
+ 130,
+ 129,
+ 128,
+ 127,
+ 126,
+ 125,
+ 124,
+ 123,
+ 122,
+ 121,
+ 120,
+ 119,
+ 118,
+ 117,
+ 116,
+ 115,
+ 114, /* 0 dB */
+ 113,
+ 112,
+ 111,
+ 109,
+ 108,
+ 107,
+ 105,
+ 104,
+ 103,
+ 101,
+ 99,
+ 98,
+ 96,
+ 93,
+ 91,
+ 89,
+ 86,
+ 83,
+ 81,
+ 77,
+ 74,
+ 71,
+ 67,
+ 63,
+ 59,
+ 54,
+ 49,
+ 44,
+ 38,
+ 32,
+ 26,
+ 19,
+ 10,
+ 4,
+ 2,
+ 1, /* +18 dB */
+};
+
+static inline u8 tas3004_treble(int idx)
+{
+ return tas3004_treble_table[idx];
+}
+
+/* I only save the difference here to the treble table
+ * so that the binary is smaller...
+ * I have also ignored completely differences of
+ * +/- 1
+ */
+static s8 tas3004_bass_diff_to_treble[] = {
+ 2, /* 7 dB, offset 50 */
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 4,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 14,
+ 13,
+ 8,
+ 1, /* 18 dB */
+};
+
+static inline u8 tas3004_bass(int idx)
+{
+ u8 result = tas3004_treble_table[idx];
+
+ if (idx >= 50)
+ result += tas3004_bass_diff_to_treble[idx-50];
+ return result;
+}
--- linux-2.6-fetch.orig/sound/aoa/codecs/snd-aoa-codec-tas.c 2006-07-07 18:10:09.470223603 +0200
+++ linux-2.6-fetch/sound/aoa/codecs/snd-aoa-codec-tas.c 2006-07-07 18:25:07.330223603 +0200@@ -485,6 +503,89 @@ static struct snd_kcontrol_new capture_s
.put = tas_snd_capture_source_put,
};
+static int tas_snd_treble_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = TAS3004_TREBLE_MIN;
+ uinfo->value.integer.max = TAS3004_TREBLE_MAX;
+ return 0;
+}
+
+static int tas_snd_treble_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = tas->treble;
+ return 0;
+}
+
+static int tas_snd_treble_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ if (tas->treble == ucontrol->value.integer.value[0])
+ return 0;
+
+ tas->treble = ucontrol->value.integer.value[0];
+ if (tas->hw_enabled)
+ tas_set_treble(tas);
+ return 1;
+}
+
+static struct snd_kcontrol_new treble_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Treble",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = tas_snd_treble_info,
+ .get = tas_snd_treble_get,
+ .put = tas_snd_treble_put,
+};
+
+static int tas_snd_bass_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = TAS3004_BASS_MIN;
+ uinfo->value.integer.max = TAS3004_BASS_MAX;
+ return 0;
+}
+
+static int tas_snd_bass_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = tas->bass;
+ return 0;
+}
+
+static int tas_snd_bass_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ if (tas->bass == ucontrol->value.integer.value[0])
+ return 0;
+
+ tas->bass = ucontrol->value.integer.value[0];
+ if (tas->hw_enabled)
+ tas_set_bass(tas);
+ return 1;
+}
+
+static struct snd_kcontrol_new bass_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Bass",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = tas_snd_bass_info,
+ .get = tas_snd_bass_get,
+ .put = tas_snd_bass_put,
+};
static struct transfer_info tas_transfers[] = {
{