summaryrefslogtreecommitdiff
path: root/firmware/drivers/wm8975.c
diff options
context:
space:
mode:
authorSteve Gotthardt <gotthardt@rockbox.org>2007-01-13 23:57:19 +0000
committerSteve Gotthardt <gotthardt@rockbox.org>2007-01-13 23:57:19 +0000
commitd4afc4b9b917dd98ab8dc5bf8e1487c62170852d (patch)
tree02e9ee3657a417cc02310febbfdc224b495ef203 /firmware/drivers/wm8975.c
parent1010b76c72a560e50243f6805e70fe091fd2fb1c (diff)
downloadrockbox-d4afc4b9b917dd98ab8dc5bf8e1487c62170852d.tar.gz
rockbox-d4afc4b9b917dd98ab8dc5bf8e1487c62170852d.zip
Added zero crossing check before changing volume to avoid noise during volume changes. Removed extra volume sets. Added delay for vref to settle per app notes to reduce start up clicks.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12001 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/wm8975.c')
-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) */