/*
* 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>:
*
* Input support by Renzo Davoli <renzo@cs.unibo.it>
*
*/
#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/interrupt.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 "tas3004.h"
#include "tas_ioctl.h"
/* #define DEBUG_DRCE */
#define TAS3004_BIQUAD_FILTER_COUNT 7
#define TAS3004_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 tas3004_data_t {
struct tas_data_t super;
int device_id;
int output_id;
int speaker_id;
struct tas_drce_t drce_state;
};
#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
#define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
static const union tas_biquad_t tas3004_eq_unity = {
.buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
};
static const struct tas_drce_t tas3004_drce_min = {
.enable = 1,
.above = { .val = MAKE_RATIO(16,0), .expand = 0 },
.below = { .val = MAKE_RATIO(2,0), .expand = 0 },
.threshold = -0x59a0,
.energy = MAKE_TIME(0, 1700),
.attack = MAKE_TIME(0, 1700),
.decay = MAKE_TIME(0, 1700),
};
static const struct tas_drce_t tas3004_drce_max = {
.enable = 1,
.above = { .val = MAKE_RATIO(1,500), .expand = 1 },
.below = { .val = MAKE_RATIO(2,0), .expand = 1 },
.threshold = -0x0,
.energy = MAKE_TIME(2,400000),
.attack = MAKE_TIME(2,400000),
.decay = MAKE_TIME(2,400000),
};
static const unsigned short time_constants[]={
MAKE_TIME(0, 1700),
MAKE_TIME(0, 3500),
MAKE_TIME(0, 6700),
MAKE_TIME(0, 13000),
MAKE_TIME(0, 26000),
MAKE_TIME(0, 53000),
MAKE_TIME(0,106000),
MAKE_TIME(0,212000),
MAKE_TIME(0,425000),
MAKE_TIME(0,850000),
MAKE_TIME(1,700000),
MAKE_TIME(2,400000),
};
static const unsigned short above_threshold_compression_ratio[]={
MAKE_RATIO( 1, 70),
MAKE_RATIO( 1,140),
MAKE_RATIO( 1,230),
MAKE_RATIO( 1,330),
MAKE_RATIO( 1,450),
MAKE_RATIO( 1,600),
MAKE_RATIO( 1,780),
MAKE_RATIO( 2, 0),
MAKE_RATIO( 2,290),
MAKE_RATIO( 2,670),
MAKE_RATIO( 3,200),
MAKE_RATIO( 4, 0),
MAKE_RATIO( 5,330),
MAKE_RATIO( 8, 0),
MAKE_RATIO(16, 0),
};
static const unsigned short above_thr