// SPDX-License-Identifier: GPL-2.0-only
/*
 * Apple Onboard Audio driver for Onyx codec
 *
 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
 *
 * 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>
#include <linux/of.h>
#include <linux/slab.h>
#include <sound/asoundef.h>
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");

#include "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) {
		*value = 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 const 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;

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

	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;

	if (ucontrol->value.integer.value[0] < -128 + VOLUME_RANGE_SHIFT ||
	    ucontrol->value.integer.value[0] > -1 + VOLUME_RANGE_SHIFT)
		return -EINVAL;
	if (ucontrol->value.integer.value[1] < -128 + VOLUME_RANGE_SHIFT ||
	    ucontrol->value.integer.value[1] > -1 + VOLUME_RANGE_SHIFT)
		return -EINVAL;

	guard(mutex)(&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])
		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);

	return 1;
}

static const 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;

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

	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;

	if (ucontrol->value.integer.value[0] < 3 + INPUTGAIN_RANGE_SHIFT ||
	    ucontrol->value.integer.value[0] > 28 + INPUTGAIN_RANGE_SHIFT)
		return -EINVAL;
	guard(mutex)(&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);

	return n != v;
}

static const 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 const char * const texts[] = { "Line-In", "Microphone" };

	return snd_ctl_enum_info(uinfo, 1, 2, texts);
}

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;

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

	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;

	guard(mutex)(&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);
}

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

static const 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,
};

#define onyx_snd_mute_info	snd_ctl_boolean_stereo_info

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;

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

	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;

	guard(mutex)(&onyx->mutex);
	if (onyx->analog_locked)
		return -EBUSY;

	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);

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

static const 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,
};


#define onyx_snd_single_bit_info	snd_ctl_boolean_mono_info

#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;

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

	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;

	guard(mutex)(&onyx->mutex);
	if (spdiflock && onyx->spdif_locked) {
		/* even if alsamixer doesn't care.. */
		return -EBUSY;
	}
	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);

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

#define SINGLE_BIT(n, type, description, address, mask, flags)	 	\
static const 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 const 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;

	guard(mutex)(&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;

	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;

	guard(mutex)(&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);

	return 1;
}

static int onyx_set_spdif_pcm_rate(struct onyx *onyx, unsigned int rate)
{
	u8 dig_info3, fs;

	switch (rate) {
	case 32000:
		fs = IEC958_AES3_CON_FS_32000;
		break;
	case 44100:
		fs = IEC958_AES3_CON_FS_44100;
		break;
	case 48000:
		fs = IEC958_AES3_CON_FS_48000;
		break;
	default:
		return -EINVAL;
	}

	if (onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &dig_info3))
		return -EBUSY;
	dig_info3 = (dig_info3 & ~IEC958_AES3_CON_FS) | fs;
	if (onyx_write_register(onyx, ONYX_REG_DIG_INFO3, dig_info3))
		return -EBUSY;

	return 0;
}

static const struct snd_kcontrol_new onyx_spdif_ctrl = {
	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE |
			SNDRV_CTL_ELEM_ACCESS_VOLATILE,
	.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 const 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 const 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;

	guard(mutex)(&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);

	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;

	guard(mutex)(&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))
			return -EBUSY;
		onyx->analog_locked = 1;
		return 0;
	}
#endif
	switch (substream->runtime->rate) {
	case 32000:
	case 44100:
	case 48000:
		if (onyx->codec.connected & 2)
			return onyx_set_spdif_pcm_rate(onyx,
						       substream->runtime->rate);
		return 0;
	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))
			return -EBUSY;
		onyx->spdif_locked = 1;
		return 0;
	}

	return -EBUSY;
}

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

	guard(mutex)(&onyx->mutex);
	onyx->open_count++;

	return 0;
}

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

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

	return 0;
}

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

	guard(mutex)(&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;
	}

	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;

	guard(mutex)(&onyx->mutex);
	if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
		return -ENXIO;
	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 */
	return 0;
}

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

	guard(mutex)(&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))
		return -ENXIO;
	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);
	return 0;
}

#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_CODEC, 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_obj(struct codec_info);
		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_obj(struct codec_info);
		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 int onyx_i2c_probe(struct i2c_client *client)
{
	struct device_node *node = client->dev.of_node;
	struct onyx *onyx;
	u8 dummy;

	onyx = kzalloc_obj(struct onyx);

	if (!onyx)
		return -ENOMEM;

	mutex_init(&onyx->mutex);
	onyx->i2c = client;
	i2c_set_clientdata(client, onyx);

	/* 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) {
		printk(KERN_ERR PFX "failed to read control register\n");
		goto fail;
	}

	strscpy(onyx->codec.name, "onyx");
	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)) {
		goto fail_put;
	}
	printk(KERN_DEBUG PFX "created and attached onyx instance\n");
	return 0;
 fail_put:
	of_node_put(onyx->codec.node);
 fail:
	kfree(onyx);
	return -ENODEV;
}

static void onyx_i2c_remove(struct i2c_client *client)
{
	struct onyx *onyx = i2c_get_clientdata(client);

	aoa_codec_unregister(&onyx->codec);
	of_node_put(onyx->codec.node);
	kfree(onyx->codec_info);
	kfree(onyx);
}

static const struct i2c_device_id onyx_i2c_id[] = {
	{ "MAC,pcm3052" },
	{ }
};
MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);

static struct i2c_driver onyx_driver = {
	.driver = {
		.name = "aoa_codec_onyx",
	},
	.probe = onyx_i2c_probe,
	.remove = onyx_i2c_remove,
	.id_table = onyx_i2c_id,
};

module_i2c_driver(onyx_driver);
