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