Miata: parport with ECP

Kurt Garloff <[email protected]> Tue, 1 Jul 2003 00:02:00 +0200
Newsgroups gmane.linux.suse.axp
Organization SuSE(DE), TU/e(NL)
Message-ID <[email protected]>
Hi,

my DPWS600 serves as server for various things and I was very annoyed
when I found out that printing does not work reliably: Large files
produced garbled output, so I suspected lost data (overruns?) on the 
parallel port.  I tried tunelp to no avail.

Miata chipset docu got me further. The parport is controlled by a
NS87303 and can be set to various locations: LPT1(3bc), LPT2(378) and
LPT3(278). Only the latter two are EPP/ECP capable. However 3bc is
standard and the BIOS has no option to change it. NS87303 docu told
me how to do that. I use the attached module (loading fails!) to tweak
the 87303 registers and can then i
modprobe parport_pc io=0x378 irq=7 dma=3
The parport driver then uses ECP and printing then works perfectly.

Maybe it's useful for somebody else.

Regards,
-- 
Kurt Garloff  <[email protected]>                          Eindhoven, NL
GPG key: See mail header, key servers                 SuSE Labs (Head)
SuSE Linux AG, Nuernberg, DE                            SCSI, Security
set_lpt2.c (text/plain, 2.1 KB)
/* Compile with
 gcc -O2 -Wall -fno-strict-aliasing -fno-common -fomit-frame-pointer   \
 -pipe -mno-fp-regs -ffixed-8 -finline-limit-1000 -mcpu=ev56 -Wa,-mev6 \
 -DMODULE -D__KERNEL__ -I/usr/src/linux/include -c set_lpt2.c
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/config.h>
#include <asm/errno.h>
#include <asm-sparc64/ns87303.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("[email protected]");
MODULE_DESCRIPTION("Miata: Configures the Super-IO chip (NS83707): parport to 0x378 and enable EPP+ECP");

inline unsigned char read_superio_reg (int reg)
{
	outb (reg, 0x026e);
	inb (0x026f);
	return inb (0x026f);
}

inline void write_superio_reg (int reg, unsigned char val)
{
	outb (reg, 0x026e);
	inb (0x026f);
	outb (val, 0x026f);
	outb (val, 0x026f);
}

inline void setbits_superio_reg (int reg, unsigned char val, unsigned char mask)
{
	unsigned char rval;
	outb (reg, 0x026e);
	rval = inb (0x026f);
	rval &= ~mask; rval |= val & mask;
	outb (rval, 0x026f);
	outb (rval, 0x026f);
}

void dump_super ()
{
	int reg;
	printk ("SuperIO:");
	for (reg = 0; reg <= CS1CF1; ++reg) {
		unsigned char val = read_superio_reg (reg);
		printk (" %02x", val);
	}
	printk ("\n");
}

void set_lpt2()
{
	// Enable parallel port
	setbits_superio_reg (FER, 1, 1);
	// LPT port B (0x378)
	setbits_superio_reg (FAR, FAR_LPTB, FAR_LPT_MASK);
	// Enable EPP 1.9 + ECP
	setbits_superio_reg (PCR, PCR_EPP_ENABLE | PCR_EPP_IEEE | PCR_ECP_ENABLE | PCR_ECP_CLK_ENA, 0x0f);
	// Set LPTB to IRQ7 & enable LPR CTR control of port dir
	setbits_superio_reg (PTR, PTR_LPTB_IRQ7 | PTR_LPT_REG_DIR, 0x88);
	// Enable short host read/write (ECP/EPP)
	setbits_superio_reg (FCR, FCR_ZWS_ENA, FCR_ZWS_ENA);
	// EPP timeout IRQ
	//setbits_superio_reg (TUP, TUP_EPP_TIMO, TUP_EPP_TIMO);
	// Always use IRQ7
	setbits_superio_reg (ASC, ASC_LPT_IRQ7, ASC_LPT_IRQ7);
}

int __init init_superio(void)
{
	printk (" FER FAR PTR FCR PCR KRR PMC TUP SID ASC C0F0 C0F1 C1F0 C1F1\n");
	dump_super ();
	set_lpt2 ();
	dump_super ();
	return 1;
}

void __exit exit_module(void)
{
	return;
}

module_init(init_superio);
module_exit(exit_module);
signature.asc (application/pgp-signature, 198 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux)

iD8DBQE/ALNXxmLh6hyYd04RAnUZAKCaS9RN38hJWiZ3Vh12xxYTnmCCpACgqo49
po9AlUtSjdGNqsrcl0oxq70=
=cmOb
-----END PGP SIGNATURE-----