Commit | Line | Data |
---|---|---|
ff360633 | 1 | /* ad.c 6.2 84/08/29 */ |
1416af58 SL |
2 | |
3 | #include "ad.h" | |
4 | #if NAD > 0 | |
5 | /* | |
6 | * Data translation AD converter interface -- Bill Reeves | |
7 | */ | |
961945a8 SL |
8 | #include "../machine/pte.h" |
9 | ||
ff360633 JB |
10 | #include "param.h" |
11 | #include "dir.h" | |
12 | #include "user.h" | |
13 | #include "buf.h" | |
14 | #include "systm.h" | |
15 | #include "map.h" | |
896962b1 | 16 | |
ff360633 JB |
17 | #include "ubareg.h" |
18 | #include "ubavar.h" | |
19 | #include "adreg.h" | |
1416af58 SL |
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 | { | |
7da157da | 46 | register int br, cvec; /* value-result */ |
1416af58 SL |
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; | |
9c0adba0 | 52 | return (sizeof (struct addevice)); |
1416af58 SL |
53 | } |
54 | ||
7da157da | 55 | /*ARGSUSED*/ |
1416af58 SL |
56 | adattach(ui) |
57 | struct uba_device *ui; | |
58 | { | |
7da157da | 59 | |
1416af58 SL |
60 | } |
61 | ||
62 | adopen(dev) | |
63 | dev_t dev; | |
64 | { | |
65 | register struct ad *adp; | |
66 | register struct uba_device *ui; | |
67 | ||
7da157da BJ |
68 | if (ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || |
69 | (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) | |
70 | return (ENXIO); | |
1416af58 SL |
71 | adp->ad_open = 1; |
72 | adp->ad_icnt = 0; | |
73 | adp->ad_state = 0; | |
74 | adp->ad_uid = u.u_uid; | |
7da157da | 75 | return (0); |
1416af58 SL |
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 = | |
7da157da | 92 | (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; |
1416af58 SL |
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) { | |
942f05a9 SL |
99 | |
100 | case ADIOSCHAN: | |
1416af58 | 101 | adp = &ad[ADUNIT(dev)]; |
942f05a9 | 102 | adp->ad_chan = (*(int *)data)<<8; |
1416af58 | 103 | break; |
942f05a9 SL |
104 | |
105 | case ADIOGETW: | |
1416af58 SL |
106 | adp = &ad[ADUNIT(dev)]; |
107 | spl6(); | |
108 | adaddr->ad_csr = adp->ad_chan; | |
109 | i = 1000; | |
7da157da | 110 | while (i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { |
1416af58 SL |
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; | |
7da157da | 116 | while (adp->ad_state&ADBUSY) |
1416af58 SL |
117 | sleep((caddr_t)adp, ADWAITPRI); |
118 | spl0(); | |
942f05a9 | 119 | *(int *)data = adp->ad_softdata; |
1416af58 | 120 | break; |
942f05a9 | 121 | |
1416af58 | 122 | default: |
7da157da | 123 | return (ENOTTY); /* Not a legal ioctl cmd. */ |
1416af58 | 124 | } |
7da157da | 125 | return (0); |
1416af58 SL |
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 |