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 static unsigned int eq1_reg
;
113 static 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 #ifdef AUDIOHW_HAVE_BASS
254 void audiohw_set_bass(int value
)
256 eq1_reg
= (eq1_reg
& ~EQ_GAIN_MASK
) | EQ_GAIN_VALUE(value
);
257 wmcodec_write(EQ1
, 0x100 | eq1_reg
);
259 #endif /* AUDIOHW_HAVE_BASS */
261 #ifdef AUDIOHW_HAVE_BASS_CUTOFF
262 void audiohw_set_bass_cutoff(int value
)
264 eq1_reg
= (eq1_reg
& ~EQ_CUTOFF_MASK
) | EQ_CUTOFF_VALUE(value
);
265 wmcodec_write(EQ1
, 0x100 | eq1_reg
);
267 #endif /* AUDIOHW_HAVE_BASS_CUTOFF */
269 #ifdef AUDIOHW_HAVE_TREBLE
270 void audiohw_set_treble(int value
)
272 eq5_reg
= (eq5_reg
& ~EQ_GAIN_MASK
) | EQ_GAIN_VALUE(value
);
273 wmcodec_write(EQ5
, eq5_reg
);
275 #endif /* AUDIOHW_HAVE_TREBLE */
277 #ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
278 void audiohw_set_treble_cutoff(int value
)
280 eq5_reg
= (eq5_reg
& ~EQ_CUTOFF_MASK
) | EQ_CUTOFF_VALUE(value
);
281 wmcodec_write(EQ5
, eq5_reg
);
283 #endif /* AUDIOHW_HAVE_TREBLE_CUTOFF */
285 /* Nice shutdown of WM8985 codec */
286 void audiohw_close(void)
290 wmcodec_write(PWRMGMT3
, 0x0);
292 wmcodec_write(PWRMGMT1
, 0x0);
294 wmcodec_write(PWRMGMT2
, 0x40);
297 #if 0 /* function is currently unused */
298 /* Note: Disable output before calling this function */
299 void audiohw_set_sample_rate(int fsel
)
301 /* Currently the WM8985 acts as slave to the SoC I2S controller, so no
302 setup is needed here. This seems to be in contrast to every other WM
303 driver in Rockbox, so this may need to change in the future. */
308 #ifdef HAVE_RECORDING
309 void audiohw_enable_recording(bool source_mic
)
311 (void)source_mic
; /* We only have a line-in (I think) */
313 wmcodec_write(RESET
, 0x1ff); /*Reset*/
315 wmcodec_write(PWRMGMT1
, 0x2b);
316 wmcodec_write(PWRMGMT2
, 0x18f); /* Enable ADC - 0x0c enables left/right PGA input, and 0x03 turns on power to the ADCs */
317 wmcodec_write(PWRMGMT3
, 0x6f);
319 wmcodec_write(AINTFCE
, 0x10);
320 wmcodec_write(CLKCTRL
, 0x49);
322 wmcodec_write(OUTCTRL
, 1);
324 /* The iPod can handle multiple frequencies, but fix at 44.1KHz
326 audiohw_set_frequency(HW_FREQ_DEFAULT
);
328 wmcodec_write(INCTRL
,0x44); /* Connect L2 and R2 inputs */
330 /* Set L2/R2_2BOOSTVOL to 0db (bits 4-6) */
340 wmcodec_write(LADCBOOST
,0x50);
341 wmcodec_write(RADCBOOST
,0x50);
343 /* Set L/R input PGA Volume to 0db */
344 // wm8758_write(LINPGAVOL,0x3f);
345 // wm8758_write(RINPGAVOL,0x13f);
347 /* Enable monitoring */
348 wmcodec_write(LOUTMIX
,0x17); /* Enable output mixer - BYPL2LMIX @ 0db*/
349 wmcodec_write(ROUTMIX
,0x17); /* Enable output mixer - BYPR2RMIX @ 0db*/
354 void audiohw_disable_recording(void) {
357 wmcodec_write(PWRMGMT3
, 0x0);
359 wmcodec_write(PWRMGMT1
, 0x0);
361 wmcodec_write(PWRMGMT2
, 0x40);
364 void audiohw_set_recvol(int left
, int right
, int type
) {
371 void audiohw_set_monitor(bool enable
) {
375 #endif /* HAVE_RECORDING */