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