brintos

brintos / linux-shallow public Read only

0
0
Text · 5.0 KiB · 5577b8e Raw
262 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/******************************************************************************3 *4 *	(C)Copyright 1998,1999 SysKonnect,5 *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.6 *7 *	See the file "skfddi.c" for further information.8 *9 *	The information in this file is provided "AS IS" without warranty.10 *11 ******************************************************************************/12 13/*14 * Timer Driver for FBI board (timer chip 82C54)15 */16 17/*18 * Modifications:19 *20 *	28-Jun-1994 sw	Edit v1.6.21 *			MCA: Added support for the SK-NET FDDI-FM2 adapter. The22 *			 following functions have been added(+) or modified(*):23 *			 hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)24 */25 26#include "h/types.h"27#include "h/fddi.h"28#include "h/smc.h"29 30/*31 * Prototypes of local functions.32 */33/* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */34/*static void hwt_restart() ; */35 36/************************37 *38 *	hwt_start39 *40 *	Start hardware timer (clock ticks are 16us).41 *42 *	void hwt_start(43 *		struct s_smc *smc,44 *		u_long time) ;45 * In46 *	smc - A pointer to the SMT Context structure.47 *48 *	time - The time in units of 16us to load the timer with.49 * Out50 *	Nothing.51 *52 ************************/53#define	HWT_MAX	(65000)54 55void hwt_start(struct s_smc *smc, u_long time)56{57	u_short	cnt ;58 59	if (time > HWT_MAX)60		time = HWT_MAX ;61 62	smc->hw.t_start = time ;63	smc->hw.t_stop = 0L ;64 65	cnt = (u_short)time ;66	/*67	 * if time < 16 us68	 *	time = 16 us69	 */70	if (!cnt)71		cnt++ ;72 73	outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ;	/* Load timer value. */74	outpw(ADDR(B2_TI_CRTL), TIM_START) ;		/* Start timer. */75 76	smc->hw.timer_activ = TRUE ;77}78 79/************************80 *81 *	hwt_stop82 *83 *	Stop hardware timer.84 *85 *	void hwt_stop(86 *		struct s_smc *smc) ;87 * In88 *	smc - A pointer to the SMT Context structure.89 * Out90 *	Nothing.91 *92 ************************/93void hwt_stop(struct s_smc *smc)94{95	outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;96	outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;97 98	smc->hw.timer_activ = FALSE ;99}100 101/************************102 *103 *	hwt_init104 *105 *	Initialize hardware timer.106 *107 *	void hwt_init(108 *		struct s_smc *smc) ;109 * In110 *	smc - A pointer to the SMT Context structure.111 * Out112 *	Nothing.113 *114 ************************/115void hwt_init(struct s_smc *smc)116{117	smc->hw.t_start = 0 ;118	smc->hw.t_stop	= 0 ;119	smc->hw.timer_activ = FALSE ;120 121	hwt_restart(smc) ;122}123 124/************************125 *126 *	hwt_restart127 *128 *	Clear timer interrupt.129 *130 *	void hwt_restart(131 *		struct s_smc *smc) ;132 * In133 *	smc - A pointer to the SMT Context structure.134 * Out135 *	Nothing.136 *137 ************************/138void hwt_restart(struct s_smc *smc)139{140	hwt_stop(smc) ;141}142 143/************************144 *145 *	hwt_read146 *147 *	Stop hardware timer and read time elapsed since last start.148 *149 *	u_long hwt_read(smc) ;150 * In151 *	smc - A pointer to the SMT Context structure.152 * Out153 *	The elapsed time since last start in units of 16us.154 *155 ************************/156u_long hwt_read(struct s_smc *smc)157{158	u_short	tr ;159	u_long	is ;160 161	if (smc->hw.timer_activ) {162		hwt_stop(smc) ;163		tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;164 165		is = GET_ISR() ;166		/* Check if timer expired (or wraparound). */167		if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {168			hwt_restart(smc) ;169			smc->hw.t_stop = smc->hw.t_start ;170		}171		else172			smc->hw.t_stop = smc->hw.t_start - tr ;173	}174	return smc->hw.t_stop;175}176 177#ifdef	PCI178/************************179 *180 *	hwt_quick_read181 *182 *	Stop hardware timer and read timer value and start the timer again.183 *184 *	u_long hwt_read(smc) ;185 * In186 *	smc - A pointer to the SMT Context structure.187 * Out188 *	current timer value in units of 80ns.189 *190 ************************/191u_long hwt_quick_read(struct s_smc *smc)192{193	u_long interval ;194	u_long time ;195 196	interval = inpd(ADDR(B2_TI_INI)) ;197	outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;198	time = inpd(ADDR(B2_TI_VAL)) ;199	outpd(ADDR(B2_TI_INI),time) ;200	outpw(ADDR(B2_TI_CRTL), TIM_START) ;201	outpd(ADDR(B2_TI_INI),interval) ;202 203	return time;204}205 206/************************207 *208 *	hwt_wait_time(smc,start,duration)209 *210 *	This function returnes after the amount of time is elapsed211 *	since the start time.212 * 213 * para	start		start time214 *	duration	time to wait215 *216 * NOTE: The function will return immediately, if the timer is not217 *	 started218 ************************/219void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)220{221	long	diff ;222	long	interval ;223	int	wrapped ;224 225	/*226	 * check if timer is running227	 */228	if (smc->hw.timer_activ == FALSE ||229		hwt_quick_read(smc) == hwt_quick_read(smc)) {230		return ;231	}232 233	interval = inpd(ADDR(B2_TI_INI)) ;234	if (interval > duration) {235		do {236			diff = (long)(start - hwt_quick_read(smc)) ;237			if (diff < 0) {238				diff += interval ;239			}240		} while (diff <= duration) ;241	}242	else {243		diff = interval ;244		wrapped = 0 ;245		do {246			if (!wrapped) {247				if (hwt_quick_read(smc) >= start) {248					diff += interval ;249					wrapped = 1 ;250				}251			}252			else {253				if (hwt_quick_read(smc) < start) {254					wrapped = 0 ;255				}256			}257		} while (diff <= duration) ;258	}259}260#endif261 262