/*
 *	Low-level parallel-support for PC-style hardware integrated in the
 *	LASI-Controller (on GSC-Bus) for HP-PARISC Workstations
 *
 *	(C) 1999-2001 by Helge Deller <deller@gmx.de>
 *
 *
 *	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.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * based on parport_pc.c by
 * 	    Grant Guenther <grant@torque.net>
 * 	    Phil Blundell <Philip.Blundell@pobox.com>
 *          Tim Waugh <tim@cyberelk.demon.co.uk>
 *	    Jose Renau <renau@acm.org>
 *          David Campbell <campbell@torque.net>
 *          Andrea Arcangeli
 */

#ifndef	__DRIVERS_PARPORT_PARPORT_GSC_H
#define	__DRIVERS_PARPORT_PARPORT_GSC_H

#include <asm/io.h>
#include <linux/delay.h>

#undef	DEBUG_PARPORT	/* undefine for production */
#define DELAY_TIME 	0

#if DELAY_TIME == 0
#define parport_readb	gsc_readb
#define parport_writeb	gsc_writeb
#else
static __inline__ unsigned char parport_readb( unsigned long port )
{
    udelay(DELAY_TIME);
    return gsc_readb(port);
}

static __inline__ void parport_writeb( unsigned char value, unsigned long port )
{
    gsc_writeb(value,port);
    udelay(DELAY_TIME);
}
#endif

/* --- register definitions ------------------------------- */

#define EPPDATA(p)  ((p)->base    + 0x4)
#define EPPADDR(p)  ((p)->base    + 0x3)
#define CONTROL(p)  ((p)->base    + 0x2)
#define STATUS(p)   ((p)->base    + 0x1)
#define DATA(p)     ((p)->base    + 0x0)

struct parport_gsc_private {
	/* Contents of CTR. */
	unsigned char ctr;

	/* Bitmask of writable CTR bits. */
	unsigned char ctr_writable;

	/* Number of bytes per portword. */
	int pword;

	/* Not used yet. */
	int readIntrThreshold;
	int writeIntrThreshold;

	/* buffer suitable for DMA, if DMA enabled */
	char *dma_buf;
	dma_addr_t dma_handle;
	struct pci_dev *dev;
};

static inline void parport_gsc_write_data(struct parport *p, unsigned char d)
{
#ifdef DEBUG_PARPORT
	printk (KERN_DEBUG "parport_gsc_write_data(%p,0x%02x)\n", p, d);
#endif
	parport_writeb(d, DATA(p));
}

static inline unsigned char parport_gsc_read_data(struct parport *p)
{
	unsigned char val = parport_readb (DATA (p));
#ifdef DEBUG_PARPORT
	printk (KERN_DEBUG "parport_gsc_read_data(%p) = 0x%02x\n",
		p, val);
#endif
	return val;
}

/* __parport_gsc_frob_control differs from parport_gsc_frob_control in that
 * it doesn't do any extra masking. */
static inline unsigned char __parport_gsc_frob_control(struct parport *p,
							unsigned char mask,
							unsigned char val)
{
	struct parport_gsc_private *priv = p->physport->private_data;
	unsigned char ctr = priv->ctr;
#ifdef DEBUG_PARPORT
	printk (KERN_DEBUG
		"__parport_gsc_frob_control(%02x,%02x): %02x -> %02x\n",
		mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
#endif
	ctr = (ctr & ~mask) ^ val;
	ctr &= priv->ctr_writable; /* only write writable bits. */
	parport_writeb (ctr, CONTROL (p));
	priv->ctr = ctr;	/* Update soft copy */
	return ctr;
}

static inline void parport_gsc_data_reverse(struct parport *p)
{
	__parport_gsc_frob_control (p, 0x20, 0x20);
}

static inline void parport_gsc_data_forward(struct parport *p)
{
	__parport_gsc_frob_control (p, 0x20, 0x00);
}

static inline void parport_gsc_write_control(struct parport *p,
						 unsigned char d)
{
	const unsigned char wm = (PARPORT_CONTROL_STROBE |
				  PARPORT_CONTROL_AUTOFD |
				  PARPORT_CONTROL_INIT |
				  PARPORT_CONTROL_SELECT);

	/* Take this out when drivers have adapted to newer interface. */
	if (d & 0x20) {
		printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
			p->name, p->cad->name);
		parport_gsc_data_reverse (p);
	}

	__parport_gsc_frob_control (p, wm, d & wm);
}

static inline unsigned char parport_gsc_read_control(struct parport *p)
{
	const unsigned char rm = (PARPORT_CONTROL_STROBE |
				  PARPORT_CONTROL_AUTOFD |
				  PARPORT_CONTROL_INIT |
				  PARPORT_CONTROL_SELECT);
	const struct parport_gsc_private *priv = p->physport->private_data;
	return priv->ctr & rm; /* Use soft copy */
}

static inline unsigned char parport_gsc_frob_control(struct parport *p,
							unsigned char mask,
							unsigned char val)
{
	const unsigned char wm = (PARPORT_CONTROL_STROBE |
				  PARPORT_CONTROL_AUTOFD |
				  PARPORT_CONTROL_INIT |
				  PARPORT_CONTROL_SELECT);

	/* Take this out when drivers have adapted to newer interface. */
	if (mask & 0x20) {
		printk (KERN_DEBUG "%s (%s): use data_%s for this!\n",
			p->name, p->cad->name,
			(val & 0x20) ? "reverse" : "forward");
		if (val & 0x20)
			parport_gsc_data_reverse (p);
		else
			parport_gsc_data_forward (p);
	}

	/* Restrict mask and val to control lines. */
	mask &= wm;
	val &= wm;

	return __parport_gsc_frob_control (p, mask, val);
}

static inline unsigned char parport_gsc_read_status(struct parport *p)
{
	return parport_readb (STATUS(p));
}

static inline void parport_gsc_disable_irq(struct parport *p)
{
	__parport_gsc_frob_control (p, 0x10, 0x00);
}

static inline void parport_gsc_enable_irq(struct parport *p)
{
	__parport_gsc_frob_control (p, 0x10, 0x10);
}

extern void parport_gsc_release_resources(struct parport *p);

extern int parport_gsc_claim_resources(struct parport *p);

extern void parport_gsc_init_state(struct pardevice *, struct parport_state *s);

extern void parport_gsc_save_state(struct parport *p, struct parport_state *s);

extern void parport_gsc_restore_state(struct parport *p, struct parport_state *s);

extern void parport_gsc_inc_use_count(void);

extern void parport_gsc_dec_use_count(void);

extern struct parport *parport_gsc_probe_port(unsigned long base,
						unsigned long base_hi,
						int irq, int dma,
						struct pci_dev *dev);

#endif	/* __DRIVERS_PARPORT_PARPORT_GSC_H */
