summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/wm8975.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/firmware/drivers/wm8975.c b/firmware/drivers/wm8975.c
index 12aa46821a..89e0b155da 100644
--- a/firmware/drivers/wm8975.c
+++ b/firmware/drivers/wm8975.c
@@ -41,6 +41,11 @@
41#include "wm8975.h" 41#include "wm8975.h"
42#include "i2s.h" 42#include "i2s.h"
43 43
44/* use zero crossing to reduce clicks during volume changes */
45#define VOLUME_ZC_WAIT (1<<7)
46
47
48
44/* convert tenth of dB volume (-730..60) to master volume register value */ 49/* convert tenth of dB volume (-730..60) to master volume register value */
45int tenthdb2master(int db) 50int tenthdb2master(int db)
46{ 51{
@@ -96,6 +101,9 @@ void audiohw_enable_output(bool enable)
96 101
97 /* 2. Enable Vmid and VREF. */ 102 /* 2. Enable Vmid and VREF. */
98 wmcodec_write(PWRMGMT1, 0xc0); /*Pwr Mgmt(1)*/ 103 wmcodec_write(PWRMGMT1, 0xc0); /*Pwr Mgmt(1)*/
104
105 /* From app notes: allow Vref to stabilize to reduce clicks */
106 sleep(HZ/4);
99 107
100 /* 3. Enable DACs as required. */ 108 /* 3. Enable DACs as required. */
101 wmcodec_write(PWRMGMT2, 0x180); /*Pwr Mgmt(2)*/ 109 wmcodec_write(PWRMGMT2, 0x180); /*Pwr Mgmt(2)*/
@@ -111,10 +119,8 @@ void audiohw_enable_output(bool enable)
111 audiohw_set_sample_rate(WM8975_44100HZ); 119 audiohw_set_sample_rate(WM8975_44100HZ);
112 120
113 /* set the volume to -6dB */ 121 /* set the volume to -6dB */
114 wmcodec_write(LOUT1VOL, IPOD_PCM_LEVEL); 122 wmcodec_write(LOUT1VOL, VOLUME_ZC_WAIT | IPOD_PCM_LEVEL);
115 wmcodec_write(ROUT1VOL,0x100 | IPOD_PCM_LEVEL); 123 wmcodec_write(ROUT1VOL, VOLUME_ZC_WAIT | 0x100 | IPOD_PCM_LEVEL);
116 wmcodec_write(LOUT1VOL, IPOD_PCM_LEVEL);
117 wmcodec_write(ROUT1VOL,0x100 | IPOD_PCM_LEVEL);
118 124
119 wmcodec_write(LOUTMIX1, 0x150); /* Left out Mix(def) */ 125 wmcodec_write(LOUTMIX1, 0x150); /* Left out Mix(def) */
120 wmcodec_write(LOUTMIX2, 0x50); 126 wmcodec_write(LOUTMIX2, 0x50);
@@ -131,6 +137,8 @@ void audiohw_enable_output(bool enable)
131 } 137 }
132} 138}
133 139
140
141
134int audiohw_set_master_vol(int vol_l, int vol_r) 142int audiohw_set_master_vol(int vol_l, int vol_r)
135{ 143{
136 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ 144 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
@@ -140,8 +148,8 @@ int audiohw_set_master_vol(int vol_l, int vol_r)
140 /* 0101111 == mute (0x2f) */ 148 /* 0101111 == mute (0x2f) */
141 149
142 /* OUT1 */ 150 /* OUT1 */
143 wmcodec_write(LOUT1VOL, vol_l); 151 wmcodec_write(LOUT1VOL, VOLUME_ZC_WAIT | vol_l);
144 wmcodec_write(ROUT1VOL, 0x100 | vol_r); 152 wmcodec_write(ROUT1VOL, VOLUME_ZC_WAIT | 0x100 | vol_r);
145 153
146 return 0; 154 return 0;
147} 155}
@@ -149,8 +157,8 @@ int audiohw_set_master_vol(int vol_l, int vol_r)
149int audiohw_set_lineout_vol(int vol_l, int vol_r) 157int audiohw_set_lineout_vol(int vol_l, int vol_r)
150{ 158{
151 /* OUT2 */ 159 /* OUT2 */
152 wmcodec_write(LOUT2VOL, vol_l); 160 wmcodec_write(LOUT2VOL, VOLUME_ZC_WAIT | vol_l);
153 wmcodec_write(ROUT2VOL, 0x100 | vol_r); 161 wmcodec_write(ROUT2VOL, VOLUME_ZC_WAIT | 0x100 | vol_r);
154 162
155 return 0; 163 return 0;
156} 164}
@@ -267,7 +275,7 @@ void audiohw_enable_recording(bool source_mic)
267 275
268 if (source_mic) { 276 if (source_mic) {
269 /* VSEL=10(def) DATSEL=10 (use right ADC only) */ 277 /* VSEL=10(def) DATSEL=10 (use right ADC only) */
270 wmcodec_write(0x17, 0xc8); /* Additional control(1) */ 278 wmcodec_write(0x17, 0xc9); /* Additional control(1) */
271 279
272 /* VROI=1 (sets output resistance to 40kohms) */ 280 /* VROI=1 (sets output resistance to 40kohms) */
273 wmcodec_write(0x1b, 0x40); /* Additional control(3) */ 281 wmcodec_write(0x1b, 0x40); /* Additional control(3) */
@@ -277,7 +285,7 @@ void audiohw_enable_recording(bool source_mic)
277 wmcodec_write(0x21, 0x60); /* ADCR signal path */ 285 wmcodec_write(0x21, 0x60); /* ADCR signal path */
278 } else { 286 } else {
279 /* VSEL=10(def) DATSEL=00 (left->left, right->right) */ 287 /* VSEL=10(def) DATSEL=00 (left->left, right->right) */
280 wmcodec_write(0x17, 0xc0); /* Additional control(1) */ 288 wmcodec_write(0x17, 0xc1); /* Additional control(1) */
281 289
282 /* VROI=1 (sets output resistance to 40kohms) */ 290 /* VROI=1 (sets output resistance to 40kohms) */
283 wmcodec_write(0x1b, 0x40); /* Additional control(3) */ 291 wmcodec_write(0x1b, 0x40); /* Additional control(3) */