1 /* ad.c 4.3 82/08/01 */ 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 return (sizeof (struct addevice)); 51 } 52 53 adattach(ui) 54 struct uba_device *ui; 55 { 56 } 57 58 adopen(dev) 59 dev_t dev; 60 { 61 register struct ad *adp; 62 register struct uba_device *ui; 63 64 if(ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || 65 (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) { 66 u.u_error = ENXIO; 67 return; 68 } 69 adp->ad_open = 1; 70 adp->ad_icnt = 0; 71 adp->ad_state = 0; 72 adp->ad_uid = u.u_uid; 73 } 74 75 adclose(dev) 76 dev_t dev; 77 { 78 79 ad[ADUNIT(dev)].ad_open = 0; 80 ad[ADUNIT(dev)].ad_state = 0; 81 } 82 83 /*ARGSUSED*/ 84 adioctl(dev, cmd, addr, flag) 85 dev_t dev; 86 register caddr_t addr; 87 { 88 register struct addevice *adaddr = 89 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 90 register struct uba_device *ui = addinfo[ADUNIT(dev)]; 91 register struct ad *adp; 92 register int i; 93 short int chan; 94 95 switch (cmd) { 96 97 case ADIOSCHAN: 98 adp = &ad[ADUNIT(dev)]; 99 adp->ad_chan = (*(int *)data)<<8; 100 break; 101 102 case ADIOGETW: 103 adp = &ad[ADUNIT(dev)]; 104 spl6(); 105 adaddr->ad_csr = adp->ad_chan; 106 i = 1000; 107 while(i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { 108 adp->ad_loop++; 109 adaddr->ad_csr = adp->ad_chan; 110 } 111 adp->ad_state |= ADBUSY; 112 adaddr->ad_csr |= AD_IENABLE|AD_START; 113 while(adp->ad_state&ADBUSY) 114 sleep((caddr_t)adp, ADWAITPRI); 115 spl0(); 116 *(int *)data = adp->ad_softdata; 117 break; 118 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