Linux Audio

Check our new training course

Loading...
v3.15
 
  1/******************************************************************************
  2 *
  3 *	(C)Copyright 1998,1999 SysKonnect,
  4 *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  5 *
  6 *	See the file "skfddi.c" for further information.
  7 *
  8 *	This program is free software; you can redistribute it and/or modify
  9 *	it under the terms of the GNU General Public License as published by
 10 *	the Free Software Foundation; either version 2 of the License, or
 11 *	(at your option) any later version.
 12 *
 13 *	The information in this file is provided "AS IS" without warranty.
 14 *
 15 ******************************************************************************/
 16
 17/*
 18 * Timer Driver for FBI board (timer chip 82C54)
 19 */
 20
 21/*
 22 * Modifications:
 23 *
 24 *	28-Jun-1994 sw	Edit v1.6.
 25 *			MCA: Added support for the SK-NET FDDI-FM2 adapter. The
 26 *			 following functions have been added(+) or modified(*):
 27 *			 hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)
 28 */
 29
 30#include "h/types.h"
 31#include "h/fddi.h"
 32#include "h/smc.h"
 33
 34#ifndef	lint
 35static const char ID_sccs[] = "@(#)hwt.c	1.13 97/04/23 (C) SK " ;
 36#endif
 37
 38/*
 39 * Prototypes of local functions.
 40 */
 41/* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
 42/*static void hwt_restart() ; */
 43
 44/************************
 45 *
 46 *	hwt_start
 47 *
 48 *	Start hardware timer (clock ticks are 16us).
 49 *
 50 *	void hwt_start(
 51 *		struct s_smc *smc,
 52 *		u_long time) ;
 53 * In
 54 *	smc - A pointer to the SMT Context structure.
 55 *
 56 *	time - The time in units of 16us to load the timer with.
 57 * Out
 58 *	Nothing.
 59 *
 60 ************************/
 61#define	HWT_MAX	(65000)
 62
 63void hwt_start(struct s_smc *smc, u_long time)
 64{
 65	u_short	cnt ;
 66
 67	if (time > HWT_MAX)
 68		time = HWT_MAX ;
 69
 70	smc->hw.t_start = time ;
 71	smc->hw.t_stop = 0L ;
 72
 73	cnt = (u_short)time ;
 74	/*
 75	 * if time < 16 us
 76	 *	time = 16 us
 77	 */
 78	if (!cnt)
 79		cnt++ ;
 80
 81	outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ;	/* Load timer value. */
 82	outpw(ADDR(B2_TI_CRTL), TIM_START) ;		/* Start timer. */
 83
 84	smc->hw.timer_activ = TRUE ;
 85}
 86
 87/************************
 88 *
 89 *	hwt_stop
 90 *
 91 *	Stop hardware timer.
 92 *
 93 *	void hwt_stop(
 94 *		struct s_smc *smc) ;
 95 * In
 96 *	smc - A pointer to the SMT Context structure.
 97 * Out
 98 *	Nothing.
 99 *
100 ************************/
101void hwt_stop(struct s_smc *smc)
102{
103	outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
104	outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
105
106	smc->hw.timer_activ = FALSE ;
107}
108
109/************************
110 *
111 *	hwt_init
112 *
113 *	Initialize hardware timer.
114 *
115 *	void hwt_init(
116 *		struct s_smc *smc) ;
117 * In
118 *	smc - A pointer to the SMT Context structure.
119 * Out
120 *	Nothing.
121 *
122 ************************/
123void hwt_init(struct s_smc *smc)
124{
125	smc->hw.t_start = 0 ;
126	smc->hw.t_stop	= 0 ;
127	smc->hw.timer_activ = FALSE ;
128
129	hwt_restart(smc) ;
130}
131
132/************************
133 *
134 *	hwt_restart
135 *
136 *	Clear timer interrupt.
137 *
138 *	void hwt_restart(
139 *		struct s_smc *smc) ;
140 * In
141 *	smc - A pointer to the SMT Context structure.
142 * Out
143 *	Nothing.
144 *
145 ************************/
146void hwt_restart(struct s_smc *smc)
147{
148	hwt_stop(smc) ;
149}
150
151/************************
152 *
153 *	hwt_read
154 *
155 *	Stop hardware timer and read time elapsed since last start.
156 *
157 *	u_long hwt_read(smc) ;
158 * In
159 *	smc - A pointer to the SMT Context structure.
160 * Out
161 *	The elapsed time since last start in units of 16us.
162 *
163 ************************/
164u_long hwt_read(struct s_smc *smc)
165{
166	u_short	tr ;
167	u_long	is ;
168
169	if (smc->hw.timer_activ) {
170		hwt_stop(smc) ;
171		tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
172
173		is = GET_ISR() ;
174		/* Check if timer expired (or wraparound). */
175		if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
176			hwt_restart(smc) ;
177			smc->hw.t_stop = smc->hw.t_start ;
178		}
179		else
180			smc->hw.t_stop = smc->hw.t_start - tr ;
181	}
182	return smc->hw.t_stop;
183}
184
185#ifdef	PCI
186/************************
187 *
188 *	hwt_quick_read
189 *
190 *	Stop hardware timer and read timer value and start the timer again.
191 *
192 *	u_long hwt_read(smc) ;
193 * In
194 *	smc - A pointer to the SMT Context structure.
195 * Out
196 *	current timer value in units of 80ns.
197 *
198 ************************/
199u_long hwt_quick_read(struct s_smc *smc)
200{
201	u_long interval ;
202	u_long time ;
203
204	interval = inpd(ADDR(B2_TI_INI)) ;
205	outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
206	time = inpd(ADDR(B2_TI_VAL)) ;
207	outpd(ADDR(B2_TI_INI),time) ;
208	outpw(ADDR(B2_TI_CRTL), TIM_START) ;
209	outpd(ADDR(B2_TI_INI),interval) ;
210
211	return time;
212}
213
214/************************
215 *
216 *	hwt_wait_time(smc,start,duration)
217 *
218 *	This function returnes after the amount of time is elapsed
219 *	since the start time.
220 * 
221 * para	start		start time
222 *	duration	time to wait
223 *
224 * NOTE: The function will return immediately, if the timer is not
225 *	 started
226 ************************/
227void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
228{
229	long	diff ;
230	long	interval ;
231	int	wrapped ;
232
233	/*
234	 * check if timer is running
235	 */
236	if (smc->hw.timer_activ == FALSE ||
237		hwt_quick_read(smc) == hwt_quick_read(smc)) {
238		return ;
239	}
240
241	interval = inpd(ADDR(B2_TI_INI)) ;
242	if (interval > duration) {
243		do {
244			diff = (long)(start - hwt_quick_read(smc)) ;
245			if (diff < 0) {
246				diff += interval ;
247			}
248		} while (diff <= duration) ;
249	}
250	else {
251		diff = interval ;
252		wrapped = 0 ;
253		do {
254			if (!wrapped) {
255				if (hwt_quick_read(smc) >= start) {
256					diff += interval ;
257					wrapped = 1 ;
258				}
259			}
260			else {
261				if (hwt_quick_read(smc) < start) {
262					wrapped = 0 ;
263				}
264			}
265		} while (diff <= duration) ;
266	}
267}
268#endif
269
v5.4
  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#ifndef	lint
 31static const char ID_sccs[] = "@(#)hwt.c	1.13 97/04/23 (C) SK " ;
 32#endif
 33
 34/*
 35 * Prototypes of local functions.
 36 */
 37/* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
 38/*static void hwt_restart() ; */
 39
 40/************************
 41 *
 42 *	hwt_start
 43 *
 44 *	Start hardware timer (clock ticks are 16us).
 45 *
 46 *	void hwt_start(
 47 *		struct s_smc *smc,
 48 *		u_long time) ;
 49 * In
 50 *	smc - A pointer to the SMT Context structure.
 51 *
 52 *	time - The time in units of 16us to load the timer with.
 53 * Out
 54 *	Nothing.
 55 *
 56 ************************/
 57#define	HWT_MAX	(65000)
 58
 59void hwt_start(struct s_smc *smc, u_long time)
 60{
 61	u_short	cnt ;
 62
 63	if (time > HWT_MAX)
 64		time = HWT_MAX ;
 65
 66	smc->hw.t_start = time ;
 67	smc->hw.t_stop = 0L ;
 68
 69	cnt = (u_short)time ;
 70	/*
 71	 * if time < 16 us
 72	 *	time = 16 us
 73	 */
 74	if (!cnt)
 75		cnt++ ;
 76
 77	outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ;	/* Load timer value. */
 78	outpw(ADDR(B2_TI_CRTL), TIM_START) ;		/* Start timer. */
 79
 80	smc->hw.timer_activ = TRUE ;
 81}
 82
 83/************************
 84 *
 85 *	hwt_stop
 86 *
 87 *	Stop hardware timer.
 88 *
 89 *	void hwt_stop(
 90 *		struct s_smc *smc) ;
 91 * In
 92 *	smc - A pointer to the SMT Context structure.
 93 * Out
 94 *	Nothing.
 95 *
 96 ************************/
 97void hwt_stop(struct s_smc *smc)
 98{
 99	outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
100	outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
101
102	smc->hw.timer_activ = FALSE ;
103}
104
105/************************
106 *
107 *	hwt_init
108 *
109 *	Initialize hardware timer.
110 *
111 *	void hwt_init(
112 *		struct s_smc *smc) ;
113 * In
114 *	smc - A pointer to the SMT Context structure.
115 * Out
116 *	Nothing.
117 *
118 ************************/
119void hwt_init(struct s_smc *smc)
120{
121	smc->hw.t_start = 0 ;
122	smc->hw.t_stop	= 0 ;
123	smc->hw.timer_activ = FALSE ;
124
125	hwt_restart(smc) ;
126}
127
128/************************
129 *
130 *	hwt_restart
131 *
132 *	Clear timer interrupt.
133 *
134 *	void hwt_restart(
135 *		struct s_smc *smc) ;
136 * In
137 *	smc - A pointer to the SMT Context structure.
138 * Out
139 *	Nothing.
140 *
141 ************************/
142void hwt_restart(struct s_smc *smc)
143{
144	hwt_stop(smc) ;
145}
146
147/************************
148 *
149 *	hwt_read
150 *
151 *	Stop hardware timer and read time elapsed since last start.
152 *
153 *	u_long hwt_read(smc) ;
154 * In
155 *	smc - A pointer to the SMT Context structure.
156 * Out
157 *	The elapsed time since last start in units of 16us.
158 *
159 ************************/
160u_long hwt_read(struct s_smc *smc)
161{
162	u_short	tr ;
163	u_long	is ;
164
165	if (smc->hw.timer_activ) {
166		hwt_stop(smc) ;
167		tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
168
169		is = GET_ISR() ;
170		/* Check if timer expired (or wraparound). */
171		if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
172			hwt_restart(smc) ;
173			smc->hw.t_stop = smc->hw.t_start ;
174		}
175		else
176			smc->hw.t_stop = smc->hw.t_start - tr ;
177	}
178	return smc->hw.t_stop;
179}
180
181#ifdef	PCI
182/************************
183 *
184 *	hwt_quick_read
185 *
186 *	Stop hardware timer and read timer value and start the timer again.
187 *
188 *	u_long hwt_read(smc) ;
189 * In
190 *	smc - A pointer to the SMT Context structure.
191 * Out
192 *	current timer value in units of 80ns.
193 *
194 ************************/
195u_long hwt_quick_read(struct s_smc *smc)
196{
197	u_long interval ;
198	u_long time ;
199
200	interval = inpd(ADDR(B2_TI_INI)) ;
201	outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
202	time = inpd(ADDR(B2_TI_VAL)) ;
203	outpd(ADDR(B2_TI_INI),time) ;
204	outpw(ADDR(B2_TI_CRTL), TIM_START) ;
205	outpd(ADDR(B2_TI_INI),interval) ;
206
207	return time;
208}
209
210/************************
211 *
212 *	hwt_wait_time(smc,start,duration)
213 *
214 *	This function returnes after the amount of time is elapsed
215 *	since the start time.
216 * 
217 * para	start		start time
218 *	duration	time to wait
219 *
220 * NOTE: The function will return immediately, if the timer is not
221 *	 started
222 ************************/
223void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
224{
225	long	diff ;
226	long	interval ;
227	int	wrapped ;
228
229	/*
230	 * check if timer is running
231	 */
232	if (smc->hw.timer_activ == FALSE ||
233		hwt_quick_read(smc) == hwt_quick_read(smc)) {
234		return ;
235	}
236
237	interval = inpd(ADDR(B2_TI_INI)) ;
238	if (interval > duration) {
239		do {
240			diff = (long)(start - hwt_quick_read(smc)) ;
241			if (diff < 0) {
242				diff += interval ;
243			}
244		} while (diff <= duration) ;
245	}
246	else {
247		diff = interval ;
248		wrapped = 0 ;
249		do {
250			if (!wrapped) {
251				if (hwt_quick_read(smc) >= start) {
252					diff += interval ;
253					wrapped = 1 ;
254				}
255			}
256			else {
257				if (hwt_quick_read(smc) < start) {
258					wrapped = 0 ;
259				}
260			}
261		} while (diff <= duration) ;
262	}
263}
264#endif
265