aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/emu10k1/emuproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/emu10k1/emuproc.c')
-rw-r--r--sound/pci/emu10k1/emuproc.c124
1 files changed, 89 insertions, 35 deletions
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index b939e03aaed..2ca9f2e9313 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -1,8 +1,11 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Creative Labs, Inc.
* Routines for control of EMU10K1 chips / proc interface routines
*
+ * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
+ * Added EMU 1010 support.
+ *
* BUGS:
* --
*
@@ -25,7 +28,6 @@
*
*/
-#include <sound/driver.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <sound/core.h>
@@ -237,8 +239,42 @@ static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_emu10k1 *emu = entry->private_data;
- snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
- snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
+ u32 value;
+ u32 value2;
+ unsigned long flags;
+ u32 rate;
+
+ if (emu->card_capabilities->emu_model) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, 0x38, &value);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ if ((value & 0x1) == 0) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, 0x2a, &value);
+ snd_emu1010_fpga_read(emu, 0x2b, &value2);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ rate = 0x1770000 / (((value << 5) | value2)+1);
+ snd_iprintf(buffer, "ADAT Locked : %u\n", rate);
+ } else {
+ snd_iprintf(buffer, "ADAT Unlocked\n");
+ }
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, 0x20, &value);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ if ((value & 0x4) == 0) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, 0x28, &value);
+ snd_emu1010_fpga_read(emu, 0x29, &value2);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ rate = 0x1770000 / (((value << 5) | value2)+1);
+ snd_iprintf(buffer, "SPDIF Locked : %d\n", rate);
+ } else {
+ snd_iprintf(buffer, "SPDIF Unlocked\n");
+ }
+ } else {
+ snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
+ snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
+ }
#if 0
val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0);
snd_iprintf(buffer, "\nZoomed Video\n");
@@ -255,7 +291,7 @@ static void snd_emu10k1_proc_rates_read(struct snd_info_entry *entry,
unsigned int val, tmp, n;
val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0);
tmp = (val >> 16) & 0x8;
- for (n=0;n<4;n++) {
+ for (n = 0; n < 4; n++) {
tmp = val >> (16 + (n*4));
if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]);
else snd_iprintf(buffer, "Channel %d: No input\n", n);
@@ -305,15 +341,17 @@ static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry,
#define TOTAL_SIZE_CODE (0x200*8)
#define A_TOTAL_SIZE_CODE (0x400*8)
-static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *buf,
- unsigned long count, unsigned long pos)
+static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
+ void *file_private_data,
+ struct file *file, char __user *buf,
+ size_t count, loff_t pos)
{
- long size;
struct snd_emu10k1 *emu = entry->private_data;
unsigned int offset;
int tram_addr = 0;
+ unsigned int *tmp;
+ long res;
+ unsigned int idx;
if (!strcmp(entry->name, "fx8010_tram_addr")) {
offset = TANKMEMADDRREGBASE;
@@ -325,30 +363,25 @@ static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
} else {
offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
}
- size = count;
- if (pos + size > entry->size)
- size = (long)entry->size - pos;
- if (size > 0) {
- unsigned int *tmp;
- long res;
- unsigned int idx;
- if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL)
- return -ENOMEM;
- for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++)
- if (tram_addr && emu->audigy) {
- tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
- tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
- } else
- tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
- if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
- res = -EFAULT;
- else {
- res = size;
+
+ tmp = kmalloc(count + 8, GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
+ for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) {
+ unsigned int val;
+ val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
+ if (tram_addr && emu->audigy) {
+ val >>= 11;
+ val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
}
- kfree(tmp);
- return res;
+ tmp[idx] = val;
}
- return 0;
+ if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count))
+ res = -EFAULT;
+ else
+ res = count;
+ kfree(tmp);
+ return res;
}
static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
@@ -372,6 +405,23 @@ static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
}
#ifdef CONFIG_SND_DEBUG
+static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
+{
+ struct snd_emu10k1 *emu = entry->private_data;
+ u32 value;
+ unsigned long flags;
+ int i;
+ snd_iprintf(buffer, "EMU1010 Registers:\n\n");
+
+ for(i = 0; i < 0x40; i+=1) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, i, &value);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ snd_iprintf(buffer, "%02X: %08X, %02X\n", i, value, (value >> 8) & 0x7f);
+ }
+}
+
static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
@@ -398,7 +448,7 @@ static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry,
while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x", &reg, &val) != 2)
continue;
- if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) {
+ if (reg < 0x40 && val <= 0xffffffff) {
spin_lock_irqsave(&emu->emu_lock, flags);
outl(val, emu->port + (reg & 0xfffffffc));
spin_unlock_irqrestore(&emu->emu_lock, flags);
@@ -474,7 +524,7 @@ static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry,
while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
continue;
- if ((reg < 0xa0) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
+ if (reg < 0xa0 && val <= 0xffffffff && channel_id <= 3)
snd_ptr_write(emu, iobase, reg, channel_id, val);
}
}
@@ -527,10 +577,14 @@ static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
.read = snd_emu10k1_fx8010_read,
};
-int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
+int snd_emu10k1_proc_init(struct snd_emu10k1 *emu)
{
struct snd_info_entry *entry;
#ifdef CONFIG_SND_DEBUG
+ if (emu->card_capabilities->emu_model) {
+ if (! snd_card_proc_new(emu->card, "emu1010_regs", &entry))
+ snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read);
+ }
if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read);
entry->c.text.write = snd_emu_proc_io_reg_write;