xref: /csrg-svn/sys/vax/uba/ad.c (revision 23317)
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