// SPDX-License-Identifier: GPL-2.0-only
/*
 * oxfw_hwdep.c - a part of driver for OXFW970/971 based devices
 *
 * Copyright (c) 2014 Takashi Sakamoto
 */

/*
 * This codes give three functionality.
 *
 * 1.get firewire node information
 * 2.get notification about starting/stopping stream
 * 3.lock/unlock stream
 */

#include "oxfw.h"

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

	spin_lock_irq(&oxfw->lock);

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

	memset(&event, 0, sizeof(event));
	event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
	event.lock_status.status = (oxfw->dev_lock_count > 0);
	oxfw->dev_lock_changed = false;

	count = min_t(long, count, sizeof(event.lock_status));

	spin_unlock_irq(&oxfw->lock);

	if (copy_to_user(buf, &event, count))
		return -EFAULT;

	return count;
}

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

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

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

	return events;
}

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

	memset(&info, 0, sizeof(info));
	info.type = SNDRV_FIREWIRE_TYPE_OXFW;
	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_oxfw *oxfw)
{
	int err;

	spin_lock_irq(&oxfw->lock);

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

	spin_unlock_irq(&oxfw->lock);

	return err;
}

static int hwdep_unlock(struct snd_oxfw *oxfw)
{
	int err;

	spin_lock_irq(&oxfw->lock);

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

	spin_unlock_irq(&oxfw->lock);

	return err;
}

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

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

	return 0;
}

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

	switch (cmd) {
	case SNDRV_FIREWIRE_IOCTL_GET_INFO:
		return hwdep_get_info(oxfw, (void __user *)arg);
	case SNDRV_FIREWIRE_IOCTL_LOCK:
		return hwdep_lock(oxfw);
	case SNDRV_FIREWIRE_IOCTL_UNLOCK:
		return hwdep_unlock(oxfw);
	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_oxfw_create_hwdep(struct snd_oxfw *oxfw)
{
	static const struct snd_hwdep_ops hwdep_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(oxfw->card, oxfw->card->driver, 0, &hwdep);
	if (err < 0)
		goto end;
	strcpy(hwdep->name, oxfw->card->driver);
	hwdep->iface = SNDRV_HWDEP_IFACE_FW_OXFW;
	hwdep->ops = hwdep_ops;
	hwdep->private_data = oxfw;
	hwdep->exclusive = true;
end:
	return err;
}
