// SPDX-License-Identifier: GPL-2.0-only
/*
 * Regmap support for HD-audio verbs
 *
 * A virtual register is translated to one or more hda verbs for write,
 * vice versa for read.
 *
 * A few limitations:
 * - Provided for not all verbs but only subset standard non-volatile verbs.
 * - For reading, only AC_VERB_GET_* variants can be used.
 * - For writing, mapped to the *corresponding* AC_VERB_SET_* variants,
 *   so can't handle asymmetric verbs for read and write
 */

#include <linux/slab.h>
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/export.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <sound/core.h>
#include <sound/hdaudio.h>
#include <sound/hda_regmap.h>
#include "local.h"

static int codec_pm_lock(struct hdac_device *codec)
{
	return snd_hdac_keep_power_up(codec);
}

static void codec_pm_unlock(struct hdac_device *codec, int lock)
{
	if (lock == 1)
		snd_hdac_power_down_pm(codec);
}

#define get_verb(reg)	(((reg) >> 8) & 0xfff)

static bool hda_volatile_reg(struct device *dev, unsigned int reg)
{
	struct hdac_device *codec = dev_to_hdac_dev(dev);
	unsigned int verb = get_verb(reg);

	switch (verb) {
	case AC_VERB_GET_PROC_COEF:
		return !codec->cache_coef;
	case AC_VERB_GET_COEF_INDEX:
	case AC_VERB_GET_PROC_STATE:
	case AC_VERB_GET_POWER_STATE:
	case AC_VERB_GET_PIN_SENSE:
	case AC_VERB_GET_HDMI_DIP_SIZE:
	case AC_VERB_GET_HDMI_ELDD:
	case AC_VERB_GET_HDMI_DIP_INDEX:
	case AC_VERB_GET_HDMI_DIP_DATA:
	case AC_VERB_GET_HDMI_DIP_XMIT:
	case AC_VERB_GET_HDMI_CP_CTRL:
	case AC_VERB_GET_HDMI_CHAN_SLOT:
	case AC_VERB_GET_DEVICE_SEL:
	case AC_VERB_GET_DEVICE_LIST:	/* read-only volatile */
		return true;
	}

	return false;
}

static bool hda_writeable_reg(struct device *dev, unsigned int reg)
{
	struct hdac_device *codec = dev_to_hdac_dev(dev);
	unsigned int verb = get_verb(reg);
	const unsigned int *v;
	int i;

	snd_array_for_each(&codec->vendor_verbs, i, v) {
		if (verb == *v)
			return true;
	}

	if (codec->caps_overwriting)
		return true;

	switch (verb & 0xf00) {
	case AC_VERB_GET_STREAM_FORMAT:
	case AC_VERB_GET_AMP_GAIN_MUTE:
		return true;
	case AC_VERB_GET_PROC_COEF:
		return codec->cache_coef;
	case 0xf00:
		break;
	default:
		return false;
	}

	switch (verb) {
	case AC_VERB_GET_CONNECT_SEL:
	case AC_VERB_GET_SDI_SELECT:
	case AC_VERB_GET_PIN_WIDGET_CONTROL:
	case AC_VERB_GET_UNSOLICITED_RESPONSE: /* only as SET_UNSOLICITED_ENABLE */
	case AC_VERB_GET_BEEP_CONTROL:
	case AC_VERB_GET_EAPD_BTLENABLE:
	case AC_VERB_GET_DIGI_CONVERT_1:
	case AC_VERB_GET_DIGI_CONVERT_2: /* only for beep control */
	case AC_VERB_GET_VOLUME_KNOB_CONTROL:
	case AC_VERB_GET_GPIO_MASK:
	case AC_VERB_GET_GPIO_DIRECTION:
	case AC_VERB_GET_GPIO_DATA: /* not for volatile read */
	case AC_VERB_GET_GPIO_WAKE_MASK:
	case AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK:
	case AC_VERB_GET_GPIO_STICKY_MASK:
		return true;
	}

	return false;
}

static bool hda_readable_reg(struct device *dev, unsigned int reg)
{
	struct hdac_device *codec = dev_to_hdac_dev(dev);
	unsigned int verb = get_verb(reg);

	if (codec->caps_overwriting)
		return true;

	switch (verb) {
	case AC_VERB_PARAMETERS:
	case AC_VERB_GET_CONNECT_LIST:
	case AC_VERB_GET_SUBSYSTEM_ID:
		return true;
	/* below are basically writable, but disabled for reducing unnecessary
	 * writes at sync
	 */
	case AC_VERB_GET_CONFIG_DEFAULT: /* usually just read */
	case AC_VERB_GET_CONV: /* managed in PCM code */
	case AC_VERB_GET_CVT_CHAN_COUNT: /* managed in HDMI CA code */
		return true;
	}

	return hda_writeable_reg(dev, reg);
}

/*
 * Stereo amp pseudo register:
 * for making easier to handle the stereo volume control, we provide a
 * fake register to deal both left and right channels by a single
 * (pseudo) register access.  A verb consisting of SET_AMP_GAIN with
 * *both* SET_LEFT and SET_RIGHT bits takes a 16bit value, the lower 8bit
 * for the left and the upper 8bit for the right channel.
 */
static bool is_stereo_amp_verb(unsigned int reg)
{
	if (((reg >> 8) & 0x700) != AC_VERB_SET_AMP_GAIN_MUTE)
		return false;
	return (reg & (AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT)) ==
		(AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT);
}

/* read a pseudo stereo amp register (16bit left+right) */
static int hda_reg_read_stereo_amp(struct hdac_device *codec,
				   unsigned int reg, unsigned int *val)
{
	unsigned int left, right;
	int err;

	reg &= ~(AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT);
	err = snd_hdac_exec_verb(codec, reg | AC_AMP_GET_LEFT, 0, &left);
	if (err < 0)
		return err;
	err = snd_hdac_exec_verb(codec, reg | AC_AMP_GET_RIGHT, 0, &right);
	if (err < 0)
		return err;
	*val = left | (right << 8);
	return 0;
}

/* write a pseudo stereo amp register (16bit left+right) */
static int hda_reg_write_stereo_amp(struct hdac_device *codec,
				    unsigned int reg, unsigned int val)
{
	int err;
	unsigned int verb, left, right;

	verb = AC_VERB_SET_AMP_GAIN_MUTE << 8;
	if (reg & AC_AMP_GET_OUTPUT)
		verb |= AC_AMP_SET_OUTPUT;
	else
		verb |= AC_AMP_SET_INPUT | ((reg & 0xf) << 8);
	reg = (reg & ~0xfffff) | verb;

	left = val & 0xff;
	right = (val >> 8) & 0xff;
	if (left == right) {
		reg |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
		return snd_hdac_exec_verb(codec, reg | left, 0, NULL);
	}

	err = snd_hdac_exec_verb(codec, reg | AC_AMP_SET_LEFT | left, 0, NULL);
	if (err < 0)
		return err;
	err = snd_hdac_exec_verb(codec, reg | AC_AMP_SET_RIGHT | right, 0, NULL);
	if (err < 0)
		return err;
	return 0;
}

/* read a pseudo coef register (16bit) */
static int hda_reg_read_coef(struct hdac_device *codec, unsigned int reg,
			     unsigned int *val)
{
	unsigned int verb;
	int err;

	if (!codec->cache_coef)
		return -EINVAL;
	/* LSB 8bit = coef index */
	verb = (reg & ~0xfff00) | (AC_VERB_SET_COEF_INDEX << 8);
	err = snd_hdac_exec_verb(codec, verb, 0, NULL);
	if (err < 0)
		return err;
	verb = (reg & ~0xfffff) | (AC_VERB_GET_COEF_INDEX << 8);
	return snd_hdac_exec_verb(codec, verb, 0, val);
}

/* write a pseudo coef register (16bit) */
static int hda_reg_write_coef(struct hdac_device *codec, unsigned int reg,
			      unsigned int val)
{
	unsigned int verb;
	int err;

	if (!codec->cache_coef)
		return -EINVAL;
	/* LSB 8bit = coef index */
	verb = (reg & ~0xfff00) | (AC_VERB_SET_COEF_INDEX << 8);
	err = snd_hdac_exec_verb(codec, verb, 0, NULL);
	if (err < 0)
		return err;
	verb = (reg & ~0xfffff) | (AC_VERB_GET_COEF_INDEX << 8) |
		(val & 0xffff);
	return snd_hdac_exec_verb(codec, verb, 0, NULL);
}

static int hda_reg_read(void *context, unsigned int reg, unsigned int *val)
{
	struct hdac_device *codec = context;
	int verb = get_verb(reg);
	int err;
	int pm_lock = 0;

	if (verb != AC_VERB_GET_POWER_STATE) {
		pm_lock = codec_pm_lock(codec);
		if (pm_lock < 0)
			return -EAGAIN;
	}
	reg |= (codec->addr << 28);
	if (is_stereo_amp_verb(reg)) {
		err = hda_reg_read_stereo_amp(codec, reg, val);
		goto out;
	}
	if (verb == AC_VERB_GET_PROC_COEF) {
		err = hda_reg_read_coef(codec, reg, val);
		goto out;
	}
	if ((verb & 0x700) == AC_VERB_SET_AMP_GAIN_MUTE)
		reg &= ~AC_AMP_FAKE_MUTE;

	err = snd_hdac_exec_verb(codec, reg, 0, val);
	if (err < 0)
		goto out;
	/* special handling for asymmetric reads */
	if (verb == AC_VERB_GET_POWER_STATE) {
		if (*val & AC_PWRST_ERROR)
			*val = -1;
		else /* take only the actual state */
			*val = (*val >> 4) & 0x0f;
	}
 out:
	codec_pm_unlock(codec, pm_lock);
	return err;
}

static int hda_reg_write(void *context, unsigned int reg, unsigned int val)
{
	struct hdac_device *codec = context;
	unsigned int verb;
	int i, bytes, err;
	int pm_lock = 0;

	if (codec->caps_overwriting)
		return 0;

	reg &= ~0x00080000U; /* drop GET bit */
	reg |= (codec->addr << 28);
	verb = get_verb(reg);

	if (verb != AC_VERB_SET_POWER_STATE) {
		pm_lock = codec_pm_lock(codec);
		if (pm_lock < 0)
			return codec->lazy_cache ? 0 : -EAGAIN;
	}

	if (is_stereo_amp_verb(reg)) {
		err = hda_reg_write_stereo_amp(codec, reg, val);
		goto out;
	}

	if (verb == AC_VERB_SET_PROC_COEF) {
		err = hda_reg_write_coef(codec, reg, val);
		goto out;
	}

	switch (verb & 0xf00) {
	case AC_VERB_SET_AMP_GAIN_MUTE:
		if ((reg & AC_AMP_FAKE_MUTE) && (val & AC_AMP_MUTE))
			val = 0;
		verb = AC_VERB_SET_AMP_GAIN_MUTE;
		if (reg & AC_AMP_GET_LEFT)
			verb |= AC_AMP_SET_LEFT >> 8;
		else
			verb |= AC_AMP_SET_RIGHT >> 8;
		if (reg & AC_AMP_GET_OUTPUT) {
			verb |= AC_AMP_SET_OUTPUT >> 8;
		} else {
			verb |= AC_AMP_SET_INPUT >> 8;
			verb |= reg & 0xf;
		}
		break;
	}

	switch (verb) {
	case AC_VERB_SET_DIGI_CONVERT_1:
		bytes = 2;
		break;
	case AC_VERB_SET_CONFIG_DEFAULT_BYTES_0:
		bytes = 4;
		break;
	default:
		bytes = 1;
		break;
	}

	for (i = 0; i < bytes; i++) {
		reg &= ~0xfffff;
		reg |= (verb + i) << 8 | ((val >> (8 * i)) & 0xff);
		err = snd_hdac_exec_verb(codec, reg, 0, NULL);
		if (err < 0)
			goto out;
	}

 out:
	codec_pm_unlock(codec, pm_lock);
	return err;
}

static const struct regmap_config hda_regmap_cfg = {
	.name = "hdaudio",
	.reg_bits = 32,
	.val_bits = 32,
	.max_register = 0xfffffff,
	.writeable_reg = hda_writeable_reg,
	.readable_reg = hda_readable_reg,
	.volatile_reg = hda_volatile_reg,
	.cache_type = REGCACHE_RBTREE,
	.reg_read = hda_reg_read,
	.reg_write = hda_reg_write,
	.use_single_read = true,
	.use_single_write = true,
	.disable_locking = true,
};

/**
 * snd_hdac_regmap_init - Initialize regmap for HDA register accesses
 * @codec: the codec object
 *
 * Returns zero for success or a negative error code.
 */
int snd_hdac_regmap_init(struct hdac_device *codec)
{
	struct regmap *regmap;

	regmap = regmap_init(&codec->dev, NULL, codec, &hda_regmap_cfg);
	if (IS_ERR(regmap))
		return PTR_ERR(regmap);
	codec->regmap = regmap;
	snd_array_init(&codec->vendor_verbs, sizeof(unsigned int), 8);
	return 0;
}
EXPORT_SYMBOL_GPL(snd_hdac_regmap_init);

/**
 * snd_hdac_regmap_init - Release the regmap from HDA codec
 * @codec: the codec object
 */
void snd_hdac_regmap_exit(struct hdac_device *codec)
{
	if (codec->regmap) {
		regmap_exit(codec->regmap);
		codec->regmap = NULL;
		snd_array_free(&codec->vendor_verbs);
	}
}
EXPORT_SYMBOL_GPL(snd_hdac_regmap_exit);

/**
 * snd_hdac_regmap_add_vendor_verb - add a vendor-specific verb to regmap
 * @codec: the codec object
 * @verb: verb to allow accessing via regmap
 *
 * Returns zero for success or a negative error code.
 */
int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
				    unsigned int verb)
{
	unsigned int *p = snd_array_new(&codec->vendor_verbs);

	if (!p)
		return -ENOMEM;
	*p = verb | 0x800; /* set GET bit */
	return 0;
}
EXPORT_SYMBOL_GPL(snd_hdac_regmap_add_vendor_verb);

/*
 * helper functions
 */

/* write a pseudo-register value (w/o power sequence) */
static int reg_raw_write(struct hdac_device *codec, unsigned int reg,
			 unsigned int val)
{
	if (!codec->regmap)
		return hda_reg_write(codec, reg, val);
	else
		return regmap_write(codec->regmap, reg, val);
}

/**
 * snd_hdac_regmap_write_raw - write a pseudo register with power mgmt
 * @codec: the codec object
 * @reg: pseudo register
 * @val: value to write
 *
 * Returns zero if successful or a negative error code.
 */
int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
			      unsigned int val)
{
	int err;

	err = reg_raw_write(codec, reg, val);
	if (err == -EAGAIN) {
		err = snd_hdac_power_up_pm(codec);
		if (err >= 0)
			err = reg_raw_write(codec, reg, val);
		snd_hdac_power_down_pm(codec);
	}
	return err;
}
EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw);

static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
			unsigned int *val, bool uncached)
{
	if (uncached || !codec->regmap)
		return hda_reg_read(codec, reg, val);
	else
		return regmap_read(codec->regmap, reg, val);
}

static int __snd_hdac_regmap_read_raw(struct hdac_device *codec,
				      unsigned int reg, unsigned int *val,
				      bool uncached)
{
	int err;

	err = reg_raw_read(codec, reg, val, uncached);
	if (err == -EAGAIN) {
		err = snd_hdac_power_up_pm(codec);
		if (err >= 0)
			err = reg_raw_read(codec, reg, val, uncached);
		snd_hdac_power_down_pm(codec);
	}
	return err;
}

/**
 * snd_hdac_regmap_read_raw - read a pseudo register with power mgmt
 * @codec: the codec object
 * @reg: pseudo register
 * @val: pointer to store the read value
 *
 * Returns zero if successful or a negative error code.
 */
int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
			     unsigned int *val)
{
	return __snd_hdac_regmap_read_raw(codec, reg, val, false);
}
EXPORT_SYMBOL_GPL(snd_hdac_regmap_read_raw);

/* Works like snd_hdac_regmap_read_raw(), but this doesn't read from the
 * cache but always via hda verbs.
 */
int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec,
				      unsigned int reg, unsigned int *val)
{
	return __snd_hdac_regmap_read_raw(codec, reg, val, true);
}

/**
 * snd_hdac_regmap_update_raw - update a pseudo register with power mgmt
 * @codec: the codec object
 * @reg: pseudo register
 * @mask: bit mask to udpate
 * @val: value to update
 *
 * Returns zero if successful or a negative error code.
 */
int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
			       unsigned int mask, unsigned int val)
{
	unsigned int orig;
	int err;

	val &= mask;
	err = snd_hdac_regmap_read_raw(codec, reg, &orig);
	if (err < 0)
		return err;
	val |= orig & ~mask;
	if (val == orig)
		return 0;
	err = snd_hdac_regmap_write_raw(codec, reg, val);
	if (err < 0)
		return err;
	return 1;
}
EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw);
