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