xref: /original-bsd/sys/vax/uba/ad.c (revision 39bdaf89)
1a5032031Smckusick /*
2bd14c547Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
3a5032031Smckusick  * All rights reserved.  The Berkeley software License Agreement
4a5032031Smckusick  * specifies the terms and conditions for redistribution.
5a5032031Smckusick  *
6*39bdaf89Sbostic  *	@(#)ad.c	7.8 (Berkeley) 12/16/90
7a5032031Smckusick  */
8a704d760Ssam 
9a704d760Ssam #include "ad.h"
10a704d760Ssam #if NAD > 0
11a704d760Ssam /*
12a704d760Ssam  * Data translation AD converter interface -- Bill Reeves
13a704d760Ssam  */
14*39bdaf89Sbostic #include "../include/pte.h"
1551ea8f2eSsam 
16*39bdaf89Sbostic #include "sys/param.h"
17*39bdaf89Sbostic #include "sys/ioctl.h"
18*39bdaf89Sbostic #include "sys/user.h"
19*39bdaf89Sbostic #include "sys/buf.h"
20*39bdaf89Sbostic #include "sys/systm.h"
21*39bdaf89Sbostic #include "sys/map.h"
22f65a77c3Sroot 
23146803c9Sbloom #include "ubareg.h"
24146803c9Sbloom #include "ubavar.h"
25146803c9Sbloom #include "adreg.h"
26a704d760Ssam 
27a704d760Ssam #define ADBUSY 01
28a704d760Ssam #define ADWAITPRI (PZERO+1)
29a704d760Ssam 
30a704d760Ssam int adprobe(), adattach();
31a704d760Ssam struct uba_device *addinfo[NAD];
32a704d760Ssam u_short adstd[] = { 0770400, 0000000, 0 };
33a704d760Ssam struct uba_driver addriver =
34a704d760Ssam 	{ adprobe, 0, adattach, 0, adstd, "ad", addinfo, 0, 0 };
35a704d760Ssam 
36a704d760Ssam struct ad {
37a704d760Ssam 	char	ad_open;
38a704d760Ssam 	short int ad_uid;
39a704d760Ssam 	short int ad_state;
40a704d760Ssam 	short int ad_softcsr;
41a704d760Ssam 	short int ad_softdata;
42a704d760Ssam 	short int ad_chan;
43a704d760Ssam 	int	ad_icnt;
44a704d760Ssam 	int	ad_loop;
45a704d760Ssam } ad[NAD];
46a704d760Ssam 
47a704d760Ssam #define ADUNIT(dev) (minor(dev))
48a704d760Ssam 
adprobe(reg)49a704d760Ssam adprobe(reg)
50a704d760Ssam 	caddr_t reg;
51a704d760Ssam {
520015c898Sroot 	register int br, cvec;		/* value-result */
53a704d760Ssam 	register struct addevice *adaddr = (struct addevice *) reg;
54a704d760Ssam 
55a704d760Ssam 	adaddr->ad_csr = AD_IENABLE | AD_START;
56a704d760Ssam 	DELAY(40000);
57a704d760Ssam 	adaddr->ad_csr = 0;
58ec13279bSkre 	return (sizeof (struct addevice));
59a704d760Ssam }
60a704d760Ssam 
610015c898Sroot /*ARGSUSED*/
62a704d760Ssam adattach(ui)
63a704d760Ssam 	struct uba_device *ui;
64a704d760Ssam {
650015c898Sroot 
66a704d760Ssam }
67a704d760Ssam 
adopen(dev)68a704d760Ssam adopen(dev)
69a704d760Ssam 	dev_t dev;
70a704d760Ssam {
71a704d760Ssam 	register struct ad *adp;
72a704d760Ssam 	register struct uba_device *ui;
73a704d760Ssam 
74a704d760Ssam 	if (ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open ||
750015c898Sroot 	    (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0)
760015c898Sroot 		return (ENXIO);
77a704d760Ssam 	adp->ad_open = 1;
78a704d760Ssam 	adp->ad_icnt = 0;
79a704d760Ssam 	adp->ad_state = 0;
80a704d760Ssam 	adp->ad_uid = u.u_uid;
810015c898Sroot 	return (0);
82a704d760Ssam }
83a704d760Ssam 
adclose(dev)84a704d760Ssam adclose(dev)
85a704d760Ssam 	dev_t dev;
86a704d760Ssam {
87a704d760Ssam 
88a704d760Ssam 	ad[ADUNIT(dev)].ad_open = 0;
89a704d760Ssam 	ad[ADUNIT(dev)].ad_state = 0;
90cc8db2eaSkarels 	return (0);
91a704d760Ssam }
92a704d760Ssam 
93a704d760Ssam /*ARGSUSED*/
adioctl(dev,cmd,addr,flag)94a704d760Ssam adioctl(dev, cmd, addr, flag)
95a704d760Ssam 	dev_t dev;
96a704d760Ssam 	register caddr_t addr;
97a704d760Ssam {
98a704d760Ssam 	register struct addevice *adaddr =
99a704d760Ssam 	    (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr;
100a704d760Ssam 	register struct uba_device *ui = addinfo[ADUNIT(dev)];
101a704d760Ssam 	register struct ad *adp;
102a704d760Ssam 	register int i;
103a704d760Ssam 	short int chan;
104a704d760Ssam 
105a704d760Ssam 	switch (cmd) {
1061bd4d42fSsam 
1071bd4d42fSsam 	case ADIOSCHAN:
108a704d760Ssam 		adp = &ad[ADUNIT(dev)];
10927d35b39Smckusick 		adp->ad_chan = (*(int *)addr)<<8;
110a704d760Ssam 		break;
1111bd4d42fSsam 
1121bd4d42fSsam 	case ADIOGETW:
113a704d760Ssam 		adp = &ad[ADUNIT(dev)];
114a704d760Ssam 		spl6();
115a704d760Ssam 		adaddr->ad_csr = adp->ad_chan;
116a704d760Ssam 		i = 1000;
117a704d760Ssam 		while (i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) {
118a704d760Ssam 			adp->ad_loop++;
119a704d760Ssam 			adaddr->ad_csr = adp->ad_chan;
120a704d760Ssam 		}
121a704d760Ssam 		adp->ad_state |= ADBUSY;
122a704d760Ssam 		adaddr->ad_csr |= AD_IENABLE|AD_START;
123cc8db2eaSkarels 		i = 0;
124a704d760Ssam 		while (adp->ad_state&ADBUSY)
125cc8db2eaSkarels 			if (i = tsleep((caddr_t)adp, ADWAITPRI | PCATCH,
126cc8db2eaSkarels 			    devio, 0)
127cc8db2eaSkarels 				break;
128a704d760Ssam 		spl0();
129cc8db2eaSkarels 		if (i)
130cc8db2eaSkarels 			return (i);
13127d35b39Smckusick 		*(int *)addr = adp->ad_softdata;
132a704d760Ssam 		break;
1331bd4d42fSsam 
134a704d760Ssam 	default:
1350015c898Sroot 		return (ENOTTY);	/* Not a legal ioctl cmd. */
136a704d760Ssam 	}
1370015c898Sroot 	return (0);
138a704d760Ssam }
139a704d760Ssam 
140a704d760Ssam /*ARGSUSED*/
141a704d760Ssam adintr(dev)
142a704d760Ssam 	dev_t dev;
143a704d760Ssam {
144a704d760Ssam 	register struct addevice *adaddr =
145a704d760Ssam 			(struct addevice *) addinfo[ADUNIT(dev)]->ui_addr;
146a704d760Ssam 	register struct ad *adp = &ad[ADUNIT(dev)];
147a704d760Ssam 
148a704d760Ssam 	adp->ad_icnt++;
149a704d760Ssam 	adp->ad_softcsr = adaddr->ad_csr;
150a704d760Ssam 	adp->ad_softdata = adaddr->ad_data;
151a704d760Ssam 	if(adp->ad_state&ADBUSY) {
152a704d760Ssam 		adp->ad_state &= ~ADBUSY;
153a704d760Ssam 		wakeup((caddr_t)adp);
154a704d760Ssam 	}
155a704d760Ssam }
156a704d760Ssam 
157a704d760Ssam adreset(uban)
158a704d760Ssam 	int uban;
159a704d760Ssam {
160a704d760Ssam 	register int i;
161a704d760Ssam 	register struct uba_device *ui;
162a704d760Ssam 	register struct ad *adp = ad;
163a704d760Ssam 	register struct addevice *adaddr;
164a704d760Ssam 
165a704d760Ssam 	for(i = 0; i < NAD; i++, adp++) {
166a704d760Ssam 		if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 ||
167a704d760Ssam 				ui->ui_ubanum != uban || adp->ad_open == 0)
168a704d760Ssam 			continue;
169a704d760Ssam 		printf(" ad%d", i);
170a704d760Ssam 		if(adp->ad_state&ADBUSY == 0)
171a704d760Ssam 			continue;
172a704d760Ssam 		adaddr = (struct addevice *) ui->ui_addr;
173a704d760Ssam 		adaddr->ad_csr = 0;
174a704d760Ssam 		adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START;
175a704d760Ssam 	}
176a704d760Ssam }
177a704d760Ssam #endif
178