// SPDX-License-Identifier: GPL-2.0-only
/*
 * motu-hwdep.c - a part of driver for MOTU FireWire series
 *
 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
 */

/*
 * This codes have five functionalities.
 *
 * 1.get information about firewire node
 * 2.get notification about starting/stopping stream
 * 3.lock/unlock streaming
 *
 */

#include "motu.h"

static bool has_dsp_event(struct snd_motu *motu)
{
	if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP)
		return (snd_motu_register_dsp_message_parser_count_event(motu) > 0);
	else
		return false;
}

static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
		       loff_t *offset)
{
	struct snd_motu *motu = hwdep->private_data;
	DEFINE_WAIT(wait);
	union snd_firewire_event event;

	spin_lock_irq(&motu->lock);

	while (!motu->dev_lock_changed && motu->msg == 0 && !has_dsp_event(motu)) {
		prepare_to_wait(&motu->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
		spin_unlock_irq(&motu->lock);
		schedule();
		finish_wait(&motu->hwdep_wait, &wait);
		if (signal_pending(current))
			return -ERESTARTSYS;
		spin_lock_irq(&motu->lock);
	}

	memset(&event, 0, sizeof(event));
	if (motu->dev_lock_changed) {
		event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
		event.lock_status.status = (motu->dev_lock_count > 0);
		motu->dev_lock_changed = false;
		spin_unlock_irq(&motu->lock);

		count = min_t(long, count, sizeof(event));
		if (copy_to_user(buf, &event, count))
			return -EFAULT;
	} else if (motu->msg > 0) {
		event.motu_notification.type = SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION;
		event.motu_notification.message = motu->msg;
		motu->msg = 0;
		spin_unlock_irq(&motu->lock);

		count = min_t(long, count, sizeof(event));
		if (copy_to_user(buf, &event, count))
			return -EFAULT;
	} else if (has_dsp_event(motu)) {
		size_t consumed = 0;
		u32 __user *ptr;
		u32 ev;

		spin_unlock_irq(&motu->lock);

		// Header is filled later.
		consumed += sizeof(event.motu_register_dsp_change);

		while (consumed < count &&
		       snd_motu_register_dsp_message_parser_copy_event(motu, &ev)) {
			ptr = (u32 __user *)(buf + consumed);
			if (put_user(ev, ptr))
				return -EFAULT;
			consumed += sizeof(ev);
		}

		event.motu_register_dsp_change.type = SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE;
		event.motu_register_dsp_change.count =
			(consumed - sizeof(event.motu_register_dsp_change)) / 4;
		if (copy_to_user(buf, &event, sizeof(event.motu_register_dsp_change)))
			return -EFAULT;

		count = consumed;
	}

	return count;
}

static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
			       poll_table *wait)
{
	struct snd_motu *motu = hwdep->private_data;
	__poll_t events;

	poll_wait(file, &motu->hwdep_wait, wait);

	spin_lock_irq(&motu->lock);
	if (motu->dev_lock_changed || motu->msg || has_dsp_event(motu))
		events = EPOLLIN | EPOLLRDNORM;
	else
		events = 0;
	spin_unlock_irq(&motu->lock);

	return events | EPOLLOUT;
}

static int hwdep_get_info(struct snd_motu *motu, void __user *arg)
{
	struct fw_device *dev = fw_parent_device(motu->unit);
	struct snd_firewire_get_info info;

	memset(&info, 0, sizeof(info));
	info.type = SNDRV_FIREWIRE_TYPE_MOTU;
	info.card = dev->card->index;
	*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
	*(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
	strscpy(info.device_name, dev_name(&dev->device),
		sizeof(info.device_name));

	if (copy_to_user(arg, &info, sizeof(info)))
		return -EFAULT;

	return 0;
}

static int hwdep_lock(struct snd_motu *motu)
{
	int err;

	spin_lock_irq(&motu->lock);

	if (motu->dev_lock_count == 0) {
		motu->dev_lock_count = -1;
		err = 0;
	} else {
		err = -EBUSY;
	}

	spin_unlock_irq(&motu->lock);

	return err;
}

static int hwdep_unlock(struct snd_motu *motu)
{
	int err;

	spin_lock_irq(&motu->lock);

	if (motu->dev_lock_count == -1) {
		motu->dev_lock_count = 0;
		err = 0;
	} else {
		err = -EBADFD;
	}

	spin_unlock_irq(&motu->lock);

	return err;
}

static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
	struct snd_motu *motu = hwdep->private_data;

	spin_lock_irq(&motu->lock);
	if (motu->dev_lock_count == -1)
		motu->dev_lock_count = 0;
	spin_unlock_irq(&motu->lock);

	return 0;
}

static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,
	    unsigned int cmd, unsigned long arg)
{
	struct snd_motu *motu = hwdep->private_data;

	switch (cmd) {
	case SNDRV_FIREWIRE_IOCTL_GET_INFO:
		return hwdep_get_info(motu, (void __user *)arg);
	case SNDRV_FIREWIRE_IOCTL_LOCK:
		return hwdep_lock(motu);
	case SNDRV_FIREWIRE_IOCTL_UNLOCK:
		return hwdep_unlock(motu);
	case SNDRV_FIREWIRE_IOCTL_MOTU_REGISTER_DSP_METER:
	{
		struct snd_firewire_motu_register_dsp_meter *meter;
		int err;

		if (!(motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP))
			return -ENXIO;

		meter = kzalloc(sizeof(*meter), GFP_KERNEL);
		if (!meter)
			return -ENOMEM;

		snd_motu_register_dsp_message_parser_copy_meter(motu, meter);

		err = copy_to_user((void __user *)arg, meter, sizeof(*meter));
		kfree(meter);

		if (err)
			return -EFAULT;

		return 0;
	}
	case SNDRV_FIREWIRE_IOCTL_MOTU_COMMAND_DSP_METER:
	{
		struct snd_firewire_motu_command_dsp_meter *meter;
		int err;

		if (!(motu->spec->flags & SND_MOTU_SPEC_COMMAND_DSP))
			return -ENXIO;

		meter = kzalloc(sizeof(*meter), GFP_KERNEL);
		if (!meter)
			return -ENOMEM;

		snd_motu_command_dsp_message_parser_copy_meter(motu, meter);

		err = copy_to_user((void __user *)arg, meter, sizeof(*meter));
		kfree(meter);

		if (err)
			return -EFAULT;

		return 0;
	}
	case SNDRV_FIREWIRE_IOCTL_MOTU_REGISTER_DSP_PARAMETER:
	{
		struct snd_firewire_motu_register_dsp_parameter *param;
		int err;

		if (!(motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP))
			return -ENXIO;

		param = kzalloc(sizeof(*param), GFP_KERNEL);
		if (!param)
			return -ENOMEM;

		snd_motu_register_dsp_message_parser_copy_parameter(motu, param);

		err = copy_to_user((void __user *)arg, param, sizeof(*param));
		kfree(param);
		if (err)
			return -EFAULT;

		return 0;
	}
	default:
		return -ENOIOCTLCMD;
	}
}

#ifdef CONFIG_COMPAT
static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
			      unsigned int cmd, unsigned long arg)
{
	return hwdep_ioctl(hwdep, file, cmd,
			   (unsigned long)compat_ptr(arg));
}
#else
#define hwdep_compat_ioctl NULL
#endif

int snd_motu_create_hwdep_device(struct snd_motu *motu)
{
	static const struct snd_hwdep_ops ops = {
		.read		= hwdep_read,
		.release	= hwdep_release,
		.poll		= hwdep_poll,
		.ioctl		= hwdep_ioctl,
		.ioctl_compat	= hwdep_compat_ioctl,
	};
	struct snd_hwdep *hwdep;
	int err;

	err = snd_hwdep_new(motu->card, motu->card->driver, 0, &hwdep);
	if (err < 0)
		return err;

	strcpy(hwdep->name, "MOTU");
	hwdep->iface = SNDRV_HWDEP_IFACE_FW_MOTU;
	hwdep->ops = ops;
	hwdep->private_data = motu;
	hwdep->exclusive = true;

	motu->hwdep = hwdep;

	return 0;
}
