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