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