xref: /linux-6.15/include/linux/parport_pc.h (revision 6640727f)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef __LINUX_PARPORT_PC_H
31da177e4SLinus Torvalds #define __LINUX_PARPORT_PC_H
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds #include <asm/io.h>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds /* --- register definitions ------------------------------- */
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds #define ECONTROL(p) ((p)->base_hi + 0x2)
101da177e4SLinus Torvalds #define CONFIGB(p)  ((p)->base_hi + 0x1)
111da177e4SLinus Torvalds #define CONFIGA(p)  ((p)->base_hi + 0x0)
121da177e4SLinus Torvalds #define FIFO(p)     ((p)->base_hi + 0x0)
131da177e4SLinus Torvalds #define EPPDATA(p)  ((p)->base    + 0x4)
141da177e4SLinus Torvalds #define EPPADDR(p)  ((p)->base    + 0x3)
151da177e4SLinus Torvalds #define CONTROL(p)  ((p)->base    + 0x2)
161da177e4SLinus Torvalds #define STATUS(p)   ((p)->base    + 0x1)
171da177e4SLinus Torvalds #define DATA(p)     ((p)->base    + 0x0)
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds struct parport_pc_private {
201da177e4SLinus Torvalds 	/* Contents of CTR. */
211da177e4SLinus Torvalds 	unsigned char ctr;
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds 	/* Bitmask of writable CTR bits. */
241da177e4SLinus Torvalds 	unsigned char ctr_writable;
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds 	/* Whether or not there's an ECR. */
271da177e4SLinus Torvalds 	int ecr;
281da177e4SLinus Torvalds 
29*6640727fSMaciej W. Rozycki 	/* Bitmask of writable ECR bits. */
30*6640727fSMaciej W. Rozycki 	unsigned char ecr_writable;
31*6640727fSMaciej W. Rozycki 
321da177e4SLinus Torvalds 	/* Number of PWords that FIFO will hold. */
331da177e4SLinus Torvalds 	int fifo_depth;
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds 	/* Number of bytes per portword. */
361da177e4SLinus Torvalds 	int pword;
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds 	/* Not used yet. */
391da177e4SLinus Torvalds 	int readIntrThreshold;
401da177e4SLinus Torvalds 	int writeIntrThreshold;
411da177e4SLinus Torvalds 
421da177e4SLinus Torvalds 	/* buffer suitable for DMA, if DMA enabled */
431da177e4SLinus Torvalds 	char *dma_buf;
441da177e4SLinus Torvalds 	dma_addr_t dma_handle;
451da177e4SLinus Torvalds 	struct list_head list;
461da177e4SLinus Torvalds 	struct parport *port;
471da177e4SLinus Torvalds };
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds struct parport_pc_via_data
501da177e4SLinus Torvalds {
511da177e4SLinus Torvalds 	/* ISA PnP IRQ routing register 1 */
521da177e4SLinus Torvalds 	u8 via_pci_parport_irq_reg;
531da177e4SLinus Torvalds 	/* ISA PnP DMA request routing register */
541da177e4SLinus Torvalds 	u8 via_pci_parport_dma_reg;
551da177e4SLinus Torvalds 	/* Register and value to enable SuperIO configuration access */
561da177e4SLinus Torvalds 	u8 via_pci_superio_config_reg;
571da177e4SLinus Torvalds 	u8 via_pci_superio_config_data;
581da177e4SLinus Torvalds 	/* SuperIO function register number */
591da177e4SLinus Torvalds 	u8 viacfg_function;
601da177e4SLinus Torvalds 	/* parallel port control register number */
611da177e4SLinus Torvalds 	u8 viacfg_parport_control;
621da177e4SLinus Torvalds 	/* Parallel port base address register */
631da177e4SLinus Torvalds 	u8 viacfg_parport_base;
641da177e4SLinus Torvalds };
651da177e4SLinus Torvalds 
parport_pc_write_data(struct parport * p,unsigned char d)661da177e4SLinus Torvalds static __inline__ void parport_pc_write_data(struct parport *p, unsigned char d)
671da177e4SLinus Torvalds {
681da177e4SLinus Torvalds #ifdef DEBUG_PARPORT
691da177e4SLinus Torvalds 	printk (KERN_DEBUG "parport_pc_write_data(%p,0x%02x)\n", p, d);
701da177e4SLinus Torvalds #endif
711da177e4SLinus Torvalds 	outb(d, DATA(p));
721da177e4SLinus Torvalds }
731da177e4SLinus Torvalds 
parport_pc_read_data(struct parport * p)741da177e4SLinus Torvalds static __inline__ unsigned char parport_pc_read_data(struct parport *p)
751da177e4SLinus Torvalds {
761da177e4SLinus Torvalds 	unsigned char val = inb (DATA (p));
771da177e4SLinus Torvalds #ifdef DEBUG_PARPORT
781da177e4SLinus Torvalds 	printk (KERN_DEBUG "parport_pc_read_data(%p) = 0x%02x\n",
791da177e4SLinus Torvalds 		p, val);
801da177e4SLinus Torvalds #endif
811da177e4SLinus Torvalds 	return val;
821da177e4SLinus Torvalds }
831da177e4SLinus Torvalds 
841da177e4SLinus Torvalds #ifdef DEBUG_PARPORT
dump_parport_state(char * str,struct parport * p)8581684ee6SAdrian Bunk static inline void dump_parport_state (char *str, struct parport *p)
861da177e4SLinus Torvalds {
871da177e4SLinus Torvalds 	/* here's hoping that reading these ports won't side-effect anything underneath */
881da177e4SLinus Torvalds 	unsigned char ecr = inb (ECONTROL (p));
891da177e4SLinus Torvalds 	unsigned char dcr = inb (CONTROL (p));
901da177e4SLinus Torvalds 	unsigned char dsr = inb (STATUS (p));
91110bee75SMarko Kohtala 	static const char *const ecr_modes[] = {"SPP", "PS2", "PPFIFO", "ECP", "xXx", "yYy", "TST", "CFG"};
9268799398SDave Jones 	const struct parport_pc_private *priv = p->physport->private_data;
931da177e4SLinus Torvalds 	int i;
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds 	printk (KERN_DEBUG "*** parport state (%s): ecr=[%s", str, ecr_modes[(ecr & 0xe0) >> 5]);
961da177e4SLinus Torvalds 	if (ecr & 0x10) printk (",nErrIntrEn");
971da177e4SLinus Torvalds 	if (ecr & 0x08) printk (",dmaEn");
981da177e4SLinus Torvalds 	if (ecr & 0x04) printk (",serviceIntr");
991da177e4SLinus Torvalds 	if (ecr & 0x02) printk (",f_full");
1001da177e4SLinus Torvalds 	if (ecr & 0x01) printk (",f_empty");
1011da177e4SLinus Torvalds 	for (i=0; i<2; i++) {
1021da177e4SLinus Torvalds 		printk ("]  dcr(%s)=[", i ? "soft" : "hard");
1031da177e4SLinus Torvalds 		dcr = i ? priv->ctr : inb (CONTROL (p));
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds 		if (dcr & 0x20) {
1061da177e4SLinus Torvalds 			printk ("rev");
1071da177e4SLinus Torvalds 		} else {
1081da177e4SLinus Torvalds 			printk ("fwd");
1091da177e4SLinus Torvalds 		}
1101da177e4SLinus Torvalds 		if (dcr & 0x10) printk (",ackIntEn");
1111da177e4SLinus Torvalds 		if (!(dcr & 0x08)) printk (",N-SELECT-IN");
1121da177e4SLinus Torvalds 		if (dcr & 0x04) printk (",N-INIT");
1131da177e4SLinus Torvalds 		if (!(dcr & 0x02)) printk (",N-AUTOFD");
1141da177e4SLinus Torvalds 		if (!(dcr & 0x01)) printk (",N-STROBE");
1151da177e4SLinus Torvalds 	}
1161da177e4SLinus Torvalds 	printk ("]  dsr=[");
1171da177e4SLinus Torvalds 	if (!(dsr & 0x80)) printk ("BUSY");
1181da177e4SLinus Torvalds 	if (dsr & 0x40) printk (",N-ACK");
1191da177e4SLinus Torvalds 	if (dsr & 0x20) printk (",PERROR");
1201da177e4SLinus Torvalds 	if (dsr & 0x10) printk (",SELECT");
1211da177e4SLinus Torvalds 	if (dsr & 0x08) printk (",N-FAULT");
1221da177e4SLinus Torvalds 	printk ("]\n");
1231da177e4SLinus Torvalds 	return;
1241da177e4SLinus Torvalds }
1251da177e4SLinus Torvalds #else	/* !DEBUG_PARPORT */
1261da177e4SLinus Torvalds #define dump_parport_state(args...)
1271da177e4SLinus Torvalds #endif	/* !DEBUG_PARPORT */
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds /* __parport_pc_frob_control differs from parport_pc_frob_control in that
1301da177e4SLinus Torvalds  * it doesn't do any extra masking. */
__parport_pc_frob_control(struct parport * p,unsigned char mask,unsigned char val)1311da177e4SLinus Torvalds static __inline__ unsigned char __parport_pc_frob_control (struct parport *p,
1321da177e4SLinus Torvalds 							   unsigned char mask,
1331da177e4SLinus Torvalds 							   unsigned char val)
1341da177e4SLinus Torvalds {
1351da177e4SLinus Torvalds 	struct parport_pc_private *priv = p->physport->private_data;
1361da177e4SLinus Torvalds 	unsigned char ctr = priv->ctr;
1371da177e4SLinus Torvalds #ifdef DEBUG_PARPORT
1381da177e4SLinus Torvalds 	printk (KERN_DEBUG
1391da177e4SLinus Torvalds 		"__parport_pc_frob_control(%02x,%02x): %02x -> %02x\n",
1401da177e4SLinus Torvalds 		mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
1411da177e4SLinus Torvalds #endif
1421da177e4SLinus Torvalds 	ctr = (ctr & ~mask) ^ val;
1431da177e4SLinus Torvalds 	ctr &= priv->ctr_writable; /* only write writable bits. */
1441da177e4SLinus Torvalds 	outb (ctr, CONTROL (p));
1451da177e4SLinus Torvalds 	priv->ctr = ctr;	/* Update soft copy */
1461da177e4SLinus Torvalds 	return ctr;
1471da177e4SLinus Torvalds }
1481da177e4SLinus Torvalds 
parport_pc_data_reverse(struct parport * p)1491da177e4SLinus Torvalds static __inline__ void parport_pc_data_reverse (struct parport *p)
1501da177e4SLinus Torvalds {
1511da177e4SLinus Torvalds 	__parport_pc_frob_control (p, 0x20, 0x20);
1521da177e4SLinus Torvalds }
1531da177e4SLinus Torvalds 
parport_pc_data_forward(struct parport * p)1541da177e4SLinus Torvalds static __inline__ void parport_pc_data_forward (struct parport *p)
1551da177e4SLinus Torvalds {
1561da177e4SLinus Torvalds 	__parport_pc_frob_control (p, 0x20, 0x00);
1571da177e4SLinus Torvalds }
1581da177e4SLinus Torvalds 
parport_pc_write_control(struct parport * p,unsigned char d)1591da177e4SLinus Torvalds static __inline__ void parport_pc_write_control (struct parport *p,
1601da177e4SLinus Torvalds 						 unsigned char d)
1611da177e4SLinus Torvalds {
1621da177e4SLinus Torvalds 	const unsigned char wm = (PARPORT_CONTROL_STROBE |
1631da177e4SLinus Torvalds 				  PARPORT_CONTROL_AUTOFD |
1641da177e4SLinus Torvalds 				  PARPORT_CONTROL_INIT |
1651da177e4SLinus Torvalds 				  PARPORT_CONTROL_SELECT);
1661da177e4SLinus Torvalds 
1671da177e4SLinus Torvalds 	/* Take this out when drivers have adapted to newer interface. */
1681da177e4SLinus Torvalds 	if (d & 0x20) {
1691da177e4SLinus Torvalds 		printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
1701da177e4SLinus Torvalds 			p->name, p->cad->name);
1711da177e4SLinus Torvalds 		parport_pc_data_reverse (p);
1721da177e4SLinus Torvalds 	}
1731da177e4SLinus Torvalds 
1741da177e4SLinus Torvalds 	__parport_pc_frob_control (p, wm, d & wm);
1751da177e4SLinus Torvalds }
1761da177e4SLinus Torvalds 
parport_pc_read_control(struct parport * p)1771da177e4SLinus Torvalds static __inline__ unsigned char parport_pc_read_control(struct parport *p)
1781da177e4SLinus Torvalds {
1791da177e4SLinus Torvalds 	const unsigned char rm = (PARPORT_CONTROL_STROBE |
1801da177e4SLinus Torvalds 				  PARPORT_CONTROL_AUTOFD |
1811da177e4SLinus Torvalds 				  PARPORT_CONTROL_INIT |
1821da177e4SLinus Torvalds 				  PARPORT_CONTROL_SELECT);
1831da177e4SLinus Torvalds 	const struct parport_pc_private *priv = p->physport->private_data;
1841da177e4SLinus Torvalds 	return priv->ctr & rm; /* Use soft copy */
1851da177e4SLinus Torvalds }
1861da177e4SLinus Torvalds 
parport_pc_frob_control(struct parport * p,unsigned char mask,unsigned char val)1871da177e4SLinus Torvalds static __inline__ unsigned char parport_pc_frob_control (struct parport *p,
1881da177e4SLinus Torvalds 							 unsigned char mask,
1891da177e4SLinus Torvalds 							 unsigned char val)
1901da177e4SLinus Torvalds {
1911da177e4SLinus Torvalds 	const unsigned char wm = (PARPORT_CONTROL_STROBE |
1921da177e4SLinus Torvalds 				  PARPORT_CONTROL_AUTOFD |
1931da177e4SLinus Torvalds 				  PARPORT_CONTROL_INIT |
1941da177e4SLinus Torvalds 				  PARPORT_CONTROL_SELECT);
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds 	/* Take this out when drivers have adapted to newer interface. */
1971da177e4SLinus Torvalds 	if (mask & 0x20) {
1981da177e4SLinus Torvalds 		printk (KERN_DEBUG "%s (%s): use data_%s for this!\n",
1991da177e4SLinus Torvalds 			p->name, p->cad->name,
2001da177e4SLinus Torvalds 			(val & 0x20) ? "reverse" : "forward");
2011da177e4SLinus Torvalds 		if (val & 0x20)
2021da177e4SLinus Torvalds 			parport_pc_data_reverse (p);
2031da177e4SLinus Torvalds 		else
2041da177e4SLinus Torvalds 			parport_pc_data_forward (p);
2051da177e4SLinus Torvalds 	}
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 	/* Restrict mask and val to control lines. */
2081da177e4SLinus Torvalds 	mask &= wm;
2091da177e4SLinus Torvalds 	val &= wm;
2101da177e4SLinus Torvalds 
2111da177e4SLinus Torvalds 	return __parport_pc_frob_control (p, mask, val);
2121da177e4SLinus Torvalds }
2131da177e4SLinus Torvalds 
parport_pc_read_status(struct parport * p)2141da177e4SLinus Torvalds static __inline__ unsigned char parport_pc_read_status(struct parport *p)
2151da177e4SLinus Torvalds {
2161da177e4SLinus Torvalds 	return inb(STATUS(p));
2171da177e4SLinus Torvalds }
2181da177e4SLinus Torvalds 
2191da177e4SLinus Torvalds 
parport_pc_disable_irq(struct parport * p)2201da177e4SLinus Torvalds static __inline__ void parport_pc_disable_irq(struct parport *p)
2211da177e4SLinus Torvalds {
2221da177e4SLinus Torvalds 	__parport_pc_frob_control (p, 0x10, 0x00);
2231da177e4SLinus Torvalds }
2241da177e4SLinus Torvalds 
parport_pc_enable_irq(struct parport * p)2251da177e4SLinus Torvalds static __inline__ void parport_pc_enable_irq(struct parport *p)
2261da177e4SLinus Torvalds {
2271da177e4SLinus Torvalds 	__parport_pc_frob_control (p, 0x10, 0x10);
2281da177e4SLinus Torvalds }
2291da177e4SLinus Torvalds 
2301da177e4SLinus Torvalds extern void parport_pc_release_resources(struct parport *p);
2311da177e4SLinus Torvalds 
2321da177e4SLinus Torvalds extern int parport_pc_claim_resources(struct parport *p);
2331da177e4SLinus Torvalds 
2341da177e4SLinus Torvalds /* PCMCIA code will want to get us to look at a port.  Provide a mechanism. */
2351da177e4SLinus Torvalds extern struct parport *parport_pc_probe_port(unsigned long base,
2361da177e4SLinus Torvalds 					     unsigned long base_hi,
2371da177e4SLinus Torvalds 					     int irq, int dma,
23851dcdfecSAlan Cox 					     struct device *dev,
23951dcdfecSAlan Cox 					     int irqflags);
2401da177e4SLinus Torvalds extern void parport_pc_unregister_port(struct parport *p);
2411da177e4SLinus Torvalds 
2421da177e4SLinus Torvalds #endif
243