mirror of
https://github.com/joel16/android_kernel_sony_msm8994.git
synced 2024-11-24 20:50:30 +00:00
The next round of scheduled OSS code removal
This patch contains the next round of scheduled OSS code removal. Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
5b4db0c2f2
commit
fc37449f79
@ -219,13 +219,6 @@ Who: Jean Delvare <khali@linux-fr.org>,
|
||||
|
||||
---------------------------
|
||||
|
||||
What: drivers depending on OBSOLETE_OSS
|
||||
When: options in 2.6.22, code in 2.6.24
|
||||
Why: OSS drivers with ALSA replacements
|
||||
Who: Adrian Bunk <bunk@stusta.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: ACPI procfs interface
|
||||
When: July 2008
|
||||
Why: ACPI sysfs conversion should be finished by January 2008.
|
||||
|
@ -1,64 +0,0 @@
|
||||
/proc/sound, /dev/sndstat
|
||||
-------------------------
|
||||
|
||||
/proc/sound and /dev/sndstat is not supported by the
|
||||
driver. To find out whether the driver succeeded loading,
|
||||
check the kernel log (dmesg).
|
||||
|
||||
|
||||
ALaw/uLaw sample formats
|
||||
------------------------
|
||||
|
||||
This driver does not support the ALaw/uLaw sample formats.
|
||||
ALaw is the default mode when opening a sound device
|
||||
using OSS/Free. The reason for the lack of support is
|
||||
that the hardware does not support these formats, and adding
|
||||
conversion routines to the kernel would lead to very ugly
|
||||
code in the presence of the mmap interface to the driver.
|
||||
And since xquake uses mmap, mmap is considered important :-)
|
||||
and no sane application uses ALaw/uLaw these days anyway.
|
||||
In short, playing a Sun .au file as follows:
|
||||
|
||||
cat my_file.au > /dev/dsp
|
||||
|
||||
does not work. Instead, you may use the play script from
|
||||
Chris Bagwell's sox-12.14 package (available from the URL
|
||||
below) to play many different audio file formats.
|
||||
The script automatically determines the audio format
|
||||
and does do audio conversions if necessary.
|
||||
http://home.sprynet.com/sprynet/cbagwell/projects.html
|
||||
|
||||
|
||||
Blocking vs. nonblocking IO
|
||||
---------------------------
|
||||
|
||||
Unlike OSS/Free this driver honours the O_NONBLOCK file flag
|
||||
not only during open, but also during read and write.
|
||||
This is an effort to make the sound driver interface more
|
||||
regular. Timidity has problems with this; a patch
|
||||
is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
|
||||
(Timidity patched will also run on OSS/Free).
|
||||
|
||||
|
||||
MIDI UART
|
||||
---------
|
||||
|
||||
The driver supports a simple MIDI UART interface, with
|
||||
no ioctl's supported.
|
||||
|
||||
|
||||
MIDI synthesizer
|
||||
----------------
|
||||
|
||||
This soundcard does not have any hardware MIDI synthesizer;
|
||||
MIDI synthesis has to be done in software. To allow this
|
||||
the driver/soundcard supports two PCM (/dev/dsp) interfaces.
|
||||
|
||||
There is a freely available software package that allows
|
||||
MIDI file playback on this soundcard called Timidity.
|
||||
See http://www.cgs.fi/~tt/timidity/.
|
||||
|
||||
|
||||
|
||||
Thomas Sailer
|
||||
t.sailer@alumni.ethz.ch
|
@ -2940,13 +2940,6 @@ L: linux-kernel@vger.kernel.org
|
||||
L: linux-pci@atrey.karlin.mff.cuni.cz
|
||||
S: Supported
|
||||
|
||||
PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
|
||||
P: Thomas Sailer
|
||||
M: sailer@ife.ee.ethz.ch
|
||||
L: linux-sound@vger.kernel.org
|
||||
W: http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html
|
||||
S: Maintained
|
||||
|
||||
PCI SUBSYSTEM
|
||||
P: Greg Kroah-Hartman
|
||||
M: gregkh@suse.de
|
||||
|
@ -36,7 +36,6 @@ obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
|
||||
obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
|
||||
obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
|
||||
obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o
|
||||
obj-$(CONFIG_SOUND_ES1371) += es1371.o ac97_codec.o
|
||||
obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o
|
||||
obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o
|
||||
obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
|
||||
|
@ -2,12 +2,6 @@
|
||||
# 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
|
||||
|
@ -1,251 +0,0 @@
|
||||
/*********************************************************/
|
||||
/* 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_ */
|
@ -1,209 +0,0 @@
|
||||
/*
|
||||
* 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 = {
|
||||
.driver = {
|
||||
.name = "DAC3550A driver V " DACA_VERSION,
|
||||
},
|
||||
.id = I2C_DRIVERID_DACA,
|
||||
.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 = kzalloc(sizeof(*new_client), GFP_KERNEL);
|
||||
if (!new_client)
|
||||
return -ENOMEM;
|
||||
|
||||
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);
|
||||
}
|
@ -59,7 +59,6 @@ static inline int ioctl_return(int __user *addr, int value)
|
||||
*/
|
||||
|
||||
#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) ||\
|
||||
@ -83,10 +82,6 @@ static inline int ioctl_return(int __user *addr, int value)
|
||||
#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
|
||||
*/
|
||||
@ -168,9 +163,6 @@ struct sound_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) */
|
||||
@ -253,11 +245,6 @@ struct sound_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
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -202,13 +202,6 @@ module_param(numWriteBufs, int, 0);
|
||||
static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */
|
||||
module_param(writeBufSize, int, 0);
|
||||
|
||||
#ifdef HAS_RECORD
|
||||
static unsigned int numReadBufs = DEFAULT_N_BUFFERS;
|
||||
module_param(numReadBufs, int, 0);
|
||||
static unsigned int readBufSize = DEFAULT_BUFF_SIZE; /* in bytes */
|
||||
module_param(readBufSize, int, 0);
|
||||
#endif
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#ifdef MODULE
|
||||
@ -403,10 +396,6 @@ static void mixer_init(void)
|
||||
|
||||
struct sound_queue dmasound_write_sq;
|
||||
static void sq_reset_output(void) ;
|
||||
#ifdef HAS_RECORD
|
||||
struct sound_queue dmasound_read_sq;
|
||||
static void sq_reset_input(void) ;
|
||||
#endif
|
||||
|
||||
static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
|
||||
{
|
||||
@ -530,12 +519,6 @@ printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ;
|
||||
sq->rear = -1;
|
||||
setup_func = dmasound.mach.write_sq_setup;
|
||||
}
|
||||
#ifdef HAS_RECORD
|
||||
else {
|
||||
sq->rear = 0;
|
||||
setup_func = dmasound.mach.read_sq_setup;
|
||||
}
|
||||
#endif
|
||||
if (setup_func)
|
||||
return setup_func();
|
||||
return 0 ;
|
||||
@ -672,13 +655,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
|
||||
}
|
||||
if (file->f_mode & FMODE_WRITE )
|
||||
poll_wait(file, &write_sq.action_queue, wait);
|
||||
#ifdef HAS_RECORD
|
||||
if (file->f_mode & FMODE_READ)
|
||||
poll_wait(file, &read_sq.action_queue, wait);
|
||||
if (file->f_mode & FMODE_READ)
|
||||
if (read_sq.block_size - read_sq.rear_size > 0)
|
||||
mask |= POLLIN | POLLRDNORM;
|
||||
#endif
|
||||
if (file->f_mode & FMODE_WRITE)
|
||||
if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
|
||||
mask |= POLLOUT | POLLWRNORM;
|
||||
@ -686,101 +662,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAS_RECORD
|
||||
/*
|
||||
* Here is how the values are used for reading.
|
||||
* The value 'active' simply indicates the DMA is running. This is done
|
||||
* so the driver semantics are DMA starts when the first read is posted.
|
||||
* The value 'front' indicates the buffer we should next send to the user.
|
||||
* The value 'rear' indicates the buffer the DMA is currently filling.
|
||||
* When 'front' == 'rear' the buffer "ring" is empty (we always have an
|
||||
* empty available). The 'rear_size' is used to track partial offsets
|
||||
* into the buffer we are currently returning to the user.
|
||||
|
||||
* This level (> [1.5]) doesn't care what strategy the LL driver uses with
|
||||
* DMA on over-run. It can leave it running (and keep active == 1) or it
|
||||
* can kill it and set active == 0 in which case this routine will spot
|
||||
* it and restart the DMA.
|
||||
*/
|
||||
|
||||
static ssize_t sq_read(struct file *file, char __user *dst, size_t uLeft,
|
||||
loff_t *ppos)
|
||||
{
|
||||
|
||||
ssize_t uRead, bLeft, bUsed, uUsed;
|
||||
|
||||
if (uLeft == 0)
|
||||
return 0;
|
||||
|
||||
/* cater for the compatibility mode - record compiled in but no LL */
|
||||
if (dmasound.mach.record == NULL)
|
||||
return -EINVAL ;
|
||||
|
||||
/* see comment in sq_write()
|
||||
*/
|
||||
|
||||
if( shared_resources_initialised == 0) {
|
||||
dmasound.mach.init() ;
|
||||
shared_resources_initialised = 1 ;
|
||||
}
|
||||
|
||||
/* set up the sq if it is not already done. see comments in sq_write().
|
||||
*/
|
||||
|
||||
if (read_sq.locked == 0) {
|
||||
if ((uRead = sq_setup(&read_sq)) < 0)
|
||||
return uRead ;
|
||||
}
|
||||
|
||||
uRead = 0;
|
||||
|
||||
/* Move what the user requests, depending upon other options.
|
||||
*/
|
||||
while (uLeft > 0) {
|
||||
|
||||
/* we happened to get behind and the LL driver killed DMA
|
||||
then we should set it going again. This also sets it
|
||||
going the first time through.
|
||||
*/
|
||||
if ( !read_sq.active )
|
||||
dmasound.mach.record();
|
||||
|
||||
/* When front == rear, the DMA is not done yet.
|
||||
*/
|
||||
while (read_sq.front == read_sq.rear) {
|
||||
if (read_sq.open_mode & O_NONBLOCK) {
|
||||
return uRead > 0 ? uRead : -EAGAIN;
|
||||
}
|
||||
SLEEP(read_sq.action_queue);
|
||||
if (signal_pending(current))
|
||||
return uRead > 0 ? uRead : -EINTR;
|
||||
}
|
||||
|
||||
/* The amount we move is either what is left in the
|
||||
* current buffer or what the user wants.
|
||||
*/
|
||||
bLeft = read_sq.block_size - read_sq.rear_size;
|
||||
bUsed = read_sq.rear_size;
|
||||
uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft,
|
||||
read_sq.buffers[read_sq.front],
|
||||
&bUsed, bLeft);
|
||||
if (uUsed <= 0)
|
||||
return uUsed;
|
||||
dst += uUsed;
|
||||
uRead += uUsed;
|
||||
uLeft -= uUsed;
|
||||
read_sq.rear_size += bUsed;
|
||||
if (read_sq.rear_size >= read_sq.block_size) {
|
||||
read_sq.rear_size = 0;
|
||||
read_sq.front++;
|
||||
if (read_sq.front >= read_sq.max_active)
|
||||
read_sq.front = 0;
|
||||
}
|
||||
}
|
||||
return uRead;
|
||||
}
|
||||
#endif /* HAS_RECORD */
|
||||
|
||||
static inline void sq_init_waitqueue(struct sound_queue *sq)
|
||||
{
|
||||
init_waitqueue_head(&sq->action_queue);
|
||||
@ -854,23 +735,6 @@ static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
|
||||
#define write_sq_open(file) \
|
||||
sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
|
||||
|
||||
#ifdef HAS_RECORD
|
||||
#define read_sq_init_waitqueue() sq_init_waitqueue(&read_sq)
|
||||
#if 0 /* blocking open() */
|
||||
#define read_sq_wake_up(file) sq_wake_up(&read_sq, file, FMODE_READ)
|
||||
#endif
|
||||
#define read_sq_release_buffers() sq_release_buffers(&read_sq)
|
||||
#define read_sq_open(file) \
|
||||
sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize )
|
||||
#else
|
||||
#define read_sq_init_waitqueue() do {} while (0)
|
||||
#if 0 /* blocking open() */
|
||||
#define read_sq_wake_up(file) do {} while (0)
|
||||
#endif
|
||||
#define read_sq_release_buffers() do {} while (0)
|
||||
#define sq_reset_input() do {} while (0)
|
||||
#endif
|
||||
|
||||
static int sq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int rc;
|
||||
@ -881,25 +745,11 @@ static int sq_open(struct inode *inode, struct file *file)
|
||||
rc = write_sq_open(file); /* checks the f_mode */
|
||||
if (rc)
|
||||
goto out;
|
||||
#ifdef HAS_RECORD
|
||||
if (dmasound.mach.record) {
|
||||
rc = read_sq_open(file); /* checks the f_mode */
|
||||
if (rc)
|
||||
goto out;
|
||||
} else { /* no record function installed; in compat mode */
|
||||
if (file->f_mode & FMODE_READ) {
|
||||
/* TODO: if O_RDWR, release any resources grabbed by write part */
|
||||
rc = -ENXIO;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#else /* !HAS_RECORD */
|
||||
if (file->f_mode & FMODE_READ) {
|
||||
/* TODO: if O_RDWR, release any resources grabbed by write part */
|
||||
rc = -ENXIO ; /* I think this is what is required by open(2) */
|
||||
goto out;
|
||||
}
|
||||
#endif /* HAS_RECORD */
|
||||
|
||||
if (dmasound.mach.sq_open)
|
||||
dmasound.mach.sq_open(file->f_mode);
|
||||
@ -956,43 +806,9 @@ static void sq_reset_output(void)
|
||||
write_sq.user_frag_size = 0 ;
|
||||
}
|
||||
|
||||
#ifdef HAS_RECORD
|
||||
|
||||
static void sq_reset_input(void)
|
||||
{
|
||||
if (dmasound.mach.record && read_sq.active) {
|
||||
if (dmasound.mach.abort_read) { /* this routine must really be present */
|
||||
read_sq.syncing = 1 ;
|
||||
/* this can use the read_sq.sync_queue to sleep if
|
||||
necessary - it should not return until DMA
|
||||
is really stopped - because we might deallocate
|
||||
the buffers as the next action...
|
||||
*/
|
||||
dmasound.mach.abort_read() ;
|
||||
} else {
|
||||
printk(KERN_ERR
|
||||
"dmasound_core: %s has no abort_read()!! all bets are off\n",
|
||||
dmasound.mach.name) ;
|
||||
}
|
||||
}
|
||||
read_sq.syncing =
|
||||
read_sq.active =
|
||||
read_sq.front =
|
||||
read_sq.count =
|
||||
read_sq.rear = 0 ;
|
||||
|
||||
/* OK - we can unlock the parameters and fragment settings */
|
||||
read_sq.locked = 0 ;
|
||||
read_sq.user_frags = 0 ;
|
||||
read_sq.user_frag_size = 0 ;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void sq_reset(void)
|
||||
{
|
||||
sq_reset_output() ;
|
||||
sq_reset_input() ;
|
||||
/* we could consider resetting the shared_resources_owner here... but I
|
||||
think it is probably still rather non-obvious to application writer
|
||||
*/
|
||||
@ -1038,17 +854,6 @@ static int sq_release(struct inode *inode, struct file *file)
|
||||
|
||||
lock_kernel();
|
||||
|
||||
#ifdef HAS_RECORD
|
||||
/* probably best to do the read side first - so that time taken to do it
|
||||
overlaps with playing any remaining output samples.
|
||||
*/
|
||||
if (file->f_mode & FMODE_READ) {
|
||||
sq_reset_input() ; /* make sure dma is stopped and all is quiet */
|
||||
read_sq_release_buffers();
|
||||
read_sq.busy = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (file->f_mode & FMODE_WRITE) {
|
||||
if (write_sq.busy)
|
||||
rc = sq_fsync(file, file->f_path.dentry);
|
||||
@ -1105,11 +910,6 @@ static int shared_resources_are_mine(mode_t md)
|
||||
|
||||
static int queues_are_quiescent(void)
|
||||
{
|
||||
#ifdef HAS_RECORD
|
||||
if (dmasound.mach.record)
|
||||
if (read_sq.locked)
|
||||
return 0 ;
|
||||
#endif
|
||||
if (write_sq.locked)
|
||||
return 0 ;
|
||||
return 1 ;
|
||||
@ -1185,13 +985,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
|
||||
the read_sq ones.
|
||||
*/
|
||||
size = 0 ;
|
||||
#ifdef HAS_RECORD
|
||||
if (dmasound.mach.record && (file->f_mode & FMODE_READ)) {
|
||||
if ( !read_sq.locked )
|
||||
sq_setup(&read_sq) ; /* set params */
|
||||
size = read_sq.user_frag_size ;
|
||||
}
|
||||
#endif
|
||||
if (file->f_mode & FMODE_WRITE) {
|
||||
if ( !write_sq.locked )
|
||||
sq_setup(&write_sq) ;
|
||||
@ -1214,8 +1007,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
|
||||
everything - read, however, is killed imediately.
|
||||
*/
|
||||
result = 0 ;
|
||||
if ((file->f_mode & FMODE_READ) && dmasound.mach.record)
|
||||
sq_reset_input() ;
|
||||
if (file->f_mode & FMODE_WRITE) {
|
||||
result = sq_fsync(file, file->f_path.dentry);
|
||||
sq_reset_output() ;
|
||||
@ -1294,13 +1085,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
|
||||
result = 0 ;
|
||||
nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
|
||||
size = data & 0xffff;
|
||||
#ifdef HAS_RECORD
|
||||
if ((file->f_mode & FMODE_READ) && dmasound.mach.record) {
|
||||
result = set_queue_frags(&read_sq, nbufs, size) ;
|
||||
if (result)
|
||||
return result ;
|
||||
}
|
||||
#endif
|
||||
if (file->f_mode & FMODE_WRITE) {
|
||||
result = set_queue_frags(&write_sq, nbufs, size) ;
|
||||
if (result)
|
||||
@ -1348,20 +1132,6 @@ static const struct file_operations sq_fops =
|
||||
.release = sq_release,
|
||||
};
|
||||
|
||||
#ifdef HAS_RECORD
|
||||
static const struct file_operations sq_fops_record =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.write = sq_write,
|
||||
.poll = sq_poll,
|
||||
.ioctl = sq_ioctl,
|
||||
.open = sq_open,
|
||||
.release = sq_release,
|
||||
.read = sq_read,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int sq_init(void)
|
||||
{
|
||||
const struct file_operations *fops = &sq_fops;
|
||||
@ -1369,10 +1139,6 @@ static int sq_init(void)
|
||||
int sq_unit;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_RECORD
|
||||
if (dmasound.mach.record)
|
||||
fops = &sq_fops_record;
|
||||
#endif
|
||||
sq_unit = register_sound_dsp(fops, -1);
|
||||
if (sq_unit < 0) {
|
||||
printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
|
||||
@ -1380,7 +1146,6 @@ static int sq_init(void)
|
||||
}
|
||||
|
||||
write_sq_init_waitqueue();
|
||||
read_sq_init_waitqueue();
|
||||
|
||||
/* These parameters will be restored for every clean open()
|
||||
* in the case of multiple open()s (e.g. dsp0 & dsp1) they
|
||||
@ -1406,11 +1171,7 @@ static int sq_init(void)
|
||||
driver.
|
||||
*/
|
||||
|
||||
#ifdef HAS_RECORD
|
||||
#define STAT_BUFF_LEN 1024
|
||||
#else
|
||||
#define STAT_BUFF_LEN 768
|
||||
#endif
|
||||
|
||||
/* this is how much space we will allow the low-level driver to use
|
||||
in the stat buffer. Currently, 2 * (80 character line + <NL>).
|
||||
@ -1518,11 +1279,6 @@ static int state_open(struct inode *inode, struct file *file)
|
||||
len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
|
||||
len += sprintf(buffer+len,"%9s:%8d%6d\n",
|
||||
"write", write_sq.numBufs, write_sq.bufSize) ;
|
||||
#ifdef HAS_RECORD
|
||||
if (dmasound.mach.record)
|
||||
len += sprintf(buffer+len,"%9s:%8d%6d\n",
|
||||
"read", read_sq.numBufs, read_sq.bufSize) ;
|
||||
#endif
|
||||
len += sprintf(buffer+len,
|
||||
"Current : MaxFrg FragSiz MaxAct Frnt Rear "
|
||||
"Cnt RrSize A B S L xruns\n") ;
|
||||
@ -1531,14 +1287,6 @@ static int state_open(struct inode *inode, struct file *file)
|
||||
write_sq.max_active, write_sq.front, write_sq.rear,
|
||||
write_sq.count, write_sq.rear_size, write_sq.active,
|
||||
write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
|
||||
#ifdef HAS_RECORD
|
||||
if (dmasound.mach.record)
|
||||
len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
|
||||
"read", read_sq.max_count, read_sq.block_size,
|
||||
read_sq.max_active, read_sq.front, read_sq.rear,
|
||||
read_sq.count, read_sq.rear_size, read_sq.active,
|
||||
read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ;
|
||||
#endif
|
||||
#ifdef DEBUG_DMASOUND
|
||||
printk("dmasound: stat buffer used %d bytes\n", len) ;
|
||||
#endif
|
||||
@ -1638,13 +1386,6 @@ int dmasound_init(void)
|
||||
(dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
|
||||
printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
|
||||
numWriteBufs, writeBufSize) ;
|
||||
#ifdef HAS_RECORD
|
||||
if (dmasound.mach.record)
|
||||
printk(KERN_INFO
|
||||
"Read will use %4d fragments of %7d bytes as default\n",
|
||||
numReadBufs, readBufSize) ;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1659,7 +1400,6 @@ void dmasound_deinit(void)
|
||||
}
|
||||
|
||||
write_sq_release_buffers();
|
||||
read_sq_release_buffers();
|
||||
|
||||
if (mixer_unit >= 0)
|
||||
unregister_sound_mixer(mixer_unit);
|
||||
@ -1684,36 +1424,12 @@ static int dmasound_setup(char *str)
|
||||
*/
|
||||
|
||||
switch (ints[0]) {
|
||||
#ifdef HAS_RECORD
|
||||
case 5:
|
||||
if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS))
|
||||
printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
|
||||
else
|
||||
catchRadius = ints[5];
|
||||
/* fall through */
|
||||
case 4:
|
||||
if (ints[4] < MIN_BUFFERS)
|
||||
printk("dmasound_setup: invalid number of read buffers, using default = %d\n",
|
||||
numReadBufs);
|
||||
else
|
||||
numReadBufs = ints[4];
|
||||
/* fall through */
|
||||
case 3:
|
||||
if ((size = ints[3]) < 256) /* check for small buffer specs */
|
||||
size <<= 10 ;
|
||||
if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
|
||||
printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize);
|
||||
else
|
||||
readBufSize = size;
|
||||
/* fall through */
|
||||
#else
|
||||
case 3:
|
||||
if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
|
||||
printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
|
||||
else
|
||||
catchRadius = ints[3];
|
||||
/* fall through */
|
||||
#endif
|
||||
case 2:
|
||||
if (ints[1] < MIN_BUFFERS)
|
||||
printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
|
||||
@ -1830,9 +1546,6 @@ EXPORT_SYMBOL(dmasound_init);
|
||||
EXPORT_SYMBOL(dmasound_deinit);
|
||||
#endif
|
||||
EXPORT_SYMBOL(dmasound_write_sq);
|
||||
#ifdef HAS_RECORD
|
||||
EXPORT_SYMBOL(dmasound_read_sq);
|
||||
#endif
|
||||
EXPORT_SYMBOL(dmasound_catchRadius);
|
||||
#ifdef HAS_8BIT_TABLES
|
||||
EXPORT_SYMBOL(dmasound_ulaw2dma8);
|
||||
|
@ -1,849 +0,0 @@
|
||||
/*
|
||||
* Driver for the i2c/i2s based TA3004 sound chip used
|
||||
* on some Apple hardware. Also known as "snapper".
|
||||
*
|
||||
* Tobias Sargeant <tobias.sargeant@bigpond.com>
|
||||
* Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
|
||||
*
|
||||
* TODO:
|
||||
* -----
|
||||
* * Enable control over input line 2 (is this connected?)
|
||||
* * Implement sleep support (at least mute everything and
|
||||
* * set gains to minimum during sleep)
|
||||
* * Look into some of Darwin's tweaks regarding the mute
|
||||
* * lines (delays & different behaviour on some HW)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.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 <linux/soundcard.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include "dmasound.h"
|
||||
#include "tas_common.h"
|
||||
#include "tas3001c.h"
|
||||
|
||||
#include "tas_ioctl.h"
|
||||
|
||||
#define TAS3001C_BIQUAD_FILTER_COUNT 6
|
||||
#define TAS3001C_BIQUAD_CHANNEL_COUNT 2
|
||||
|
||||
#define VOL_DEFAULT (100 * 4 / 5)
|
||||
#define INPUT_DEFAULT (100 * 4 / 5)
|
||||
#define BASS_DEFAULT (100 / 2)
|
||||
#define TREBLE_DEFAULT (100 / 2)
|
||||
|
||||
struct tas3001c_data_t {
|
||||
struct tas_data_t super;
|
||||
int device_id;
|
||||
int output_id;
|
||||
int speaker_id;
|
||||
struct tas_drce_t drce_state;
|
||||
struct work_struct change;
|
||||
};
|
||||
|
||||
|
||||
static const union tas_biquad_t
|
||||
tas3001c_eq_unity={
|
||||
.buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }
|
||||
};
|
||||
|
||||
|
||||
static inline unsigned char db_to_regval(short db) {
|
||||
int r=0;
|
||||
|
||||
r=(db+0x59a0) / 0x60;
|
||||
|
||||
if (r < 0x91) return 0x91;
|
||||
if (r > 0xef) return 0xef;
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline short quantize_db(short db) {
|
||||
return db_to_regval(db) * 0x60 - 0x59a0;
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
register_width(enum tas3001c_reg_t r)
|
||||
{
|
||||
switch(r) {
|
||||
case TAS3001C_REG_MCR:
|
||||
case TAS3001C_REG_TREBLE:
|
||||
case TAS3001C_REG_BASS:
|
||||
return 1;
|
||||
|
||||
case TAS3001C_REG_DRC:
|
||||
return 2;
|
||||
|
||||
case TAS3001C_REG_MIXER1:
|
||||
case TAS3001C_REG_MIXER2:
|
||||
return 3;
|
||||
|
||||
case TAS3001C_REG_VOLUME:
|
||||
return 6;
|
||||
|
||||
case TAS3001C_REG_LEFT_BIQUAD0:
|
||||
case TAS3001C_REG_LEFT_BIQUAD1:
|
||||
case TAS3001C_REG_LEFT_BIQUAD2:
|
||||
case TAS3001C_REG_LEFT_BIQUAD3:
|
||||
case TAS3001C_REG_LEFT_BIQUAD4:
|
||||
case TAS3001C_REG_LEFT_BIQUAD5:
|
||||
case TAS3001C_REG_LEFT_BIQUAD6:
|
||||
|
||||
case TAS3001C_REG_RIGHT_BIQUAD0:
|
||||
case TAS3001C_REG_RIGHT_BIQUAD1:
|
||||
case TAS3001C_REG_RIGHT_BIQUAD2:
|
||||
case TAS3001C_REG_RIGHT_BIQUAD3:
|
||||
case TAS3001C_REG_RIGHT_BIQUAD4:
|
||||
case TAS3001C_REG_RIGHT_BIQUAD5:
|
||||
case TAS3001C_REG_RIGHT_BIQUAD6:
|
||||
return 15;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_write_register( struct tas3001c_data_t *self,
|
||||
enum tas3001c_reg_t reg_num,
|
||||
char *data,
|
||||
uint write_mode)
|
||||
{
|
||||
if (reg_num==TAS3001C_REG_MCR ||
|
||||
reg_num==TAS3001C_REG_BASS ||
|
||||
reg_num==TAS3001C_REG_TREBLE) {
|
||||
return tas_write_byte_register(&self->super,
|
||||
(uint)reg_num,
|
||||
*data,
|
||||
write_mode);
|
||||
} else {
|
||||
return tas_write_register(&self->super,
|
||||
(uint)reg_num,
|
||||
register_width(reg_num),
|
||||
data,
|
||||
write_mode);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_sync_register( struct tas3001c_data_t *self,
|
||||
enum tas3001c_reg_t reg_num)
|
||||
{
|
||||
if (reg_num==TAS3001C_REG_MCR ||
|
||||
reg_num==TAS3001C_REG_BASS ||
|
||||
reg_num==TAS3001C_REG_TREBLE) {
|
||||
return tas_sync_byte_register(&self->super,
|
||||
(uint)reg_num,
|
||||
register_width(reg_num));
|
||||
} else {
|
||||
return tas_sync_register(&self->super,
|
||||
(uint)reg_num,
|
||||
register_width(reg_num));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_read_register( struct tas3001c_data_t *self,
|
||||
enum tas3001c_reg_t reg_num,
|
||||
char *data,
|
||||
uint write_mode)
|
||||
{
|
||||
return tas_read_register(&self->super,
|
||||
(uint)reg_num,
|
||||
register_width(reg_num),
|
||||
data);
|
||||
}
|
||||
|
||||
static inline int
|
||||
tas3001c_fast_load(struct tas3001c_data_t *self, int fast)
|
||||
{
|
||||
if (fast)
|
||||
self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80;
|
||||
else
|
||||
self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f;
|
||||
return tas3001c_sync_register(self,TAS3001C_REG_MCR);
|
||||
}
|
||||
|
||||
static uint
|
||||
tas3001c_supported_mixers(struct tas3001c_data_t *self)
|
||||
{
|
||||
return SOUND_MASK_VOLUME |
|
||||
SOUND_MASK_PCM |
|
||||
SOUND_MASK_ALTPCM |
|
||||
SOUND_MASK_TREBLE |
|
||||
SOUND_MASK_BASS;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer)
|
||||
{
|
||||
switch(mixer) {
|
||||
case SOUND_MIXER_VOLUME:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint
|
||||
tas3001c_stereo_mixers(struct tas3001c_data_t *self)
|
||||
{
|
||||
uint r=tas3001c_supported_mixers(self);
|
||||
uint i;
|
||||
|
||||
for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
|
||||
if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i))
|
||||
r &= ~(1<<i);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level)
|
||||
{
|
||||
if (!self)
|
||||
return -1;
|
||||
|
||||
*level=self->super.mixer[mixer];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level)
|
||||
{
|
||||
int rc;
|
||||
tas_shadow_t *shadow;
|
||||
|
||||
uint temp;
|
||||
uint offset=0;
|
||||
|
||||
if (!self)
|
||||
return -1;
|
||||
|
||||
shadow=self->super.shadow;
|
||||
|
||||
if (!tas3001c_mixer_is_stereo(self,mixer))
|
||||
level = tas_mono_to_stereo(level);
|
||||
|
||||
switch(mixer) {
|
||||
case SOUND_MIXER_VOLUME:
|
||||
temp = tas3001c_gain.master[level&0xff];
|
||||
shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff;
|
||||
shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8) & 0xff;
|
||||
shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0) & 0xff;
|
||||
temp = tas3001c_gain.master[(level>>8)&0xff];
|
||||
shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff;
|
||||
shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8) & 0xff;
|
||||
shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0) & 0xff;
|
||||
rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
|
||||
break;
|
||||
case SOUND_MIXER_ALTPCM:
|
||||
/* tas3001c_fast_load(self, 1); */
|
||||
level = tas_mono_to_stereo(level);
|
||||
temp = tas3001c_gain.mixer[level&0xff];
|
||||
shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff;
|
||||
shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8) & 0xff;
|
||||
shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0) & 0xff;
|
||||
rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
|
||||
/* tas3001c_fast_load(self, 0); */
|
||||
break;
|
||||
case SOUND_MIXER_PCM:
|
||||
/* tas3001c_fast_load(self, 1); */
|
||||
level = tas_mono_to_stereo(level);
|
||||
temp = tas3001c_gain.mixer[level&0xff];
|
||||
shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff;
|
||||
shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8) & 0xff;
|
||||
shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0) & 0xff;
|
||||
rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
|
||||
/* tas3001c_fast_load(self, 0); */
|
||||
break;
|
||||
case SOUND_MIXER_TREBLE:
|
||||
temp = tas3001c_gain.treble[level&0xff];
|
||||
shadow[TAS3001C_REG_TREBLE][0]=temp&0xff;
|
||||
rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
|
||||
break;
|
||||
case SOUND_MIXER_BASS:
|
||||
temp = tas3001c_gain.bass[level&0xff];
|
||||
shadow[TAS3001C_REG_BASS][0]=temp&0xff;
|
||||
rc = tas3001c_sync_register(self,TAS3001C_REG_BASS);
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
self->super.mixer[mixer]=level;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_leave_sleep(struct tas3001c_data_t *self)
|
||||
{
|
||||
unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
|
||||
|
||||
if (!self)
|
||||
return -1;
|
||||
|
||||
/* Make sure something answers on the i2c bus */
|
||||
if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
|
||||
WRITE_NORMAL|FORCE_WRITE) < 0)
|
||||
return -1;
|
||||
|
||||
tas3001c_fast_load(self, 1);
|
||||
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
|
||||
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
|
||||
|
||||
tas3001c_fast_load(self, 0);
|
||||
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_enter_sleep(struct tas3001c_data_t *self)
|
||||
{
|
||||
/* Stub for now, but I have the details on low-power mode */
|
||||
if (!self)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_sync_biquad( struct tas3001c_data_t *self,
|
||||
u_int channel,
|
||||
u_int filter)
|
||||
{
|
||||
enum tas3001c_reg_t reg;
|
||||
|
||||
if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
|
||||
filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
|
||||
|
||||
reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
|
||||
|
||||
return tas3001c_sync_register(self,reg);
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_write_biquad_shadow( struct tas3001c_data_t *self,
|
||||
u_int channel,
|
||||
u_int filter,
|
||||
const union tas_biquad_t *biquad)
|
||||
{
|
||||
tas_shadow_t *shadow=self->super.shadow;
|
||||
enum tas3001c_reg_t reg;
|
||||
|
||||
if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
|
||||
filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
|
||||
|
||||
reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
|
||||
|
||||
SET_4_20(shadow[reg], 0,biquad->coeff.b0);
|
||||
SET_4_20(shadow[reg], 3,biquad->coeff.b1);
|
||||
SET_4_20(shadow[reg], 6,biquad->coeff.b2);
|
||||
SET_4_20(shadow[reg], 9,biquad->coeff.a1);
|
||||
SET_4_20(shadow[reg],12,biquad->coeff.a2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_write_biquad( struct tas3001c_data_t *self,
|
||||
u_int channel,
|
||||
u_int filter,
|
||||
const union tas_biquad_t *biquad)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad);
|
||||
if (rc < 0) return rc;
|
||||
|
||||
return tas3001c_sync_biquad(self, channel, filter);
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_write_biquad_list( struct tas3001c_data_t *self,
|
||||
u_int filter_count,
|
||||
u_int flags,
|
||||
struct tas_biquad_ctrl_t *biquads)
|
||||
{
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
|
||||
|
||||
for (i=0; i<filter_count; i++) {
|
||||
rc=tas3001c_write_biquad(self,
|
||||
biquads[i].channel,
|
||||
biquads[i].filter,
|
||||
&biquads[i].data);
|
||||
if (rc < 0) break;
|
||||
}
|
||||
|
||||
if (flags & TAS_BIQUAD_FAST_LOAD) {
|
||||
tas3001c_fast_load(self,0);
|
||||
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_read_biquad( struct tas3001c_data_t *self,
|
||||
u_int channel,
|
||||
u_int filter,
|
||||
union tas_biquad_t *biquad)
|
||||
{
|
||||
tas_shadow_t *shadow=self->super.shadow;
|
||||
enum tas3001c_reg_t reg;
|
||||
|
||||
if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
|
||||
filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
|
||||
|
||||
reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
|
||||
|
||||
biquad->coeff.b0=GET_4_20(shadow[reg], 0);
|
||||
biquad->coeff.b1=GET_4_20(shadow[reg], 3);
|
||||
biquad->coeff.b2=GET_4_20(shadow[reg], 6);
|
||||
biquad->coeff.a1=GET_4_20(shadow[reg], 9);
|
||||
biquad->coeff.a2=GET_4_20(shadow[reg],12);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_eq_rw( struct tas3001c_data_t *self,
|
||||
u_int cmd,
|
||||
u_long arg)
|
||||
{
|
||||
int rc;
|
||||
struct tas_biquad_ctrl_t biquad;
|
||||
void __user *argp = (void __user *)arg;
|
||||
|
||||
if (copy_from_user(&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (cmd & SIOC_IN) {
|
||||
rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
|
||||
if (rc != 0) return rc;
|
||||
}
|
||||
|
||||
if (cmd & SIOC_OUT) {
|
||||
rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
|
||||
if (rc != 0) return rc;
|
||||
|
||||
if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_eq_list_rw( struct tas3001c_data_t *self,
|
||||
u_int cmd,
|
||||
u_long arg)
|
||||
{
|
||||
int rc;
|
||||
int filter_count;
|
||||
int flags;
|
||||
int i,j;
|
||||
char sync_required[2][6];
|
||||
struct tas_biquad_ctrl_t biquad;
|
||||
struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
|
||||
|
||||
memset(sync_required,0,sizeof(sync_required));
|
||||
|
||||
if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_from_user(&flags, &argp->flags, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
if (cmd & SIOC_IN) {
|
||||
}
|
||||
|
||||
for (i=0; i < filter_count; i++) {
|
||||
if (copy_from_user(&biquad, &argp->biquads[i],
|
||||
sizeof(struct tas_biquad_ctrl_t))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (cmd & SIOC_IN) {
|
||||
sync_required[biquad.channel][biquad.filter]=1;
|
||||
rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
|
||||
if (rc != 0) return rc;
|
||||
}
|
||||
|
||||
if (cmd & SIOC_OUT) {
|
||||
rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
|
||||
if (rc != 0) return rc;
|
||||
|
||||
if (copy_to_user(&argp->biquads[i], &biquad,
|
||||
sizeof(struct tas_biquad_ctrl_t))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd & SIOC_IN) {
|
||||
if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
|
||||
for (i=0; i<2; i++) {
|
||||
for (j=0; j<6; j++) {
|
||||
if (sync_required[i][j]) {
|
||||
rc=tas3001c_sync_biquad(self, i, j);
|
||||
if (rc < 0) return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flags & TAS_BIQUAD_FAST_LOAD) {
|
||||
tas3001c_fast_load(self,0);
|
||||
/* now we need to set up the mixers again,
|
||||
because leaving fast mode resets them. */
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_update_drce( struct tas3001c_data_t *self,
|
||||
int flags,
|
||||
struct tas_drce_t *drce)
|
||||
{
|
||||
tas_shadow_t *shadow;
|
||||
shadow=self->super.shadow;
|
||||
|
||||
shadow[TAS3001C_REG_DRC][1] = 0xc1;
|
||||
|
||||
if (flags & TAS_DRCE_THRESHOLD) {
|
||||
self->drce_state.threshold=quantize_db(drce->threshold);
|
||||
shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
|
||||
}
|
||||
|
||||
if (flags & TAS_DRCE_ENABLE) {
|
||||
self->drce_state.enable = drce->enable;
|
||||
}
|
||||
|
||||
if (!self->drce_state.enable) {
|
||||
shadow[TAS3001C_REG_DRC][0] = 0xf0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DRCE
|
||||
printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n",
|
||||
self->drce_state.enable,
|
||||
self->drce_state.threshold);
|
||||
|
||||
printk("DRCE IOCTL: reg [ %02x %02x ]\n",
|
||||
(unsigned char)shadow[TAS3001C_REG_DRC][0],
|
||||
(unsigned char)shadow[TAS3001C_REG_DRC][1]);
|
||||
#endif
|
||||
|
||||
return tas3001c_sync_register(self, TAS3001C_REG_DRC);
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_drce_rw( struct tas3001c_data_t *self,
|
||||
u_int cmd,
|
||||
u_long arg)
|
||||
{
|
||||
int rc;
|
||||
struct tas_drce_ctrl_t drce_ctrl;
|
||||
void __user *argp = (void __user *)arg;
|
||||
|
||||
if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
|
||||
return -EFAULT;
|
||||
|
||||
#ifdef DEBUG_DRCE
|
||||
printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n",
|
||||
drce_ctrl.flags,
|
||||
drce_ctrl.data.enable,
|
||||
drce_ctrl.data.threshold);
|
||||
#endif
|
||||
|
||||
if (cmd & SIOC_IN) {
|
||||
rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (cmd & SIOC_OUT) {
|
||||
if (drce_ctrl.flags & TAS_DRCE_ENABLE)
|
||||
drce_ctrl.data.enable = self->drce_state.enable;
|
||||
|
||||
if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
|
||||
drce_ctrl.data.threshold = self->drce_state.threshold;
|
||||
|
||||
if (copy_to_user(argp, &drce_ctrl,
|
||||
sizeof(struct tas_drce_ctrl_t))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tas3001c_update_device_parameters(struct tas3001c_data_t *self)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
if (!self) return;
|
||||
|
||||
if (self->output_id == TAS_OUTPUT_HEADPHONES) {
|
||||
tas3001c_fast_load(self, 1);
|
||||
|
||||
for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) {
|
||||
for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) {
|
||||
tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity);
|
||||
}
|
||||
}
|
||||
|
||||
tas3001c_fast_load(self, 0);
|
||||
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; tas3001c_eq_prefs[i]; i++) {
|
||||
struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i];
|
||||
|
||||
if (eq->device_id == self->device_id &&
|
||||
(eq->output_id == 0 || eq->output_id == self->output_id) &&
|
||||
(eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
|
||||
|
||||
tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce);
|
||||
tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tas3001c_device_change_handler(struct work_struct *work)
|
||||
{
|
||||
struct tas3001c_data_t *self;
|
||||
self = container_of(work, struct tas3001c_data_t, change);
|
||||
tas3001c_update_device_parameters(self);
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_output_device_change( struct tas3001c_data_t *self,
|
||||
int device_id,
|
||||
int output_id,
|
||||
int speaker_id)
|
||||
{
|
||||
self->device_id=device_id;
|
||||
self->output_id=output_id;
|
||||
self->speaker_id=speaker_id;
|
||||
|
||||
schedule_work(&self->change);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_device_ioctl( struct tas3001c_data_t *self,
|
||||
u_int cmd,
|
||||
u_long arg)
|
||||
{
|
||||
uint __user *argp = (void __user *)arg;
|
||||
switch (cmd) {
|
||||
case TAS_READ_EQ:
|
||||
case TAS_WRITE_EQ:
|
||||
return tas3001c_eq_rw(self, cmd, arg);
|
||||
|
||||
case TAS_READ_EQ_LIST:
|
||||
case TAS_WRITE_EQ_LIST:
|
||||
return tas3001c_eq_list_rw(self, cmd, arg);
|
||||
|
||||
case TAS_READ_EQ_FILTER_COUNT:
|
||||
put_user(TAS3001C_BIQUAD_FILTER_COUNT, argp);
|
||||
return 0;
|
||||
|
||||
case TAS_READ_EQ_CHANNEL_COUNT:
|
||||
put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, argp);
|
||||
return 0;
|
||||
|
||||
case TAS_READ_DRCE:
|
||||
case TAS_WRITE_DRCE:
|
||||
return tas3001c_drce_rw(self, cmd, arg);
|
||||
|
||||
case TAS_READ_DRCE_CAPS:
|
||||
put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, argp);
|
||||
return 0;
|
||||
|
||||
case TAS_READ_DRCE_MIN:
|
||||
case TAS_READ_DRCE_MAX: {
|
||||
struct tas_drce_ctrl_t drce_ctrl;
|
||||
|
||||
if (copy_from_user(&drce_ctrl, argp,
|
||||
sizeof(struct tas_drce_ctrl_t))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
|
||||
if (cmd == TAS_READ_DRCE_MIN) {
|
||||
drce_ctrl.data.threshold=-36<<8;
|
||||
} else {
|
||||
drce_ctrl.data.threshold=-6<<8;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user(argp, &drce_ctrl,
|
||||
sizeof(struct tas_drce_ctrl_t))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_init_mixer(struct tas3001c_data_t *self)
|
||||
{
|
||||
unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
|
||||
|
||||
/* Make sure something answers on the i2c bus */
|
||||
if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
|
||||
WRITE_NORMAL|FORCE_WRITE) < 0)
|
||||
return -1;
|
||||
|
||||
tas3001c_fast_load(self, 1);
|
||||
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6);
|
||||
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
|
||||
(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6);
|
||||
|
||||
tas3001c_fast_load(self, 0);
|
||||
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
|
||||
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_uninit_mixer(struct tas3001c_data_t *self)
|
||||
{
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, 0);
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
|
||||
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, 0);
|
||||
tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas3001c_init(struct i2c_client *client)
|
||||
{
|
||||
struct tas3001c_data_t *self;
|
||||
size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t));
|
||||
int i, j;
|
||||
|
||||
self = kzalloc(sz, GFP_KERNEL);
|
||||
if (!self)
|
||||
return -ENOMEM;
|
||||
|
||||
self->super.client = client;
|
||||
self->super.shadow = (tas_shadow_t *)(self+1);
|
||||
self->output_id = TAS_OUTPUT_HEADPHONES;
|
||||
|
||||
dev_set_drvdata(&client->dev, self);
|
||||
|
||||
for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++)
|
||||
for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++)
|
||||
tas3001c_write_biquad_shadow(self, i, j,
|
||||
&tas3001c_eq_unity);
|
||||
|
||||
INIT_WORK(&self->change, tas3001c_device_change_handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tas3001c_uninit(struct tas3001c_data_t *self)
|
||||
{
|
||||
tas3001c_uninit_mixer(self);
|
||||
kfree(self);
|
||||
}
|
||||
|
||||
struct tas_driver_hooks_t tas3001c_hooks = {
|
||||
.init = (tas_hook_init_t)tas3001c_init,
|
||||
.post_init = (tas_hook_post_init_t)tas3001c_init_mixer,
|
||||
.uninit = (tas_hook_uninit_t)tas3001c_uninit,
|
||||
.get_mixer_level = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level,
|
||||
.set_mixer_level = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level,
|
||||
.enter_sleep = (tas_hook_enter_sleep_t)tas3001c_enter_sleep,
|
||||
.leave_sleep = (tas_hook_leave_sleep_t)tas3001c_leave_sleep,
|
||||
.supported_mixers = (tas_hook_supported_mixers_t)tas3001c_supported_mixers,
|
||||
.mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo,
|
||||
.stereo_mixers = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers,
|
||||
.output_device_change = (tas_hook_output_device_change_t)tas3001c_output_device_change,
|
||||
.device_ioctl = (tas_hook_device_ioctl_t)tas3001c_device_ioctl
|
||||
};
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Header file for the i2c/i2s based TA3001c sound chip used
|
||||
* on some Apple hardware. Also known as "tumbler".
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Written by Christopher C. Chimelis <chris@debian.org>
|
||||
*/
|
||||
|
||||
#ifndef _TAS3001C_H_
|
||||
#define _TAS3001C_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "tas_common.h"
|
||||
#include "tas_eq_prefs.h"
|
||||
|
||||
/*
|
||||
* Macros that correspond to the registers that we write to
|
||||
* when setting the various values.
|
||||
*/
|
||||
|
||||
#define TAS3001C_VERSION "0.3"
|
||||
#define TAS3001C_DATE "20011214"
|
||||
|
||||
#define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION
|
||||
#define I2C_DRIVERID_TAS3001C (I2C_DRIVERID_TAS_BASE+0)
|
||||
|
||||
extern struct tas_driver_hooks_t tas3001c_hooks;
|
||||
extern struct tas_gain_t tas3001c_gain;
|
||||
extern struct tas_eq_pref_t *tas3001c_eq_prefs[];
|
||||
|
||||
enum tas3001c_reg_t {
|
||||
TAS3001C_REG_MCR = 0x01,
|
||||
TAS3001C_REG_DRC = 0x02,
|
||||
|
||||
TAS3001C_REG_VOLUME = 0x04,
|
||||
TAS3001C_REG_TREBLE = 0x05,
|
||||
TAS3001C_REG_BASS = 0x06,
|
||||
TAS3001C_REG_MIXER1 = 0x07,
|
||||
TAS3001C_REG_MIXER2 = 0x08,
|
||||
|
||||
TAS3001C_REG_LEFT_BIQUAD0 = 0x0a,
|
||||
TAS3001C_REG_LEFT_BIQUAD1 = 0x0b,
|
||||
TAS3001C_REG_LEFT_BIQUAD2 = 0x0c,
|
||||
TAS3001C_REG_LEFT_BIQUAD3 = 0x0d,
|
||||
TAS3001C_REG_LEFT_BIQUAD4 = 0x0e,
|
||||
TAS3001C_REG_LEFT_BIQUAD5 = 0x0f,
|
||||
TAS3001C_REG_LEFT_BIQUAD6 = 0x10,
|
||||
|
||||
TAS3001C_REG_RIGHT_BIQUAD0 = 0x13,
|
||||
TAS3001C_REG_RIGHT_BIQUAD1 = 0x14,
|
||||
TAS3001C_REG_RIGHT_BIQUAD2 = 0x15,
|
||||
TAS3001C_REG_RIGHT_BIQUAD3 = 0x16,
|
||||
TAS3001C_REG_RIGHT_BIQUAD4 = 0x17,
|
||||
TAS3001C_REG_RIGHT_BIQUAD5 = 0x18,
|
||||
TAS3001C_REG_RIGHT_BIQUAD6 = 0x19,
|
||||
|
||||
TAS3001C_REG_MAX = 0x20
|
||||
};
|
||||
|
||||
#endif /* _TAS3001C_H_ */
|
@ -1,375 +0,0 @@
|
||||
#include "tas_common.h"
|
||||
#include "tas_eq_prefs.h"
|
||||
|
||||
static struct tas_drce_t eqp_0e_2_1_drce = {
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -15.33 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_0e_2_1 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x0e,
|
||||
.output_id = TAS_OUTPUT_EXTERNAL_SPKR,
|
||||
.speaker_id = 0x01,
|
||||
|
||||
.drce = &eqp_0e_2_1_drce,
|
||||
|
||||
.filter_count = 12,
|
||||
.biquads = eqp_0e_2_1_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static struct tas_drce_t eqp_10_1_0_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -12.46 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_10_1_0 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x10,
|
||||
.output_id = TAS_OUTPUT_INTERNAL_SPKR,
|
||||
.speaker_id = 0x00,
|
||||
|
||||
.drce = &eqp_10_1_0_drce,
|
||||
|
||||
.filter_count = 12,
|
||||
.biquads = eqp_10_1_0_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static struct tas_drce_t eqp_15_2_1_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -15.33 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_15_2_1 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x15,
|
||||
.output_id = TAS_OUTPUT_EXTERNAL_SPKR,
|
||||
.speaker_id = 0x01,
|
||||
|
||||
.drce = &eqp_15_2_1_drce,
|
||||
|
||||
.filter_count = 12,
|
||||
.biquads = eqp_15_2_1_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static struct tas_drce_t eqp_15_1_0_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = 0.0 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_15_1_0 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x15,
|
||||
.output_id = TAS_OUTPUT_INTERNAL_SPKR,
|
||||
.speaker_id = 0x00,
|
||||
|
||||
.drce = &eqp_15_1_0_drce,
|
||||
|
||||
.filter_count = 12,
|
||||
.biquads = eqp_15_1_0_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static struct tas_drce_t eqp_0f_2_1_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -15.33 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_0f_2_1 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x0f,
|
||||
.output_id = TAS_OUTPUT_EXTERNAL_SPKR,
|
||||
.speaker_id = 0x01,
|
||||
|
||||
.drce = &eqp_0f_2_1_drce,
|
||||
|
||||
.filter_count = 12,
|
||||
.biquads = eqp_0f_2_1_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static struct tas_drce_t eqp_0f_1_0_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -15.33 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_0f_1_0 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x0f,
|
||||
.output_id = TAS_OUTPUT_INTERNAL_SPKR,
|
||||
.speaker_id = 0x00,
|
||||
|
||||
.drce = &eqp_0f_1_0_drce,
|
||||
|
||||
.filter_count = 12,
|
||||
.biquads = eqp_0f_1_0_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static uint tas3001c_master_tab[]={
|
||||
0x0, 0x75, 0x9c, 0xbb,
|
||||
0xdb, 0xfb, 0x11e, 0x143,
|
||||
0x16b, 0x196, 0x1c3, 0x1f5,
|
||||
0x229, 0x263, 0x29f, 0x2e1,
|
||||
0x328, 0x373, 0x3c5, 0x41b,
|
||||
0x478, 0x4dc, 0x547, 0x5b8,
|
||||
0x633, 0x6b5, 0x740, 0x7d5,
|
||||
0x873, 0x91c, 0x9d2, 0xa92,
|
||||
0xb5e, 0xc39, 0xd22, 0xe19,
|
||||
0xf20, 0x1037, 0x1161, 0x129e,
|
||||
0x13ed, 0x1551, 0x16ca, 0x185d,
|
||||
0x1a08, 0x1bcc, 0x1dac, 0x1fa7,
|
||||
0x21c1, 0x23fa, 0x2655, 0x28d6,
|
||||
0x2b7c, 0x2e4a, 0x3141, 0x3464,
|
||||
0x37b4, 0x3b35, 0x3ee9, 0x42d3,
|
||||
0x46f6, 0x4b53, 0x4ff0, 0x54ce,
|
||||
0x59f2, 0x5f5f, 0x6519, 0x6b24,
|
||||
0x7183, 0x783c, 0x7f53, 0x86cc,
|
||||
0x8ead, 0x96fa, 0x9fba, 0xa8f2,
|
||||
0xb2a7, 0xbce1, 0xc7a5, 0xd2fa,
|
||||
0xdee8, 0xeb75, 0xf8aa, 0x1068e,
|
||||
0x1152a, 0x12487, 0x134ad, 0x145a5,
|
||||
0x1577b, 0x16a37, 0x17df5, 0x192bd,
|
||||
0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1,
|
||||
0x20b55, 0x22727, 0x24456, 0x262f2,
|
||||
0x2830b
|
||||
};
|
||||
|
||||
static uint tas3001c_mixer_tab[]={
|
||||
0x0, 0x748, 0x9be, 0xbaf,
|
||||
0xda4, 0xfb1, 0x11de, 0x1431,
|
||||
0x16ad, 0x1959, 0x1c37, 0x1f4b,
|
||||
0x2298, 0x2628, 0x29fb, 0x2e12,
|
||||
0x327d, 0x3734, 0x3c47, 0x41b4,
|
||||
0x4787, 0x4dbe, 0x546d, 0x5b86,
|
||||
0x632e, 0x6b52, 0x7400, 0x7d54,
|
||||
0x873b, 0x91c6, 0x9d1a, 0xa920,
|
||||
0xb5e5, 0xc38c, 0xd21b, 0xe18f,
|
||||
0xf1f5, 0x1036a, 0x1160f, 0x129d6,
|
||||
0x13ed0, 0x1550c, 0x16ca0, 0x185c9,
|
||||
0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75,
|
||||
0x21c0f, 0x23fa3, 0x26552, 0x28d64,
|
||||
0x2b7c9, 0x2e4a2, 0x31411, 0x3463b,
|
||||
0x37b44, 0x3b353, 0x3ee94, 0x42d30,
|
||||
0x46f55, 0x4b533, 0x4fefc, 0x54ce5,
|
||||
0x59f25, 0x5f5f6, 0x65193, 0x6b23c,
|
||||
0x71835, 0x783c3, 0x7f52c, 0x86cc0,
|
||||
0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a,
|
||||
0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0,
|
||||
0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4,
|
||||
0x1152a3, 0x12486a, 0x134ac8, 0x145a55,
|
||||
0x1577ac, 0x16a370, 0x17df51, 0x192bc2,
|
||||
0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04,
|
||||
0x20b542, 0x227268, 0x244564, 0x262f26,
|
||||
0x2830af
|
||||
};
|
||||
|
||||
static uint tas3001c_treble_tab[]={
|
||||
0x96, 0x95, 0x95, 0x94,
|
||||
0x93, 0x92, 0x92, 0x91,
|
||||
0x90, 0x90, 0x8f, 0x8e,
|
||||
0x8d, 0x8d, 0x8c, 0x8b,
|
||||
0x8a, 0x8a, 0x89, 0x88,
|
||||
0x88, 0x87, 0x86, 0x85,
|
||||
0x85, 0x84, 0x83, 0x83,
|
||||
0x82, 0x81, 0x80, 0x80,
|
||||
0x7f, 0x7e, 0x7e, 0x7d,
|
||||
0x7c, 0x7b, 0x7b, 0x7a,
|
||||
0x79, 0x78, 0x78, 0x77,
|
||||
0x76, 0x76, 0x75, 0x74,
|
||||
0x73, 0x73, 0x72, 0x71,
|
||||
0x71, 0x70, 0x6e, 0x6d,
|
||||
0x6d, 0x6c, 0x6b, 0x6a,
|
||||
0x69, 0x68, 0x67, 0x66,
|
||||
0x65, 0x63, 0x62, 0x62,
|
||||
0x60, 0x5f, 0x5d, 0x5c,
|
||||
0x5a, 0x58, 0x56, 0x55,
|
||||
0x53, 0x51, 0x4f, 0x4c,
|
||||
0x4a, 0x48, 0x45, 0x43,
|
||||
0x40, 0x3d, 0x3a, 0x37,
|
||||
0x35, 0x32, 0x2e, 0x2a,
|
||||
0x27, 0x22, 0x1e, 0x1a,
|
||||
0x15, 0x11, 0xc, 0x7,
|
||||
0x1
|
||||
};
|
||||
|
||||
static uint tas3001c_bass_tab[]={
|
||||
0x86, 0x83, 0x81, 0x7f,
|
||||
0x7d, 0x7b, 0x79, 0x78,
|
||||
0x76, 0x75, 0x74, 0x72,
|
||||
0x71, 0x6f, 0x6e, 0x6d,
|
||||
0x6c, 0x6b, 0x69, 0x67,
|
||||
0x65, 0x64, 0x61, 0x60,
|
||||
0x5e, 0x5d, 0x5c, 0x5b,
|
||||
0x5a, 0x59, 0x58, 0x57,
|
||||
0x56, 0x55, 0x55, 0x54,
|
||||
0x53, 0x52, 0x50, 0x4f,
|
||||
0x4d, 0x4c, 0x4b, 0x49,
|
||||
0x47, 0x45, 0x44, 0x42,
|
||||
0x41, 0x3f, 0x3e, 0x3d,
|
||||
0x3c, 0x3b, 0x39, 0x38,
|
||||
0x37, 0x36, 0x35, 0x34,
|
||||
0x33, 0x31, 0x30, 0x2f,
|
||||
0x2e, 0x2c, 0x2b, 0x2b,
|
||||
0x29, 0x28, 0x27, 0x26,
|
||||
0x25, 0x24, 0x22, 0x21,
|
||||
0x20, 0x1e, 0x1c, 0x19,
|
||||
0x18, 0x18, 0x17, 0x16,
|
||||
0x15, 0x14, 0x13, 0x12,
|
||||
0x11, 0x10, 0xf, 0xe,
|
||||
0xd, 0xb, 0xa, 0x9,
|
||||
0x8, 0x6, 0x4, 0x2,
|
||||
0x1
|
||||
};
|
||||
|
||||
struct tas_gain_t tas3001c_gain = {
|
||||
.master = tas3001c_master_tab,
|
||||
.treble = tas3001c_treble_tab,
|
||||
.bass = tas3001c_bass_tab,
|
||||
.mixer = tas3001c_mixer_tab
|
||||
};
|
||||
|
||||
struct tas_eq_pref_t *tas3001c_eq_prefs[]={
|
||||
&eqp_0e_2_1,
|
||||
&eqp_10_1_0,
|
||||
&eqp_15_2_1,
|
||||
&eqp_15_1_0,
|
||||
&eqp_0f_2_1,
|
||||
&eqp_0f_1_0,
|
||||
NULL
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Header file for the i2c/i2s based TA3004 sound chip used
|
||||
* on some Apple hardware. Also known as "tumbler".
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Written by Christopher C. Chimelis <chris@debian.org>
|
||||
*/
|
||||
|
||||
#ifndef _TAS3004_H_
|
||||
#define _TAS3004_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "tas_common.h"
|
||||
#include "tas_eq_prefs.h"
|
||||
|
||||
/*
|
||||
* Macros that correspond to the registers that we write to
|
||||
* when setting the various values.
|
||||
*/
|
||||
|
||||
#define TAS3004_VERSION "0.3"
|
||||
#define TAS3004_DATE "20011214"
|
||||
|
||||
#define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION
|
||||
#define I2C_DRIVERID_TAS3004 (I2C_DRIVERID_TAS_BASE+1)
|
||||
|
||||
extern struct tas_driver_hooks_t tas3004_hooks;
|
||||
extern struct tas_gain_t tas3004_gain;
|
||||
extern struct tas_eq_pref_t *tas3004_eq_prefs[];
|
||||
|
||||
enum tas3004_reg_t {
|
||||
TAS3004_REG_MCR = 0x01,
|
||||
TAS3004_REG_DRC = 0x02,
|
||||
|
||||
TAS3004_REG_VOLUME = 0x04,
|
||||
TAS3004_REG_TREBLE = 0x05,
|
||||
TAS3004_REG_BASS = 0x06,
|
||||
TAS3004_REG_LEFT_MIXER = 0x07,
|
||||
TAS3004_REG_RIGHT_MIXER = 0x08,
|
||||
|
||||
TAS3004_REG_LEFT_BIQUAD0 = 0x0a,
|
||||
TAS3004_REG_LEFT_BIQUAD1 = 0x0b,
|
||||
TAS3004_REG_LEFT_BIQUAD2 = 0x0c,
|
||||
TAS3004_REG_LEFT_BIQUAD3 = 0x0d,
|
||||
TAS3004_REG_LEFT_BIQUAD4 = 0x0e,
|
||||
TAS3004_REG_LEFT_BIQUAD5 = 0x0f,
|
||||
TAS3004_REG_LEFT_BIQUAD6 = 0x10,
|
||||
|
||||
TAS3004_REG_RIGHT_BIQUAD0 = 0x13,
|
||||
TAS3004_REG_RIGHT_BIQUAD1 = 0x14,
|
||||
TAS3004_REG_RIGHT_BIQUAD2 = 0x15,
|
||||
TAS3004_REG_RIGHT_BIQUAD3 = 0x16,
|
||||
TAS3004_REG_RIGHT_BIQUAD4 = 0x17,
|
||||
TAS3004_REG_RIGHT_BIQUAD5 = 0x18,
|
||||
TAS3004_REG_RIGHT_BIQUAD6 = 0x19,
|
||||
|
||||
TAS3004_REG_LEFT_LOUD_BIQUAD = 0x21,
|
||||
TAS3004_REG_RIGHT_LOUD_BIQUAD = 0x22,
|
||||
|
||||
TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN = 0x23,
|
||||
TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24,
|
||||
|
||||
TAS3004_REG_TEST = 0x29,
|
||||
|
||||
TAS3004_REG_ANALOG_CTRL = 0x40,
|
||||
TAS3004_REG_TEST1 = 0x41,
|
||||
TAS3004_REG_TEST2 = 0x42,
|
||||
TAS3004_REG_MCR2 = 0x43,
|
||||
|
||||
TAS3004_REG_MAX = 0x44
|
||||
};
|
||||
|
||||
#endif /* _TAS3004_H_ */
|
@ -1,301 +0,0 @@
|
||||
#include "tas3004.h"
|
||||
#include "tas_eq_prefs.h"
|
||||
|
||||
static struct tas_drce_t eqp_17_1_0_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -19.12 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
|
||||
{ .channel = 0, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
|
||||
{ .channel = 1, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_17_1_0 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x17,
|
||||
.output_id = TAS_OUTPUT_INTERNAL_SPKR,
|
||||
.speaker_id = 0x00,
|
||||
|
||||
.drce = &eqp_17_1_0_drce,
|
||||
|
||||
.filter_count = 14,
|
||||
.biquads = eqp_17_1_0_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static struct tas_drce_t eqp_18_1_0_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -13.14 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
|
||||
{ .channel = 0, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
|
||||
{ .channel = 1, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_18_1_0 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x18,
|
||||
.output_id = TAS_OUTPUT_INTERNAL_SPKR,
|
||||
.speaker_id = 0x00,
|
||||
|
||||
.drce = &eqp_18_1_0_drce,
|
||||
|
||||
.filter_count = 14,
|
||||
.biquads = eqp_18_1_0_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static struct tas_drce_t eqp_1a_1_0_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -10.75 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
|
||||
{ .channel = 0, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
|
||||
{ .channel = 1, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_1a_1_0 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x1a,
|
||||
.output_id = TAS_OUTPUT_INTERNAL_SPKR,
|
||||
.speaker_id = 0x00,
|
||||
|
||||
.drce = &eqp_1a_1_0_drce,
|
||||
|
||||
.filter_count = 14,
|
||||
.biquads = eqp_1a_1_0_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static struct tas_drce_t eqp_1c_1_0_drce={
|
||||
.enable = 1,
|
||||
.above = { .val = 3.0 * (1<<8), .expand = 0 },
|
||||
.below = { .val = 1.0 * (1<<8), .expand = 0 },
|
||||
.threshold = -14.34 * (1<<8),
|
||||
.energy = 2.4 * (1<<12),
|
||||
.attack = 0.013 * (1<<12),
|
||||
.decay = 0.212 * (1<<12),
|
||||
};
|
||||
|
||||
static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={
|
||||
{ .channel = 0, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
|
||||
{ .channel = 0, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
|
||||
{ .channel = 0, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
|
||||
{ .channel = 0, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
|
||||
{ .channel = 0, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
|
||||
{ .channel = 0, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
|
||||
{ .channel = 0, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } },
|
||||
|
||||
{ .channel = 1, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
|
||||
{ .channel = 1, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
|
||||
{ .channel = 1, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
|
||||
{ .channel = 1, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
|
||||
{ .channel = 1, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
|
||||
{ .channel = 1, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
|
||||
{ .channel = 1, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }
|
||||
};
|
||||
|
||||
static struct tas_eq_pref_t eqp_1c_1_0 = {
|
||||
.sample_rate = 44100,
|
||||
.device_id = 0x1c,
|
||||
.output_id = TAS_OUTPUT_INTERNAL_SPKR,
|
||||
.speaker_id = 0x00,
|
||||
|
||||
.drce = &eqp_1c_1_0_drce,
|
||||
|
||||
.filter_count = 14,
|
||||
.biquads = eqp_1c_1_0_biquads
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
static uint tas3004_master_tab[]={
|
||||
0x0, 0x75, 0x9c, 0xbb,
|
||||
0xdb, 0xfb, 0x11e, 0x143,
|
||||
0x16b, 0x196, 0x1c3, 0x1f5,
|
||||
0x229, 0x263, 0x29f, 0x2e1,
|
||||
0x328, 0x373, 0x3c5, 0x41b,
|
||||
0x478, 0x4dc, 0x547, 0x5b8,
|
||||
0x633, 0x6b5, 0x740, 0x7d5,
|
||||
0x873, 0x91c, 0x9d2, 0xa92,
|
||||
0xb5e, 0xc39, 0xd22, 0xe19,
|
||||
0xf20, 0x1037, 0x1161, 0x129e,
|
||||
0x13ed, 0x1551, 0x16ca, 0x185d,
|
||||
0x1a08, 0x1bcc, 0x1dac, 0x1fa7,
|
||||
0x21c1, 0x23fa, 0x2655, 0x28d6,
|
||||
0x2b7c, 0x2e4a, 0x3141, 0x3464,
|
||||
0x37b4, 0x3b35, 0x3ee9, 0x42d3,
|
||||
0x46f6, 0x4b53, 0x4ff0, 0x54ce,
|
||||
0x59f2, 0x5f5f, 0x6519, 0x6b24,
|
||||
0x7183, 0x783c, 0x7f53, 0x86cc,
|
||||
0x8ead, 0x96fa, 0x9fba, 0xa8f2,
|
||||
0xb2a7, 0xbce1, 0xc7a5, 0xd2fa,
|
||||
0xdee8, 0xeb75, 0xf8aa, 0x1068e,
|
||||
0x1152a, 0x12487, 0x134ad, 0x145a5,
|
||||
0x1577b, 0x16a37, 0x17df5, 0x192bd,
|
||||
0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1,
|
||||
0x20b55, 0x22727, 0x24456, 0x262f2,
|
||||
0x2830b
|
||||
};
|
||||
|
||||
static uint tas3004_mixer_tab[]={
|
||||
0x0, 0x748, 0x9be, 0xbaf,
|
||||
0xda4, 0xfb1, 0x11de, 0x1431,
|
||||
0x16ad, 0x1959, 0x1c37, 0x1f4b,
|
||||
0x2298, 0x2628, 0x29fb, 0x2e12,
|
||||
0x327d, 0x3734, 0x3c47, 0x41b4,
|
||||
0x4787, 0x4dbe, 0x546d, 0x5b86,
|
||||
0x632e, 0x6b52, 0x7400, 0x7d54,
|
||||
0x873b, 0x91c6, 0x9d1a, 0xa920,
|
||||
0xb5e5, 0xc38c, 0xd21b, 0xe18f,
|
||||
0xf1f5, 0x1036a, 0x1160f, 0x129d6,
|
||||
0x13ed0, 0x1550c, 0x16ca0, 0x185c9,
|
||||
0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75,
|
||||
0x21c0f, 0x23fa3, 0x26552, 0x28d64,
|
||||
0x2b7c9, 0x2e4a2, 0x31411, 0x3463b,
|
||||
0x37b44, 0x3b353, 0x3ee94, 0x42d30,
|
||||
0x46f55, 0x4b533, 0x4fefc, 0x54ce5,
|
||||
0x59f25, 0x5f5f6, 0x65193, 0x6b23c,
|
||||
0x71835, 0x783c3, 0x7f52c, 0x86cc0,
|
||||
0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a,
|
||||
0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0,
|
||||
0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4,
|
||||
0x1152a3, 0x12486a, 0x134ac8, 0x145a55,
|
||||
0x1577ac, 0x16a370, 0x17df51, 0x192bc2,
|
||||
0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04,
|
||||
0x20b542, 0x227268, 0x244564, 0x262f26,
|
||||
0x2830af
|
||||
};
|
||||
|
||||
static uint tas3004_treble_tab[]={
|
||||
0x96, 0x95, 0x95, 0x94,
|
||||
0x93, 0x92, 0x92, 0x91,
|
||||
0x90, 0x90, 0x8f, 0x8e,
|
||||
0x8d, 0x8d, 0x8c, 0x8b,
|
||||
0x8a, 0x8a, 0x89, 0x88,
|
||||
0x88, 0x87, 0x86, 0x85,
|
||||
0x85, 0x84, 0x83, 0x83,
|
||||
0x82, 0x81, 0x80, 0x80,
|
||||
0x7f, 0x7e, 0x7e, 0x7d,
|
||||
0x7c, 0x7b, 0x7b, 0x7a,
|
||||
0x79, 0x78, 0x78, 0x77,
|
||||
0x76, 0x76, 0x75, 0x74,
|
||||
0x73, 0x73, 0x72, 0x71,
|
||||
0x71, 0x68, 0x45, 0x5b,
|
||||
0x6d, 0x6c, 0x6b, 0x6a,
|
||||
0x69, 0x68, 0x67, 0x66,
|
||||
0x65, 0x63, 0x62, 0x62,
|
||||
0x60, 0x5e, 0x5c, 0x5b,
|
||||
0x59, 0x57, 0x55, 0x53,
|
||||
0x52, 0x4f, 0x4d, 0x4a,
|
||||
0x48, 0x46, 0x43, 0x40,
|
||||
0x3d, 0x3a, 0x36, 0x33,
|
||||
0x2f, 0x2c, 0x27, 0x23,
|
||||
0x1f, 0x1a, 0x15, 0xf,
|
||||
0x8, 0x5, 0x2, 0x1,
|
||||
0x1
|
||||
};
|
||||
|
||||
static uint tas3004_bass_tab[]={
|
||||
0x96, 0x95, 0x95, 0x94,
|
||||
0x93, 0x92, 0x92, 0x91,
|
||||
0x90, 0x90, 0x8f, 0x8e,
|
||||
0x8d, 0x8d, 0x8c, 0x8b,
|
||||
0x8a, 0x8a, 0x89, 0x88,
|
||||
0x88, 0x87, 0x86, 0x85,
|
||||
0x85, 0x84, 0x83, 0x83,
|
||||
0x82, 0x81, 0x80, 0x80,
|
||||
0x7f, 0x7e, 0x7e, 0x7d,
|
||||
0x7c, 0x7b, 0x7b, 0x7a,
|
||||
0x79, 0x78, 0x78, 0x77,
|
||||
0x76, 0x76, 0x75, 0x74,
|
||||
0x73, 0x73, 0x72, 0x71,
|
||||
0x70, 0x6f, 0x6e, 0x6d,
|
||||
0x6c, 0x6b, 0x6a, 0x6a,
|
||||
0x69, 0x67, 0x66, 0x66,
|
||||
0x65, 0x63, 0x62, 0x62,
|
||||
0x61, 0x60, 0x5e, 0x5d,
|
||||
0x5b, 0x59, 0x57, 0x55,
|
||||
0x53, 0x51, 0x4f, 0x4c,
|
||||
0x4a, 0x48, 0x46, 0x44,
|
||||
0x41, 0x3e, 0x3b, 0x38,
|
||||
0x36, 0x33, 0x2f, 0x2b,
|
||||
0x28, 0x24, 0x20, 0x1c,
|
||||
0x17, 0x12, 0xd, 0x7,
|
||||
0x1
|
||||
};
|
||||
|
||||
struct tas_gain_t tas3004_gain={
|
||||
.master = tas3004_master_tab,
|
||||
.treble = tas3004_treble_tab,
|
||||
.bass = tas3004_bass_tab,
|
||||
.mixer = tas3004_mixer_tab
|
||||
};
|
||||
|
||||
struct tas_eq_pref_t *tas3004_eq_prefs[]={
|
||||
&eqp_17_1_0,
|
||||
&eqp_18_1_0,
|
||||
&eqp_1a_1_0,
|
||||
&eqp_1c_1_0,
|
||||
NULL
|
||||
};
|
@ -1,214 +0,0 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.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 <linux/soundcard.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include "tas_common.h"
|
||||
|
||||
#define CALL0(proc) \
|
||||
do { \
|
||||
struct tas_data_t *self; \
|
||||
if (!tas_client || driver_hooks == NULL) \
|
||||
return -1; \
|
||||
self = dev_get_drvdata(&tas_client->dev); \
|
||||
if (driver_hooks->proc) \
|
||||
return driver_hooks->proc(self); \
|
||||
else \
|
||||
return -EINVAL; \
|
||||
} while (0)
|
||||
|
||||
#define CALL(proc,arg...) \
|
||||
do { \
|
||||
struct tas_data_t *self; \
|
||||
if (!tas_client || driver_hooks == NULL) \
|
||||
return -1; \
|
||||
self = dev_get_drvdata(&tas_client->dev); \
|
||||
if (driver_hooks->proc) \
|
||||
return driver_hooks->proc(self, ## arg); \
|
||||
else \
|
||||
return -EINVAL; \
|
||||
} while (0)
|
||||
|
||||
|
||||
static u8 tas_i2c_address = 0x34;
|
||||
static struct i2c_client *tas_client;
|
||||
|
||||
static int tas_attach_adapter(struct i2c_adapter *);
|
||||
static int tas_detach_client(struct i2c_client *);
|
||||
|
||||
struct i2c_driver tas_driver = {
|
||||
.driver = {
|
||||
.name = "tas",
|
||||
},
|
||||
.attach_adapter = tas_attach_adapter,
|
||||
.detach_client = tas_detach_client,
|
||||
};
|
||||
|
||||
struct tas_driver_hooks_t *driver_hooks;
|
||||
|
||||
int
|
||||
tas_register_driver(struct tas_driver_hooks_t *hooks)
|
||||
{
|
||||
driver_hooks = hooks;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tas_get_mixer_level(int mixer, uint *level)
|
||||
{
|
||||
CALL(get_mixer_level,mixer,level);
|
||||
}
|
||||
|
||||
int
|
||||
tas_set_mixer_level(int mixer,uint level)
|
||||
{
|
||||
CALL(set_mixer_level,mixer,level);
|
||||
}
|
||||
|
||||
int
|
||||
tas_enter_sleep(void)
|
||||
{
|
||||
CALL0(enter_sleep);
|
||||
}
|
||||
|
||||
int
|
||||
tas_leave_sleep(void)
|
||||
{
|
||||
CALL0(leave_sleep);
|
||||
}
|
||||
|
||||
int
|
||||
tas_supported_mixers(void)
|
||||
{
|
||||
CALL0(supported_mixers);
|
||||
}
|
||||
|
||||
int
|
||||
tas_mixer_is_stereo(int mixer)
|
||||
{
|
||||
CALL(mixer_is_stereo,mixer);
|
||||
}
|
||||
|
||||
int
|
||||
tas_stereo_mixers(void)
|
||||
{
|
||||
CALL0(stereo_mixers);
|
||||
}
|
||||
|
||||
int
|
||||
tas_output_device_change(int device_id,int layout_id,int speaker_id)
|
||||
{
|
||||
CALL(output_device_change,device_id,layout_id,speaker_id);
|
||||
}
|
||||
|
||||
int
|
||||
tas_device_ioctl(u_int cmd, u_long arg)
|
||||
{
|
||||
CALL(device_ioctl,cmd,arg);
|
||||
}
|
||||
|
||||
int
|
||||
tas_post_init(void)
|
||||
{
|
||||
CALL0(post_init);
|
||||
}
|
||||
|
||||
static int
|
||||
tas_detect_client(struct i2c_adapter *adapter, int address)
|
||||
{
|
||||
static const char *client_name = "tas Digital Equalizer";
|
||||
struct i2c_client *new_client;
|
||||
int rc = -ENODEV;
|
||||
|
||||
if (!driver_hooks) {
|
||||
printk(KERN_ERR "tas_detect_client called with no hooks !\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
|
||||
if (!new_client)
|
||||
return -ENOMEM;
|
||||
|
||||
new_client->addr = address;
|
||||
new_client->adapter = adapter;
|
||||
new_client->driver = &tas_driver;
|
||||
strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
|
||||
|
||||
if (driver_hooks->init(new_client))
|
||||
goto bail;
|
||||
|
||||
/* Tell the i2c layer a new client has arrived */
|
||||
if (i2c_attach_client(new_client)) {
|
||||
driver_hooks->uninit(dev_get_drvdata(&new_client->dev));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
tas_client = new_client;
|
||||
return 0;
|
||||
bail:
|
||||
tas_client = NULL;
|
||||
kfree(new_client);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
tas_attach_adapter(struct i2c_adapter *adapter)
|
||||
{
|
||||
if (!strncmp(adapter->name, "mac-io", 6))
|
||||
return tas_detect_client(adapter, tas_i2c_address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tas_detach_client(struct i2c_client *client)
|
||||
{
|
||||
if (client == tas_client) {
|
||||
driver_hooks->uninit(dev_get_drvdata(&client->dev));
|
||||
|
||||
i2c_detach_client(client);
|
||||
kfree(client);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
tas_cleanup(void)
|
||||
{
|
||||
i2c_del_driver(&tas_driver);
|
||||
}
|
||||
|
||||
int __init
|
||||
tas_init(int driver_id, const char *driver_name)
|
||||
{
|
||||
const u32* paddr;
|
||||
struct device_node *tas_node;
|
||||
|
||||
printk(KERN_INFO "tas driver [%s])\n", driver_name);
|
||||
|
||||
#ifndef CONFIG_I2C_POWERMAC
|
||||
request_module("i2c-powermac");
|
||||
#endif
|
||||
tas_node = of_find_node_by_name("deq");
|
||||
if (tas_node == NULL)
|
||||
return -ENODEV;
|
||||
paddr = of_get_property(tas_node, "i2c-address", NULL);
|
||||
if (paddr) {
|
||||
tas_i2c_address = (*paddr) >> 1;
|
||||
printk(KERN_INFO "using i2c address: 0x%x from device-tree\n",
|
||||
tas_i2c_address);
|
||||
} else
|
||||
printk(KERN_INFO "using i2c address: 0x%x (default)\n",
|
||||
tas_i2c_address);
|
||||
of_node_put(tas_node);
|
||||
|
||||
return i2c_add_driver(&tas_driver);
|
||||
}
|
@ -1,284 +0,0 @@
|
||||
#ifndef _TAS_COMMON_H_
|
||||
#define _TAS_COMMON_H_
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/soundcard.h>
|
||||
#include <asm/string.h>
|
||||
|
||||
#define I2C_DRIVERID_TAS_BASE (0xFEBA)
|
||||
|
||||
#define SET_4_20(shadow, offset, val) \
|
||||
do { \
|
||||
(shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
|
||||
(shadow)[(offset)+1] = ((val) >> 8) & 0xff; \
|
||||
(shadow)[(offset)+2] = ((val) >> 0) & 0xff; \
|
||||
} while (0)
|
||||
|
||||
#define GET_4_20(shadow, offset) \
|
||||
(((u_int)((shadow)[(offset)+0]) << 16) | \
|
||||
((u_int)((shadow)[(offset)+1]) << 8) | \
|
||||
((u_int)((shadow)[(offset)+2]) << 0))
|
||||
|
||||
|
||||
#define TAS_BIQUAD_FAST_LOAD 0x01
|
||||
|
||||
#define TAS_DRCE_ENABLE 0x01
|
||||
#define TAS_DRCE_ABOVE_RATIO 0x02
|
||||
#define TAS_DRCE_BELOW_RATIO 0x04
|
||||
#define TAS_DRCE_THRESHOLD 0x08
|
||||
#define TAS_DRCE_ENERGY 0x10
|
||||
#define TAS_DRCE_ATTACK 0x20
|
||||
#define TAS_DRCE_DECAY 0x40
|
||||
|
||||
#define TAS_DRCE_ALL 0x7f
|
||||
|
||||
|
||||
#define TAS_OUTPUT_HEADPHONES 0x00
|
||||
#define TAS_OUTPUT_INTERNAL_SPKR 0x01
|
||||
#define TAS_OUTPUT_EXTERNAL_SPKR 0x02
|
||||
|
||||
|
||||
union tas_biquad_t {
|
||||
struct {
|
||||
int b0,b1,b2,a1,a2;
|
||||
} coeff;
|
||||
int buf[5];
|
||||
};
|
||||
|
||||
struct tas_biquad_ctrl_t {
|
||||
u_int channel:4;
|
||||
u_int filter:4;
|
||||
|
||||
union tas_biquad_t data;
|
||||
};
|
||||
|
||||
struct tas_biquad_ctrl_list_t {
|
||||
int flags;
|
||||
int filter_count;
|
||||
struct tas_biquad_ctrl_t biquads[0];
|
||||
};
|
||||
|
||||
struct tas_ratio_t {
|
||||
unsigned short val; /* 8.8 */
|
||||
unsigned short expand; /* 0 = compress, !0 = expand. */
|
||||
};
|
||||
|
||||
struct tas_drce_t {
|
||||
unsigned short enable;
|
||||
struct tas_ratio_t above;
|
||||
struct tas_ratio_t below;
|
||||
short threshold; /* dB, 8.8 signed */
|
||||
unsigned short energy; /* seconds, 4.12 unsigned */
|
||||
unsigned short attack; /* seconds, 4.12 unsigned */
|
||||
unsigned short decay; /* seconds, 4.12 unsigned */
|
||||
};
|
||||
|
||||
struct tas_drce_ctrl_t {
|
||||
uint flags;
|
||||
|
||||
struct tas_drce_t data;
|
||||
};
|
||||
|
||||
struct tas_gain_t
|
||||
{
|
||||
unsigned int *master;
|
||||
unsigned int *treble;
|
||||
unsigned int *bass;
|
||||
unsigned int *mixer;
|
||||
};
|
||||
|
||||
typedef char tas_shadow_t[0x45];
|
||||
|
||||
struct tas_data_t
|
||||
{
|
||||
struct i2c_client *client;
|
||||
tas_shadow_t *shadow;
|
||||
uint mixer[SOUND_MIXER_NRDEVICES];
|
||||
};
|
||||
|
||||
typedef int (*tas_hook_init_t)(struct i2c_client *);
|
||||
typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
|
||||
typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
|
||||
|
||||
typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
|
||||
typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
|
||||
|
||||
typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
|
||||
typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
|
||||
|
||||
typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
|
||||
typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
|
||||
typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
|
||||
|
||||
typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
|
||||
typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
|
||||
|
||||
struct tas_driver_hooks_t {
|
||||
/*
|
||||
* All hardware initialisation must be performed in
|
||||
* post_init(), as tas_dmasound_init() does a hardware reset.
|
||||
*
|
||||
* init() is called before tas_dmasound_init() so that
|
||||
* ouput_device_change() is always called after i2c driver
|
||||
* initialisation. The implication is that
|
||||
* output_device_change() must cope with the fact that it
|
||||
* may be called before post_init().
|
||||
*/
|
||||
|
||||
tas_hook_init_t init;
|
||||
tas_hook_post_init_t post_init;
|
||||
tas_hook_uninit_t uninit;
|
||||
|
||||
tas_hook_get_mixer_level_t get_mixer_level;
|
||||
tas_hook_set_mixer_level_t set_mixer_level;
|
||||
|
||||
tas_hook_enter_sleep_t enter_sleep;
|
||||
tas_hook_leave_sleep_t leave_sleep;
|
||||
|
||||
tas_hook_supported_mixers_t supported_mixers;
|
||||
tas_hook_mixer_is_stereo_t mixer_is_stereo;
|
||||
tas_hook_stereo_mixers_t stereo_mixers;
|
||||
|
||||
tas_hook_output_device_change_t output_device_change;
|
||||
tas_hook_device_ioctl_t device_ioctl;
|
||||
};
|
||||
|
||||
enum tas_write_mode_t {
|
||||
WRITE_HW = 0x01,
|
||||
WRITE_SHADOW = 0x02,
|
||||
WRITE_NORMAL = 0x03,
|
||||
FORCE_WRITE = 0x04
|
||||
};
|
||||
|
||||
static inline uint
|
||||
tas_mono_to_stereo(uint mono)
|
||||
{
|
||||
mono &=0xff;
|
||||
return mono | (mono<<8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Todo: make these functions a bit more efficient !
|
||||
*/
|
||||
static inline int
|
||||
tas_write_register( struct tas_data_t *self,
|
||||
uint reg_num,
|
||||
uint reg_width,
|
||||
char *data,
|
||||
uint write_mode)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (reg_width==0 || data==NULL || self==NULL)
|
||||
return -EINVAL;
|
||||
if (!(write_mode & FORCE_WRITE) &&
|
||||
!memcmp(data,self->shadow[reg_num],reg_width))
|
||||
return 0;
|
||||
|
||||
if (write_mode & WRITE_SHADOW)
|
||||
memcpy(self->shadow[reg_num],data,reg_width);
|
||||
if (write_mode & WRITE_HW) {
|
||||
rc=i2c_smbus_write_i2c_block_data(self->client,
|
||||
reg_num,
|
||||
reg_width,
|
||||
data);
|
||||
if (rc < 0) {
|
||||
printk("tas: I2C block write failed \n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tas_sync_register( struct tas_data_t *self,
|
||||
uint reg_num,
|
||||
uint reg_width)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (reg_width==0 || self==NULL)
|
||||
return -EINVAL;
|
||||
rc=i2c_smbus_write_i2c_block_data(self->client,
|
||||
reg_num,
|
||||
reg_width,
|
||||
self->shadow[reg_num]);
|
||||
if (rc < 0) {
|
||||
printk("tas: I2C block write failed \n");
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tas_write_byte_register( struct tas_data_t *self,
|
||||
uint reg_num,
|
||||
char data,
|
||||
uint write_mode)
|
||||
{
|
||||
if (self==NULL)
|
||||
return -1;
|
||||
if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
|
||||
return 0;
|
||||
if (write_mode & WRITE_SHADOW)
|
||||
self->shadow[reg_num][0]=data;
|
||||
if (write_mode & WRITE_HW) {
|
||||
if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
|
||||
printk("tas: I2C byte write failed \n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tas_sync_byte_register( struct tas_data_t *self,
|
||||
uint reg_num,
|
||||
uint reg_width)
|
||||
{
|
||||
if (reg_width==0 || self==NULL)
|
||||
return -1;
|
||||
if (i2c_smbus_write_byte_data(
|
||||
self->client, reg_num, self->shadow[reg_num][0]) < 0) {
|
||||
printk("tas: I2C byte write failed \n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tas_read_register( struct tas_data_t *self,
|
||||
uint reg_num,
|
||||
uint reg_width,
|
||||
char *data)
|
||||
{
|
||||
if (reg_width==0 || data==NULL || self==NULL)
|
||||
return -1;
|
||||
memcpy(data,self->shadow[reg_num],reg_width);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
|
||||
|
||||
extern int tas_get_mixer_level(int mixer,uint *level);
|
||||
extern int tas_set_mixer_level(int mixer,uint level);
|
||||
extern int tas_enter_sleep(void);
|
||||
extern int tas_leave_sleep(void);
|
||||
extern int tas_supported_mixers(void);
|
||||
extern int tas_mixer_is_stereo(int mixer);
|
||||
extern int tas_stereo_mixers(void);
|
||||
extern int tas_output_device_change(int,int,int);
|
||||
extern int tas_device_ioctl(u_int, u_long);
|
||||
|
||||
extern void tas_cleanup(void);
|
||||
extern int tas_init(int driver_id,const char *driver_name);
|
||||
extern int tas_post_init(void);
|
||||
|
||||
#endif /* _TAS_COMMON_H_ */
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: t
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
@ -1,24 +0,0 @@
|
||||
#ifndef _TAS_EQ_PREFS_H_
|
||||
#define _TAS_EQ_PREFS_H_
|
||||
|
||||
struct tas_eq_pref_t {
|
||||
u_int sample_rate;
|
||||
u_int device_id;
|
||||
u_int output_id;
|
||||
u_int speaker_id;
|
||||
|
||||
struct tas_drce_t *drce;
|
||||
|
||||
u_int filter_count;
|
||||
struct tas_biquad_ctrl_t *biquads;
|
||||
};
|
||||
|
||||
#endif /* _TAS_EQ_PREFS_H_ */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: t
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
@ -1,23 +0,0 @@
|
||||
#ifndef _TAS_IOCTL_H_
|
||||
#define _TAS_IOCTL_H_
|
||||
|
||||
#include <linux/soundcard.h>
|
||||
|
||||
|
||||
#define TAS_READ_EQ _SIOR('t',0,struct tas_biquad_ctrl_t)
|
||||
#define TAS_WRITE_EQ _SIOW('t',0,struct tas_biquad_ctrl_t)
|
||||
|
||||
#define TAS_READ_EQ_LIST _SIOR('t',1,struct tas_biquad_ctrl_t)
|
||||
#define TAS_WRITE_EQ_LIST _SIOW('t',1,struct tas_biquad_ctrl_t)
|
||||
|
||||
#define TAS_READ_EQ_FILTER_COUNT _SIOR('t',2,int)
|
||||
#define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int)
|
||||
|
||||
#define TAS_READ_DRCE _SIOR('t',4,struct tas_drce_ctrl_t)
|
||||
#define TAS_WRITE_DRCE _SIOW('t',4,struct tas_drce_ctrl_t)
|
||||
|
||||
#define TAS_READ_DRCE_CAPS _SIOR('t',5,int)
|
||||
#define TAS_READ_DRCE_MIN _SIOR('t',6,int)
|
||||
#define TAS_READ_DRCE_MAX _SIOR('t',7,int)
|
||||
|
||||
#endif
|
@ -1,898 +0,0 @@
|
||||
/*
|
||||
* linux/sound/oss/dmasound/trans_16.c
|
||||
*
|
||||
* 16 bit translation routines. Only used by Power mac at present.
|
||||
*
|
||||
* See linux/sound/oss/dmasound/dmasound_core.c for copyright and
|
||||
* history prior to 08/02/2001.
|
||||
*
|
||||
* 08/02/2001 Iain Sandoe
|
||||
* split from dmasound_awacs.c
|
||||
* 11/29/2003 Renzo Davoli (King Enzo)
|
||||
* - input resampling (for soft rate < hard rate)
|
||||
* - software line in gain control
|
||||
*/
|
||||
|
||||
#include <linux/soundcard.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include "dmasound.h"
|
||||
|
||||
extern int expand_bal; /* Balance factor for expanding (not volume!) */
|
||||
static short dmasound_alaw2dma16[] ;
|
||||
static short dmasound_ulaw2dma16[] ;
|
||||
|
||||
static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
|
||||
static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
|
||||
static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft);
|
||||
|
||||
/*** Translations ************************************************************/
|
||||
|
||||
static int expand_data; /* Data for expanding */
|
||||
|
||||
static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
short *table = dmasound.soft.format == AFMT_MU_LAW
|
||||
? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
|
||||
ssize_t count, used;
|
||||
short *p = (short *) &frame[*frameUsed];
|
||||
int val, stereo = dmasound.soft.stereo;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
while (count > 0) {
|
||||
u_char data;
|
||||
if (get_user(data, userPtr++))
|
||||
return -EFAULT;
|
||||
val = table[data];
|
||||
*p++ = val;
|
||||
if (stereo) {
|
||||
if (get_user(data, userPtr++))
|
||||
return -EFAULT;
|
||||
val = table[data];
|
||||
}
|
||||
*p++ = val;
|
||||
count--;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 2: used;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
ssize_t count, used;
|
||||
short *p = (short *) &frame[*frameUsed];
|
||||
int val, stereo = dmasound.soft.stereo;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
while (count > 0) {
|
||||
u_char data;
|
||||
if (get_user(data, userPtr++))
|
||||
return -EFAULT;
|
||||
val = data << 8;
|
||||
*p++ = val;
|
||||
if (stereo) {
|
||||
if (get_user(data, userPtr++))
|
||||
return -EFAULT;
|
||||
val = data << 8;
|
||||
}
|
||||
*p++ = val;
|
||||
count--;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 2: used;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
ssize_t count, used;
|
||||
short *p = (short *) &frame[*frameUsed];
|
||||
int val, stereo = dmasound.soft.stereo;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
while (count > 0) {
|
||||
u_char data;
|
||||
if (get_user(data, userPtr++))
|
||||
return -EFAULT;
|
||||
val = (data ^ 0x80) << 8;
|
||||
*p++ = val;
|
||||
if (stereo) {
|
||||
if (get_user(data, userPtr++))
|
||||
return -EFAULT;
|
||||
val = (data ^ 0x80) << 8;
|
||||
}
|
||||
*p++ = val;
|
||||
count--;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 2: used;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
ssize_t count, used;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
short *fp = (short *) &frame[*frameUsed];
|
||||
|
||||
frameLeft >>= 2;
|
||||
userCount >>= (stereo? 2: 1);
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
if (!stereo) {
|
||||
short __user *up = (short __user *) userPtr;
|
||||
while (count > 0) {
|
||||
short data;
|
||||
if (get_user(data, up++))
|
||||
return -EFAULT;
|
||||
*fp++ = data;
|
||||
*fp++ = data;
|
||||
count--;
|
||||
}
|
||||
} else {
|
||||
if (copy_from_user(fp, userPtr, count * 4))
|
||||
return -EFAULT;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 4: used * 2;
|
||||
}
|
||||
|
||||
static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
ssize_t count, used;
|
||||
int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
|
||||
int stereo = dmasound.soft.stereo;
|
||||
short *fp = (short *) &frame[*frameUsed];
|
||||
short __user *up = (short __user *) userPtr;
|
||||
|
||||
frameLeft >>= 2;
|
||||
userCount >>= (stereo? 2: 1);
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
while (count > 0) {
|
||||
short data;
|
||||
if (get_user(data, up++))
|
||||
return -EFAULT;
|
||||
data ^= mask;
|
||||
*fp++ = data;
|
||||
if (stereo) {
|
||||
if (get_user(data, up++))
|
||||
return -EFAULT;
|
||||
data ^= mask;
|
||||
}
|
||||
*fp++ = data;
|
||||
count--;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 4: used * 2;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
unsigned short *table = (unsigned short *)
|
||||
(dmasound.soft.format == AFMT_MU_LAW
|
||||
? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
|
||||
unsigned int data = expand_data;
|
||||
unsigned int *p = (unsigned int *) &frame[*frameUsed];
|
||||
int bal = expand_bal;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int utotal, ftotal;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
u_char c;
|
||||
if (bal < 0) {
|
||||
if (userCount == 0)
|
||||
break;
|
||||
if (get_user(c, userPtr++))
|
||||
return -EFAULT;
|
||||
data = table[c];
|
||||
if (stereo) {
|
||||
if (get_user(c, userPtr++))
|
||||
return -EFAULT;
|
||||
data = (data << 16) + table[c];
|
||||
} else
|
||||
data = (data << 16) + data;
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
*p++ = data;
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_bal = bal;
|
||||
expand_data = data;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 2: utotal;
|
||||
}
|
||||
|
||||
static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
unsigned int *p = (unsigned int *) &frame[*frameUsed];
|
||||
unsigned int data = expand_data;
|
||||
int bal = expand_bal;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
int utotal, ftotal;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
u_char c;
|
||||
if (bal < 0) {
|
||||
if (userCount == 0)
|
||||
break;
|
||||
if (get_user(c, userPtr++))
|
||||
return -EFAULT;
|
||||
data = c << 8;
|
||||
if (stereo) {
|
||||
if (get_user(c, userPtr++))
|
||||
return -EFAULT;
|
||||
data = (data << 16) + (c << 8);
|
||||
} else
|
||||
data = (data << 16) + data;
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
*p++ = data;
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_bal = bal;
|
||||
expand_data = data;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 2: utotal;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
unsigned int *p = (unsigned int *) &frame[*frameUsed];
|
||||
unsigned int data = expand_data;
|
||||
int bal = expand_bal;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
int utotal, ftotal;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
u_char c;
|
||||
if (bal < 0) {
|
||||
if (userCount == 0)
|
||||
break;
|
||||
if (get_user(c, userPtr++))
|
||||
return -EFAULT;
|
||||
data = (c ^ 0x80) << 8;
|
||||
if (stereo) {
|
||||
if (get_user(c, userPtr++))
|
||||
return -EFAULT;
|
||||
data = (data << 16) + ((c ^ 0x80) << 8);
|
||||
} else
|
||||
data = (data << 16) + data;
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
*p++ = data;
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_bal = bal;
|
||||
expand_data = data;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 2: utotal;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
unsigned int *p = (unsigned int *) &frame[*frameUsed];
|
||||
unsigned int data = expand_data;
|
||||
unsigned short __user *up = (unsigned short __user *) userPtr;
|
||||
int bal = expand_bal;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
int utotal, ftotal;
|
||||
|
||||
frameLeft >>= 2;
|
||||
userCount >>= (stereo? 2: 1);
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
unsigned short c;
|
||||
if (bal < 0) {
|
||||
if (userCount == 0)
|
||||
break;
|
||||
if (get_user(data, up++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
if (get_user(c, up++))
|
||||
return -EFAULT;
|
||||
data = (data << 16) + c;
|
||||
} else
|
||||
data = (data << 16) + data;
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
*p++ = data;
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_bal = bal;
|
||||
expand_data = data;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 4: utotal * 2;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
|
||||
unsigned int *p = (unsigned int *) &frame[*frameUsed];
|
||||
unsigned int data = expand_data;
|
||||
unsigned short __user *up = (unsigned short __user *) userPtr;
|
||||
int bal = expand_bal;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
int utotal, ftotal;
|
||||
|
||||
frameLeft >>= 2;
|
||||
userCount >>= (stereo? 2: 1);
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
unsigned short c;
|
||||
if (bal < 0) {
|
||||
if (userCount == 0)
|
||||
break;
|
||||
if (get_user(data, up++))
|
||||
return -EFAULT;
|
||||
data ^= mask;
|
||||
if (stereo) {
|
||||
if (get_user(c, up++))
|
||||
return -EFAULT;
|
||||
data = (data << 16) + (c ^ mask);
|
||||
} else
|
||||
data = (data << 16) + data;
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
*p++ = data;
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_bal = bal;
|
||||
expand_data = data;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 4: utotal * 2;
|
||||
}
|
||||
|
||||
/* data in routines... */
|
||||
|
||||
static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
ssize_t count, used;
|
||||
short *p = (short *) &frame[*frameUsed];
|
||||
int val, stereo = dmasound.soft.stereo;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
while (count > 0) {
|
||||
u_char data;
|
||||
|
||||
val = *p++;
|
||||
val = (val * software_input_volume) >> 7;
|
||||
data = val >> 8;
|
||||
if (put_user(data, (u_char __user *)userPtr++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
val = *p;
|
||||
val = (val * software_input_volume) >> 7;
|
||||
data = val >> 8;
|
||||
if (put_user(data, (u_char __user *)userPtr++))
|
||||
return -EFAULT;
|
||||
}
|
||||
p++;
|
||||
count--;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 2: used;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
ssize_t count, used;
|
||||
short *p = (short *) &frame[*frameUsed];
|
||||
int val, stereo = dmasound.soft.stereo;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
while (count > 0) {
|
||||
u_char data;
|
||||
|
||||
val = *p++;
|
||||
val = (val * software_input_volume) >> 7;
|
||||
data = (val >> 8) ^ 0x80;
|
||||
if (put_user(data, (u_char __user *)userPtr++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
val = *p;
|
||||
val = (val * software_input_volume) >> 7;
|
||||
data = (val >> 8) ^ 0x80;
|
||||
if (put_user(data, (u_char __user *)userPtr++))
|
||||
return -EFAULT;
|
||||
}
|
||||
p++;
|
||||
count--;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 2: used;
|
||||
}
|
||||
|
||||
static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
ssize_t count, used;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
short *fp = (short *) &frame[*frameUsed];
|
||||
short __user *up = (short __user *) userPtr;
|
||||
|
||||
frameLeft >>= 2;
|
||||
userCount >>= (stereo? 2: 1);
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
while (count > 0) {
|
||||
short data;
|
||||
|
||||
data = *fp++;
|
||||
data = (data * software_input_volume) >> 7;
|
||||
if (put_user(data, up++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
data = *fp;
|
||||
data = (data * software_input_volume) >> 7;
|
||||
if (put_user(data, up++))
|
||||
return -EFAULT;
|
||||
}
|
||||
fp++;
|
||||
count--;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 4: used * 2;
|
||||
}
|
||||
|
||||
static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
ssize_t count, used;
|
||||
int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
|
||||
int stereo = dmasound.soft.stereo;
|
||||
short *fp = (short *) &frame[*frameUsed];
|
||||
short __user *up = (short __user *) userPtr;
|
||||
|
||||
frameLeft >>= 2;
|
||||
userCount >>= (stereo? 2: 1);
|
||||
used = count = min_t(unsigned long, userCount, frameLeft);
|
||||
while (count > 0) {
|
||||
int data;
|
||||
|
||||
data = *fp++;
|
||||
data = (data * software_input_volume) >> 7;
|
||||
data ^= mask;
|
||||
if (put_user(data, up++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
data = *fp;
|
||||
data = (data * software_input_volume) >> 7;
|
||||
data ^= mask;
|
||||
if (put_user(data, up++))
|
||||
return -EFAULT;
|
||||
}
|
||||
fp++;
|
||||
count--;
|
||||
}
|
||||
*frameUsed += used * 4;
|
||||
return stereo? used * 4: used * 2;
|
||||
}
|
||||
|
||||
/* data in routines (reducing speed)... */
|
||||
|
||||
static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
short *p = (short *) &frame[*frameUsed];
|
||||
int bal = expand_read_bal;
|
||||
int vall,valr, stereo = dmasound.soft.stereo;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int utotal, ftotal;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
u_char data;
|
||||
|
||||
if (bal<0 && userCount == 0)
|
||||
break;
|
||||
vall = *p++;
|
||||
vall = (vall * software_input_volume) >> 7;
|
||||
if (stereo) {
|
||||
valr = *p;
|
||||
valr = (valr * software_input_volume) >> 7;
|
||||
}
|
||||
p++;
|
||||
if (bal < 0) {
|
||||
data = vall >> 8;
|
||||
if (put_user(data, (u_char __user *)userPtr++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
data = valr >> 8;
|
||||
if (put_user(data, (u_char __user *)userPtr++))
|
||||
return -EFAULT;
|
||||
}
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_read_bal=bal;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 2: utotal;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
short *p = (short *) &frame[*frameUsed];
|
||||
int bal = expand_read_bal;
|
||||
int vall,valr, stereo = dmasound.soft.stereo;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int utotal, ftotal;
|
||||
|
||||
frameLeft >>= 2;
|
||||
if (stereo)
|
||||
userCount >>= 1;
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
u_char data;
|
||||
|
||||
if (bal<0 && userCount == 0)
|
||||
break;
|
||||
|
||||
vall = *p++;
|
||||
vall = (vall * software_input_volume) >> 7;
|
||||
if (stereo) {
|
||||
valr = *p;
|
||||
valr = (valr * software_input_volume) >> 7;
|
||||
}
|
||||
p++;
|
||||
if (bal < 0) {
|
||||
data = (vall >> 8) ^ 0x80;
|
||||
if (put_user(data, (u_char __user *)userPtr++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
data = (valr >> 8) ^ 0x80;
|
||||
if (put_user(data, (u_char __user *)userPtr++))
|
||||
return -EFAULT;
|
||||
}
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_read_bal=bal;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 2: utotal;
|
||||
}
|
||||
|
||||
static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
int bal = expand_read_bal;
|
||||
short *fp = (short *) &frame[*frameUsed];
|
||||
short __user *up = (short __user *) userPtr;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int utotal, ftotal;
|
||||
|
||||
frameLeft >>= 2;
|
||||
userCount >>= (stereo? 2: 1);
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
int datal,datar;
|
||||
|
||||
if (bal<0 && userCount == 0)
|
||||
break;
|
||||
|
||||
datal = *fp++;
|
||||
datal = (datal * software_input_volume) >> 7;
|
||||
if (stereo) {
|
||||
datar = *fp;
|
||||
datar = (datar * software_input_volume) >> 7;
|
||||
}
|
||||
fp++;
|
||||
if (bal < 0) {
|
||||
if (put_user(datal, up++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
if (put_user(datar, up++))
|
||||
return -EFAULT;
|
||||
}
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_read_bal=bal;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 4: utotal * 2;
|
||||
}
|
||||
|
||||
static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
|
||||
u_char frame[], ssize_t *frameUsed,
|
||||
ssize_t frameLeft)
|
||||
{
|
||||
int bal = expand_read_bal;
|
||||
int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
|
||||
short *fp = (short *) &frame[*frameUsed];
|
||||
short __user *up = (short __user *) userPtr;
|
||||
int stereo = dmasound.soft.stereo;
|
||||
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
|
||||
int utotal, ftotal;
|
||||
|
||||
frameLeft >>= 2;
|
||||
userCount >>= (stereo? 2: 1);
|
||||
ftotal = frameLeft;
|
||||
utotal = userCount;
|
||||
while (frameLeft) {
|
||||
int datal,datar;
|
||||
|
||||
if (bal<0 && userCount == 0)
|
||||
break;
|
||||
|
||||
datal = *fp++;
|
||||
datal = (datal * software_input_volume) >> 7;
|
||||
datal ^= mask;
|
||||
if (stereo) {
|
||||
datar = *fp;
|
||||
datar = (datar * software_input_volume) >> 7;
|
||||
datar ^= mask;
|
||||
}
|
||||
fp++;
|
||||
if (bal < 0) {
|
||||
if (put_user(datal, up++))
|
||||
return -EFAULT;
|
||||
if (stereo) {
|
||||
if (put_user(datar, up++))
|
||||
return -EFAULT;
|
||||
}
|
||||
userCount--;
|
||||
bal += hSpeed;
|
||||
}
|
||||
frameLeft--;
|
||||
bal -= sSpeed;
|
||||
}
|
||||
expand_read_bal=bal;
|
||||
*frameUsed += (ftotal - frameLeft) * 4;
|
||||
utotal -= userCount;
|
||||
return stereo? utotal * 4: utotal * 2;
|
||||
}
|
||||
|
||||
|
||||
TRANS transAwacsNormal = {
|
||||
.ct_ulaw= pmac_ct_law,
|
||||
.ct_alaw= pmac_ct_law,
|
||||
.ct_s8= pmac_ct_s8,
|
||||
.ct_u8= pmac_ct_u8,
|
||||
.ct_s16be= pmac_ct_s16,
|
||||
.ct_u16be= pmac_ct_u16,
|
||||
.ct_s16le= pmac_ct_s16,
|
||||
.ct_u16le= pmac_ct_u16,
|
||||
};
|
||||
|
||||
TRANS transAwacsExpand = {
|
||||
.ct_ulaw= pmac_ctx_law,
|
||||
.ct_alaw= pmac_ctx_law,
|
||||
.ct_s8= pmac_ctx_s8,
|
||||
.ct_u8= pmac_ctx_u8,
|
||||
.ct_s16be= pmac_ctx_s16,
|
||||
.ct_u16be= pmac_ctx_u16,
|
||||
.ct_s16le= pmac_ctx_s16,
|
||||
.ct_u16le= pmac_ctx_u16,
|
||||
};
|
||||
|
||||
TRANS transAwacsNormalRead = {
|
||||
.ct_s8= pmac_ct_s8_read,
|
||||
.ct_u8= pmac_ct_u8_read,
|
||||
.ct_s16be= pmac_ct_s16_read,
|
||||
.ct_u16be= pmac_ct_u16_read,
|
||||
.ct_s16le= pmac_ct_s16_read,
|
||||
.ct_u16le= pmac_ct_u16_read,
|
||||
};
|
||||
|
||||
TRANS transAwacsExpandRead = {
|
||||
.ct_s8= pmac_ctx_s8_read,
|
||||
.ct_u8= pmac_ctx_u8_read,
|
||||
.ct_s16be= pmac_ctx_s16_read,
|
||||
.ct_u16be= pmac_ctx_u16_read,
|
||||
.ct_s16le= pmac_ctx_s16_read,
|
||||
.ct_u16le= pmac_ctx_u16_read,
|
||||
};
|
||||
|
||||
/* translation tables */
|
||||
/* 16 bit mu-law */
|
||||
|
||||
static short dmasound_ulaw2dma16[] = {
|
||||
-32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
|
||||
-23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
|
||||
-15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
|
||||
-11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
|
||||
-7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
|
||||
-5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
|
||||
-3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
|
||||
-2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
|
||||
-1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
|
||||
-1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
|
||||
-876, -844, -812, -780, -748, -716, -684, -652,
|
||||
-620, -588, -556, -524, -492, -460, -428, -396,
|
||||
-372, -356, -340, -324, -308, -292, -276, -260,
|
||||
-244, -228, -212, -196, -180, -164, -148, -132,
|
||||
-120, -112, -104, -96, -88, -80, -72, -64,
|
||||
-56, -48, -40, -32, -24, -16, -8, 0,
|
||||
32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
|
||||
23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
|
||||
15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
|
||||
11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
|
||||
7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
|
||||
5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
|
||||
3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
|
||||
2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
|
||||
1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
|
||||
1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
|
||||
876, 844, 812, 780, 748, 716, 684, 652,
|
||||
620, 588, 556, 524, 492, 460, 428, 396,
|
||||
372, 356, 340, 324, 308, 292, 276, 260,
|
||||
244, 228, 212, 196, 180, 164, 148, 132,
|
||||
120, 112, 104, 96, 88, 80, 72, 64,
|
||||
56, 48, 40, 32, 24, 16, 8, 0,
|
||||
};
|
||||
|
||||
/* 16 bit A-law */
|
||||
|
||||
static short dmasound_alaw2dma16[] = {
|
||||
-5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
|
||||
-7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
|
||||
-2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
|
||||
-3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
|
||||
-22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
|
||||
-30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
|
||||
-11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
|
||||
-15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
|
||||
-344, -328, -376, -360, -280, -264, -312, -296,
|
||||
-472, -456, -504, -488, -408, -392, -440, -424,
|
||||
-88, -72, -120, -104, -24, -8, -56, -40,
|
||||
-216, -200, -248, -232, -152, -136, -184, -168,
|
||||
-1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
|
||||
-1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
|
||||
-688, -656, -752, -720, -560, -528, -624, -592,
|
||||
-944, -912, -1008, -976, -816, -784, -880, -848,
|
||||
5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
|
||||
7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
|
||||
2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
|
||||
3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
|
||||
22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
|
||||
30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
|
||||
11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
|
||||
15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
|
||||
344, 328, 376, 360, 280, 264, 312, 296,
|
||||
472, 456, 504, 488, 408, 392, 440, 424,
|
||||
88, 72, 120, 104, 24, 8, 56, 40,
|
||||
216, 200, 248, 232, 152, 136, 184, 168,
|
||||
1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
|
||||
1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
|
||||
688, 656, 752, 720, 560, 528, 624, 592,
|
||||
944, 912, 1008, 976, 816, 784, 880, 848,
|
||||
};
|
3131
sound/oss/es1371.c
3131
sound/oss/es1371.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user