diff options
Diffstat (limited to 'firmware/drivers/audio/wm8758.c')
-rw-r--r-- | firmware/drivers/audio/wm8758.c | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/firmware/drivers/audio/wm8758.c b/firmware/drivers/audio/wm8758.c index bb05960ced..715c921e33 100644 --- a/firmware/drivers/audio/wm8758.c +++ b/firmware/drivers/audio/wm8758.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include "audiohw.h" | 33 | #include "audiohw.h" |
34 | 34 | ||
35 | const struct sound_settings_info audiohw_settings[] = { | 35 | const struct sound_settings_info audiohw_settings[] = { |
36 | [SOUND_VOLUME] = {"dB", 0, 1, -58, 6, -25}, | 36 | [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25}, |
37 | [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0}, | 37 | [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0}, |
38 | [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0}, | 38 | [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0}, |
39 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, | 39 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, |
@@ -52,13 +52,46 @@ const struct sound_settings_info audiohw_settings[] = { | |||
52 | static unsigned short eq1_reg = EQ1_EQ3DMODE | EQ_GAIN_VALUE(0); | 52 | static unsigned short eq1_reg = EQ1_EQ3DMODE | EQ_GAIN_VALUE(0); |
53 | static unsigned short eq5_reg = EQ_GAIN_VALUE(0); | 53 | static unsigned short eq5_reg = EQ_GAIN_VALUE(0); |
54 | 54 | ||
55 | /* convert tenth of dB volume (-57..6) to master volume register value */ | 55 | /* convert tenth of dB volume (-89..6) to master volume register value */ |
56 | int tenthdb2master(int db) | 56 | int tenthdb2master(int db) |
57 | { | 57 | { |
58 | /* att DAC AMP result | ||
59 | +6dB 0 +6 96 | ||
60 | 0dB 0 0 90 | ||
61 | -57dB 0 -57 33 | ||
62 | -58dB -1 -57 32 | ||
63 | -89dB -32 -57 1 | ||
64 | -90dB -oo -oo 0 */ | ||
58 | if (db < VOLUME_MIN) { | 65 | if (db < VOLUME_MIN) { |
59 | return 0x40; | 66 | return 0; |
60 | } else { | 67 | } else { |
61 | return (db/10)+57; | 68 | return (db-VOLUME_MIN)/10 + 1; |
69 | } | ||
70 | } | ||
71 | |||
72 | /* helper function that calculates the register setting for amplifier and | ||
73 | DAC volume out of the input from tenthdb2master() */ | ||
74 | static void get_volume_params(int db, int *dac, int *amp) | ||
75 | { | ||
76 | /* should never happen, set max volume for amp and dac */ | ||
77 | if (db > 96) { | ||
78 | *dac = 255; | ||
79 | *amp = 63; | ||
80 | } | ||
81 | /* set dac to max and set volume for amp (better snr) */ | ||
82 | else if (db > 32) { | ||
83 | *dac = 255; | ||
84 | *amp = (db-90)+57; | ||
85 | } | ||
86 | /* set amp to min and reduce dac output */ | ||
87 | else if (db > 0) { | ||
88 | *dac = (db-33)*2 + 255; | ||
89 | *amp = 0; | ||
90 | } | ||
91 | /* mute all */ | ||
92 | else { | ||
93 | *dac = 0x00; | ||
94 | *amp = 0x40; | ||
62 | } | 95 | } |
63 | } | 96 | } |
64 | 97 | ||
@@ -123,16 +156,29 @@ void audiohw_postinit(void) | |||
123 | 156 | ||
124 | void audiohw_set_master_vol(int vol_l, int vol_r) | 157 | void audiohw_set_master_vol(int vol_l, int vol_r) |
125 | { | 158 | { |
126 | /* OUT1 */ | 159 | int dac_l, amp_l, dac_r, amp_r; |
127 | wmcodec_write(LOUT1VOL, LOUT1VOL_LOUT1ZC | vol_l); | 160 | get_volume_params(vol_l, &dac_l, &_l); |
128 | wmcodec_write(ROUT1VOL, ROUT1VOL_OUT1VU | ROUT1VOL_ROUT1ZC | vol_r); | 161 | get_volume_params(vol_r, &dac_r, &_r); |
162 | |||
163 | /* set DAC | ||
164 | Important: DAC is global and will also affect lineout */ | ||
165 | wmcodec_write(LDACVOL, dac_l); | ||
166 | wmcodec_write(RDACVOL, dac_r | RDACVOL_DACVU); | ||
167 | |||
168 | /* set headphone amp OUT1 */ | ||
169 | wmcodec_write(LOUT1VOL, amp_l | LOUT1VOL_LOUT1ZC); | ||
170 | wmcodec_write(ROUT1VOL, amp_r | ROUT1VOL_ROUT1ZC | ROUT1VOL_OUT1VU); | ||
129 | } | 171 | } |
130 | 172 | ||
131 | void audiohw_set_lineout_vol(int vol_l, int vol_r) | 173 | void audiohw_set_lineout_vol(int vol_l, int vol_r) |
132 | { | 174 | { |
133 | /* OUT2 */ | 175 | int dac_l, amp_l, dac_r, amp_r; |
134 | wmcodec_write(LOUT2VOL, LOUT2VOL_LOUT2ZC | vol_l); | 176 | get_volume_params(vol_l, &dac_l, &_l); |
135 | wmcodec_write(ROUT2VOL, ROUT2VOL_OUT2VU | ROUT2VOL_ROUT2ZC | vol_r); | 177 | get_volume_params(vol_r, &dac_r, &_r); |
178 | |||
179 | /* set lineout amp OUT2 */ | ||
180 | wmcodec_write(LOUT2VOL, amp_l | LOUT2VOL_LOUT2ZC); | ||
181 | wmcodec_write(ROUT2VOL, amp_r | ROUT2VOL_ROUT2ZC | ROUT2VOL_OUT2VU); | ||
136 | } | 182 | } |
137 | 183 | ||
138 | void audiohw_set_bass(int value) | 184 | void audiohw_set_bass(int value) |