18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Low-level parallel-support for PC-style hardware integrated in the 48c2ecf20Sopenharmony_ci * LASI-Controller (on GSC-Bus) for HP-PARISC Workstations 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * (C) 1999-2001 by Helge Deller <deller@gmx.de> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * based on parport_pc.c by 98c2ecf20Sopenharmony_ci * Grant Guenther <grant@torque.net> 108c2ecf20Sopenharmony_ci * Phil Blundell <Philip.Blundell@pobox.com> 118c2ecf20Sopenharmony_ci * Tim Waugh <tim@cyberelk.demon.co.uk> 128c2ecf20Sopenharmony_ci * Jose Renau <renau@acm.org> 138c2ecf20Sopenharmony_ci * David Campbell 148c2ecf20Sopenharmony_ci * Andrea Arcangeli 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifndef __DRIVERS_PARPORT_PARPORT_GSC_H 188c2ecf20Sopenharmony_ci#define __DRIVERS_PARPORT_PARPORT_GSC_H 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include <asm/io.h> 218c2ecf20Sopenharmony_ci#include <linux/delay.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#undef DEBUG_PARPORT /* undefine for production */ 248c2ecf20Sopenharmony_ci#define DELAY_TIME 0 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#if DELAY_TIME == 0 278c2ecf20Sopenharmony_ci#define parport_readb gsc_readb 288c2ecf20Sopenharmony_ci#define parport_writeb gsc_writeb 298c2ecf20Sopenharmony_ci#else 308c2ecf20Sopenharmony_cistatic __inline__ unsigned char parport_readb( unsigned long port ) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci udelay(DELAY_TIME); 338c2ecf20Sopenharmony_ci return gsc_readb(port); 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic __inline__ void parport_writeb( unsigned char value, unsigned long port ) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci gsc_writeb(value,port); 398c2ecf20Sopenharmony_ci udelay(DELAY_TIME); 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci#endif 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* --- register definitions ------------------------------- */ 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define EPPDATA(p) ((p)->base + 0x4) 468c2ecf20Sopenharmony_ci#define EPPADDR(p) ((p)->base + 0x3) 478c2ecf20Sopenharmony_ci#define CONTROL(p) ((p)->base + 0x2) 488c2ecf20Sopenharmony_ci#define STATUS(p) ((p)->base + 0x1) 498c2ecf20Sopenharmony_ci#define DATA(p) ((p)->base + 0x0) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistruct parport_gsc_private { 528c2ecf20Sopenharmony_ci /* Contents of CTR. */ 538c2ecf20Sopenharmony_ci unsigned char ctr; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci /* Bitmask of writable CTR bits. */ 568c2ecf20Sopenharmony_ci unsigned char ctr_writable; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci /* Number of bytes per portword. */ 598c2ecf20Sopenharmony_ci int pword; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* Not used yet. */ 628c2ecf20Sopenharmony_ci int readIntrThreshold; 638c2ecf20Sopenharmony_ci int writeIntrThreshold; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci /* buffer suitable for DMA, if DMA enabled */ 668c2ecf20Sopenharmony_ci char *dma_buf; 678c2ecf20Sopenharmony_ci dma_addr_t dma_handle; 688c2ecf20Sopenharmony_ci struct pci_dev *dev; 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic inline void parport_gsc_write_data(struct parport *p, unsigned char d) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci#ifdef DEBUG_PARPORT 748c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s(%p,0x%02x)\n", __func__, p, d); 758c2ecf20Sopenharmony_ci#endif 768c2ecf20Sopenharmony_ci parport_writeb(d, DATA(p)); 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic inline unsigned char parport_gsc_read_data(struct parport *p) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci unsigned char val = parport_readb (DATA (p)); 828c2ecf20Sopenharmony_ci#ifdef DEBUG_PARPORT 838c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s(%p) = 0x%02x\n", __func__, p, val); 848c2ecf20Sopenharmony_ci#endif 858c2ecf20Sopenharmony_ci return val; 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/* __parport_gsc_frob_control differs from parport_gsc_frob_control in that 898c2ecf20Sopenharmony_ci * it doesn't do any extra masking. */ 908c2ecf20Sopenharmony_cistatic inline unsigned char __parport_gsc_frob_control(struct parport *p, 918c2ecf20Sopenharmony_ci unsigned char mask, 928c2ecf20Sopenharmony_ci unsigned char val) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci struct parport_gsc_private *priv = p->physport->private_data; 958c2ecf20Sopenharmony_ci unsigned char ctr = priv->ctr; 968c2ecf20Sopenharmony_ci#ifdef DEBUG_PARPORT 978c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s(%02x,%02x): %02x -> %02x\n", 988c2ecf20Sopenharmony_ci __func__, mask, val, 998c2ecf20Sopenharmony_ci ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); 1008c2ecf20Sopenharmony_ci#endif 1018c2ecf20Sopenharmony_ci ctr = (ctr & ~mask) ^ val; 1028c2ecf20Sopenharmony_ci ctr &= priv->ctr_writable; /* only write writable bits. */ 1038c2ecf20Sopenharmony_ci parport_writeb (ctr, CONTROL (p)); 1048c2ecf20Sopenharmony_ci priv->ctr = ctr; /* Update soft copy */ 1058c2ecf20Sopenharmony_ci return ctr; 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic inline void parport_gsc_data_reverse(struct parport *p) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci __parport_gsc_frob_control (p, 0x20, 0x20); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic inline void parport_gsc_data_forward(struct parport *p) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci __parport_gsc_frob_control (p, 0x20, 0x00); 1168c2ecf20Sopenharmony_ci} 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic inline void parport_gsc_write_control(struct parport *p, 1198c2ecf20Sopenharmony_ci unsigned char d) 1208c2ecf20Sopenharmony_ci{ 1218c2ecf20Sopenharmony_ci const unsigned char wm = (PARPORT_CONTROL_STROBE | 1228c2ecf20Sopenharmony_ci PARPORT_CONTROL_AUTOFD | 1238c2ecf20Sopenharmony_ci PARPORT_CONTROL_INIT | 1248c2ecf20Sopenharmony_ci PARPORT_CONTROL_SELECT); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci /* Take this out when drivers have adapted to newer interface. */ 1278c2ecf20Sopenharmony_ci if (d & 0x20) { 1288c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s (%s): use data_reverse for this!\n", 1298c2ecf20Sopenharmony_ci p->name, p->cad->name); 1308c2ecf20Sopenharmony_ci parport_gsc_data_reverse (p); 1318c2ecf20Sopenharmony_ci } 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci __parport_gsc_frob_control (p, wm, d & wm); 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic inline unsigned char parport_gsc_read_control(struct parport *p) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci const unsigned char rm = (PARPORT_CONTROL_STROBE | 1398c2ecf20Sopenharmony_ci PARPORT_CONTROL_AUTOFD | 1408c2ecf20Sopenharmony_ci PARPORT_CONTROL_INIT | 1418c2ecf20Sopenharmony_ci PARPORT_CONTROL_SELECT); 1428c2ecf20Sopenharmony_ci const struct parport_gsc_private *priv = p->physport->private_data; 1438c2ecf20Sopenharmony_ci return priv->ctr & rm; /* Use soft copy */ 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic inline unsigned char parport_gsc_frob_control(struct parport *p, 1478c2ecf20Sopenharmony_ci unsigned char mask, 1488c2ecf20Sopenharmony_ci unsigned char val) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci const unsigned char wm = (PARPORT_CONTROL_STROBE | 1518c2ecf20Sopenharmony_ci PARPORT_CONTROL_AUTOFD | 1528c2ecf20Sopenharmony_ci PARPORT_CONTROL_INIT | 1538c2ecf20Sopenharmony_ci PARPORT_CONTROL_SELECT); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci /* Take this out when drivers have adapted to newer interface. */ 1568c2ecf20Sopenharmony_ci if (mask & 0x20) { 1578c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s (%s): use data_%s for this!\n", 1588c2ecf20Sopenharmony_ci p->name, p->cad->name, 1598c2ecf20Sopenharmony_ci (val & 0x20) ? "reverse" : "forward"); 1608c2ecf20Sopenharmony_ci if (val & 0x20) 1618c2ecf20Sopenharmony_ci parport_gsc_data_reverse (p); 1628c2ecf20Sopenharmony_ci else 1638c2ecf20Sopenharmony_ci parport_gsc_data_forward (p); 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci /* Restrict mask and val to control lines. */ 1678c2ecf20Sopenharmony_ci mask &= wm; 1688c2ecf20Sopenharmony_ci val &= wm; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci return __parport_gsc_frob_control (p, mask, val); 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic inline unsigned char parport_gsc_read_status(struct parport *p) 1748c2ecf20Sopenharmony_ci{ 1758c2ecf20Sopenharmony_ci return parport_readb (STATUS(p)); 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic inline void parport_gsc_disable_irq(struct parport *p) 1798c2ecf20Sopenharmony_ci{ 1808c2ecf20Sopenharmony_ci __parport_gsc_frob_control (p, 0x10, 0x00); 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic inline void parport_gsc_enable_irq(struct parport *p) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci __parport_gsc_frob_control (p, 0x10, 0x10); 1868c2ecf20Sopenharmony_ci} 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ciextern void parport_gsc_release_resources(struct parport *p); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ciextern int parport_gsc_claim_resources(struct parport *p); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ciextern void parport_gsc_init_state(struct pardevice *, struct parport_state *s); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ciextern void parport_gsc_save_state(struct parport *p, struct parport_state *s); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ciextern void parport_gsc_restore_state(struct parport *p, struct parport_state *s); 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ciextern void parport_gsc_inc_use_count(void); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ciextern void parport_gsc_dec_use_count(void); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ciextern struct parport *parport_gsc_probe_port(unsigned long base, 2038c2ecf20Sopenharmony_ci unsigned long base_hi, 2048c2ecf20Sopenharmony_ci int irq, int dma, 2058c2ecf20Sopenharmony_ci struct parisc_device *padev); 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci#endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ 208