From 4af26e7e98b6d4b2e1c94a54ad7ca02d55bb04cc Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Wed, 5 Nov 2008 00:24:46 +0000 Subject: Onda VX747: * Commit (premature) SD, USB & audio drivers * Fix ramdisk.c mistake * Add battery readout git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19011 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/mips/ingenic_jz47xx/codec-jz4740.c | 280 +++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 firmware/target/mips/ingenic_jz47xx/codec-jz4740.c (limited to 'firmware/target/mips/ingenic_jz47xx/codec-jz4740.c') diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c new file mode 100644 index 0000000000..6c3ed8cf2a --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c @@ -0,0 +1,280 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Maurus Cuelenaere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "jz4740.h" + +static unsigned short codec_volume; +static unsigned short codec_base_gain; +static unsigned short codec_mic_gain; +static bool HP_on_off_flag; +static int HP_register_value; +static int IS_WRITE_PCM; + +static void i2s_codec_clear(void) +{ + REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL | + ICDC_CDCCR1_VRCGH | ICDC_CDCCR1_HPOV0 | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP | + ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); +} + +static void i2s_codec_init(void) +{ + __aic_select_i2s(); + __i2s_internal_codec(); + + __aic_enable(); + + __i2s_set_oss_sample_size(16); + + REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL | + ICDC_CDCCR1_VRCGH | ICDC_CDCCR1_HPOV0 | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP | + ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); /* reset */ + udelay(10); + REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL | + ICDC_CDCCR1_VRCGH | ICDC_CDCCR1_HPOV0 | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP | + ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); + //REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(ICDC_CDCCR2_AINVOL_DB(0)) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) | + REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) | + ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_6)); + HP_on_off_flag = 0; /* HP is off */ +} + +static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */ +{ + v = v & 0xff; + if(v < 0) + v = 0; + if(v > 100) + v = 100; + codec_mic_gain = 31 * v/100; + + REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x1f << 16)) | (codec_mic_gain << 16)); +} + +static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */ +{ + v = v & 0xff; + if(v < 0) + v = 0; + if(v > 100) + v = 100; + + if(v < 25) + codec_base_gain = 0; + if(v >= 25 && v < 50) + codec_base_gain = 1; + if(v >= 50 && v < 75) + codec_base_gain = 2; + if(v >= 75 && v <= 100) + codec_base_gain = 3; + + REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x3 << 4)) | (codec_base_gain << 4)); +} + +static void i2s_codec_set_volume(unsigned short v) /* 0 <= v <= 100 */ +{ + v = v & 0xff; + if(v < 0) + v = 0; + if(v > 100) + v = 100; + + if(v < 25) + codec_volume = 0; + if(v >= 25 && v < 50) + codec_volume = 1; + if(v >= 50 && v < 75) + codec_volume = 2; + if(v >= 75 && v <= 100) + codec_volume = 3; + + REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x3)) | codec_volume); +} + +static unsigned short i2s_codec_get_bass(void) +{ + unsigned short val; + int ret; + if(codec_base_gain == 0) + val = 0; + if(codec_base_gain == 1) + val = 25; + if(codec_base_gain == 2) + val = 50; + if(codec_base_gain == 3) + val = 75; + + ret = val << 8; + val = val | ret; +} + +static unsigned short i2s_codec_get_mic(void) +{ + unsigned short val; + int ret; + val = 100 * codec_mic_gain / 31; + ret = val << 8; + val = val | ret; +} + +static unsigned short i2s_codec_get_volume(void) +{ + unsigned short val; + int ret; + + if(codec_volume == 0) + val = 0; + if(codec_volume == 1) + val = 25; + if(codec_volume == 2) + val = 50; + if(codec_volume == 3) + val = 75; + + ret = val << 8; + val = val | ret; + return val; +} + +static void i2s_codec_set_samplerate(unsigned short rate) +{ + unsigned short speed = 0; + unsigned short val = 0; + + switch (rate) + { + case 8000: + speed = 0; + break; + case 11025: + speed = 1; + break; + case 12000: + speed = 2; + break; + case 16000: + speed = 3; + break; + case 22050: + speed = 4; + break; + case 24000: + speed = 5; + break; + case 32000: + speed = 6; + break; + case 44100: + speed = 7; + break; + case 48000: + speed = 8; + break; + default: + break; + } + REG_ICDC_CDCCR2 |= 0x00000f00; + speed = speed << 8; + + speed |= 0xfffff0ff; + REG_ICDC_CDCCR2 &= speed; +} + +static void HP_turn_on(void) +{ + //see 1.3.4.1 + + REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); //set suspend 0 + + mdelay(15); + REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVR | ICDC_CDCCR1_VRCGL | ICDC_CDCCR1_VRCGH); + REG_ICDC_CDCCR1 |= (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_HPCG); + + mdelay(600); + REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_HPCG | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP); + + mdelay(2); + HP_register_value = REG_ICDC_CDCCR1; + + //see 1.3.4.2 + /*REG_ICDC_CDCCR1 &= 0xfffffffc; + mdelay(7); + REG_ICDC_CDCCR1 |= 0x00040400; + mdelay(15); + REG_ICDC_CDCCR1 &= 0xfffbfbff; + udelay(500); + REG_ICDC_CDCCR1 &= 0xffe5fcff; + REG_ICDC_CDCCR1 |= 0x01000000; + mdelay(400); + REG_ICDC_CDCCR1 &= 0xfffeffff; + mdelay(7); + HP_register_value = REG_ICDC_CDCCR1;*/ + + //see 1.3.4.3 + +} + + +static void HP_turn_off(void) +{ + //see 1.3.4.1 + mdelay(2); + REG_ICDC_CDCCR1 = HP_register_value; + REG_ICDC_CDCCR1 |= 0x001b0300; + REG_ICDC_CDCCR1 &= 0xfeffffff; + + mdelay(15); + REG_ICDC_CDCCR1 |= 0x00000002;//set suspend 1 + + //see 1.3.4.2 + /*mdelay(4); + REG_ICDC_CDCCR1 = HP_register_value; + REG_ICDC_CDCCR1 |= 0x001b0300; + REG_ICDC_CDCCR1 &= 0xfeffffff; + mdelay(4); + REG_ICDC_CDCCR1 |= 0x00000400; + mdelay(15); + REG_ICDC_CDCCR1 &= 0xfffffdff; + mdelay(7); + REG_ICDC_CDCCR1 |= 0x00000002;*/ + + //see 1.3.4.3 + +} + +void audiohw_mute(bool mute) +{ + if(mute) + REG_ICDC_CDCCR1 |= ICDC_CDCCR1_HPMUTE; + else + REG_ICDC_CDCCR1 &= ~ICDC_CDCCR1_HPMUTE; +} + +void audiohw_preinit(void) +{ + i2s_reset(); +} + +void audiohw_postinit(void) +{ + audiohw_mute(false); +} -- cgit v1.2.3