X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Foss%2Fau1000.c;h=eacb0aef21e1831d6795225aba3b6d6cc00c46e4;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=ccfbad2dd02fbba35cea528f0d703659fc7098c5;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c index ccfbad2dd..eacb0aef2 100644 --- a/sound/oss/au1000.c +++ b/sound/oss/au1000.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -66,21 +67,20 @@ #include #include #include -#include +#include +#include + #include #include -#include -#include -#include +#include +#include /* --------------------------------------------------------------------- */ #undef OSS_DOCUMENTED_MIXER_SEMANTICS -#define AU1000_DEBUG +#undef AU1000_DEBUG #undef AU1000_VERBOSE_DEBUG -#define USE_COHERENT_DMA - #define AU1000_MODULE_NAME "Au1000 audio" #define PFX AU1000_MODULE_NAME @@ -100,7 +100,7 @@ /* Boot options */ static int vra = 0; // 0 = no VRA, 1 = use VRA if codec supports it -MODULE_PARM(vra, "i"); +module_param(vra, bool, 0); MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it"); @@ -116,14 +116,14 @@ struct au1000_state { struct proc_dir_entry *ac97_ps; #endif /* AU1000_DEBUG */ - struct ac97_codec *codec; + struct ac97_codec codec; unsigned codec_base_caps;// AC'97 reg 00h, "Reset Register" unsigned codec_ext_caps; // AC'97 reg 28h, "Extended Audio ID" int no_vra; // do not use VRA spinlock_t lock; - struct semaphore open_sem; - struct semaphore sem; + struct mutex open_mutex; + struct mutex sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -191,35 +191,6 @@ static inline unsigned ld2(unsigned int x) return r; } - -#ifdef USE_COHERENT_DMA -static inline void * dma_alloc(size_t size, dma_addr_t * dma_handle) -{ - void* ret = (void *)__get_free_pages(GFP_ATOMIC | GFP_DMA, - get_order(size)); - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_phys(ret); - } - return ret; -} - -static inline void dma_free(size_t size, void* va, dma_addr_t dma_handle) -{ - free_pages((unsigned long)va, get_order(size)); -} -#else -static inline void * dma_alloc(size_t size, dma_addr_t * dma_handle) -{ - return pci_alloc_consistent(NULL, size, dma_handle); -} - -static inline void dma_free(size_t size, void* va, dma_addr_t dma_handle) -{ - pci_free_consistent(NULL, size, va, dma_handle); -} -#endif - /* --------------------------------------------------------------------- */ static void au1000_delay(int msec) @@ -356,17 +327,17 @@ static void set_adc_rate(struct au1000_state *s, unsigned rate) adc->src_factor = 1; - ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS); + ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS); rate = rate > 48000 ? 48000 : rate; // enable VRA - wrcodec(s->codec, AC97_EXTENDED_STATUS, + wrcodec(&s->codec, AC97_EXTENDED_STATUS, ac97_extstat | AC97_EXTSTAT_VRA); // now write the sample rate - wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate); + wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate); // read it back for actual supported rate - adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE); + adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE); #ifdef AU1000_VERBOSE_DEBUG dbg("%s: set to %d Hz", __FUNCTION__, adc_rate); @@ -374,11 +345,11 @@ static void set_adc_rate(struct au1000_state *s, unsigned rate) // some codec's don't allow unequal DAC and ADC rates, in which case // writing one rate reg actually changes both. - dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE); + dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE); if (dac->num_channels > 2) - wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate); + wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate); if (dac->num_channels > 4) - wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate); + wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate); adc->sample_rate = adc_rate; dac->sample_rate = dac_rate; @@ -401,23 +372,23 @@ static void set_dac_rate(struct au1000_state *s, unsigned rate) dac->src_factor = 1; - ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS); + ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS); rate = rate > 48000 ? 48000 : rate; // enable VRA - wrcodec(s->codec, AC97_EXTENDED_STATUS, + wrcodec(&s->codec, AC97_EXTENDED_STATUS, ac97_extstat | AC97_EXTSTAT_VRA); // now write the sample rate - wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate); + wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate); // I don't support different sample rates for multichannel, // so make these channels the same. if (dac->num_channels > 2) - wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate); + wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate); if (dac->num_channels > 4) - wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate); + wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate); // read it back for actual supported rate - dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE); + dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE); #ifdef AU1000_VERBOSE_DEBUG dbg("%s: set to %d Hz", __FUNCTION__, dac_rate); @@ -425,7 +396,7 @@ static void set_dac_rate(struct au1000_state *s, unsigned rate) // some codec's don't allow unequal DAC and ADC rates, in which case // writing one rate reg actually changes both. - adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE); + adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE); dac->sample_rate = dac_rate; adc->sample_rate = adc_rate; @@ -594,7 +565,7 @@ static void start_adc(struct au1000_state *s) #define DMABUF_DEFAULTORDER (17-PAGE_SHIFT) #define DMABUF_MINORDER 1 -extern inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db) +static inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db) { struct page *page, *pend; @@ -603,8 +574,11 @@ extern inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db) pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); for (page = virt_to_page(db->rawbuf); page <= pend; page++) - mem_map_unreserve(page); - dma_free(PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr); + ClearPageReserved(page); + dma_free_noncoherent(NULL, + PAGE_SIZE << db->buforder, + db->rawbuf, + db->dmaaddr); } db->rawbuf = db->nextIn = db->nextOut = NULL; db->mapped = db->ready = 0; @@ -622,18 +596,20 @@ static int prog_dmabuf(struct au1000_state *s, struct dmabuf *db) db->ready = db->mapped = 0; for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) - if ((db->rawbuf = dma_alloc(PAGE_SIZE << order, - &db->dmaaddr))) + if ((db->rawbuf = dma_alloc_noncoherent(NULL, + PAGE_SIZE << order, + &db->dmaaddr, + 0))) break; if (!db->rawbuf) return -ENOMEM; db->buforder = order; /* now mark the pages as reserved; - otherwise remap_page_range doesn't do what we want */ + otherwise remap_pfn_range doesn't do what we want */ pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); for (page = virt_to_page(db->rawbuf); page <= pend; page++) - mem_map_reserve(page); + SetPageReserved(page); } db->cnt_factor = 1; @@ -693,14 +669,14 @@ static int prog_dmabuf(struct au1000_state *s, struct dmabuf *db) return 0; } -extern inline int prog_dmabuf_adc(struct au1000_state *s) +static inline int prog_dmabuf_adc(struct au1000_state *s) { stop_adc(s); return prog_dmabuf(s, &s->dma_adc); } -extern inline int prog_dmabuf_dac(struct au1000_state *s) +static inline int prog_dmabuf_dac(struct au1000_state *s) { stop_dac(s); return prog_dmabuf(s, &s->dma_dac); @@ -708,7 +684,7 @@ extern inline int prog_dmabuf_dac(struct au1000_state *s) /* hold spinlock for the following */ -static void dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct au1000_state *s = (struct au1000_state *) dev_id; struct dmabuf *dac = &s->dma_dac; @@ -723,7 +699,7 @@ static void dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) if ((buff_done = get_dma_buffer_done(dac->dmanr)) == 0) { /* fastpath out, to ease interrupt sharing */ - return; + return IRQ_HANDLED; } spin_lock(&s->lock); @@ -786,10 +762,12 @@ static void dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) wake_up(&dac->wait); spin_unlock(&s->lock); + + return IRQ_HANDLED; } -static void adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct au1000_state *s = (struct au1000_state *) dev_id; struct dmabuf *adc = &s->dma_adc; @@ -804,7 +782,7 @@ static void adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) if ((buff_done = get_dma_buffer_done(adc->dmanr)) == 0) { /* fastpath out, to ease interrupt sharing */ - return; + return IRQ_HANDLED; } spin_lock(&s->lock); @@ -816,7 +794,7 @@ static void adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) stop_adc(s); adc->error++; err("adc overrun"); - return; + return IRQ_NONE; } adc->nextIn += adc->dma_fragsize; @@ -853,7 +831,7 @@ static void adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) adc->error++; err("adc overrun"); spin_unlock(&s->lock); - return; + return IRQ_NONE; } adc->nextIn += 2*adc->dma_fragsize; @@ -873,6 +851,8 @@ static void adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) wake_up(&adc->wait); spin_unlock(&s->lock); + + return IRQ_HANDLED; } /* --------------------------------------------------------------------- */ @@ -904,7 +884,7 @@ static int au1000_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct au1000_state *s = (struct au1000_state *)file->private_data; - struct ac97_codec *codec = s->codec; + struct ac97_codec *codec = &s->codec; return mixdev_ioctl(codec, cmd, arg); } @@ -1128,7 +1108,7 @@ static ssize_t au1000_read(struct file *file, char *buffer, count *= db->cnt_factor; - down(&s->sem); + mutex_lock(&s->sem); add_wait_queue(&db->wait, &wait); while (count > 0) { @@ -1147,14 +1127,14 @@ static ssize_t au1000_read(struct file *file, char *buffer, ret = -EAGAIN; goto out; } - up(&s->sem); + mutex_unlock(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out2; } - down(&s->sem); + mutex_lock(&s->sem); } } while (avail <= 0); @@ -1181,7 +1161,7 @@ static ssize_t au1000_read(struct file *file, char *buffer, } // while (count > 0) out: - up(&s->sem); + mutex_unlock(&s->sem); out2: remove_wait_queue(&db->wait, &wait); set_current_state(TASK_RUNNING); @@ -1209,7 +1189,7 @@ static ssize_t au1000_write(struct file *file, const char *buffer, count *= db->cnt_factor; - down(&s->sem); + mutex_lock(&s->sem); add_wait_queue(&db->wait, &wait); while (count > 0) { @@ -1226,14 +1206,14 @@ static ssize_t au1000_write(struct file *file, const char *buffer, ret = -EAGAIN; goto out; } - up(&s->sem); + mutex_unlock(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out2; } - down(&s->sem); + mutex_lock(&s->sem); } } while (avail <= 0); @@ -1262,7 +1242,7 @@ static ssize_t au1000_write(struct file *file, const char *buffer, } // while (count > 0) out: - up(&s->sem); + mutex_unlock(&s->sem); out2: remove_wait_queue(&db->wait, &wait); set_current_state(TASK_RUNNING); @@ -1317,10 +1297,10 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma) unsigned long size; int ret = 0; - dbg(__FUNCTION__); + dbg("%s", __FUNCTION__); lock_kernel(); - down(&s->sem); + mutex_lock(&s->sem); if (vma->vm_flags & VM_WRITE) db = &s->dma_dac; else if (vma->vm_flags & VM_READ) @@ -1338,7 +1318,7 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma) ret = -EINVAL; goto out; } - if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), + if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) { ret = -EAGAIN; goto out; @@ -1346,7 +1326,7 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags &= ~VM_IO; db->mapped = 1; out: - up(&s->sem); + mutex_unlock(&s->sem); unlock_kernel(); return ret; } @@ -1499,9 +1479,9 @@ static int au1000_ioctl(struct inode *inode, struct file *file, s->dma_dac.num_channels = val ? 2 : 1; if (s->codec_ext_caps & AC97_EXT_DACS) { // disable surround and center/lfe in AC'97 - u16 ext_stat = rdcodec(s->codec, + u16 ext_stat = rdcodec(&s->codec, AC97_EXTENDED_STATUS); - wrcodec(s->codec, AC97_EXTENDED_STATUS, + wrcodec(&s->codec, AC97_EXTENDED_STATUS, ext_stat | (AC97_EXTSTAT_PRI | AC97_EXTSTAT_PRJ | AC97_EXTSTAT_PRK)); @@ -1551,9 +1531,9 @@ static int au1000_ioctl(struct inode *inode, struct file *file, // disable surround and center/lfe // channels in AC'97 u16 ext_stat = - rdcodec(s->codec, + rdcodec(&s->codec, AC97_EXTENDED_STATUS); - wrcodec(s->codec, + wrcodec(&s->codec, AC97_EXTENDED_STATUS, ext_stat | (AC97_EXTSTAT_PRI | AC97_EXTSTAT_PRJ | @@ -1562,14 +1542,14 @@ static int au1000_ioctl(struct inode *inode, struct file *file, // enable surround, center/lfe // channels in AC'97 u16 ext_stat = - rdcodec(s->codec, + rdcodec(&s->codec, AC97_EXTENDED_STATUS); ext_stat &= ~AC97_EXTSTAT_PRJ; if (val == 6) ext_stat &= ~(AC97_EXTSTAT_PRI | AC97_EXTSTAT_PRK); - wrcodec(s->codec, + wrcodec(&s->codec, AC97_EXTENDED_STATUS, ext_stat); } @@ -1831,7 +1811,7 @@ static int au1000_ioctl(struct inode *inode, struct file *file, return -EINVAL; } - return mixdev_ioctl(s->codec, cmd, arg); + return mixdev_ioctl(&s->codec, cmd, arg); } @@ -1851,21 +1831,21 @@ static int au1000_open(struct inode *inode, struct file *file) file->private_data = s; /* wait for device to become free */ - down(&s->open_sem); + mutex_lock(&s->open_mutex); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - up(&s->open_sem); + mutex_unlock(&s->open_mutex); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - up(&s->open_sem); + mutex_unlock(&s->open_mutex); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - down(&s->open_sem); + mutex_lock(&s->open_mutex); } stop_dac(s); @@ -1901,8 +1881,8 @@ static int au1000_open(struct inode *inode, struct file *file) } s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - up(&s->open_sem); - init_MUTEX(&s->sem); + mutex_unlock(&s->open_mutex); + mutex_init(&s->sem); return nonseekable_open(inode, file); } @@ -1918,7 +1898,7 @@ static int au1000_release(struct inode *inode, struct file *file) lock_kernel(); } - down(&s->open_sem); + mutex_lock(&s->open_mutex); if (file->f_mode & FMODE_WRITE) { stop_dac(s); dealloc_dmabuf(s, &s->dma_dac); @@ -1928,7 +1908,7 @@ static int au1000_release(struct inode *inode, struct file *file) dealloc_dmabuf(s, &s->dma_adc); } s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE)); - up(&s->open_sem); + mutex_unlock(&s->open_mutex); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -1982,7 +1962,7 @@ static int proc_au1000_dump(char *buf, char **start, off_t fpos, len += sprintf(buf + len, "----------------------\n"); for (cnt = 0; cnt <= 0x7e; cnt += 2) len += sprintf(buf + len, "reg %02x = %04x\n", - cnt, rdcodec(s->codec, cnt)); + cnt, rdcodec(&s->codec, cnt)); if (fpos >= len) { *start = buf; @@ -2009,32 +1989,27 @@ static int __devinit au1000_probe(void) { struct au1000_state *s = &au1000_state; int val; +#ifdef AU1000_DEBUG char proc_str[80]; +#endif memset(s, 0, sizeof(struct au1000_state)); init_waitqueue_head(&s->dma_adc.wait); init_waitqueue_head(&s->dma_dac.wait); init_waitqueue_head(&s->open_wait); - init_MUTEX(&s->open_sem); + mutex_init(&s->open_mutex); spin_lock_init(&s->lock); - - s->codec = ac97_alloc_codec(); - if(s->codec == NULL) - { - error("Out of memory"); - return -1; - } - s->codec->private_data = s; - s->codec->id = 0; - s->codec->codec_read = rdcodec; - s->codec->codec_write = wrcodec; - s->codec->codec_wait = waitcodec; + s->codec.private_data = s; + s->codec.id = 0; + s->codec.codec_read = rdcodec; + s->codec.codec_write = wrcodec; + s->codec.codec_wait = waitcodec; - if (!request_region(virt_to_phys((void *) AC97C_CONFIG), + if (!request_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14, AU1000_MODULE_NAME)) { err("AC'97 ports in use"); - goto err_codec; + return -1; } // Allocate the DMA Channels if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX, @@ -2056,25 +2031,17 @@ static int __devinit au1000_probe(void) s->dma_dac.dmanr, get_dma_done_irq(s->dma_dac.dmanr), s->dma_adc.dmanr, get_dma_done_irq(s->dma_adc.dmanr)); -#ifdef USE_COHERENT_DMA // enable DMA coherency in read/write DMA channels set_dma_mode(s->dma_dac.dmanr, get_dma_mode(s->dma_dac.dmanr) & ~DMA_NC); set_dma_mode(s->dma_adc.dmanr, get_dma_mode(s->dma_adc.dmanr) & ~DMA_NC); -#else - // disable DMA coherency in read/write DMA channels - set_dma_mode(s->dma_dac.dmanr, - get_dma_mode(s->dma_dac.dmanr) | DMA_NC); - set_dma_mode(s->dma_adc.dmanr, - get_dma_mode(s->dma_adc.dmanr) | DMA_NC); -#endif /* register devices */ if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0) goto err_dev1; - if ((s->codec->dev_mixer = + if ((s->codec.dev_mixer = register_sound_mixer(&au1000_mixer_fops, -1)) < 0) goto err_dev2; @@ -2107,11 +2074,11 @@ static int __devinit au1000_probe(void) au_writel(0, AC97C_CONFIG); /* codec init */ - if (!ac97_probe_codec(s->codec)) + if (!ac97_probe_codec(&s->codec)) goto err_dev3; - s->codec_base_caps = rdcodec(s->codec, AC97_RESET); - s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID); + s->codec_base_caps = rdcodec(&s->codec, AC97_RESET); + s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID); info("AC'97 Base/Extended ID = %04x/%04x", s->codec_base_caps, s->codec_ext_caps); @@ -2123,12 +2090,12 @@ static int __devinit au1000_probe(void) * ALTPCM). ac97_codec.c does not handle detection * of this channel correctly. */ - s->codec->supported_mixers |= SOUND_MASK_ALTPCM; + s->codec.supported_mixers |= SOUND_MASK_ALTPCM; /* * Now set AUX_OUT's default volume. */ val = 0x4343; - mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_ALTPCM, + mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM, (unsigned long) &val); if (!(s->codec_ext_caps & AC97_EXTID_VRA)) { @@ -2136,8 +2103,8 @@ static int __devinit au1000_probe(void) s->no_vra = 1; } else if (!vra) { // Boot option says disable VRA - u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS); - wrcodec(s->codec, AC97_EXTENDED_STATUS, + u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS); + wrcodec(&s->codec, AC97_EXTENDED_STATUS, ac97_extstat & ~AC97_EXTSTAT_VRA); s->no_vra = 1; } @@ -2146,20 +2113,38 @@ static int __devinit au1000_probe(void) /* set mic to be the recording source */ val = SOUND_MASK_MIC; - mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, + mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val); #ifdef AU1000_DEBUG sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME, - s->codec->id); + s->codec.id); s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL, - ac97_read_proc, s->codec); + ac97_read_proc, &s->codec); +#endif + +#ifdef CONFIG_MIPS_XXS1500 + /* deassert eapd */ + wrcodec(&s->codec, AC97_POWER_CONTROL, + rdcodec(&s->codec, AC97_POWER_CONTROL) & ~0x8000); + /* mute a number of signals which seem to be causing problems + * if not muted. + */ + wrcodec(&s->codec, AC97_PCBEEP_VOL, 0x8000); + wrcodec(&s->codec, AC97_PHONE_VOL, 0x8008); + wrcodec(&s->codec, AC97_MIC_VOL, 0x8008); + wrcodec(&s->codec, AC97_LINEIN_VOL, 0x8808); + wrcodec(&s->codec, AC97_CD_VOL, 0x8808); + wrcodec(&s->codec, AC97_VIDEO_VOL, 0x8808); + wrcodec(&s->codec, AC97_AUX_VOL, 0x8808); + wrcodec(&s->codec, AC97_PCMOUT_VOL, 0x0808); + wrcodec(&s->codec, AC97_GENERAL_PURPOSE, 0x2000); #endif return 0; err_dev3: - unregister_sound_mixer(s->codec->dev_mixer); + unregister_sound_mixer(s->codec.dev_mixer); err_dev2: unregister_sound_dsp(s->dev_audio); err_dev1: @@ -2167,9 +2152,7 @@ static int __devinit au1000_probe(void) err_dma2: free_au1000_dma(s->dma_dac.dmanr); err_dma1: - release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14); - err_codec: - ac97_release_codec(s->codec); + release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14); return -1; } @@ -2186,10 +2169,9 @@ static void au1000_remove(void) synchronize_irq(); free_au1000_dma(s->dma_adc.dmanr); free_au1000_dma(s->dma_dac.dmanr); - release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14); + release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14); unregister_sound_dsp(s->dev_audio); - unregister_sound_mixer(s->codec->dev_mixer); - ac97_release_codec(s->codec); + unregister_sound_mixer(s->codec.dev_mixer); } static int __init init_au1000(void) @@ -2218,7 +2200,7 @@ static int __init au1000_setup(char *options) if (!options || !*options) return 0; - while (this_opt = strsep(&options, ",")) { + while ((this_opt = strsep(&options, ","))) { if (!*this_opt) continue; if (!strncmp(this_opt, "vra", 3)) {