aboutsummaryrefslogtreecommitdiffstats
path: root/sound/aoa
diff options
context:
space:
mode:
Diffstat (limited to 'sound/aoa')
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h134
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.c116
2 files changed, 247 insertions, 3 deletions
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
new file mode 100644
index 000000000000..69b61136fd54
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
@@ -0,0 +1,134 @@
1/*
2 * This file is only included exactly once!
3 *
4 * The tables here are derived from the tas3004 datasheet,
5 * modulo typo corrections and some smoothing...
6 */
7
8#define TAS3004_TREBLE_MIN 0
9#define TAS3004_TREBLE_MAX 72
10#define TAS3004_BASS_MIN 0
11#define TAS3004_BASS_MAX 72
12#define TAS3004_TREBLE_ZERO 36
13#define TAS3004_BASS_ZERO 36
14
15static u8 tas3004_treble_table[] = {
16 150, /* -18 dB */
17 149,
18 148,
19 147,
20 146,
21 145,
22 144,
23 143,
24 142,
25 141,
26 140,
27 139,
28 138,
29 137,
30 136,
31 135,
32 134,
33 133,
34 132,
35 131,
36 130,
37 129,
38 128,
39 127,
40 126,
41 125,
42 124,
43 123,
44 122,
45 121,
46 120,
47 119,
48 118,
49 117,
50 116,
51 115,
52 114, /* 0 dB */
53 113,
54 112,
55 111,
56 109,
57 108,
58 107,
59 105,
60 104,
61 103,
62 101,
63 99,
64 98,
65 96,
66 93,
67 91,
68 89,
69 86,
70 83,
71 81,
72 77,
73 74,
74 71,
75 67,
76 63,
77 59,
78 54,
79 49,
80 44,
81 38,
82 32,
83 26,
84 19,
85 10,
86 4,
87 2,
88 1, /* +18 dB */
89};
90
91static inline u8 tas3004_treble(int idx)
92{
93 return tas3004_treble_table[idx];
94}
95
96/* I only save the difference here to the treble table
97 * so that the binary is smaller...
98 * I have also ignored completely differences of
99 * +/- 1
100 */
101static s8 tas3004_bass_diff_to_treble[] = {
102 2, /* 7 dB, offset 50 */
103 2,
104 2,
105 2,
106 2,
107 1,
108 2,
109 2,
110 2,
111 3,
112 4,
113 4,
114 5,
115 6,
116 7,
117 8,
118 9,
119 10,
120 11,
121 14,
122 13,
123 8,
124 1, /* 18 dB */
125};
126
127static inline u8 tas3004_bass(int idx)
128{
129 u8 result = tas3004_treble_table[idx];
130
131 if (idx >= 50)
132 result += tas3004_bass_diff_to_treble[idx-50];
133 return result;
134}
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index 009f57576f9c..16c0b6b0a805 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -72,6 +72,7 @@ MODULE_DESCRIPTION("tas codec driver for snd-aoa");
72 72
73#include "snd-aoa-codec-tas.h" 73#include "snd-aoa-codec-tas.h"
74#include "snd-aoa-codec-tas-gain-table.h" 74#include "snd-aoa-codec-tas-gain-table.h"
75#include "snd-aoa-codec-tas-basstreble.h"
75#include "../aoa.h" 76#include "../aoa.h"
76#include "../soundbus/soundbus.h" 77#include "../soundbus/soundbus.h"
77 78
@@ -87,6 +88,7 @@ struct tas {
87 hw_enabled:1; 88 hw_enabled:1;
88 u8 cached_volume_l, cached_volume_r; 89 u8 cached_volume_l, cached_volume_r;
89 u8 mixer_l[3], mixer_r[3]; 90 u8 mixer_l[3], mixer_r[3];
91 u8 bass, treble;
90 u8 acr; 92 u8 acr;
91 int drc_range; 93 int drc_range;
92}; 94};
@@ -128,6 +130,22 @@ static void tas3004_set_drc(struct tas *tas)
128 tas_write_reg(tas, TAS_REG_DRC, 6, val); 130 tas_write_reg(tas, TAS_REG_DRC, 6, val);
129} 131}
130 132
133static void tas_set_treble(struct tas *tas)
134{
135 u8 tmp;
136
137 tmp = tas3004_treble(tas->treble);
138 tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp);
139}
140
141static void tas_set_bass(struct tas *tas)
142{
143 u8 tmp;
144
145 tmp = tas3004_bass(tas->bass);
146 tas_write_reg(tas, TAS_REG_BASS, 1, &tmp);
147}
148
131static void tas_set_volume(struct tas *tas) 149static void tas_set_volume(struct tas *tas)
132{ 150{
133 u8 block[6]; 151 u8 block[6];
@@ -485,6 +503,89 @@ static struct snd_kcontrol_new capture_source_control = {
485 .put = tas_snd_capture_source_put, 503 .put = tas_snd_capture_source_put,
486}; 504};
487 505
506static int tas_snd_treble_info(struct snd_kcontrol *kcontrol,
507 struct snd_ctl_elem_info *uinfo)
508{
509 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
510 uinfo->count = 1;
511 uinfo->value.integer.min = TAS3004_TREBLE_MIN;
512 uinfo->value.integer.max = TAS3004_TREBLE_MAX;
513 return 0;
514}
515
516static int tas_snd_treble_get(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_value *ucontrol)
518{
519 struct tas *tas = snd_kcontrol_chip(kcontrol);
520
521 ucontrol->value.integer.value[0] = tas->treble;
522 return 0;
523}
524
525static int tas_snd_treble_put(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
527{
528 struct tas *tas = snd_kcontrol_chip(kcontrol);
529
530 if (tas->treble == ucontrol->value.integer.value[0])
531 return 0;
532
533 tas->treble = ucontrol->value.integer.value[0];
534 if (tas->hw_enabled)
535 tas_set_treble(tas);
536 return 1;
537}
538
539static struct snd_kcontrol_new treble_control = {
540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
541 .name = "Treble",
542 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
543 .info = tas_snd_treble_info,
544 .get = tas_snd_treble_get,
545 .put = tas_snd_treble_put,
546};
547
548static int tas_snd_bass_info(struct snd_kcontrol *kcontrol,
549 struct snd_ctl_elem_info *uinfo)
550{
551 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
552 uinfo->count = 1;
553 uinfo->value.integer.min = TAS3004_BASS_MIN;
554 uinfo->value.integer.max = TAS3004_BASS_MAX;
555 return 0;
556}
557
558static int tas_snd_bass_get(struct snd_kcontrol *kcontrol,
559 struct snd_ctl_elem_value *ucontrol)
560{
561 struct tas *tas = snd_kcontrol_chip(kcontrol);
562
563 ucontrol->value.integer.value[0] = tas->bass;
564 return 0;
565}
566
567static int tas_snd_bass_put(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_value *ucontrol)
569{
570 struct tas *tas = snd_kcontrol_chip(kcontrol);
571
572 if (tas->bass == ucontrol->value.integer.value[0])
573 return 0;
574
575 tas->bass = ucontrol->value.integer.value[0];
576 if (tas->hw_enabled)
577 tas_set_bass(tas);
578 return 1;
579}
580
581static struct snd_kcontrol_new bass_control = {
582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
583 .name = "Bass",
584 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
585 .info = tas_snd_bass_info,
586 .get = tas_snd_bass_get,
587 .put = tas_snd_bass_put,
588};
488 589
489static struct transfer_info tas_transfers[] = { 590static struct transfer_info tas_transfers[] = {
490 { 591 {
@@ -541,9 +642,10 @@ static int tas_reset_init(struct tas *tas)
541 tas3004_set_drc(tas); 642 tas3004_set_drc(tas);
542 643
543 /* Set treble & bass to 0dB */ 644 /* Set treble & bass to 0dB */
544 tmp = 114; 645 tas->treble = TAS3004_TREBLE_ZERO;
545 tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp); 646 tas->bass = TAS3004_BASS_ZERO;
546 tas_write_reg(tas, TAS_REG_BASS, 1, &tmp); 647 tas_set_treble(tas);
648 tas_set_bass(tas);
547 649
548 tas->acr &= ~TAS_ACR_ANALOG_PDOWN; 650 tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
549 if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr)) 651 if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
@@ -682,6 +784,14 @@ static int tas_init_codec(struct aoa_codec *codec)
682 if (err) 784 if (err)
683 goto error; 785 goto error;
684 786
787 err = aoa_snd_ctl_add(snd_ctl_new1(&treble_control, tas));
788 if (err)
789 goto error;
790
791 err = aoa_snd_ctl_add(snd_ctl_new1(&bass_control, tas));
792 if (err)
793 goto error;
794
685 return 0; 795 return 0;
686 error: 796 error:
687 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); 797 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);