⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aud_atom.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 3 页
字号:
/*----------------------------------------------------------------------------+|       This source code has been made available to you by IBM on an AS-IS|       basis.  Anyone receiving this source is licensed under IBM|       copyrights to use it in any way he or she deems fit, including|       copying it, modifying it, compiling it, and redistributing it either|       with or without modifications.  No license under IBM patents or|       patent applications is to be implied by the copyright license.||       Any user of this software should understand that IBM cannot provide|       technical support for this software and will not be responsible for|       any consequences resulting from the use of this software.||       Any person who transfers this source code or any derivative work|       must include the IBM copyright notice, this paragraph, and the|       preceding two paragraphs in the transferred software.||       COPYRIGHT   I B M   CORPORATION 1997, 1999, 2003|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| File:   aud_atom.c| Purpose: audio driver atom layer PALLAS| Changes:| Date:     Comment:| -----     --------| 15-Oct-01 create | 21-Jan-03 Prevent audio pops due to turning on/off clocks to the DAC.|           This main cause for this is due to the ADISO bit in CTRL0|           being cleared by the reset to clear the rate buffer and|           by the loading of microcode.  Fixed by using the reset cmd|           that will specifically clear the rate buffer instead of the|           global audio reset (which also resets the CTRL regs), and|           by not clearing the ADISO bit during microcode loading.| 17-Jun-03 Initial implementation to get audio status.  MPEG/AC3/UPCM| 17-Jun-03 Added UPCM selection for 8-bit UPCM streams| 20-Jun-03 Change init/stop/start to use halt decoding (pause) instead of |           start parsing.  This should prevent "losing" stream data between |           stop/start and provided a quicker stop (pause).  The forcing |           on/off of mute was also removed (see aud_osi.c)| 25-Jun-03 Added support for DTS/LPCM coreload and the AC3 decoding coreloads| 25-Jun-03 Force encoded SPDIF output if decoding AC3 not available| 25-Jun-03 Added stream status support for DTS/LPCM coreload| 26-Jun-03 Changed default of _mute var since mute not forced on during open| 22-Jul-03 Fixed LPCM status bit definitions| 23-Jul-03 Fill audio microcode description structure variable| 25-Jul-03 Added check to be sure that the audio physical memory size defined was large enough+----------------------------------------------------------------------------*/#include <os/os-io.h>#include <os/os-interrupt.h>#include <os/drv_debug.h>#include <os/os-sync.h>#include "aud_osi.h"#include "aud_atom.h"#include "aud_atom_hw.h"#include "aud_uc.h"#include "astb_d.h"struct aud_ucode_info stb_info = {  "s5amp3",  aud_ucode_stb, sizeof(aud_ucode_stb_len),  astb_d, sizeof(astb_d),};#ifdef AC3_ENABLE#include "aud_dvd.h"#include "advd_d.h"struct aud_ucode_info dvd_info = {  "s5advdr",   aud_ucode_dvd, sizeof(aud_ucode_dvd),  advd_d, sizeof(advd_d),};#endif#ifdef DTS_ENABLE#include "aud_dts.h"#include "adts_d.h"struct aud_ucode_info dts_info = {  "s5adts",   aud_ucode_dts, sizeof(aud_ucode_dts),  adts_d, sizeof(adts_d),};#endifstruct aud_ucode_info *aud_ucode_info[] = {  &stb_info,#if AC3_ENABLE  &dvd_info,#endif#if AC3_ENABLE  &dts_info,#endif  NULL};/*notify channel change done to demux*/extern  int aud_cc_done();extern  void vid_atom_set_stc(STC_T *pData);void*   _seg1_log = NULL;int     _mute = 0;/*local definition*/#define DEF_AUD_IRQ_MASK        DECOD_AUD_IMR_CCC | \                                DECOD_AUD_IMR_CM  | \                                DECOD_AUD_IMR_CM2 | \                                DECOD_AUD_IMR_RTBC | \                                DECOD_AUD_IMR_AMSIint aud_atom_load_microcode(const unsigned short *code, int count);INT aud_atom_load_dfile(void *base, const unsigned char *dfile,                         int df_len, unsigned long rb_off);inline void aud_atom_reset_rb();INT aud_atom_init(ADEC_CON *pAConf){    unsigned long reg;    const USHORT *code;     const unsigned char *data;    int count, dcount;    unsigned long control;    /*-------------------------------------------------------------------------+    | Disable interrupts during reset.    +-------------------------------------------------------------------------*/    // disable_irq(STB_AUD_INT);  // YYD disabled    /*-------------------------------------------------------------------------+    | Reset the core.    +-------------------------------------------------------------------------*/    aud_atom_reset_rb();    /*-------------------------------------------------------------------------+    | After soft reset here must be at least 20 processor cycles before    | another read/write to MPEG audio DCR.    +-------------------------------------------------------------------------*/    os_cpu_clock_delay(30);    // clear all buffer    //mpeg_a_buf_blank(pADEC);    /*-------------------------------------------------------------------------+    | Write the MPEG audio code segment registers.    +-------------------------------------------------------------------------*/    if ((pAConf->seg1 & DECOD_AUD_SEG_ALIGN) != 0)    {        printk("ERROR: MPEG_A_MEM_START value must be 0x%8.8x byte aligned\n",DECOD_AUD_SEG_ALIGN);        return (-1);    }    if ((pAConf->seg2 & DECOD_AUD_SEG_ALIGN) != 0)    {        printk("ERROR: Audio segment 2 value must be 0x%8.8x byte aligned\n",DECOD_AUD_SEG_ALIGN);        return (-1);    }    if ((pAConf->rb_base & DECOD_AUD_SEG_ALIGN) != 0)    {        printk("ERROR: Audio rate buffer base must be 0x%8.8x byte aligned\n",DECOD_AUD_SEG_ALIGN);        return (-1);    }    PDEBUG("MPEG_A_SEGMENT1 = 0x%8.8x and ends at 0x%8.8x\n",MPEG_A_SEGMENT1,MPEG_A_SEGMENT1+MPEG_A_SEGMENT1_SIZE);    PDEBUG("MPEG_A_SEGMENT3 = 0x%8.8x and ends at 0x%8.8x\n",MPEG_A_SEGMENT3,MPEG_A_SEGMENT3+MPEG_A_SEGMENT3_SIZE);    PDEBUG("MPEG_A_SEGMENT2 = 0x%8.8x and ends at 0x%8.8x\n",MPEG_A_SEGMENT2,MPEG_A_SEGMENT2+MPEG_A_SEGMENT2_SIZE);    PDEBUG("MPEG_A_CLIP_BUF_START = 0x%8.8x and ends at 0x%8.8x\n",MPEG_A_CLIP_BUF_START,MPEG_A_CLIP_BUF_START+MPEG_A_CLIP_BUF_LEN);    PDEBUG("MPEG_A_MIXER_BUF_START = 0x%8.8x and ends at 0x%8.8x\n",MPEG_A_MIXER_BUF_START,MPEG_A_MIXER_BUF_START+MPEG_A_MIXER_BUF_LEN);    /*-------------------------------------------------------------------------+    | Make sure the defined audio size is large enough.    +-------------------------------------------------------------------------*/    if(((MPEG_A_MIXER_BUF_START + MPEG_A_MIXER_BUF_LEN)- MPEG_A_SEGMENT1) > MPEG_A_MEM_SIZE)    {       printk("ERROR: MPEG_A_MEM_SIZE 0x%8.8x is not large enough to cover the audio memory allocations 0x%8.8x\n"       ,MPEG_A_MEM_SIZE,(int)((MPEG_A_MIXER_BUF_START + MPEG_A_MIXER_BUF_LEN)- MPEG_A_SEGMENT1) );       return (-1);    }    PDEBUG("setting audio segment 1 to 0x%8x\n", pAConf->seg1);    MT_DCR(AUD_SEG1, pAConf->seg1 >> DECOD_AUD_SEG_SH);    PDEBUG("setting audio segment 2 to 0x%8x\n", pAConf->seg2);    MT_DCR(AUD_SEG2, pAConf->seg2 >> DECOD_AUD_SEG_SH);    /*-------------------------------------------------------------------------+    | 64K rate buffer is configured in following statement.    +-------------------------------------------------------------------------*/    PDEBUG("setting audio segment 3 to 0x%8x\n", pAConf->rb_base);    MT_DCR(AUD_SEG3, (pAConf->rb_base >> DECOD_AUD_SEG_SH) | (0xF << 28));    //       ((pAConf->rb_size & 0xF) << 28));    /*-------------------------------------------------------------------------+    | Initialize offsets for bank1.    +-------------------------------------------------------------------------*/    MT_DCR(AUD_OFFSETS, pAConf->rb_off);    /*-------------------------------------------------------------------------+    | Check the microcode load type.    +-------------------------------------------------------------------------*/    code = (const USHORT*)aud_ucode_stb; /* Set default coreload to mpeg      */    count = aud_ucode_stb_len;    data = astb_d;     dcount = astb_d_len;    switch (pAConf->mode)    {        case AUD_MODE_AC3:#ifdef AC3_ENABLE	  if (aud_ucode_dvd_len > 0) {            code = (const USHORT*)aud_ucode_dvd;            count = aud_ucode_dvd_len;	    data = advd_d;	    dcount = advd_d_len;	    control = DECOD_AUD_CTRL2_DM |	      DECOD_AUD_CTRL2_LL | DECOD_AUD_CTRL2_HL |	      DECOD_AUD_CTRL2_DN | DECOD_AUD_CTRL2_AC3;	  } else #endif	    if (aud_ucode_stb_len > 0) {	      control = DECOD_AUD_CTRL2_ID | DECOD_AUD_CTRL2_AC3;	    } else {	      return (-1);	    }	  break;        case AUD_MODE_STB_MPEG:	  if (aud_ucode_stb_len == 1)            {	      return (-1);            }	  control = DECOD_AUD_CTRL2_MPEG;	  break;        case AUD_MODE_STB_PCM:	  if (aud_ucode_stb_len == 1)            {	      return (-1);            }	  control = DECOD_AUD_CTRL2_PCM;	  break;#ifdef DTS_ENABLE        case AUD_MODE_DTS:	  if (aud_ucode_dts_len > 0) {            code = (const USHORT*)aud_ucode_dts;            count = aud_ucode_dts_len;	    data = adts_d;	    dcount = adts_d_len;            control = DECOD_AUD_CTRL2_ID | 	              DECOD_AUD_CTRL2_DTS;	  } else {	    return (-1);	  }	  break;        case AUD_MODE_LPCM:	  if (aud_ucode_dts_len > 0) {            code = (const USHORT*)aud_ucode_dts;            count = aud_ucode_dts_len;	    data = adts_d;	    dcount = adts_d_len;            control = DECOD_AUD_CTRL2_LPCM;	  } else {	    return (-1);	  }	  break;#endif    default:      return (-1);    }    if(aud_atom_load_microcode(code, count/2) != 0)    {        PDEBUG("load microcode error\n");        return -1;    }    PDEBUG("load microcode OK\n");    if(_seg1_log != NULL)    {        if( aud_atom_load_dfile((void*)_seg1_log, data, dcount, pAConf->rb_off) < 0)        {            PDEBUG("load data file error\n");            return -1;        }    }    /*-------------------------------------------------------------------------+    | Setup stream ID register.    +-------------------------------------------------------------------------*/    if(pAConf->mode == AUD_MODE_STB_MPEG)  /* If MPEG, set MPEG pes id's      */    {        MT_DCR(AUD_STREAM_ID, DECOD_AUD_DEF_ID);    }    else                                   /* All others use private stream id*/    {        MT_DCR(AUD_STREAM_ID, DECOD_AUD_DEF_AC3_ID);    }    /*-------------------------------------------------------------------------+    | Start DSP.  Download end flag must be set.    +-------------------------------------------------------------------------*/    MT_DCR(AUD_CTRL0,               DECOD_AUD_CTRL0_START_DECODER |                DECOD_AUD_CTRL0_DOWNLOAD_END  |               DECOD_AUD_CTRL0_START_PARSING |               DECOD_AUD_CTRL0_ENABLE_INT);    /*-------------------------------------------------------------------------+    | Enable DACs    +-------------------------------------------------------------------------*/#ifdef CONFIG_OLIVIA // ShaoLin add for Olivia    MT_DCR(AUD_CTRL1, MF_DCR(AUD_CTRL1) | DECOD_AUD_CTRL1_DAC_EN | 0x08 | 0x01);#endif    reg = MF_DCR(AUD_CTRL1) | DECOD_AUD_CTRL1_DAC_EN;    MT_DCR(AUD_CTRL1, reg);    /*-------------------------------------------------------------------------+    | Set correct mode.    +-------------------------------------------------------------------------*/    MT_DCR(AUD_CTRL2, control);    aud_atom_reset_rb(); // YYD, as required by uc 3.01 after set stream format    return (0);}void aud_atom_close(){    unsigned long reg;    /*-------------------------------------------------------------------------+    | Reset the rate buffers.    +-------------------------------------------------------------------------*/    aud_atom_reset_rb();    //stop decoder and disable interrupt    reg = MF_DCR(AUD_CTRL0) &                 (~(DECOD_AUD_CTRL0_START_DECODER |                    DECOD_AUD_CTRL0_ENABLE_INT));    MT_DCR(AUD_CTRL0, reg);}INT aud_atom_set_stream_type(audStream_t stream){    unsigned long stream_type;    unsigned long reg;    //    unsigned long ctrl2;    /*-------------------------------------------------------------------------+    | Reset the core.    +-------------------------------------------------------------------------*/    aud_atom_reset_rb();    /*-------------------------------------------------------------------------+    | After soft reset here must be at least 20 processor cycles before    | another read/write to MPEG audio DCR.    +-------------------------------------------------------------------------*/    os_cpu_clock_delay(30);    reg = MF_DCR(AUD_CTRL0) & (~DECOD_AUD_CTRL0_TYPE_MPEG1);    //    ctrl2 = MF_DCR(AUD_CTRL2) & (~DECOD_AUD_CTRL2_PCM);    switch (stream)    {        case AUD_STREAM_TYPE_MPEG1:            stream_type = DECOD_AUD_CTRL0_TYPE_MPEG1;	    //            ctrl2 |= DECOD_AUD_CTRL2_MPEG;            break;        case AUD_STREAM_TYPE_PES:            stream_type = DECOD_AUD_CTRL0_TYPE_PES;	    //            ctrl2 |= DECOD_AUD_CTRL2_MPEG;            break;        case AUD_STREAM_TYPE_ES:            stream_type = DECOD_AUD_CTRL0_TYPE_ES;	    //            ctrl2 |= DECOD_AUD_CTRL2_MPEG;            break;        case AUD_STREAM_TYPE_PCM:  // YYD, add for PCM support            stream_type = DECOD_AUD_CTRL0_TYPE_ES;	    //            ctrl2 |= DECOD_AUD_CTRL2_PCM;            break;        default:            return (-1);    }    PDEBUG("new stream type =%ld\n", stream_type);    MT_DCR(AUD_CTRL0, reg | stream_type | DECOD_AUD_CTRL0_START_DECODER);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -