1*7417Skre /* ad.c 4.2 82/07/15 */ 27295Ssam 37295Ssam #include "ad.h" 47295Ssam #if NAD > 0 57295Ssam /* 67295Ssam * Data translation AD converter interface -- Bill Reeves 77295Ssam */ 87295Ssam #include "../h/param.h" 97295Ssam #include "../h/dir.h" 107295Ssam #include "../h/user.h" 117295Ssam #include "../h/buf.h" 127295Ssam #include "../h/systm.h" 137295Ssam #include "../h/map.h" 147295Ssam #include "../h/pte.h" 157295Ssam #include "../h/ubareg.h" 167295Ssam #include "../h/ubavar.h" 177295Ssam #include "../h/adreg.h" 187295Ssam 197295Ssam #define ADBUSY 01 207295Ssam #define ADWAITPRI (PZERO+1) 217295Ssam 227295Ssam int adprobe(), adattach(); 237295Ssam struct uba_device *addinfo[NAD]; 247295Ssam u_short adstd[] = { 0770400, 0000000, 0 }; 257295Ssam struct uba_driver addriver = 267295Ssam { adprobe, 0, adattach, 0, adstd, "ad", addinfo, 0, 0 }; 277295Ssam 287295Ssam struct ad { 297295Ssam char ad_open; 307295Ssam short int ad_uid; 317295Ssam short int ad_state; 327295Ssam short int ad_softcsr; 337295Ssam short int ad_softdata; 347295Ssam short int ad_chan; 357295Ssam int ad_icnt; 367295Ssam int ad_loop; 377295Ssam } ad[NAD]; 387295Ssam 397295Ssam #define ADUNIT(dev) (minor(dev)) 407295Ssam 417295Ssam adprobe(reg) 427295Ssam caddr_t reg; 437295Ssam { 447295Ssam register int br, cvec; 457295Ssam register struct addevice *adaddr = (struct addevice *) reg; 467295Ssam 477295Ssam adaddr->ad_csr = AD_IENABLE | AD_START; 487295Ssam DELAY(40000); 497295Ssam adaddr->ad_csr = 0; 50*7417Skre return (sizeof (struct addevice)); 517295Ssam } 527295Ssam 537295Ssam adattach(ui) 547295Ssam struct uba_device *ui; 557295Ssam { 567295Ssam } 577295Ssam 587295Ssam adopen(dev) 597295Ssam dev_t dev; 607295Ssam { 617295Ssam register struct ad *adp; 627295Ssam register struct uba_device *ui; 637295Ssam 647295Ssam if(ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || 657295Ssam (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) { 667295Ssam u.u_error = ENXIO; 677295Ssam return; 687295Ssam } 697295Ssam adp->ad_open = 1; 707295Ssam adp->ad_icnt = 0; 717295Ssam adp->ad_state = 0; 727295Ssam adp->ad_uid = u.u_uid; 737295Ssam } 747295Ssam 757295Ssam adclose(dev) 767295Ssam dev_t dev; 777295Ssam { 787295Ssam 797295Ssam ad[ADUNIT(dev)].ad_open = 0; 807295Ssam ad[ADUNIT(dev)].ad_state = 0; 817295Ssam } 827295Ssam 837295Ssam /*ARGSUSED*/ 847295Ssam adioctl(dev, cmd, addr, flag) 857295Ssam dev_t dev; 867295Ssam register caddr_t addr; 877295Ssam { 887295Ssam register struct addevice *adaddr = 897295Ssam (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 907295Ssam register struct uba_device *ui = addinfo[ADUNIT(dev)]; 917295Ssam register struct ad *adp; 927295Ssam register int i; 937295Ssam short int chan; 947295Ssam 957295Ssam switch (cmd) { 967295Ssam case AD_CHAN: 977295Ssam adp = &ad[ADUNIT(dev)]; 987295Ssam chan = fuword(addr); 997295Ssam if(chan == -1) 1007295Ssam u.u_error = EFAULT; 1017295Ssam else 1027295Ssam adp->ad_chan = chan<<8; 1037295Ssam break; 1047295Ssam case AD_READ: 1057295Ssam adp = &ad[ADUNIT(dev)]; 1067295Ssam spl6(); 1077295Ssam adaddr->ad_csr = adp->ad_chan; 1087295Ssam i = 1000; 1097295Ssam while(i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { 1107295Ssam adp->ad_loop++; 1117295Ssam adaddr->ad_csr = adp->ad_chan; 1127295Ssam } 1137295Ssam adp->ad_state |= ADBUSY; 1147295Ssam adaddr->ad_csr |= AD_IENABLE|AD_START; 1157295Ssam while(adp->ad_state&ADBUSY) 1167295Ssam sleep((caddr_t)adp, ADWAITPRI); 1177295Ssam spl0(); 1187295Ssam (void) suword(addr, adp->ad_softdata); 1197295Ssam break; 1207295Ssam default: 1217295Ssam u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ 1227295Ssam } 1237295Ssam } 1247295Ssam 1257295Ssam /*ARGSUSED*/ 1267295Ssam adintr(dev) 1277295Ssam dev_t dev; 1287295Ssam { 1297295Ssam register struct addevice *adaddr = 1307295Ssam (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 1317295Ssam register struct ad *adp = &ad[ADUNIT(dev)]; 1327295Ssam 1337295Ssam adp->ad_icnt++; 1347295Ssam adp->ad_softcsr = adaddr->ad_csr; 1357295Ssam adp->ad_softdata = adaddr->ad_data; 1367295Ssam if(adp->ad_state&ADBUSY) { 1377295Ssam adp->ad_state &= ~ADBUSY; 1387295Ssam wakeup((caddr_t)adp); 1397295Ssam } 1407295Ssam } 1417295Ssam 1427295Ssam adreset(uban) 1437295Ssam int uban; 1447295Ssam { 1457295Ssam register int i; 1467295Ssam register struct uba_device *ui; 1477295Ssam register struct ad *adp = ad; 1487295Ssam register struct addevice *adaddr; 1497295Ssam 1507295Ssam for(i = 0; i < NAD; i++, adp++) { 1517295Ssam if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 || 1527295Ssam ui->ui_ubanum != uban || adp->ad_open == 0) 1537295Ssam continue; 1547295Ssam printf(" ad%d", i); 1557295Ssam if(adp->ad_state&ADBUSY == 0) 1567295Ssam continue; 1577295Ssam adaddr = (struct addevice *) ui->ui_addr; 1587295Ssam adaddr->ad_csr = 0; 1597295Ssam adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START; 1607295Ssam } 1617295Ssam } 1627295Ssam #endif 163