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

#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/slab.h>

#include <asm/io.h>
#include <asm/prom.h>
#include <asm/macio.h>
#include <asm/pmac_feature.h>
#include <asm/pmac_pfunc.h>
#include <asm/keylargo.h>

#include "i2sbus.h"

int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
{
	*c = kzalloc(sizeof(struct i2sbus_control), GFP_KERNEL);
	if (!*c)
		return -ENOMEM;

	INIT_LIST_HEAD(&(*c)->list);

	(*c)->macio = dev->bus->chip;
	return 0;
}

void i2sbus_control_destroy(struct i2sbus_control *c)
{
	kfree(c);
}

/* this is serialised externally */
int i2sbus_control_add_dev(struct i2sbus_control *c,
			   struct i2sbus_dev *i2sdev)
{
	struct device_node *np;

	np = i2sdev->sound.ofdev.dev.of_node;
	i2sdev->enable = pmf_find_function(np, "enable");
	i2sdev->cell_enable = pmf_find_function(np, "cell-enable");
	i2sdev->clock_enable = pmf_find_function(np, "clock-enable");
	i2sdev->cell_disable = pmf_find_function(np, "cell-disable");
	i2sdev->clock_disable = pmf_find_function(np, "clock-disable");

	/* if the bus number is not 0 or 1 we absolutely need to use
	 * the platform functions -- there's nothing in Darwin that
	 * would allow seeing a system behind what the FCRs are then,
	 * and I don't want to go parsing a bunch of platform functions
	 * by hand to try finding a system... */
	if (i2sdev->bus_number != 0 && i2sdev->bus_number != 1 &&
	    (!i2sdev->enable ||
	     !i2sdev->cell_enable || !i2sdev->clock_enable ||
	     !i2sdev->cell_disable || !i2sdev->clock_disable)) {
		pmf_put_function(i2sdev->enable);
		pmf_put_function(i2sdev->cell_enable);
		pmf_put_function(i2sdev->clock_enable);
		pmf_put_function(i2sdev->cell_disable);
		pmf_put_function(i2sdev->clock_disable);
		return -ENODEV;
	}

	list_add(&i2sdev->item, &c->list);

	return 0;
}

void i2sbus_control_remove_dev(struct i2sbus_control *c,
			       struct i2sbus_dev *i2sdev)
{
	/* this is serialised externally */
	list_del(&i2sdev->item);
	if (list_empty(&c->list))
		i2sbus_control_destroy(c);
}

int i2sbus_control_enable(struct i2sbus_control *c,
			  struct i2sbus_dev *i2sdev)
{
	struct pmf_args args = { .count = 0 };
	struct macio_chip *macio = c->macio;

	if (i2sdev->enable)
		return pmf_call_one(i2sdev->enable, &args);

	if (macio == NULL || macio->base == NULL)
		return -ENODEV;

	switch (i2sdev->bus_number) {
	case 0:
		/* these need to be locked or done through
		 * newly created feature calls! */
		MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
		break;
	case 1:
		MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_ENABLE);
		break;
	default:
		return -ENODEV;
	}
	return 0;
}

int i2sbus_control_cell(struct i2sbus_control *c,
			struct i2sbus_dev *i2sdev,
			int enable)
{
	struct pmf_args args = { .count = 0 };
	struct macio_chip *macio = c->macio;

	switch (enable) {
	case 0:
		if (i2sdev->cell_disable)
			return pmf_call_one(i2sdev->cell_disable, &args);
		break;
	case 1:
		if (i2sdev->cell_enable)
			return pmf_call_one(i2sdev->cell_enable, &args);
		break;
	default:
		printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
		return -ENODEV;
	}

	if (macio == NULL || macio->base == NULL)
		return -ENODEV;

	switch (i2sdev->bus_number) {
	case 0:
		if (enable)
			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
		else
			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
		break;
	case 1:
		if (enable)
			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
		else
			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
		break;
	default:
		return -ENODEV;
	}
	return 0;
}

int i2sbus_control_clock(struct i2sbus_control *c,
			 struct i2sbus_dev *i2sdev,
			 int enable)
{
	struct pmf_args args = { .count = 0 };
	struct macio_chip *macio = c->macio;

	switch (enable) {
	case 0:
		if (i2sdev->clock_disable)
			return pmf_call_one(i2sdev->clock_disable, &args);
		break;
	case 1:
		if (i2sdev->clock_enable)
			return pmf_call_one(i2sdev->clock_enable, &args);
		break;
	default:
		printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
		return -ENODEV;
	}

	if (macio == NULL || macio->base == NULL)
		return -ENODEV;

	switch (i2sdev->bus_number) {
	case 0:
		if (enable)
			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
		else
			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
		break;
	case 1:
		if (enable)
			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
		else
			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
		break;
	default:
		return -ENODEV;
	}
	return 0;
}
