aboutsummaryrefslogtreecommitdiff
path: root/sound/oss/dmasound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/oss/dmasound
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'sound/oss/dmasound')
-rw-r--r--sound/oss/dmasound/Kconfig58
-rw-r--r--sound/oss/dmasound/Makefile13
-rw-r--r--sound/oss/dmasound/awacs_defs.h251
-rw-r--r--sound/oss/dmasound/dac3550a.c210
-rw-r--r--sound/oss/dmasound/dmasound.h277
-rw-r--r--sound/oss/dmasound/dmasound_atari.c1600
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c3176
-rw-r--r--sound/oss/dmasound/dmasound_core.c1829
-rw-r--r--sound/oss/dmasound/dmasound_paula.c743
-rw-r--r--sound/oss/dmasound/dmasound_q40.c634
-rw-r--r--sound/oss/dmasound/tas3001c.c850
-rw-r--r--sound/oss/dmasound/tas3001c.h64
-rw-r--r--sound/oss/dmasound/tas3001c_tables.c375
-rw-r--r--sound/oss/dmasound/tas3004.c1140
-rw-r--r--sound/oss/dmasound/tas3004.h77
-rw-r--r--sound/oss/dmasound/tas3004_tables.c301
-rw-r--r--sound/oss/dmasound/tas_common.c214
-rw-r--r--sound/oss/dmasound/tas_common.h284
-rw-r--r--sound/oss/dmasound/tas_eq_prefs.h24
-rw-r--r--sound/oss/dmasound/tas_ioctl.h24
-rw-r--r--sound/oss/dmasound/trans_16.c897
21 files changed, 13041 insertions, 0 deletions
diff --git a/sound/oss/dmasound/Kconfig b/sound/oss/dmasound/Kconfig
new file mode 100644
index 00000000000..cb845580fe0
--- /dev/null
+++ b/sound/oss/dmasound/Kconfig
@@ -0,0 +1,58 @@
+config DMASOUND_ATARI
+ tristate "Atari DMA sound support"
+ depends on ATARI && SOUND
+ select DMASOUND
+ help
+ If you want to use the internal audio of your Atari in Linux, answer
+ Y to this question. This will provide a Sun-like /dev/audio,
+ compatible with the Linux/i386 sound system. Otherwise, say N.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you
+ want). If you want to compile it as a module, say M here and read
+ <file:Documentation/kbuild/modules.txt>.
+
+config DMASOUND_PMAC
+ tristate "PowerMac DMA sound support"
+ depends on PPC32 && PPC_PMAC && SOUND && I2C
+ select DMASOUND
+ help
+ If you want to use the internal audio of your PowerMac in Linux,
+ answer Y to this question. This will provide a Sun-like /dev/audio,
+ compatible with the Linux/i386 sound system. Otherwise, say N.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you
+ want). If you want to compile it as a module, say M here and read
+ <file:Documentation/kbuild/modules.txt>.
+
+config DMASOUND_PAULA
+ tristate "Amiga DMA sound support"
+ depends on (AMIGA || APUS) && SOUND
+ select DMASOUND
+ help
+ If you want to use the internal audio of your Amiga in Linux, answer
+ Y to this question. This will provide a Sun-like /dev/audio,
+ compatible with the Linux/i386 sound system. Otherwise, say N.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you
+ want). If you want to compile it as a module, say M here and read
+ <file:Documentation/kbuild/modules.txt>.
+
+config DMASOUND_Q40
+ tristate "Q40 sound support"
+ depends on Q40 && SOUND
+ select DMASOUND
+ help
+ If you want to use the internal audio of your Q40 in Linux, answer
+ Y to this question. This will provide a Sun-like /dev/audio,
+ compatible with the Linux/i386 sound system. Otherwise, say N.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you
+ want). If you want to compile it as a module, say M here and read
+ <file:Documentation/kbuild/modules.txt>.
+
+config DMASOUND
+ tristate
diff --git a/sound/oss/dmasound/Makefile b/sound/oss/dmasound/Makefile
new file mode 100644
index 00000000000..4611636b1a8
--- /dev/null
+++ b/sound/oss/dmasound/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the DMA sound driver
+#
+
+dmasound_pmac-y += dmasound_awacs.o \
+ trans_16.o dac3550a.o tas_common.o \
+ tas3001c.o tas3001c_tables.o \
+ tas3004.o tas3004_tables.o
+
+obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o
+obj-$(CONFIG_DMASOUND_PMAC) += dmasound_core.o dmasound_pmac.o
+obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o
+obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o
diff --git a/sound/oss/dmasound/awacs_defs.h b/sound/oss/dmasound/awacs_defs.h
new file mode 100644
index 00000000000..2194f46b046
--- /dev/null
+++ b/sound/oss/dmasound/awacs_defs.h
@@ -0,0 +1,251 @@
+/*********************************************************/
+/* This file was written by someone, somewhere, sometime */
+/* And is released into the Public Domain */
+/*********************************************************/
+
+#ifndef _AWACS_DEFS_H_
+#define _AWACS_DEFS_H_
+
+/*******************************/
+/* AWACs Audio Register Layout */
+/*******************************/
+
+struct awacs_regs {
+ unsigned control; /* Audio control register */
+ unsigned pad0[3];
+ unsigned codec_ctrl; /* Codec control register */
+ unsigned pad1[3];
+ unsigned codec_stat; /* Codec status register */
+ unsigned pad2[3];
+ unsigned clip_count; /* Clipping count register */
+ unsigned pad3[3];
+ unsigned byteswap; /* Data is little-endian if 1 */
+};
+
+/*******************/
+/* Audio Bit Masks */
+/*******************/
+
+/* Audio Control Reg Bit Masks */
+/* ----- ------- --- --- ----- */
+#define MASK_ISFSEL (0xf) /* Input SubFrame Select */
+#define MASK_OSFSEL (0xf << 4) /* Output SubFrame Select */
+#define MASK_RATE (0x7 << 8) /* Sound Rate */
+#define MASK_CNTLERR (0x1 << 11) /* Error */
+#define MASK_PORTCHG (0x1 << 12) /* Port Change */
+#define MASK_IEE (0x1 << 13) /* Enable Interrupt on Error */
+#define MASK_IEPC (0x1 << 14) /* Enable Interrupt on Port Change */
+#define MASK_SSFSEL (0x3 << 15) /* Status SubFrame Select */
+
+/* Audio Codec Control Reg Bit Masks */
+/* ----- ----- ------- --- --- ----- */
+#define MASK_NEWECMD (0x1 << 24) /* Lock: don't write to reg when 1 */
+#define MASK_EMODESEL (0x3 << 22) /* Send info out on which frame? */
+#define MASK_EXMODEADDR (0x3ff << 12) /* Extended Mode Address -- 10 bits */
+#define MASK_EXMODEDATA (0xfff) /* Extended Mode Data -- 12 bits */
+
+/* Audio Codec Control Address Values / Masks */
+/* ----- ----- ------- ------- ------ - ----- */
+#define MASK_ADDR0 (0x0 << 12) /* Expanded Data Mode Address 0 */
+#define MASK_ADDR_MUX MASK_ADDR0 /* Mux Control */
+#define MASK_ADDR_GAIN MASK_ADDR0
+
+#define MASK_ADDR1 (0x1 << 12) /* Expanded Data Mode Address 1 */
+#define MASK_ADDR_MUTE MASK_ADDR1
+#define MASK_ADDR_RATE MASK_ADDR1
+
+#define MASK_ADDR2 (0x2 << 12) /* Expanded Data Mode Address 2 */
+#define MASK_ADDR_VOLA MASK_ADDR2 /* Volume Control A -- Headphones */
+#define MASK_ADDR_VOLHD MASK_ADDR2
+
+#define MASK_ADDR4 (0x4 << 12) /* Expanded Data Mode Address 4 */
+#define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */
+#define MASK_ADDR_VOLSPK MASK_ADDR4
+
+/* additional registers of screamer */
+#define MASK_ADDR5 (0x5 << 12) /* Expanded Data Mode Address 5 */
+#define MASK_ADDR6 (0x6 << 12) /* Expanded Data Mode Address 6 */
+#define MASK_ADDR7 (0x7 << 12) /* Expanded Data Mode Address 7 */
+
+/* Address 0 Bit Masks & Macros */
+/* ------- - --- ----- - ------ */
+#define MASK_GAINRIGHT (0xf) /* Gain Right Mask */
+#define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */
+#define MASK_GAINLINE (0x1 << 8) /* Disable Mic preamp */
+#define MASK_GAINMIC (0x0 << 8) /* Enable Mic preamp */
+
+#define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */
+#define MASK_MUX_MIC (0x1 << 10) /* Select Mic in MUX */
+#define MASK_MUX_AUDIN (0x1 << 11) /* Select Audio In in MUX */
+#define MASK_MUX_LINE MASK_MUX_AUDIN
+
+#define GAINRIGHT(x) ((x) & MASK_GAINRIGHT)
+#define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT)
+
+#define DEF_CD_GAIN 0x00bb
+#define DEF_MIC_GAIN 0x00cc
+
+/* Address 1 Bit Masks */
+/* ------- - --- ----- */
+#define MASK_ADDR1RES1 (0x3) /* Reserved */
+#define MASK_RECALIBRATE (0x1 << 2) /* Recalibrate */
+#define MASK_SAMPLERATE (0x7 << 3) /* Sample Rate: */
+#define MASK_LOOPTHRU (0x1 << 6) /* Loopthrough Enable */
+#define MASK_CMUTE (0x1 << 7) /* Output C (Speaker) Mute when 1 */
+#define MASK_SPKMUTE MASK_CMUTE
+#define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */
+#define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */
+#define MASK_HDMUTE MASK_AMUTE
+#define MASK_PAROUT0 (0x1 << 10) /* Parallel Output 0 */
+#define MASK_PAROUT1 (0x2 << 10) /* Parallel Output 1 */
+
+#define MASK_MIC_BOOST (0x4) /* screamer mic boost */
+
+#define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */
+#define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */
+#define SAMPLERATE_24000 (0x2 << 3) /* 24 or 22.05 kHz */
+#define SAMPLERATE_19200 (0x3 << 3) /* 19.2 or 17.64 kHz */
+#define SAMPLERATE_16000 (0x4 << 3) /* 16 or 14.7 kHz */
+#define SAMPLERATE_12000 (0x5 << 3) /* 12 or 11.025 kHz */
+#define SAMPLERATE_9600 (0x6 << 3) /* 9.6 or 8.82 kHz */
+#define SAMPLERATE_8000 (0x7 << 3) /* 8 or 7.35 kHz */
+
+/* Address 2 & 4 Bit Masks & Macros */
+/* ------- - - - --- ----- - ------ */
+#define MASK_OUTVOLRIGHT (0xf) /* Output Right Volume */
+#define MASK_ADDR2RES1 (0x2 << 4) /* Reserved */
+#define MASK_ADDR4RES1 MASK_ADDR2RES1
+#define MASK_OUTVOLLEFT (0xf << 6) /* Output Left Volume */
+#define MASK_ADDR2RES2 (0x2 << 10) /* Reserved */
+#define MASK_ADDR4RES2 MASK_ADDR2RES2
+
+#define VOLRIGHT(x) (((~(x)) & MASK_OUTVOLRIGHT))
+#define VOLLEFT(x) (((~(x)) << 6) & MASK_OUTVOLLEFT)
+
+/* Audio Codec Status Reg Bit Masks */
+/* ----- ----- ------ --- --- ----- */
+#define MASK_EXTEND (0x1 << 23) /* Extend */
+#define MASK_VALID (0x1 << 22) /* Valid Data? */
+#define MASK_OFLEFT (0x1 << 21) /* Overflow Left */
+#define MASK_OFRIGHT (0x1 << 20) /* Overflow Right */
+#define MASK_ERRCODE (0xf << 16) /* Error Code */
+#define MASK_REVISION (0xf << 12) /* Revision Number */
+#define MASK_MFGID (0xf << 8) /* Mfg. ID */
+#define MASK_CODSTATRES (0xf << 4) /* bits 4 - 7 reserved */
+#define MASK_INPPORT (0xf) /* Input Port */
+#define MASK_HDPCONN 8 /* headphone plugged in */
+
+/* Clipping Count Reg Bit Masks */
+/* -------- ----- --- --- ----- */
+#define MASK_CLIPLEFT (0xff << 7) /* Clipping Count, Left Channel */
+#define MASK_CLIPRIGHT (0xff) /* Clipping Count, Right Channel */
+
+/* DBDMA ChannelStatus Bit Masks */
+/* ----- ------------- --- ----- */
+#define MASK_CSERR (0x1 << 7) /* Error */
+#define MASK_EOI (0x1 << 6) /* End of Input -- only for Input Channel */
+#define MASK_CSUNUSED (0x1f << 1) /* bits 1-5 not used */
+#define MASK_WAIT (0x1) /* Wait */
+
+/* Various Rates */
+/* ------- ----- */
+#define RATE_48000 (0x0 << 8) /* 48 kHz */
+#define RATE_44100 (0x0 << 8) /* 44.1 kHz */
+#define RATE_32000 (0x1 << 8) /* 32 kHz */
+#define RATE_29400 (0x1 << 8) /* 29.4 kHz */
+#define RATE_24000 (0x2 << 8) /* 24 kHz */
+#define RATE_22050 (0x2 << 8) /* 22.05 kHz */
+#define RATE_19200 (0x3 << 8) /* 19.2 kHz */
+#define RATE_17640 (0x3 << 8) /* 17.64 kHz */
+#define RATE_16000 (0x4 << 8) /* 16 kHz */
+#define RATE_14700 (0x4 << 8) /* 14.7 kHz */
+#define RATE_12000 (0x5 << 8) /* 12 kHz */
+#define RATE_11025 (0x5 << 8) /* 11.025 kHz */
+#define RATE_9600 (0x6 << 8) /* 9.6 kHz */
+#define RATE_8820 (0x6 << 8) /* 8.82 kHz */
+#define RATE_8000 (0x7 << 8) /* 8 kHz */
+#define RATE_7350 (0x7 << 8) /* 7.35 kHz */
+
+#define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */
+
+/*******************/
+/* Burgundy values */
+/*******************/
+
+#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
+#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
+
+#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12)
+#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12)
+#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12)
+#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12)
+
+#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12)
+#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12)
+#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12)
+#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12)
+
+#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12)
+#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12)
+
+#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12)
+
+#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12)
+
+#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12)
+#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12)
+#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12)
+
+#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1)
+#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2)
+#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3)
+#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
+
+#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1)
+#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2)
+#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3)
+#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
+
+
+/* These are all default values for the burgundy */
+#define DEF_BURGUNDY_INPSEL21 (0xAA)
+#define DEF_BURGUNDY_INPSEL3 (0x0A)
+
+#define DEF_BURGUNDY_GAINCD (0x33)
+#define DEF_BURGUNDY_GAINLINE (0x44)
+#define DEF_BURGUNDY_GAINMIC (0x44)
+#define DEF_BURGUNDY_GAINMODEM (0x06)
+
+/* Remember: lowest volume here is 0x9b */
+#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC)
+#define DEF_BURGUNDY_VOLLINE (0x00000000)
+#define DEF_BURGUNDY_VOLMIC (0x00000000)
+#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC)
+
+#define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f)
+#define DEF_BURGUNDY_OUTPUTENABLES (0x0A)
+
+#define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF)
+
+#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E)
+
+#define DEF_BURGUNDY_ATTENSPEAKER (0x44)
+#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
+#define DEF_BURGUNDY_ATTENHP (0xCC)
+
+/*********************/
+/* i2s layout values */
+/*********************/
+
+#define I2S_REG_INT_CTL 0x00
+#define I2S_REG_SERIAL_FORMAT 0x10
+#define I2S_REG_CODEC_MSG_OUT 0x20
+#define I2S_REG_CODEC_MSG_IN 0x30
+#define I2S_REG_FRAME_COUNT 0x40
+#define I2S_REG_FRAME_MATCH 0x50
+#define I2S_REG_DATAWORD_SIZES 0x60
+#define I2S_REG_PEAKLEVEL_SEL 0x70
+#define I2S_REG_PEAKLEVEL_IN0 0x80
+#define I2S_REG_PEAKLEVEL_IN1 0x90
+
+#endif /* _AWACS_DEFS_H_ */
diff --git a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c
new file mode 100644
index 00000000000..533895eba0e
--- /dev/null
+++ b/sound/oss/dmasound/dac3550a.c
@@ -0,0 +1,210 @@
+/*
+ * Driver for the i2c/i2s based DAC3550a sound chip used
+ * on some Apple iBooks. Also known as "DACA".
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/ioport.h>
+#include <linux/sysctl.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+
+#include "dmasound.h"
+
+/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer
+ * control code, as well as info derived from the AppleDACAAudio driver
+ * from Darwin CVS (main thing I derived being register numbers and
+ * values, as well as when to make the calls). */
+
+#define I2C_DRIVERID_DACA (0xFDCB)
+
+#define DACA_VERSION "0.1"
+#define DACA_DATE "20010930"
+
+static int cur_left_vol;
+static int cur_right_vol;
+static struct i2c_client *daca_client;
+
+static int daca_attach_adapter(struct i2c_adapter *adapter);
+static int daca_detect_client(struct i2c_adapter *adapter, int address);
+static int daca_detach_client(struct i2c_client *client);
+
+struct i2c_driver daca_driver = {
+ .owner = THIS_MODULE,
+ .name = "DAC3550A driver V " DACA_VERSION,
+ .id = I2C_DRIVERID_DACA,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = daca_attach_adapter,
+ .detach_client = daca_detach_client,
+};
+
+#define VOL_MAX ((1<<20) - 1)
+
+void daca_get_volume(uint * left_vol, uint *right_vol)
+{
+ *left_vol = cur_left_vol >> 5;
+ *right_vol = cur_right_vol >> 5;
+}
+
+int daca_set_volume(uint left_vol, uint right_vol)
+{
+ unsigned short voldata;
+
+ if (!daca_client)
+ return -1;
+
+ /* Derived from experience, not from any specific values */
+ left_vol <<= 5;
+ right_vol <<= 5;
+
+ if (left_vol > VOL_MAX)
+ left_vol = VOL_MAX;
+ if (right_vol > VOL_MAX)
+ right_vol = VOL_MAX;
+
+ voldata = ((left_vol >> 14) & 0x3f) << 8;
+ voldata |= (right_vol >> 14) & 0x3f;
+
+ if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {
+ printk("daca: failed to set volume \n");
+ return -1;
+ }
+
+ cur_left_vol = left_vol;
+ cur_right_vol = right_vol;
+
+ return 0;
+}
+
+int daca_leave_sleep(void)
+{
+ if (!daca_client)
+ return -1;
+
+ /* Do a short sleep, just to make sure I2C bus is awake and paying
+ * attention to us
+ */
+ msleep(20);
+ /* Write the sample rate reg the value it needs */
+ i2c_smbus_write_byte_data(daca_client, 1, 8);
+ daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
+ /* Another short delay, just to make sure the other I2C bus writes
+ * have taken...
+ */
+ msleep(20);
+ /* Write the global config reg - invert right power amp,
+ * DAC on, use 5-volt mode */
+ i2c_smbus_write_byte_data(daca_client, 3, 0x45);
+
+ return 0;
+}
+
+int daca_enter_sleep(void)
+{
+ if (!daca_client)
+ return -1;
+
+ i2c_smbus_write_byte_data(daca_client, 1, 8);
+ daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
+
+ /* Write the global config reg - invert right power amp,
+ * DAC on, enter low-power mode, use 5-volt mode
+ */
+ i2c_smbus_write_byte_data(daca_client, 3, 0x65);
+
+ return 0;
+}
+
+static int daca_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!strncmp(adapter->name, "mac-io", 6))
+ daca_detect_client(adapter, 0x4d);
+ return 0;
+}
+
+static int daca_init_client(struct i2c_client * new_client)
+{
+ /*
+ * Probe is not working with the current i2c-keywest
+ * driver. We try to use addr 0x4d on each adapters
+ * instead, by setting the format register.
+ *
+ * FIXME: I'm sure that can be obtained from the
+ * device-tree. --BenH.
+ */
+
+ /* Write the global config reg - invert right power amp,
+ * DAC on, use 5-volt mode
+ */
+ if (i2c_smbus_write_byte_data(new_client, 3, 0x45))
+ return -1;
+
+ i2c_smbus_write_byte_data(new_client, 1, 8);
+ daca_client = new_client;
+ daca_set_volume(15000, 15000);
+
+ return 0;
+}
+
+static int daca_detect_client(struct i2c_adapter *adapter, int address)
+{
+ const char *client_name = "DAC 3550A Digital Equalizer";
+ struct i2c_client *new_client;
+ int rc = -ENODEV;
+
+ new_client = kmalloc(sizeof(*new_client), GFP_KERNEL);
+ if (!new_client)
+ return -ENOMEM;
+ memset(new_client, 0, sizeof(*new_client));
+
+ new_client->addr = address;
+ new_client->adapter = adapter;
+ new_client->driver = &daca_driver;
+ new_client->flags = 0;
+ strcpy(new_client->name, client_name);
+
+ if (daca_init_client(new_client))
+ goto bail;
+
+ /* Tell the i2c layer a new client has arrived */
+ if (i2c_attach_client(new_client))
+ goto bail;
+
+ return 0;
+ bail:
+ kfree(new_client);
+ return rc;
+}
+
+
+static int daca_detach_client(struct i2c_client *client)
+{
+ if (client == daca_client)
+ daca_client = NULL;
+
+ i2c_detach_client(client);
+ kfree(client);
+ return 0;
+}
+
+void daca_cleanup(void)
+{
+ i2c_del_driver(&daca_driver);
+}
+
+int daca_init(void)
+{
+ printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE);
+ return i2c_add_driver(&daca_driver);
+}
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
new file mode 100644
index 00000000000..9a2f50f0b18
--- /dev/null
+++ b/sound/oss/dmasound/dmasound.h
@@ -0,0 +1,277 @@
+#ifndef _dmasound_h_
+/*
+ * linux/sound/oss/dmasound/dmasound.h
+ *
+ *
+ * Minor numbers for the sound driver.
+ *
+ * Unfortunately Creative called the codec chip of SB as a DSP. For this
+ * reason the /dev/dsp is reserved for digitized audio use. There is a
+ * device for true DSP processors but it will be called something else.
+ * In v3.0 it's /dev/sndproc but this could be a temporary solution.
+ */
+#define _dmasound_h_
+
+#include <linux/types.h>
+#include <linux/config.h>
+
+#define SND_NDEVS 256 /* Number of supported devices */
+#define SND_DEV_CTL 0 /* Control port /dev/mixer */
+#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
+ synthesizer and MIDI output) */
+#define SND_DEV_MIDIN 2 /* Raw midi access */
+#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
+#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
+#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
+#define SND_DEV_STATUS 6 /* /dev/sndstat */
+/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
+#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
+#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
+#define SND_DEV_PSS SND_DEV_SNDPROC
+
+/* switch on various prinks */
+#define DEBUG_DMASOUND 1
+
+#define MAX_AUDIO_DEV 5
+#define MAX_MIXER_DEV 4
+#define MAX_SYNTH_DEV 3
+#define MAX_MIDI_DEV 6
+#define MAX_TIMER_DEV 3
+
+#define MAX_CATCH_RADIUS 10
+
+#define le2be16(x) (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
+#define le2be16dbl(x) (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff))
+
+#define IOCTL_IN(arg, ret) \
+ do { int error = get_user(ret, (int __user *)(arg)); \
+ if (error) return error; \
+ } while (0)
+#define IOCTL_OUT(arg, ret) ioctl_return((int __user *)(arg), ret)
+
+static inline int ioctl_return(int __user *addr, int value)
+{
+ return value < 0 ? value : put_user(value, addr);
+}
+
+
+ /*
+ * Configuration
+ */
+
+#undef HAS_8BIT_TABLES
+#undef HAS_RECORD
+
+#if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\
+ defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\
+ defined(CONFIG_DMASOUND_Q40) || defined(CONFIG_DMASOUND_Q40_MODULE)
+#define HAS_8BIT_TABLES
+#define MIN_BUFFERS 4
+#define MIN_BUFSIZE (1<<12) /* in bytes (- where does this come from ?) */
+#define MIN_FRAG_SIZE 8 /* not 100% sure about this */
+#define MAX_BUFSIZE (1<<17) /* Limit for Amiga is 128 kb */
+#define MAX_FRAG_SIZE 15 /* allow *4 for mono-8 => stereo-16 (for multi) */
+
+#else /* is pmac and multi is off */
+
+#define MIN_BUFFERS 2
+#define MIN_BUFSIZE (1<<8) /* in bytes */
+#define MIN_FRAG_SIZE 8
+#define MAX_BUFSIZE (1<<18) /* this is somewhat arbitrary for pmac */
+#define MAX_FRAG_SIZE 16 /* need to allow *4 for mono-8 => stereo-16 */
+#endif
+
+#define DEFAULT_N_BUFFERS 4
+#define DEFAULT_BUFF_SIZE (1<<15)
+
+#if defined(CONFIG_DMASOUND_PMAC) || defined(CONFIG_DMASOUND_PMAC_MODULE)
+#define HAS_RECORD
+#endif
+
+ /*
+ * Initialization
+ */
+
+extern int dmasound_init(void);
+#ifdef MODULE
+extern void dmasound_deinit(void);
+#else
+#define dmasound_deinit() do { } while (0)
+#endif
+
+/* description of the set-up applies to either hard or soft settings */
+
+typedef struct {
+ int format; /* AFMT_* */
+ int stereo; /* 0 = mono, 1 = stereo */
+ int size; /* 8/16 bit*/
+ int speed; /* speed */
+} SETTINGS;
+
+ /*
+ * Machine definitions
+ */
+
+typedef struct {
+ const char *name;
+ const char *name2;
+ struct module *owner;
+ void *(*dma_alloc)(unsigned int, int);
+ void (*dma_free)(void *, unsigned int);
+ int (*irqinit)(void);
+#ifdef MODULE
+ void (*irqcleanup)(void);
+#endif
+ void (*init)(void);
+ void (*silence)(void);
+ int (*setFormat)(int);
+ int (*setVolume)(int);
+ int (*setBass)(int);
+ int (*setTreble)(int);
+ int (*setGain)(int);
+ void (*play)(void);
+ void (*record)(void); /* optional */
+ void (*mixer_init)(void); /* optional */
+ int (*mixer_ioctl)(u_int, u_long); /* optional */
+ int (*write_sq_setup)(void); /* optional */
+ int (*read_sq_setup)(void); /* optional */
+ int (*sq_open)(mode_t); /* optional */
+ int (*state_info)(char *, size_t); /* optional */
+ void (*abort_read)(void); /* optional */
+ int min_dsp_speed;
+ int max_dsp_speed;
+ int version ;
+ int hardware_afmts ; /* OSS says we only return h'ware info */
+ /* when queried via SNDCTL_DSP_GETFMTS */
+ int capabilities ; /* low-level reply to SNDCTL_DSP_GETCAPS */
+ SETTINGS default_hard ; /* open() or init() should set something valid */
+ SETTINGS default_soft ; /* you can make it look like old OSS, if you want to */
+} MACHINE;
+
+ /*
+ * Low level stuff
+ */
+
+typedef struct {
+ ssize_t (*ct_ulaw)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
+ ssize_t (*ct_alaw)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
+ ssize_t (*ct_s8)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
+ ssize_t (*ct_u8)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
+ ssize_t (*ct_s16be)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
+ ssize_t (*ct_u16be)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
+ ssize_t (*ct_s16le)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
+ ssize_t (*ct_u16le)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
+} TRANS;
+
+struct sound_settings {
+ MACHINE mach; /* machine dependent things */
+ SETTINGS hard; /* hardware settings */
+ SETTINGS soft; /* software settings */
+ SETTINGS dsp; /* /dev/dsp default settings */
+ TRANS *trans_write; /* supported translations */
+#ifdef HAS_RECORD
+ TRANS *trans_read; /* supported translations */
+#endif
+ int volume_left; /* volume (range is machine dependent) */
+ int volume_right;
+ int bass; /* tone (range is machine dependent) */
+ int treble;
+ int gain;
+ int minDev; /* minor device number currently open */
+ spinlock_t lock;
+};
+
+extern struct sound_settings dmasound;
+
+#ifdef HAS_8BIT_TABLES
+extern char dmasound_ulaw2dma8[];
+extern char dmasound_alaw2dma8[];
+#endif
+
+ /*
+ * Mid level stuff
+ */
+
+static inline int dmasound_set_volume(int volume)
+{
+ return dmasound.mach.setVolume(volume);
+}
+
+static inline int dmasound_set_bass(int bass)
+{
+ return dmasound.mach.setBass ? dmasound.mach.setBass(bass) : 50;
+}
+
+static inline int dmasound_set_treble(int treble)
+{
+ return dmasound.mach.setTreble ? dmasound.mach.setTreble(treble) : 50;
+}
+
+static inline int dmasound_set_gain(int gain)
+{
+ return dmasound.mach.setGain ? dmasound.mach.setGain(gain) : 100;
+}
+
+
+ /*
+ * Sound queue stuff, the heart of the driver
+ */
+
+struct sound_queue {
+ /* buffers allocated for this queue */
+ int numBufs; /* real limits on what the user can have */
+ int bufSize; /* in bytes */
+ char **buffers;
+
+ /* current parameters */
+ int locked ; /* params cannot be modified when != 0 */
+ int user_frags ; /* user requests this many */
+ int user_frag_size ; /* of this size */
+ int max_count; /* actual # fragments <= numBufs */
+ int block_size; /* internal block size in bytes */
+ int max_active; /* in-use fragments <= max_count */
+
+ /* it shouldn't be necessary to declare any of these volatile */
+ int front, rear, count;
+ int rear_size;
+ /*
+ * The use of the playing field depends on the hardware
+ *
+ * Atari, PMac: The number of frames that are loaded/playing
+ *
+ * Amiga: Bit 0 is set: a frame is loaded
+ * Bit 1 is set: a frame is playing
+ */
+ int active;
+ wait_queue_head_t action_queue, open_queue, sync_queue;
+ int open_mode;
+ int busy, syncing, xruns, died;
+};
+
+#define SLEEP(queue) interruptible_sleep_on_timeout(&queue, HZ)
+#define WAKE_UP(queue) (wake_up_interruptible(&queue))
+
+extern struct sound_queue dmasound_write_sq;
+#define write_sq dmasound_write_sq
+
+#ifdef HAS_RECORD
+extern struct sound_queue dmasound_read_sq;
+#define read_sq dmasound_read_sq
+#endif
+
+extern int dmasound_catchRadius;
+#define catchRadius dmasound_catchRadius
+
+/* define the value to be put in the byte-swap reg in mac-io
+ when we want it to swap for us.
+*/
+#define BS_VAL 1
+
+#define SW_INPUT_VOLUME_SCALE 4
+#define SW_INPUT_VOLUME_DEFAULT (128 / SW_INPUT_VOLUME_SCALE)
+
+extern int expand_bal; /* Balance factor for expanding (not volume!) */
+extern int expand_read_bal; /* Balance factor for reading */
+extern uint software_input_volume; /* software implemented recording volume! */
+
+#endif /* _dmasound_h_ */
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
new file mode 100644
index 00000000000..8daaf87664b
--- /dev/null
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -0,0 +1,1600 @@
+/*
+ * linux/sound/oss/dmasound/dmasound_atari.c
+ *
+ * Atari TT and Falcon DMA Sound Driver
+ *
+ * See linux/sound/oss/dmasound/dmasound_core.c for copyright and credits
+ * prior to 28/01/2001
+ *
+ * 28/01/2001 [0.1] Iain Sandoe
+ * - added versioning
+ * - put in and populated the hardware_afmts field.
+ * [0.2] - put in SNDCTL_DSP_GETCAPS value.
+ * 01/02/2001 [0.3] - put in default hard/soft settings.
+ */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/soundcard.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <asm/uaccess.h>
+#include <asm/atariints.h>
+#include <asm/atari_stram.h>
+
+#include "dmasound.h"
+
+#define DMASOUND_ATARI_REVISION 0
+#define DMASOUND_ATARI_EDITION 3
+
+extern void atari_microwire_cmd(int cmd);
+
+static int is_falcon;
+static int write_sq_ignore_int; /* ++TeSche: used for Falcon */
+
+static int expand_bal; /* Balance factor for expanding (not volume!) */
+static int expand_data; /* Data for expanding */
+
+
+/*** Translations ************************************************************/
+
+
+/* ++TeSche: radically changed for new expanding purposes...
+ *
+ * These two routines now deal with copying/expanding/translating the samples
+ * from user space into our buffer at the right frequency. They take care about
+ * how much data there's actually to read, how much buffer space there is and<