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

📄 maestro3.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
}static void m3_assp_write(struct m3_card *card,         u16 region, u16 index, u16 data){    unsigned long flags;    spin_lock_irqsave(&(card->lock), flags);    __m3_assp_write(card, region, index, data);    spin_unlock_irqrestore(&(card->lock), flags);}static void m3_assp_halt(struct m3_card *card){    card->reset_state = m3_inb(card, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;    mdelay(10);    m3_outb(card, card->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);}static void m3_assp_continue(struct m3_card *card){    m3_outb(card, card->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);}/* * This makes me sad. the maestro3 has lists * internally that must be packed.. 0 terminates, * apparently, or maybe all unused entries have * to be 0, the lists have static lengths set * by the binary code images. */static int m3_add_list(struct m3_card *card,        struct m3_list *list, u16 val){    DPRINTK(DPSTR, "adding val 0x%x to list 0x%p at pos %d\n",            val, list, list->curlen);    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,            list->mem_addr + list->curlen,            val);    return list->curlen++;}static void m3_remove_list(struct m3_card *card,        struct m3_list *list, int index){    u16  val;    int lastindex = list->curlen - 1;    DPRINTK(DPSTR, "removing ind %d from list 0x%p\n",            index, list);    if(index != lastindex) {        val = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,                list->mem_addr + lastindex);        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,                list->mem_addr + index,                val);    }    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,            list->mem_addr + lastindex,            0);    list->curlen--;}static void set_fmt(struct m3_state *s, unsigned char mask, unsigned char data){    int tmp;    s->fmt = (s->fmt & mask) | data;    tmp = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;    /* write to 'mono' word */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 1,             (tmp & ESS_FMT_STEREO) ? 0 : 1);    /* write to '8bit' word */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 2,             (tmp & ESS_FMT_16BIT) ? 0 : 1);    tmp = (s->fmt >> ESS_ADC_SHIFT) & ESS_FMT_MASK;    /* write to 'mono' word */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 1,             (tmp & ESS_FMT_STEREO) ? 0 : 1);    /* write to '8bit' word */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 2,             (tmp & ESS_FMT_16BIT) ? 0 : 1);}static void set_dac_rate(struct m3_state *s, unsigned int rate){    u32 freq;    if (rate > 48000)        rate = 48000;    if (rate < 8000)        rate = 8000;    s->ratedac = rate;    freq = ((rate << 15) + 24000 ) / 48000;    if(freq)         freq--;    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->dac_inst.data + CDATA_FREQUENCY,            freq);}static void set_adc_rate(struct m3_state *s, unsigned int rate){    u32 freq;    if (rate > 48000)        rate = 48000;    if (rate < 8000)        rate = 8000;    s->rateadc = rate;    freq = ((rate << 15) + 24000 ) / 48000;    if(freq)         freq--;    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->adc_inst.data + CDATA_FREQUENCY,            freq);}static void inc_timer_users(struct m3_card *card){    unsigned long flags;    spin_lock_irqsave(&card->lock, flags);        card->timer_users++;    DPRINTK(DPSYS, "inc timer users now %d\n",            card->timer_users);    if(card->timer_users != 1)         goto out;    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,        KDATA_TIMER_COUNT_RELOAD,         240 ) ;    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,        KDATA_TIMER_COUNT_CURRENT,         240 ) ;    m3_outw(card,              m3_inw(card, HOST_INT_CTRL) | CLKRUN_GEN_ENABLE,            HOST_INT_CTRL);out:    spin_unlock_irqrestore(&card->lock, flags);}static void dec_timer_users(struct m3_card *card){    unsigned long flags;    spin_lock_irqsave(&card->lock, flags);    card->timer_users--;    DPRINTK(DPSYS, "dec timer users now %d\n",            card->timer_users);    if(card->timer_users > 0 )         goto out;    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,        KDATA_TIMER_COUNT_RELOAD,         0 ) ;    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,        KDATA_TIMER_COUNT_CURRENT,         0 ) ;    m3_outw(card,  m3_inw(card, HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE,            HOST_INT_CTRL);out:    spin_unlock_irqrestore(&card->lock, flags);}/* * {start,stop}_{adc,dac} should be called * while holding the 'state' lock and they * will try to grab the 'card' lock.. */static void stop_adc(struct m3_state *s){    if (! (s->enable & ADC_RUNNING))         return;    s->enable &= ~ADC_RUNNING;    dec_timer_users(s->card);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->adc_inst.data + CDATA_INSTANCE_READY, 0);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            KDATA_ADC1_REQUEST, 0);}    static void stop_dac(struct m3_state *s){    if (! (s->enable & DAC_RUNNING))         return;    DPRINTK(DPSYS, "stop_dac()\n");    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->dac_inst.data + CDATA_INSTANCE_READY, 0);    s->enable &= ~DAC_RUNNING;    s->card->dacs_active--;    dec_timer_users(s->card);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            KDATA_MIXER_TASK_NUMBER,             s->card->dacs_active ) ;}    static void start_dac(struct m3_state *s){    if( (!s->dma_dac.mapped && s->dma_dac.count < 1) ||            !s->dma_dac.ready ||            (s->enable & DAC_RUNNING))         return;    DPRINTK(DPSYS, "start_dac()\n");    s->enable |= DAC_RUNNING;    s->card->dacs_active++;    inc_timer_users(s->card);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->dac_inst.data + CDATA_INSTANCE_READY, 1);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            KDATA_MIXER_TASK_NUMBER,             s->card->dacs_active ) ;}    static void start_adc(struct m3_state *s){    if ((! s->dma_adc.mapped &&                s->dma_adc.count >= (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))         || !s->dma_adc.ready         || (s->enable & ADC_RUNNING) )             return;    DPRINTK(DPSYS, "start_adc()\n");    s->enable |= ADC_RUNNING;    inc_timer_users(s->card);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            KDATA_ADC1_REQUEST, 1);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->adc_inst.data + CDATA_INSTANCE_READY, 1);}    static struct play_vals {    u16 addr, val;} pv[] = {    {CDATA_LEFT_VOLUME, ARB_VOLUME},    {CDATA_RIGHT_VOLUME, ARB_VOLUME},    {SRC3_DIRECTION_OFFSET, 0} ,    /* +1, +2 are stereo/16 bit */    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */    {SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */    {SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */    {SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */    {SRC3_DIRECTION_OFFSET + 21, 0} /* booster */};/* the mode passed should be already shifted and masked */static void m3_play_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size){    int dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);    int dsp_in_buffer = s->dac_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;    struct dmabuf *db = &s->dma_dac;    int i;    DPRINTK(DPSTR, "mode=%d rate=%d buf=%p len=%d.\n",        mode, rate, buffer, size);#define LO(x) ((x) & 0xffff)#define HI(x) LO((x) >> 16)    /* host dma buffer pointers */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_HOST_SRC_ADDRL,        LO(virt_to_bus(buffer)));    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_HOST_SRC_ADDRH,        HI(virt_to_bus(buffer)));    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1L,        LO(virt_to_bus(buffer) + size));    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1H,        HI(virt_to_bus(buffer) + size));    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_HOST_SRC_CURRENTL,        LO(virt_to_bus(buffer)));    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_HOST_SRC_CURRENTH,        HI(virt_to_bus(buffer)));#undef LO#undef HI    /* dsp buffers */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_IN_BUF_BEGIN,        dsp_in_buffer);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_IN_BUF_END_PLUS_1,        dsp_in_buffer + (dsp_in_size / 2));    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_IN_BUF_HEAD,        dsp_in_buffer);        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_IN_BUF_TAIL,        dsp_in_buffer);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_OUT_BUF_BEGIN,        dsp_out_buffer);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_OUT_BUF_END_PLUS_1,        dsp_out_buffer + (dsp_out_size / 2));    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_OUT_BUF_HEAD,        dsp_out_buffer);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_OUT_BUF_TAIL,        dsp_out_buffer);    /*     * some per client initializers     */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 12,        s->dac_inst.data + 40 + 8);    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 19,        s->dac_inst.code + MINISRC_COEF_LOC);    /* enable or disable low pass filter? */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 22,        s->ratedac > 45000 ? 0xff : 0 );        /* tell it which way dma is going? */    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,        s->dac_inst.data + CDATA_DMA_CONTROL,        DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);    /*     * set an armload of static initializers     */    for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++)         m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,            s->dac_inst.data + pv[i].addr, pv[i].val);    /*      * put us in the lists if we're not already there     */    if(db->in_lists == 0) {        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list,                 s->dac_inst.data >> DP_SHIFT_COUNT);        db->dma_index = m3_add_list(s->card, &s->card->dma_list,                 s->dac_inst.data >> DP_SHIFT_COUNT);        db->mixer_index = m3_add_list(s->card, &s->card->mixer_list,                 s->dac_inst.data >> DP_SHIFT_COUNT);        db->in_lists = 1;    }    set_dac_rate(s,rate);    start_dac(s);}/* *    Native record driver  */

⌨️ 快捷键说明

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