y296144646q 发表于 2010-6-7 21:43:23

uda1341在ALSA驱动架构上如何实现全双工

你好:
   我附上了我修改后的代码,请看看。(或是你们有更好的在高版本内核中实现的,恳求告诉我一下,我好做参考,谢谢!)
   我最近一直都在整uda1341的全双工驱动,想把以前的2.6.13版本的tq2440_uda1341.c驱动移植到2.6.30.4内核版本上,本人很早就在使用贵公司的产品(tq2440)。现在想实现一个视屏通话,但是就差声卡的这部分移植。求求技术人员帮帮忙。
   在2.6.13版本的内核中,我发现就是在初始化init的时候为output_stream和input_sream结构类型出事话后面需要使用到的dma通道。我发现我只能使用dma1进行申请,但是我发现内核打印信息的地方给出了dma有4个通道,后面我勉为其难的使用了dma0映射到了0通道,dma3映射到了1通道。不知道这样是不是会不会出现问题。(这是我第一处做的大修改,如下)。
   output_stream.dma_ch = 3;
    output_stream.dmaclient.name = "audio_out";
    if (audio_init_dma(&output_stream, "UDA1341 out"))
    {
      audio_clear_dma(&output_stream);
      printk(KERN_WARNING AUDIO_NAME_VERBOSE ": unable to get DMA channels\n");
      return -EBUSY;
    }
    input_stream.dma_ch = 0;
    input_stream.dmaclient.name = "audio_in";
    if (audio_init_dma(&input_stream, "UDA1341 in"))
    {
      audio_clear_dma(&input_stream);
      printk(KERN_WARNING AUDIO_NAME_VERBOSE ": unable to get DMA channels\n");
      return -EBUSY;
    }
   我第二次大的修改就是发现2.6.13版本内核中对iis寄存器的访问有很大的偏差,我做的修改是参考2.6.30.4版本内核中的driver/sound/soc/s3c24xx/s3c24xx-ii2.c关于probe函数中对iis寄存器的初始化,不知道我这样是否可以正确使用到iis寄存器来完成数据传输。(这是我第二处大的修改,如下)
    s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);
    if (s3c24xx_i2s.regs == NULL)
                return -ENXIO;
    s3c2410_gpio_cfgpin(S3C2410_GPE0,(0x02 << 0));
    s3c2410_gpio_cfgpin(S3C2410_GPE1,(0x02 << 2));
    s3c2410_gpio_cfgpin(S3C2410_GPE2,(0x02 << 4));
    s3c2410_gpio_cfgpin(S3C2410_GPE3,(0x02 << 6));
    s3c2410_gpio_cfgpin(S3C2410_GPE4,(0x02 << 8));
    writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON);
还有已处在start_utu2440_iis_bus_txrx函数里,如下:
    u32 iisfcon=0;
        u32 iiscon=0;
        u32 iismod=0;
      writel(iismod,s3c24xx_i2s.regs + S3C2410_IISMOD);
        writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
        writel(iiscon,s3c24xx_i2s.regs + S3C2410_IISCON);
      writel((IISPSR_A(iispsr_value(AUDIO_RATE_DEFAULT)) | IISPSR_B(iispsr_value(AUDIO_RATE_DEFAULT))),S3C2410_IISPSR);
      iiscon = (IISCON_TX_DMA   /* Transmit DMA service request */
            |IISCON_RX_DMA
            //| IISCON_RX_IDLE/* Receive Channel idle */
            | IISCON_PRESCALE);   /* IIS Prescaler Enable */
        writel(iiscon,s3c24xx_i2s.regs + S3C2410_IISCON);
      iismod = (IISMOD_SEL_MA   /* Master mode */
            | IISMOD_SEL_RX
            | IISMOD_SEL_TX   /* Transmit */
            | IISMOD_CH_RIGHT /* Low for left channel */
            | IISMOD_FMT_MSB/* MSB-justified format */
            | IISMOD_BIT_16   /* Serial data bit/channel is 16 bit */
#if (S_CLOCK_FREQ == 384)
            | IISMOD_FREQ_384 /* Master clock freq = 384 fs */
#else
            | IISMOD_FREQ_256 /* Master clock freq = 256 fs */
#endif
            | IISMOD_SFREQ_32);   /* 32 fs */
    writel(iismod,s3c24xx_i2s.regs + S3C2410_IISMOD);
    iisfcon = (IISFCON_TX_DMA/* Transmit FIFO access mode: DMA */
                |IISFCON_RX_DMA
                | IISFCON_TX_EN
                | IISFCON_RX_EN);   /* Transmit FIFO enable */
    writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
    iiscon |= IISCON_EN;      /* IIS enable(start) */
    writel(iiscon,s3c24xx_i2s.regs + S3C2410_IISCON);
   最后一处,我并没有做什么大的修改,我只是重新定义了struct semaphore这个结构类型。原因是如果我使用2.6.30.4的struct semaphore结构类型的话,不让我通过,因为这两个版本的内核关于这个结构体做了很大的修改,为了通过,我在最前面重新定义为struct semaphore1。这样该我觉得不会出错的理由是,关于这个信号量只有两个地方用到,第一就是atomic原子操作,还有就是up和down。第一个不会出错的原因是,两个内核版本的原子操作函数没变,只要保真传进函数的参数类型一样就可以了。第二个不会出错的原因是,up和down这个锁只有在多个进程对/dev/dsp这个设备同时打开的时候才起作用,由于我测试的时候只是用的是cat /dev/dsp > /dev/dsp。(关于这出修改,如下)
   struct semaphore1 {
        atomic_t                count;
        int                sleepers;
        wait_queue_head_t        wait;
};
       typedef struct
{
    int             size;       /* buffer size */
    char         *start;      /* point to actual buffer */
    dma_addr_t      dma_addr;   /* physical buffer address */
    struct semaphore1sem;
    int             master;   /* owner for buffer allocation, contain size when true */
} audio_buf_t;
   关于内核配置,可以说我完全是按以前天堑关于2.6.13内核配置方法来的,现在2.6.30.4和2.6.28的内核配置是一点都没选。关于driver/l3在高版本内核中没有,我就把2.6.13内核中的相应文件放到高版本中,配置后很快就通过了。
   我测试的结果是这样的:
#cat /dev/dsp > /dev/dsp
   
calculated (4-1) freq = 32552, error = 11548
calculated (3-1) freq = 43402, error = 698
calculated (2-1) freq = 65104, error = 21004
selected prescale value = 2, freq = 43402, error = 698
requested sample_rate = 44100
calculated (4-1) freq = 32552, error = 11548
calculated (3-1) freq = 43402, error = 698
calculated (2-1) freq = 65104, error = 21004
selected prescale value = 2, freq = 43402, error = 698
Unable to handle kernel NULL pointer dereference at virtual address 00000008
pgd = c3ac4000
*pgd=33ac1031, *pte=00000000, *ppte=00000000
Internal error: Oops: 817 [#1]
Modules linked in: ov9650 rt73usb rt2x00usb rt2x00lib mac80211 input_polldev
CPU: 0    Not tainted(2.6.30.4-EmbedSky #55)
PC is at utu2440_audio_open+0xa8/0x18c
LR is at release_console_sem+0x18c/0x1e4
pc : [<c020e118>]    lr : [<c00486cc>]    psr: 60000013
sp : c3a21df0ip : a0000013fp : c3a21e14
r10: c03c5c34r9 : 00020241r8 : c3aac900
r7 : c03c5c34r6 : 00000002r5 : 0000ac44r4 : 00000000
r3 : 00000032r2 : c03752a8r1 : c4824000r0 : 00000042
Flags: nZCvIRQs onFIQs onMode SVC_32ISA ARMSegment user
Control: c000717fTable: 33ac4000DAC: 00000015
Process sh (pid: 458, stack limit = 0xc3a20268)
Stack: (0xc3a21df0 to 0xc3a22000)
1de0:                                     c02d3ee8 00000003 00000003 c3aac900
1e00: c3a2cec0 c03c5bf0 c3a21e3c c3a21e18 c020cd00 c020e080 00000000 c388d380
1e20: c3a2cec0 c3aac900 c3472580 c384f400 c3a21e64 c3a21e40 c00995c4 c020cb80
1e40: 00000000 00000003 00000000 c3aac900 c3a2cec0 c00994f8 c3a21e8c c3a21e68
1e60: c0094ac0 c0099508 c3aac900 c3910f60 00020242 c3a12000 00000022 c3a21ed8
1e80: c3a21eac c3a21e90 c0094d58 c0094a00 00000000 c3910f60 00000000 c3472580
1ea0: c3a21f64 c3a21eb0 c00a1cc4 c0094d04 a0000013 c3a21f28 00000000 00000000
1ec0: c3a21f30 000001b6 00000000 00000000 c0036008 c3a20000 c384f400 c3472580
1ee0: 0024543e 00000003 c3a12005 00000300 00000000 00000000 c3a21f7c c3a21f08
1f00: c00a3254 c00a2f18 c3a21f28 0000001c c3a21f74 c3a20000 00000003 00020242
1f20: 000001b6 c3aac900 00000000 c3a20000 c384f400 c3472580 c00aa9fc 00000003
1f40: c3a12000 00020241 000001b6 ffffff9c c3a20000 00000000 c3a21f94 c3a21f68
1f60: c009491c c00a1ae4 00000000 08000000 00000000 000001b6 00000241 001e0244
1f80: 00000005 c0036008 c3a21fa4 c3a21f98 c00949cc c00948bc 00000000 c3a21fa8
1fa0: c0035e60 c00949b8 000001b6 00000241 001e0244 00020241 000001b6 001de8b8
1fc0: 000001b6 00000241 001e0244 00000005 001e24d8 001df4c0 001e0398 ffffffff
1fe0: be9016c8 be901550 0005d32c 00129208 60000010 001e0244 00000000 00000000
Backtrace:
[<c020e070>] (utu2440_audio_open+0x0/0x18c) from [<c020cd00>] (soundcore_open+0x190/0x210)
[<c020cb70>] (soundcore_open+0x0/0x210) from [<c00995c4>] (chrdev_open+0xcc/0x170)
[<c00994f8>] (chrdev_open+0x0/0x170) from [<c0094ac0>] (__dentry_open+0xd0/0x270)
r7:c00994f8 r6:c3a2cec0 r5:c3aac900 r4:00000000
[<c00949f0>] (__dentry_open+0x0/0x270) from [<c0094d58>] (nameidata_to_filp+0x64/0x6c)
[<c0094cf4>] (nameidata_to_filp+0x0/0x6c) from [<c00a1cc4>] (do_filp_open+0x1f0/0x7e8)
r5:c3472580 r4:00000000
[<c00a1ad4>] (do_filp_open+0x0/0x7e8) from [<c009491c>] (do_sys_open+0x70/0xe8)
[<c00948ac>] (do_sys_open+0x0/0xe8) from [<c00949cc>] (sys_open+0x24/0x28)
r8:c0036008 r7:00000005 r6:001e0244 r5:00000241 r4:000001b6
[<c00949a8>] (sys_open+0x0/0x28) from [<c0035e60>] (ret_fast_syscall+0x0/0x2c)
Code: ebffff82 e597109c e3a03032 e1800286 (e5840008)
---[ end trace 265aa373ffd8985a ]---

y296144646q 发表于 2010-6-7 21:56:58

问下 怎么上传文件啊 我为啥不能啊

y296144646q 发表于 2010-6-7 21:58:34

我想把代码上传给你。。。。

y296144646q 发表于 2010-6-8 15:22:34

对了 最重要的是问下内核的驱动本身是全双工吗如果是 那上面就白问了 就是应用程序的事了。

亚瑟王 发表于 2010-6-8 18:34:47

直接使用天嵌科技提供的2.6.30.4的内核,该内核带的驱动是支持全双工的。

guoyin 发表于 2010-6-9 20:17:44

应该是驱动支持全双工的就可以了吧!还需要改内核吗?

亚瑟王 发表于 2010-6-10 17:47:35

不需要改内核。

shwjl 发表于 2010-11-12 10:22:52

2.6.30.4的内核不支持O_RDWR方式打开/dev/dsp

liguan1024 发表于 2011-2-4 01:14:19

mark 学习一下

anbokeji 发表于 2012-5-22 16:00:52

亚瑟王 发表于 2010-6-10 17:47 static/image/common/back.gif
不需要改内核。

哥我觉得要改啊 它不支持这个读写啊 这两天我也一直在搞   一直找您解决问题 您一直不在

亚瑟王 发表于 2012-5-23 18:57:11

anbokeji 发表于 2012-5-22 16:00 static/image/common/back.gif
哥我觉得要改啊 它不支持这个读写啊 这两天我也一直在搞   一直找您解决问题 您一直不在

亲,明天上班了你问一下售后吧,他那边测试过这个的。
页: [1]
查看完整版本: uda1341在ALSA驱动架构上如何实现全双工