// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2018 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#define LOG_CATEGORY UCLASS_SOUND

#include <common.h>
#include <dm.h>
#include <i2s.h>
#include <log.h>
#include <malloc.h>
#include <sound.h>
#include <linux/delay.h>

#define SOUND_BITS_IN_BYTE 8

int sound_setup(struct udevice *dev)
{
	struct sound_ops *ops = sound_get_ops(dev);

	if (!ops->setup)
		return 0;

	return ops->setup(dev);
}

int sound_play(struct udevice *dev, void *data, uint data_size)
{
	struct sound_ops *ops = sound_get_ops(dev);

	if (!ops->play)
		return -ENOSYS;

	return ops->play(dev, data, data_size);
}

int sound_stop_play(struct udevice *dev)
{
	struct sound_ops *ops = sound_get_ops(dev);

	if (!ops->play)
		return -ENOSYS;

	return ops->stop_play(dev);
}

int sound_start_beep(struct udevice *dev, int frequency_hz)
{
	struct sound_ops *ops = sound_get_ops(dev);

	if (!ops->start_beep)
		return -ENOSYS;

	return ops->start_beep(dev, frequency_hz);
}

int sound_stop_beep(struct udevice *dev)
{
	struct sound_ops *ops = sound_get_ops(dev);

	if (!ops->stop_beep)
		return -ENOSYS;

	return ops->stop_beep(dev);
}

int sound_beep(struct udevice *dev, int msecs, int frequency_hz)
{
	struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
	struct i2s_uc_priv *i2s_uc_priv;
	unsigned short *data;
	uint data_size;
	int ret;

	ret = sound_setup(dev);
	if (ret && ret != -EALREADY)
		return ret;

	/* Try using the beep interface if available */
	ret = sound_start_beep(dev, frequency_hz);
	if (ret != -ENOSYS) {
		if (ret)
			return ret;
		mdelay(msecs);
		ret = sound_stop_beep(dev);

		return ret;
	}

	/* Buffer length computation */
	i2s_uc_priv = dev_get_uclass_priv(uc_priv->i2s);
	data_size = i2s_uc_priv->samplingrate * i2s_uc_priv->channels;
	data_size *= (i2s_uc_priv->bitspersample / SOUND_BITS_IN_BYTE);
	data = malloc(data_size);
	if (!data) {
		debug("%s: malloc failed\n", __func__);
		return -ENOMEM;
	}

	sound_create_square_wave(i2s_uc_priv->samplingrate, data, data_size,
				 frequency_hz, i2s_uc_priv->channels);

	ret = 0;
	while (msecs >= 1000) {
		ret = sound_play(dev, data, data_size);
		if (ret)
			break;
		msecs -= 1000;
	}
	if (!ret && msecs) {
		unsigned long size =
			(data_size * msecs) / (sizeof(int) * 1000);

		ret = sound_play(dev, data, size);
	}
	sound_stop_play(dev);

	free(data);

	return ret;
}

int sound_find_codec_i2s(struct udevice *dev)
{
	struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
	struct ofnode_phandle_args args;
	ofnode node;
	int ret;

	/* First the codec */
	node = ofnode_find_subnode(dev_ofnode(dev), "codec");
	if (!ofnode_valid(node)) {
		debug("Failed to find /cpu subnode\n");
		return -EINVAL;
	}
	ret = ofnode_parse_phandle_with_args(node, "sound-dai",
					     "#sound-dai-cells", 0, 0, &args);
	if (ret) {
		debug("Cannot find phandle: %d\n", ret);
		return ret;
	}
	ret = uclass_get_device_by_ofnode(UCLASS_AUDIO_CODEC, args.node,
					  &uc_priv->codec);
	if (ret) {
		debug("Cannot find codec: %d\n", ret);
		return ret;
	}

	/* Now the i2s */
	node = ofnode_find_subnode(dev_ofnode(dev), "cpu");
	if (!ofnode_valid(node)) {
		debug("Failed to find /cpu subnode\n");
		return -EINVAL;
	}
	ret = ofnode_parse_phandle_with_args(node, "sound-dai",
					     "#sound-dai-cells", 0, 0, &args);
	if (ret) {
		debug("Cannot find phandle: %d\n", ret);
		return ret;
	}
	ret = uclass_get_device_by_ofnode(UCLASS_I2S, args.node, &uc_priv->i2s);
	if (ret) {
		debug("Cannot find i2s: %d\n", ret);
		return ret;
	}
	debug("Probed sound '%s' with codec '%s' and i2s '%s'\n", dev->name,
	      uc_priv->codec->name, uc_priv->i2s->name);

	return 0;
}

UCLASS_DRIVER(sound) = {
	.id		= UCLASS_SOUND,
	.name		= "sound",
	.per_device_auto	= sizeof(struct sound_uc_priv),
};
