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

	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;

	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;

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

	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;

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

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

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

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

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

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

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

	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", 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)) {
		goto fail;
	}
	printk(KERN_DEBUG PFX "created and attached onyx instance\n");
	return 0;
 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", 0 },
	{ }
};
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);
