GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / staging / comedi / drivers / comedi_8254.h
1 /*
2  * comedi_8254.h
3  * Generic 8254 timer/counter support
4  * Copyright (C) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
5  *
6  * COMEDI - Linux Control and Measurement Device Interface
7  * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
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
20 #ifndef _COMEDI_8254_H
21 #define _COMEDI_8254_H
22
23 #include <linux/types.h>
24
25 struct comedi_device;
26 struct comedi_insn;
27 struct comedi_subdevice;
28
29 /*
30  * Common oscillator base values in nanoseconds
31  */
32 #define I8254_OSC_BASE_10MHZ    100
33 #define I8254_OSC_BASE_5MHZ     200
34 #define I8254_OSC_BASE_4MHZ     250
35 #define I8254_OSC_BASE_2MHZ     500
36 #define I8254_OSC_BASE_1MHZ     1000
37 #define I8254_OSC_BASE_100KHZ   10000
38 #define I8254_OSC_BASE_10KHZ    100000
39 #define I8254_OSC_BASE_1KHZ     1000000
40
41 /*
42  * I/O access size used to read/write registers
43  */
44 #define I8254_IO8               1
45 #define I8254_IO16              2
46 #define I8254_IO32              4
47
48 /*
49  * Register map for generic 8254 timer (I8254_IO8 with 0 regshift)
50  */
51 #define I8254_COUNTER0_REG              0x00
52 #define I8254_COUNTER1_REG              0x01
53 #define I8254_COUNTER2_REG              0x02
54 #define I8254_CTRL_REG                  0x03
55 #define I8254_CTRL_SEL_CTR(x)           ((x) << 6)
56 #define I8254_CTRL_READBACK(x)          (I8254_CTRL_SEL_CTR(3) | BIT(x))
57 #define I8254_CTRL_READBACK_COUNT       I8254_CTRL_READBACK(4)
58 #define I8254_CTRL_READBACK_STATUS      I8254_CTRL_READBACK(5)
59 #define I8254_CTRL_READBACK_SEL_CTR(x)  (2 << (x))
60 #define I8254_CTRL_RW(x)                (((x) & 0x3) << 4)
61 #define I8254_CTRL_LATCH                I8254_CTRL_RW(0)
62 #define I8254_CTRL_LSB_ONLY             I8254_CTRL_RW(1)
63 #define I8254_CTRL_MSB_ONLY             I8254_CTRL_RW(2)
64 #define I8254_CTRL_LSB_MSB              I8254_CTRL_RW(3)
65
66 /* counter maps zero to 0x10000 */
67 #define I8254_MAX_COUNT                 0x10000
68
69 /**
70  * struct comedi_8254 - private data used by this module
71  * @iobase:             PIO base address of the registers (in/out)
72  * @mmio:               MMIO base address of the registers (read/write)
73  * @iosize:             I/O size used to access the registers (b/w/l)
74  * @regshift:           register gap shift
75  * @osc_base:           cascaded oscillator speed in ns
76  * @divisor:            divisor for single counter
77  * @divisor1:           divisor loaded into first cascaded counter
78  * @divisor2:           divisor loaded into second cascaded counter
79  * #next_div:           next divisor for single counter
80  * @next_div1:          next divisor to use for first cascaded counter
81  * @next_div2:          next divisor to use for second cascaded counter
82  * @clock_src;          current clock source for each counter (driver specific)
83  * @gate_src;           current gate source  for each counter (driver specific)
84  * @busy:               flags used to indicate that a counter is "busy"
85  * @insn_config:        driver specific (*insn_config) callback
86  */
87 struct comedi_8254 {
88         unsigned long iobase;
89         void __iomem *mmio;
90         unsigned int iosize;
91         unsigned int regshift;
92         unsigned int osc_base;
93         unsigned int divisor;
94         unsigned int divisor1;
95         unsigned int divisor2;
96         unsigned int next_div;
97         unsigned int next_div1;
98         unsigned int next_div2;
99         unsigned int clock_src[3];
100         unsigned int gate_src[3];
101         bool busy[3];
102
103         int (*insn_config)(struct comedi_device *dev,
104                            struct comedi_subdevice *s,
105                            struct comedi_insn *insn, unsigned int *data);
106 };
107
108 unsigned int comedi_8254_status(struct comedi_8254 *i8254,
109                                 unsigned int counter);
110 unsigned int comedi_8254_read(struct comedi_8254 *i8254, unsigned int counter);
111 void comedi_8254_write(struct comedi_8254 *i8254,
112                        unsigned int counter, unsigned int val);
113
114 int comedi_8254_set_mode(struct comedi_8254 *i8254,
115                          unsigned int counter, unsigned int mode);
116 int comedi_8254_load(struct comedi_8254 *i8254,
117                      unsigned int counter, unsigned int val, unsigned int mode);
118
119 void comedi_8254_pacer_enable(struct comedi_8254 *i8254,
120                               unsigned int counter1, unsigned int counter2,
121                               bool enable);
122 void comedi_8254_update_divisors(struct comedi_8254 *i8254);
123 void comedi_8254_cascade_ns_to_timer(struct comedi_8254 *i8254,
124                                      unsigned int *nanosec, unsigned int flags);
125 void comedi_8254_ns_to_timer(struct comedi_8254 *i8254,
126                              unsigned int *nanosec, unsigned int flags);
127
128 void comedi_8254_set_busy(struct comedi_8254 *i8254,
129                           unsigned int counter, bool busy);
130
131 void comedi_8254_subdevice_init(struct comedi_subdevice *s,
132                                 struct comedi_8254 *i8254);
133
134 struct comedi_8254 *comedi_8254_init(unsigned long iobase,
135                                      unsigned int osc_base,
136                                      unsigned int iosize,
137                                      unsigned int regshift);
138 struct comedi_8254 *comedi_8254_mm_init(void __iomem *mmio,
139                                         unsigned int osc_base,
140                                         unsigned int iosize,
141                                         unsigned int regshift);
142
143 #endif  /* _COMEDI_8254_H */