1/*-
  2 * SPDX-License-Identifier: BSD-2-Clause
  3 *
  4 * Copyright (c) 1997, 1998, 1999 Nicolas Souchu
  5 * All rights reserved.
  6 *
  7 * Redistribution and use in source and binary forms, with or without
  8 * modification, are permitted provided that the following conditions
  9 * are met:
 10 * 1. Redistributions of source code must retain the above copyright
 11 *    notice, this list of conditions and the following disclaimer.
 12 * 2. Redistributions in binary form must reproduce the above copyright
 13 *    notice, this list of conditions and the following disclaimer in the
 14 *    documentation and/or other materials provided with the distribution.
 15 *
 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 26 * SUCH DAMAGE.
 27 *
 28 */
 29#ifndef __PPBCONF_H
 30#define __PPBCONF_H
 31
 32#define n(flags) (~(flags) & (flags))
 33
 34/*
 35 * Parallel Port Chipset control bits.
 36 */
 37#define STROBE		0x01
 38#define AUTOFEED	0x02
 39#define nINIT		0x04
 40#define SELECTIN	0x08
 41#define IRQENABLE	0x10
 42#define PCD		0x20
 43
 44#define nSTROBE		n(STROBE)
 45#define nAUTOFEED	n(AUTOFEED)
 46#define INIT		n(nINIT)
 47#define nSELECTIN	n(SELECTIN)
 48#define nPCD		n(PCD)
 49
 50/*
 51 * Parallel Port Chipset status bits.
 52 */
 53#define TIMEOUT		0x01
 54#define nFAULT		0x08
 55#define SELECT		0x10
 56#define PERROR		0x20
 57#define nACK		0x40
 58#define nBUSY		0x80
 59
 60#ifdef _KERNEL
 61#include <sys/queue.h>
 62
 63/*
 64 * Parallel Port Bus sleep/wakeup queue.
 65 */
 66#define PPBPRI	(PZERO+8)
 67
 68/*
 69 * Parallel Port Chipset mode masks.
 70 * NIBBLE mode is supposed to be available under each other modes.
 71 */
 72#define PPB_COMPATIBLE	0x0	/* Centronics compatible mode */
 73
 74#define PPB_NIBBLE	0x1	/* reverse 4 bit mode */
 75#define PPB_PS2		0x2	/* PS/2 byte mode */
 76#define PPB_EPP		0x4	/* EPP mode, 32 bit */
 77#define PPB_ECP		0x8	/* ECP mode */
 78
 79/* mode aliases */
 80#define PPB_SPP		PPB_NIBBLE|PPB_PS2
 81#define PPB_BYTE	PPB_PS2
 82
 83#define PPB_MASK		0x0f
 84#define PPB_OPTIONS_MASK	0xf0
 85
 86#define PPB_IS_EPP(mode) (mode & PPB_EPP)
 87#define PPB_IN_EPP_MODE(bus) (PPB_IS_EPP (ppb_get_mode (bus)))
 88#define PPB_IN_NIBBLE_MODE(bus) (ppb_get_mode (bus) & PPB_NIBBLE)
 89#define PPB_IN_PS2_MODE(bus) (ppb_get_mode (bus) & PPB_PS2)
 90
 91/*
 92 * Structure to store status information.
 93 */
 94struct ppb_status {
 95	unsigned char status;
 96
 97	unsigned int timeout:1;
 98	unsigned int error:1;
 99	unsigned int select:1;
100	unsigned int paper_end:1;
101	unsigned int ack:1;
102	unsigned int busy:1;
103};
104
105/* Parallel port bus I/O opcodes */
106#define PPB_OUTSB_EPP	1
107#define PPB_OUTSW_EPP	2
108#define PPB_OUTSL_EPP	3
109#define PPB_INSB_EPP	4
110#define PPB_INSW_EPP	5
111#define PPB_INSL_EPP	6
112#define PPB_RDTR	7
113#define PPB_RSTR	8
114#define PPB_RCTR	9
115#define PPB_REPP_A	10
116#define PPB_REPP_D	11
117#define PPB_RECR	12
118#define PPB_RFIFO	13
119#define PPB_WDTR	14
120#define PPB_WSTR	15
121#define PPB_WCTR	16
122#define PPB_WEPP_A	17
123#define PPB_WEPP_D	18
124#define PPB_WECR	19
125#define PPB_WFIFO	20
126
127/*
128 * How tsleep() is called in ppb_request_bus().
129 */
130#define PPB_DONTWAIT	0
131#define PPB_NOINTR	0
132#define PPB_WAIT	0x1
133#define PPB_INTR	0x2
134#define PPB_POLL	0x4
135#define PPB_FOREVER	-1
136
137/*
138 * Microsequence stuff.
139 */
140#define PPB_MS_MAXLEN	64		/* XXX according to MS_INS_MASK */
141#define PPB_MS_MAXARGS	3		/* according to MS_ARG_MASK */
142
143/* maximum number of mode dependent
144 * submicrosequences for in/out operations
145 */
146#define PPB_MAX_XFER	6
147
148union ppb_insarg {
149	int	i;
150	void	*p;
151	char	*c;
152	int	(* f)(void *, char *);
153};
154
155struct ppb_microseq {
156	int			opcode;			/* microins. opcode */
157	union ppb_insarg	arg[PPB_MS_MAXARGS];	/* arguments */
158};
159
160/* microseqences used for GET/PUT operations */
161struct ppb_xfer {
162	struct ppb_microseq *loop;		/* the loop microsequence */
163};
164
165/*
166 * Parallel Port Bus Device structure.
167 */
168struct ppb_data;			/* see below */
169
170struct ppb_context {
171	int valid;			/* 1 if the struct is valid */
172	int mode;			/* XXX chipset operating mode */
173
174	struct microseq *curpc;		/* pc in curmsq */
175	struct microseq *curmsq;	/* currently executed microseqence */
176};
177
178/*
179 * List of IVARS available to ppb device drivers
180 */
181#define PPBUS_IVAR_MODE 0
182
183/* other fields are reserved to the ppbus internals */
184
185struct ppb_device {
186	const char *name;		/* name of the device */
187
188	u_int flags;			/* flags */
189
190	struct ppb_context ctx;		/* context of the device */
191
192					/* mode dependent get msq. If NULL,
193					 * IEEE1284 code is used */
194	struct ppb_xfer
195		get_xfer[PPB_MAX_XFER];
196
197					/* mode dependent put msq. If NULL,
198					 * IEEE1284 code is used */
199	struct ppb_xfer
200		put_xfer[PPB_MAX_XFER];
201
202	driver_intr_t *intr_hook;
203	void *intr_arg;
204};
205
206/* EPP standards */
207#define EPP_1_9		0x0			/* default */
208#define EPP_1_7		0x1
209
210/* Parallel Port Chipset IVARS */		/* elsewhere XXX */
211#define PPC_IVAR_EPP_PROTO	0
212#define PPC_IVAR_LOCK		1
213#define PPC_IVAR_INTR_HANDLER	2
214
215/*
216 * Maximum size of the PnP info string
217 */
218#define PPB_PnP_STRING_SIZE	256			/* XXX */
219
220/*
221 * Parallel Port Bus structure.
222 */
223struct ppb_data {
224#define PPB_PnP_PRINTER	0
225#define PPB_PnP_MODEM	1
226#define PPB_PnP_NET	2
227#define PPB_PnP_HDC	3
228#define PPB_PnP_PCMCIA	4
229#define PPB_PnP_MEDIA	5
230#define PPB_PnP_FDC	6
231#define PPB_PnP_PORTS	7
232#define PPB_PnP_SCANNER	8
233#define PPB_PnP_DIGICAM	9
234#define PPB_PnP_UNKNOWN	10
235	int class_id;		/* not a PnP device if class_id < 0 */
236
237	int state;		/* current IEEE1284 state */
238	int error;		/* last IEEE1284 error */
239
240	int mode;		/* IEEE 1284-1994 mode
241				 * NIBBLE, PS2, EPP or ECP */
242
243	device_t ppb_owner;	/* device which owns the bus */
244
245	struct mtx *ppc_lock;	/* lock of parent device */
246	struct resource *ppc_irq_res;
247};
248
249struct callout;
250
251typedef int (*ppc_intr_handler)(void *);
252
253extern int ppb_attach_device(device_t);
254extern int ppb_request_bus(device_t, device_t, int);
255extern int ppb_release_bus(device_t, device_t);
256
257/* bus related functions */
258extern void ppb_lock(device_t);
259extern void ppb_unlock(device_t);
260extern struct mtx *ppb_get_lock(device_t);
261extern void _ppb_assert_locked(device_t, const char *, int);
262extern void ppb_init_callout(device_t, struct callout *, int);
263extern int ppb_sleep(device_t, void *, int, const char *, int);
264extern int ppb_get_status(device_t, struct ppb_status *);
265extern int ppb_poll_bus(device_t, int, uint8_t, uint8_t, int);
266extern int ppb_reset_epp_timeout(device_t);
267extern int ppb_ecp_sync(device_t);
268extern int ppb_get_epp_protocol(device_t);
269extern int ppb_set_mode(device_t, int);		/* returns old mode */
270extern int ppb_get_mode(device_t);		/* returns current mode */
271extern int ppb_write(device_t, char *, int, int);
272
273#ifdef INVARIANTS
274#define ppb_assert_locked(dev)	_ppb_assert_locked(dev, __FILE__, __LINE__)
275#else
276#define ppb_assert_locked(dev)
277#endif
278#endif /* _KERNEL */
279
280#endif /* !__PPBCONF_H */