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


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(void *self)
{
	if (self)
		tas3001c_update_device_parameters(self);
}

static struct work_struct device_change;

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(&device_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 = kmalloc(sz, GFP_KERNEL);
	if (!self)
		return -ENOMEM;
	memset(self, 0, sz);

	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(&device_change, tas3001c_device_change_handler, self);
	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
};
