1*7629Ssam /* ad.c 4.3 82/08/01 */ 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; 507417Skre 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) { 96*7629Ssam 97*7629Ssam case ADIOSCHAN: 987295Ssam adp = &ad[ADUNIT(dev)]; 99*7629Ssam adp->ad_chan = (*(int *)data)<<8; 1007295Ssam break; 101*7629Ssam 102*7629Ssam case ADIOGETW: 1037295Ssam adp = &ad[ADUNIT(dev)]; 1047295Ssam spl6(); 1057295Ssam adaddr->ad_csr = adp->ad_chan; 1067295Ssam i = 1000; 1077295Ssam while(i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { 1087295Ssam adp->ad_loop++; 1097295Ssam adaddr->ad_csr = adp->ad_chan; 1107295Ssam } 1117295Ssam adp->ad_state |= ADBUSY; 1127295Ssam adaddr->ad_csr |= AD_IENABLE|AD_START; 1137295Ssam while(adp->ad_state&ADBUSY) 1147295Ssam sleep((caddr_t)adp, ADWAITPRI); 1157295Ssam spl0(); 116*7629Ssam *(int *)data = adp->ad_softdata; 1177295Ssam break; 118*7629Ssam 1197295Ssam default: 1207295Ssam u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ 1217295Ssam } 1227295Ssam } 1237295Ssam 1247295Ssam /*ARGSUSED*/ 1257295Ssam adintr(dev) 1267295Ssam dev_t dev; 1277295Ssam { 1287295Ssam register struct addevice *adaddr = 1297295Ssam (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 1307295Ssam register struct ad *adp = &ad[ADUNIT(dev)]; 1317295Ssam 1327295Ssam adp->ad_icnt++; 1337295Ssam adp->ad_softcsr = adaddr->ad_csr; 1347295Ssam adp->ad_softdata = adaddr->ad_data; 1357295Ssam if(adp->ad_state&ADBUSY) { 1367295Ssam adp->ad_state &= ~ADBUSY; 1377295Ssam wakeup((caddr_t)adp); 1387295Ssam } 1397295Ssam } 1407295Ssam 1417295Ssam adreset(uban) 1427295Ssam int uban; 1437295Ssam { 1447295Ssam register int i; 1457295Ssam register struct uba_device *ui; 1467295Ssam register struct ad *adp = ad; 1477295Ssam register struct addevice *adaddr; 1487295Ssam 1497295Ssam for(i = 0; i < NAD; i++, adp++) { 1507295Ssam if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 || 1517295Ssam ui->ui_ubanum != uban || adp->ad_open == 0) 1527295Ssam continue; 1537295Ssam printf(" ad%d", i); 1547295Ssam if(adp->ad_state&ADBUSY == 0) 1557295Ssam continue; 1567295Ssam adaddr = (struct addevice *) ui->ui_addr; 1577295Ssam adaddr->ad_csr = 0; 1587295Ssam adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START; 1597295Ssam } 1607295Ssam } 1617295Ssam #endif 162