xref: /csrg-svn/sys/vax/uba/ad.c (revision 40044)
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.4 (Berkeley) 02/08/90
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 #include "tsleep.h"
28 
29 #define ADBUSY 01
30 #define ADWAITPRI (PZERO+1)
31 
32 int adprobe(), adattach();
33 struct uba_device *addinfo[NAD];
34 u_short adstd[] = { 0770400, 0000000, 0 };
35 struct uba_driver addriver =
36 	{ adprobe, 0, adattach, 0, adstd, "ad", addinfo, 0, 0 };
37 
38 struct ad {
39 	char	ad_open;
40 	short int ad_uid;
41 	short int ad_state;
42 	short int ad_softcsr;
43 	short int ad_softdata;
44 	short int ad_chan;
45 	int	ad_icnt;
46 	int	ad_loop;
47 } ad[NAD];
48 
49 #define ADUNIT(dev) (minor(dev))
50 
51 adprobe(reg)
52 	caddr_t reg;
53 {
54 	register int br, cvec;		/* value-result */
55 	register struct addevice *adaddr = (struct addevice *) reg;
56 
57 	adaddr->ad_csr = AD_IENABLE | AD_START;
58 	DELAY(40000);
59 	adaddr->ad_csr = 0;
60 	return (sizeof (struct addevice));
61 }
62 
63 /*ARGSUSED*/
64 adattach(ui)
65 	struct uba_device *ui;
66 {
67 
68 }
69 
70 adopen(dev)
71 	dev_t dev;
72 {
73 	register struct ad *adp;
74 	register struct uba_device *ui;
75 
76 	if (ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open ||
77 	    (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0)
78 		return (ENXIO);
79 	adp->ad_open = 1;
80 	adp->ad_icnt = 0;
81 	adp->ad_state = 0;
82 	adp->ad_uid = u.u_uid;
83 	return (0);
84 }
85 
86 adclose(dev)
87 	dev_t dev;
88 {
89 
90 	ad[ADUNIT(dev)].ad_open = 0;
91 	ad[ADUNIT(dev)].ad_state = 0;
92 }
93 
94 /*ARGSUSED*/
95 adioctl(dev, cmd, addr, flag)
96 	dev_t dev;
97 	register caddr_t addr;
98 {
99 	register struct addevice *adaddr =
100 	    (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr;
101 	register struct uba_device *ui = addinfo[ADUNIT(dev)];
102 	register struct ad *adp;
103 	register int i;
104 	short int chan;
105 
106 	switch (cmd) {
107 
108 	case ADIOSCHAN:
109 		adp = &ad[ADUNIT(dev)];
110 		adp->ad_chan = (*(int *)addr)<<8;
111 		break;
112 
113 	case ADIOGETW:
114 		adp = &ad[ADUNIT(dev)];
115 		spl6();
116 		adaddr->ad_csr = adp->ad_chan;
117 		i = 1000;
118 		while (i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) {
119 			adp->ad_loop++;
120 			adaddr->ad_csr = adp->ad_chan;
121 		}
122 		adp->ad_state |= ADBUSY;
123 		adaddr->ad_csr |= AD_IENABLE|AD_START;
124 		while (adp->ad_state&ADBUSY)
125 			tsleep((caddr_t)adp, ADWAITPRI, SLP_AD_GETW), 0;
126 		spl0();
127 		*(int *)addr = adp->ad_softdata;
128 		break;
129 
130 	default:
131 		return (ENOTTY);	/* Not a legal ioctl cmd. */
132 	}
133 	return (0);
134 }
135 
136 /*ARGSUSED*/
137 adintr(dev)
138 	dev_t dev;
139 {
140 	register struct addevice *adaddr =
141 			(struct addevice *) addinfo[ADUNIT(dev)]->ui_addr;
142 	register struct ad *adp = &ad[ADUNIT(dev)];
143 
144 	adp->ad_icnt++;
145 	adp->ad_softcsr = adaddr->ad_csr;
146 	adp->ad_softdata = adaddr->ad_data;
147 	if(adp->ad_state&ADBUSY) {
148 		adp->ad_state &= ~ADBUSY;
149 		wakeup((caddr_t)adp);
150 	}
151 }
152 
153 adreset(uban)
154 	int uban;
155 {
156 	register int i;
157 	register struct uba_device *ui;
158 	register struct ad *adp = ad;
159 	register struct addevice *adaddr;
160 
161 	for(i = 0; i < NAD; i++, adp++) {
162 		if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 ||
163 				ui->ui_ubanum != uban || adp->ad_open == 0)
164 			continue;
165 		printf(" ad%d", i);
166 		if(adp->ad_state&ADBUSY == 0)
167 			continue;
168 		adaddr = (struct addevice *) ui->ui_addr;
169 		adaddr->ad_csr = 0;
170 		adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START;
171 	}
172 }
173 #endif
174