1 /* ad.c 4.1 82/06/26 */ 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 #include "../h/ubareg.h" 16 #include "../h/ubavar.h" 17 #include "../h/adreg.h" 18 19 #define ADBUSY 01 20 #define ADWAITPRI (PZERO+1) 21 22 int adprobe(), adattach(); 23 struct uba_device *addinfo[NAD]; 24 u_short adstd[] = { 0770400, 0000000, 0 }; 25 struct uba_driver addriver = 26 { adprobe, 0, adattach, 0, adstd, "ad", addinfo, 0, 0 }; 27 28 struct ad { 29 char ad_open; 30 short int ad_uid; 31 short int ad_state; 32 short int ad_softcsr; 33 short int ad_softdata; 34 short int ad_chan; 35 int ad_icnt; 36 int ad_loop; 37 } ad[NAD]; 38 39 #define ADUNIT(dev) (minor(dev)) 40 41 adprobe(reg) 42 caddr_t reg; 43 { 44 register int br, cvec; 45 register struct addevice *adaddr = (struct addevice *) reg; 46 47 adaddr->ad_csr = AD_IENABLE | AD_START; 48 DELAY(40000); 49 adaddr->ad_csr = 0; 50 } 51 52 adattach(ui) 53 struct uba_device *ui; 54 { 55 } 56 57 adopen(dev) 58 dev_t dev; 59 { 60 register struct ad *adp; 61 register struct uba_device *ui; 62 63 if(ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || 64 (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) { 65 u.u_error = ENXIO; 66 return; 67 } 68 adp->ad_open = 1; 69 adp->ad_icnt = 0; 70 adp->ad_state = 0; 71 adp->ad_uid = u.u_uid; 72 } 73 74 adclose(dev) 75 dev_t dev; 76 { 77 78 ad[ADUNIT(dev)].ad_open = 0; 79 ad[ADUNIT(dev)].ad_state = 0; 80 } 81 82 /*ARGSUSED*/ 83 adioctl(dev, cmd, addr, flag) 84 dev_t dev; 85 register caddr_t addr; 86 { 87 register struct addevice *adaddr = 88 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 89 register struct uba_device *ui = addinfo[ADUNIT(dev)]; 90 register struct ad *adp; 91 register int i; 92 short int chan; 93 94 switch (cmd) { 95 case AD_CHAN: 96 adp = &ad[ADUNIT(dev)]; 97 chan = fuword(addr); 98 if(chan == -1) 99 u.u_error = EFAULT; 100 else 101 adp->ad_chan = chan<<8; 102 break; 103 case AD_READ: 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 (void) suword(addr, adp->ad_softdata); 118 break; 119 default: 120 u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ 121 } 122 } 123 124 /*ARGSUSED*/ 125 adintr(dev) 126 dev_t dev; 127 { 128 register struct addevice *adaddr = 129 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 130 register struct ad *adp = &ad[ADUNIT(dev)]; 131 132 adp->ad_icnt++; 133 adp->ad_softcsr = adaddr->ad_csr; 134 adp->ad_softdata = adaddr->ad_data; 135 if(adp->ad_state&ADBUSY) { 136 adp->ad_state &= ~ADBUSY; 137 wakeup((caddr_t)adp); 138 } 139 } 140 141 adreset(uban) 142 int uban; 143 { 144 register int i; 145 register struct uba_device *ui; 146 register struct ad *adp = ad; 147 register struct addevice *adaddr; 148 149 for(i = 0; i < NAD; i++, adp++) { 150 if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 || 151 ui->ui_ubanum != uban || adp->ad_open == 0) 152 continue; 153 printf(" ad%d", i); 154 if(adp->ad_state&ADBUSY == 0) 155 continue; 156 adaddr = (struct addevice *) ui->ui_addr; 157 adaddr->ad_csr = 0; 158 adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START; 159 } 160 } 161 #endif 162