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