1 /* ad.c 4.6 82/10/17 */ 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; /* value-result */ 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 /*ARGSUSED*/ 55 adattach(ui) 56 struct uba_device *ui; 57 { 58 59 } 60 61 adopen(dev) 62 dev_t dev; 63 { 64 register struct ad *adp; 65 register struct uba_device *ui; 66 67 if (ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || 68 (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) 69 return (ENXIO); 70 adp->ad_open = 1; 71 adp->ad_icnt = 0; 72 adp->ad_state = 0; 73 adp->ad_uid = u.u_uid; 74 return (0); 75 } 76 77 adclose(dev) 78 dev_t dev; 79 { 80 81 ad[ADUNIT(dev)].ad_open = 0; 82 ad[ADUNIT(dev)].ad_state = 0; 83 } 84 85 /*ARGSUSED*/ 86 adioctl(dev, cmd, addr, flag) 87 dev_t dev; 88 register caddr_t addr; 89 { 90 register struct addevice *adaddr = 91 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 92 register struct uba_device *ui = addinfo[ADUNIT(dev)]; 93 register struct ad *adp; 94 register int i; 95 short int chan; 96 97 switch (cmd) { 98 99 case ADIOSCHAN: 100 adp = &ad[ADUNIT(dev)]; 101 adp->ad_chan = (*(int *)data)<<8; 102 break; 103 104 case ADIOGETW: 105 adp = &ad[ADUNIT(dev)]; 106 spl6(); 107 adaddr->ad_csr = adp->ad_chan; 108 i = 1000; 109 while (i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { 110 adp->ad_loop++; 111 adaddr->ad_csr = adp->ad_chan; 112 } 113 adp->ad_state |= ADBUSY; 114 adaddr->ad_csr |= AD_IENABLE|AD_START; 115 while (adp->ad_state&ADBUSY) 116 sleep((caddr_t)adp, ADWAITPRI); 117 spl0(); 118 *(int *)data = adp->ad_softdata; 119 break; 120 121 default: 122 return (ENOTTY); /* Not a legal ioctl cmd. */ 123 } 124 return (0); 125 } 126 127 /*ARGSUSED*/ 128 adintr(dev) 129 dev_t dev; 130 { 131 register struct addevice *adaddr = 132 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 133 register struct ad *adp = &ad[ADUNIT(dev)]; 134 135 adp->ad_icnt++; 136 adp->ad_softcsr = adaddr->ad_csr; 137 adp->ad_softdata = adaddr->ad_data; 138 if(adp->ad_state&ADBUSY) { 139 adp->ad_state &= ~ADBUSY; 140 wakeup((caddr_t)adp); 141 } 142 } 143 144 adreset(uban) 145 int uban; 146 { 147 register int i; 148 register struct uba_device *ui; 149 register struct ad *adp = ad; 150 register struct addevice *adaddr; 151 152 for(i = 0; i < NAD; i++, adp++) { 153 if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 || 154 ui->ui_ubanum != uban || adp->ad_open == 0) 155 continue; 156 printf(" ad%d", i); 157 if(adp->ad_state&ADBUSY == 0) 158 continue; 159 adaddr = (struct addevice *) ui->ui_addr; 160 adaddr->ad_csr = 0; 161 adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START; 162 } 163 } 164 #endif 165