patch-2.4.19 linux-2.4.19/drivers/sound/nec_vrc5477.c
Next file: linux-2.4.19/drivers/sound/nm256_audio.c
Previous file: linux-2.4.19/drivers/sound/msnd_pinnacle.c
Back to the patch index
Back to the overall index
- Lines: 741
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/sound/nec_vrc5477.c
- Orig date:
Thu Oct 25 13:53:52 2001
diff -urN linux-2.4.18/drivers/sound/nec_vrc5477.c linux-2.4.19/drivers/sound/nec_vrc5477.c
@@ -6,6 +6,8 @@
* AC97 sound dirver for NEC Vrc5477 chip (an integrated,
* multi-function controller chip for MIPS CPUs)
*
+ * VRA support Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -83,17 +85,25 @@
#include <asm/uaccess.h>
#include <asm/hardirq.h>
-#include <asm/ddb5xxx/debug.h>
+/* -------------------debug macros -------------------------------------- */
+/* #undef VRC5477_AC97_DEBUG */
+#define VRC5477_AC97_DEBUG
#undef VRC5477_AC97_VERBOSE_DEBUG
+/* #define VRC5477_AC97_VERBOSE_DEBUG */
-/* one must turn on CONFIG_LL_DEBUG before VERBOSE_DEBUG is turned */
#if defined(VRC5477_AC97_VERBOSE_DEBUG)
-#if !defined(CONFIG_LL_DEBUG)
-#error "You must turn CONFIG_LL_DEBUG"
-#endif
+#define VRC5477_AC97_DEBUG
#endif
+#if defined(VRC5477_AC97_DEBUG)
+#include <linux/kernel.h>
+#define ASSERT(x) if (!(x)) { \
+ panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+#else
+#define ASSERT(x)
+#endif /* VRC5477_AC97_DEBUG */
+
#if defined(VRC5477_AC97_VERBOSE_DEBUG)
static u16 inTicket=0; /* check sync between intr & write */
static u16 outTicket=0;
@@ -179,16 +189,17 @@
unsigned long io;
unsigned int irq;
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
/* debug /proc entry */
struct proc_dir_entry *ps;
struct proc_dir_entry *ac97_ps;
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
struct ac97_codec codec;
unsigned dacChannels, adcChannels;
unsigned short dacRate, adcRate;
+ unsigned short extended_status;
spinlock_t lock;
struct semaphore open_sem;
@@ -226,7 +237,7 @@
/* --------------------------------------------------------------------- */
-extern inline unsigned ld2(unsigned int x)
+static inline unsigned ld2(unsigned int x)
{
unsigned r = 0;
@@ -275,7 +286,7 @@
(VRC5477_CODEC_RD_RRDYA | VRC5477_CODEC_RD_RRDYD) ) {
/* we get either addr or data, or both */
if (result & VRC5477_CODEC_RD_RRDYA) {
- MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+ ASSERT(addr == ((result >> 16) & 0x7f) );
}
if (result & VRC5477_CODEC_RD_RRDYD) {
break;
@@ -315,6 +326,43 @@
while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
}
+static int ac97_codec_not_present(struct ac97_codec *codec)
+{
+ struct vrc5477_ac97_state *s =
+ (struct vrc5477_ac97_state *)codec->private_data;
+ unsigned long flags;
+ unsigned short count = 0xffff;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ /* wait until we can access codec registers */
+ do {
+ if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
+ break;
+ } while (--count);
+
+ if (count == 0) {
+ spin_unlock_irqrestore(&s->lock, flags);
+ return -1;
+ }
+
+ /* write 0 to reset */
+ outl((AC97_RESET << 16) | 0, s->io + VRC5477_CODEC_WR);
+
+ /* test whether we get a response from ac97 chip */
+ count = 0xffff;
+ do {
+ if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
+ break;
+ } while (--count);
+
+ if (count == 0) {
+ spin_unlock_irqrestore(&s->lock, flags);
+ return -1;
+ }
+ spin_unlock_irqrestore(&s->lock, flags);
+ return 0;
+}
/* --------------------------------------------------------------------- */
@@ -345,14 +393,16 @@
static void set_dac_rate(struct vrc5477_ac97_state *s, unsigned rate)
{
+ if(s->extended_status & AC97_EXTSTAT_VRA) {
wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, rate);
- s->dacRate = rate;
+ s->dacRate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+ }
}
/* --------------------------------------------------------------------- */
-extern inline void
+static inline void
stop_dac(struct vrc5477_ac97_state *s)
{
struct dmabuf* db = &s->dma_dac;
@@ -408,7 +458,7 @@
}
/* we should have some data to do the DMA trasnfer */
- MIPS_ASSERT(db->count >= db->fragSize);
+ ASSERT(db->count >= db->fragSize);
/* clear pending fales interrupts */
outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END,
@@ -442,12 +492,12 @@
outl (temp, s->io + VRC5477_CTRL);
/* it is time to setup next dma transfer */
- MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
- MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+ ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+ ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
temp = db->nextOut + db->fragSize;
if (temp >= db->fragTotalSize) {
- MIPS_ASSERT(temp == db->fragTotalSize);
+ ASSERT(temp == db->fragTotalSize);
temp = 0;
}
@@ -463,14 +513,14 @@
#if defined(VRC5477_AC97_VERBOSE_DEBUG)
outTicket = *(u16*)(db->lbuf+db->nextOut);
if (db->count > db->fragSize) {
- MIPS_ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
+ ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
}
#endif
spin_unlock_irqrestore(&s->lock, flags);
}
-extern inline void stop_adc(struct vrc5477_ac97_state *s)
+static inline void stop_adc(struct vrc5477_ac97_state *s)
{
struct dmabuf* db = &s->dma_adc;
unsigned long flags;
@@ -521,7 +571,7 @@
}
/* we should at least have some free space in the buffer */
- MIPS_ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
+ ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
/* clear pending ones */
outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END,
@@ -553,7 +603,7 @@
/* it is time to setup next dma transfer */
temp = db->nextIn + db->fragSize;
if (temp >= db->fragTotalSize) {
- MIPS_ASSERT(temp == db->fragTotalSize);
+ ASSERT(temp == db->fragTotalSize);
temp = 0;
}
outl(db->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
@@ -569,11 +619,11 @@
#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
#define DMABUF_MINORDER 1
-extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s,
+static inline void dealloc_dmabuf(struct vrc5477_ac97_state *s,
struct dmabuf *db)
{
if (db->lbuf) {
- MIPS_ASSERT(db->rbuf);
+ ASSERT(db->rbuf);
pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
db->lbuf, db->lbufDma);
pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
@@ -592,7 +642,7 @@
unsigned bufsize;
if (!db->lbuf) {
- MIPS_ASSERT(!db->rbuf);
+ ASSERT(!db->rbuf);
db->ready = 0;
for (order = DMABUF_DEFAULTORDER;
@@ -606,7 +656,7 @@
&db->rbufDma);
if (db->lbuf && db->rbuf) break;
if (db->lbuf) {
- MIPS_ASSERT(!db->rbuf);
+ ASSERT(!db->rbuf);
pci_free_consistent(s->dev,
PAGE_SIZE << order,
db->lbuf,
@@ -614,7 +664,7 @@
}
}
if (!db->lbuf) {
- MIPS_ASSERT(!db->rbuf);
+ ASSERT(!db->rbuf);
return -ENOMEM;
}
@@ -643,13 +693,13 @@
return 0;
}
-extern inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
+static inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
{
stop_adc(s);
return prog_dmabuf(s, &s->dma_adc, s->adcRate);
}
-extern inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
+static inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
{
stop_dac(s);
return prog_dmabuf(s, &s->dma_dac, s->dacRate);
@@ -677,7 +727,7 @@
/* set the base addr for next DMA transfer */
temp = adc->nextIn + 2*adc->fragSize;
if (temp >= adc->fragTotalSize) {
- MIPS_ASSERT( (temp == adc->fragTotalSize) ||
+ ASSERT( (temp == adc->fragTotalSize) ||
(temp == adc->fragTotalSize + adc->fragSize) );
temp -= adc->fragTotalSize;
}
@@ -687,7 +737,7 @@
/* adjust nextIn */
adc->nextIn += adc->fragSize;
if (adc->nextIn >= adc->fragTotalSize) {
- MIPS_ASSERT(adc->nextIn == adc->fragTotalSize);
+ ASSERT(adc->nextIn == adc->fragTotalSize);
adc->nextIn = 0;
}
@@ -706,13 +756,13 @@
unsigned temp;
/* next DMA transfer should already started */
- MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
- MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+ // ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+ // ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
/* let us set for next next DMA transfer */
temp = dac->nextOut + dac->fragSize*2;
if (temp >= dac->fragTotalSize) {
- MIPS_ASSERT( (temp == dac->fragTotalSize) ||
+ ASSERT( (temp == dac->fragTotalSize) ||
(temp == dac->fragTotalSize + dac->fragSize) );
temp -= dac->fragTotalSize;
}
@@ -728,35 +778,35 @@
printk("assert fail: - %d vs %d\n",
*(u16*)(dac->lbuf + dac->nextOut),
outTicket);
- MIPS_ASSERT(1 == 0);
+ ASSERT(1 == 0);
}
#endif
/* adjust nextOut pointer */
dac->nextOut += dac->fragSize;
if (dac->nextOut >= dac->fragTotalSize) {
- MIPS_ASSERT(dac->nextOut == dac->fragTotalSize);
+ ASSERT(dac->nextOut == dac->fragTotalSize);
dac->nextOut = 0;
}
/* adjust count */
dac->count -= dac->fragSize;
if (dac->count <=0 ) {
- MIPS_ASSERT(dac->count == 0);
- MIPS_ASSERT(dac->nextIn == dac->nextOut);
/* buffer under run */
+ dac->count = 0;
+ dac->nextIn = dac->nextOut;
stop_dac(s);
}
#if defined(VRC5477_AC97_VERBOSE_DEBUG)
if (dac->count) {
outTicket ++;
- MIPS_ASSERT(*(u16*)(dac->lbuf + dac->nextOut) == outTicket);
+ ASSERT(*(u16*)(dac->lbuf + dac->nextOut) == outTicket);
}
#endif
/* we cannot have both under run and someone is waiting on us */
- MIPS_ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
+ ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
/* wake up anybody listening */
if (waitqueue_active(&dac->wait))
@@ -805,12 +855,6 @@
/* --------------------------------------------------------------------- */
-static loff_t vrc5477_ac97_llseek(struct file *file, loff_t offset, int origin)
-{
- return -ESPIPE;
-}
-
-
static int vrc5477_ac97_open_mixdev(struct inode *inode, struct file *file)
{
int minor = MINOR(inode->i_rdev);
@@ -852,7 +896,7 @@
static /*const*/ struct file_operations vrc5477_ac97_mixer_fops = {
owner: THIS_MODULE,
- llseek: vrc5477_ac97_llseek,
+ llseek: no_llseek,
ioctl: vrc5477_ac97_ioctl_mixdev,
open: vrc5477_ac97_open_mixdev,
release: vrc5477_ac97_release_mixdev,
@@ -911,7 +955,7 @@
copyCount -= count;
bufStart += count;
- MIPS_ASSERT(bufStart <= db->fragTotalSize);
+ ASSERT(bufStart <= db->fragTotalSize);
buffer += count *2;
}
return 0;
@@ -943,12 +987,12 @@
}
if (copyCount + db->nextOut > db->fragTotalSize) {
copyCount = db->fragTotalSize - db->nextOut;
- MIPS_ASSERT((copyCount % db->fragSize) == 0);
+ ASSERT((copyCount % db->fragSize) == 0);
}
copyFragCount = (copyCount-1) >> db->fragShift;
copyFragCount = (copyFragCount+1) << db->fragShift;
- MIPS_ASSERT(copyFragCount >= copyCount);
+ ASSERT(copyFragCount >= copyCount);
/* we copy differently based on adc channels */
if (s->adcChannels == 1) {
@@ -971,12 +1015,12 @@
db->nextOut += copyFragCount;
if (db->nextOut >= db->fragTotalSize) {
- MIPS_ASSERT(db->nextOut == db->fragTotalSize);
+ ASSERT(db->nextOut == db->fragTotalSize);
db->nextOut = 0;
}
- MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
- MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+ ASSERT((copyFragCount % db->fragSize) == 0);
+ ASSERT( (count == 0) || (copyCount == copyFragCount));
}
spin_lock_irqsave(&s->lock, flags);
@@ -1005,7 +1049,7 @@
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
- MIPS_ASSERT(db->ready);
+ ASSERT(db->ready);
while (count > 0) {
// wait for samples in capture buffer
@@ -1030,7 +1074,7 @@
}
} while (avail <= 0);
- MIPS_ASSERT( (avail % db->fragSize) == 0);
+ ASSERT( (avail % db->fragSize) == 0);
copyCount = copy_adc_to_user(s, buffer, count, avail);
if (copyCount <=0 ) {
if (!ret) ret = -EFAULT;
@@ -1053,7 +1097,7 @@
struct dmabuf *db = &s->dma_dac;
int bufStart = db->nextIn;
- MIPS_ASSERT(db->ready);
+ ASSERT(db->ready);
for (; copyCount > 0; ) {
int i;
@@ -1071,7 +1115,7 @@
copyCount -= count;
bufStart += count;
- MIPS_ASSERT(bufStart <= db->fragTotalSize);
+ ASSERT(bufStart <= db->fragTotalSize);
buffer += count *2;
}
return 0;
@@ -1107,13 +1151,11 @@
}
if (copyCount + db->nextIn > db->fragTotalSize) {
copyCount = db->fragTotalSize - db->nextIn;
- MIPS_ASSERT((copyCount % db->fragSize) == 0);
- MIPS_ASSERT(copyCount > 0);
+ ASSERT(copyCount > 0);
}
- copyFragCount = (copyCount-1) >> db->fragShift;
- copyFragCount = (copyFragCount+1) << db->fragShift;
- MIPS_ASSERT(copyFragCount >= copyCount);
+ copyFragCount = copyCount;
+ ASSERT(copyFragCount >= copyCount);
/* we copy differently based on the number channels */
if (s->dacChannels == 1) {
@@ -1153,12 +1195,11 @@
db->nextIn += copyFragCount;
if (db->nextIn >= db->fragTotalSize) {
- MIPS_ASSERT(db->nextIn == db->fragTotalSize);
+ ASSERT(db->nextIn == db->fragTotalSize);
db->nextIn = 0;
}
- MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
- MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+ ASSERT( (count == 0) || (copyCount == copyFragCount));
}
spin_lock_irqsave(&s->lock, flags);
@@ -1168,7 +1209,7 @@
}
/* nextIn should not be equal to nextOut unless we are full */
- MIPS_ASSERT( ( (db->count == db->fragTotalSize) &&
+ ASSERT( ( (db->count == db->fragTotalSize) &&
(db->nextIn == db->nextOut) ) ||
( (db->count < db->fragTotalSize) &&
(db->nextIn != db->nextOut) ) );
@@ -1216,7 +1257,6 @@
}
} while (avail <= 0);
- MIPS_ASSERT( (avail % db->fragSize) == 0);
copyCount = copy_dac_from_user(s, buffer, count, avail);
if (copyCount < 0) {
if (!ret) ret = -EFAULT;
@@ -1257,7 +1297,7 @@
return mask;
}
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
static struct ioctl_str_t {
unsigned int cmd;
const char* str;
@@ -1308,7 +1348,7 @@
int count;
int val, ret;
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
if (ioctl_str[count].cmd == cmd)
break;
@@ -1618,7 +1658,7 @@
static /*const*/ struct file_operations vrc5477_ac97_audio_fops = {
owner: THIS_MODULE,
- llseek: vrc5477_ac97_llseek,
+ llseek: no_llseek,
read: vrc5477_ac97_read,
write: vrc5477_ac97_write,
poll: vrc5477_ac97_poll,
@@ -1639,7 +1679,7 @@
* CODEC chipstate
*/
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
struct {
const char *regname;
@@ -1763,7 +1803,7 @@
return len;
}
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
/* --------------------------------------------------------------------- */
@@ -1776,88 +1816,13 @@
MODULE_DESCRIPTION("NEC Vrc5477 audio (AC97) Driver");
MODULE_LICENSE("GPL");
-/* --------------------------------------------------------------------- */
-extern void jsun_scan_pci_bus(void);
-extern void vrc5477_show_pci_regs(void);
-extern void vrc5477_show_pdar_regs(void);
-
-/* -------------------------------------------------------- */
-#define AC97_BASE 0xbb000000
-#define myinl(x) *(volatile u32*)(AC97_BASE + (x))
-#define myoutl(x,y) *(volatile u32*)(AC97_BASE + (y)) = (x)
-
-u16 myrdcodec(u8 addr)
-{
- u32 result;
-
- /* wait until we can access codec registers */
- // while (inl(VRC5477_CODEC_WR) & 0x80000000);
-
- /* write the address and "read" command to codec */
- addr = addr & 0x7f;
- myoutl((addr << 16) | VRC5477_CODEC_WR_RWC, VRC5477_CODEC_WR);
-
- /* get the return result */
- udelay(100); /* workaround hardware bug */
- // dump_memory(0xbb000000, 48);
- while ( ((result=myinl(VRC5477_CODEC_RD)) & 0xc0000000) != 0xc0000000);
- MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
- return result & 0xffff;
-}
-
-void mywrcodec(u8 addr, u16 data)
-{
- /* wait until we can access codec registers */
- while (myinl(VRC5477_CODEC_WR) & 0x80000000);
-
- /* write the address and value to codec */
- myoutl((addr << 16) | data, VRC5477_CODEC_WR);
-
-}
-
-
-void jsun_ac97_test(struct vrc5477_ac97_state *s)
-{
- int i;
-
- /* reset codec */
- /*
- wrcodec(&s->codec, 0, 0);
- while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
- */
- mywrcodec(0, 0);
- while (myinl(VRC5477_CODEC_WR) & 0x80000000);
-
- for (i=0; i< 0x40; i+=4) {
- MIPS_ASSERT(inl(s->io+i) == myinl(i));
- }
-
- printk("codec registers : ");
- for (i=0; i<= 0x3a; i+=2) {
- if ( (i%0x10) == 0) {
- printk("\n%02x\t", i);
- }
- // printk("%04x\t", rdcodec(&s->codec, i));
- printk("%04x\t", myrdcodec(i));
- }
- printk("\n\n");
- printk("codec registers : ");
- for (i=0; i<= 0x3a; i+=2) {
- if ( (i%0x10) == 0) {
- printk("\n%02x\t", i);
- }
- printk("%04x\t", rdcodec(&s->codec, i));
- }
- printk("\n\n");
-}
-
static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev,
const struct pci_device_id *pciid)
{
struct vrc5477_ac97_state *s;
+#ifdef VRC5477_AC97_DEBUG
char proc_str[80];
-
- MIPS_DEBUG(printk("vrc5477_ac97_probe() invoked\n"));
+#endif
if (pcidev->irq == 0)
return -1;
@@ -1889,6 +1854,13 @@
* no persistent state across file opens.
*/
+ /* test if get response from ac97, if not return */
+ if (ac97_codec_not_present(&(s->codec))) {
+ printk(KERN_ERR PFX "no ac97 codec\n");
+ goto err_region;
+
+ }
+
if (!request_region(s->io, pci_resource_len(pcidev,0),
VRC5477_AC97_MODULE_NAME)) {
printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
@@ -1910,37 +1882,27 @@
register_sound_mixer(&vrc5477_ac97_mixer_fops, -1)) < 0)
goto err_dev2;
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
/* intialize the debug proc device */
s->ps = create_proc_read_entry(VRC5477_AC97_MODULE_NAME, 0, NULL,
proc_vrc5477_ac97_dump, NULL);
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
/* enable pci io and bus mastering */
if (pci_enable_device(pcidev))
goto err_dev3;
pci_set_master(pcidev);
-/*
-jsun_scan_pci_bus();
-vrc5477_show_pci_regs();
-vrc5477_show_pdar_regs();
-*/
-
/* cold reset the AC97 */
outl(VRC5477_ACLINK_CTRL_RST_ON | VRC5477_ACLINK_CTRL_RST_TIME,
s->io + VRC5477_ACLINK_CTRL);
while (inl(s->io + VRC5477_ACLINK_CTRL) & VRC5477_ACLINK_CTRL_RST_ON);
-/*
-jsun_ac97_test(s);
-*/
-
/* codec init */
if (!ac97_probe_codec(&s->codec))
goto err_dev3;
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
sprintf(proc_str, "driver/%s/%d/ac97",
VRC5477_AC97_MODULE_NAME, s->codec.id);
s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
@@ -1948,16 +1910,28 @@
/* TODO : why this proc file does not show up? */
#endif
+ /* Try to enable variable rate audio mode. */
+ wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+ rdcodec(&s->codec, AC97_EXTENDED_STATUS) | AC97_EXTSTAT_VRA);
+ /* Did we enable it? */
+ if(rdcodec(&s->codec, AC97_EXTENDED_STATUS) & AC97_EXTSTAT_VRA)
+ s->extended_status |= AC97_EXTSTAT_VRA;
+ else {
+ s->dacRate = 48000;
+ printk(KERN_INFO PFX "VRA mode not enabled; rate fixed at %d.",
+ s->dacRate);
+ }
+
/* let us get the default volumne louder */
- wrcodec(&s->codec, 0x2, 0);
- wrcodec(&s->codec, 0x18, 0x0707);
- /* mute line in loopback to line out */
- wrcodec(&s->codec, 0x10, 0x8000);
+ wrcodec(&s->codec, 0x2, 0x1010); /* master volume, middle */
+ wrcodec(&s->codec, 0xc, 0x10); /* phone volume, middle */
+ // wrcodec(&s->codec, 0xe, 0x10); /* misc volume, middle */
+ wrcodec(&s->codec, 0x10, 0x8000); /* line-in 2 line-out disable */
+ wrcodec(&s->codec, 0x18, 0x0707); /* PCM out (line out) middle */
+
/* by default we select line in the input */
wrcodec(&s->codec, 0x1a, 0x0404);
- /* pick middle value for record gain */
- // wrcodec(&s->codec, 0x1c, 0x0707);
wrcodec(&s->codec, 0x1c, 0x0f0f);
wrcodec(&s->codec, 0x1e, 0x07);
@@ -1995,10 +1969,12 @@
if (!s)
return;
list_del(&s->devs);
-#ifdef CONFIG_LL_DEBUG
+
+#ifdef VRC5477_AC97_DEBUG
if (s->ps)
remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL);
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
+
synchronize_irq();
free_irq(s->irq, s);
release_region(s->io, pci_resource_len(dev,0));
@@ -2009,8 +1985,6 @@
}
-#define PCI_VENDOR_ID_NEC 0x1033
-#define PCI_DEVICE_ID_NEC_VRC5477_AC97 0x00A6
static struct pci_device_id id_table[] __devinitdata = {
{ PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC5477_AC97,
PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
@@ -2030,7 +2004,7 @@
{
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk("Vrc5477 AC97 driver: version v0.1 time " __TIME__ " " __DATE__ " by Jun Sun\n");
+ printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n");
return pci_module_init(&vrc5477_ac97_driver);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)