// SPDX-License-Identifier: GPL-2.0-only
//
// Common code for Cirrus Logic Smart Amplifiers
//
// Copyright (C) 2024 Cirrus Logic, Inc. and
//               Cirrus Logic International Semiconductor Ltd.

#include <asm/byteorder.h>
#include <kunit/static_stub.h>
#include <linux/debugfs.h>
#include <linux/dev_printk.h>
#include <linux/efi.h>
#include <linux/firmware/cirrus/cs_dsp.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/overflow.h>
#include <linux/pci_ids.h>
#include <linux/slab.h>
#include <linux/timekeeping.h>
#include <linux/types.h>
#include <sound/cs-amp-lib.h>

#define CIRRUS_LOGIC_CALIBRATION_EFI_NAME L"CirrusSmartAmpCalibrationData"
#define CIRRUS_LOGIC_CALIBRATION_EFI_GUID \
	EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, 0x5a, 0xa3, 0x5d, 0xb3)

#define LENOVO_SPEAKER_ID_EFI_NAME L"SdwSpeaker"
#define LENOVO_SPEAKER_ID_EFI_GUID \
	EFI_GUID(0x48df970e, 0xe27f, 0x460a, 0xb5, 0x86, 0x77, 0x19, 0x80, 0x1d, 0x92, 0x82)

#define HP_SPEAKER_ID_EFI_NAME L"HPSpeakerID"
#define HP_SPEAKER_ID_EFI_GUID \
	EFI_GUID(0xc49593a4, 0xd099, 0x419b, 0xa2, 0xc3, 0x67, 0xe9, 0x80, 0xe6, 0x1d, 0x1e)

#define HP_CALIBRATION_EFI_NAME L"SmartAmpCalibrationData"
#define HP_CALIBRATION_EFI_GUID \
	EFI_GUID(0x53559579, 0x8753, 0x4f5c, 0x91, 0x30, 0xe8, 0x2a, 0xcf, 0xb8, 0xd8, 0x93)

#define DELL_SSIDEXV2_EFI_NAME L"SSIDexV2Data"
#define DELL_SSIDEXV2_EFI_GUID \
	EFI_GUID(0x6a5f35df, 0x1432, 0x4656, 0x85, 0x97, 0x31, 0x04, 0xd5, 0xbf, 0x3a, 0xb0)

static const struct cs_amp_lib_cal_efivar {
	efi_char16_t *name;
	efi_guid_t *guid;
} cs_amp_lib_cal_efivars[] = {
	{
		.name = HP_CALIBRATION_EFI_NAME,
		.guid = &HP_CALIBRATION_EFI_GUID,
	},
	{
		.name = CIRRUS_LOGIC_CALIBRATION_EFI_NAME,
		.guid = &CIRRUS_LOGIC_CALIBRATION_EFI_GUID,
	},
};

#define CS_AMP_CAL_DEFAULT_EFI_ATTR			\
		(EFI_VARIABLE_NON_VOLATILE |		\
		 EFI_VARIABLE_BOOTSERVICE_ACCESS |	\
		 EFI_VARIABLE_RUNTIME_ACCESS)

/* Offset from Unix time to Windows time (100ns since 1 Jan 1601) */
#define UNIX_TIME_TO_WINDOWS_TIME_OFFSET	116444736000000000ULL

static DEFINE_MUTEX(cs_amp_efi_cal_write_lock);

static u64 cs_amp_time_now_in_windows_time(void)
{
	u64 time_in_100ns = div_u64(ktime_get_real_ns(), 100);

	return time_in_100ns + UNIX_TIME_TO_WINDOWS_TIME_OFFSET;
}

static int cs_amp_write_cal_coeff(struct cs_dsp *dsp,
				  const struct cirrus_amp_cal_controls *controls,
				  const char *ctl_name, u32 val)
{
	struct cs_dsp_coeff_ctl *cs_ctl;
	__be32 beval = cpu_to_be32(val);
	int ret;

	KUNIT_STATIC_STUB_REDIRECT(cs_amp_write_cal_coeff, dsp, controls, ctl_name, val);

	if (IS_REACHABLE(CONFIG_FW_CS_DSP)) {
		mutex_lock(&dsp->pwr_lock);
		cs_ctl = cs_dsp_get_ctl(dsp, ctl_name, controls->mem_region, controls->alg_id);
		ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, &beval, sizeof(beval));
		mutex_unlock(&dsp->pwr_lock);

		if (ret < 0) {
			dev_err(dsp->dev, "Failed to write to '%s': %d\n", ctl_name, ret);
			return ret;
		}

		return 0;
	}

	return -ENODEV;
}

static int cs_amp_read_cal_coeff(struct cs_dsp *dsp,
				 const struct cirrus_amp_cal_controls *controls,
				 const char *ctl_name, u32 *val)
{
	struct cs_dsp_coeff_ctl *cs_ctl;
	__be32 beval;
	int ret;

	KUNIT_STATIC_STUB_REDIRECT(cs_amp_read_cal_coeff, dsp, controls, ctl_name, val);

	if (!IS_REACHABLE(CONFIG_FW_CS_DSP))
		return -ENODEV;

	scoped_guard(mutex, &dsp->pwr_lock) {
		cs_ctl = cs_dsp_get_ctl(dsp, ctl_name, controls->mem_region, controls->alg_id);
		ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, &beval, sizeof(beval));
	}

	if (ret < 0) {
		dev_err(dsp->dev, "Failed to write to '%s': %d\n", ctl_name, ret);
		return ret;
	}

	*val = be32_to_cpu(beval);

	return 0;
}

static int _cs_amp_write_cal_coeffs(struct cs_dsp *dsp,
				    const struct cirrus_amp_cal_controls *controls,
				    const struct cirrus_amp_cal_data *data)
{
	int ret;

	dev_dbg(dsp->dev, "Calibration: Ambient=%#x, Status=%#x, CalR=%d\n",
		data->calAmbient, data->calStatus, data->calR);

	if (list_empty(&dsp->ctl_list)) {
		dev_info(dsp->dev, "Calibration disabled due to missing firmware controls\n");
		return -ENOENT;
	}

	ret = cs_amp_write_cal_coeff(dsp, controls, controls->ambient, data->calAmbient);
	if (ret)
		return ret;

	ret = cs_amp_write_cal_coeff(dsp, controls, controls->calr, data->calR);
	if (ret)
		return ret;

	ret = cs_amp_write_cal_coeff(dsp, controls, controls->status, data->calStatus);
	if (ret)
		return ret;

	ret = cs_amp_write_cal_coeff(dsp, controls, controls->checksum, data->calR + 1);
	if (ret)
		return ret;

	return 0;
}

static int _cs_amp_read_cal_coeffs(struct cs_dsp *dsp,
				    const struct cirrus_amp_cal_controls *controls,
				    struct cirrus_amp_cal_data *data)
{
	u64 time;
	u32 val;
	int ret;

	if (list_empty(&dsp->ctl_list)) {
		dev_info(dsp->dev, "Calibration disabled due to missing firmware controls\n");
		return -ENOENT;
	}

	ret = cs_amp_read_cal_coeff(dsp, controls, controls->ambient, &val);
	if (ret)
		return ret;

	data->calAmbient = (s8)val;

	ret = cs_amp_read_cal_coeff(dsp, controls, controls->calr, &val);
	if (ret)
		return ret;

	data->calR = (u16)val;

	ret = cs_amp_read_cal_coeff(dsp, controls, controls->status, &val);
	if (ret)
		return ret;

	data->calStatus = (u8)val;

	/* Fill in timestamp */
	time = cs_amp_time_now_in_windows_time();
	data->calTime[0] = (u32)time;
	data->calTime[1] = (u32)(time >> 32);

	return 0;
}

/**
 * cs_amp_write_cal_coeffs - Write calibration data to firmware controls.
 * @dsp:	Pointer to struct cs_dsp.
 * @controls:	Pointer to definition of firmware controls to be written.
 * @data:	Pointer to calibration data.
 *
 * Returns: 0 on success, else negative error value.
 */
int cs_amp_write_cal_coeffs(struct cs_dsp *dsp,
			    const struct cirrus_amp_cal_controls *controls,
			    const struct cirrus_amp_cal_data *data)
{
	if (IS_REACHABLE(CONFIG_FW_CS_DSP) || IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS))
		return _cs_amp_write_cal_coeffs(dsp, controls, data);
	else
		return -ENODEV;
}
EXPORT_SYMBOL_NS_GPL(cs_amp_write_cal_coeffs, "SND_SOC_CS_AMP_LIB");

/**
 * cs_amp_read_cal_coeffs - Read calibration data from firmware controls.
 * @dsp:	Pointer to struct cs_dsp.
 * @controls:	Pointer to definition of firmware controls to be read.
 * @data:	Pointer to calibration data where results will be written.
 *
 * Returns: 0 on success, else negative error value.
 */
int cs_amp_read_cal_coeffs(struct cs_dsp *dsp,
			   const struct cirrus_amp_cal_controls *controls,
			   struct cirrus_amp_cal_data *data)
{
	if (IS_REACHABLE(CONFIG_FW_CS_DSP) || IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS))
		return _cs_amp_read_cal_coeffs(dsp, controls, data);
	else
		return -ENODEV;
}
EXPORT_SYMBOL_NS_GPL(cs_amp_read_cal_coeffs, "SND_SOC_CS_AMP_LIB");

/**
 * cs_amp_write_ambient_temp - write value to calibration ambient temperature
 * @dsp:	Pointer to struct cs_dsp.
 * @controls:	Pointer to definition of firmware controls to be read.
 * @temp:	Temperature in degrees celcius.
 *
 * Returns: 0 on success, else negative error value.
 */
int cs_amp_write_ambient_temp(struct cs_dsp *dsp,
			      const struct cirrus_amp_cal_controls *controls,
			      u32 temp)
{
	return cs_amp_write_cal_coeff(dsp, controls, controls->ambient, temp);
}
EXPORT_SYMBOL_NS_GPL(cs_amp_write_ambient_temp, "SND_SOC_CS_AMP_LIB");

static efi_status_t cs_amp_get_efi_variable(efi_char16_t *name,
					    efi_guid_t *guid,
					    u32 *returned_attr,
					    unsigned long *size,
					    void *buf)
{
	u32 attr;

	if (!returned_attr)
		returned_attr = &attr;

	KUNIT_STATIC_STUB_REDIRECT(cs_amp_get_efi_variable, name, guid,
				   returned_attr, size, buf);

	if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
		return efi.get_variable(name, guid, returned_attr, size, buf);

	return EFI_NOT_FOUND;
}

static efi_status_t cs_amp_set_efi_variable(efi_char16_t *name,
					    efi_guid_t *guid,
					    u32 attr,
					    unsigned long size,
					    void *buf)
{
	KUNIT_STATIC_STUB_REDIRECT(cs_amp_set_efi_variable, name, guid, attr, size, buf);

	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE))
		return EFI_NOT_FOUND;

	return efi.set_variable(name, guid, attr, size, buf);
}

static int cs_amp_convert_efi_status(efi_status_t status)
{
	switch (status) {
	case EFI_SUCCESS:
		return 0;
	case EFI_NOT_FOUND:
		return -ENOENT;
	case EFI_BUFFER_TOO_SMALL:
		return -EFBIG;
	case EFI_WRITE_PROTECTED:
	case EFI_UNSUPPORTED:
	case EFI_ACCESS_DENIED:
	case EFI_SECURITY_VIOLATION:
		return -EACCES;
	default:
		return -EIO;
	}
}

static void *cs_amp_alloc_get_efi_variable(efi_char16_t *name,
					   efi_guid_t *guid,
					   u32 *returned_attr)
{
	efi_status_t status;
	unsigned long size = 0;

	status = cs_amp_get_efi_variable(name, guid, NULL, &size, NULL);
	if (status != EFI_BUFFER_TOO_SMALL)
		return ERR_PTR(cs_amp_convert_efi_status(status));

	/* Over-alloc to ensure strings are always NUL-terminated */
	void *buf __free(kfree) = kzalloc(size + 1, GFP_KERNEL);
	if (!buf)
		return ERR_PTR(-ENOMEM);

	status = cs_amp_get_efi_variable(name, guid, returned_attr, &size, buf);
	if (status != EFI_SUCCESS)
		return ERR_PTR(cs_amp_convert_efi_status(status));

	return_ptr(buf);
}

static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_buffer(struct device *dev,
							     efi_char16_t **name,
							     efi_guid_t **guid,
							     u32 *attr)
{
	struct cirrus_amp_efi_data *efi_data;
	unsigned long data_size = 0;
	u8 *data;
	efi_status_t status;
	int i, ret;

	/* Find EFI variable and get size */
	for (i = 0; i < ARRAY_SIZE(cs_amp_lib_cal_efivars); i++) {
		status = cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name,
						 cs_amp_lib_cal_efivars[i].guid,
						 attr, &data_size, NULL);
		if (status == EFI_BUFFER_TOO_SMALL)
			break;
	}

	if (status != EFI_BUFFER_TOO_SMALL)
		return ERR_PTR(-ENOENT);

	if (name)
		*name = cs_amp_lib_cal_efivars[i].name;

	if (guid)
		*guid = cs_amp_lib_cal_efivars[i].guid;

	if (data_size < sizeof(*efi_data)) {
		dev_err(dev, "EFI cal variable truncated\n");
		return ERR_PTR(-EOVERFLOW);
	}

	/* Get variable contents into buffer */
	data = kmalloc(data_size, GFP_KERNEL);
	if (!data)
		return ERR_PTR(-ENOMEM);

	status = cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name,
					 cs_amp_lib_cal_efivars[i].guid,
					 attr, &data_size, data);
	if (status != EFI_SUCCESS) {
		ret = -EINVAL;
		goto err;
	}

	efi_data = (struct cirrus_amp_efi_data *)data;
	dev_dbg(dev, "Calibration: Size=%d, Amp Count=%d\n", efi_data->size, efi_data->count);

	if ((efi_data->count > 128) ||
	    struct_size(efi_data, data, efi_data->count) > data_size) {
		dev_err(dev, "EFI cal variable truncated\n");
		ret = -EOVERFLOW;
		goto err;
	}

	/* This could be zero-filled space pre-allocated by the BIOS */
	if (efi_data->size == 0)
		efi_data->size = data_size;

	return efi_data;

err:
	kfree(data);
	dev_err(dev, "Failed to read calibration data from EFI: %d\n", ret);

	return ERR_PTR(ret);
}

static int cs_amp_set_cal_efi_buffer(struct device *dev,
				     efi_char16_t *name,
				     efi_guid_t *guid,
				     u32 attr,
				     struct cirrus_amp_efi_data *data)
{
	efi_status_t status;

	status = cs_amp_set_efi_variable(name, guid, attr,
					 struct_size(data, data, data->count), data);

	return cs_amp_convert_efi_status(status);
}

static int _cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, int amp_index,
					    struct cirrus_amp_cal_data *out_data)
{
	struct cirrus_amp_efi_data *efi_data;
	struct cirrus_amp_cal_data *cal = NULL;
	int i, ret;

	efi_data = cs_amp_get_cal_efi_buffer(dev, NULL, NULL, NULL);
	if (IS_ERR(efi_data))
		return PTR_ERR(efi_data);

	if (target_uid) {
		for (i = 0; i < efi_data->count; ++i) {
			u64 cal_target = cs_amp_cal_target_u64(&efi_data->data[i]);

			/* Skip empty entries */
			if (!efi_data->data[i].calTime[0] && !efi_data->data[i].calTime[1])
				continue;

			/* Skip entries with unpopulated silicon ID */
			if (cal_target == 0)
				continue;

			if (cal_target == target_uid) {
				cal = &efi_data->data[i];
				break;
			}
		}
	}

	if (!cal && (amp_index >= 0) && (amp_index < efi_data->count) &&
	    (efi_data->data[amp_index].calTime[0] || efi_data->data[amp_index].calTime[1])) {
		u64 cal_target = cs_amp_cal_target_u64(&efi_data->data[amp_index]);

		/*
		 * Treat unpopulated cal_target as a wildcard.
		 * If target_uid != 0 we can only get here if cal_target == 0
		 * or it didn't match any cal_target value.
		 * If target_uid == 0 it is a wildcard.
		 */
		if ((cal_target == 0) || (target_uid == 0))
			cal = &efi_data->data[amp_index];
		else
			dev_warn(dev, "Calibration entry %d does not match silicon ID", amp_index);
	}

	if (cal) {
		memcpy(out_data, cal, sizeof(*out_data));
		ret = 0;
	} else {
		dev_warn(dev, "No calibration for silicon ID %#llx\n", target_uid);
		ret = -ENOENT;
	}

	kfree(efi_data);

	return ret;
}

static int _cs_amp_set_efi_calibration_data(struct device *dev, int amp_index, int num_amps,
					    const struct cirrus_amp_cal_data *in_data)
{
	u64 cal_target = cs_amp_cal_target_u64(in_data);
	unsigned long num_entries;
	struct cirrus_amp_efi_data *data;
	efi_char16_t *name = CIRRUS_LOGIC_CALIBRATION_EFI_NAME;
	efi_guid_t *guid = &CIRRUS_LOGIC_CALIBRATION_EFI_GUID;
	u32 attr = CS_AMP_CAL_DEFAULT_EFI_ATTR;
	int i, ret;

	if (cal_target == 0)
		return -EINVAL;

	data = cs_amp_get_cal_efi_buffer(dev, &name, &guid, &attr);
	ret = PTR_ERR_OR_ZERO(data);
	if (ret == -ENOENT) {
		data = NULL;
		goto alloc_new;
	} else if (ret) {
		return ret;
	}

	/*
	 * If the EFI variable is just zero-filled reserved space the count
	 * must be set.
	 */
	if (data->count == 0)
		data->count = (data->size - struct_offset(data, data)) / sizeof(data->data[0]);

	if (amp_index < 0) {
		/* Is there already a slot for this target? */
		for (amp_index = 0; amp_index < data->count; amp_index++) {
			if (cs_amp_cal_target_u64(&data->data[amp_index]) == cal_target)
				break;
		}

		/* Else find an empty slot */
		if (amp_index >= data->count) {
			for (amp_index = 0; amp_index < data->count; amp_index++) {
				if ((data->data[amp_index].calTime[0] == 0) &&
				    (data->data[amp_index].calTime[1] == 0))
					break;
			}
		}
	} else {
		/*
		 * If the index is forced there could be another active
		 * slot with the same calTarget. So deduplicate.
		 */
		for (i = 0; i < data->count; i++) {
			if (i == amp_index)
				continue;

			if ((data->data[i].calTime[0] == 0) && (data->data[i].calTime[1] == 0))
				continue;

			if (cs_amp_cal_target_u64(&data->data[i]) == cal_target)
				memset(data->data[i].calTime, 0, sizeof(data->data[i].calTime));
		}
	}

alloc_new:
	if (amp_index < 0)
		amp_index = 0;

	num_entries = max(num_amps, amp_index + 1);
	if (!data || (data->count < num_entries)) {
		struct cirrus_amp_efi_data *new_data;
		unsigned int new_data_size = struct_size(data, data, num_entries);

		new_data = kzalloc(new_data_size, GFP_KERNEL);
		if (!new_data) {
			ret = -ENOMEM;
			goto err;
		}

		if (data) {
			memcpy(new_data, data, struct_size(data, data, data->count));
			kfree(data);
		}

		data = new_data;
		data->count = num_entries;
		data->size = new_data_size;
	}

	data->data[amp_index] = *in_data;
	ret = cs_amp_set_cal_efi_buffer(dev, name, guid, attr, data);
	if (ret)
		dev_err(dev, "Failed writing calibration to EFI: %d\n", ret);
err:
	kfree(data);

	return ret;
}

/**
 * cs_amp_get_efi_calibration_data - get an entry from calibration data in EFI.
 * @dev:	struct device of the caller.
 * @target_uid:	UID to match, or zero to ignore UID matching.
 * @amp_index:	Entry index to use, or -1 to prevent lookup by index.
 * @out_data:	struct cirrus_amp_cal_data where the entry will be copied.
 *
 * This function can perform 3 types of lookup:
 *
 * (target_uid > 0, amp_index >= 0)
 *	UID search with fallback to using the array index.
 *	Search the calibration data for a non-zero calTarget that matches
 *	target_uid, and if found return that entry. Else, if the entry at
 *	[amp_index] has calTarget == 0, return that entry. Else fail.
 *
 * (target_uid > 0, amp_index < 0)
 *	UID search only.
 *	Search the calibration data for a non-zero calTarget that matches
 *	target_uid, and if found return that entry. Else fail.
 *
 * (target_uid == 0, amp_index >= 0)
 *	Array index fetch only.
 *	Return the entry at [amp_index].
 *
 * An array lookup will be skipped if amp_index exceeds the number of
 * entries in the calibration array, and in this case the return will
 * be -ENOENT. An out-of-range amp_index does not prevent matching by
 * target_uid - it has the same effect as passing amp_index < 0.
 *
 * If the EFI data is too short to be a valid entry, or the entry count
 * in the EFI data overflows the actual length of the data, this function
 * returns -EOVERFLOW.
 *
 * Return: 0 if the entry was found, -ENOENT if no entry was found,
 *	   -EOVERFLOW if the EFI file is corrupt, else other error value.
 */
int cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, int amp_index,
				    struct cirrus_amp_cal_data *out_data)
{
	if (IS_ENABLED(CONFIG_EFI) || IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS))
		return _cs_amp_get_efi_calibration_data(dev, target_uid, amp_index, out_data);
	else
		return -ENOENT;
}
EXPORT_SYMBOL_NS_GPL(cs_amp_get_efi_calibration_data, "SND_SOC_CS_AMP_LIB");

/**
 * cs_amp_set_efi_calibration_data - write a calibration data entry to EFI.
 * @dev:	struct device of the caller.
 * @amp_index:	Entry index to use, or -1 to use any available slot.
 * @num_amps:	Maximum number of amps to reserve slots for, or -1 to ignore.
 * @in_data:	struct cirrus_amp_cal_data entry to be written to EFI.
 *
 * If a Vendor-specific variable exists it will be updated,
 * else if the Cirrus variable exists it will be updated
 * else the Cirrus variable will be created.
 *
 * If amp_index >= 0 the data will be placed in this entry of the calibration
 * data array, overwriting what was in that entry. Any other entries with the
 * same calTarget will be marked empty.
 *
 * If amp_index < 0 and in_data->calTarget matches any existing entry, that
 * entry will be overwritten. Else the first available free entry will be used,
 * extending the size of the EFI variable if there are no free entries.
 *
 * If num_amps > 0 the EFI variable will be sized to contain at least this
 * many calibration entries, with any new entries marked empty.
 *
 * Return: 0 if the write was successful, -EFBIG if space could not be made in
 *	   the EFI file to add the entry, -EACCES if it was not possible to
 *	   read or write the EFI variable.
 */
int cs_amp_set_efi_calibration_data(struct device *dev, int amp_index, int num_amps,
				    const struct cirrus_amp_cal_data *in_data)
{
	if (IS_ENABLED(CONFIG_EFI) || IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS)) {
		scoped_guard(mutex, &cs_amp_efi_cal_write_lock) {
			return _cs_amp_set_efi_calibration_data(dev, amp_index,
								num_amps, in_data);
		}
	}

	return -ENOENT;
}
EXPORT_SYMBOL_NS_GPL(cs_amp_set_efi_calibration_data, "SND_SOC_CS_AMP_LIB");

struct cs_amp_spkid_efi {
	efi_char16_t *name;
	efi_guid_t *guid;
	u8 values[2];
};

static int cs_amp_get_efi_byte_spkid(struct device *dev, const struct cs_amp_spkid_efi *info)
{
	efi_status_t status;
	unsigned long size;
	u8 spkid;
	int i, ret;

	size = sizeof(spkid);
	status = cs_amp_get_efi_variable(info->name, info->guid, NULL, &size, &spkid);
	ret = cs_amp_convert_efi_status(status);
	if (ret < 0)
		return ret;

	if (size == 0)
		return -ENOENT;

	for (i = 0; i < ARRAY_SIZE(info->values); i++) {
		if (info->values[i] == spkid)
			return i;
	}

	dev_err(dev, "EFI speaker ID bad value %#x\n", spkid);

	return -EINVAL;
}

static const struct cs_amp_spkid_efi cs_amp_spkid_byte_types[] = {
	{
		.name = LENOVO_SPEAKER_ID_EFI_NAME,
		.guid = &LENOVO_SPEAKER_ID_EFI_GUID,
		.values = { 0xd0, 0xd1 },
	},
	{
		.name = HP_SPEAKER_ID_EFI_NAME,
		.guid = &HP_SPEAKER_ID_EFI_GUID,
		.values = { 0x30, 0x31 },
	},
};

/**
 * cs_amp_get_vendor_spkid - get a speaker ID from vendor-specific storage
 * @dev:	pointer to struct device
 *
 * Known vendor-specific methods of speaker ID are checked and if one is
 * found its speaker ID value is returned.
 *
 * Return: >=0 is a valid speaker ID. -ENOENT if a vendor-specific method
 *	   was not found. -EACCES if the vendor-specific storage could not
 *	   be read. Other error values indicate that the data from the
 *	   vendor-specific storage was found but could not be understood.
 */
int cs_amp_get_vendor_spkid(struct device *dev)
{
	int i, ret;

	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE) &&
	    !IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS))
		return -ENOENT;

	for (i = 0; i < ARRAY_SIZE(cs_amp_spkid_byte_types); i++) {
		ret = cs_amp_get_efi_byte_spkid(dev, &cs_amp_spkid_byte_types[i]);
		if (ret != -ENOENT)
			return ret;
	}

	return -ENOENT;
}
EXPORT_SYMBOL_NS_GPL(cs_amp_get_vendor_spkid, "SND_SOC_CS_AMP_LIB");

static const char *cs_amp_devm_get_dell_ssidex(struct device *dev,
					       int ssid_vendor, int ssid_device)
{
	unsigned int hex_prefix;
	char audio_id[4];
	char delim;
	char *p;
	int ret;

	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE) &&
	    !IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS))
		return ERR_PTR(-ENOENT);

	char *ssidex_buf __free(kfree) = cs_amp_alloc_get_efi_variable(DELL_SSIDEXV2_EFI_NAME,
								       &DELL_SSIDEXV2_EFI_GUID,
								       NULL);
	ret = PTR_ERR_OR_ZERO(ssidex_buf);
	if (ret == -ENOENT)
		return ERR_PTR(-ENOENT);
	else if (ret < 0)
		return ssidex_buf;

	/*
	 * SSIDExV2 string is a series of underscore delimited fields.
	 * First field is all or part of the SSID. Second field should be
	 * a 2-character audio hardware id, followed by other identifiers.
	 * Older models did not have the 2-character audio id, so reject
	 * the string if the second field is not 2 characters.
	 */
	ret = sscanf(ssidex_buf, "%8x_%2s%c", &hex_prefix, audio_id, &delim);
	if (ret < 2)
		return ERR_PTR(-ENOENT);

	if ((ret == 3) && (delim != '_'))
		return ERR_PTR(-ENOENT);

	if (strlen(audio_id) != 2)
		return ERR_PTR(-ENOENT);

	p = devm_kstrdup(dev, audio_id, GFP_KERNEL);
	if (!p)
		return ERR_PTR(-ENOMEM);

	return p;
}

/**
 * cs_amp_devm_get_vendor_specific_variant_id - get variant ID string
 * @dev:	 pointer to struct device
 * @ssid_vendor: PCI Subsystem Vendor (-1 if unknown)
 * @ssid_device: PCI Subsystem Device (-1 if unknown)
 *
 * Known vendor-specific hardware identifiers are checked and if one is
 * found its content is returned as a NUL-terminated string. The returned
 * string is devm-managed.
 *
 * The returned string is not guaranteed to be globally unique.
 * Generally it should be combined with some other qualifier, such as
 * PCI SSID, to create a globally unique ID.
 *
 * If the caller has a PCI SSID it should pass it in @ssid_vendor and
 * @ssid_device. If the vendor-spefic ID contains this SSID it will be
 * stripped from the returned string to prevent duplication.
 *
 * If the caller does not have a PCI SSID, pass -1 for @ssid_vendor and
 * @ssid_device.
 *
 * Return:
 * * a pointer to a devm-managed string
 * * ERR_PTR(-ENOENT) if no vendor-specific qualifier
 * * ERR_PTR error value
 */
const char *cs_amp_devm_get_vendor_specific_variant_id(struct device *dev,
						       int ssid_vendor,
						       int ssid_device)
{
	KUNIT_STATIC_STUB_REDIRECT(cs_amp_devm_get_vendor_specific_variant_id,
				   dev, ssid_vendor, ssid_device);

	if ((ssid_vendor == PCI_VENDOR_ID_DELL) || (ssid_vendor < 0))
		return cs_amp_devm_get_dell_ssidex(dev, ssid_vendor, ssid_device);

	return ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL_NS_GPL(cs_amp_devm_get_vendor_specific_variant_id, "SND_SOC_CS_AMP_LIB");

/**
 * cs_amp_create_debugfs - create a debugfs directory for a device
 *
 * @dev: pointer to struct device
 *
 * Creates a node under "cirrus_logic" in the root of the debugfs filesystem.
 * This is for Cirrus-specific debugfs functionality to be grouped in a
 * defined way, independently of the debugfs provided by ALSA/ASoC.
 * The general ALSA/ASoC debugfs may not be enabled, and does not necessarily
 * have a stable layout or naming convention.
 *
 * Return: Pointer to the dentry for the created directory, or -ENODEV.
 */
struct dentry *cs_amp_create_debugfs(struct device *dev)
{
	struct dentry *dir, *created;

	/* debugfs_lookup() can return NULL or ERR_PTR on error */
	dir = debugfs_lookup("cirrus_logic", NULL);
	if (!IS_ERR_OR_NULL(dir)) {
		created = debugfs_create_dir(dev_name(dev), dir);
		dput(dir);

		return created;
	}

	dir = debugfs_create_dir("cirrus_logic", NULL);

	return debugfs_create_dir(dev_name(dev), dir);
}
EXPORT_SYMBOL_NS_GPL(cs_amp_create_debugfs, "SND_SOC_CS_AMP_LIB");

static const struct cs_amp_test_hooks cs_amp_test_hook_ptrs = {
	.get_efi_variable = cs_amp_get_efi_variable,
	.set_efi_variable = cs_amp_set_efi_variable,
	.write_cal_coeff = cs_amp_write_cal_coeff,
	.read_cal_coeff = cs_amp_read_cal_coeff,
};

const struct cs_amp_test_hooks * const cs_amp_test_hooks =
	PTR_IF(IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS), &cs_amp_test_hook_ptrs);
EXPORT_SYMBOL_NS_GPL(cs_amp_test_hooks, "SND_SOC_CS_AMP_LIB");

MODULE_DESCRIPTION("Cirrus Logic amplifier library");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("FW_CS_DSP");
