diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/wm8975.c | 28 |
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 */ |
45 | int tenthdb2master(int db) | 50 | int 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 | |||
134 | int audiohw_set_master_vol(int vol_l, int vol_r) | 142 | int 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) | |||
149 | int audiohw_set_lineout_vol(int vol_l, int vol_r) | 157 | int 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) */ |