diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /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/Kconfig | 58 | ||||
-rw-r--r-- | sound/oss/dmasound/Makefile | 13 | ||||
-rw-r--r-- | sound/oss/dmasound/awacs_defs.h | 251 | ||||
-rw-r--r-- | sound/oss/dmasound/dac3550a.c | 210 | ||||
-rw-r--r-- | sound/oss/dmasound/dmasound.h | 277 | ||||
-rw-r--r-- | sound/oss/dmasound/dmasound_atari.c | 1600 | ||||
-rw-r--r-- | sound/oss/dmasound/dmasound_awacs.c | 3176 | ||||
-rw-r--r-- | sound/oss/dmasound/dmasound_core.c | 1829 | ||||
-rw-r--r-- | sound/oss/dmasound/dmasound_paula.c | 743 | ||||
-rw-r--r-- | sound/oss/dmasound/dmasound_q40.c | 634 | ||||
-rw-r--r-- | sound/oss/dmasound/tas3001c.c | 850 | ||||
-rw-r--r-- | sound/oss/dmasound/tas3001c.h | 64 | ||||
-rw-r--r-- | sound/oss/dmasound/tas3001c_tables.c | 375 | ||||
-rw-r--r-- | sound/oss/dmasound/tas3004.c | 1140 | ||||
-rw-r--r-- | sound/oss/dmasound/tas3004.h | 77 | ||||
-rw-r--r-- | sound/oss/dmasound/tas3004_tables.c | 301 | ||||
-rw-r--r-- | sound/oss/dmasound/tas_common.c | 214 | ||||
-rw-r--r-- | sound/oss/dmasound/tas_common.h | 284 | ||||
-rw-r--r-- | sound/oss/dmasound/tas_eq_prefs.h | 24 | ||||
-rw-r--r-- | sound/oss/dmasound/tas_ioctl.h | 24 | ||||
-rw-r--r-- | sound/oss/dmasound/trans_16.c | 897 |
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< |