Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/******************************************************************************
  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. The
 22 *			 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_start
 39 *
 40 *	Start hardware timer (clock ticks are 16us).
 41 *
 42 *	void hwt_start(
 43 *		struct s_smc *smc,
 44 *		u_long time) ;
 45 * In
 46 *	smc - A pointer to the SMT Context structure.
 47 *
 48 *	time - The time in units of 16us to load the timer with.
 49 * Out
 50 *	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 us
 68	 *	time = 16 us
 69	 */
 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_stop
 82 *
 83 *	Stop hardware timer.
 84 *
 85 *	void hwt_stop(
 86 *		struct s_smc *smc) ;
 87 * In
 88 *	smc - A pointer to the SMT Context structure.
 89 * Out
 90 *	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_init
104 *
105 *	Initialize hardware timer.
106 *
107 *	void hwt_init(
108 *		struct s_smc *smc) ;
109 * In
110 *	smc - A pointer to the SMT Context structure.
111 * Out
112 *	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_restart
127 *
128 *	Clear timer interrupt.
129 *
130 *	void hwt_restart(
131 *		struct s_smc *smc) ;
132 * In
133 *	smc - A pointer to the SMT Context structure.
134 * Out
135 *	Nothing.
136 *
137 ************************/
138void hwt_restart(struct s_smc *smc)
139{
140	hwt_stop(smc) ;
141}
142
143/************************
144 *
145 *	hwt_read
146 *
147 *	Stop hardware timer and read time elapsed since last start.
148 *
149 *	u_long hwt_read(smc) ;
150 * In
151 *	smc - A pointer to the SMT Context structure.
152 * Out
153 *	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		else
172			smc->hw.t_stop = smc->hw.t_start - tr ;
173	}
174	return smc->hw.t_stop;
175}
176
177#ifdef	PCI
178/************************
179 *
180 *	hwt_quick_read
181 *
182 *	Stop hardware timer and read timer value and start the timer again.
183 *
184 *	u_long hwt_read(smc) ;
185 * In
186 *	smc - A pointer to the SMT Context structure.
187 * Out
188 *	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 elapsed
211 *	since the start time.
212 * 
213 * para	start		start time
214 *	duration	time to wait
215 *
216 * NOTE: The function will return immediately, if the timer is not
217 *	 started
218 ************************/
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 running
227	 */
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#endif
261