/*
 * i2sbus driver
 *
 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
 *
 * GPL v2, can be found in COPYING.
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>

#include <sound/core.h>

#include <asm/macio.h>
#include <asm/dbdma.h>

#include "../soundbus.h"
#include "i2sbus.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_DESCRIPTION("Apple Soundbus: I2S support");

static int force;
module_param(force, int, 0444);
MODULE_PARM_DESC(force, "Force loading i2sbus even when"
			" no layout-id property is present");

static struct of_device_id i2sbus_match[] = {
	{ .name = "i2s" },
	{ }
};

MODULE_DEVICE_TABLE(of, i2sbus_match);

static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
				       struct dbdma_command_mem *r,
				       int numcmds)
{
	/* one more for rounding, one for branch back, one for stop command */
	r->size = (numcmds + 3) * sizeof(struct dbdma_cmd);
	/* We use the PCI APIs for now until the generic one gets fixed
	 * enough or until we get some macio-specific versions
	 */
	r->space = dma_alloc_coherent(
			&macio_get_pci_dev(i2sdev->macio)->dev,
			r->size,
			&r->bus_addr,
			GFP_KERNEL);

	if (!r->space) return -ENOMEM;

	memset(r->space, 0, r->size);
	r->cmds = (void*)DBDMA_ALIGN(r->space);
	r->bus_cmd_start = r->bus_addr +
			   (dma_addr_t)((char*)r->cmds - (char*)r->space);

	return 0;
}

static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
				       struct dbdma_command_mem *r)
{
	if (!r->space) return;
	
	dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
			    r->size, r->space, r->bus_addr);
}

static void i2sbus_release_dev(struct device *dev)
{
	struct i2sbus_dev *i2sdev;
	int i;

	i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev);

 	if (i2sdev->intfregs) iounmap(i2sdev->intfregs);
 	if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma);
 	if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma);
	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
		if (i2sdev->allocated_resource[i])
			release_and_free_resource(i2sdev->allocated_resource[i]);
	free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring);
	free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring);
	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
		free_irq(i2sdev->interrupts[i], i2sdev);
	i2sbus_control_remove_dev(i2sdev->control, i2sdev);
	mutex_destroy(&i2sdev->lock);
	kfree(i2sdev);
}

static irqreturn_t i2sbus_bus_intr(int irq, void *devid)
{
	struct i2sbus_dev *dev = devid;
	u32 intreg;

	spin_lock(&dev->low_lock);
	intreg = in_le32(&dev->intfregs->intr_ctl);

	/* acknowledge interrupt reasons */
	out_le32(&dev->intfregs->intr_ctl, intreg);

	spin_unlock(&dev->low_lock);

	return IRQ_HANDLED;
}


/*
 * XXX FIXME: We test the layout_id's here to get the proper way of
 * mapping in various registers, thanks to bugs in Apple device-trees.
 * We could instead key off the machine model and the name of the i2s
 * node (i2s-a). This we'll do when we move it all to macio_asic.c
 * and have that export items for each sub-node too.
 */
static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
				     int layout, struct resource *res)
{
	struct device_node *parent;
	int pindex, rc = -ENXIO;
	const u32 *reg;

	/* Machines with layout 76 and 36 (K2 based) have a weird device
	 * tree what we need to special case.
	 * Normal machines just fetch the resource from the i2s-X node.
	 * Darwin further divides normal machines into old and new layouts
	 * with a subtely different code path but that doesn't seem necessary
	 * in practice, they just bloated it. In addition, even on our K2
	 * case the i2s-modem node, if we ever want to handle it, uses the
	 * normal layout
	 */
	if (layout != 76 && layout != 36)
		return of_address_to_resource(np, index, res);

	parent = of_get_parent(np);
	pindex = (index == aoa_resource_i2smmio) ? 0 : 1;
	rc = of_address_to_resource(parent, pindex, res);
	if (rc)
		goto bail;
	reg = of_get_property(np, "reg", NULL);
	if (reg == NULL) {
		rc = -ENXIO;
		goto bail;
	}
	res->start += reg[index * 2];
	res->end = res->start + reg[index * 2 + 1] - 1;
 bail:
	of_node_put(parent);
	return rc;
}

/* FIXME: look at device node refcounting */
static int i2sbus_add_dev(struct macio_dev *macio,
			  struct i2sbus_control *control,
			  struct device_node *np)
{
	struct i2sbus_dev *dev;
	struct device_node *child = NULL, *sound = NULL;
	struct resource *r;
	int i, layout = 0, rlen;
	static const char *rnames[] = { "i2sbus: %s (control)",
					"i2sbus: %s (tx)",
					"i2sbus: %s (rx)" };
	static irq_handler_t ints[] = {
		i2sbus_bus_intr,
		i2sbus_tx_intr,
		i2sbus_rx_intr
	};

	if (strlen(np->name) != 5)
		return 0;
	if (strncmp(np->name, "i2s-", 4))
		return 0;

	dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL);
	if (!dev)
		return 0;

	i = 0;
	while ((child = of_get_next_child(np, child))) {
		if (strcmp(child->name, "sound") == 0) {
			i++;
			sound = child;
		}
	}
	if (i == 1) {
		const u32 *layout_id =
			of_get_property(sound, "layout-id", NULL);
		if (layout_id) {
			layout = *layout_id;
			snprintf(dev->sound.modalias, 32,
				 "sound-layout-%d", layout);
			force = 1;
		}
	}
	/* for the time being, until we can handle non-layout-id
	 * things in some fabric, refuse to attach if there is no
	 * layout-id property or we haven't been forced to attach.
	 * When there are two i2s busses and only one has a layout-id,
	 * then this depends on the order, but that isn't important
	 * either as the second one in that case is just a modem. */
	if (!force) {
		kfree(dev);
		return -ENODEV;
	}

	mutex_init(&dev->lock);
	spin_lock_init(&dev->low_lock);
	dev->sound.ofdev.node = np;
	dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask;
	dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask;
	dev->sound.ofdev.dev.parent = &macio->ofdev.dev;
	dev->sound.ofdev.dev.release = i2sbus_release_dev;
	dev->sound.attach_codec = i2sbus_attach_codec;
	dev->sound.detach_codec = i2sbus_detach_codec;
	dev->sound.pcmid = -1;
	dev->macio = macio;
	dev->control = control;
	dev->bus_number = np->name[4] - 'a';
	INIT_LIST_HEAD(&dev->sound.codec_list);

	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
		dev->interrupts[i] = -1;
		snprintf(dev->rnames[i], sizeof(dev->rnames[i]),
			 rnames[i], np->name);
	}
	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
		int irq = irq_of_parse_and_map(np, i);
		if (request_irq(irq, ints[i], 0, dev->rnames[i], dev))
			goto err;
		dev->interrupts[i] = irq;
	}


	/* Resource handling is problematic as some device-trees contain
	 * useless crap (ugh ugh ugh). We work around that here by calling
	 * specific functions for calculating the appropriate resources.
	 *
	 * This will all be moved to macio_asic.c at one point
	 */
	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
		if (i2sbus_get_and_fixup_rsrc(np,i,layout,&dev->resources[i]))
			goto err;
		/* If only we could use our resource dev->resources[i]...
		 * but request_resource doesn't know about parents and
		 * contained resources...
		 */
		dev->allocated_resource[i] = 
			request_mem_region(dev->resources[i].start,
					   dev->resources[i].end -
					   dev->resources[i].start + 1,
					   dev->rnames[i]);
		if (!dev->allocated_resource[i]) {
			printk(KERN_ERR "i2sbus: failed to claim resource %d!\n", i);
			goto err;
		}
	}

	r = &dev->resources[aoa_resource_i2smmio];
	rlen = r->end - r->start + 1;
	if (rlen < sizeof(struct i2s_interface_regs))
		goto err;
	dev->intfregs = ioremap(r->start, rlen);

	r = &dev->resources[aoa_resource_txdbdma];
	rlen = r->end - r->start + 1;
	if (rlen < sizeof(struct dbdma_regs))
		goto err;
	dev->out.dbdma = ioremap(r->start, rlen);

	r = &dev->resources[aoa_resource_rxdbdma];
	rlen = r->end - r->start + 1;
	if (rlen < sizeof(struct dbdma_regs))
		goto err;
	dev->in.dbdma = ioremap(r->start, rlen);

	if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma)
		goto err;

	if (alloc_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring,
					MAX_DBDMA_COMMANDS))
		goto err;
	if (alloc_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring,
					MAX_DBDMA_COMMANDS))
		goto err;

	if (i2sbus_control_add_dev(dev->control, dev)) {
		printk(KERN_ERR "i2sbus: control layer didn't like bus\n");
		goto err;
	}

	if (soundbus_add_one(&dev->sound)) {
		printk(KERN_DEBUG "i2sbus: device registration error!\n");
		goto err;
	}

	/* enable this cell */
	i2sbus_control_cell(dev->control, dev, 1);
	i2sbus_control_enable(dev->control, dev);
	i2sbus_control_clock(dev->control, dev, 1);

	return 1;
 err:
	for (i=0;i<3;i++)
		if (dev->interrupts[i] != -1)
			free_irq(dev->interrupts[i], dev);
	free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring);
	free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring);
	if (dev->intfregs) iounmap(dev->intfregs);
	if (dev->out.dbdma) iounmap(dev->out.dbdma);
	if (dev->in.dbdma) iounmap(dev->in.dbdma);
	for (i=0;i<3;i++)
		if (dev->allocated_resource[i])
			release_and_free_resource(dev->allocated_resource[i]);
	mutex_destroy(&dev->lock);
	kfree(dev);
	return 0;
}

static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
{
	struct device_node *np = NULL;
	int got = 0, err;
	struct i2sbus_control *control = NULL;

	err = i2sbus_control_init(dev, &control);
	if (err)
		return err;
	if (!control) {
		printk(KERN_ERR "i2sbus_control_init API breakage\n");
		return -ENODEV;
	}

	while ((np = of_get_next_child(dev->ofdev.node, np))) {
		if (of_device_is_compatible(np, "i2sbus") ||
		    of_device_is_compatible(np, "i2s-modem")) {
			got += i2sbus_add_dev(dev, control, np);
		}
	}

	if (!got) {
		/* found none, clean up */
		i2sbus_control_destroy(control);
		return -ENODEV;
	}

	dev->ofdev.dev.driver_data = control;

	return 0;
}

static int i2sbus_remove(struct macio_dev* dev)
{
	struct i2sbus_control *control = dev->ofdev.dev.driver_data;
	struct i2sbus_dev *i2sdev, *tmp;

	list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
		soundbus_remove_one(&i2sdev->sound);

	return 0;
}

#ifdef CONFIG_PM
static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
{
	struct i2sbus_control *control = dev->ofdev.dev.driver_data;
	struct codec_info_item *cii;
	struct i2sbus_dev* i2sdev;
	int err, ret = 0;

	list_for_each_entry(i2sdev, &control->list, item) {
		/* Notify Alsa */
		if (i2sdev->sound.pcm) {
			/* Suspend PCM streams */
			snd_pcm_suspend_all(i2sdev->sound.pcm);
		}

		/* Notify codecs */
		list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
			err = 0;
			if (cii->codec->suspend)
				err = cii->codec->suspend(cii, state);
			if (err)
				ret = err;
		}

		/* wait until streams are stopped */
		i2sbus_wait_for_stop_both(i2sdev);
	}

	return ret;
}

static int i2sbus_resume(struct macio_dev* dev)
{
	struct i2sbus_control *control = dev->ofdev.dev.driver_data;
	struct codec_info_item *cii;
	struct i2sbus_dev* i2sdev;
	int err, ret = 0;

	list_for_each_entry(i2sdev, &control->list, item) {
		/* reset i2s bus format etc. */
		i2sbus_pcm_prepare_both(i2sdev);

		/* Notify codecs so they can re-initialize */
		list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
			err = 0;
			if (cii->codec->resume)
				err = cii->codec->resume(cii);
			if (err)
				ret = err;
		}
	}

	return ret;
}
#endif /* CONFIG_PM */

static int i2sbus_shutdown(struct macio_dev* dev)
{
	return 0;
}

static struct macio_driver i2sbus_drv = {
	.name = "soundbus-i2s",
	.owner = THIS_MODULE,
	.match_table = i2sbus_match,
	.probe = i2sbus_probe,
	.remove = i2sbus_remove,
#ifdef CONFIG_PM
	.suspend = i2sbus_suspend,
	.resume = i2sbus_resume,
#endif
	.shutdown = i2sbus_shutdown,
};

static int __init soundbus_i2sbus_init(void)
{
	return macio_register_driver(&i2sbus_drv);
}

static void __exit soundbus_i2sbus_exit(void)
{
	macio_unregister_driver(&i2sbus_drv);
}

module_init(soundbus_i2sbus_init);
module_exit(soundbus_i2sbus_exit);
