1 /* ad.c 6.2 84/08/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 "param.h" 11 #include "dir.h" 12 #include "user.h" 13 #include "buf.h" 14 #include "systm.h" 15 #include "map.h" 16 17 #include "ubareg.h" 18 #include "ubavar.h" 19 #include "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 166