ppb_1284.c revision 28980
1/*-
2 * Copyright (c) 1997 Nicolas Souchu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 *	$Id: ppb_1284.c,v 1.1 1997/08/16 14:05:32 msmith Exp $
27 *
28 */
29#include <sys/param.h>
30#include <sys/systm.h>
31
32#include <machine/clock.h>
33
34#include <dev/ppbus/ppbconf.h>
35#include <dev/ppbus/ppb_1284.h>
36
37/*
38 * nibble_1284_wait()
39 *
40 * Wait for the peripherial up to 40ms
41 */
42int
43nibble_1284_wait(struct ppb_device *dev, char mask, char status)
44{
45	int i;
46
47	return (ppb_poll_device(dev, 4, mask, status, PPB_NOINTR));
48}
49
50#define nibble2char(s) (((s & ~nACK) >> 3) | (~s & nBUSY) >> 4)
51
52/*
53 * nibble_1284_inbyte()
54 *
55 * Read data in NIBBLE mode
56 */
57int
58nibble_1284_inbyte(struct ppb_device *dev, char *buffer)
59{
60	char nibble[2], r;
61	int i, error;
62
63	r = ppb_rctr(dev);
64
65	for (i = 0; i < 2; i++) {
66		/* ready to take data (nAUTO low) */
67		ppb_wctr(dev, r | AUTOFEED);
68
69		if ((error = nibble_1284_wait(dev, nACK, 0))) {
70			ppb_wctr(dev, r);
71			return (error);
72		}
73
74		/* read nibble */
75		nibble[i] = ppb_rstr(dev);
76
77#ifdef DEBUG_1284
78		printf("nibble_1284_inbyte: nibble[%d]=0x%x\n", i, nibble[i]);
79#endif
80
81		/* ack, not ready for another nibble */
82		ppb_wctr(dev, r & ~AUTOFEED);
83
84		/* wait ack from peripherial */
85		if ((error = nibble_1284_wait(dev, nACK, nACK))) {
86			ppb_wctr(dev, r);
87			return (error);
88		}
89	}
90
91	*buffer = ((nibble2char(nibble[1]) << 4) & 0xf0) |
92				(nibble2char(nibble[0]) & 0x0f);
93
94#ifdef DEBUG_1284
95	printf("nibble_1284_inbyte: byte=0x%x\n", *buffer);
96#endif
97
98	return (0);
99}
100
101/*
102 * nibble_1284_sync()
103 */
104void
105nibble_1284_sync(struct ppb_device *dev)
106{
107	char ctr;
108
109	ctr = ppb_rctr(dev);
110
111	ppb_wctr(dev, (ctr & ~AUTOFEED) | SELECTIN);
112	if (nibble_1284_wait(dev, nACK, 0))
113		return;
114
115	ppb_wctr(dev, ctr | AUTOFEED);
116	nibble_1284_wait(dev, nACK, nACK);
117
118	ppb_wctr(dev, (ctr & ~AUTOFEED) | SELECTIN);
119
120	return;
121}
122
123/*
124 * nibble_1284_mode()
125 *
126 * Normal nibble mode or request device id mode (see ppb_1284.h)
127 */
128int
129nibble_1284_mode(struct ppb_device *dev, int mode)
130{
131	char ctrl;
132	int error;
133
134	ctrl = ppb_rctr(dev);
135
136	ppb_wdtr(dev, mode);
137	DELAY(5);
138
139	ppb_wctr(dev, (ctrl & ~SELECTIN) | AUTOFEED);
140	if ((error = nibble_1284_wait(dev, nACK | ERROR | SELECT | nFAULT,
141			ERROR | SELECT | nFAULT))) {
142		ppb_wctr(dev, ctrl);
143		return (error);
144	}
145
146	ppb_wctr(dev, ppb_rctr(dev) | STROBE);
147	DELAY(5);
148
149	ppb_wctr(dev, ppb_rctr(dev) & ~STROBE);
150	DELAY(5);
151
152	ppb_wctr(dev, ppb_rctr(dev) & ~AUTOFEED);
153
154	return (0);
155}
156