/*
 * IEEE 1284.3 Parallel port daisy chain and multiplexor code
 * 
 * Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 * ??-12-1998: Initial implementation.
 * 31-01-1999: Make port-cloning transparent.
 * 13-02-1999: Move DeviceID technique from parport_probe.
 * 13-03-1999: Get DeviceID from non-IEEE 1284.3 devices too.
 * 22-02-2000: Count devices that are actually detected.
 *
 * Any part of this program may be used in documents licensed under
 * the GNU Free Documentation License, Version 1.1 or any later version
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/parport.h>
#include <linux/delay.h>
#include <linux/sched.h>

#include <asm/current.h>
#include <asm/uaccess.h>

#undef DEBUG

#ifdef DEBUG
#define DPRINTK(stuff...) printk (stuff)
#else
#define DPRINTK(stuff...)
#endif

static struct daisydev {
	struct daisydev *next;
	struct parport *port;
	int daisy;
	int devnum;
} *topology = NULL;
static DEFINE_SPINLOCK(topology_lock);

static int numdevs = 0;

/* Forward-declaration of lower-level functions. */
static int mux_present (struct parport *port);
static int num_mux_ports (struct parport *port);
static int select_port (struct parport *port);
static int assign_addrs (struct parport *port);

/* Add a device to the discovered topology. */
static void add_dev (int devnum, struct parport *port, int daisy)
{
	struct daisydev *newdev, **p;
	newdev = kmalloc (sizeof (struct daisydev), GFP_KERNEL);
	if (newdev) {
		newdev->port = port;
		newdev->daisy = daisy;
		newdev->devnum = devnum;
		spin_lock(&topology_lock);
		for (p = &topology; *p && (*p)->devnum<devnum; p = &(*p)->next)
			;
		newdev->next = *p;
		*p = newdev;
		spin_unlock(&topology_lock);
	}
}

/* Clone a parport (actually, make an alias). */
static struct parport *clone_parport (struct parport *real, int muxport)
{
	struct parport *extra = parport_register_port (real->base,
						       real->irq,
						       real->dma,
						       real->ops);
	if (extra) {
		extra->portnum = real->portnum;
		extra->physport = real;
		extra->muxport = muxport;
		real->slaves[muxport-1] = extra;
	}

	return extra;
}

/* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains.
 * Return value is number of devices actually detected. */
int parport_daisy_init (struct parport *port)
{
	int detected = 0;
	char *deviceid;
	static const char *th[] = { /*0*/"th", "st", "nd", "rd", "th" };
	int num_ports;
	int i;
	int last_try = 0;

again:
	/* Because this is called before any other devices exist,
	 * we don't have to claim exclusive access.  */

	/* If mux present on normal port, need to create new
	 * parports for each extra port. */
	if (port->muxport < 0 && mux_present (port) &&
	    /* don't be fooled: a mux must have 2 or 4 ports. */
	    ((num_ports = num_mux_ports (port)) == 2 || num_ports == 4)) {
		/* Leave original as port zero. */
		port->muxport = 0;
		printk (KERN_INFO
			"%s: 1st (default) port of %d-way multiplexor\n",
			port->name, num_ports);
		for (i = 1; i < num_ports; i++) {
			/* Clone the port. */
			struct parport *extra = clone_parport (port, i);
			if (!extra) {
				if (signal_pending (current))
					break;

				schedule ();
				continue;
			}

			printk (KERN_INFO
				"%s: %d%s port of %d-way multiplexor on %s\n",
				extra->name, i + 1, th[i + 1], num_ports,
				port->name);

			/* Analyse that port too.  We won't recurse
			   forever because of the 'port->muxport < 0'
			   test above. */
			parport_daisy_init(extra);
		}
	}

	if (port->muxport >= 0)
		select_port (port);

	parport_daisy_deselect_all (port);
	detected += assign_addrs (port);

	/* Count the potential legacy device at the end. */
	add_dev (numdevs++, port, -1);

	/* Find out the legacy device's IEEE 1284 device ID. */
	deviceid = kmalloc (1000, GFP_KERNEL);
	if (deviceid) {
		if (parport_device_id (numdevs - 1, deviceid, 1000) > 2)
			detected++;

		kfree (deviceid);
	}

	if (!detected && !last_try) {
		/* No devices were detected.  Perhaps they are in some
                   funny state; let's try to reset them and see if
                   they wake up. */
		parport_daisy_fini (port);
		parport_write_control (port, PARPORT_CONTROL_SELECT);
		udelay (50);
		parport_write_control (port,
				       PARPORT_CONTROL_SELECT |
				       PARPORT_CONTROL_INIT);
		udelay (50);
		last_try = 1;
		goto again;
	}

	return detected;
}

/* Forget about devices on a physical port. */
void parport_daisy_fini (struct parport *port)
{
	struct daisydev **p;

	spin_lock(&topology_lock);
	p = &topology;
	while (*p) {
		struct daisydev *dev = *p;
		if (dev->port != port) {
			p = &dev->next;
			continue;
		}
		*p = dev->next;
		kfree(dev);
	}

	/* Gaps in the numbering could be handled better.  How should
           someone enumerate through all IEEE1284.3 devices in the
           topology?. */
	if (!topology) numdevs = 0;
	spin_unlock(&topology_lock);
	return;
}

/**
 *	parport_open - find a device by canonical device number
 *	@devnum: canonical device number
 *	@name: name to associate with the device
 *	@pf: preemption callback
 *	@kf: kick callback
 *	@irqf: interrupt handler
 *	@flags: registration flags
 *	@handle: driver data
 *
 *	This function is similar to parport_register_device(), except
 *	that it locates a device by its number rather than by the port
 *	it is attached to.
 *
 *	All parameters except for @devnum are the same as for
 *	parport_register_device().  The return value is the same as
 *	for parport_register_device().
 **/

struct pardevice *parport_open (int devnum, const char *name,
				int (*pf) (void *), void (*kf) (void *),
				void (*irqf) (int, void *, struct pt_regs *),
				int flags, void *handle)
{
	struct daisydev *p = topology;
	struct parport *port;
	struct pardevice *dev;
	int daisy;

	spin_lock(&topology_lock);
	while (p && p->devnum != devnum)
		p = p->next;

	if (!p) {
		spin_unlock(&topology_lock);
		return NULL;
	}

	daisy = p->daisy;
	port = parport_get_port(p->port);
	spin_unlock(&topology_lock);

	dev = parport_register_device (port, name, pf, kf,
				       irqf, flags, handle);
	parport_put_port(port);
	if (!dev)
		return NULL;

	dev->daisy = daisy;

	/* Check that there really is a device to select. */
	if (daisy >= 0) {
		int selected;
		parport_claim_or_block (dev);
		selected = port->daisy;
		parport_release (dev);

		if (selected != port->daisy) {
			/* No corresponding device. */
			parport_unregister_device (dev);
			return NULL;
		}
	}

	return dev;
}

/**
 *	parport_close - close a device opened with parport_open()
 *	@dev: device to close
 *
 *	This is to parport_open() as parport_unregister_device() is to
 *	parport_register_device().
 **/

void parport_close (struct pardevice *dev)
{
	parport_unregister_device (dev);
}

/**
 *	parport_device_num - convert device coordinates
 *	@parport: parallel port number
 *	@mux: multiplexor port number (-1 for no multiplexor)
 *	@daisy: daisy chain address (-1 for no daisy chain address)
 *
 *	This tries to locate a device on the given parallel port,
 *	multiplexor port and daisy chain address, and returns its
 *	device number or -NXIO if no device with those coordinates
 *	exists.
 **/

int parport_device_num (int parport, int mux, int daisy)
{
	int res = -ENXIO;
	struct daisydev *dev;

	spin_lock(&topology_lock);
	dev = topology;
	while (dev && dev->port->portnum != parport &&
	       dev->port->muxport != mux && dev->daisy != daisy)
		dev = dev->next;
	if (dev)
		res = dev->devnum;
	spin_unlock(&topology_lock);

	return res;
}

/* Send a daisy-chain-style CPP command packet. */
static int cpp_daisy (struct parport *port, int cmd)
{
	unsigned char s;

	parport_data_forward (port);
	parport_write_data (port, 0xaa); udelay (2);
	parport_write_data (port, 0x55); udelay (2);
	parport_write_data (port, 0x00); udelay (2);
	parport_write_data (port, 0xff); udelay (2);
	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
					  | PARPORT_STATUS_PAPEROUT
					  | PARPORT_STATUS_SELECT
					  | PARPORT_STATUS_ERROR);
	if (s != (PARPORT_STATUS_BUSY
		  | PARPORT_STATUS_PAPEROUT
		  | PARPORT_STATUS_SELECT
		  | PARPORT_STATUS_ERROR)) {
		DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n",
			 port->name, s);
		return -ENXIO;
	}

	parport_write_data (port, 0x87); udelay (2);
	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
					  | PARPORT_STATUS_PAPEROUT
					  | PARPORT_STATUS_SELECT
					  | PARPORT_STATUS_ERROR);
	if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
		DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n",
			 port->name, s);
		return -ENXIO;
	}

	parport_write_data (port, 0x78); udelay (2);
	parport_write_data (port, cmd); udelay (2);
	parport_frob_control (port,
			      PARPORT_CONTROL_STROBE,
			      PARPORT_CONTROL_STROBE);
	udelay (1);
	parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
	udelay (1);
	s = parport_read_status (port);
	parport_write_data (port, 0xff); udelay (2);

	return s;
}

/* Send a mux-style CPP command packet. */
static int cpp_mux (struct parport *port, int cmd)
{
	unsigned char s;
	int rc;

	parport_data_forward (port);
	parport_write_data (port, 0xaa); udelay (2);
	parport_write_data (port, 0x55); udelay (2);
	parport_write_data (port, 0xf0); udelay (2);
	parport_write_data (port, 0x0f); udelay (2);
	parport_write_data (port, 0x52); udelay (2);
	parport_write_data (port, 0xad); udelay (2);
	parport_write_data (port, cmd); udelay (2);

	s = parport_read_status (port);
	if (!(s & PARPORT_STATUS_ACK)) {
		DPRINTK (KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n",
			 port->name, cmd, s);
		return -EIO;
	}

	rc = (((s & PARPORT_STATUS_SELECT   ? 1 : 0) << 0) |
	      ((s & PARPORT_STATUS_PAPEROUT ? 1 : 0) << 1) |
	      ((s & PARPORT_STATUS_BUSY     ? 0 : 1) << 2) |
	      ((s & PARPORT_STATUS_ERROR    ? 0 : 1) << 3));

	return rc;
}

void parport_daisy_deselect_all (struct parport *port)
{
	cpp_daisy (port, 0x30);
}

int parport_daisy_select (struct parport *port, int daisy, int mode)
{
	switch (mode)
	{
		// For these modes we should switch to EPP mode:
		case IEEE1284_MODE_EPP:
		case IEEE1284_MODE_EPPSL:
		case IEEE1284_MODE_EPPSWE:
			return (cpp_daisy (port, 0x20 + daisy) &
				PARPORT_STATUS_ERROR);

		// For these modes we should switch to ECP mode:
		case IEEE1284_MODE_ECP:
		case IEEE1284_MODE_ECPRLE:
		case IEEE1284_MODE_ECPSWE: 
			return (cpp_daisy (port, 0xd0 + daisy) &
				PARPORT_STATUS_ERROR);

		// Nothing was told for BECP in Daisy chain specification.
		// May be it's wise to use ECP?
		case IEEE1284_MODE_BECP:
		// Others use compat mode
		case IEEE1284_MODE_NIBBLE:
		case IEEE1284_MODE_BYTE:
		case IEEE1284_MODE_COMPAT:
		default:
			return (cpp_daisy (port, 0xe0 + daisy) &
				PARPORT_STATUS_ERROR);
	}
}

static int mux_present (struct parport *port)
{
	return cpp_mux (port, 0x51) == 3;
}

static int num_mux_ports (struct parport *port)
{
	return cpp_mux (port, 0x58);
}

static int select_port (struct parport *port)
{
	int muxport = port->muxport;
	return cpp_mux (port, 0x60 + muxport) == muxport;
}

static int assign_addrs (struct parport *port)
{
	unsigned char s, last_dev;
	unsigned char daisy;
	int thisdev = numdevs;
	int detected;
	char *deviceid;

	parport_data_forward (port);
	parport_write_data (port, 0xaa); udelay (2);
	parport_write_data (port, 0x55); udelay (2);
	parport_write_data (port, 0x00); udelay (2);
	parport_write_data (port, 0xff); udelay (2);
	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
					  | PARPORT_STATUS_PAPEROUT
					  | PARPORT_STATUS_SELECT
					  | PARPORT_STATUS_ERROR);
	if (s != (PARPORT_STATUS_BUSY
		  | PARPORT_STATUS_PAPEROUT
		  | PARPORT_STATUS_SELECT
		  | PARPORT_STATUS_ERROR)) {
		DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n",
			 port->name, s);
		return 0;
	}

	parport_write_data (port, 0x87); udelay (2);
	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
					  | PARPORT_STATUS_PAPEROUT
					  | PARPORT_STATUS_SELECT
					  | PARPORT_STATUS_ERROR);
	if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
		DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n",
			 port->name, s);
		return 0;
	}

	parport_write_data (port, 0x78); udelay (2);
	last_dev = 0; /* We've just been speaking to a device, so we
			 know there must be at least _one_ out there. */

	for (daisy = 0; daisy < 4; daisy++) {
		parport_write_data (port, daisy);
		udelay (2);
		parport_frob_control (port,
				      PARPORT_CONTROL_STROBE,
				      PARPORT_CONTROL_STROBE);
		udelay (1);
		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
		udelay (1);

		if (last_dev)
			/* No more devices. */
			break;

		last_dev = !(parport_read_status (port)
			     & PARPORT_STATUS_BUSY);

		add_dev (numdevs++, port, daisy);
	}

	parport_write_data (port, 0xff); udelay (2);
	detected = numdevs - thisdev;
	DPRINTK (KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name,
		 detected);

	/* Ask the new devices to introduce themselves. */
	deviceid = kmalloc (1000, GFP_KERNEL);
	if (!deviceid) return 0;

	for (daisy = 0; thisdev < numdevs; thisdev++, daisy++)
		parport_device_id (thisdev, deviceid, 1000);

	kfree (deviceid);
	return detected;
}
