/*
 * bebob_hwdep.c - a part of driver for BeBoB based devices
 *
 * Copyright (c) 2013-2014 Takashi Sakamoto
 *
 * Licensed under the terms of the GNU General Public License, version 2.
 */

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

#include "bebob.h"

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

	spin_lock_irq(&bebob->lock);

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

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

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

	spin_unlock_irq(&bebob->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_bebob *bebob = hwdep->private_data;
	__poll_t events;

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

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

	return events;
}

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

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

	spin_lock_irq(&bebob->lock);

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

	spin_unlock_irq(&bebob->lock);

	return err;
}

static int
hwdep_unlock(struct snd_bebob *bebob)
{
	int err;

	spin_lock_irq(&bebob->lock);

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

	spin_unlock_irq(&bebob->lock);

	return err;
}

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

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

	return 0;
}

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

	switch (cmd) {
	case SNDRV_FIREWIRE_IOCTL_GET_INFO:
		return hwdep_get_info(bebob, (void __user *)arg);
	case SNDRV_FIREWIRE_IOCTL_LOCK:
		return hwdep_lock(bebob);
	case SNDRV_FIREWIRE_IOCTL_UNLOCK:
		return hwdep_unlock(bebob);
	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_bebob_create_hwdep_device(struct snd_bebob *bebob)
{
	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(bebob->card, "BeBoB", 0, &hwdep);
	if (err < 0)
		goto end;
	strcpy(hwdep->name, "BeBoB");
	hwdep->iface = SNDRV_HWDEP_IFACE_FW_BEBOB;
	hwdep->ops = ops;
	hwdep->private_data = bebob;
	hwdep->exclusive = true;
end:
	return err;
}

