1*23317Smckusick /* 2*23317Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23317Smckusick * All rights reserved. The Berkeley software License Agreement 4*23317Smckusick * specifies the terms and conditions for redistribution. 5*23317Smckusick * 6*23317Smckusick * @(#)ad.c 6.3 (Berkeley) 06/08/85 7*23317Smckusick */ 87295Ssam 97295Ssam #include "ad.h" 107295Ssam #if NAD > 0 117295Ssam /* 127295Ssam * Data translation AD converter interface -- Bill Reeves 137295Ssam */ 149771Ssam #include "../machine/pte.h" 159771Ssam 1617073Sbloom #include "param.h" 1717073Sbloom #include "dir.h" 1817073Sbloom #include "user.h" 1917073Sbloom #include "buf.h" 2017073Sbloom #include "systm.h" 2117073Sbloom #include "map.h" 227295Ssam 2317073Sbloom #include "ubareg.h" 2417073Sbloom #include "ubavar.h" 2517073Sbloom #include "adreg.h" 268472Sroot 277295Ssam #define ADBUSY 01 287295Ssam #define ADWAITPRI (PZERO+1) 297295Ssam 307295Ssam int adprobe(), adattach(); 317295Ssam struct uba_device *addinfo[NAD]; 327295Ssam u_short adstd[] = { 0770400, 0000000, 0 }; 337295Ssam struct uba_driver addriver = 347295Ssam { adprobe, 0, adattach, 0, adstd, "ad", addinfo, 0, 0 }; 357295Ssam 367295Ssam struct ad { 377295Ssam char ad_open; 387295Ssam short int ad_uid; 397295Ssam short int ad_state; 407295Ssam short int ad_softcsr; 417295Ssam short int ad_softdata; 427295Ssam short int ad_chan; 437295Ssam int ad_icnt; 447295Ssam int ad_loop; 457295Ssam } ad[NAD]; 467295Ssam 477295Ssam #define ADUNIT(dev) (minor(dev)) 487295Ssam 497295Ssam adprobe(reg) 507295Ssam caddr_t reg; 517295Ssam { 528566Sroot register int br, cvec; /* value-result */ 537295Ssam register struct addevice *adaddr = (struct addevice *) reg; 547295Ssam 557295Ssam adaddr->ad_csr = AD_IENABLE | AD_START; 567295Ssam DELAY(40000); 577295Ssam adaddr->ad_csr = 0; 587417Skre return (sizeof (struct addevice)); 597295Ssam } 607295Ssam 618566Sroot /*ARGSUSED*/ 627295Ssam adattach(ui) 637295Ssam struct uba_device *ui; 647295Ssam { 658566Sroot 667295Ssam } 677295Ssam 687295Ssam adopen(dev) 697295Ssam dev_t dev; 707295Ssam { 717295Ssam register struct ad *adp; 727295Ssam register struct uba_device *ui; 737295Ssam 748566Sroot if (ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open || 758566Sroot (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0) 768566Sroot return (ENXIO); 777295Ssam adp->ad_open = 1; 787295Ssam adp->ad_icnt = 0; 797295Ssam adp->ad_state = 0; 807295Ssam adp->ad_uid = u.u_uid; 818566Sroot return (0); 827295Ssam } 837295Ssam 847295Ssam adclose(dev) 857295Ssam dev_t dev; 867295Ssam { 877295Ssam 887295Ssam ad[ADUNIT(dev)].ad_open = 0; 897295Ssam ad[ADUNIT(dev)].ad_state = 0; 907295Ssam } 917295Ssam 927295Ssam /*ARGSUSED*/ 937295Ssam adioctl(dev, cmd, addr, flag) 947295Ssam dev_t dev; 957295Ssam register caddr_t addr; 967295Ssam { 977295Ssam register struct addevice *adaddr = 988566Sroot (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 997295Ssam register struct uba_device *ui = addinfo[ADUNIT(dev)]; 1007295Ssam register struct ad *adp; 1017295Ssam register int i; 1027295Ssam short int chan; 1037295Ssam 1047295Ssam switch (cmd) { 1057629Ssam 1067629Ssam case ADIOSCHAN: 1077295Ssam adp = &ad[ADUNIT(dev)]; 1087629Ssam adp->ad_chan = (*(int *)data)<<8; 1097295Ssam break; 1107629Ssam 1117629Ssam case ADIOGETW: 1127295Ssam adp = &ad[ADUNIT(dev)]; 1137295Ssam spl6(); 1147295Ssam adaddr->ad_csr = adp->ad_chan; 1157295Ssam i = 1000; 1168566Sroot while (i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) { 1177295Ssam adp->ad_loop++; 1187295Ssam adaddr->ad_csr = adp->ad_chan; 1197295Ssam } 1207295Ssam adp->ad_state |= ADBUSY; 1217295Ssam adaddr->ad_csr |= AD_IENABLE|AD_START; 1228566Sroot while (adp->ad_state&ADBUSY) 1237295Ssam sleep((caddr_t)adp, ADWAITPRI); 1247295Ssam spl0(); 1257629Ssam *(int *)data = adp->ad_softdata; 1267295Ssam break; 1277629Ssam 1287295Ssam default: 1298566Sroot return (ENOTTY); /* Not a legal ioctl cmd. */ 1307295Ssam } 1318566Sroot return (0); 1327295Ssam } 1337295Ssam 1347295Ssam /*ARGSUSED*/ 1357295Ssam adintr(dev) 1367295Ssam dev_t dev; 1377295Ssam { 1387295Ssam register struct addevice *adaddr = 1397295Ssam (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr; 1407295Ssam register struct ad *adp = &ad[ADUNIT(dev)]; 1417295Ssam 1427295Ssam adp->ad_icnt++; 1437295Ssam adp->ad_softcsr = adaddr->ad_csr; 1447295Ssam adp->ad_softdata = adaddr->ad_data; 1457295Ssam if(adp->ad_state&ADBUSY) { 1467295Ssam adp->ad_state &= ~ADBUSY; 1477295Ssam wakeup((caddr_t)adp); 1487295Ssam } 1497295Ssam } 1507295Ssam 1517295Ssam adreset(uban) 1527295Ssam int uban; 1537295Ssam { 1547295Ssam register int i; 1557295Ssam register struct uba_device *ui; 1567295Ssam register struct ad *adp = ad; 1577295Ssam register struct addevice *adaddr; 1587295Ssam 1597295Ssam for(i = 0; i < NAD; i++, adp++) { 1607295Ssam if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 || 1617295Ssam ui->ui_ubanum != uban || adp->ad_open == 0) 1627295Ssam continue; 1637295Ssam printf(" ad%d", i); 1647295Ssam if(adp->ad_state&ADBUSY == 0) 1657295Ssam continue; 1667295Ssam adaddr = (struct addevice *) ui->ui_addr; 1677295Ssam adaddr->ad_csr = 0; 1687295Ssam adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START; 1697295Ssam } 1707295Ssam } 1717295Ssam #endif 172