1 /* ad.c 4.5 82/10/10 */ 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; 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 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) { 97 98 case ADIOSCHAN: 99 adp = &ad[ADUNIT(dev)]; 100 adp->ad_chan = (*(int *)data)<<8; 101 break; 102 103 case ADIOGETW: 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(); 117 *(int *)data = adp->ad_softdata; 118 break; 119 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 163