243 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef __LINUX_PARPORT_PC_H3#define __LINUX_PARPORT_PC_H4 5#include <asm/io.h>6 7/* --- register definitions ------------------------------- */8 9#define ECONTROL(p) ((p)->base_hi + 0x2)10#define CONFIGB(p) ((p)->base_hi + 0x1)11#define CONFIGA(p) ((p)->base_hi + 0x0)12#define FIFO(p) ((p)->base_hi + 0x0)13#define EPPDATA(p) ((p)->base + 0x4)14#define EPPADDR(p) ((p)->base + 0x3)15#define CONTROL(p) ((p)->base + 0x2)16#define STATUS(p) ((p)->base + 0x1)17#define DATA(p) ((p)->base + 0x0)18 19struct parport_pc_private {20 /* Contents of CTR. */21 unsigned char ctr;22 23 /* Bitmask of writable CTR bits. */24 unsigned char ctr_writable;25 26 /* Whether or not there's an ECR. */27 int ecr;28 29 /* Bitmask of writable ECR bits. */30 unsigned char ecr_writable;31 32 /* Number of PWords that FIFO will hold. */33 int fifo_depth;34 35 /* Number of bytes per portword. */36 int pword;37 38 /* Not used yet. */39 int readIntrThreshold;40 int writeIntrThreshold;41 42 /* buffer suitable for DMA, if DMA enabled */43 char *dma_buf;44 dma_addr_t dma_handle;45 struct list_head list;46 struct parport *port;47};48 49struct parport_pc_via_data50{51 /* ISA PnP IRQ routing register 1 */52 u8 via_pci_parport_irq_reg;53 /* ISA PnP DMA request routing register */54 u8 via_pci_parport_dma_reg;55 /* Register and value to enable SuperIO configuration access */56 u8 via_pci_superio_config_reg;57 u8 via_pci_superio_config_data;58 /* SuperIO function register number */59 u8 viacfg_function;60 /* parallel port control register number */61 u8 viacfg_parport_control;62 /* Parallel port base address register */63 u8 viacfg_parport_base;64};65 66static __inline__ void parport_pc_write_data(struct parport *p, unsigned char d)67{68#ifdef DEBUG_PARPORT69 printk (KERN_DEBUG "parport_pc_write_data(%p,0x%02x)\n", p, d);70#endif71 outb(d, DATA(p));72}73 74static __inline__ unsigned char parport_pc_read_data(struct parport *p)75{76 unsigned char val = inb (DATA (p));77#ifdef DEBUG_PARPORT78 printk (KERN_DEBUG "parport_pc_read_data(%p) = 0x%02x\n",79 p, val);80#endif81 return val;82}83 84#ifdef DEBUG_PARPORT85static inline void dump_parport_state (char *str, struct parport *p)86{87 /* here's hoping that reading these ports won't side-effect anything underneath */88 unsigned char ecr = inb (ECONTROL (p));89 unsigned char dcr = inb (CONTROL (p));90 unsigned char dsr = inb (STATUS (p));91 static const char *const ecr_modes[] = {"SPP", "PS2", "PPFIFO", "ECP", "xXx", "yYy", "TST", "CFG"};92 const struct parport_pc_private *priv = p->physport->private_data;93 int i;94 95 printk (KERN_DEBUG "*** parport state (%s): ecr=[%s", str, ecr_modes[(ecr & 0xe0) >> 5]);96 if (ecr & 0x10) printk (",nErrIntrEn");97 if (ecr & 0x08) printk (",dmaEn");98 if (ecr & 0x04) printk (",serviceIntr");99 if (ecr & 0x02) printk (",f_full");100 if (ecr & 0x01) printk (",f_empty");101 for (i=0; i<2; i++) {102 printk ("] dcr(%s)=[", i ? "soft" : "hard");103 dcr = i ? priv->ctr : inb (CONTROL (p));104 105 if (dcr & 0x20) {106 printk ("rev");107 } else {108 printk ("fwd");109 }110 if (dcr & 0x10) printk (",ackIntEn");111 if (!(dcr & 0x08)) printk (",N-SELECT-IN");112 if (dcr & 0x04) printk (",N-INIT");113 if (!(dcr & 0x02)) printk (",N-AUTOFD");114 if (!(dcr & 0x01)) printk (",N-STROBE");115 }116 printk ("] dsr=[");117 if (!(dsr & 0x80)) printk ("BUSY");118 if (dsr & 0x40) printk (",N-ACK");119 if (dsr & 0x20) printk (",PERROR");120 if (dsr & 0x10) printk (",SELECT");121 if (dsr & 0x08) printk (",N-FAULT");122 printk ("]\n");123 return;124}125#else /* !DEBUG_PARPORT */126#define dump_parport_state(args...)127#endif /* !DEBUG_PARPORT */128 129/* __parport_pc_frob_control differs from parport_pc_frob_control in that130 * it doesn't do any extra masking. */131static __inline__ unsigned char __parport_pc_frob_control (struct parport *p,132 unsigned char mask,133 unsigned char val)134{135 struct parport_pc_private *priv = p->physport->private_data;136 unsigned char ctr = priv->ctr;137#ifdef DEBUG_PARPORT138 printk (KERN_DEBUG139 "__parport_pc_frob_control(%02x,%02x): %02x -> %02x\n",140 mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);141#endif142 ctr = (ctr & ~mask) ^ val;143 ctr &= priv->ctr_writable; /* only write writable bits. */144 outb (ctr, CONTROL (p));145 priv->ctr = ctr; /* Update soft copy */146 return ctr;147}148 149static __inline__ void parport_pc_data_reverse (struct parport *p)150{151 __parport_pc_frob_control (p, 0x20, 0x20);152}153 154static __inline__ void parport_pc_data_forward (struct parport *p)155{156 __parport_pc_frob_control (p, 0x20, 0x00);157}158 159static __inline__ void parport_pc_write_control (struct parport *p,160 unsigned char d)161{162 const unsigned char wm = (PARPORT_CONTROL_STROBE |163 PARPORT_CONTROL_AUTOFD |164 PARPORT_CONTROL_INIT |165 PARPORT_CONTROL_SELECT);166 167 /* Take this out when drivers have adapted to newer interface. */168 if (d & 0x20) {169 printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",170 p->name, p->cad->name);171 parport_pc_data_reverse (p);172 }173 174 __parport_pc_frob_control (p, wm, d & wm);175}176 177static __inline__ unsigned char parport_pc_read_control(struct parport *p)178{179 const unsigned char rm = (PARPORT_CONTROL_STROBE |180 PARPORT_CONTROL_AUTOFD |181 PARPORT_CONTROL_INIT |182 PARPORT_CONTROL_SELECT);183 const struct parport_pc_private *priv = p->physport->private_data;184 return priv->ctr & rm; /* Use soft copy */185}186 187static __inline__ unsigned char parport_pc_frob_control (struct parport *p,188 unsigned char mask,189 unsigned char val)190{191 const unsigned char wm = (PARPORT_CONTROL_STROBE |192 PARPORT_CONTROL_AUTOFD |193 PARPORT_CONTROL_INIT |194 PARPORT_CONTROL_SELECT);195 196 /* Take this out when drivers have adapted to newer interface. */197 if (mask & 0x20) {198 printk (KERN_DEBUG "%s (%s): use data_%s for this!\n",199 p->name, p->cad->name,200 (val & 0x20) ? "reverse" : "forward");201 if (val & 0x20)202 parport_pc_data_reverse (p);203 else204 parport_pc_data_forward (p);205 }206 207 /* Restrict mask and val to control lines. */208 mask &= wm;209 val &= wm;210 211 return __parport_pc_frob_control (p, mask, val);212}213 214static __inline__ unsigned char parport_pc_read_status(struct parport *p)215{216 return inb(STATUS(p));217}218 219 220static __inline__ void parport_pc_disable_irq(struct parport *p)221{222 __parport_pc_frob_control (p, 0x10, 0x00);223}224 225static __inline__ void parport_pc_enable_irq(struct parport *p)226{227 __parport_pc_frob_control (p, 0x10, 0x10);228}229 230extern void parport_pc_release_resources(struct parport *p);231 232extern int parport_pc_claim_resources(struct parport *p);233 234/* PCMCIA code will want to get us to look at a port. Provide a mechanism. */235extern struct parport *parport_pc_probe_port(unsigned long base,236 unsigned long base_hi,237 int irq, int dma,238 struct device *dev,239 int irqflags);240extern void parport_pc_unregister_port(struct parport *p);241 242#endif243