/* Low-level parallel-port routines for 8255-based PC-style hardware.
*
* Authors: Phil Blundell <philb@gnu.org>
* Tim Waugh <tim@cyberelk.demon.co.uk>
* Jose Renau <renau@acm.org>
* David Campbell
* Andrea Arcangeli
*
* based on work by Grant Guenther <grant@torque.net> and Phil Blundell.
*
* Cleaned up include files - Russell King <linux@arm.uk.linux.org>
* DMA support - Bert De Jonghe <bert@sophis.be>
* Many ECP bugs fixed. Fred Barnes & Jamie Lokier, 1999
* More PCI support now conditional on CONFIG_PCI, 03/2001, Paul G.
* Various hacks, Fred Barnes, 04/2001
* Updated probing logic - Adam Belay <ambx1@neo.rr.com>
*/
/* This driver should work with any hardware that is broadly compatible
* with that in the IBM PC. This applies to the majority of integrated
* I/O chipsets that are commonly available. The expected register
* layout is:
*
* base+0 data
* base+1 status
* base+2 control
*
* In addition, there are some optional registers:
*
* base+3 EPP address
* base+4 EPP data
* base+0x400 ECP config A
* base+0x401 ECP config B
* base+0x402 ECP control
*
* All registers are 8 bits wide and read/write. If your hardware differs
* only in register addresses (eg because your registers are on 32-bit
* word boundaries) then you can alter the constants in parport_pc.h to
* accommodate this.
*
* Note that the ECP registers may not start at offset 0x400 for PCI cards,
* but rather will start at port->base_hi.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/pnp.h>
#include <linux/platform_device.h>
#include <linux/sysctl.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <asm/dma.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
#include <linux/via.h>
#include <asm/parport.h>
#define PARPORT_PC_MAX_PORTS PARPORT_MAX
#ifdef CONFIG_ISA_DMA_API
#define HAS_DMA
#endif
/* ECR modes */
#define ECR_SPP 00
#define ECR_PS2 01
#define ECR_PPF 02
#define ECR_ECP 03
#define ECR_EPP 04
#define ECR_VND 05
#define ECR_TST 06
#define ECR_CNF 07
#define ECR_MODE_MASK 0xe0
#define ECR_WRITE(p, v) frob_econtrol((p), 0xff, (v))
#undef DEBUG
#ifdef DEBUG
#define DPRINTK printk
#else
#define DPRINTK(stuff...)
#endif
#define NR_SUPERIOS 3
static struct superio_struct { /* For Super-IO chips autodetection */
int io;
int irq;
int dma;
} superios[NR_SUPERIOS] = { {0,},};
static int user_specified;
#if defined(CONFIG_PARPORT_PC_SUPERIO) || \
(defined(CONFIG_PARPORT_1284) && defined(CONFIG_PARPORT_PC_FIFO))
static int verbose_probing;
#endif
static int pci_registered_parport;
static int pnp_registered_parport;
/* frob_control, but for ECR */
static void frob_econtrol(struct parport *pb, unsigned char m,
unsigned char v)
{
unsigned char ectr = 0;
if (m != 0xff)
ectr = inb(ECONTROL(pb));
DPRINTK(KERN_DEBUG "frob_econtrol(%02x,%02x): %02x -> %02x\n",
m, v, ectr, (ectr & ~m) ^ v);
outb((ectr & ~m) ^ v, ECONTROL(pb));
}
static inline void frob_set_mode(struct parport *p, int mode)
{
frob_econtrol(p, ECR_MODE_MASK, mode << 5);
}
#ifdef CONFIG_PARPORT_PC_FIFO
/* Safely change the mode bits in the ECR
Returns:
0 : Success
-EBUSY: Could not drain FIFO in some finite amount of time,
mode not changed!
*/
static int change_mode(struct parport *p, int m)
{
const struct parport_pc_private *priv = p->physport->private_data;
unsigned char oecr;
int mode;
DPRINTK(KERN_INFO "parport change_mode ECP-ISA to mode 0x%02x\n", m);
if (!priv->ecr) {
printk(KERN_DEBUG "change_mode: but there's no ECR!\n");
return 0;
}
/* Bits <7:5> contain the mode. */
oecr = inb(ECONTROL(p));
mode = (oecr >> 5) & 0x7;
if (mode == m)
return 0;
if (mode >= 2 && !(priv->ctr & 0x20)) {
/* This mode resets the FIFO, so we may
* have to wait for it to drain first. */
unsigned long expire = jiffies + p->physport->cad->timeout;
int counter;
switch (mode) {
case ECR_PPF: /* Parallel Port FIFO mode */
case ECR_ECP: /* ECP Parallel Port mode */
/* Busy wait for 200us */
for (counter = 0; counter < 40; counter++) {
if (inb(ECONTROL(p)) & 0x01)
break;
if (signal_pending(current))
break;
udelay(5);
}
/* Poll slowly. */
while (!(inb(ECONTROL(p)) & 0x01)) {
if (time_after_eq(jiffies, expire))
/* The FIFO is stuck. */
return -EBUSY;
schedule_timeout_interruptible(
msecs_to_jiffies(10));
if (signal_pending(current))
break;
}
}
}
if (mode >= 2 && m >= 2) {
/* We have to go through mode 001 */
oecr &= ~(7 << 5);
oecr |= ECR_PS2 << 5;
ECR_WRITE(p, oecr);
}
/* Set the mode. */
oecr &= ~(7 << 5);
oecr |= m << 5;
ECR_WRITE(p, oecr);
return 0;
}
#endif /* FIFO support */
/*
* Clear TIMEOUT BIT in EPP MODE
*
* This is also used in SPP detection.
*/
static int clear_epp_timeout(struct parport *pb)
{
unsigned char r;
if (!(parport_pc_read_status(pb) & 0x01))
return 1;
/* To clear timeout some chips require double read */
parport_pc_read_status(pb);
r = parport_pc_read_status(pb);
outb(r | 0x01, STATUS(pb)); /* Some reset by writing 1 */
outb(r & 0xfe, STATUS(pb)); /* Others by writing 0 */
r = parport_pc_read_status(pb);
return !(r & 0x01);
}
/*
* Access functions.
*
* Most of these aren't static because they may be used by the
* parport_xxx_yyy macros. extern __inline__ versions of several
* of these are in parport_pc.h.
*/
static void parport_pc_init_state(struct pardevice *dev,
struct parport_state *s)
{
s->u.pc.ctr = 0xc;
if (dev->irq_func &&
dev->port->irq != PARPORT_IRQ_NONE)
/* Set ackIntEn */
s->u.pc.ctr |= 0x10;
s->u.pc.ecr = 0x34; /* NetMos chip can cause problems 0x24;
* D.Gruszka VScom */
}
static void parport_pc_save_state(struct parport *p, struct parport_state *s)
{
const struct parport_pc_private *priv = p->physport->private_data;
s->u.pc.ctr = priv->ctr;
if (priv->ecr)
s->u.pc.ecr = inb(ECONTROL(p));
}
static void parport_pc_restore_state(struct parport *p,
struct parport_state *s)
{
struct parport_pc_private *priv = p->physport->private_data;
register unsigned char c = s->u.pc.ctr & priv->ctr_writable;
outb(c, CONTROL(p));
priv->ctr = c;
if (priv->ecr)
ECR_WRITE(p, s->u.pc.ecr);
}
#ifdef CONFIG_PARPORT_1284
static size_t parport_pc_epp_read_data(struct parport *port, void *buf,
size_t length, int flags)
{
size_t got = 0;
if (flags & PARPORT_W91284PIC) {
unsigned char status;
size_t left = length;
/* use knowledge about data lines..:
* nFault is 0 if there is at least 1 byte in the Warp's FIFO
* pError is 1 if there are 16 bytes in the Warp's FIFO
*/
status = inb(STATUS(port));
while (!(status & 0x08) && got < length) {
if (left >= 16 && (status & 0x20) && !(status & 0x08)) {
/* can grab 16 bytes from warp fifo */
if (!((long)buf & 0x03))
insl(EPPDATA(port), buf, 4);
else
insb(EPPDATA(port), buf, 16);
buf += 16;
got += 16;
left -= 16;
} else {
/* grab single byte from the warp fifo */
*((char *)buf) = inb(EPPDATA(port));
buf++;
got++;
left--;
}
status = inb(STATUS(port));
if (status & 0x01) {
/* EPP timeout should never occur... */
printk(KERN_DEBUG
"%s: EPP timeout occurred while talking to w91284pic (should not have done)\n", port->name);
clear_epp_timeout(port);
}
}
return got;
}
if ((flags & PARPORT_EPP_FAST) && (length > 1)) {
if (!(((long)buf | length) & 0x03))
insl(EPPDATA(port), buf, (length >> 2));
else
insb(EPPDATA(port), buf, length);
if (inb(STATUS(port)) & 0x01) {
clear_epp_timeout(port);
return -EIO;
}
return length;
}
for (; got < length; got++) {
*((char *)bu