comedi_8254.h 4.4 KB

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