1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /* ns87303.h: Configuration Register Description for the
3*4882a593Smuzhiyun * National Semiconductor PC87303 (SuperIO).
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #ifndef _SPARC_NS87303_H
9*4882a593Smuzhiyun #define _SPARC_NS87303_H 1
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun /*
12*4882a593Smuzhiyun * Control Register Index Values
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun #define FER 0x00
15*4882a593Smuzhiyun #define FAR 0x01
16*4882a593Smuzhiyun #define PTR 0x02
17*4882a593Smuzhiyun #define FCR 0x03
18*4882a593Smuzhiyun #define PCR 0x04
19*4882a593Smuzhiyun #define KRR 0x05
20*4882a593Smuzhiyun #define PMC 0x06
21*4882a593Smuzhiyun #define TUP 0x07
22*4882a593Smuzhiyun #define SID 0x08
23*4882a593Smuzhiyun #define ASC 0x09
24*4882a593Smuzhiyun #define CS0CF0 0x0a
25*4882a593Smuzhiyun #define CS0CF1 0x0b
26*4882a593Smuzhiyun #define CS1CF0 0x0c
27*4882a593Smuzhiyun #define CS1CF1 0x0d
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun /* Function Enable Register (FER) bits */
30*4882a593Smuzhiyun #define FER_EDM 0x10 /* Encoded Drive and Motor pin information */
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun /* Function Address Register (FAR) bits */
33*4882a593Smuzhiyun #define FAR_LPT_MASK 0x03
34*4882a593Smuzhiyun #define FAR_LPTB 0x00
35*4882a593Smuzhiyun #define FAR_LPTA 0x01
36*4882a593Smuzhiyun #define FAR_LPTC 0x02
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun /* Power and Test Register (PTR) bits */
39*4882a593Smuzhiyun #define PTR_LPTB_IRQ7 0x08
40*4882a593Smuzhiyun #define PTR_LEVEL_IRQ 0x80 /* When not ECP/EPP: Use level IRQ */
41*4882a593Smuzhiyun #define PTR_LPT_REG_DIR 0x80 /* When ECP/EPP: LPT CTR controls direction */
42*4882a593Smuzhiyun /* of the parallel port */
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* Function Control Register (FCR) bits */
45*4882a593Smuzhiyun #define FCR_LDE 0x10 /* Logical Drive Exchange */
46*4882a593Smuzhiyun #define FCR_ZWS_ENA 0x20 /* Enable short host read/write in ECP/EPP */
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /* Printer Control Register (PCR) bits */
49*4882a593Smuzhiyun #define PCR_EPP_ENABLE 0x01
50*4882a593Smuzhiyun #define PCR_EPP_IEEE 0x02 /* Enable EPP Version 1.9 (IEEE 1284) */
51*4882a593Smuzhiyun #define PCR_ECP_ENABLE 0x04
52*4882a593Smuzhiyun #define PCR_ECP_CLK_ENA 0x08 /* If 0 ECP Clock is stopped on Power down */
53*4882a593Smuzhiyun #define PCR_IRQ_POLAR 0x20 /* If 0 IRQ is level high or negative pulse, */
54*4882a593Smuzhiyun /* if 1 polarity is inverted */
55*4882a593Smuzhiyun #define PCR_IRQ_ODRAIN 0x40 /* If 1, IRQ is open drain */
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* Tape UARTs and Parallel Port Config Register (TUP) bits */
58*4882a593Smuzhiyun #define TUP_EPP_TIMO 0x02 /* Enable EPP timeout IRQ */
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun /* Advanced SuperIO Config Register (ASC) bits */
61*4882a593Smuzhiyun #define ASC_LPT_IRQ7 0x01 /* Always use IRQ7 for LPT */
62*4882a593Smuzhiyun #define ASC_DRV2_SEL 0x02 /* Logical Drive Exchange controlled by TDR */
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #define FER_RESERVED 0x00
65*4882a593Smuzhiyun #define FAR_RESERVED 0x00
66*4882a593Smuzhiyun #define PTR_RESERVED 0x73
67*4882a593Smuzhiyun #define FCR_RESERVED 0xc4
68*4882a593Smuzhiyun #define PCR_RESERVED 0x10
69*4882a593Smuzhiyun #define KRR_RESERVED 0x00
70*4882a593Smuzhiyun #define PMC_RESERVED 0x98
71*4882a593Smuzhiyun #define TUP_RESERVED 0xfb
72*4882a593Smuzhiyun #define SIP_RESERVED 0x00
73*4882a593Smuzhiyun #define ASC_RESERVED 0x18
74*4882a593Smuzhiyun #define CS0CF0_RESERVED 0x00
75*4882a593Smuzhiyun #define CS0CF1_RESERVED 0x08
76*4882a593Smuzhiyun #define CS1CF0_RESERVED 0x00
77*4882a593Smuzhiyun #define CS1CF1_RESERVED 0x08
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun #ifdef __KERNEL__
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun #include <linux/spinlock.h>
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #include <asm/io.h>
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun extern spinlock_t ns87303_lock;
86*4882a593Smuzhiyun
ns87303_modify(unsigned long port,unsigned int index,unsigned char clr,unsigned char set)87*4882a593Smuzhiyun static inline int ns87303_modify(unsigned long port, unsigned int index,
88*4882a593Smuzhiyun unsigned char clr, unsigned char set)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun static unsigned char reserved[] = {
91*4882a593Smuzhiyun FER_RESERVED, FAR_RESERVED, PTR_RESERVED, FCR_RESERVED,
92*4882a593Smuzhiyun PCR_RESERVED, KRR_RESERVED, PMC_RESERVED, TUP_RESERVED,
93*4882a593Smuzhiyun SIP_RESERVED, ASC_RESERVED, CS0CF0_RESERVED, CS0CF1_RESERVED,
94*4882a593Smuzhiyun CS1CF0_RESERVED, CS1CF1_RESERVED
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun unsigned long flags;
97*4882a593Smuzhiyun unsigned char value;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun if (index > 0x0d)
100*4882a593Smuzhiyun return -EINVAL;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun spin_lock_irqsave(&ns87303_lock, flags);
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun outb(index, port);
105*4882a593Smuzhiyun value = inb(port + 1);
106*4882a593Smuzhiyun value &= ~(reserved[index] | clr);
107*4882a593Smuzhiyun value |= set;
108*4882a593Smuzhiyun outb(value, port + 1);
109*4882a593Smuzhiyun outb(value, port + 1);
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun spin_unlock_irqrestore(&ns87303_lock, flags);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun return 0;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun #endif /* __KERNEL__ */
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun #endif /* !(_SPARC_NS87303_H) */
119