1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)ad.c 7.7 (Berkeley) 04/03/90 7 */ 8 9 #include "ad.h" 10 #if NAD > 0 11 /* 12 * Data translation AD converter interface -- Bill Reeves 13 */ 14 #include "machine/pte.h" 15 16 #include "param.h" 17 #include "ioctl.h" 18 #include "user.h" 19 #include "buf.h" 20 #include "systm.h" 21 #include "map.h" 22 23 #include "ubareg.h" 24 #include "ubavar.h" 25 #include "adreg.h" 26 27 #define ADBUSY 01 28 #define ADWAITPRI (PZERO+1) 29 30 int adprobe(), adattach(); 31 struct uba_device *addinfo[NAD]; 32 u_short adstd[] = { 0770400, 0000000, 0 }; 33 struct uba_driver addriver = 34 { adprobe, 0, adattach, 0, adstd, "ad", addinfo, 0, 0 }; 35 36 struct ad { 37 char ad_open; 38 short int ad_uid; 39 short int ad_state; 40 short int ad_softcsr; 41 short int ad_softdata; 42 short int ad_chan; 43 int ad_icnt; 44 int ad_loop; 45 } ad[NAD]; 46 47 #define ADUNIT(dev) (minor(dev)) 48 49 adprobe(reg) 50 caddr_t reg; 51 { 52 register int br, cvec; /* value-result */ 53 register struct addevice *adaddr = (struct addevice *) reg; 54 55 adaddr->ad_csr = AD_IENABLE | AD_START; 56 DELAY(40000); 57 adaddr->ad_csr = 0; 58 return (sizeof (struct addevice)); 59 } 60 61 /*ARGSUSED*/ 62 adattach(ui) 63 struct uba_device *ui; 64 { 65 66 } 67 68 adopen(dev) 69 dev_t dev; 70 { 71 register struct ad *adp; 72 register struct uba_device *ui; 73 74 if (ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || 75 (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) 76 return (ENXIO); 77 adp->ad_open = 1; 78 adp->ad_icnt = 0; 79 adp->ad_state = 0; 80 adp->ad_uid = u.u_uid; 81 return (0); 82 } 83 84 adclose(dev) 85 dev_t dev; 86 { 87 88 ad[ADUNIT(dev)].ad_open = 0; 89 ad[ADUNIT(dev)].ad_state = 0; 90 return (0); 91 } 92 93 /*ARGSUSED*/ 94 adioctl(dev, cmd, addr, flag) 95 dev_t dev; 96 register caddr_t addr; 97 { 98 register struct addevice *adaddr = 99 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 100 register struct uba_device *ui = addinfo[ADUNIT(dev)]; 101 register struct ad *adp; 102 register int i; 103 short int chan; 104 105 switch (cmd) { 106 107 case ADIOSCHAN: 108 adp = &ad[ADUNIT(dev)]; 109 adp->ad_chan = (*(int *)addr)<<8; 110 break; 111 112 case ADIOGETW: 113 adp = &ad[ADUNIT(dev)]; 114 spl6(); 115 adaddr->ad_csr = adp->ad_chan; 116 i = 1000; 117 while (i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { 118 adp->ad_loop++; 119 adaddr->ad_csr = adp->ad_chan; 120 } 121 adp->ad_state |= ADBUSY; 122 adaddr->ad_csr |= AD_IENABLE|AD_START; 123 i = 0; 124 while (adp->ad_state&ADBUSY) 125 if (i = tsleep((caddr_t)adp, ADWAITPRI | PCATCH, 126 devio, 0) 127 break; 128 spl0(); 129 if (i) 130 return (i); 131 *(int *)addr = adp->ad_softdata; 132 break; 133 134 default: 135 return (ENOTTY); /* Not a legal ioctl cmd. */ 136 } 137 return (0); 138 } 139 140 /*ARGSUSED*/ 141 adintr(dev) 142 dev_t dev; 143 { 144 register struct addevice *adaddr = 145 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 146 register struct ad *adp = &ad[ADUNIT(dev)]; 147 148 adp->ad_icnt++; 149 adp->ad_softcsr = adaddr->ad_csr; 150 adp->ad_softdata = adaddr->ad_data; 151 if(adp->ad_state&ADBUSY) { 152 adp->ad_state &= ~ADBUSY; 153 wakeup((caddr_t)adp); 154 } 155 } 156 157 adreset(uban) 158 int uban; 159 { 160 register int i; 161 register struct uba_device *ui; 162 register struct ad *adp = ad; 163 register struct addevice *adaddr; 164 165 for(i = 0; i < NAD; i++, adp++) { 166 if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 || 167 ui->ui_ubanum != uban || adp->ad_open == 0) 168 continue; 169 printf(" ad%d", i); 170 if(adp->ad_state&ADBUSY == 0) 171 continue; 172 adaddr = (struct addevice *) ui->ui_addr; 173 adaddr->ad_csr = 0; 174 adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START; 175 } 176 } 177 #endif 178