diff options
Diffstat (limited to 'firmware/drivers/uda1380.c')
-rw-r--r-- | firmware/drivers/uda1380.c | 140 |
1 files changed, 104 insertions, 36 deletions
diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c index de3faddfe7..ef19dcf1c5 100644 --- a/firmware/drivers/uda1380.c +++ b/firmware/drivers/uda1380.c | |||
@@ -41,8 +41,8 @@ | |||
41 | 41 | ||
42 | int uda1380_write_reg(unsigned char reg, unsigned short value); | 42 | int uda1380_write_reg(unsigned char reg, unsigned short value); |
43 | unsigned short uda1380_regs[0x30]; | 43 | unsigned short uda1380_regs[0x30]; |
44 | short uda1380_balance; | 44 | short recgain_mic; |
45 | short uda1380_volume; | 45 | short recgain_line; |
46 | 46 | ||
47 | /* Definition of a playback configuration to start with */ | 47 | /* Definition of a playback configuration to start with */ |
48 | 48 | ||
@@ -51,13 +51,20 @@ unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] = | |||
51 | { | 51 | { |
52 | REG_0, EN_DAC | EN_INT | EN_DEC | SYSCLK_256FS | WSPLL_25_50, | 52 | REG_0, EN_DAC | EN_INT | EN_DEC | SYSCLK_256FS | WSPLL_25_50, |
53 | REG_I2S, I2S_IFMT_IIS, | 53 | REG_I2S, I2S_IFMT_IIS, |
54 | REG_PWR, PON_BIAS, /* PON_HP & PON_DAC is enabled later */ | 54 | REG_PWR, PON_BIAS, |
55 | REG_AMIX, AMIX_RIGHT(0x3f) | AMIX_LEFT(0x3f), /* 00=max, 3f=mute */ | 55 | /* PON_HP & PON_DAC is enabled later */ |
56 | REG_MASTER_VOL, MASTER_VOL_LEFT(0x20) | MASTER_VOL_RIGHT(0x20), /* 00=max, ff=mute */ | 56 | REG_AMIX, AMIX_RIGHT(0x3f) | AMIX_LEFT(0x3f), |
57 | REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff), /* 00=max, ff=mute */ | 57 | /* 00=max, 3f=mute */ |
58 | REG_EQ, EQ_MODE_MAX, /* Bass and tremble = 0 dB */ | 58 | REG_MASTER_VOL, MASTER_VOL_LEFT(0x20) | MASTER_VOL_RIGHT(0x20), |
59 | REG_MUTE, MUTE_MASTER | MUTE_CH2, /* Mute everything to start with */ | 59 | /* 00=max, ff=mute */ |
60 | REG_MIX_CTL, MIX_CTL_MIX, /* Enable mixer */ | 60 | REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff), |
61 | /* 00=max, ff=mute */ | ||
62 | REG_EQ, EQ_MODE_MAX, | ||
63 | /* Bass and tremble = 0 dB */ | ||
64 | REG_MUTE, MUTE_MASTER | MUTE_CH2, | ||
65 | /* Mute everything to start with */ | ||
66 | REG_MIX_CTL, MIX_CTL_MIX, | ||
67 | /* Enable mixer */ | ||
61 | REG_DEC_VOL, 0, | 68 | REG_DEC_VOL, 0, |
62 | REG_PGA, MUTE_ADC, | 69 | REG_PGA, MUTE_ADC, |
63 | REG_ADC, SKIP_DCFIL, | 70 | REG_ADC, SKIP_DCFIL, |
@@ -110,7 +117,8 @@ int uda1380_set_mixer_vol(int channel1, int channel2) | |||
110 | */ | 117 | */ |
111 | void uda1380_set_bass(int value) | 118 | void uda1380_set_bass(int value) |
112 | { | 119 | { |
113 | uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~BASS_MASK) | BASSL(value) | BASSR(value)); | 120 | uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~BASS_MASK) |
121 | | BASSL(value) | BASSR(value)); | ||
114 | } | 122 | } |
115 | 123 | ||
116 | /** | 124 | /** |
@@ -118,7 +126,8 @@ void uda1380_set_bass(int value) | |||
118 | */ | 126 | */ |
119 | void uda1380_set_treble(int value) | 127 | void uda1380_set_treble(int value) |
120 | { | 128 | { |
121 | uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~TREBLE_MASK) | TREBLEL(value) | TREBLER(value)); | 129 | uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~TREBLE_MASK) |
130 | | TREBLEL(value) | TREBLER(value)); | ||
122 | } | 131 | } |
123 | 132 | ||
124 | /** | 133 | /** |
@@ -187,12 +196,13 @@ void uda1380_reset(void) | |||
187 | /* Initialize UDA1380 codec with default register values (uda1380_defaults) */ | 196 | /* Initialize UDA1380 codec with default register values (uda1380_defaults) */ |
188 | int uda1380_init(void) | 197 | int uda1380_init(void) |
189 | { | 198 | { |
199 | recgain_mic = 0; | ||
200 | recgain_line = 0; | ||
201 | |||
190 | uda1380_reset(); | 202 | uda1380_reset(); |
191 | 203 | ||
192 | if (uda1380_set_regs() == -1) | 204 | if (uda1380_set_regs() == -1) |
193 | return -1; | 205 | return -1; |
194 | uda1380_balance = 0; | ||
195 | uda1380_volume = 0x20; /* Taken from uda1380_defaults */ | ||
196 | 206 | ||
197 | return 0; | 207 | return 0; |
198 | } | 208 | } |
@@ -222,14 +232,19 @@ void uda1380_enable_recording(bool source_mic) | |||
222 | 232 | ||
223 | if (source_mic) | 233 | if (source_mic) |
224 | { | 234 | { |
235 | /* VGA_GAIN: 0=0 dB, F=30dB */ | ||
225 | uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_LNA | PON_ADCL); | 236 | uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_LNA | PON_ADCL); |
226 | uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & VGA_GAIN_MASK) | SEL_LNA | SEL_MIC | EN_DCFIL); /* VGA_GAIN: 0=0 dB, F=30dB */ | 237 | uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & VGA_GAIN_MASK) |
238 | | SEL_LNA | SEL_MIC | EN_DCFIL); | ||
227 | uda1380_write_reg(REG_PGA, 0); | 239 | uda1380_write_reg(REG_PGA, 0); |
228 | } else | 240 | } else |
229 | { | 241 | { |
230 | uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_PGAL | PON_ADCL | PON_PGAR | PON_ADCR); | 242 | /* PGA_GAIN: 0=0 dB, F=24dB */ |
243 | uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_PGAL | PON_ADCL | ||
244 | | PON_PGAR | PON_ADCR); | ||
231 | uda1380_write_reg(REG_ADC, EN_DCFIL); | 245 | uda1380_write_reg(REG_ADC, EN_DCFIL); |
232 | uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & PGA_GAIN_MASK) | PGA_GAINL(0) | PGA_GAINR(0)); /* PGA_GAIN: 0=0 dB, F=24dB */ | 246 | uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & PGA_GAIN_MASK) |
247 | | PGA_GAINL(0) | PGA_GAINR(0)); | ||
233 | } | 248 | } |
234 | 249 | ||
235 | sleep(HZ/8); | 250 | sleep(HZ/8); |
@@ -248,7 +263,9 @@ void uda1380_disable_recording(void) | |||
248 | sleep(HZ/8); | 263 | sleep(HZ/8); |
249 | 264 | ||
250 | uda1380_write_reg(REG_I2S, I2S_IFMT_IIS); | 265 | uda1380_write_reg(REG_I2S, I2S_IFMT_IIS); |
251 | uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] & ~(PON_LNA | PON_ADCL | PON_ADCR | PON_PGAL | PON_PGAR)); | 266 | uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] & ~(PON_LNA | PON_ADCL |
267 | | PON_ADCR | PON_PGAL | ||
268 | | PON_PGAR)); | ||
252 | uda1380_write_reg(REG_0, uda1380_regs[REG_0] & ~EN_ADC); | 269 | uda1380_write_reg(REG_0, uda1380_regs[REG_0] & ~EN_ADC); |
253 | uda1380_write_reg(REG_ADC, SKIP_DCFIL); | 270 | uda1380_write_reg(REG_ADC, SKIP_DCFIL); |
254 | } | 271 | } |
@@ -260,41 +277,89 @@ void uda1380_disable_recording(void) | |||
260 | * AUDIO_GAIN_MIC: left -128 .. 108 -> -64 .. 54 dB gain | 277 | * AUDIO_GAIN_MIC: left -128 .. 108 -> -64 .. 54 dB gain |
261 | * AUDIO_GAIN_LINEIN left & right -128 .. 96 -> -64 .. 48 dB gain | 278 | * AUDIO_GAIN_LINEIN left & right -128 .. 96 -> -64 .. 48 dB gain |
262 | * | 279 | * |
263 | * Note: For all types the value 0 gives 0 dB gain. | 280 | * Note: - For all types the value 0 gives 0 dB gain. |
281 | * - order of setting both values determines if the small glitch will | ||
282 | be a peak or a dip. The small glitch is caused by the time between | ||
283 | setting the two gains | ||
264 | */ | 284 | */ |
265 | void uda1380_set_recvol(int left, int right, int type) | 285 | void uda1380_set_recvol(int left, int right, int type) |
266 | { | 286 | { |
267 | int left_ag, right_ag; | 287 | int left_ag, right_ag; |
268 | /*int old_irq_level;*/ | ||
269 | 288 | ||
270 | switch (type) | 289 | switch (type) |
271 | { | 290 | { |
272 | case AUDIO_GAIN_MIC: | 291 | case AUDIO_GAIN_MIC: |
273 | left_ag = MIN(MAX(0, left / 4), 15); | 292 | left_ag = MIN(MAX(0, left / 4), 15); |
274 | left -= left_ag * 4; | 293 | left -= left_ag * 4; |
275 | /* allow nothing in between the two calls */ | 294 | |
276 | /*old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);*/ | 295 | if(left < recgain_mic) |
277 | uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & ~VGA_GAIN_MASK) | 296 | { |
278 | | VGA_GAIN(left_ag)); | 297 | uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) |
279 | uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | DEC_VOLR(left)); | 298 | | DEC_VOLR(left)); |
280 | /*set_irq_level(old_irq_level);*/ | 299 | uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] |
300 | & ~VGA_GAIN_MASK) | ||
301 | | VGA_GAIN(left_ag)); | ||
302 | } | ||
303 | else | ||
304 | { | ||
305 | uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] | ||
306 | & ~VGA_GAIN_MASK) | ||
307 | | VGA_GAIN(left_ag)); | ||
308 | uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | ||
309 | | DEC_VOLR(left)); | ||
310 | } | ||
311 | recgain_mic = left; | ||
281 | logf("Mic: %dA/%dD", left_ag, left); | 312 | logf("Mic: %dA/%dD", left_ag, left); |
282 | break; | 313 | break; |
283 | 314 | ||
284 | case AUDIO_GAIN_LINEIN: | 315 | case AUDIO_GAIN_LINEIN: |
285 | left_ag = MIN(MAX(0, left / 6), 8); | 316 | left_ag = MIN(MAX(0, left / 6), 8); |
286 | left -= left_ag * 6; | 317 | left -= left_ag * 6; |
287 | right_ag = MIN(MAX(0, right / 6), 8); | 318 | right_ag = MIN(MAX(0, right / 6), 8); |
288 | right -= right_ag * 6; | 319 | right -= right_ag * 6; |
289 | /* allow nothing in between the two calls */ | 320 | |
290 | /*old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);*/ | 321 | if(left < recgain_line) |
291 | uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK) | 322 | { |
292 | | PGA_GAINL(left_ag) | PGA_GAINR(right_ag)); | 323 | /* for this order we can combine both registers, |
293 | uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | DEC_VOLR(right)); | 324 | making the glitch even smaller */ |
294 | /*set_irq_level(old_irq_level);*/ | 325 | unsigned char data[6]; |
326 | unsigned short value_dec; | ||
327 | unsigned short value_pga; | ||
328 | value_dec = DEC_VOLL(left) | DEC_VOLR(right); | ||
329 | value_pga = (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK) | ||
330 | | PGA_GAINL(left_ag) | PGA_GAINR(right_ag); | ||
331 | |||
332 | data[0] = UDA1380_ADDR; | ||
333 | data[1] = REG_DEC_VOL; | ||
334 | data[2] = value_dec >> 8; | ||
335 | data[3] = value_dec & 0xff; | ||
336 | data[4] = value_pga >> 8; | ||
337 | data[5] = value_pga & 0xff; | ||
338 | |||
339 | if (i2c_write(1, data, 6) != 6) | ||
340 | { | ||
341 | DEBUGF("uda1380 error reg=combi rec gain"); | ||
342 | } | ||
343 | else | ||
344 | { | ||
345 | uda1380_regs[REG_DEC_VOL] = value_dec; | ||
346 | uda1380_regs[REG_PGA] = value_pga; | ||
347 | } | ||
348 | } | ||
349 | else | ||
350 | { | ||
351 | uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] | ||
352 | & ~PGA_GAIN_MASK) | ||
353 | | PGA_GAINL(left_ag) | ||
354 | | PGA_GAINR(right_ag)); | ||
355 | uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | ||
356 | | DEC_VOLR(right)); | ||
357 | } | ||
358 | |||
359 | recgain_line = left; | ||
295 | logf("Line L: %dA/%dD", left_ag, left); | 360 | logf("Line L: %dA/%dD", left_ag, left); |
296 | logf("Line R: %dA/%dD", right_ag, right); | 361 | logf("Line R: %dA/%dD", right_ag, right); |
297 | break; | 362 | break; |
298 | } | 363 | } |
299 | } | 364 | } |
300 | 365 | ||
@@ -311,16 +376,19 @@ void uda1380_set_monitor(int enable) | |||
311 | uda1380_write_reg(REG_MUTE, uda1380_regs[REG_MUTE] | MUTE_CH2); | 376 | uda1380_write_reg(REG_MUTE, uda1380_regs[REG_MUTE] | MUTE_CH2); |
312 | } | 377 | } |
313 | 378 | ||
314 | /* Change the order of the noise chaper, 5th order is recommended above 32kHz */ | 379 | /* Change the order of the noise chaper, |
380 | 5th order is recommended above 32kHz */ | ||
315 | void uda1380_set_nsorder(int order) | 381 | void uda1380_set_nsorder(int order) |
316 | { | 382 | { |
317 | switch(order) | 383 | switch(order) |
318 | { | 384 | { |
319 | case 5: | 385 | case 5: |
320 | uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] | MIX_CTL_SEL_NS); | 386 | uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] |
387 | | MIX_CTL_SEL_NS); | ||
321 | break; | 388 | break; |
322 | case 3: | 389 | case 3: |
323 | default: | 390 | default: |
324 | uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] & ~MIX_CTL_SEL_NS); | 391 | uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] |
392 | & ~MIX_CTL_SEL_NS); | ||
325 | } | 393 | } |
326 | } | 394 | } |