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