/*
 *   Simple (MOD player) - Instrument routines
 *   Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */
 
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/ainstr_simple.h>
#include <sound/initval.h>
#include <asm/uaccess.h>

MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support.");
MODULE_LICENSE("GPL");

static unsigned int snd_seq_simple_size(unsigned int size, unsigned int format)
{
	unsigned int result = size;
	
	if (format & SIMPLE_WAVE_16BIT)
		result <<= 1;
	if (format & SIMPLE_WAVE_STEREO)
		result <<= 1;
	return result;
}

static void snd_seq_simple_instr_free(snd_simple_ops_t *ops,
				      simple_instrument_t *ip,
				      int atomic)
{
	if (ops->remove_sample)
		ops->remove_sample(ops->private_data, ip, atomic);
}

static int snd_seq_simple_put(void *private_data, snd_seq_kinstr_t *instr,
			      char __user *instr_data, long len,
			      int atomic, int cmd)
{
	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
	simple_instrument_t *ip;
	simple_xinstrument_t ix;
	int err;
	gfp_t gfp_mask;
	unsigned int real_size;

	if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
		return -EINVAL;
	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
	/* copy instrument data */
	if (len < (long)sizeof(ix))
		return -EINVAL;
	if (copy_from_user(&ix, instr_data, sizeof(ix)))
		return -EFAULT;
	if (ix.stype != SIMPLE_STRU_INSTR)
		return -EINVAL;
	instr_data += sizeof(ix);
	len -= sizeof(ix);
	ip = (simple_instrument_t *)KINSTR_DATA(instr);
	ip->share_id[0] = le32_to_cpu(ix.share_id[0]);
	ip->share_id[1] = le32_to_cpu(ix.share_id[1]);
	ip->share_id[2] = le32_to_cpu(ix.share_id[2]);
	ip->share_id[3] = le32_to_cpu(ix.share_id[3]);
	ip->format = le32_to_cpu(ix.format);
	ip->size = le32_to_cpu(ix.size);
	ip->start = le32_to_cpu(ix.start);
	ip->loop_start = le32_to_cpu(ix.loop_start);
	ip->loop_end = le32_to_cpu(ix.loop_end);
	ip->loop_repeat = le16_to_cpu(ix.loop_repeat);
	ip->effect1 = ix.effect1;
	ip->effect1_depth = ix.effect1_depth;
	ip->effect2 = ix.effect2;
	ip->effect2_depth = ix.effect2_depth;
	real_size = snd_seq_simple_size(ip->size, ip->format);
	if (len < (long)real_size)
		return -EINVAL;
	if (ops->put_sample) {
		err = ops->put_sample(ops->private_data, ip,
				      instr_data, real_size, atomic);
		if (err < 0)
			return err;
	}
	return 0;
}

static int snd_seq_simple_get(void *private_data, snd_seq_kinstr_t *instr,
			      char __user *instr_data, long len,
			      int atomic, int cmd)
{
	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
	simple_instrument_t *ip;
	simple_xinstrument_t ix;
	int err;
	unsigned int real_size;
	
	if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
		return -EINVAL;
	if (len < (long)sizeof(ix))
		return -ENOMEM;
	memset(&ix, 0, sizeof(ix));
	ip = (simple_instrument_t *)KINSTR_DATA(instr);
	ix.stype = SIMPLE_STRU_INSTR;
	ix.share_id[0] = cpu_to_le32(ip->share_id[0]);
	ix.share_id[1] = cpu_to_le32(ip->share_id[1]);
	ix.share_id[2] = cpu_to_le32(ip->share_id[2]);
	ix.share_id[3] = cpu_to_le32(ip->share_id[3]);
	ix.format = cpu_to_le32(ip->format);
	ix.size = cpu_to_le32(ip->size);
	ix.start = cpu_to_le32(ip->start);
	ix.loop_start = cpu_to_le32(ip->loop_start);
	ix.loop_end = cpu_to_le32(ip->loop_end);
	ix.loop_repeat = cpu_to_le32(ip->loop_repeat);
	ix.effect1 = cpu_to_le16(ip->effect1);
	ix.effect1_depth = cpu_to_le16(ip->effect1_depth);
	ix.effect2 = ip->effect2;
	ix.effect2_depth = ip->effect2_depth;
	if (copy_to_user(instr_data, &ix, sizeof(ix)))
		return -EFAULT;
	instr_data += sizeof(ix);
	len -= sizeof(ix);
	real_size = snd_seq_simple_size(ip->size, ip->format);
	if (len < (long)real_size)
		return -ENOMEM;
	if (ops->get_sample) {
		err = ops->get_sample(ops->private_data, ip,
				      instr_data, real_size, atomic);
		if (err < 0)
			return err;
	}
	return 0;
}

static int snd_seq_simple_get_size(void *private_data, snd_seq_kinstr_t *instr,
				   long *size)
{
	simple_instrument_t *ip;

	ip = (simple_instrument_t *)KINSTR_DATA(instr);
	*size = sizeof(simple_xinstrument_t) + snd_seq_simple_size(ip->size, ip->format);
	return 0;
}

static int snd_seq_simple_remove(void *private_data,
			         snd_seq_kinstr_t *instr,
                                 int atomic)
{
	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
	simple_instrument_t *ip;

	ip = (simple_instrument_t *)KINSTR_DATA(instr);
	snd_seq_simple_instr_free(ops, ip, atomic);
	return 0;
}

static void snd_seq_simple_notify(void *private_data,
			          snd_seq_kinstr_t *instr,
                                  int what)
{
	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;

	if (ops->notify)
		ops->notify(ops->private_data, instr, what);
}

int snd_seq_simple_init(snd_simple_ops_t *ops,
		        void *private_data,
		        snd_seq_kinstr_ops_t *next)
{
	memset(ops, 0, sizeof(*ops));
	ops->private_data = private_data;
	ops->kops.private_data = ops;
	ops->kops.add_len = sizeof(simple_instrument_t);
	ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_SIMPLE;
	ops->kops.put = snd_seq_simple_put;
	ops->kops.get = snd_seq_simple_get;
	ops->kops.get_size = snd_seq_simple_get_size;
	ops->kops.remove = snd_seq_simple_remove;
	ops->kops.notify = snd_seq_simple_notify;
	ops->kops.next = next;
	return 0;
}

/*
 *  Init part
 */

static int __init alsa_ainstr_simple_init(void)
{
	return 0;
}

static void __exit alsa_ainstr_simple_exit(void)
{
}

module_init(alsa_ainstr_simple_init)
module_exit(alsa_ainstr_simple_exit)

EXPORT_SYMBOL(snd_seq_simple_init);
