oss uda1341移植到linux-2.6.22(s3c2410)的痛苦,各位大侠救命啊!
时间:2007-11-14
来源:互联网
我现在在向linux-2.6.22 移植uda3141的oss驱动。现在连声音也没有,希望大侠能指点一下。附件是uda1341的代码
问题如下:
1. Audio驱动,我的理解是 打开I2S--> I2S往UDA1341传PCM数据 -->I2S FIFO空 --> 自动从要求DMA传数据 --> DMA所有数据传输完成 --> 传送新的数据给DMA BUFFER。
我如何确定,是I2S根本没有启动传送,还是DMA问题。如何处理?
2. 2.6.22的DMA部分有改动,你有移植过吗?
3. 无声音输出,你觉得是什么问题。
4. 我一直怀疑,我是否因为硬件的内存映射有问题,造成根本就没有实际写到硬件寄存器。如何判断。我也不知道!
希望得到您的回复。
//----------------------------------------------------------
// 启动,初始化uda1341声卡信息。看起来没啥问题。
driver_register : s3c2410iis_driver...
L3_addr:0x16
L3_data:0x40
L3_data:0x29
L3_data:0x83
L3_addr:0x14
L3_data:0x0
L3_data:0x40
L3_data:0x80
L3_data:0xc2
L3_data:0xf9
s3c2410iis_probe(): DMA_CH2 for UDA1341 out
search the channel map for first free, dma_channels:4
mapped channel 2 to 0
s3c2410iis_probe(): DMA_CH1 for UDA1341 in
search the channel map for first free, dma_channels:4
mapped channel 1 to 1
UDA1341 audio driver initialized
//-------------------------------------------------------------------
// cat 一个文件,如下信息。停在最后一行不动了。似乎是只灌完4个buffer,由于没一个buffer空,所以DMA不再请求。
# cat wp.wav > /dev/dsp
audio_open
initialization s3c2410 iis bus.
prescaler = 2
prescaler = 2
s3c2410-uda1341: audio_set_dsp_speed:44100 prescaler:66
write IISCON,[0xf0d00000]:0x33
write IISMOD,[0xf0d0000c]:0xffff
write IISFCON,[0xf0d00004]:0xdd
audio_clear_buf
audio_write : start count=8192
audio_setup_buf(),nbfrags:4,fragsize:8192 (我把buffer改成了4个)
buf 0: start ffc27000 dma 859963392
buf 1: start ffc29000 dma 859971584
buf 2: start ffc2b000 dma 859979776
buf 3: start ffc2d000 dma 859987968
ACH2:write 8192 to 0
audio_write : end count=8192
audio_write : start count=8192
ACH:write 8192 to 1
audio_write : end count=8192
audio_write : start count=8192
ACH2:write 8192 to 2
audio_write : end count=8192
audio_write : start count=8192
ACH2:write 8192 to 3
audio_write : end count=8192
audio_write : start count=8192
audio_write : end count=-512 (为什么有负数)
(停在这里不动了。)
//-------------------------------------------------------------------
// 查看中断情况,发现I2SSDO,I2SSDI 中断次数为0. 也就是将DMA确实根本没中断过。
# cat /proc/interrupts
CPU0
25: 0 s3c s3c2410-wdt
30: 345303 s3c S3C2410 Timer Tick
32: 0 s3c s3c2410-lcd
33: 0 s3c I2SSDO
34: 0 s3c I2SSDI
43: 0 s3c s3c2410-i2c
53: 1 s3c-ext eth0
70: 176 s3c-uart0 s3c2410-uart
71: 415 s3c-uart0 s3c2410-uart
Err: 0
#
#
问题如下:
1. Audio驱动,我的理解是 打开I2S--> I2S往UDA1341传PCM数据 -->I2S FIFO空 --> 自动从要求DMA传数据 --> DMA所有数据传输完成 --> 传送新的数据给DMA BUFFER。
我如何确定,是I2S根本没有启动传送,还是DMA问题。如何处理?
2. 2.6.22的DMA部分有改动,你有移植过吗?
3. 无声音输出,你觉得是什么问题。
4. 我一直怀疑,我是否因为硬件的内存映射有问题,造成根本就没有实际写到硬件寄存器。如何判断。我也不知道!
希望得到您的回复。
//----------------------------------------------------------
// 启动,初始化uda1341声卡信息。看起来没啥问题。
driver_register : s3c2410iis_driver...
L3_addr:0x16
L3_data:0x40
L3_data:0x29
L3_data:0x83
L3_addr:0x14
L3_data:0x0
L3_data:0x40
L3_data:0x80
L3_data:0xc2
L3_data:0xf9
s3c2410iis_probe(): DMA_CH2 for UDA1341 out
search the channel map for first free, dma_channels:4
mapped channel 2 to 0
s3c2410iis_probe(): DMA_CH1 for UDA1341 in
search the channel map for first free, dma_channels:4
mapped channel 1 to 1
UDA1341 audio driver initialized
//-------------------------------------------------------------------
// cat 一个文件,如下信息。停在最后一行不动了。似乎是只灌完4个buffer,由于没一个buffer空,所以DMA不再请求。
# cat wp.wav > /dev/dsp
audio_open
initialization s3c2410 iis bus.
prescaler = 2
prescaler = 2
s3c2410-uda1341: audio_set_dsp_speed:44100 prescaler:66
write IISCON,[0xf0d00000]:0x33
write IISMOD,[0xf0d0000c]:0xffff
write IISFCON,[0xf0d00004]:0xdd
audio_clear_buf
audio_write : start count=8192
audio_setup_buf(),nbfrags:4,fragsize:8192 (我把buffer改成了4个)
buf 0: start ffc27000 dma 859963392
buf 1: start ffc29000 dma 859971584
buf 2: start ffc2b000 dma 859979776
buf 3: start ffc2d000 dma 859987968
ACH2:write 8192 to 0
audio_write : end count=8192
audio_write : start count=8192
ACH:write 8192 to 1
audio_write : end count=8192
audio_write : start count=8192
ACH2:write 8192 to 2
audio_write : end count=8192
audio_write : start count=8192
ACH2:write 8192 to 3
audio_write : end count=8192
audio_write : start count=8192
audio_write : end count=-512 (为什么有负数)
(停在这里不动了。)
//-------------------------------------------------------------------
// 查看中断情况,发现I2SSDO,I2SSDI 中断次数为0. 也就是将DMA确实根本没中断过。
# cat /proc/interrupts
CPU0
25: 0 s3c s3c2410-wdt
30: 345303 s3c S3C2410 Timer Tick
32: 0 s3c s3c2410-lcd
33: 0 s3c I2SSDO
34: 0 s3c I2SSDI
43: 0 s3c s3c2410-i2c
53: 1 s3c-ext eth0
70: 176 s3c-uart0 s3c2410-uart
71: 415 s3c-uart0 s3c2410-uart
Err: 0
#
#
作者: manwjh 发布时间: 2007-11-14
static ssize_t smdk2410_audio_write(struct file *file, const char *buffer,
size_t count, loff_t * ppos)
{
const char *buffer0 = buffer;
audio_stream_t *s = &output_stream;
int chunksize, ret = 0;
DPRINTK("audio_write : start count=%d\n", count);
switch (file->f_flags & O_ACCMODE) {
case O_WRONLY:
case O_RDWR:
break;
default:
return -EPERM;
}
if (!s->buffers && audio_setup_buf(s))
return -ENOMEM;
count &= ~0x03;
while (count > 0) {
audio_buf_t *b = s->buf;
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
if (down_trylock(&b->sem))
break;
} else {
ret = -ERESTARTSYS;
if (down_interruptible(&b->sem))
break;
}
if (audio_channels == 2) {
chunksize = s->fragsize - b->size; //
if (chunksize > count)
chunksize = count;
DPRINTK("ACH2:write %d to %d\n", chunksize, s->buf_idx);
if (copy_from_user(b->start + b->size, buffer, chunksize)) {
up(&b->sem);
return -EFAULT;
}
b->size += chunksize;
} else {
chunksize = (s->fragsize - b->size) >> 1;
if (chunksize > count)
chunksize = count;
DPRINTK("write %d to %d\n", chunksize*2, s->buf_idx);
if (copy_from_user_mono_stereo(b->start + b->size, buffer, chunksize)) {
up(&b->sem);
return -EFAULT;
}
b->size += chunksize*2;
}
buffer += chunksize;
count -= chunksize;
if (b->size < s->fragsize) {
up(&b->sem);
break;
}
if((ret = s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, b->size))) {
printk(PFX"dma enqueue failed.\n");
return ret;
}
b->size = 0;
NEXT_BUF(s, buf);
}
if ((buffer - buffer0))
ret = buffer - buffer0;
DPRINTK("audio_write : end count=%d\n\n", ret);
return ret;
}
static int smdk2410_audio_open(struct inode *inode, struct file *file)
{
int cold = !audio_active;
DPRINTK("audio_open\n");
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
// if (audio_rd_refcount || audio_wr_refcount)
if (audio_rd_refcount) //mdy by wjh, 有人认为这是不能同时录放的原因
return -EBUSY;
audio_rd_refcount++;
} else if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
if (audio_wr_refcount)
return -EBUSY;
audio_wr_refcount++;
} else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
if (audio_rd_refcount || audio_wr_refcount)
return -EBUSY;
audio_rd_refcount++;
audio_wr_refcount++;
} else
return -EINVAL;
if (cold) {
audio_rate = AUDIO_RATE_DEFAULT;
audio_channels = AUDIO_CHANNELS_DEFAULT;
audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;
audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;
init_s3c2410_iis_bus_txrx();
if ((file->f_mode & FMODE_WRITE)){
// init_s3c2410_iis_bus_tx();//del by wjh
audio_clear_buf(&output_stream);
}
if ((file->f_mode & FMODE_READ)){
// init_s3c2410_iis_bus_rx(); //del by wjh
audio_clear_buf(&input_stream);
}
}
return 0;
}
static void init_uda1341(void)
{
unsigned long flags;
uda1341_volume = 62 - ((DEF_VOLUME * 61) / 100);
uda1341_boost = 0;
uda_sampling = DATA2_DEEMP_NONE;
uda_sampling &= ~(DATA2_MUTE);
local_irq_save(flags);
s3c2410_gpio_setpin(S3C2410_GPB2,1); //L3MODE=1
s3c2410_gpio_setpin(S3C2410_GPB3,1); //L3MODE=1
s3c2410_gpio_setpin(S3C2410_GPB4,1); //L3CLOCK=1
local_irq_restore(flags);
//uda1341, initialization status control register
uda1341_l3_address(UDA1341_REG_STATUS); // reset uda1341
uda1341_l3_data(STAT0_RST);
uda1341_l3_data(STAT0_SC_256FS | STAT0_IF_MSB|STAT0_DC_FILTER);
uda1341_l3_data(STAT1 | STAT1_ADC_ON | STAT1_DAC_ON);
//uda1341, set DATA0,DATA1 register
uda1341_l3_address(UDA1341_REG_DATA0);
uda1341_l3_data(DATA0 |DATA0_VOLUME(0x0)); // maximum volume
uda1341_l3_data(DATA1 |DATA1_BASS(uda1341_boost)| DATA1_TREBLE(0));
// uda1341_l3_data((DATA2 |DATA2_DEEMP_NONE) &~(DATA2_MUTE)); //??? wjh
uda1341_l3_data(DATA2 | uda_sampling); /* --;;*/
uda1341_l3_data(EXTADDR(EXT2));
uda1341_l3_data(EXTDATA(EXT2_MIC_GAIN(0x6)) | EXT2_MIXMODE_CH1);
}
/* DMA_CH1 input, DMA_CH2 output */
static int __init audio_init_dma(audio_stream_t * s, char *desc)
{
int ret ;
// s3c2410_dmasrc_t source; //mdy by wjh, because Linux-2.6.22, dma.h changed
enum s3c2410_dmasrc source;
int hwcfg;
unsigned long devaddr;
dmach_t channel;
int dcon;
unsigned int flags = 0;
// DPRINTK("audio init dma: Chanel %d,%s\n,",s->dma_ch,desc); //wjh debug
if(s->dma_ch == DMA_CH2){
channel = 2;
source = S3C2410_DMASRC_MEM;
hwcfg = 3;
devaddr = 0x55000010;
// dcon = 1<<31; //test wjh
// dcon = (1<<31) | (2<<24);
// dcon = 0xa0800000;
dcon = 0xa0900000;
flags = S3C2410_DMAF_AUTOSTART;
ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);
s3c2410_dma_devconfig(channel, source, hwcfg, devaddr);
s3c2410_dma_config(channel, 2, dcon);
s3c2410_dma_set_buffdone_fn(channel, audio_dmaout_done_callback);
s3c2410_dma_setflags(channel, flags);
// ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);
s->dma_ok = 1;
return ret;
}
else if(s->dma_ch == DMA_CH1){
channel = 1;
ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_in, NULL);
s3c2410_dma_set_buffdone_fn(channel, audio_dmain_done_callback);
return ret ;
}
else
return 1;
}
size_t count, loff_t * ppos)
{
const char *buffer0 = buffer;
audio_stream_t *s = &output_stream;
int chunksize, ret = 0;
DPRINTK("audio_write : start count=%d\n", count);
switch (file->f_flags & O_ACCMODE) {
case O_WRONLY:
case O_RDWR:
break;
default:
return -EPERM;
}
if (!s->buffers && audio_setup_buf(s))
return -ENOMEM;
count &= ~0x03;
while (count > 0) {
audio_buf_t *b = s->buf;
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
if (down_trylock(&b->sem))
break;
} else {
ret = -ERESTARTSYS;
if (down_interruptible(&b->sem))
break;
}
if (audio_channels == 2) {
chunksize = s->fragsize - b->size; //
if (chunksize > count)
chunksize = count;
DPRINTK("ACH2:write %d to %d\n", chunksize, s->buf_idx);
if (copy_from_user(b->start + b->size, buffer, chunksize)) {
up(&b->sem);
return -EFAULT;
}
b->size += chunksize;
} else {
chunksize = (s->fragsize - b->size) >> 1;
if (chunksize > count)
chunksize = count;
DPRINTK("write %d to %d\n", chunksize*2, s->buf_idx);
if (copy_from_user_mono_stereo(b->start + b->size, buffer, chunksize)) {
up(&b->sem);
return -EFAULT;
}
b->size += chunksize*2;
}
buffer += chunksize;
count -= chunksize;
if (b->size < s->fragsize) {
up(&b->sem);
break;
}
if((ret = s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, b->size))) {
printk(PFX"dma enqueue failed.\n");
return ret;
}
b->size = 0;
NEXT_BUF(s, buf);
}
if ((buffer - buffer0))
ret = buffer - buffer0;
DPRINTK("audio_write : end count=%d\n\n", ret);
return ret;
}
static int smdk2410_audio_open(struct inode *inode, struct file *file)
{
int cold = !audio_active;
DPRINTK("audio_open\n");
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
// if (audio_rd_refcount || audio_wr_refcount)
if (audio_rd_refcount) //mdy by wjh, 有人认为这是不能同时录放的原因
return -EBUSY;
audio_rd_refcount++;
} else if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
if (audio_wr_refcount)
return -EBUSY;
audio_wr_refcount++;
} else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
if (audio_rd_refcount || audio_wr_refcount)
return -EBUSY;
audio_rd_refcount++;
audio_wr_refcount++;
} else
return -EINVAL;
if (cold) {
audio_rate = AUDIO_RATE_DEFAULT;
audio_channels = AUDIO_CHANNELS_DEFAULT;
audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;
audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;
init_s3c2410_iis_bus_txrx();
if ((file->f_mode & FMODE_WRITE)){
// init_s3c2410_iis_bus_tx();//del by wjh
audio_clear_buf(&output_stream);
}
if ((file->f_mode & FMODE_READ)){
// init_s3c2410_iis_bus_rx(); //del by wjh
audio_clear_buf(&input_stream);
}
}
return 0;
}
static void init_uda1341(void)
{
unsigned long flags;
uda1341_volume = 62 - ((DEF_VOLUME * 61) / 100);
uda1341_boost = 0;
uda_sampling = DATA2_DEEMP_NONE;
uda_sampling &= ~(DATA2_MUTE);
local_irq_save(flags);
s3c2410_gpio_setpin(S3C2410_GPB2,1); //L3MODE=1
s3c2410_gpio_setpin(S3C2410_GPB3,1); //L3MODE=1
s3c2410_gpio_setpin(S3C2410_GPB4,1); //L3CLOCK=1
local_irq_restore(flags);
//uda1341, initialization status control register
uda1341_l3_address(UDA1341_REG_STATUS); // reset uda1341
uda1341_l3_data(STAT0_RST);
uda1341_l3_data(STAT0_SC_256FS | STAT0_IF_MSB|STAT0_DC_FILTER);
uda1341_l3_data(STAT1 | STAT1_ADC_ON | STAT1_DAC_ON);
//uda1341, set DATA0,DATA1 register
uda1341_l3_address(UDA1341_REG_DATA0);
uda1341_l3_data(DATA0 |DATA0_VOLUME(0x0)); // maximum volume
uda1341_l3_data(DATA1 |DATA1_BASS(uda1341_boost)| DATA1_TREBLE(0));
// uda1341_l3_data((DATA2 |DATA2_DEEMP_NONE) &~(DATA2_MUTE)); //??? wjh
uda1341_l3_data(DATA2 | uda_sampling); /* --;;*/
uda1341_l3_data(EXTADDR(EXT2));
uda1341_l3_data(EXTDATA(EXT2_MIC_GAIN(0x6)) | EXT2_MIXMODE_CH1);
}
/* DMA_CH1 input, DMA_CH2 output */
static int __init audio_init_dma(audio_stream_t * s, char *desc)
{
int ret ;
// s3c2410_dmasrc_t source; //mdy by wjh, because Linux-2.6.22, dma.h changed
enum s3c2410_dmasrc source;
int hwcfg;
unsigned long devaddr;
dmach_t channel;
int dcon;
unsigned int flags = 0;
// DPRINTK("audio init dma: Chanel %d,%s\n,",s->dma_ch,desc); //wjh debug
if(s->dma_ch == DMA_CH2){
channel = 2;
source = S3C2410_DMASRC_MEM;
hwcfg = 3;
devaddr = 0x55000010;
// dcon = 1<<31; //test wjh
// dcon = (1<<31) | (2<<24);
// dcon = 0xa0800000;
dcon = 0xa0900000;
flags = S3C2410_DMAF_AUTOSTART;
ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);
s3c2410_dma_devconfig(channel, source, hwcfg, devaddr);
s3c2410_dma_config(channel, 2, dcon);
s3c2410_dma_set_buffdone_fn(channel, audio_dmaout_done_callback);
s3c2410_dma_setflags(channel, flags);
// ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);
s->dma_ok = 1;
return ret;
}
else if(s->dma_ch == DMA_CH1){
channel = 1;
ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_in, NULL);
s3c2410_dma_set_buffdone_fn(channel, audio_dmain_done_callback);
return ret ;
}
else
return 1;
}
作者: manwjh 发布时间: 2007-11-14
static int s3c2410iis_probe(struct device *dev) {
struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
unsigned long flags;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
printk(KERN_INFO PFX "failed to get memory region resouce\n");
return -ENOENT;
}
// DPRINTK("s3c2410iis_probe(): get resource...\n"); //wjh debug
iis_base = (void *)S3C24XX_VA_IIS ;
if (iis_base == 0) {
printk(KERN_INFO PFX "failed to ioremap() region\n");
return -EINVAL;
}
// DPRINTK("s3c2410iis_probe()-iis_base:%d\n",iis_base); //wjh debug
iis_clock = clk_get(dev, "iis");
if (iis_clock == NULL) {
printk(KERN_INFO PFX "failed to find clock source\n");
return -ENOENT;
}
// DPRINTK("s3c2410iis_probe()-iis_clock:%d\n",iis_clock); //wjh debug
clk_enable(iis_clock);
local_irq_save(flags);
/* GPB 4: L3CLOCK, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
// s3c2410_gpio_pullup(S3C2410_GPB4, 1);
/* GPB 3: L3DATA, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB3,S3C2410_GPB3_OUTP);
/* GPB 2: L3MODE, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB2,S3C2410_GPB2_OUTP);
// s3c2410_gpio_pullup(S3C2410_GPB2, 1);
/* GPE 3: I2SSDI */
s3c2410_gpio_cfgpin(S3C2410_GPE3,S3C2410_GPE3_I2SSDI);
s3c2410_gpio_pullup(S3C2410_GPE3, 1);
/* GPE 0: I2SLRCK */
s3c2410_gpio_cfgpin(S3C2410_GPE0,S3C2410_GPE0_I2SLRCK);
s3c2410_gpio_pullup(S3C2410_GPE0, 1);
/* GPE 1: I2SSCLK */
s3c2410_gpio_cfgpin(S3C2410_GPE1,S3C2410_GPE1_I2SSCLK);
s3c2410_gpio_pullup(S3C2410_GPE1, 1);
/* GPE 2: CDCLK */
s3c2410_gpio_cfgpin(S3C2410_GPE2,S3C2410_GPE2_CDCLK);
s3c2410_gpio_pullup(S3C2410_GPE2, 1);
/* GPE 4: I2SSDO */
s3c2410_gpio_cfgpin(S3C2410_GPE4,S3C2410_GPE4_I2SSDO);
s3c2410_gpio_pullup(S3C2410_GPE4, 1);
local_irq_restore(flags);
init_s3c2410_iis_bus(); /* clear I2S controller of S3C2410, IISPSR,IISCON,IISMOD,IISFCON = 0x0s */
init_uda1341();
//audio DMA initialization
DPRINTK("s3c2410iis_probe(): DMA_CH2 for UDA1341 out\n"); //wjh debug
output_stream.dma_ch = DMA_CH2;
if (audio_init_dma(&output_stream, "UDA1341 out")) {
audio_clear_dma(&output_stream,&s3c2410iis_dma_out);
printk( KERN_WARNING AUDIO_NAME_VERBOSE
": unable to get DMA channels\n" );
return -EBUSY;
}
DPRINTK("s3c2410iis_probe(): DMA_CH1 for UDA1341 in\n"); //wjh debug
input_stream.dma_ch = DMA_CH1;
if (audio_init_dma(&input_stream, "UDA1341 in")) {
audio_clear_dma(&input_stream,&s3c2410iis_dma_in);
printk( KERN_WARNING AUDIO_NAME_VERBOSE
": unable to get DMA channels\n" );
return -EBUSY;
}
audio_dev_dsp = register_sound_dsp(&smdk2410_audio_fops, -1);
audio_dev_mixer = register_sound_mixer(&smdk2410_mixer_fops, -1);
printk(AUDIO_NAME_VERBOSE " initialized\n");
return 0;
}
struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
unsigned long flags;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
printk(KERN_INFO PFX "failed to get memory region resouce\n");
return -ENOENT;
}
// DPRINTK("s3c2410iis_probe(): get resource...\n"); //wjh debug
iis_base = (void *)S3C24XX_VA_IIS ;
if (iis_base == 0) {
printk(KERN_INFO PFX "failed to ioremap() region\n");
return -EINVAL;
}
// DPRINTK("s3c2410iis_probe()-iis_base:%d\n",iis_base); //wjh debug
iis_clock = clk_get(dev, "iis");
if (iis_clock == NULL) {
printk(KERN_INFO PFX "failed to find clock source\n");
return -ENOENT;
}
// DPRINTK("s3c2410iis_probe()-iis_clock:%d\n",iis_clock); //wjh debug
clk_enable(iis_clock);
local_irq_save(flags);
/* GPB 4: L3CLOCK, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
// s3c2410_gpio_pullup(S3C2410_GPB4, 1);
/* GPB 3: L3DATA, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB3,S3C2410_GPB3_OUTP);
/* GPB 2: L3MODE, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB2,S3C2410_GPB2_OUTP);
// s3c2410_gpio_pullup(S3C2410_GPB2, 1);
/* GPE 3: I2SSDI */
s3c2410_gpio_cfgpin(S3C2410_GPE3,S3C2410_GPE3_I2SSDI);
s3c2410_gpio_pullup(S3C2410_GPE3, 1);
/* GPE 0: I2SLRCK */
s3c2410_gpio_cfgpin(S3C2410_GPE0,S3C2410_GPE0_I2SLRCK);
s3c2410_gpio_pullup(S3C2410_GPE0, 1);
/* GPE 1: I2SSCLK */
s3c2410_gpio_cfgpin(S3C2410_GPE1,S3C2410_GPE1_I2SSCLK);
s3c2410_gpio_pullup(S3C2410_GPE1, 1);
/* GPE 2: CDCLK */
s3c2410_gpio_cfgpin(S3C2410_GPE2,S3C2410_GPE2_CDCLK);
s3c2410_gpio_pullup(S3C2410_GPE2, 1);
/* GPE 4: I2SSDO */
s3c2410_gpio_cfgpin(S3C2410_GPE4,S3C2410_GPE4_I2SSDO);
s3c2410_gpio_pullup(S3C2410_GPE4, 1);
local_irq_restore(flags);
init_s3c2410_iis_bus(); /* clear I2S controller of S3C2410, IISPSR,IISCON,IISMOD,IISFCON = 0x0s */
init_uda1341();
//audio DMA initialization
DPRINTK("s3c2410iis_probe(): DMA_CH2 for UDA1341 out\n"); //wjh debug
output_stream.dma_ch = DMA_CH2;
if (audio_init_dma(&output_stream, "UDA1341 out")) {
audio_clear_dma(&output_stream,&s3c2410iis_dma_out);
printk( KERN_WARNING AUDIO_NAME_VERBOSE
": unable to get DMA channels\n" );
return -EBUSY;
}
DPRINTK("s3c2410iis_probe(): DMA_CH1 for UDA1341 in\n"); //wjh debug
input_stream.dma_ch = DMA_CH1;
if (audio_init_dma(&input_stream, "UDA1341 in")) {
audio_clear_dma(&input_stream,&s3c2410iis_dma_in);
printk( KERN_WARNING AUDIO_NAME_VERBOSE
": unable to get DMA channels\n" );
return -EBUSY;
}
audio_dev_dsp = register_sound_dsp(&smdk2410_audio_fops, -1);
audio_dev_mixer = register_sound_mixer(&smdk2410_mixer_fops, -1);
printk(AUDIO_NAME_VERBOSE " initialized\n");
return 0;
}
作者: manwjh 发布时间: 2007-11-14
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28