SmartAudio/lichee/brandy/u-boot-2011.09/drivers/audio/sunxi_codec.c

289 lines
6.6 KiB
C
Raw Normal View History

2018-07-13 01:31:50 +00:00
/*
* (C) Copyright 2012
* wangflord@allwinnertech.com
*
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program;
*
*/
#include <common.h>
#include <asm/arch/cpu.h>
#include <asm/arch/clock.h>
#include <asm/arch/codec.h>
#include <asm/arch/dma.h>
struct sunxi_codec_t *sunxi_codec;
uint hdma = 0;
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sunxi_codec_init(void)
{
#if 0
struct sunxi_ccm_reg *ccm_reg = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
sunxi_codec = (struct sunxi_codec_t *)SUNXI_CODEC_BASE;
//open codec clock
ccm_reg->apb0_gate |= 1;
ccm_reg->audio_codec_clk_cfg |= (1U << 31);
//open dac
sunxi_codec->dac_dpc = 0x80800000;
sunxi_codec->dac_fifoc = 0x10400f11;
sunxi_codec->adc_actl |= (1 << 4);
sunxi_codec->dac_actl |= (0x3U<<30)|(0x1<<8)|(0x1<<6)|(0x3c);
#endif
return 0;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sunxi_codec_config(int samplerate, int samplebit, int channel)
{
#if 0
uint reg_value;
struct sunxi_ccm_reg *ccm_reg = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
reg_value = sunxi_codec->dac_fifoc;
reg_value &= ~((1 << 6) | (1 << 5) | (0x0eU << 29));
if(samplebit == 24)
{
reg_value |= (1 << 5);
}
if(channel != 2)
{
reg_value |= (1 << 6);
}
if(samplerate%2000)
{
debug("sunxi codec samplerate as 44100\n");
ccm_reg->pll2_cfg = 0;
}
else
{
debug("sunxi codec samplerate as 48000\n");
ccm_reg->pll2_cfg = 0;
}
switch(samplerate)
{
case 48000:
case 44100:
{
break;
}
case 32000:
{
reg_value |= (1 << 29);
break;
}
case 24000:
case 22050:
{
reg_value |= (2 << 29);
break;
}
case 16000:
{
reg_value |= (3 << 29);
break;
}
case 12000:
case 11025:
{
reg_value |= (4 << 29);
break;
}
case 8000:
{
reg_value |= (5 << 29);
break;
}
default:
{
printf("sunxi codec config error : audio sample %d not supported\n", samplerate);
return -1;
}
}
sunxi_codec->dac_fifoc = reg_value;
#endif
return 0;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sunxi_codec_start(void *buffer, uint length, uint loop_mode)
{
#if 0
sunxi_dma_setting_t dma_cfg;
if(!hdma)
{
hdma = sunxi_dma_request(0);
if(!hdma)
{
printf("sunxi codec error : request dma failed\n");
return -1;
}
}
dma_cfg.cfg.src_drq_type = DMAC_CFG_DEST_TYPE_DRAM;
dma_cfg.cfg.src_addr_mode = 0; //Դ<>˵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD>
dma_cfg.cfg.src_burst_length = 0; //burst = 1
dma_cfg.cfg.src_data_width = 1; //һ<>δ<EFBFBD><CEB4><EFBFBD>16bit
dma_cfg.cfg.dst_drq_type = DMAC_CFG_SRC_TYPE_CODEC;
dma_cfg.cfg.dst_addr_mode = 1; //Ŀ<>Ķ˵<C4B6>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>
dma_cfg.cfg.dst_burst_length = 0; //burst = 1
dma_cfg.cfg.dst_data_width = 1; //һ<>ν<EFBFBD><CEBD><EFBFBD>16bit
dma_cfg.loop_mode = loop_mode;
dma_cfg.wait_cyc = 4;
dma_cfg.data_block_size = 1 * 16/8;
dma_cfg.loop_mode = loop_mode;
sunxi_dma_setting(hdma, &dma_cfg);
flush_cache((uint)buffer, length);
sunxi_dma_start(hdma, (uint)buffer, (uint)(&sunxi_codec->dac_txdata), length);
#endif
return 0;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sunxi_codec_stop(void)
{
#if 0
if(!hdma)
{
printf("sunxi codec error : cant stop without dma\n");
return -1;
}
sunxi_dma_stop(hdma);
#endif
return 0;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sunxi_codec_wink(void *buffer, uint length)
{
#if 0
if(!hdma)
{
printf("sunxi codec error : cant stop without dma\n");
return -1;
}
sunxi_dma_stop(hdma);
flush_cache((uint)buffer, length);
sunxi_dma_start(hdma, (uint)buffer, (uint)(&sunxi_codec->dac_txdata), length);
#endif
return 0;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int audio_codec_exit(void)
{
#if 0
struct sunxi_ccm_reg *ccm_reg = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
ccm_reg->apb0_gate &= ~1;
ccm_reg->audio_codec_clk_cfg &= ~(1U << 31);
#endif
return 0;
}