nidas  v1.2-1520
gpio_mm.h
Go to the documentation of this file.
1 /* -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8; -*- */
2 /* vim: set shiftwidth=8 softtabstop=8 expandtab: */
3 /*
4  ********************************************************************
5  ** NIDAS: NCAR In-situ Data Acquistion Software
6  **
7  ** 2008, Copyright University Corporation for Atmospheric Research
8  **
9  ** This program is free software; you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation; either version 2 of the License, or
12  ** (at your option) any later version.
13  **
14  ** This program is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** The LICENSE.txt file accompanying this software contains
20  ** a copy of the GNU General Public License. If it is not found,
21  ** write to the Free Software Foundation, Inc.,
22  ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  **
24  ********************************************************************
25 */
26 /*
27 
28  Driver for Diamond Systems Corp GPIO-MM series of Counter/Timer
29  Digital I/O Cards.
30 
31  Original Author: Gordon Maclean
32 
33 */
34 
35 /*
36  * Each board has 10 16-bit counters and gobs of digital I/O pins.
37  *
38  * The implementation of a frequency counter uses 3 counters.
39  * One counter on a board is used as a general timer clock.
40  * Other driver modules can register with this clock to be
41  * called back at periodic times.
42  *
43  * Therefore each board supports up to 3 frequency input
44  * devices, or 9 pulse counters.
45  *
46  * Eventually the driver could also support a digital device,
47  * for controlling all the I/O pins. Dig I/O interrupt
48  * support is also available.
49  *
50  * So the following devices can be opened concurrently on a board:
51  * 3 frequency counters, 1 dio
52  * 2 frequency counters, 3 pulse counters, 1 dio
53  * 1 frequency counters, 6 pulse counters, 1 dio
54  * 0 frequency counters, 9 pulse counters, 1 dio
55  *
56  * Support for the pulse counters, dio and events has not been added yet....
57  *
58  * Board #0: Device table:
59  * device devname minor number
60  * freq cntr 0: /dev/gpiomm_fcntr0 0
61  * freq cntr 1: /dev/gpiomm_fcntr1 1
62  * freq cntr 2: /dev/gpiomm_fcntr2 2
63  * digital i/O: /dev/gpiomm_dio0 3
64  * pulse cntr 0: /dev/gpiomm_cntr0 4
65  * pulse cntr 1: /dev/gpiomm_cntr1 5
66  * pulse cntr 2: /dev/gpiomm_cntr2 6
67  * pulse cntr 3: /dev/gpiomm_cntr3 7
68  * pulse cntr 4: /dev/gpiomm_cntr4 8
69  * pulse cntr 5: /dev/gpiomm_cntr5 9
70  * pulse cntr 6: /dev/gpiomm_cntr6 10
71  * pulse cntr 7: /dev/gpiomm_cntr7 11
72  * pulse cntr 8: /dev/gpiomm_cntr8 12
73  * event 0: /dev/gpiomm_event0 13
74  *
75  * Board #1: Device table:
76  * device devname minor number (board0 + 14)
77  * freq cntr 0: /dev/gpiomm_fcntr3 14
78  * freq cntr 1: /dev/gpiomm_fcntr4 15
79  * freq cntr 2: /dev/gpiomm_fcntr5 16
80  * digital i/O: /dev/gpiomm_dio1 17
81  * pulse cntr 0: /dev/gpiomm_cntr9 18
82  * pulse cntr 1: /dev/gpiomm_cntr10 19
83  * pulse cntr 2: /dev/gpiomm_cntr11 10
84  * pulse cntr 3: /dev/gpiomm_cntr12 21
85  * pulse cntr 4: /dev/gpiomm_cntr13 22
86  * pulse cntr 5: /dev/gpiomm_cntr14 23
87  * pulse cntr 6: /dev/gpiomm_cntr15 24
88  * pulse cntr 7: /dev/gpiomm_cntr16 25
89  * pulse cntr 8: /dev/gpiomm_cntr17 26
90  * event 0: /dev/gpiomm_event1 27
91  */
92 
93 #ifndef NIDAS_DIAMOND_GPIO_MM_H
94 #define NIDAS_DIAMOND_GPIO_MM_H
95 
96 #ifndef __KERNEL__
97 /* User programs need this for the _IO macros, but kernel
98  * modules get their's elsewhere.
99  */
100 #include <sys/ioctl.h>
101 #include <sys/types.h>
102 #endif
103 
104 /* This header is also included from user-side code that
105  * wants to get the values of the ioctl commands, and
106  * the definition of the structures.
107  */
108 
110 {
111  int outputPeriodUsec; // how often to report
112  int numPulses; // how many pulses to time
114 };
115 
117 {
118  unsigned int lostSamples;
119  unsigned int pulseUnderflow;
120  unsigned int badGateWarning;
121  unsigned int badStatusWarning;
122 };
123 
125 {
127 };
128 
130 {
131  unsigned int nevents;
132  unsigned int lostSamples;
133 };
134 
135 /* Pick a character as the magic number of your driver.
136  * It isn't strictly necessary that it be distinct between
137  * all modules on the system, but is a good idea. With
138  * distinct magic numbers one can catch a user sending
139  * an ioctl to the wrong device.
140  */
141 #define GPIO_MM_IOC_MAGIC 'g'
142 
143 /*
144  * The enumeration of IOCTLs that this driver supports.
145  * See pages 130-132 of Linux Device Driver's Manual
146  */
147 
149 #define GPIO_MM_FCNTR_START \
150  _IOW(GPIO_MM_IOC_MAGIC,0,struct GPIO_MM_fcntr_config)
151 #define GPIO_MM_FCNTR_GET_STATUS \
152  _IOR(GPIO_MM_IOC_MAGIC,1,struct GPIO_MM_fcntr_status)
153 
154 #define GPIO_MM_EVENT_START \
155  _IOW(GPIO_MM_IOC_MAGIC,2,struct GPIO_MM_event_config)
156 #define GPIO_MM_EVENT_GET_STATUS \
157  _IOR(GPIO_MM_IOC_MAGIC,3,struct GPIO_MM_event_status)
158 
159 /* Maximum IOCTL number in above values */
160 #define GPIO_MM_IOC_MAXNR 3
161 
162 #define GPIO_MM_CT_CLOCK_HZ 20000000
163 
164 #ifdef __KERNEL__
165 /******** Start of definitions used by driver modules only **********/
166 
167 #include <linux/cdev.h>
168 #include <linux/device.h>
169 #include <nidas/linux/util.h>
170 #include "gpio_mm_regs.h"
171 
172 typedef void (*gpio_timer_callback_func_t) (void* privateData);
173 
179 struct gpio_timer_callback
180 {
181  struct list_head list;
182  gpio_timer_callback_func_t callbackFunc;
183  void* privateData;
184  unsigned int usecs;
185  unsigned int tickModulus;
186 };
187 
202 extern struct gpio_timer_callback *register_gpio_timer_callback(
203  gpio_timer_callback_func_t callback,unsigned int usecs,
204  void *privateData, int *errp);
205 
232 extern long unregister_gpio_timer_callback(struct gpio_timer_callback *cb,
233  int wait);
234 
235 /* Size of ISA I/O space */
236 #define GPIO_MM_DIO_IOPORT_WIDTH 8
237 #define GPIO_MM_CT_IOPORT_WIDTH 16
238 
239 #define MAX_GPIO_MM_BOARDS 5 // number of boards supported by driver
240 
241 /* See device table in above comments */
242 #define GPIO_MM_MINORS_PER_BOARD 14
243 
244 /* Use 3 counter timers to implement one frequency counter */
245 #define GPIO_MM_CNTR_PER_FCNTR 3
246 
247 /* This will be 10/3=3 for GPIO-MM */
248 #define GPIO_MM_FCNTR_PER_BOARD (GPIO_MM_CNTR_PER_BOARD/GPIO_MM_CNTR_PER_FCNTR)
249 
250 #define GPIO_MM_FCNTR_SAMPLE_QUEUE_SIZE 16
251 
252 #define GPIO_MM_EVENT_SAMPLE_QUEUE_SIZE 16
253 
254 /* Which counter 0-9 to use for a general purpose timer */
255 #define GPIO_MM_TIMER_COUNTER 9
256 
257 #define CALLBACK_POOL_SIZE 64 /* number of timer callbacks we can support */
258 
263 struct freq_sample
264 {
265  dsm_sample_time_t timetag; // timetag of sample
266  dsm_sample_length_t length; // number of bytes in data (8)
267  int pulses;
268  int ticks;
269 };
270 
274 struct event_sample
275 {
276  dsm_sample_time_t timetag; // timetag of sample
277  dsm_sample_length_t length; // number of bytes in data (0)
278  unsigned int nevents;
279 };
280 
281 struct GPIO_MM;
282 
286 struct GPIO_MM_fcntr
287 {
288  struct GPIO_MM* brd;
289 
290  struct device* device;
291 
292  int num; // which freq counter on board
293 
294  struct GPIO_MM_fcntr_status status;
295 
296  char deviceName[32];
297 
298  struct cdev cdev;
299 
303  int numPulses;
304 
308  int outputPeriodUsec;
309 
310  atomic_t num_opened; // number of times opened
311 
312  struct gpio_timer_callback* timer_callback;
313 
314  struct dsm_sample_circ_buf samples; // samples out of b.h.
315 
319  wait_queue_head_t rwaitq;
320 
321  struct sample_read_state read_state;
322 
326  long latencyJiffies;
327 
331  unsigned long lastWakeup;
332 
333 };
334 
338 struct GPIO_MM_event
339 {
340  struct GPIO_MM* brd;
341 
342  struct device* device;
343 
344  struct GPIO_MM_event_status status;
345 
346  char deviceName[32];
347 
348  struct cdev cdev;
349 
350  atomic_t num_opened; // number of times opened
351 
352  struct dsm_sample_circ_buf samples; // event samples
353 
357  wait_queue_head_t rwaitq;
358 
359  struct sample_read_state read_state;
360 
364  long latencyJiffies;
365 
369  unsigned long lastWakeup;
370 
371 };
372 
373 /*
374  * The GPIO timer.
375  */
376 struct GPIO_MM_timer
377 {
378  struct GPIO_MM* brd;
379 
383  struct list_head callbackList;
384 
388  struct list_head callbackPool;
389 
393  struct list_head pendingAdds;
394 
398  struct gpio_timer_callback *pendingRemoves[CALLBACK_POOL_SIZE];
399 
400  int nPendingRemoves;
401 
406  spinlock_t callbackLock;
407 
413  unsigned int usecs;
414 
415  unsigned int irqsReceived;
416 
420  unsigned int tick;
421 
425  unsigned int tickLimit;
426 
427  int scaler;
428 
432  struct tasklet_struct tasklet;
433 
438  int callbacksChanged;
439 
444  wait_queue_head_t callbackWaitQ;
445 
446 };
447 
451 struct GPIO_MM
452 {
453  int num; // which board in system, from 0
454  unsigned int ioport_dio; // ioport address of DIO regs
455  unsigned long dio_addr; // Base address of 8255 DIO regs
456 
457  unsigned int ioport_ct; // ioport address of cntr/timer
458  unsigned long ct_addr; // Base address of 9513 cntr/timer regs
459  int irqs[2]; // values of ISA irq A and B
460  int reqirqs[2]; // requested system irqs A and B
461  int cntr_used[GPIO_MM_CNTR_PER_BOARD]; // 0=unused, 1=used
462 
463  int boardID;
464 
468  unsigned char mmode_lsb[2];
469  unsigned char mmode_msb[2];
470 
471  struct GPIO_MM_timer* timer;
472 
476  struct GPIO_MM_fcntr* fcntrs;
477 
481  struct GPIO_MM_event* event;
482 
487  spinlock_t reglock;
488 
489 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
490  struct mutex brd_mutex; // lock for non-interrupt board ops
491 #else
492  struct semaphore brd_mutex; // lock for non-interrupt board ops
493 #endif
494 };
495 
496 #endif
497 
498 #endif
unsigned int lostSamples
Definition: gpio_mm.h:132
static string device
Definition: sing.cc:60
Definition: gpio_mm.h:129
struct gpio_timer_callback * register_gpio_timer_callback(gpio_timer_callback_func_t callback, unsigned int usecs, void *privateData, int *errp)
Definition: gpio_mm.c:2000
int outputPeriodUsec
Definition: gpio_mm.h:111
unsigned int nevents
Definition: gpio_mm.h:131
#define GPIO_MM_CNTR_PER_BOARD
Definition: gpio_mm_regs.h:39
unsigned int badGateWarning
Definition: gpio_mm.h:120
unsigned int pulseUnderflow
Definition: gpio_mm.h:119
unsigned int lostSamples
Definition: gpio_mm.h:118
#define CALLBACK_POOL_SIZE
Definition: pc104sg.c:190
int dsm_sample_time_t
Depending on the module, either tenths of milliseconds, or milliseconds since 00:00 UTC today...
Definition: types.h:48
long unregister_gpio_timer_callback(struct gpio_timer_callback *cb, int wait)
Definition: gpio_mm.c:2010
static int irqs[MAX_DMMAT_BOARDS]
Definition: dmd_mmat.c:73
unsigned int badStatusWarning
Definition: gpio_mm.h:121
int latencyUsecs
Definition: gpio_mm.h:126
int numPulses
Definition: gpio_mm.h:112
Definition: gpio_mm.h:116
int latencyUsecs
Definition: gpio_mm.h:113
unsigned int dsm_sample_length_t
length of data portion of sample.
Definition: types.h:51
Definition: gpio_mm.h:124
Definition: gpio_mm.h:109