/*
 *  linux/drivers/sound/vidc.c
 *
 *  Copyright (C) 1997-2000 by Russell King <rmk@arm.linux.org.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *  VIDC20 audio driver.
 *
 * The VIDC20 sound hardware consists of the VIDC20 itself, a DAC and a DMA
 * engine.  The DMA transfers fixed-format (16-bit little-endian linear)
 * samples to the VIDC20, which then transfers this data serially to the
 * DACs.  The samplerate is controlled by the VIDC.
 *
 * We currently support a mixer device, but it is currently non-functional.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>

#include <asm/hardware.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/hardware/iomd.h>
#include <asm/irq.h>
#include <asm/system.h>

#include "sound_config.h"
#include "vidc.h"

#ifndef _SIOC_TYPE
#define _SIOC_TYPE(x)	_IOC_TYPE(x)
#endif
#ifndef _SIOC_NR
#define _SIOC_NR(x)	_IOC_NR(x)
#endif

#define VIDC_SOUND_CLOCK	(250000)
#define VIDC_SOUND_CLOCK_EXT	(176400)

/*
 * When using SERIAL SOUND mode (external DAC), the number of physical
 * channels is fixed at 2.
 */
static int		vidc_busy;
static int		vidc_adev;
static int		vidc_audio_rate;
static char		vidc_audio_format;
static char		vidc_audio_channels;

static unsigned char	vidc_level_l[SOUND_MIXER_NRDEVICES] = {
	85,		/* master	*/
	50,		/* bass		*/
	50,		/* treble	*/
	0,		/* synth	*/
	75,		/* pcm		*/
	0,		/* speaker	*/
	100,		/* ext line	*/
	0,		/* mic		*/
	100,		/* CD		*/
	0,
};

static unsigned char	vidc_level_r[SOUND_MIXER_NRDEVICES] = {
	85,		/* master	*/
	50,		/* bass		*/
	50,		/* treble	*/
	0,		/* synth	*/
	75,		/* pcm		*/
	0,		/* speaker	*/
	100,		/* ext line	*/
	0,		/* mic		*/
	100,		/* CD		*/
	0,
};

static unsigned int	vidc_audio_volume_l;	/* left PCM vol, 0 - 65536 */
static unsigned int	vidc_audio_volume_r;	/* right PCM vol, 0 - 65536 */

extern void	vidc_update_filler(int bits, int channels);
extern int	softoss_dev;

static void
vidc_mixer_set(int mdev, unsigned int level)
{
	unsigned int lev_l = level & 0x007f;
	unsigned int lev_r = (level & 0x7f00) >> 8;
	unsigned int mlev_l, mlev_r;

	if (lev_l > 100)
		lev_l = 100;
	if (lev_r > 100)
		lev_r = 100;

#define SCALE(lev,master)	((lev) * (master) * 65536 / 10000)

	mlev_l = vidc_level_l[SOUND_MIXER_VOLUME];
	mlev_r = vidc_level_r[SOUND_MIXER_VOLUME];

	switch (mdev) {
	case SOUND_MIXER_VOLUME:
	case SOUND_MIXER_PCM:
		vidc_level_l[mdev] = lev_l;
		vidc_level_r[mdev] = lev_r;

		vidc_audio_volume_l = SCALE(lev_l, mlev_l);
		vidc_audio_volume_r = SCALE(lev_r, mlev_r);
/*printk("VIDC: PCM vol %05X %05X\n", vidc_audio_volume_l, vidc_audio_volume_r);*/
		break;
	}
#undef SCALE
}

static int vidc_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
{
	unsigned int val;
	unsigned int mdev;

	if (_SIOC_TYPE(cmd) != 'M')
		return -EINVAL;

	mdev = _SIOC_NR(cmd);

	if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
		if (get_user(val, (unsigned int __user *)arg))
			return -EFAULT;

		if (mdev < SOUND_MIXER_NRDEVICES)
			vidc_mixer_set(mdev, val);
		else
			return -EINVAL;
	}

	/*
	 * Return parameters
	 */
	switch (mdev) {
	case SOUND_MIXER_RECSRC:
		val = 0;
		break;

	case SOUND_MIXER_DEVMASK:
		val = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
		break;

	case SOUND_MIXER_STEREODEVS:
		val = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
		break;

	case SOUND_MIXER_RECMASK:
		val = 0;
		break;

	case SOUND_MIXER_CAPS:
		val = 0;
		break;

	default:
		if (mdev < SOUND_MIXER_NRDEVICES)
			val = vidc_level_l[mdev] | vidc_level_r[mdev] << 8;
		else
			return -EINVAL;
	}

	return put_user(val, (unsigned int __user *)arg) ? -EFAULT : 0;
}

static unsigned int vidc_audio_set_format(int dev, unsigned int fmt)
{
	switch (fmt) {
	default:
		fmt = AFMT_S16_LE;
	case AFMT_U8:
	case AFMT_S8:
	case AFMT_S16_LE:
		vidc_audio_format = fmt;
		vidc_update_filler(vidc_audio_format, vidc_audio_channels);
	case AFMT_QUERY:
		break;
	}
	return vidc_audio_format;
}

#define my_abs(i) ((i)<0 ? -(i) : (i))

static int vidc_audio_set_speed(int dev, int rate)
{
	if (rate) {
		unsigned int hwctrl, hwrate, hwrate_ext, rate_int, rate_ext;
		unsigned int diff_int, diff_ext;
		unsigned int newsize, new2size;

		hwctrl = 0x00000003;

		/* Using internal clock */
		hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1;
		if (hwrate < 3)
			hwrate = 3;
		if (hwrate > 255)
			hwrate = 255;

		/* Using exernal clock */
		hwrate_ext = (((VIDC_SOUND_CLOCK_EXT * 2) / rate) + 1) >> 1;
		if (hwrate_ext < 3)
			hwrate_ext = 3;
		if (hwrate_ext > 255)
			hwrate_ext = 255;

		rate_int = VIDC_SOUND_CLOCK / hwrate;
		rate_ext = VIDC_SOUND_CLOCK_EXT / hwrate_ext;

		/* Chose between external and internal clock */
		diff_int = my_abs(rate_ext-rate);
		diff_ext = my_abs(rate_int-rate);
		if (diff_ext < diff_int) {
			/*printk("VIDC: external %d %d %d\n", rate, rate_ext, hwrate_ext);*/
			hwrate=hwrate_ext;
			hwctrl=0x00000002;
			/* Allow roughly 0.4% tolerance */
			if (diff_ext > (rate/256))
				rate=rate_ext;
		} else {
			/*printk("VIDC: internal %d %d %d\n", rate, rate_int, hwrate);*/
			hwctrl=0x00000003;
			/* Allow rougly 0.4% tolerance */
			if (diff_int > (rate/256))
				rate=rate_int;
		}

		vidc_writel(0xb0000000 | (hwrate - 2));
		vidc_writel(0xb1000000 | hwctrl);

		newsize = (10000 / hwrate) & ~3;
		if (newsize < 208)
			newsize = 208;
		if (newsize > 4096)
			newsize = 4096;
		for (new2size = 128; new2size < newsize; new2size <<= 1);
		if (new2size - newsize > newsize - (new2size >> 1))
			new2size >>= 1;
		if (new2size > 4096) {
			printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n",
				newsize, new2size);
			new2size = 4096;
		}
		/*printk("VIDC: dma size %d\n", new2size);*/
		dma_bufsize = new2size;
		vidc_audio_rate = rate;
	}
	return vidc_audio_rate;
}

static short vidc_audio_set_channels(int dev, short channels)
{
	switch (channels) {
	default:
		channels = 2;
	case 1:
	case 2:
		vidc_audio_channels = channels;
		vidc_update_filler(vidc_audio_format, vidc_audio_channels);
	case 0:
		break;
	}
	return vidc_audio_channels;
}

/*
 * Open the device
 */
static int vidc_audio_open(int dev, int mode)
{
	/* This audio device does not have recording capability */
	if (mode == OPEN_READ)
		return -EPERM;

	if (vidc_busy)
		return -EBUSY;

	vidc_busy = 1;
	return 0;
}

/*
 * Close the device
 */
static void vidc_audio_close(int dev)
{
	vidc_busy = 0;
}

/*
 * Output a block via DMA to sound device.
 *
 * We just set the DMA start and count; the DMA interrupt routine
 * will take care of formatting the samples (via the appropriate
 * vidc_filler routine), and flag via vidc_audio_dma_interrupt when
 * more data is required.
 */
static void
vidc_audio_output_block(int dev, unsigned long buf, int total_count, int one)
{
	struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
	unsigned long flags;

	local_irq_save(flags);
	dma_start = buf - (unsigned long)dmap->raw_buf_phys + (unsigned long)dmap->raw_buf;
	dma_count = total_count;
	local_irq_restore(flags);
}

static void
vidc_audio_start_input(int dev, unsigned long buf, int count, int intrflag)
{
}

static int vidc_audio_prepare_for_input(int dev, int bsize, int bcount)
{
	return -EINVAL;
}

static irqreturn_t vidc_audio_dma_interrupt(void)
{
	DMAbuf_outputintr(vidc_adev, 1);
	return IRQ_HANDLED;
}

/*
 * Prepare for outputting samples.
 *
 * Each buffer that will be passed will be `bsize' bytes long,
 * with a total of `bcount' buffers.
 */
static int vidc_audio_prepare_for_output(int dev, int bsize, int bcount)
{
	struct audio_operations *adev = audio_devs[dev];

	dma_interrupt = NULL;
	adev->dmap_out->flags |= DMA_NODMA;

	return 0;
}

/*
 * Stop our current operation.
 */
static void vidc_audio_reset(int dev)
{
	dma_interrupt = NULL;
}

static int vidc_audio_local_qlen(int dev)
{
	return /*dma_count !=*/ 0;
}

static void vidc_audio_trigger(int dev, int enable_bits)
{
	struct audio_operations *adev = audio_devs[dev];

	if (enable_bits & PCM_ENABLE_OUTPUT) {
		if (!(adev->flags & DMA_ACTIVE)) {
			unsigned long flags;

			local_irq_save(flags);

			/* prevent recusion */
			adev->flags |= DMA_ACTIVE;

			dma_interrupt = vidc_audio_dma_interrupt;
			vidc_sound_dma_irq(0, NULL);
			iomd_writeb(DMA_CR_E | 0x10, IOMD_SD0CR);

			local_irq_restore(flags);
		}
	}
}

static struct audio_driver vidc_audio_driver =
{
	.owner			= THIS_MODULE,
	.open			= vidc_audio_open,
	.close			= vidc_audio_close,
	.output_block		= vidc_audio_output_block,
	.start_input		= vidc_audio_start_input,
	.prepare_for_input	= vidc_audio_prepare_for_input,
	.prepare_for_output	= vidc_audio_prepare_for_output,
	.halt_io		= vidc_audio_reset,
	.local_qlen		= vidc_audio_local_qlen,
	.trigger		= vidc_audio_trigger,
	.set_speed		= vidc_audio_set_speed,
	.set_bits		= vidc_audio_set_format,
	.set_channels		= vidc_audio_set_channels
};

static struct mixer_operations vidc_mixer_operations = {
	.owner		= THIS_MODULE,
	.id		= "VIDC",
	.name		= "VIDCsound",
	.ioctl		= vidc_mixer_ioctl
};

void vidc_update_filler(int format, int channels)
{
#define TYPE(fmt,ch) (((fmt)<<2) | ((ch)&3))

	switch (TYPE(format, channels)) {
	default:
	case TYPE(AFMT_U8, 1):
		vidc_filler = vidc_fill_1x8_u;
		break;

	case TYPE(AFMT_U8, 2):
		vidc_filler = vidc_fill_2x8_u;
		break;

	case TYPE(AFMT_S8, 1):
		vidc_filler = vidc_fill_1x8_s;
		break;

	case TYPE(AFMT_S8, 2):
		vidc_filler = vidc_fill_2x8_s;
		break;

	case TYPE(AFMT_S16_LE, 1):
		vidc_filler = vidc_fill_1x16_s;
		break;

	case TYPE(AFMT_S16_LE, 2):
		vidc_filler = vidc_fill_2x16_s;
		break;
	}
}

static void __init attach_vidc(struct address_info *hw_config)
{
	char name[32];
	int i, adev;

	sprintf(name, "VIDC %d-bit sound", hw_config->card_subtype);
	conf_printf(name, hw_config);
	memset(dma_buf, 0, sizeof(dma_buf));

	adev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, name,
			&vidc_audio_driver, sizeof(vidc_audio_driver),
			DMA_AUTOMODE, AFMT_U8 | AFMT_S8 | AFMT_S16_LE,
			NULL, hw_config->dma, hw_config->dma2);

	if (adev < 0)
		goto audio_failed;

	/*
	 * 1024 bytes => 64 buffers
	 */
	audio_devs[adev]->min_fragment = 10;
	audio_devs[adev]->mixer_dev = num_mixers;

	audio_devs[adev]->mixer_dev =
		sound_install_mixer(MIXER_DRIVER_VERSION,
				name, &vidc_mixer_operations,
				sizeof(vidc_mixer_operations), NULL);

	if (audio_devs[adev]->mixer_dev < 0)
		goto mixer_failed;

	for (i = 0; i < 2; i++) {
		dma_buf[i] = get_zeroed_page(GFP_KERNEL);
		if (!dma_buf[i]) {
			printk(KERN_ERR "%s: can't allocate required buffers\n",
				name);
			goto mem_failed;
		}
		dma_pbuf[i] = virt_to_phys((void *)dma_buf[i]);
	}

	if (sound_alloc_dma(hw_config->dma, hw_config->name)) {
		printk(KERN_ERR "%s: DMA %d is in  use\n", name, hw_config->dma);
		goto dma_failed;
	}

	if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0,
			hw_config->name, &dma_start)) {
		printk(KERN_ERR "%s: IRQ %d is in use\n", name, hw_config->irq);
		goto irq_failed;
	}
	vidc_adev = adev;
	vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8));

#if defined(CONFIG_SOUND_SOFTOSS) || defined(CONFIG_SOUND_SOFTOSS_MODULE)
	softoss_dev = adev;
#endif
	return;

irq_failed:
	sound_free_dma(hw_config->dma);
dma_failed:
mem_failed:
	for (i = 0; i < 2; i++)
		free_page(dma_buf[i]);
	sound_unload_mixerdev(audio_devs[adev]->mixer_dev);
mixer_failed:
	sound_unload_audiodev(adev);
audio_failed:
	return;
}

static int __init probe_vidc(struct address_info *hw_config)
{
	hw_config->irq		= IRQ_DMAS0;
	hw_config->dma		= DMA_VIRTUAL_SOUND;
	hw_config->dma2		= -1;
	hw_config->card_subtype	= 16;
	hw_config->name		= "VIDC20";
	return 1;
}

static void __exit unload_vidc(struct address_info *hw_config)
{
	int i, adev = vidc_adev;

	vidc_adev = -1;

	free_irq(hw_config->irq, &dma_start);
	sound_free_dma(hw_config->dma);

	if (adev >= 0) {
		sound_unload_mixerdev(audio_devs[adev]->mixer_dev);
		sound_unload_audiodev(adev);
		for (i = 0; i < 2; i++)
			free_page(dma_buf[i]);
	}
}

static struct address_info cfg;

static int __init init_vidc(void)
{
	if (probe_vidc(&cfg) == 0)
		return -ENODEV;

	attach_vidc(&cfg);

	return 0;
}

static void __exit cleanup_vidc(void)
{
	unload_vidc(&cfg);
}

module_init(init_vidc);
module_exit(cleanup_vidc);

MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("VIDC20 audio driver");
MODULE_LICENSE("GPL");
