1*8472Sroot /* ad.c 4.5 82/10/10 */ 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 16*8472Sroot #include "../vaxuba/ubareg.h" 17*8472Sroot #include "../vaxuba/ubavar.h" 18*8472Sroot #include "../vaxuba/adreg.h" 19*8472Sroot 207295Ssam #define ADBUSY 01 217295Ssam #define ADWAITPRI (PZERO+1) 227295Ssam 237295Ssam int adprobe(), adattach(); 247295Ssam struct uba_device *addinfo[NAD]; 257295Ssam u_short adstd[] = { 0770400, 0000000, 0 }; 267295Ssam struct uba_driver addriver = 277295Ssam { adprobe, 0, adattach, 0, adstd, "ad", addinfo, 0, 0 }; 287295Ssam 297295Ssam struct ad { 307295Ssam char ad_open; 317295Ssam short int ad_uid; 327295Ssam short int ad_state; 337295Ssam short int ad_softcsr; 347295Ssam short int ad_softdata; 357295Ssam short int ad_chan; 367295Ssam int ad_icnt; 377295Ssam int ad_loop; 387295Ssam } ad[NAD]; 397295Ssam 407295Ssam #define ADUNIT(dev) (minor(dev)) 417295Ssam 427295Ssam adprobe(reg) 437295Ssam caddr_t reg; 447295Ssam { 457295Ssam register int br, cvec; 467295Ssam register struct addevice *adaddr = (struct addevice *) reg; 477295Ssam 487295Ssam adaddr->ad_csr = AD_IENABLE | AD_START; 497295Ssam DELAY(40000); 507295Ssam adaddr->ad_csr = 0; 517417Skre return (sizeof (struct addevice)); 527295Ssam } 537295Ssam 547295Ssam adattach(ui) 557295Ssam struct uba_device *ui; 567295Ssam { 577295Ssam } 587295Ssam 597295Ssam adopen(dev) 607295Ssam dev_t dev; 617295Ssam { 627295Ssam register struct ad *adp; 637295Ssam register struct uba_device *ui; 647295Ssam 657295Ssam if(ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || 667295Ssam (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) { 677295Ssam u.u_error = ENXIO; 687295Ssam return; 697295Ssam } 707295Ssam adp->ad_open = 1; 717295Ssam adp->ad_icnt = 0; 727295Ssam adp->ad_state = 0; 737295Ssam adp->ad_uid = u.u_uid; 747295Ssam } 757295Ssam 767295Ssam adclose(dev) 777295Ssam dev_t dev; 787295Ssam { 797295Ssam 807295Ssam ad[ADUNIT(dev)].ad_open = 0; 817295Ssam ad[ADUNIT(dev)].ad_state = 0; 827295Ssam } 837295Ssam 847295Ssam /*ARGSUSED*/ 857295Ssam adioctl(dev, cmd, addr, flag) 867295Ssam dev_t dev; 877295Ssam register caddr_t addr; 887295Ssam { 897295Ssam register struct addevice *adaddr = 907295Ssam (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 917295Ssam register struct uba_device *ui = addinfo[ADUNIT(dev)]; 927295Ssam register struct ad *adp; 937295Ssam register int i; 947295Ssam short int chan; 957295Ssam 967295Ssam switch (cmd) { 977629Ssam 987629Ssam case ADIOSCHAN: 997295Ssam adp = &ad[ADUNIT(dev)]; 1007629Ssam adp->ad_chan = (*(int *)data)<<8; 1017295Ssam break; 1027629Ssam 1037629Ssam case ADIOGETW: 1047295Ssam adp = &ad[ADUNIT(dev)]; 1057295Ssam spl6(); 1067295Ssam adaddr->ad_csr = adp->ad_chan; 1077295Ssam i = 1000; 1087295Ssam while(i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { 1097295Ssam adp->ad_loop++; 1107295Ssam adaddr->ad_csr = adp->ad_chan; 1117295Ssam } 1127295Ssam adp->ad_state |= ADBUSY; 1137295Ssam adaddr->ad_csr |= AD_IENABLE|AD_START; 1147295Ssam while(adp->ad_state&ADBUSY) 1157295Ssam sleep((caddr_t)adp, ADWAITPRI); 1167295Ssam spl0(); 1177629Ssam *(int *)data = adp->ad_softdata; 1187295Ssam break; 1197629Ssam 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