/*
 * 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;
	struct work_struct change;
};

#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_threshold_expansion_ratio[]={
	MAKE_RATIO(1, 60),
	MAKE_RATIO(1,130),
	MAKE_RATIO(1,190),
	MAKE_RATIO(1,250),
	MAKE_RATIO(1,310),
	MAKE_RATIO(1,380),
	MAKE_RATIO(1,440),
	MAKE_RATIO(1,500)
};

static const unsigned short below_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)
};

static const unsigned short below_threshold_expansion_ratio[]={
	MAKE_RATIO(1, 60),
	MAKE_RATIO(1,130),
	MAKE_RATIO(1,190),
	MAKE_RATIO(1,250),
	MAKE_RATIO(1,310),
	MAKE_RATIO(1,380),
	MAKE_RATIO(1,440),
	MAKE_RATIO(1,500),
	MAKE_RATIO(1,560),
	MAKE_RATIO(1,630),
	MAKE_RATIO(1,690),
	MAKE_RATIO(1,750),
	MAKE_RATIO(1,810),
	MAKE_RATIO(1,880),
	MAKE_RATIO(1,940),
	MAKE_RATIO(2,  0)
};

static inline int
search(	unsigned short val,
	const unsigned short *arr,
	const int arrsize) {
	/*
	 * This could be a binary search, but for small tables,
	 * a linear search is likely to be faster
	 */

	int i;

	for (i=0; i < arrsize; i++)
		if (arr[i] >= val)
			goto _1;
	return arrsize-1;
 _1:
	if (i == 0)
		return 0;
	return (arr[i]-val < val-arr[i-1]) ? i : i-1;
}

#define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))

static inline int
time_index(unsigned short time)
{
	return SEARCH(time, time_constants);
}


static inline int
above_threshold_compression_index(unsigned short ratio)
{
	return SEARCH(ratio, above_threshold_compression_ratio);
}


static inline int
above_threshold_expansion_index(unsigned short ratio)
{
	return SEARCH(ratio, above_threshold_expansion_ratio);
}


static inline int
below_threshold_compression_index(unsigned short ratio)
{
	return SEARCH(ratio, below_threshold_compression_ratio);
}


static inline int
below_threshold_expansion_index(unsigned short ratio)
{
	return SEARCH(ratio, below_threshold_expansion_ratio);
}

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 tas3004_reg_t r)
{
	switch(r) {
	case TAS3004_REG_MCR:
 	case TAS3004_REG_TREBLE:
	case TAS3004_REG_BASS:
	case TAS3004_REG_ANALOG_CTRL:
	case TAS3004_REG_TEST1:
	case TAS3004_REG_TEST2:
	case TAS3004_REG_MCR2:
		return 1;

	case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
	case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
		return 3;

	case TAS3004_REG_DRC:
	case TAS3004_REG_VOLUME:
		return 6;

	case TAS3004_REG_LEFT_MIXER:
	case TAS3004_REG_RIGHT_MIXER:
		return 9;

	case TAS3004_REG_TEST:
		return 10;

	case TAS3004_REG_LEFT_BIQUAD0:
	case TAS3004_REG_LEFT_BIQUAD1:
	case TAS3004_REG_LEFT_BIQUAD2:
	case TAS3004_REG_LEFT_BIQUAD3:
	case TAS3004_REG_LEFT_BIQUAD4:
	case TAS3004_REG_LEFT_BIQUAD5:
	case TAS3004_REG_LEFT_BIQUAD6:

	case TAS3004_REG_RIGHT_BIQUAD0:
	case TAS3004_REG_RIGHT_BIQUAD1:
	case TAS3004_REG_RIGHT_BIQUAD2:
	case TAS3004_REG_RIGHT_BIQUAD3:
	case TAS3004_REG_RIGHT_BIQUAD4:
	case TAS3004_REG_RIGHT_BIQUAD5:
	case TAS3004_REG_RIGHT_BIQUAD6:

	case TAS3004_REG_LEFT_LOUD_BIQUAD:
	case TAS3004_REG_RIGHT_LOUD_BIQUAD:
		return 15;

	default:
		return 0;
	}
}

static int
tas3004_write_register(	struct tas3004_data_t *self,
			enum tas3004_reg_t reg_num,
			char *data,
			uint write_mode)
{
	if (reg_num==TAS3004_REG_MCR ||
	    reg_num==TAS3004_REG_BASS ||
	    reg_num==TAS3004_REG_TREBLE ||
	    reg_num==TAS3004_REG_ANALOG_CTRL) {
		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
tas3004_sync_register(	struct tas3004_data_t *self,
			enum tas3004_reg_t reg_num)
{
	if (reg_num==TAS3004_REG_MCR ||
	    reg_num==TAS3004_REG_BASS ||
	    reg_num==TAS3004_REG_TREBLE ||
	    reg_num==TAS3004_REG_ANALOG_CTRL) {
		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
tas3004_read_register(	struct tas3004_data_t *self,
			enum tas3004_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
tas3004_fast_load(struct tas3004_data_t *self, int fast)
{
	if (fast)
		self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
	else
		self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
	return tas3004_sync_register(self,TAS3004_REG_MCR);
}

static uint
tas3004_supported_mixers(struct tas3004_data_t *self)
{
	return SOUND_MASK_VOLUME |
		SOUND_MASK_PCM |
		SOUND_MASK_ALTPCM |
		SOUND_MASK_IMIX |
		SOUND_MASK_TREBLE |
		SOUND_MASK_BASS |
		SOUND_MASK_MIC |
		SOUND_MASK_LINE;
}

static int
tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
{
	switch(mixer) {
	case SOUND_MIXER_VOLUME:
	case SOUND_MIXER_PCM:
	case SOUND_MIXER_ALTPCM:
	case SOUND_MIXER_IMIX:
		return 1;
	default:
		return 0;
	}
}

static uint
tas3004_stereo_mixers(struct tas3004_data_t *self)
{
	uint r = tas3004_supported_mixers(self);
	uint i;
	
	for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
		if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
			r &= ~(1<<i);
	return r;
}

static int
tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
{
	if (!self)
		return -1;

	*level = self->super.mixer[mixer];

	return 0;
}

static int
tas3004_set_mixer_level(struct tas3004_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 (!tas3004_mixer_is_stereo(self,mixer))
		level = tas_mono_to_stereo(level);
	switch(mixer) {
	case SOUND_MIXER_VOLUME:
		temp = tas3004_gain.master[level&0xff];
		SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
		temp = tas3004_gain.master[(level>>8)&0xff];
		SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
		rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
		break;
	case SOUND_MIXER_IMIX:
		offset += 3;
	case SOUND_MIXER_ALTPCM:
		offset += 3;
	case SOUND_MIXER_PCM:
		/*
		 * Don't load these in fast mode. The documentation
		 * says it can be done in either mode, but testing it
		 * shows that fast mode produces ugly clicking.
		*/
		/* tas3004_fast_load(self,1); */
		temp = tas3004_gain.mixer[level&0xff];
		SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
		temp = tas3004_gain.mixer[(level>>8)&0xff];
		SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
		rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
		if (rc == 0)
			rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
		/* tas3004_fast_load(self,0); */
		break;
	case SOUND_MIXER_TREBLE:
		temp = tas3004_gain.treble[level&0xff];
		shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
		rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
		break;
	case SOUND_MIXER_BASS:
		temp = tas3004_gain.bass[level&0xff];
		shadow[TAS3004_REG_BASS][0]=temp&0xff;
		rc = tas3004_sync_register(self,TAS3004_REG_BASS);
		break;
	case SOUND_MIXER_MIC:
		if ((level&0xff)>0) {
			software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
			if (self->super.mixer[mixer] == 0) {
				self->super.mixer[SOUND_MIXER_LINE] = 0;
				shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
				rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
			} else rc=0;
		} else {
			self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
			software_input_volume = SW_INPUT_VOLUME_SCALE *
				(self->super.mixer[SOUND_MIXER_LINE]&0xff);
			shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
			rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
		}
		break;
	case SOUND_MIXER_LINE:
		if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
			software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
			rc=0;
		}
		break;
	default:
		rc = -1;
		break;
	}
	if (rc < 0)
		return rc;
	self->super.mixer[mixer] = level;
	
	return 0;
}

static int
tas3004_leave_sleep(struct tas3004_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 (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
	    WRITE_NORMAL | FORCE_WRITE) < 0)
		return -1;

	tas3004_fast_load(self, 1);

	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);

	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);

	tas3004_fast_load(self, 0);

	(void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
	(void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
	(void)tas3004_sync_register(self,TAS3004_REG_BASS);
	(void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);

	return 0;
}

static int
tas3004_enter_sleep(struct tas3004_data_t *self)
{
	if (!self)
		return -1; 
	return 0;
}

static int
tas3004_sync_biquad(	struct tas3004_data_t *self,
			u_int channel,
			u_int filter)
{
	enum tas3004_reg_t reg;

	if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
	    filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;

	reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;

	return tas3004_sync_register(self,reg);
}

static int
tas3004_write_biquad_shadow(	struct tas3004_data_t *self,
				u_int channel,
				u_int filter,
				const union tas_biquad_t *biquad)
{
	tas_shadow_t *shadow=self->super.shadow;
	enum tas3004_reg_t reg;

	if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
	    filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;

	reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_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
tas3004_write_biquad(	struct tas3004_data_t *self,
			u_int channel,
			u_int filter,
			const union tas_biquad_t *biquad)
{
	int rc;

	rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
	if (rc < 0) return rc;

	return tas3004_sync_biquad(self, channel, filter);
}

static int
tas3004_write_biquad_list(	struct tas3004_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) tas3004_fast_load(self,1);

	for (i=0; i<filter_count; i++) {
		rc=tas3004_write_biquad(self,
					biquads[i].channel,
					biquads[i].filter,
					&biquads[i].data);
		if (rc < 0) break;
	}

	if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);

	return rc;
}

static int
tas3004_read_biquad(	struct tas3004_data_t *self,
			u_int channel,
			u_int filter,
			union tas_biquad_t *biquad)
{
	tas_shadow_t *shadow=self->super.shadow;
	enum tas3004_reg_t reg;

	if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
	    filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;

	reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_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
tas3004_eq_rw(	struct tas3004_data_t *self,
		u_int cmd,
		u_long arg)
{
	void __user *argp = (void __user *)arg;
	int rc;
	struct tas_biquad_ctrl_t biquad;

	if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
		return -EFAULT;
	}

	if (cmd & SIOC_IN) {
		rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
		if (rc != 0) return rc;
	}

	if (cmd & SIOC_OUT) {
		rc=tas3004_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
tas3004_eq_list_rw(	struct tas3004_data_t *self,
			u_int cmd,
			u_long arg)
{
	int rc = 0;
	int filter_count;
	int flags;
	int i,j;
	char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
	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=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
			if (rc != 0) return rc;
		}

		if (cmd & SIOC_OUT) {
			rc=tas3004_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) {
		/*
		 * This is OK for the tas3004. For the
		 * tas3001c, going into fast load mode causes
		 * the treble and bass to be reset to 0dB, and
		 * volume controls to be muted.
		 */
		if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
		for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
			for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
				if (sync_required[i][j]) {
					rc=tas3004_sync_biquad(self, i, j);
					if (rc < 0) goto out;
				}
			}
		}
	out:
		if (flags & TAS_BIQUAD_FAST_LOAD)
			tas3004_fast_load(self,0);
	}

	return rc;
}

static int
tas3004_update_drce(	struct tas3004_data_t *self,
			int flags,
			struct tas_drce_t *drce)
{
	tas_shadow_t *shadow;
	int i;
	shadow=self->super.shadow;

	if (flags & TAS_DRCE_ABOVE_RATIO) {
		self->drce_state.above.expand = drce->above.expand;
		if (drce->above.val == (1<<8)) {
			self->drce_state.above.val = 1<<8;
			shadow[TAS3004_REG_DRC][0] = 0x02;
					
		} else if (drce->above.expand) {
			i=above_threshold_expansion_index(drce->above.val);
			self->drce_state.above.val=above_threshold_expansion_ratio[i];
			shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
		} else {
			i=above_threshold_compression_index(drce->above.val);
			self->drce_state.above.val=above_threshold_compression_ratio[i];
			shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
		}
	}

	if (flags & TAS_DRCE_BELOW_RATIO) {
		self->drce_state.below.expand = drce->below.expand;
		if (drce->below.val == (1<<8)) {
			self->drce_state.below.val = 1<<8;
			shadow[TAS3004_REG_DRC][1] = 0x02;
					
		} else if (drce->below.expand) {
			i=below_threshold_expansion_index(drce->below.val);
			self->drce_state.below.val=below_threshold_expansion_ratio[i];
			shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
		} else {
			i=below_threshold_compression_index(drce->below.val);
			self->drce_state.below.val=below_threshold_compression_ratio[i];
			shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
		}
	}

	if (flags & TAS_DRCE_THRESHOLD) {
		self->drce_state.threshold=quantize_db(drce->threshold);
		shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
	}

	if (flags & TAS_DRCE_ENERGY) {
		i=time_index(drce->energy);
		self->drce_state.energy=time_constants[i];
		shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
	}

	if (flags & TAS_DRCE_ATTACK) {
		i=time_index(drce->attack);
		self->drce_state.attack=time_constants[i];
		shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
	}

	if (flags & TAS_DRCE_DECAY) {
		i=time_index(drce->decay);
		self->drce_state.decay=time_constants[i];
		shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
	}

	if (flags & TAS_DRCE_ENABLE) {
		self->drce_state.enable = drce->enable;
	}

	if (!self->drce_state.enable) {
		shadow[TAS3004_REG_DRC][0] |= 0x01;
	}

#ifdef DEBUG_DRCE
	printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
	       self->drce_state.enable,
	       self->drce_state.above.expand,self->drce_state.above.val,
	       self->drce_state.below.expand,self->drce_state.below.val,
	       self->drce_state.threshold,
	       self->drce_state.energy,
	       self->drce_state.attack,
	       self->drce_state.decay);

	printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
	       (unsigned char)shadow[TAS3004_REG_DRC][0],
	       (unsigned char)shadow[TAS3004_REG_DRC][1],
	       (unsigned char)shadow[TAS3004_REG_DRC][2],
	       (unsigned char)shadow[TAS3004_REG_DRC][3],
	       (unsigned char)shadow[TAS3004_REG_DRC][4],
	       (unsigned char)shadow[TAS3004_REG_DRC][5]);
#endif

	return tas3004_sync_register(self, TAS3004_REG_DRC);
}

static int
tas3004_drce_rw(	struct tas3004_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: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
	       drce_ctrl.flags,
	       drce_ctrl.data.enable,
	       drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
	       drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
	       drce_ctrl.data.threshold,
	       drce_ctrl.data.energy,
	       drce_ctrl.data.attack,
	       drce_ctrl.data.decay);
#endif

	if (cmd & SIOC_IN) {
		rc = tas3004_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_ABOVE_RATIO)
			drce_ctrl.data.above = self->drce_state.above;
		if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
			drce_ctrl.data.below = self->drce_state.below;
		if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
			drce_ctrl.data.threshold = self->drce_state.threshold;
		if (drce_ctrl.flags & TAS_DRCE_ENERGY)
			drce_ctrl.data.energy = self->drce_state.energy;
		if (drce_ctrl.flags & TAS_DRCE_ATTACK)
			drce_ctrl.data.attack = self->drce_state.attack;
		if (drce_ctrl.flags & TAS_DRCE_DECAY)
			drce_ctrl.data.decay = self->drce_state.decay;

		if (copy_to_user(argp, &drce_ctrl,
				 sizeof(struct tas_drce_ctrl_t))) {
			return -EFAULT;
		}
	}

	return 0;
}

static void
tas3004_update_device_parameters(struct tas3004_data_t *self)
{
	char data;
	int i;

	if (!self) return;

	if (self->output_id == TAS_OUTPUT_HEADPHONES) {
		/* turn on allPass when headphones are plugged in */
		data = 0x02;
	} else {
		data = 0x00;
	}

	tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);

	for (i=0; tas3004_eq_prefs[i]; i++) {
		struct tas_eq_pref_t *eq = tas3004_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)) {

			tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
			tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);

			break;
		}
	}
}

static void
tas3004_device_change_handler(struct work_struct *work)
{
	struct tas3004_data_t *self;
	self = container_of(work, struct tas3004_data_t, change);
	tas3004_update_device_parameters(self);
}

static int
tas3004_output_device_change(	struct tas3004_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
tas3004_device_ioctl(	struct tas3004_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 tas3004_eq_rw(self, cmd, arg);

	case TAS_READ_EQ_LIST:
	case TAS_WRITE_EQ_LIST:
		return tas3004_eq_list_rw(self, cmd, arg);

	case TAS_READ_EQ_FILTER_COUNT:
		put_user(TAS3004_BIQUAD_FILTER_COUNT, argp);
		return 0;

	case TAS_READ_EQ_CHANNEL_COUNT:
		put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp);
		return 0;

	case TAS_READ_DRCE:
	case TAS_WRITE_DRCE:
		return tas3004_drce_rw(self, cmd, arg);

	case TAS_READ_DRCE_CAPS:
		put_user(TAS_DRCE_ENABLE         |
			 TAS_DRCE_ABOVE_RATIO    |
			 TAS_DRCE_BELOW_RATIO    |
			 TAS_DRCE_THRESHOLD      |
			 TAS_DRCE_ENERGY         |
			 TAS_DRCE_ATTACK         |
			 TAS_DRCE_DECAY,
			 argp);
		return 0;

	case TAS_READ_DRCE_MIN:
	case TAS_READ_DRCE_MAX: {
		struct tas_drce_ctrl_t drce_ctrl;
		const struct tas_drce_t *drce_copy;

		if (copy_from_user(&drce_ctrl, argp,
				   sizeof(struct tas_drce_ctrl_t))) {
			return -EFAULT;
		}

		if (cmd == TAS_READ_DRCE_MIN) {
			drce_copy=&tas3004_drce_min;
		} else {
			drce_copy=&tas3004_drce_max;
		}

		if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
			drce_ctrl.data.above=drce_copy->above;
		}
		if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
			drce_ctrl.data.below=drce_copy->below;
		}
		if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
			drce_ctrl.data.threshold=drce_copy->threshold;
		}
		if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
			drce_ctrl.data.energy=drce_copy->energy;
		}
		if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
			drce_ctrl.data.attack=drce_copy->attack;
		}
		if (drce_ctrl.flags & TAS_DRCE_DECAY) {
			drce_ctrl.data.decay=drce_copy->decay;
		}

		if (copy_to_user(argp, &drce_ctrl,
				 sizeof(struct tas_drce_ctrl_t))) {
			return -EFAULT;
		}
	}
	}

	return -EINVAL;
}

static int
tas3004_init_mixer(struct tas3004_data_t *self)
{
	unsigned char mcr = (1<<6)+(2<<4)+(2<<2);

	/* Make sure something answers on the i2c bus */
	if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
	    WRITE_NORMAL | FORCE_WRITE) < 0)
		return -1;

	tas3004_fast_load(self, 1);

	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);

	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);

	tas3004_sync_register(self, TAS3004_REG_DRC);

	tas3004_sync_register(self, TAS3004_REG_MCR2);

	tas3004_fast_load(self, 0);

	tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
	tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
	tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
	tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);

	tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
	tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);

	tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT);

	return 0;
}

static int
tas3004_uninit_mixer(struct tas3004_data_t *self)
{
	tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
	tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
	tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
	tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);

	tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
	tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);

	tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0);

	return 0;
}

static int
tas3004_init(struct i2c_client *client)
{
	struct tas3004_data_t *self;
	size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
	char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
	char mcr2 = 0;
	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 < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
		for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
			tas3004_write_biquad_shadow(self, i, j,
					&tas3004_eq_unity);

	tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
	tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);

	INIT_WORK(&self->change, tas3004_device_change_handler);
	return 0;
}

static void 
tas3004_uninit(struct tas3004_data_t *self)
{
	tas3004_uninit_mixer(self);
	kfree(self);
}


struct tas_driver_hooks_t tas3004_hooks = {
	.init			= (tas_hook_init_t)tas3004_init,
	.post_init		= (tas_hook_post_init_t)tas3004_init_mixer,
	.uninit			= (tas_hook_uninit_t)tas3004_uninit,
	.get_mixer_level	= (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
	.set_mixer_level	= (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
	.enter_sleep		= (tas_hook_enter_sleep_t)tas3004_enter_sleep,
	.leave_sleep		= (tas_hook_leave_sleep_t)tas3004_leave_sleep,
	.supported_mixers	= (tas_hook_supported_mixers_t)tas3004_supported_mixers,
	.mixer_is_stereo	= (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
	.stereo_mixers		= (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
	.output_device_change	= (tas_hook_output_device_change_t)tas3004_output_device_change,
	.device_ioctl		= (tas_hook_device_ioctl_t)tas3004_device_ioctl
};
