/*
 * ff-hwdep.c - a part of driver for RME Fireface series
 *
 * Copyright (c) 2015-2017 Takashi Sakamoto
 *
 * Licensed under the terms of the GNU General Public License, version 2.
 */

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

#include "ff.h"

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

	spin_lock_irq(&ff->lock);

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

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

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

	spin_unlock_irq(&ff->lock);

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

	return count;
}

static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
			       poll_table *wait)
{
	struct snd_ff *ff = hwdep->private_data;
	unsigned int events;

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

	spin_lock_irq(&ff->lock);
	if (ff->dev_lock_changed)
		events = POLLIN | POLLRDNORM;
	else
		events = 0;
	spin_unlock_irq(&ff->lock);

	return events;
}

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

	memset(&info, 0, sizeof(info));
	info.type = SNDRV_FIREWIRE_TYPE_FIREFACE;
	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]);
	strlcpy(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_ff *ff)
{
	int err;

	spin_lock_irq(&ff->lock);

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

	spin_unlock_irq(&ff->lock);

	return err;
}

static int hwdep_unlock(struct snd_ff *ff)
{
	int err;

	spin_lock_irq(&ff->lock);

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

	spin_unlock_irq(&ff->lock);

	return err;
}

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

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

	return 0;
}

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

	switch (cmd) {
	case SNDRV_FIREWIRE_IOCTL_GET_INFO:
		return hwdep_get_info(ff, (void __user *)arg);
	case SNDRV_FIREWIRE_IOCTL_LOCK:
		return hwdep_lock(ff);
	case SNDRV_FIREWIRE_IOCTL_UNLOCK:
		return hwdep_unlock(ff);
	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_ff_create_hwdep_devices(struct snd_ff *ff)
{
	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(ff->card, ff->card->driver, 0, &hwdep);
	if (err < 0)
		return err;

	strcpy(hwdep->name, ff->card->driver);
	hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREFACE;
	hwdep->ops = hwdep_ops;
	hwdep->private_data = ff;
	hwdep->exclusive = true;

	return 0;
}
