// SPDX-License-Identifier: GPL-2.0-only
/*
 * i2sbus driver -- bus control routines
 *
 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
 */

#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/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;
}
