[ARM] pxa: Gumstix Verdex PCMCIA support
[linux-2.6/verdex.git] / drivers / net / skfp / hwt.c
blob053151468f93af7947d0bc9dc3da41a409a3971f
1 /******************************************************************************
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
6 * See the file "skfddi.c" for further information.
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.
13 * The information in this file is provided "AS IS" without warranty.
15 ******************************************************************************/
18 * Timer Driver for FBI board (timer chip 82C54)
22 * Modifications:
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(*)
30 #include "h/types.h"
31 #include "h/fddi.h"
32 #include "h/smc.h"
34 #ifndef lint
35 static const char ID_sccs[] = "@(#)hwt.c 1.13 97/04/23 (C) SK " ;
36 #endif
39 * Prototypes of local functions.
41 /* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
42 /*static void hwt_restart() ; */
44 /************************
46 * hwt_start
48 * Start hardware timer (clock ticks are 16us).
50 * void hwt_start(
51 * struct s_smc *smc,
52 * u_long time) ;
53 * In
54 * smc - A pointer to the SMT Context structure.
56 * time - The time in units of 16us to load the timer with.
57 * Out
58 * Nothing.
60 ************************/
61 #define HWT_MAX (65000)
63 void hwt_start(struct s_smc *smc, u_long time)
65 u_short cnt ;
67 if (time > HWT_MAX)
68 time = HWT_MAX ;
70 smc->hw.t_start = time ;
71 smc->hw.t_stop = 0L ;
73 cnt = (u_short)time ;
75 * if time < 16 us
76 * time = 16 us
78 if (!cnt)
79 cnt++ ;
81 outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ; /* Load timer value. */
82 outpw(ADDR(B2_TI_CRTL), TIM_START) ; /* Start timer. */
84 smc->hw.timer_activ = TRUE ;
87 /************************
89 * hwt_stop
91 * Stop hardware timer.
93 * void hwt_stop(
94 * struct s_smc *smc) ;
95 * In
96 * smc - A pointer to the SMT Context structure.
97 * Out
98 * Nothing.
100 ************************/
101 void hwt_stop(struct s_smc *smc)
103 outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
104 outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
106 smc->hw.timer_activ = FALSE ;
109 /************************
111 * hwt_init
113 * Initialize hardware timer.
115 * void hwt_init(
116 * struct s_smc *smc) ;
117 * In
118 * smc - A pointer to the SMT Context structure.
119 * Out
120 * Nothing.
122 ************************/
123 void hwt_init(struct s_smc *smc)
125 smc->hw.t_start = 0 ;
126 smc->hw.t_stop = 0 ;
127 smc->hw.timer_activ = FALSE ;
129 hwt_restart(smc) ;
132 /************************
134 * hwt_restart
136 * Clear timer interrupt.
138 * void hwt_restart(
139 * struct s_smc *smc) ;
140 * In
141 * smc - A pointer to the SMT Context structure.
142 * Out
143 * Nothing.
145 ************************/
146 void hwt_restart(struct s_smc *smc)
148 hwt_stop(smc) ;
151 /************************
153 * hwt_read
155 * Stop hardware timer and read time elapsed since last start.
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.
163 ************************/
164 u_long hwt_read(struct s_smc *smc)
166 u_short tr ;
167 u_long is ;
169 if (smc->hw.timer_activ) {
170 hwt_stop(smc) ;
171 tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
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 ;
179 else
180 smc->hw.t_stop = smc->hw.t_start - tr ;
182 return (smc->hw.t_stop) ;
185 #ifdef PCI
186 /************************
188 * hwt_quick_read
190 * Stop hardware timer and read timer value and start the timer again.
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.
198 ************************/
199 u_long hwt_quick_read(struct s_smc *smc)
201 u_long interval ;
202 u_long time ;
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) ;
211 return(time) ;
214 /************************
216 * hwt_wait_time(smc,start,duration)
218 * This function returnes after the amount of time is elapsed
219 * since the start time.
221 * para start start time
222 * duration time to wait
224 * NOTE: The fuction will return immediately, if the timer is not
225 * started
226 ************************/
227 void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
229 long diff ;
230 long interval ;
231 int wrapped ;
234 * check if timer is running
236 if (smc->hw.timer_activ == FALSE ||
237 hwt_quick_read(smc) == hwt_quick_read(smc)) {
238 return ;
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 ;
248 } while (diff <= duration) ;
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 ;
260 else {
261 if (hwt_quick_read(smc) < start) {
262 wrapped = 0 ;
265 } while (diff <= duration) ;
268 #endif