int dsp_mailbox_send(struct audiodsp_priv *priv,int overwrite,int num,int cmd,const char *data,int len)
{
	unsigned long flags;
	int res=-1;
	struct mail_msg *m;
    	dma_addr_t buf_map;

	m=&priv->mailbox_reg2[num];

	local_irq_save_nort(flags);
	if(overwrite || m->status==0)
	{
		
		m->cmd=cmd;
		m->data=(char *)ARM_2_ARC_ADDR_SWAP((unsigned)data);
		m->len=len;
		m->status=1;
		after_change_mailbox(m);
		if(data!=NULL && len >0)
		{
			buf_map = dma_map_single(NULL, (void *)data, len, DMA_TO_DEVICE);
			dma_unmap_single(NULL, buf_map, len, DMA_TO_DEVICE);
    		}
		MAIBOX2_IRQ_ENABLE(num);
		DSP_TRIGGER_IRQ(num);
		res=0;
	}
	local_irq_restore_nort(flags);
	return res;
}
static inline int dsp_set_stream_buffer( struct audiodsp_priv *priv)
{
      dma_addr_t buf_map;
	if(priv->stream_buffer_mem_size==0)
		{
		DSP_WD(DSP_DECODE_OUT_START_ADDR,0);
		DSP_WD(DSP_DECODE_OUT_END_ADDR,0);
		DSP_WD(DSP_DECODE_OUT_RD_ADDR,0);
		DSP_WD(DSP_DECODE_OUT_WD_ADDR,0);
		return 0;
		}
	if(priv->stream_buffer_mem==NULL)
		priv->stream_buffer_mem=(void*)kmalloc(priv->stream_buffer_mem_size,GFP_KERNEL);
	if(priv->stream_buffer_mem==NULL)
		{
		DSP_PRNT("kmalloc error,no memory for audio dsp stream buffer\n");
		return -ENOMEM;
		}
	memset((void *)priv->stream_buffer_mem,0,priv->stream_buffer_mem_size);
    	buf_map = dma_map_single(NULL, (void *)priv->stream_buffer_mem, priv->stream_buffer_mem_size, DMA_FROM_DEVICE);
	dma_unmap_single(NULL, buf_map,  priv->stream_buffer_mem_size, DMA_FROM_DEVICE);

	priv->stream_buffer_start=MAX_CACHE_ALIGN((unsigned long)priv->stream_buffer_mem);
	priv->stream_buffer_end=MIN_CACHE_ALIGN((unsigned long)priv->stream_buffer_mem+priv->stream_buffer_mem_size);
	priv->stream_buffer_size=priv->stream_buffer_end-priv->stream_buffer_start;
	if(priv->stream_buffer_size<0)
		{
		DSP_PRNT("Stream buffer set error,must more larger,mensize=%d,buffer size=%ld\n",
			priv->stream_buffer_mem_size,priv->stream_buffer_size
			);
		kfree(priv->stream_buffer_mem);
		priv->stream_buffer_mem=NULL;
		return -2;
		}
		
	DSP_WD(DSP_DECODE_OUT_START_ADDR,ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_start));
	DSP_WD(DSP_DECODE_OUT_END_ADDR,ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_end));
	DSP_WD(DSP_DECODE_OUT_RD_ADDR,ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_start));
	DSP_WD(DSP_DECODE_OUT_WD_ADDR,ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_start));
	
	DSP_PRNT("DSP stream buffer to [%#lx-%#lx]\n",ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_start),ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_end));
	return 0;
}
static inline int dsp_set_heap( struct audiodsp_priv *priv)
{
      dma_addr_t buf_map;
	if(priv->dsp_heap_size==0)
		return 0;
	if(priv->dsp_heap_start==0)
		priv->dsp_heap_start=(unsigned long)kmalloc(priv->dsp_heap_size,GFP_KERNEL);
	if(priv->dsp_heap_start==0)
		{
		DSP_PRNT("kmalloc error,no memory for audio dsp dsp_set_heap\n");
		return -ENOMEM;
		}
	memset((void *)priv->dsp_heap_start,0,priv->dsp_heap_size);
       buf_map = dma_map_single(NULL, (void *)priv->dsp_heap_start, priv->dsp_heap_size, DMA_FROM_DEVICE);
	dma_unmap_single(NULL, buf_map,  priv->dsp_heap_size, DMA_FROM_DEVICE);
	DSP_WD(DSP_MEM_START,MAX_CACHE_ALIGN(ARM_2_ARC_ADDR_SWAP(priv->dsp_heap_start)));
	DSP_WD(DSP_MEM_END,MIN_CACHE_ALIGN(ARM_2_ARC_ADDR_SWAP(priv->dsp_heap_start)+priv->dsp_heap_size));
	DSP_PRNT("DSP heap start =%#lx,size=%#lx\n",ARM_2_ARC_ADDR_SWAP(priv->dsp_heap_start),priv->dsp_heap_size);
	return 0;
}
示例#4
0
unsigned long dsp_codec_inc_rd_addr(struct audiodsp_priv *priv, int size)
{
    unsigned long rd, flags;
    local_irq_save(flags);
    rd = dsp_codec_get_rd_addr(priv);
    rd = rd + size;
    if (rd >= priv->stream_buffer_end) {
        rd = rd - priv->stream_buffer_size;
    }
    DSP_WD(DSP_DECODE_OUT_RD_ADDR, ARM_2_ARC_ADDR_SWAP((void*)rd));
    local_irq_restore(flags);
    return rd;
}