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