/*
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/videodev.h>
#include <linux/init.h>
#include <linux/kdev_t.h>
#include <linux/sound.h>
#include <linux/soundcard.h>

#include <asm/semaphore.h>
#include <asm/uaccess.h>


#define DEV_MAX  4

static int devnr = -1;
module_param(devnr, int, 0644);

MODULE_AUTHOR("Gerd Knorr");
MODULE_LICENSE("GPL");

/* ----------------------------------------------------------------------- */

struct TVMIXER {
	struct i2c_client *dev;
	int minor;
	int count;
};

static struct TVMIXER devices[DEV_MAX];

static int tvmixer_adapters(struct i2c_adapter *adap);
static int tvmixer_clients(struct i2c_client *client);

/* ----------------------------------------------------------------------- */

static int mix_to_v4l(int i)
{
	int r;

	r = ((i & 0xff) * 65536 + 50) / 100;
	if (r > 65535) r = 65535;
	if (r <     0) r =     0;
	return r;
}

static int v4l_to_mix(int i)
{
	int r;

	r = (i * 100 + 32768) / 65536;
	if (r > 100) r = 100;
	if (r <   0) r =   0;
	return r | (r << 8);
}

static int v4l_to_mix2(int l, int r)
{
	r = (r * 100 + 32768) / 65536;
	if (r > 100) r = 100;
	if (r <   0) r =   0;
	l = (l * 100 + 32768) / 65536;
	if (l > 100) l = 100;
	if (l <   0) l =   0;
	return (r << 8) | l;
}

static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct video_audio va;
	int left,right,ret,val = 0;
	struct TVMIXER *mix = file->private_data;
	struct i2c_client *client = mix->dev;
	void __user *argp = (void __user *)arg;
	int __user *p = argp;

	if (NULL == client)
		return -ENODEV;

	if (cmd == SOUND_MIXER_INFO) {
		mixer_info info;
		strlcpy(info.id, "tv card", sizeof(info.id));
		strlcpy(info.name, client->name, sizeof(info.name));
		info.modify_counter = 42 /* FIXME */;
		if (copy_to_user(argp, &info, sizeof(info)))
			return -EFAULT;
		return 0;
	}
	if (cmd == SOUND_OLD_MIXER_INFO) {
		_old_mixer_info info;
		strlcpy(info.id, "tv card", sizeof(info.id));
		strlcpy(info.name, client->name, sizeof(info.name));
		if (copy_to_user(argp, &info, sizeof(info)))
			return -EFAULT;
		return 0;
	}
	if (cmd == OSS_GETVERSION)
		return put_user(SOUND_VERSION, p);

	if (_SIOC_DIR(cmd) & _SIOC_WRITE)
		if (get_user(val, p))
			return -EFAULT;

	/* read state */
	memset(&va,0,sizeof(va));
	client->driver->command(client,VIDIOCGAUDIO,&va);

	switch (cmd) {
	case MIXER_READ(SOUND_MIXER_RECMASK):
	case MIXER_READ(SOUND_MIXER_CAPS):
	case MIXER_READ(SOUND_MIXER_RECSRC):
	case MIXER_WRITE(SOUND_MIXER_RECSRC):
		ret = 0;
		break;

	case MIXER_READ(SOUND_MIXER_STEREODEVS):
		ret = SOUND_MASK_VOLUME;
		break;
	case MIXER_READ(SOUND_MIXER_DEVMASK):
		ret = SOUND_MASK_VOLUME;
		if (va.flags & VIDEO_AUDIO_BASS)
			ret |= SOUND_MASK_BASS;
		if (va.flags & VIDEO_AUDIO_TREBLE)
			ret |= SOUND_MASK_TREBLE;
		break;

	case MIXER_WRITE(SOUND_MIXER_VOLUME):
		left  = mix_to_v4l(val);
		right = mix_to_v4l(val >> 8);
		va.volume  = max(left,right);
		va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1);
		va.balance = (left<right) ? (65535-va.balance) : va.balance;
		if (va.volume)
			va.flags &= ~VIDEO_AUDIO_MUTE;
		client->driver->command(client,VIDIOCSAUDIO,&va);
		client->driver->command(client,VIDIOCGAUDIO,&va);
		/* fall throuth */
	case MIXER_READ(SOUND_MIXER_VOLUME):
		left  = (min(65536 - va.balance,32768) *
			 va.volume) / 32768;
		right = (min(va.balance,(u16)32768) *
			 va.volume) / 32768;
		ret = v4l_to_mix2(left,right);
		break;

	case MIXER_WRITE(SOUND_MIXER_BASS):
		va.bass = mix_to_v4l(val);
		client->driver->command(client,VIDIOCSAUDIO,&va);
		client->driver->command(client,VIDIOCGAUDIO,&va);
		/* fall throuth  */
	case MIXER_READ(SOUND_MIXER_BASS):
		ret = v4l_to_mix(va.bass);
		break;

	case MIXER_WRITE(SOUND_MIXER_TREBLE):
		va.treble = mix_to_v4l(val);
		client->driver->command(client,VIDIOCSAUDIO,&va);
		client->driver->command(client,VIDIOCGAUDIO,&va);
		/* fall throuth */
	case MIXER_READ(SOUND_MIXER_TREBLE):
		ret = v4l_to_mix(va.treble);
		break;

	default:
		return -EINVAL;
	}
	if (put_user(ret, p))
		return -EFAULT;
	return 0;
}

static int tvmixer_open(struct inode *inode, struct file *file)
{
	int i, minor = iminor(inode);
	struct TVMIXER *mix = NULL;
	struct i2c_client *client = NULL;

	for (i = 0; i < DEV_MAX; i++) {
		if (devices[i].minor == minor) {
			mix = devices+i;
			client = mix->dev;
			break;
		}
	}

	if (NULL == client)
		return -ENODEV;

	/* lock bttv in memory while the mixer is in use  */
	file->private_data = mix;
	if (client->adapter->owner)
		try_module_get(client->adapter->owner);
	return 0;
}

static int tvmixer_release(struct inode *inode, struct file *file)
{
	struct TVMIXER *mix = file->private_data;
	struct i2c_client *client;

	client = mix->dev;
	if (NULL == client) {
		return -ENODEV;
	}

	module_put(client->adapter->owner);
	return 0;
}

static struct i2c_driver driver = {
	.driver = {
		.name    = "tvmixer",
	},
	.id              = I2C_DRIVERID_TVMIXER,
	.detach_adapter  = tvmixer_adapters,
	.attach_adapter  = tvmixer_adapters,
	.detach_client   = tvmixer_clients,
};

static const struct file_operations tvmixer_fops = {
	.owner		= THIS_MODULE,
	.llseek         = no_llseek,
	.ioctl          = tvmixer_ioctl,
	.open           = tvmixer_open,
	.release        = tvmixer_release,
};

/* ----------------------------------------------------------------------- */

static int tvmixer_adapters(struct i2c_adapter *adap)
{
	struct list_head  *item;
	struct i2c_client *client;

	list_for_each(item,&adap->clients) {
		client = list_entry(item, struct i2c_client, list);
		tvmixer_clients(client);
	}
	return 0;
}

static int tvmixer_clients(struct i2c_client *client)
{
	struct video_audio va;
	int i,minor;

	if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
		return -1;

	/* unregister ?? */
	for (i = 0; i < DEV_MAX; i++) {
		if (devices[i].dev == client) {
			/* unregister */
			unregister_sound_mixer(devices[i].minor);
			devices[i].dev = NULL;
			devices[i].minor = -1;
			printk("tvmixer: %s unregistered (#1)\n",
			       client->name);
			return 0;
		}
	}

	/* look for a free slot */
	for (i = 0; i < DEV_MAX; i++)
		if (NULL == devices[i].dev)
			break;
	if (i == DEV_MAX) {
		printk(KERN_WARNING "tvmixer: DEV_MAX too small\n");
		return -1;
	}

	/* audio chip with mixer ??? */
	if (NULL == client->driver->command)
		return -1;
	memset(&va,0,sizeof(va));
	if (0 != client->driver->command(client,VIDIOCGAUDIO,&va))
		return -1;
	if (0 == (va.flags & VIDEO_AUDIO_VOLUME))
		return -1;

	/* everything is fine, register */
	if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) {
		printk(KERN_ERR "tvmixer: cannot allocate mixer device\n");
		return -1;
	}

	devices[i].minor = minor;
	devices[i].count = 0;
	devices[i].dev   = client;
	printk("tvmixer: %s (%s) registered with minor %d\n",
	       client->name,client->adapter->name,minor);

	return 0;
}

/* ----------------------------------------------------------------------- */

static int __init tvmixer_init_module(void)
{
	int i;

	for (i = 0; i < DEV_MAX; i++)
		devices[i].minor = -1;

	return i2c_add_driver(&driver);
}

static void __exit tvmixer_cleanup_module(void)
{
	int i;

	i2c_del_driver(&driver);
	for (i = 0; i < DEV_MAX; i++) {
		if (devices[i].minor != -1) {
			unregister_sound_mixer(devices[i].minor);
			printk("tvmixer: %s unregistered (#2)\n",
			       devices[i].dev->name);
		}
	}
}

module_init(tvmixer_init_module);
module_exit(tvmixer_cleanup_module);

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-basic-offset: 8
 * End:
 */
