返回信息流小弟在把网上的uda1341驱动改成了adv212的驱动,adv212用的是DCS dma mode,但在2440的dma部分遇到了问题(2.6.29的内核):
1、在分配dma buffer时如果小于我请求read的大小就会不停的请求中断;
2、dma完成一buffer传输后再次enqueue时出错,出错原因是等待load buffer timeout;
3、我看到网上总有人说dma的驱动有问题,还说物理通道和映射通道什么的,但在看源码后还是不能理解,求正解;如果有需要改正的bug望告知小弟。
以上问题我都在debug的情况下走了遍源代码,会出现这样的问题完全符合设计者的思路,但关键是我不能理解……
如果有用过adv202 or adv212+2440 的有更好的数据传输方法也望赐教。
这是我第一次在这里发请教贴,希望能感受到byr的热情,谢谢~
关于dma初始化部分的源代码:
static int __init adv212_init_dma(audio_stream_t * s)
{
int ret ;
int dmacount;
enum s3c2410_dmasrc source;
int hwcfg;
unsigned long devaddr;
int dcon = 0;
unsigned int flags = 0;
devaddr = ADV212_BASE_PHYS+ ADV212_DIRECT_REG_CODE;
if(s->dmach == DMACH_XD0)
{
source =S3C2410_DMASRC_HW;
hwcfg =1 ;
dmacount = 0;
dcon=S3C2410_DCON_HANDSHAKE|S3C2410_DCON_SYNC_HCLK|S3C2410_DCON_INTREQ|S3C2410_DCON_WHOLE_SERVICE|S3C2410_DCON_INTREQ|S3C2410_DCON_AUTORELOAD|S3C2410_DCON_HWTRIG|S3C2410_DCON_WORD|dmacount;
flags = S3C2410_DMAF_AUTOSTART;
ret = s3c2410_dma_request(s->dmach, &s3c2440adv212_dma_in, NULL);
s3c2410_dma_devconfig(s->dmach, source, hwcfg, devaddr);//write source addr, srrc ctl,dist ctl
s3c2410_dma_config(s->dmach, 4, dcon); //wsh wrire dcon, change xferunit from 2 to 4
s3c2410_dma_set_buffdone_fn(s->dmach, adv212_dmain_done_callback);
s3c2410_dma_setflags(s->dmach, flags);
return 0 ;
}
else
return 1;
}
关于read部分的源代码:
static ssize_t smdk2440_adv212_read(struct file *file, char *buffer,
size_t count, loff_t * ppos)
{
/*nyp*/
const char *buffer0 = buffer;
audio_stream_t *s = &input_stream;
int chunksize, ret = 0;
unsigned short value16;
int jp2_size,i,size_tmp;
if (!s->buffers)
{
int i;
if (adv212_setup_buf(s)) //alloc DMA buffers
return -ENOMEM;
for (i = 0; i < s->nbfrags; i++)
{
audio_buf_t *b = s->buf;
printk("s->buf_idx = %u\n", s->buf_idx);
down(&b->sem);
printk("s->dmach = %d\n",s->dmach);
s3c2410_dma_enqueue(s->dmach, (void *) b, b->dma_addr, s->fragsize);
NEXT_BUF(s, buf);
}
}
if(start_flag == 0)
{
printk("\nstart output\n");
reg16_adv212_eirqflg =0xFFFF;//start compress and make adv212 can output
printk("\n***nyp3 : eirqflg=0x%x***\n",reg16_adv212_eirqflg);
value16 = s3c2410_gpio_getpin(S3C2410_GPB10);
while(value16 != 0) value16 = s3c2410_gpio_getpin(S3C2410_GPB10);
start_flag = 1;
printk("lalala\n");
}
while (count > 0)
{
audio_buf_t *b = s->buf;
// Wait for a buffer to become full
if (file->f_flags & O_NONBLOCK)
{
ret = -EAGAIN;
if (down_trylock(&b->sem))
break;
}
else {
ret = -ERESTARTSYS;
if (down_interruptible(&b->sem))
break;
}
chunksize = b->size;
if (chunksize > count) // we required less than buffer size
chunksize = count;
if (copy_to_user(buffer, b->start + s->fragsize - b->size,
chunksize))
{
up(&b->sem);
return -EFAULT;
}
b->size -= chunksize;
buffer += chunksize;
count -= chunksize;
if (b->size > 0)
{
up(&b->sem);
break;
}
//Make current buffer available for DMA again
printk("in the while s->buf_idx = %u\n", s->buf_idx);
s3c2410_dma_enqueue(s->dmach, (void *) b, b->dma_addr, s->fragsize);
NEXT_BUF(s, buf);
}
if ((buffer - buffer0))
ret = buffer - buffer0;
printk("adv212_read: return=%d bytes!\n", ret);
return ret;
}
这是一条镜像帖。来源:北邮人论坛 / embedded-system / #7412同步于 2010/1/22
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Embedded_System机器人发帖
2440DMA求教!
nyp1984
2010/1/22镜像同步2 回复
订阅后,新回复会通过你的通知中心匿名送达。