/*
 * Apple Onboard Audio driver for Onyx codec
 *
 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
 *
 * GPL v2, can be found in COPYING.
 *
 *
 * This is a driver for the pcm3052 codec chip (codenamed Onyx)
 * that is present in newer Apple hardware (with digital output).
 *
 * The Onyx codec has the following connections (listed by the bit
 * to be used in aoa_codec.connected):
 *  0: analog output
 *  1: digital output
 *  2: line input
 *  3: microphone input
 * Note that even though I know of no machine that has for example
 * the digital output connected but not the analog, I have handled
 * all the different cases in the code so that this driver may serve
 * as a good example of what to do.
 *
 * NOTE: This driver assumes that there's at most one chip to be
 * 	 used with one alsa card, in form of creating all kinds
 *	 of mixer elements without regard for their existence.
 *	 But snd-aoa assumes that there's at most one card, so
 *	 this means you can only have one onyx on a system. This
 *	 should probably be fixed by changing the assumption of
 *	 having just a single card on a system, and making the
 *	 'card' pointer accessible to anyone who needs it instead
 *	 of hiding it in the aoa_snd_* functions...
 *
 */
#include <linux/delay.h>
#include <linux/module.h>
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");

#include "snd-aoa-codec-onyx.h"
#include "../aoa.h"
#include "../soundbus/soundbus.h"


#define PFX "snd-aoa-codec-onyx: "

struct onyx {
	/* cache registers 65 to 80, they are write-only! */
	u8			cache[16];
	struct i2c_client	i2c;
	struct aoa_codec	codec;
	u32			initialised:1,
				spdif_locked:1,
				analog_locked:1,
				original_mute:2;
	int			open_count;
	struct codec_info	*codec_info;

	/* mutex serializes concurrent access to the device
	 * and this structure.
	 */
	struct mutex mutex;
};
#define codec_to_onyx(c) container_of(c, struct onyx, codec)

/* both return 0 if all ok, else on error */
static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value)
{
	s32 v;

	if (reg != ONYX_REG_CONTROL) {
		*value = onyx->cache[reg-FIRSTREGISTER];
		return 0;
	}
	v = i2c_smbus_read_byte_data(&onyx->i2c, reg);
	if (v < 0)
		return -1;
	*value = (u8)v;
	onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value;
	return 0;
}

static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value)
{
	int result;

	result = i2c_smbus_write_byte_data(&onyx->i2c, reg, value);
	if (!result)
		onyx->cache[reg-FIRSTREGISTER] = value;
	return result;
}

/* alsa stuff */

static int onyx_dev_register(struct snd_device *dev)
{
	return 0;
}

static struct snd_device_ops ops = {
	.dev_register = onyx_dev_register,
};

/* this is necessary because most alsa mixer programs
 * can't properly handle the negative range */
#define VOLUME_RANGE_SHIFT	128

static int onyx_snd_vol_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 2;
	uinfo->value.integer.min = -128 + VOLUME_RANGE_SHIFT;
	uinfo->value.integer.max = -1 + VOLUME_RANGE_SHIFT;
	return 0;
}

static int onyx_snd_vol_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	s8 l, r;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
	onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
	mutex_unlock(&onyx->mutex);

	ucontrol->value.integer.value[0] = l + VOLUME_RANGE_SHIFT;
	ucontrol->value.integer.value[1] = r + VOLUME_RANGE_SHIFT;

	return 0;
}

static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	s8 l, r;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
	onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);

	if (l + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[0] &&
	    r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1]) {
		mutex_unlock(&onyx->mutex);
		return 0;
	}

	onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_LEFT,
			    ucontrol->value.integer.value[0]
			     - VOLUME_RANGE_SHIFT);
	onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT,
			    ucontrol->value.integer.value[1]
			     - VOLUME_RANGE_SHIFT);
	mutex_unlock(&onyx->mutex);

	return 1;
}

static struct snd_kcontrol_new volume_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "Master Playback Volume",
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.info = onyx_snd_vol_info,
	.get = onyx_snd_vol_get,
	.put = onyx_snd_vol_put,
};

/* like above, this is necessary because a lot
 * of alsa mixer programs don't handle ranges
 * that don't start at 0 properly.
 * even alsamixer is one of them... */
#define INPUTGAIN_RANGE_SHIFT	(-3)

static int onyx_snd_inputgain_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	uinfo->value.integer.min = 3 + INPUTGAIN_RANGE_SHIFT;
	uinfo->value.integer.max = 28 + INPUTGAIN_RANGE_SHIFT;
	return 0;
}

static int onyx_snd_inputgain_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	u8 ig;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &ig);
	mutex_unlock(&onyx->mutex);

	ucontrol->value.integer.value[0] =
		(ig & ONYX_ADC_PGA_GAIN_MASK) + INPUTGAIN_RANGE_SHIFT;

	return 0;
}

static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	u8 v, n;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
	n = v;
	n &= ~ONYX_ADC_PGA_GAIN_MASK;
	n |= (ucontrol->value.integer.value[0] - INPUTGAIN_RANGE_SHIFT)
		& ONYX_ADC_PGA_GAIN_MASK;
	onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, n);
	mutex_unlock(&onyx->mutex);

	return n != v;
}

static struct snd_kcontrol_new inputgain_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "Master Capture Volume",
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.info = onyx_snd_inputgain_info,
	.get = onyx_snd_inputgain_get,
	.put = onyx_snd_inputgain_put,
};

static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	static char *texts[] = { "Line-In", "Microphone" };

	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
	uinfo->count = 1;
	uinfo->value.enumerated.items = 2;
	if (uinfo->value.enumerated.item > 1)
		uinfo->value.enumerated.item = 1;
	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
	return 0;
}

static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	s8 v;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
	mutex_unlock(&onyx->mutex);

	ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC);

	return 0;
}

static void onyx_set_capture_source(struct onyx *onyx, int mic)
{
	s8 v;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
	v &= ~ONYX_ADC_INPUT_MIC;
	if (mic)
		v |= ONYX_ADC_INPUT_MIC;
	onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v);
	mutex_unlock(&onyx->mutex);
}

static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	onyx_set_capture_source(snd_kcontrol_chip(kcontrol),
				ucontrol->value.enumerated.item[0]);
	return 1;
}

static struct snd_kcontrol_new capture_source_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	/* If we name this 'Input Source', it properly shows up in
	 * alsamixer as a selection, * but it's shown under the 
	 * 'Playback' category.
	 * If I name it 'Capture Source', it shows up in strange
	 * ways (two bools of which one can be selected at a
	 * time) but at least it's shown in the 'Capture'
	 * category.
	 * I was told that this was due to backward compatibility,
	 * but I don't understand then why the mangling is *not*
	 * done when I name it "Input Source".....
	 */
	.name = "Capture Source",
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.info = onyx_snd_capture_source_info,
	.get = onyx_snd_capture_source_get,
	.put = onyx_snd_capture_source_put,
};

static int onyx_snd_mute_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 1;
	return 0;
}

static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	u8 c;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c);
	mutex_unlock(&onyx->mutex);

	ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT);
	ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT);

	return 0;
}

static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	u8 v = 0, c = 0;
	int err = -EBUSY;

	mutex_lock(&onyx->mutex);
	if (onyx->analog_locked)
		goto out_unlock;

	onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
	c = v;
	c &= ~(ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT);
	if (!ucontrol->value.integer.value[0])
		c |= ONYX_MUTE_LEFT;
	if (!ucontrol->value.integer.value[1])
		c |= ONYX_MUTE_RIGHT;
	err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c);

 out_unlock:
	mutex_unlock(&onyx->mutex);

	return !err ? (v != c) : err;
}

static struct snd_kcontrol_new mute_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "Master Playback Switch",
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.info = onyx_snd_mute_info,
	.get = onyx_snd_mute_get,
	.put = onyx_snd_mute_put,
};


static int onyx_snd_single_bit_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	uinfo->count = 1;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 1;
	return 0;
}

#define FLAG_POLARITY_INVERT	1
#define FLAG_SPDIFLOCK		2

static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	u8 c;
	long int pv = kcontrol->private_value;
	u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
	u8 address = (pv >> 8) & 0xff;
	u8 mask = pv & 0xff;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, address, &c);
	mutex_unlock(&onyx->mutex);

	ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity;

	return 0;
}

static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	u8 v = 0, c = 0;
	int err;
	long int pv = kcontrol->private_value;
	u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
	u8 spdiflock = (pv >> 16) & FLAG_SPDIFLOCK;
	u8 address = (pv >> 8) & 0xff;
	u8 mask = pv & 0xff;

	mutex_lock(&onyx->mutex);
	if (spdiflock && onyx->spdif_locked) {
		/* even if alsamixer doesn't care.. */
		err = -EBUSY;
		goto out_unlock;
	}
	onyx_read_register(onyx, address, &v);
	c = v;
	c &= ~(mask);
	if (!!ucontrol->value.integer.value[0] ^ polarity)
		c |= mask;
	err = onyx_write_register(onyx, address, c);

 out_unlock:
	mutex_unlock(&onyx->mutex);

	return !err ? (v != c) : err;
}

#define SINGLE_BIT(n, type, description, address, mask, flags)	 	\
static struct snd_kcontrol_new n##_control = {				\
	.iface = SNDRV_CTL_ELEM_IFACE_##type,				\
	.name = description,						\
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,			\
	.info = onyx_snd_single_bit_info,				\
	.get = onyx_snd_single_bit_get,					\
	.put = onyx_snd_single_bit_put,					\
	.private_value = (flags << 16) | (address << 8) | mask		\
}

SINGLE_BIT(spdif,
	   MIXER,
	   SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
	   ONYX_REG_DIG_INFO4,
	   ONYX_SPDIF_ENABLE,
	   FLAG_SPDIFLOCK);
SINGLE_BIT(ovr1,
	   MIXER,
	   "Oversampling Rate",
	   ONYX_REG_DAC_CONTROL,
	   ONYX_OVR1,
	   0);
SINGLE_BIT(flt0,
	   MIXER,
	   "Fast Digital Filter Rolloff",
	   ONYX_REG_DAC_FILTER,
	   ONYX_ROLLOFF_FAST,
	   FLAG_POLARITY_INVERT);
SINGLE_BIT(hpf,
	   MIXER,
	   "Highpass Filter",
	   ONYX_REG_ADC_HPF_BYPASS,
	   ONYX_HPF_DISABLE,
	   FLAG_POLARITY_INVERT);
SINGLE_BIT(dm12,
	   MIXER,
	   "Digital De-Emphasis",
	   ONYX_REG_DAC_DEEMPH,
	   ONYX_DIGDEEMPH_CTRL,
	   0);

static int onyx_spdif_info(struct snd_kcontrol *kcontrol,
			   struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
	uinfo->count = 1;
	return 0;
}

static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	/* datasheet page 30, all others are 0 */
	ucontrol->value.iec958.status[0] = 0x3e;
	ucontrol->value.iec958.status[1] = 0xff;

	ucontrol->value.iec958.status[3] = 0x3f;
	ucontrol->value.iec958.status[4] = 0x0f;
	
	return 0;
}

static struct snd_kcontrol_new onyx_spdif_mask = {
	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
	.info =		onyx_spdif_info,
	.get =		onyx_spdif_mask_get,
};

static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
			  struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	u8 v;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
	ucontrol->value.iec958.status[0] = v & 0x3e;

	onyx_read_register(onyx, ONYX_REG_DIG_INFO2, &v);
	ucontrol->value.iec958.status[1] = v;

	onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
	ucontrol->value.iec958.status[3] = v & 0x3f;

	onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
	ucontrol->value.iec958.status[4] = v & 0x0f;
	mutex_unlock(&onyx->mutex);

	return 0;
}

static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
			  struct snd_ctl_elem_value *ucontrol)
{
	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
	u8 v;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
	v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e);
	onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v);

	v = ucontrol->value.iec958.status[1];
	onyx_write_register(onyx, ONYX_REG_DIG_INFO2, v);

	onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
	v = (v & ~0x3f) | (ucontrol->value.iec958.status[3] & 0x3f);
	onyx_write_register(onyx, ONYX_REG_DIG_INFO3, v);

	onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
	v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f);
	onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
	mutex_unlock(&onyx->mutex);

	return 1;
}

static struct snd_kcontrol_new onyx_spdif_ctrl = {
	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
	.info =		onyx_spdif_info,
	.get =		onyx_spdif_get,
	.put =		onyx_spdif_put,
};

/* our registers */

static u8 register_map[] = {
	ONYX_REG_DAC_ATTEN_LEFT,
	ONYX_REG_DAC_ATTEN_RIGHT,
	ONYX_REG_CONTROL,
	ONYX_REG_DAC_CONTROL,
	ONYX_REG_DAC_DEEMPH,
	ONYX_REG_DAC_FILTER,
	ONYX_REG_DAC_OUTPHASE,
	ONYX_REG_ADC_CONTROL,
	ONYX_REG_ADC_HPF_BYPASS,
	ONYX_REG_DIG_INFO1,
	ONYX_REG_DIG_INFO2,
	ONYX_REG_DIG_INFO3,
	ONYX_REG_DIG_INFO4
};

static u8 initial_values[ARRAY_SIZE(register_map)] = {
	0x80, 0x80, /* muted */
	ONYX_MRST | ONYX_SRST, /* but handled specially! */
	ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT,
	0, /* no deemphasis */
	ONYX_DAC_FILTER_ALWAYS,
	ONYX_OUTPHASE_INVERTED,
	(-1 /*dB*/ + 8) & 0xF, /* line in selected, -1 dB gain*/
	ONYX_ADC_HPF_ALWAYS,
	(1<<2),	/* pcm audio */
	2,	/* category: pcm coder */
	0,	/* sampling frequency 44.1 kHz, clock accuracy level II */
	1	/* 24 bit depth */
};

/* reset registers of chip, either to initial or to previous values */
static int onyx_register_init(struct onyx *onyx)
{
	int i;
	u8 val;
	u8 regs[sizeof(initial_values)];

	if (!onyx->initialised) {
		memcpy(regs, initial_values, sizeof(initial_values));
		if (onyx_read_register(onyx, ONYX_REG_CONTROL, &val))
			return -1;
		val &= ~ONYX_SILICONVERSION;
		val |= initial_values[3];
		regs[3] = val;
	} else {
		for (i=0; i<sizeof(register_map); i++)
			regs[i] = onyx->cache[register_map[i]-FIRSTREGISTER];
	}

	for (i=0; i<sizeof(register_map); i++) {
		if (onyx_write_register(onyx, register_map[i], regs[i]))
			return -1;
	}
	onyx->initialised = 1;
	return 0;
}

static struct transfer_info onyx_transfers[] = {
	/* this is first so we can skip it if no input is present...
	 * No hardware exists with that, but it's here as an example
	 * of what to do :) */
	{
		/* analog input */
		.formats = SNDRV_PCM_FMTBIT_S8 |
			   SNDRV_PCM_FMTBIT_S16_BE |
			   SNDRV_PCM_FMTBIT_S24_BE,
		.rates = SNDRV_PCM_RATE_8000_96000,
		.transfer_in = 1,
		.must_be_clock_source = 0,
		.tag = 0,
	},
	{
		/* if analog and digital are currently off, anything should go,
		 * so this entry describes everything we can do... */
		.formats = SNDRV_PCM_FMTBIT_S8 |
			   SNDRV_PCM_FMTBIT_S16_BE |
			   SNDRV_PCM_FMTBIT_S24_BE
#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
			   | SNDRV_PCM_FMTBIT_COMPRESSED_16BE
#endif
		,
		.rates = SNDRV_PCM_RATE_8000_96000,
		.tag = 0,
	},
	{
		/* analog output */
		.formats = SNDRV_PCM_FMTBIT_S8 |
			   SNDRV_PCM_FMTBIT_S16_BE |
			   SNDRV_PCM_FMTBIT_S24_BE,
		.rates = SNDRV_PCM_RATE_8000_96000,
		.transfer_in = 0,
		.must_be_clock_source = 0,
		.tag = 1,
	},
	{
		/* digital pcm output, also possible for analog out */
		.formats = SNDRV_PCM_FMTBIT_S8 |
			   SNDRV_PCM_FMTBIT_S16_BE |
			   SNDRV_PCM_FMTBIT_S24_BE,
		.rates = SNDRV_PCM_RATE_32000 |
			 SNDRV_PCM_RATE_44100 |
			 SNDRV_PCM_RATE_48000,
		.transfer_in = 0,
		.must_be_clock_source = 0,
		.tag = 2,
	},
#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
Once alsa gets supports for this kind of thing we can add it...
	{
		/* digital compressed output */
		.formats =  SNDRV_PCM_FMTBIT_COMPRESSED_16BE,
		.rates = SNDRV_PCM_RATE_32000 |
			 SNDRV_PCM_RATE_44100 |
			 SNDRV_PCM_RATE_48000,
		.tag = 2,
	},
#endif
	{}
};

static int onyx_usable(struct codec_info_item *cii,
		       struct transfer_info *ti,
		       struct transfer_info *out)
{
	u8 v;
	struct onyx *onyx = cii->codec_data;
	int spdif_enabled, analog_enabled;

	mutex_lock(&onyx->mutex);
	onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
	spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
	onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
	analog_enabled = 
		(v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
		 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
	mutex_unlock(&onyx->mutex);

	switch (ti->tag) {
	case 0: return 1;
	case 1:	return analog_enabled;
	case 2: return spdif_enabled;
	}
	return 1;
}

static int onyx_prepare(struct codec_info_item *cii,
			struct bus_info *bi,
			struct snd_pcm_substream *substream)
{
	u8 v;
	struct onyx *onyx = cii->codec_data;
	int err = -EBUSY;

	mutex_lock(&onyx->mutex);

#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
	if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
		/* mute and lock analog output */
		onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
		if (onyx_write_register(onyx
					ONYX_REG_DAC_CONTROL,
					v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
			goto out_unlock;
		onyx->analog_locked = 1;
		err = 0;
		goto out_unlock;
	}
#endif
	switch (substream->runtime->rate) {
	case 32000:
	case 44100:
	case 48000:
		/* these rates are ok for all outputs */
		/* FIXME: program spdif channel control bits here so that
		 *	  userspace doesn't have to if it only plays pcm! */
		err = 0;
		goto out_unlock;
	default:
		/* got some rate that the digital output can't do,
		 * so disable and lock it */
		onyx_read_register(cii->codec_data, ONYX_REG_DIG_INFO4, &v);
		if (onyx_write_register(onyx,
					ONYX_REG_DIG_INFO4,
					v & ~ONYX_SPDIF_ENABLE))
			goto out_unlock;
		onyx->spdif_locked = 1;
		err = 0;
		goto out_unlock;
	}

 out_unlock:
	mutex_unlock(&onyx->mutex);

	return err;
}

static int onyx_open(struct codec_info_item *cii,
		     struct snd_pcm_substream *substream)
{
	struct onyx *onyx = cii->codec_data;

	mutex_lock(&onyx->mutex);
	onyx->open_count++;
	mutex_unlock(&onyx->mutex);

	return 0;
}

static int onyx_close(struct codec_info_item *cii,
		      struct snd_pcm_substream *substream)
{
	struct onyx *onyx = cii->codec_data;

	mutex_lock(&onyx->mutex);
	onyx->open_count--;
	if (!onyx->open_count)
		onyx->spdif_locked = onyx->analog_locked = 0;
	mutex_unlock(&onyx->mutex);

	return 0;
}

static int onyx_switch_clock(struct codec_info_item *cii,
			     enum clock_switch what)
{
	struct onyx *onyx = cii->codec_data;

	mutex_lock(&onyx->mutex);
	/* this *MUST* be more elaborate later... */
	switch (what) {
	case CLOCK_SWITCH_PREPARE_SLAVE:
		onyx->codec.gpio->methods->all_amps_off(onyx->codec.gpio);
		break;
	case CLOCK_SWITCH_SLAVE:
		onyx->codec.gpio->methods->all_amps_restore(onyx->codec.gpio);
		break;
	default: /* silence warning */
		break;
	}
	mutex_unlock(&onyx->mutex);

	return 0;
}

#ifdef CONFIG_PM

static int onyx_suspend(struct codec_info_item *cii, pm_message_t state)
{
	struct onyx *onyx = cii->codec_data;
	u8 v;
	int err = -ENXIO;

	mutex_lock(&onyx->mutex);
	if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
		goto out_unlock;
	onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV);
	/* Apple does a sleep here but the datasheet says to do it on resume */
	err = 0;
 out_unlock:
	mutex_unlock(&onyx->mutex);

	return err;
}

static int onyx_resume(struct codec_info_item *cii)
{
	struct onyx *onyx = cii->codec_data;
	u8 v;
	int err = -ENXIO;

	mutex_lock(&onyx->mutex);

	/* reset codec */
	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
	msleep(1);
	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
	msleep(1);
	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
	msleep(1);

	/* take codec out of suspend (if it still is after reset) */
	if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
		goto out_unlock;
	onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV));
	/* FIXME: should divide by sample rate, but 8k is the lowest we go */
	msleep(2205000/8000);
	/* reset all values */
	onyx_register_init(onyx);
	err = 0;
 out_unlock:
	mutex_unlock(&onyx->mutex);

	return err;
}

#endif /* CONFIG_PM */

static struct codec_info onyx_codec_info = {
	.transfers = onyx_transfers,
	.sysclock_factor = 256,
	.bus_factor = 64,
	.owner = THIS_MODULE,
	.usable = onyx_usable,
	.prepare = onyx_prepare,
	.open = onyx_open,
	.close = onyx_close,
	.switch_clock = onyx_switch_clock,
#ifdef CONFIG_PM
	.suspend = onyx_suspend,
	.resume = onyx_resume,
#endif
};

static int onyx_init_codec(struct aoa_codec *codec)
{
	struct onyx *onyx = codec_to_onyx(codec);
	struct snd_kcontrol *ctl;
	struct codec_info *ci = &onyx_codec_info;
	u8 v;
	int err;

	if (!onyx->codec.gpio || !onyx->codec.gpio->methods) {
		printk(KERN_ERR PFX "gpios not assigned!!\n");
		return -EINVAL;
	}

	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
	msleep(1);
	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
	msleep(1);
	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
	msleep(1);
	
	if (onyx_register_init(onyx)) {
		printk(KERN_ERR PFX "failed to initialise onyx registers\n");
		return -ENODEV;
	}

	if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, onyx, &ops)) {
		printk(KERN_ERR PFX "failed to create onyx snd device!\n");
		return -ENODEV;
	}

	/* nothing connected? what a joke! */
	if ((onyx->codec.connected & 0xF) == 0)
		return -ENOTCONN;

	/* if no inputs are present... */
	if ((onyx->codec.connected & 0xC) == 0) {
		if (!onyx->codec_info)
			onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
		if (!onyx->codec_info)
			return -ENOMEM;
		ci = onyx->codec_info;
		*ci = onyx_codec_info;
		ci->transfers++;
	}

	/* if no outputs are present... */
	if ((onyx->codec.connected & 3) == 0) {
		if (!onyx->codec_info)
			onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
		if (!onyx->codec_info)
			return -ENOMEM;
		ci = onyx->codec_info;
		/* this is fine as there have to be inputs
		 * if we end up in this part of the code */
		*ci = onyx_codec_info;
		ci->transfers[1].formats = 0;
	}

	if (onyx->codec.soundbus_dev->attach_codec(onyx->codec.soundbus_dev,
						   aoa_get_card(),
						   ci, onyx)) {
		printk(KERN_ERR PFX "error creating onyx pcm\n");
		return -ENODEV;
	}
#define ADDCTL(n)							\
	do {								\
		ctl = snd_ctl_new1(&n, onyx);				\
		if (ctl) {						\
			ctl->id.device =				\
				onyx->codec.soundbus_dev->pcm->device;	\
			err = aoa_snd_ctl_add(ctl);			\
			if (err)					\
				goto error;				\
		}							\
	} while (0)

	if (onyx->codec.soundbus_dev->pcm) {
		/* give the user appropriate controls
		 * depending on what inputs are connected */
		if ((onyx->codec.connected & 0xC) == 0xC)
			ADDCTL(capture_source_control);
		else if (onyx->codec.connected & 4)
			onyx_set_capture_source(onyx, 0);
		else
			onyx_set_capture_source(onyx, 1);
		if (onyx->codec.connected & 0xC)
			ADDCTL(inputgain_control);

		/* depending on what output is connected,
		 * give the user appropriate controls */
		if (onyx->codec.connected & 1) {
			ADDCTL(volume_control);
			ADDCTL(mute_control);
			ADDCTL(ovr1_control);
			ADDCTL(flt0_control);
			ADDCTL(hpf_control);
			ADDCTL(dm12_control);
			/* spdif control defaults to off */
		}
		if (onyx->codec.connected & 2) {
			ADDCTL(onyx_spdif_mask);
			ADDCTL(onyx_spdif_ctrl);
		}
		if ((onyx->codec.connected & 3) == 3)
			ADDCTL(spdif_control);
		/* if only S/PDIF is connected, enable it unconditionally */
		if ((onyx->codec.connected & 3) == 2) {
			onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
			v |= ONYX_SPDIF_ENABLE;
			onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
		}
	}
#undef ADDCTL
	printk(KERN_INFO PFX "attached to onyx codec via i2c\n");

	return 0;
 error:
	onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
	snd_device_free(aoa_get_card(), onyx);
	return err;
}

static void onyx_exit_codec(struct aoa_codec *codec)
{
	struct onyx *onyx = codec_to_onyx(codec);

	if (!onyx->codec.soundbus_dev) {
		printk(KERN_ERR PFX "onyx_exit_codec called without soundbus_dev!\n");
		return;
	}
	onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
}

static struct i2c_driver onyx_driver;

static int onyx_create(struct i2c_adapter *adapter,
		       struct device_node *node,
		       int addr)
{
	struct onyx *onyx;
	u8 dummy;

	onyx = kzalloc(sizeof(struct onyx), GFP_KERNEL);

	if (!onyx)
		return -ENOMEM;

	mutex_init(&onyx->mutex);
	onyx->i2c.driver = &onyx_driver;
	onyx->i2c.adapter = adapter;
	onyx->i2c.addr = addr & 0x7f;
	strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE);

	if (i2c_attach_client(&onyx->i2c)) {
		printk(KERN_ERR PFX "failed to attach to i2c\n");
		goto fail;
	}

	/* we try to read from register ONYX_REG_CONTROL
	 * to check if the codec is present */
	if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) {
		i2c_detach_client(&onyx->i2c);
		printk(KERN_ERR PFX "failed to read control register\n");
		goto fail;
	}

	strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
	onyx->codec.owner = THIS_MODULE;
	onyx->codec.init = onyx_init_codec;
	onyx->codec.exit = onyx_exit_codec;
	onyx->codec.node = of_node_get(node);

	if (aoa_codec_register(&onyx->codec)) {
		i2c_detach_client(&onyx->i2c);
		goto fail;
	}
	printk(KERN_DEBUG PFX "created and attached onyx instance\n");
	return 0;
 fail:
	kfree(onyx);
	return -EINVAL;
}

static int onyx_i2c_attach(struct i2c_adapter *adapter)
{
	struct device_node *busnode, *dev = NULL;
	struct pmac_i2c_bus *bus;

	bus = pmac_i2c_adapter_to_bus(adapter);
	if (bus == NULL)
		return -ENODEV;
	busnode = pmac_i2c_get_bus_node(bus);

	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
		if (of_device_is_compatible(dev, "pcm3052")) {
			const u32 *addr;
			printk(KERN_DEBUG PFX "found pcm3052\n");
			addr = of_get_property(dev, "reg", NULL);
			if (!addr)
				return -ENODEV;
			return onyx_create(adapter, dev, (*addr)>>1);
		}
	}

	/* if that didn't work, try desperate mode for older
	 * machines that have stuff missing from the device tree */
	
	if (!of_device_is_compatible(busnode, "k2-i2c"))
		return -ENODEV;

	printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
	/* probe both possible addresses for the onyx chip */
	if (onyx_create(adapter, NULL, 0x46) == 0)
		return 0;
	return onyx_create(adapter, NULL, 0x47);
}

static int onyx_i2c_detach(struct i2c_client *client)
{
	struct onyx *onyx = container_of(client, struct onyx, i2c);
	int err;

	if ((err = i2c_detach_client(client)))
		return err;
	aoa_codec_unregister(&onyx->codec);
	of_node_put(onyx->codec.node);
	if (onyx->codec_info)
		kfree(onyx->codec_info);
	kfree(onyx);
	return 0;
}

static struct i2c_driver onyx_driver = {
	.driver = {
		.name = "aoa_codec_onyx",
		.owner = THIS_MODULE,
	},
	.attach_adapter = onyx_i2c_attach,
	.detach_client = onyx_i2c_detach,
};

static int __init onyx_init(void)
{
	return i2c_add_driver(&onyx_driver);
}

static void __exit onyx_exit(void)
{
	i2c_del_driver(&onyx_driver);
}

module_init(onyx_init);
module_exit(onyx_exit);
