// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for the ADB controller in the Mac I/O (Hydra) chip.
 */
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/pgtable.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/adb.h>

#include <asm/io.h>
#include <asm/hydra.h>
#include <asm/irq.h>
#include <linux/init.h>
#include <linux/ioport.h>

struct preg {
	unsigned char r;
	char pad[15];
};

struct adb_regs {
	struct preg intr;
	struct preg data[9];
	struct preg intr_enb;
	struct preg dcount;
	struct preg error;
	struct preg ctrl;
	struct preg autopoll;
	struct preg active_hi;
	struct preg active_lo;
	struct preg test;
};

/* Bits in intr and intr_enb registers */
#define DFB	1		/* data from bus */
#define TAG	2		/* transfer access grant */

/* Bits in dcount register */
#define HMB	0x0f		/* how many bytes */
#define APD	0x10		/* auto-poll data */

/* Bits in error register */
#define NRE	1		/* no response error */
#define DLE	2		/* data lost error */

/* Bits in ctrl register */
#define TAR	1		/* transfer access request */
#define DTB	2		/* data to bus */
#define CRE	4		/* command response expected */
#define ADB_RST	8		/* ADB reset */

/* Bits in autopoll register */
#define APE	1		/* autopoll enable */

static volatile struct adb_regs __iomem *adb;
static struct adb_request *current_req, *last_req;
static DEFINE_SPINLOCK(macio_lock);

static int macio_probe(void);
static int macio_init(void);
static irqreturn_t macio_adb_interrupt(int irq, void *arg);
static int macio_send_request(struct adb_request *req, int sync);
static int macio_adb_autopoll(int devs);
static void macio_adb_poll(void);
static int macio_adb_reset_bus(void);

struct adb_driver macio_adb_driver = {
	.name         = "MACIO",
	.probe        = macio_probe,
	.init         = macio_init,
	.send_request = macio_send_request,
	.autopoll     = macio_adb_autopoll,
	.poll         = macio_adb_poll,
	.reset_bus    = macio_adb_reset_bus,
};

int macio_probe(void)
{
	struct device_node *np;

	np = of_find_compatible_node(NULL, "adb", "chrp,adb0");
	if (np) {
		of_node_put(np);
		return 0;
	}
	return -ENODEV;
}

int macio_init(void)
{
	struct device_node *adbs;
	struct resource r;
	unsigned int irq;

	adbs = of_find_compatible_node(NULL, "adb", "chrp,adb0");
	if (!adbs)
		return -ENXIO;

	if (of_address_to_resource(adbs, 0, &r)) {
		of_node_put(adbs);
		return -ENXIO;
	}
	adb = ioremap(r.start, sizeof(struct adb_regs));
	if (!adb) {
		of_node_put(adbs);
		return -ENOMEM;
	}

	out_8(&adb->ctrl.r, 0);
	out_8(&adb->intr.r, 0);
	out_8(&adb->error.r, 0);
	out_8(&adb->active_hi.r, 0xff); /* for now, set all devices active */
	out_8(&adb->active_lo.r, 0xff);
	out_8(&adb->autopoll.r, APE);

	irq = irq_of_parse_and_map(adbs, 0);
	of_node_put(adbs);
	if (request_irq(irq, macio_adb_interrupt, 0, "ADB", (void *)0)) {
		iounmap(adb);
		printk(KERN_ERR "ADB: can't get irq %d\n", irq);
		return -EAGAIN;
	}
	out_8(&adb->intr_enb.r, DFB | TAG);

	printk("adb: mac-io driver 1.0 for unified ADB\n");

	return 0;
}

static int macio_adb_autopoll(int devs)
{
	unsigned long flags;
	
	spin_lock_irqsave(&macio_lock, flags);
	out_8(&adb->active_hi.r, devs >> 8);
	out_8(&adb->active_lo.r, devs);
	out_8(&adb->autopoll.r, devs? APE: 0);
	spin_unlock_irqrestore(&macio_lock, flags);
	return 0;
}

static int macio_adb_reset_bus(void)
{
	unsigned long flags;
	int timeout = 1000000;

	/* Hrm... we may want to not lock interrupts for so
	 * long ... oh well, who uses that chip anyway ? :)
	 * That function will be seldom used during boot
	 * on rare machines, so...
	 */
	spin_lock_irqsave(&macio_lock, flags);
	out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | ADB_RST);
	while ((in_8(&adb->ctrl.r) & ADB_RST) != 0) {
		if (--timeout == 0) {
			out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) & ~ADB_RST);
			spin_unlock_irqrestore(&macio_lock, flags);
			return -1;
		}
	}
	spin_unlock_irqrestore(&macio_lock, flags);
	return 0;
}

/* Send an ADB command */
static int macio_send_request(struct adb_request *req, int sync)
{
	unsigned long flags;
	int i;
	
	if (req->data[0] != ADB_PACKET)
		return -EINVAL;
	
	for (i = 0; i < req->nbytes - 1; ++i)
		req->data[i] = req->data[i+1];
	--req->nbytes;
	
	req->next = NULL;
	req->sent = 0;
	req->complete = 0;
	req->reply_len = 0;

	spin_lock_irqsave(&macio_lock, flags);
	if (current_req) {
		last_req->next = req;
		last_req = req;
	} else {
		current_req = last_req = req;
		out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
	}
	spin_unlock_irqrestore(&macio_lock, flags);
	
	if (sync) {
		while (!req->complete)
			macio_adb_poll();
	}

	return 0;
}

static irqreturn_t macio_adb_interrupt(int irq, void *arg)
{
	int i, n, err;
	struct adb_request *req = NULL;
	unsigned char ibuf[16];
	int ibuf_len = 0;
	int complete = 0;
	int autopoll = 0;
	int handled = 0;

	spin_lock(&macio_lock);
	if (in_8(&adb->intr.r) & TAG) {
		handled = 1;
		req = current_req;
		if (req) {
			/* put the current request in */
			for (i = 0; i < req->nbytes; ++i)
				out_8(&adb->data[i].r, req->data[i]);
			out_8(&adb->dcount.r, req->nbytes & HMB);
			req->sent = 1;
			if (req->reply_expected) {
				out_8(&adb->ctrl.r, DTB + CRE);
			} else {
				out_8(&adb->ctrl.r, DTB);
				current_req = req->next;
				complete = 1;
				if (current_req)
					out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
			}
		}
		out_8(&adb->intr.r, 0);
	}

	if (in_8(&adb->intr.r) & DFB) {
		handled = 1;
		err = in_8(&adb->error.r);
		if (current_req && current_req->sent) {
			/* this is the response to a command */
			req = current_req;
			if (err == 0) {
				req->reply_len = in_8(&adb->dcount.r) & HMB;
				for (i = 0; i < req->reply_len; ++i)
					req->reply[i] = in_8(&adb->data[i].r);
			}
			current_req = req->next;
			complete = 1;
			if (current_req)
				out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
		} else if (err == 0) {
			/* autopoll data */
			n = in_8(&adb->dcount.r) & HMB;
			for (i = 0; i < n; ++i)
				ibuf[i] = in_8(&adb->data[i].r);
			ibuf_len = n;
			autopoll = (in_8(&adb->dcount.r) & APD) != 0;
		}
		out_8(&adb->error.r, 0);
		out_8(&adb->intr.r, 0);
	}
	spin_unlock(&macio_lock);
	if (complete && req) {
	    void (*done)(struct adb_request *) = req->done;
	    mb();
	    req->complete = 1;
	    /* Here, we assume that if the request has a done member, the
    	     * struct request will survive to setting req->complete to 1
	     */
	    if (done)
		(*done)(req);
	}
	if (ibuf_len)
		adb_input(ibuf, ibuf_len, autopoll);

	return IRQ_RETVAL(handled);
}

static void macio_adb_poll(void)
{
	unsigned long flags;

	local_irq_save(flags);
	if (in_8(&adb->intr.r) != 0)
		macio_adb_interrupt(0, NULL);
	local_irq_restore(flags);
}
