Commit | Line | Data |
---|---|---|
896962b1 | 1 | /* ad.c 4.5 82/10/10 */ |
1416af58 SL |
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" | |
896962b1 BJ |
15 | |
16 | #include "../vaxuba/ubareg.h" | |
17 | #include "../vaxuba/ubavar.h" | |
18 | #include "../vaxuba/adreg.h" | |
1416af58 SL |
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; | |
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; | |
9c0adba0 | 51 | return (sizeof (struct addevice)); |
1416af58 SL |
52 | } |
53 | ||
54 | adattach(ui) | |
55 | struct uba_device *ui; | |
56 | { | |
57 | } | |
58 | ||
59 | adopen(dev) | |
60 | dev_t dev; | |
61 | { | |
62 | register struct ad *adp; | |
63 | register struct uba_device *ui; | |
64 | ||
65 | if(ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || | |
66 | (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) { | |
67 | u.u_error = ENXIO; | |
68 | return; | |
69 | } | |
70 | adp->ad_open = 1; | |
71 | adp->ad_icnt = 0; | |
72 | adp->ad_state = 0; | |
73 | adp->ad_uid = u.u_uid; | |
74 | } | |
75 | ||
76 | adclose(dev) | |
77 | dev_t dev; | |
78 | { | |
79 | ||
80 | ad[ADUNIT(dev)].ad_open = 0; | |
81 | ad[ADUNIT(dev)].ad_state = 0; | |
82 | } | |
83 | ||
84 | /*ARGSUSED*/ | |
85 | adioctl(dev, cmd, addr, flag) | |
86 | dev_t dev; | |
87 | register caddr_t addr; | |
88 | { | |
89 | register struct addevice *adaddr = | |
90 | (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; | |
91 | register struct uba_device *ui = addinfo[ADUNIT(dev)]; | |
92 | register struct ad *adp; | |
93 | register int i; | |
94 | short int chan; | |
95 | ||
96 | switch (cmd) { | |
942f05a9 SL |
97 | |
98 | case ADIOSCHAN: | |
1416af58 | 99 | adp = &ad[ADUNIT(dev)]; |
942f05a9 | 100 | adp->ad_chan = (*(int *)data)<<8; |
1416af58 | 101 | break; |
942f05a9 SL |
102 | |
103 | case ADIOGETW: | |
1416af58 SL |
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(); | |
942f05a9 | 117 | *(int *)data = adp->ad_softdata; |
1416af58 | 118 | break; |
942f05a9 | 119 | |
1416af58 SL |
120 | default: |
121 | u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ | |
122 | } | |
123 | } | |
124 | ||
125 | /*ARGSUSED*/ | |
126 | adintr(dev) | |
127 | dev_t dev; | |
128 | { | |
129 | register struct addevice *adaddr = | |
130 | (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; | |
131 | register struct ad *adp = &ad[ADUNIT(dev)]; | |
132 | ||
133 | adp->ad_icnt++; | |
134 | adp->ad_softcsr = adaddr->ad_csr; | |
135 | adp->ad_softdata = adaddr->ad_data; | |
136 | if(adp->ad_state&ADBUSY) { | |
137 | adp->ad_state &= ~ADBUSY; | |
138 | wakeup((caddr_t)adp); | |
139 | } | |
140 | } | |
141 | ||
142 | adreset(uban) | |
143 | int uban; | |
144 | { | |
145 | register int i; | |
146 | register struct uba_device *ui; | |
147 | register struct ad *adp = ad; | |
148 | register struct addevice *adaddr; | |
149 | ||
150 | for(i = 0; i < NAD; i++, adp++) { | |
151 | if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 || | |
152 | ui->ui_ubanum != uban || adp->ad_open == 0) | |
153 | continue; | |
154 | printf(" ad%d", i); | |
155 | if(adp->ad_state&ADBUSY == 0) | |
156 | continue; | |
157 | adaddr = (struct addevice *) ui->ui_addr; | |
158 | adaddr->ad_csr = 0; | |
159 | adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START; | |
160 | } | |
161 | } | |
162 | #endif |