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