1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
27 /* Register addresses as per datasheet Rev.4.4 */
35 #define SRATECTRL 0x07
37 #define JACKDETECT0 0x09
41 #define JACKDETECT1 0x0d
45 #define RDACVOL_DACVU 0x100
52 #define EQ_GAIN_MASK 0x001f
53 #define EQ_CUTOFF_MASK 0x0060
54 #define EQ_GAIN_VALUE(x) (((-x) + 12) & 0x1f)
55 #define EQ_CUTOFF_VALUE(x) ((((x) - 1) & 0x03) << 5)
57 #define CLASSDCTL 0x17
58 #define DACLIMIT1 0x18
59 #define DACLIMIT2 0x19
67 #define NOISEGATE 0x23
72 #define THREEDCTL 0x29
76 #define LINPGAGAIN 0x2d
77 #define RINPGAGAIN 0x2e
78 #define LADCBOOST 0x2f
79 #define RADCBOOST 0x30
91 const struct sound_settings_info audiohw_settings
[] = {
92 [SOUND_VOLUME
] = {"dB", 0, 1, -90, 6, -25},
93 [SOUND_BASS
] = {"dB", 0, 1, -12, 12, 0},
94 [SOUND_TREBLE
] = {"dB", 0, 1, -12, 12, 0},
95 [SOUND_BALANCE
] = {"%", 0, 1,-100, 100, 0},
96 [SOUND_CHANNELS
] = {"", 0, 1, 0, 5, 0},
97 [SOUND_STEREO_WIDTH
] = {"%", 0, 5, 0, 250, 100},
99 [SOUND_LEFT_GAIN
] = {"dB", 1, 1,-128, 96, 0},
100 [SOUND_RIGHT_GAIN
] = {"dB", 1, 1,-128, 96, 0},
101 [SOUND_MIC_GAIN
] = {"dB", 1, 1,-128, 108, 16},
103 #ifdef AUDIOHW_HAVE_BASS_CUTOFF
104 [SOUND_BASS_CUTOFF
] = {"", 0, 1, 1, 4, 1},
106 #ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
107 [SOUND_TREBLE_CUTOFF
] = {"", 0, 1, 1, 4, 1},
111 /* shadow registers */
112 unsigned int eq1_reg
;
113 unsigned int eq5_reg
;
115 /* convert tenth of dB volume (-89..6) to master volume register value */
116 int tenthdb2master(int db
)
118 /* Might have no sense, taken from wm8758.c :
127 if (db
< VOLUME_MIN
) {
130 return (db
-VOLUME_MIN
)/10 + 1;
134 /* helper function coming from wm8758.c that calculates the register setting for amplifier and
135 DAC volume out of the input from tenthdb2master() */
136 static void get_volume_params(int db
, int *dac
, int *amp
)
138 /* should never happen, set max volume for amp and dac */
143 /* set dac to max and set volume for amp (better snr) */
148 /* set amp to min and reduce dac output */
150 *dac
= (db
-33)*2 + 255;
160 /* Silently enable / disable audio output */
161 void audiohw_preinit(void)
163 wmcodec_write(RESET
, 0x1ff); /* Reset */
165 wmcodec_write(BIASCTL
, 0x100); /* BIASCUT = 1 */
166 wmcodec_write(OUTCTRL
, 0x6); /* Thermal shutdown */
168 wmcodec_write(PWRMGMT1
, 0x8); /* BIASEN = 1 */
170 /* Volume zero, mute all outputs */
171 wmcodec_write(LOUT1VOL
, 0x140);
172 wmcodec_write(ROUT1VOL
, 0x140);
173 wmcodec_write(LOUT2VOL
, 0x140);
174 wmcodec_write(ROUT2VOL
, 0x140);
175 wmcodec_write(OUT3MIX
, 0x40);
176 wmcodec_write(OUT4MIX
, 0x40);
178 /* DAC softmute, automute, 128OSR */
179 wmcodec_write(DACCTRL
, 0x4c);
181 wmcodec_write(OUT4ADC
, 0x2); /* POBCTRL = 1 */
183 /* Enable output, DAC and mixer */
184 wmcodec_write(PWRMGMT3
, 0x6f);
185 wmcodec_write(PWRMGMT2
, 0x180);
186 wmcodec_write(PWRMGMT1
, 0xd);
187 wmcodec_write(LOUTMIX
, 0x1);
188 wmcodec_write(ROUTMIX
, 0x1);
190 /* Disable clock since we're acting as slave to the SoC */
191 wmcodec_write(CLKGEN
, 0x0);
192 wmcodec_write(AINTFCE
, 0x10); /* 16-bit, I2S format */
194 wmcodec_write(LDACVOL
, 0x1ff); /* Full DAC digital vol */
195 wmcodec_write(RDACVOL
, 0x1ff);
197 wmcodec_write(OUT4ADC
, 0x0); /* POBCTRL = 0 */
200 static void audiohw_mute(bool mute
)
204 /* Set DACMU = 1 to soft-mute the audio DACs. */
205 wmcodec_write(DACCTRL
, 0x4c);
207 /* Set DACMU = 0 to soft-un-mute the audio DACs. */
208 wmcodec_write(DACCTRL
, 0xc);
212 void audiohw_postinit(void)
219 void audiohw_set_headphone_vol(int vol_l
, int vol_r
)
221 int dac_l
, amp_l
, dac_r
, amp_r
;
222 get_volume_params(vol_l
, &dac_l
, &_l
);
223 get_volume_params(vol_r
, &dac_r
, &_r
);
226 Important: DAC is global and will also affect lineout */
227 wmcodec_write(LDACVOL
, dac_l
);
228 wmcodec_write(RDACVOL
, dac_r
| RDACVOL_DACVU
);
230 /* set headphone amp OUT1 */
231 wmcodec_write(LOUT1VOL
, amp_l
| 0x080);
232 wmcodec_write(ROUT1VOL
, amp_r
| 0x180);
235 void audiohw_set_lineout_vol(int vol_l
, int vol_r
)
237 int dac_l
, amp_l
, dac_r
, amp_r
;
238 get_volume_params(vol_l
, &dac_l
, &_l
);
239 get_volume_params(vol_r
, &dac_r
, &_r
);
241 /* set lineout amp OUT2 */
242 wmcodec_write(LOUT2VOL
, amp_l
);
243 wmcodec_write(ROUT2VOL
, amp_r
| 0x100);
246 void audiohw_set_aux_vol(int vol_l
, int vol_r
)
249 wmcodec_write(LOUTMIX
, 0x111 | (vol_l
<< 5) );
250 wmcodec_write(ROUTMIX
, 0x111 | (vol_r
<< 5) );
253 void audiohw_set_bass(int value
)
255 eq1_reg
= (eq1_reg
& ~EQ_GAIN_MASK
) | EQ_GAIN_VALUE(value
);
256 wmcodec_write(EQ1
, 0x100 | eq1_reg
);
259 void audiohw_set_bass_cutoff(int value
)
261 eq1_reg
= (eq1_reg
& ~EQ_CUTOFF_MASK
) | EQ_CUTOFF_VALUE(value
);
262 wmcodec_write(EQ1
, 0x100 | eq1_reg
);
265 void audiohw_set_treble(int value
)
267 eq5_reg
= (eq5_reg
& ~EQ_GAIN_MASK
) | EQ_GAIN_VALUE(value
);
268 wmcodec_write(EQ5
, eq5_reg
);
271 void audiohw_set_treble_cutoff(int value
)
273 eq5_reg
= (eq5_reg
& ~EQ_CUTOFF_MASK
) | EQ_CUTOFF_VALUE(value
);
274 wmcodec_write(EQ5
, eq5_reg
);
277 /* Nice shutdown of WM8985 codec */
278 void audiohw_close(void)
282 wmcodec_write(PWRMGMT3
, 0x0);
284 wmcodec_write(PWRMGMT1
, 0x0);
286 wmcodec_write(PWRMGMT2
, 0x40);
289 /* Note: Disable output before calling this function */
290 void audiohw_set_sample_rate(int fsel
)
292 /* Currently the WM8985 acts as slave to the SoC I2S controller, so no
293 setup is needed here. This seems to be in contrast to every other WM
294 driver in Rockbox, so this may need to change in the future. */
298 #ifdef HAVE_RECORDING
299 void audiohw_enable_recording(bool source_mic
)
301 (void)source_mic
; /* We only have a line-in (I think) */
303 wmcodec_write(RESET
, 0x1ff); /*Reset*/
305 wmcodec_write(PWRMGMT1
, 0x2b);
306 wmcodec_write(PWRMGMT2
, 0x18f); /* Enable ADC - 0x0c enables left/right PGA input, and 0x03 turns on power to the ADCs */
307 wmcodec_write(PWRMGMT3
, 0x6f);
309 wmcodec_write(AINTFCE
, 0x10);
310 wmcodec_write(CLKCTRL
, 0x49);
312 wmcodec_write(OUTCTRL
, 1);
314 /* The iPod can handle multiple frequencies, but fix at 44.1KHz
316 audiohw_set_frequency(HW_FREQ_DEFAULT
);
318 wmcodec_write(INCTRL
,0x44); /* Connect L2 and R2 inputs */
320 /* Set L2/R2_2BOOSTVOL to 0db (bits 4-6) */
330 wmcodec_write(LADCBOOST
,0x50);
331 wmcodec_write(RADCBOOST
,0x50);
333 /* Set L/R input PGA Volume to 0db */
334 // wm8758_write(LINPGAVOL,0x3f);
335 // wm8758_write(RINPGAVOL,0x13f);
337 /* Enable monitoring */
338 wmcodec_write(LOUTMIX
,0x17); /* Enable output mixer - BYPL2LMIX @ 0db*/
339 wmcodec_write(ROUTMIX
,0x17); /* Enable output mixer - BYPR2RMIX @ 0db*/
344 void audiohw_disable_recording(void) {
347 wmcodec_write(PWRMGMT3
, 0x0);
349 wmcodec_write(PWRMGMT1
, 0x0);
351 wmcodec_write(PWRMGMT2
, 0x40);
354 void audiohw_set_recvol(int left
, int right
, int type
) {
361 void audiohw_set_monitor(bool enable
) {
365 #endif /* HAVE_RECORDING */