1 /* 2 * Copyright (c) 1982 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 6.3 (Berkeley) 06/08/85 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 "dir.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 } 91 92 /*ARGSUSED*/ 93 adioctl(dev, cmd, addr, flag) 94 dev_t dev; 95 register caddr_t addr; 96 { 97 register struct addevice *adaddr = 98 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 99 register struct uba_device *ui = addinfo[ADUNIT(dev)]; 100 register struct ad *adp; 101 register int i; 102 short int chan; 103 104 switch (cmd) { 105 106 case ADIOSCHAN: 107 adp = &ad[ADUNIT(dev)]; 108 adp->ad_chan = (*(int *)data)<<8; 109 break; 110 111 case ADIOGETW: 112 adp = &ad[ADUNIT(dev)]; 113 spl6(); 114 adaddr->ad_csr = adp->ad_chan; 115 i = 1000; 116 while (i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { 117 adp->ad_loop++; 118 adaddr->ad_csr = adp->ad_chan; 119 } 120 adp->ad_state |= ADBUSY; 121 adaddr->ad_csr |= AD_IENABLE|AD_START; 122 while (adp->ad_state&ADBUSY) 123 sleep((caddr_t)adp, ADWAITPRI); 124 spl0(); 125 *(int *)data = adp->ad_softdata; 126 break; 127 128 default: 129 return (ENOTTY); /* Not a legal ioctl cmd. */ 130 } 131 return (0); 132 } 133 134 /*ARGSUSED*/ 135 adintr(dev) 136 dev_t dev; 137 { 138 register struct addevice *adaddr = 139 (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 140 register struct ad *adp = &ad[ADUNIT(dev)]; 141 142 adp->ad_icnt++; 143 adp->ad_softcsr = adaddr->ad_csr; 144 adp->ad_softdata = adaddr->ad_data; 145 if(adp->ad_state&ADBUSY) { 146 adp->ad_state &= ~ADBUSY; 147 wakeup((caddr_t)adp); 148 } 149 } 150 151 adreset(uban) 152 int uban; 153 { 154 register int i; 155 register struct uba_device *ui; 156 register struct ad *adp = ad; 157 register struct addevice *adaddr; 158 159 for(i = 0; i < NAD; i++, adp++) { 160 if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 || 161 ui->ui_ubanum != uban || adp->ad_open == 0) 162 continue; 163 printf(" ad%d", i); 164 if(adp->ad_state&ADBUSY == 0) 165 continue; 166 adaddr = (struct addevice *) ui->ui_addr; 167 adaddr->ad_csr = 0; 168 adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START; 169 } 170 } 171 #endif 172