/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2005 by Andy Young * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "lcd.h" #include "cpu.h" #include "kernel.h" #include "thread.h" #include "power.h" #include "debug.h" #include "system.h" #include "sprintf.h" #include "button.h" #include "string.h" #include "file.h" #include "buffer.h" #include "audio.h" #include "logf.h" #include "i2c-coldfire.h" #include "uda1380.h" #include "pcf50606.h" /* ------------------------------------------------- */ /* Local functions and variables */ /* ------------------------------------------------- */ int uda1380_write_reg(unsigned char reg, unsigned short value); unsigned short uda1380_regs[0x30]; short recgain_mic; short recgain_line; /* Definition of a playback configuration to start with */ #define NUM_DEFAULT_REGS 13 unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] = { REG_0, EN_DAC | EN_INT | EN_DEC | SYSCLK_256FS | WSPLL_25_50, REG_I2S, I2S_IFMT_IIS, REG_PWR, PON_BIAS, /* PON_HP & PON_DAC is enabled later */ REG_AMIX, AMIX_RIGHT(0x3f) | AMIX_LEFT(0x3f), /* 00=max, 3f=mute */ REG_MASTER_VOL, MASTER_VOL_LEFT(0x20) | MASTER_VOL_RIGHT(0x20), /* 00=max, ff=mute */ REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff), /* 00=max, ff=mute */ REG_EQ, EQ_MODE_MAX, /* Bass and tremble = 0 dB */ REG_MUTE, MUTE_MASTER | MUTE_CH2, /* Mute everything to start with */ REG_MIX_CTL, MIX_CTL_MIX, /* Enable mixer */ REG_DEC_VOL, 0, REG_PGA, MUTE_ADC, REG_ADC, SKIP_DCFIL, REG_AGC, 0 }; /* Returns 0 if register was written or -1 if write failed */ int uda1380_write_reg(unsigned char reg, unsigned short value) { unsigned char data[4]; data[0] = UDA1380_ADDR; data[1] = reg; data[2] = value >> 8; data[3] = value & 0xff; if (i2c_write(1, data, 4) != 4) { DEBUGF("uda1380 error reg=0x%x", reg); return -1; } uda1380_regs[reg] = value; return 0; } /** * Sets left and right master volume (0(max) to 252(muted)) */ int uda1380_set_master_vol(int vol_l, int vol_r) { return uda1380_write_reg(REG_MASTER_VOL, MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); } /** * Sets mixer volume for both channels (0(max) to 228(muted)) */ int uda1380_set_mixer_vol(int channel1, int channel2) { return uda1380_write_reg(REG_MIX_VOL, MIX_VOL_CH_1(channel1) | MIX_VOL_CH_2(channel2)); } /** * Sets the bass value (0-12) */ void uda1380_set_bass(int value) { uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~BASS_MASK) | BASSL(value) | BASSR(value)); } /** * Sets the treble value (0-3) */ void uda1380_set_treble(int value) { uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~TREBLE_MASK) | TREBLEL(value) | TREBLER(value)); } /** * Mute (mute=1) or enable sound (mute=0) * */ int uda1380_mute(int mute) { unsigned int value = uda1380_regs[REG_MUTE]; if (mute) value = value | MUTE_MASTER; else value = value & ~MUTE_MASTER; return uda1380_write_reg(REG_MUTE, value); } /* Returns 0 if successful or -1 if some register failed */ int uda1380_set_regs(void) { int i; memset(uda1380_regs, 0, sizeof(uda1380_regs)); /* Initialize all registers */ for (i=0; i -64 .. 54 dB gain * AUDIO_GAIN_LINEIN left & right -128 .. 96 -> -64 .. 48 dB gain * * Note: - For all types the value 0 gives 0 dB gain. * - order of setting both values determines if the small glitch will be a peak or a dip. The small glitch is caused by the time between setting the two gains */ void uda1380_set_recvol(int left, int right, int type) { int left_ag, right_ag; switch (type) { case AUDIO_GAIN_MIC: left_ag = MIN(MAX(0, left / 4), 15); left -= left_ag * 4; if(left < recgain_mic) { uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | DEC_VOLR(left)); uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & ~VGA_GAIN_MASK) | VGA_GAIN(left_ag)); } else { uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & ~VGA_GAIN_MASK) | VGA_GAIN(left_ag)); uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | DEC_VOLR(left)); } recgain_mic = left; logf("Mic: %dA/%dD", left_ag, left); break; case AUDIO_GAIN_LINEIN: left_ag = MIN(MAX(0, left / 6), 8); left -= left_ag * 6; right_ag = MIN(MAX(0, right / 6), 8); right -= right_ag * 6; if(left < recgain_line) { /* for this order we can combine both registers, making the glitch even smaller */ unsigned char data[6]; unsigned short value_dec; unsigned short value_pga; value_dec = DEC_VOLL(left) | DEC_VOLR(right); value_pga = (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK) | PGA_GAINL(left_ag) | PGA_GAINR(right_ag); data[0] = UDA1380_ADDR; data[1] = REG_DEC_VOL; data[2] = value_dec >> 8; data[3] = value_dec & 0xff; data[4] = value_pga >> 8; data[5] = value_pga & 0xff; if (i2c_write(1, data, 6) != 6) { DEBUGF("uda1380 error reg=combi rec gain"); } else { uda1380_regs[REG_DEC_VOL] = value_dec; uda1380_regs[REG_PGA] = value_pga; } } else { uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK) | PGA_GAINL(left_ag) | PGA_GAINR(right_ag)); uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | DEC_VOLR(right)); } recgain_line = left; logf("Line L: %dA/%dD", left_ag, left); logf("Line R: %dA/%dD", right_ag, right); break; } } /** * Enable or disable recording monitor (so one can listen to the recording) * */ void uda1380_set_monitor(int enable) { if (enable) /* enable channel 2 */ uda1380_write_reg(REG_MUTE, uda1380_regs[REG_MUTE] & ~MUTE_CH2); else /* mute channel 2 */ uda1380_write_reg(REG_MUTE, uda1380_regs[REG_MUTE] | MUTE_CH2); } /* Change the order of the noise chaper, 5th order is recommended above 32kHz */ void uda1380_set_nsorder(int order) { switch(order) { case 5: uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] | MIX_CTL_SEL_NS); break; case 3: default: uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] & ~MIX_CTL_SEL_NS); } }