/*
 * Load Analog Devices SigmaStudio firmware files
 *
 * Copyright 2009-2014 Analog Devices Inc.
 *
 * Licensed under the GPL-2 or later.
 */

#include <linux/crc32.h>
#include <linux/firmware.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/module.h>
#include <linux/slab.h>

#include <sound/control.h>
#include <sound/soc.h>

#include "sigmadsp.h"

#define SIGMA_MAGIC "ADISIGM"

#define SIGMA_FW_CHUNK_TYPE_DATA 0
#define SIGMA_FW_CHUNK_TYPE_CONTROL 1
#define SIGMA_FW_CHUNK_TYPE_SAMPLERATES 2

struct sigmadsp_control {
	struct list_head head;
	uint32_t samplerates;
	unsigned int addr;
	unsigned int num_bytes;
	const char *name;
	struct snd_kcontrol *kcontrol;
	bool cached;
	uint8_t cache[];
};

struct sigmadsp_data {
	struct list_head head;
	uint32_t samplerates;
	unsigned int addr;
	unsigned int length;
	uint8_t data[];
};

struct sigma_fw_chunk {
	__le32 length;
	__le32 tag;
	__le32 samplerates;
} __packed;

struct sigma_fw_chunk_data {
	struct sigma_fw_chunk chunk;
	__le16 addr;
	uint8_t data[];
} __packed;

struct sigma_fw_chunk_control {
	struct sigma_fw_chunk chunk;
	__le16 type;
	__le16 addr;
	__le16 num_bytes;
	const char name[];
} __packed;

struct sigma_fw_chunk_samplerate {
	struct sigma_fw_chunk chunk;
	__le32 samplerates[];
} __packed;

struct sigma_firmware_header {
	unsigned char magic[7];
	u8 version;
	__le32 crc;
} __packed;

enum {
	SIGMA_ACTION_WRITEXBYTES = 0,
	SIGMA_ACTION_WRITESINGLE,
	SIGMA_ACTION_WRITESAFELOAD,
	SIGMA_ACTION_END,
};

struct sigma_action {
	u8 instr;
	u8 len_hi;
	__le16 len;
	__be16 addr;
	unsigned char payload[];
} __packed;

static int sigmadsp_write(struct sigmadsp *sigmadsp, unsigned int addr,
	const uint8_t data[], size_t len)
{
	return sigmadsp->write(sigmadsp->control_data, addr, data, len);
}

static int sigmadsp_read(struct sigmadsp *sigmadsp, unsigned int addr,
	uint8_t data[], size_t len)
{
	return sigmadsp->read(sigmadsp->control_data, addr, data, len);
}

static int sigmadsp_ctrl_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *info)
{
	struct sigmadsp_control *ctrl = (void *)kcontrol->private_value;

	info->type = SNDRV_CTL_ELEM_TYPE_BYTES;
	info->count = ctrl->num_bytes;

	return 0;
}

static int sigmadsp_ctrl_write(struct sigmadsp *sigmadsp,
	struct sigmadsp_control *ctrl, void *data)
{
	/* safeload loads up to 20 bytes in a atomic operation */
	if (ctrl->num_bytes > 4 && ctrl->num_bytes <= 20 && sigmadsp->ops &&
	    sigmadsp->ops->safeload)
		return sigmadsp->ops->safeload(sigmadsp, ctrl->addr, data,
			ctrl->num_bytes);
	else
		return sigmadsp_write(sigmadsp, ctrl->addr, data,
			ctrl->num_bytes);
}

static int sigmadsp_ctrl_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct sigmadsp_control *ctrl = (void *)kcontrol->private_value;
	struct sigmadsp *sigmadsp = snd_kcontrol_chip(kcontrol);
	uint8_t *data;
	int ret = 0;

	mutex_lock(&sigmadsp->lock);

	data = ucontrol->value.bytes.data;

	if (!(kcontrol->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE))
		ret = sigmadsp_ctrl_write(sigmadsp, ctrl, data);

	if (ret == 0) {
		memcpy(ctrl->cache, data, ctrl->num_bytes);
		ctrl->cached = true;
	}

	mutex_unlock(&sigmadsp->lock);

	return ret;
}

static int sigmadsp_ctrl_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct sigmadsp_control *ctrl = (void *)kcontrol->private_value;
	struct sigmadsp *sigmadsp = snd_kcontrol_chip(kcontrol);
	int ret = 0;

	mutex_lock(&sigmadsp->lock);

	if (!ctrl->cached) {
		ret = sigmadsp_read(sigmadsp, ctrl->addr, ctrl->cache,
			ctrl->num_bytes);
	}

	if (ret == 0) {
		ctrl->cached = true;
		memcpy(ucontrol->value.bytes.data, ctrl->cache,
			ctrl->num_bytes);
	}

	mutex_unlock(&sigmadsp->lock);

	return ret;
}

static void sigmadsp_control_free(struct snd_kcontrol *kcontrol)
{
	struct sigmadsp_control *ctrl = (void *)kcontrol->private_value;

	ctrl->kcontrol = NULL;
}

static bool sigma_fw_validate_control_name(const char *name, unsigned int len)
{
	unsigned int i;

	for (i = 0; i < len; i++) {
		/* Normal ASCII characters are valid */
		if (name[i] < ' ' || name[i] > '~')
			return false;
	}

	return true;
}

static int sigma_fw_load_control(struct sigmadsp *sigmadsp,
	const struct sigma_fw_chunk *chunk, unsigned int length)
{
	const struct sigma_fw_chunk_control *ctrl_chunk;
	struct sigmadsp_control *ctrl;
	unsigned int num_bytes;
	size_t name_len;
	char *name;
	int ret;

	if (length <= sizeof(*ctrl_chunk))
		return -EINVAL;

	ctrl_chunk = (const struct sigma_fw_chunk_control *)chunk;

	name_len = length - sizeof(*ctrl_chunk);
	if (name_len >= SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
		name_len = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - 1;

	/* Make sure there are no non-displayable characaters in the string */
	if (!sigma_fw_validate_control_name(ctrl_chunk->name, name_len))
		return -EINVAL;

	num_bytes = le16_to_cpu(ctrl_chunk->num_bytes);
	ctrl = kzalloc(sizeof(*ctrl) + num_bytes, GFP_KERNEL);
	if (!ctrl)
		return -ENOMEM;

	name = kzalloc(name_len + 1, GFP_KERNEL);
	if (!name) {
		ret = -ENOMEM;
		goto err_free_ctrl;
	}
	memcpy(name, ctrl_chunk->name, name_len);
	name[name_len] = '\0';
	ctrl->name = name;

	ctrl->addr = le16_to_cpu(ctrl_chunk->addr);
	ctrl->num_bytes = num_bytes;
	ctrl->samplerates = le32_to_cpu(chunk->samplerates);

	list_add_tail(&ctrl->head, &sigmadsp->ctrl_list);

	return 0;

err_free_ctrl:
	kfree(ctrl);

	return ret;
}

static int sigma_fw_load_data(struct sigmadsp *sigmadsp,
	const struct sigma_fw_chunk *chunk, unsigned int length)
{
	const struct sigma_fw_chunk_data *data_chunk;
	struct sigmadsp_data *data;

	if (length <= sizeof(*data_chunk))
		return -EINVAL;

	data_chunk = (struct sigma_fw_chunk_data *)chunk;

	length -= sizeof(*data_chunk);

	data = kzalloc(sizeof(*data) + length, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->addr = le16_to_cpu(data_chunk->addr);
	data->length = length;
	data->samplerates = le32_to_cpu(chunk->samplerates);
	memcpy(data->data, data_chunk->data, length);
	list_add_tail(&data->head, &sigmadsp->data_list);

	return 0;
}

static int sigma_fw_load_samplerates(struct sigmadsp *sigmadsp,
	const struct sigma_fw_chunk *chunk, unsigned int length)
{
	const struct sigma_fw_chunk_samplerate *rate_chunk;
	unsigned int num_rates;
	unsigned int *rates;
	unsigned int i;

	rate_chunk = (const struct sigma_fw_chunk_samplerate *)chunk;

	num_rates = (length - sizeof(*rate_chunk)) / sizeof(__le32);

	if (num_rates > 32 || num_rates == 0)
		return -EINVAL;

	/* We only allow one samplerates block per file */
	if (sigmadsp->rate_constraints.count)
		return -EINVAL;

	rates = kcalloc(num_rates, sizeof(*rates), GFP_KERNEL);
	if (!rates)
		return -ENOMEM;

	for (i = 0; i < num_rates; i++)
		rates[i] = le32_to_cpu(rate_chunk->samplerates[i]);

	sigmadsp->rate_constraints.count = num_rates;
	sigmadsp->rate_constraints.list = rates;

	return 0;
}

static int sigmadsp_fw_load_v2(struct sigmadsp *sigmadsp,
	const struct firmware *fw)
{
	struct sigma_fw_chunk *chunk;
	unsigned int length, pos;
	int ret;

	/*
	 * Make sure that there is at least one chunk to avoid integer
	 * underflows later on. Empty firmware is still valid though.
	 */
	if (fw->size < sizeof(*chunk) + sizeof(struct sigma_firmware_header))
		return 0;

	pos = sizeof(struct sigma_firmware_header);

	while (pos < fw->size - sizeof(*chunk)) {
		chunk = (struct sigma_fw_chunk *)(fw->data + pos);

		length = le32_to_cpu(chunk->length);

		if (length > fw->size - pos || length < sizeof(*chunk))
			return -EINVAL;

		switch (le32_to_cpu(chunk->tag)) {
		case SIGMA_FW_CHUNK_TYPE_DATA:
			ret = sigma_fw_load_data(sigmadsp, chunk, length);
			break;
		case SIGMA_FW_CHUNK_TYPE_CONTROL:
			ret = sigma_fw_load_control(sigmadsp, chunk, length);
			break;
		case SIGMA_FW_CHUNK_TYPE_SAMPLERATES:
			ret = sigma_fw_load_samplerates(sigmadsp, chunk, length);
			break;
		default:
			dev_warn(sigmadsp->dev, "Unknown chunk type: %d\n",
				chunk->tag);
			ret = 0;
			break;
		}

		if (ret)
			return ret;

		/*
		 * This can not overflow since if length is larger than the
		 * maximum firmware size (0x4000000) we'll error out earilier.
		 */
		pos += ALIGN(length, sizeof(__le32));
	}

	return 0;
}

static inline u32 sigma_action_len(struct sigma_action *sa)
{
	return (sa->len_hi << 16) | le16_to_cpu(sa->len);
}

static size_t sigma_action_size(struct sigma_action *sa)
{
	size_t payload = 0;

	switch (sa->instr) {
	case SIGMA_ACTION_WRITEXBYTES:
	case SIGMA_ACTION_WRITESINGLE:
	case SIGMA_ACTION_WRITESAFELOAD:
		payload = sigma_action_len(sa);
		break;
	default:
		break;
	}

	payload = ALIGN(payload, 2);

	return payload + sizeof(struct sigma_action);
}

/*
 * Returns a negative error value in case of an error, 0 if processing of
 * the firmware should be stopped after this action, 1 otherwise.
 */
static int process_sigma_action(struct sigmadsp *sigmadsp,
	struct sigma_action *sa)
{
	size_t len = sigma_action_len(sa);
	struct sigmadsp_data *data;

	pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
		sa->instr, sa->addr, len);

	switch (sa->instr) {
	case SIGMA_ACTION_WRITEXBYTES:
	case SIGMA_ACTION_WRITESINGLE:
	case SIGMA_ACTION_WRITESAFELOAD:
		if (len < 3)
			return -EINVAL;

		data = kzalloc(sizeof(*data) + len - 2, GFP_KERNEL);
		if (!data)
			return -ENOMEM;

		data->addr = be16_to_cpu(sa->addr);
		data->length = len - 2;
		memcpy(data->data, sa->payload, data->length);
		list_add_tail(&data->head, &sigmadsp->data_list);
		break;
	case SIGMA_ACTION_END:
		return 0;
	default:
		return -EINVAL;
	}

	return 1;
}

static int sigmadsp_fw_load_v1(struct sigmadsp *sigmadsp,
	const struct firmware *fw)
{
	struct sigma_action *sa;
	size_t size, pos;
	int ret;

	pos = sizeof(struct sigma_firmware_header);

	while (pos + sizeof(*sa) <= fw->size) {
		sa = (struct sigma_action *)(fw->data + pos);

		size = sigma_action_size(sa);
		pos += size;
		if (pos > fw->size || size == 0)
			break;

		ret = process_sigma_action(sigmadsp, sa);

		pr_debug("%s: action returned %i\n", __func__, ret);

		if (ret <= 0)
			return ret;
	}

	if (pos != fw->size)
		return -EINVAL;

	return 0;
}

static void sigmadsp_firmware_release(struct sigmadsp *sigmadsp)
{
	struct sigmadsp_control *ctrl, *_ctrl;
	struct sigmadsp_data *data, *_data;

	list_for_each_entry_safe(ctrl, _ctrl, &sigmadsp->ctrl_list, head) {
		kfree(ctrl->name);
		kfree(ctrl);
	}

	list_for_each_entry_safe(data, _data, &sigmadsp->data_list, head)
		kfree(data);

	INIT_LIST_HEAD(&sigmadsp->ctrl_list);
	INIT_LIST_HEAD(&sigmadsp->data_list);
}

static void devm_sigmadsp_release(struct device *dev, void *res)
{
	sigmadsp_firmware_release((struct sigmadsp *)res);
}

static int sigmadsp_firmware_load(struct sigmadsp *sigmadsp, const char *name)
{
	const struct sigma_firmware_header *ssfw_head;
	const struct firmware *fw;
	int ret;
	u32 crc;

	/* first load the blob */
	ret = request_firmware(&fw, name, sigmadsp->dev);
	if (ret) {
		pr_debug("%s: request_firmware() failed with %i\n", __func__, ret);
		goto done;
	}

	/* then verify the header */
	ret = -EINVAL;

	/*
	 * Reject too small or unreasonable large files. The upper limit has been
	 * chosen a bit arbitrarily, but it should be enough for all practical
	 * purposes and having the limit makes it easier to avoid integer
	 * overflows later in the loading process.
	 */
	if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) {
		dev_err(sigmadsp->dev, "Failed to load firmware: Invalid size\n");
		goto done;
	}

	ssfw_head = (void *)fw->data;
	if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) {
		dev_err(sigmadsp->dev, "Failed to load firmware: Invalid magic\n");
		goto done;
	}

	crc = crc32(0, fw->data + sizeof(*ssfw_head),
			fw->size - sizeof(*ssfw_head));
	pr_debug("%s: crc=%x\n", __func__, crc);
	if (crc != le32_to_cpu(ssfw_head->crc)) {
		dev_err(sigmadsp->dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n",
			le32_to_cpu(ssfw_head->crc), crc);
		goto done;
	}

	switch (ssfw_head->version) {
	case 1:
		ret = sigmadsp_fw_load_v1(sigmadsp, fw);
		break;
	case 2:
		ret = sigmadsp_fw_load_v2(sigmadsp, fw);
		break;
	default:
		dev_err(sigmadsp->dev,
			"Failed to load firmware: Invalid version %d. Supported firmware versions: 1, 2\n",
			ssfw_head->version);
		ret = -EINVAL;
		break;
	}

	if (ret)
		sigmadsp_firmware_release(sigmadsp);

done:
	release_firmware(fw);

	return ret;
}

static int sigmadsp_init(struct sigmadsp *sigmadsp, struct device *dev,
	const struct sigmadsp_ops *ops, const char *firmware_name)
{
	sigmadsp->ops = ops;
	sigmadsp->dev = dev;

	INIT_LIST_HEAD(&sigmadsp->ctrl_list);
	INIT_LIST_HEAD(&sigmadsp->data_list);
	mutex_init(&sigmadsp->lock);

	return sigmadsp_firmware_load(sigmadsp, firmware_name);
}

/**
 * devm_sigmadsp_init() - Initialize SigmaDSP instance
 * @dev: The parent device
 * @ops: The sigmadsp_ops to use for this instance
 * @firmware_name: Name of the firmware file to load
 *
 * Allocates a SigmaDSP instance and loads the specified firmware file.
 *
 * Returns a pointer to a struct sigmadsp on success, or a PTR_ERR() on error.
 */
struct sigmadsp *devm_sigmadsp_init(struct device *dev,
	const struct sigmadsp_ops *ops, const char *firmware_name)
{
	struct sigmadsp *sigmadsp;
	int ret;

	sigmadsp = devres_alloc(devm_sigmadsp_release, sizeof(*sigmadsp),
		GFP_KERNEL);
	if (!sigmadsp)
		return ERR_PTR(-ENOMEM);

	ret = sigmadsp_init(sigmadsp, dev, ops, firmware_name);
	if (ret) {
		devres_free(sigmadsp);
		return ERR_PTR(ret);
	}

	devres_add(dev, sigmadsp);

	return sigmadsp;
}
EXPORT_SYMBOL_GPL(devm_sigmadsp_init);

static int sigmadsp_rate_to_index(struct sigmadsp *sigmadsp, unsigned int rate)
{
	unsigned int i;

	for (i = 0; i < sigmadsp->rate_constraints.count; i++) {
		if (sigmadsp->rate_constraints.list[i] == rate)
			return i;
	}

	return -EINVAL;
}

static unsigned int sigmadsp_get_samplerate_mask(struct sigmadsp *sigmadsp,
	unsigned int samplerate)
{
	int samplerate_index;

	if (samplerate == 0)
		return 0;

	if (sigmadsp->rate_constraints.count) {
		samplerate_index = sigmadsp_rate_to_index(sigmadsp, samplerate);
		if (samplerate_index < 0)
			return 0;

		return BIT(samplerate_index);
	} else {
		return ~0;
	}
}

static bool sigmadsp_samplerate_valid(unsigned int supported,
	unsigned int requested)
{
	/* All samplerates are supported */
	if (!supported)
		return true;

	return supported & requested;
}

static int sigmadsp_alloc_control(struct sigmadsp *sigmadsp,
	struct sigmadsp_control *ctrl, unsigned int samplerate_mask)
{
	struct snd_kcontrol_new template;
	struct snd_kcontrol *kcontrol;

	memset(&template, 0, sizeof(template));
	template.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
	template.name = ctrl->name;
	template.info = sigmadsp_ctrl_info;
	template.get = sigmadsp_ctrl_get;
	template.put = sigmadsp_ctrl_put;
	template.private_value = (unsigned long)ctrl;
	template.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
	if (!sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask))
		template.access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;

	kcontrol = snd_ctl_new1(&template, sigmadsp);
	if (!kcontrol)
		return -ENOMEM;

	kcontrol->private_free = sigmadsp_control_free;
	ctrl->kcontrol = kcontrol;

	return snd_ctl_add(sigmadsp->component->card->snd_card, kcontrol);
}

static void sigmadsp_activate_ctrl(struct sigmadsp *sigmadsp,
	struct sigmadsp_control *ctrl, unsigned int samplerate_mask)
{
	struct snd_card *card = sigmadsp->component->card->snd_card;
	struct snd_kcontrol_volatile *vd;
	struct snd_ctl_elem_id id;
	bool active;
	bool changed = false;

	active = sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask);

	down_write(&card->controls_rwsem);
	if (!ctrl->kcontrol) {
		up_write(&card->controls_rwsem);
		return;
	}

	id = ctrl->kcontrol->id;
	vd = &ctrl->kcontrol->vd[0];
	if (active == (bool)(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) {
		vd->access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
		changed = true;
	}
	up_write(&card->controls_rwsem);

	if (active && changed) {
		mutex_lock(&sigmadsp->lock);
		if (ctrl->cached)
			sigmadsp_ctrl_write(sigmadsp, ctrl, ctrl->cache);
		mutex_unlock(&sigmadsp->lock);
	}

	if (changed)
		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &id);
}

/**
 * sigmadsp_attach() - Attach a sigmadsp instance to a ASoC component
 * @sigmadsp: The sigmadsp instance to attach
 * @component: The component to attach to
 *
 * Typically called in the components probe callback.
 *
 * Note, once this function has been called the firmware must not be released
 * until after the ALSA snd_card that the component belongs to has been
 * disconnected, even if sigmadsp_attach() returns an error.
 */
int sigmadsp_attach(struct sigmadsp *sigmadsp,
	struct snd_soc_component *component)
{
	struct sigmadsp_control *ctrl;
	unsigned int samplerate_mask;
	int ret;

	sigmadsp->component = component;

	samplerate_mask = sigmadsp_get_samplerate_mask(sigmadsp,
		sigmadsp->current_samplerate);

	list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) {
		ret = sigmadsp_alloc_control(sigmadsp, ctrl, samplerate_mask);
		if (ret)
			return ret;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(sigmadsp_attach);

/**
 * sigmadsp_setup() - Setup the DSP for the specified samplerate
 * @sigmadsp: The sigmadsp instance to configure
 * @samplerate: The samplerate the DSP should be configured for
 *
 * Loads the appropriate firmware program and parameter memory (if not already
 * loaded) and enables the controls for the specified samplerate. Any control
 * parameter changes that have been made previously will be restored.
 *
 * Returns 0 on success, a negative error code otherwise.
 */
int sigmadsp_setup(struct sigmadsp *sigmadsp, unsigned int samplerate)
{
	struct sigmadsp_control *ctrl;
	unsigned int samplerate_mask;
	struct sigmadsp_data *data;
	int ret;

	if (sigmadsp->current_samplerate == samplerate)
		return 0;

	samplerate_mask = sigmadsp_get_samplerate_mask(sigmadsp, samplerate);
	if (samplerate_mask == 0)
		return -EINVAL;

	list_for_each_entry(data, &sigmadsp->data_list, head) {
		if (!sigmadsp_samplerate_valid(data->samplerates,
		    samplerate_mask))
			continue;
		ret = sigmadsp_write(sigmadsp, data->addr, data->data,
			data->length);
		if (ret)
			goto err;
	}

	list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head)
		sigmadsp_activate_ctrl(sigmadsp, ctrl, samplerate_mask);

	sigmadsp->current_samplerate = samplerate;

	return 0;
err:
	sigmadsp_reset(sigmadsp);

	return ret;
}
EXPORT_SYMBOL_GPL(sigmadsp_setup);

/**
 * sigmadsp_reset() - Notify the sigmadsp instance that the DSP has been reset
 * @sigmadsp: The sigmadsp instance to reset
 *
 * Should be called whenever the DSP has been reset and parameter and program
 * memory need to be re-loaded.
 */
void sigmadsp_reset(struct sigmadsp *sigmadsp)
{
	struct sigmadsp_control *ctrl;

	list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head)
		sigmadsp_activate_ctrl(sigmadsp, ctrl, false);

	sigmadsp->current_samplerate = 0;
}
EXPORT_SYMBOL_GPL(sigmadsp_reset);

/**
 * sigmadsp_restrict_params() - Applies DSP firmware specific constraints
 * @sigmadsp: The sigmadsp instance
 * @substream: The substream to restrict
 *
 * Applies samplerate constraints that may be required by the firmware Should
 * typically be called from the CODEC/component drivers startup callback.
 *
 * Returns 0 on success, a negative error code otherwise.
 */
int sigmadsp_restrict_params(struct sigmadsp *sigmadsp,
	struct snd_pcm_substream *substream)
{
	if (sigmadsp->rate_constraints.count == 0)
		return 0;

	return snd_pcm_hw_constraint_list(substream->runtime, 0,
		SNDRV_PCM_HW_PARAM_RATE, &sigmadsp->rate_constraints);
}
EXPORT_SYMBOL_GPL(sigmadsp_restrict_params);

MODULE_LICENSE("GPL");
