Commit | Line | Data |
---|---|---|
c919d71c HS |
1 | /* Watchdog Related Defines */ |
2 | ||
c919d71c HS |
3 | #define ADDIDATA_TIMER 0 |
4 | #define ADDIDATA_WATCHDOG 2 | |
5 | ||
c995fe94 | 6 | /* |
1ef0cfb1 HS |
7 | * (*insn_config) for the timer subdevice |
8 | * | |
9 | * Configures The Timer, Counter or Watchdog | |
10 | * Data Pointer contains configuration parameters as below | |
11 | * data[0] : 0 Configure As Timer | |
12 | * 1 Configure As Counter | |
13 | * 2 Configure As Watchdog | |
14 | * data[1] : 1 Enable Interrupt | |
15 | * 0 Disable Interrupt | |
16 | * data[2] : Time Unit | |
17 | * data[3] : Reload Value | |
18 | */ | |
805077b9 FA |
19 | static int apci3501_config_insn_timer(struct comedi_device *dev, |
20 | struct comedi_subdevice *s, | |
21 | struct comedi_insn *insn, | |
22 | unsigned int *data) | |
c995fe94 | 23 | { |
015aebe7 | 24 | struct apci3501_private *devpriv = dev->private; |
82a6e2e7 | 25 | unsigned int ul_Command1 = 0; |
843690b7 | 26 | |
c995fe94 ADG |
27 | devpriv->tsk_Current = current; |
28 | if (data[0] == ADDIDATA_WATCHDOG) { | |
29 | ||
30 | devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG; | |
2696fb57 | 31 | /* Disable the watchdog */ |
9798df72 | 32 | outl(0x0, dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 ADG |
33 | |
34 | if (data[1] == 1) { | |
2696fb57 | 35 | /* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */ |
9798df72 | 36 | outl(0x02, dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 37 | } else { |
9798df72 HS |
38 | /* disable Timer interrupt */ |
39 | outl(0x0, dev->iobase + APCI3501_TIMER_CTRL_REG); | |
c995fe94 ADG |
40 | } |
41 | ||
9798df72 HS |
42 | outl(data[2], dev->iobase + APCI3501_TIMER_TIMEBASE_REG); |
43 | outl(data[3], dev->iobase + APCI3501_TIMER_RELOAD_REG); | |
c995fe94 | 44 | |
9798df72 HS |
45 | /* Set the mode (e2->e0) */ |
46 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG) | 0xFFF819E0UL; | |
47 | outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); | |
48 | } | |
c995fe94 ADG |
49 | |
50 | else if (data[0] == ADDIDATA_TIMER) { | |
2696fb57 | 51 | /* First Stop The Timer */ |
9798df72 | 52 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 53 | ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; |
9798df72 | 54 | outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 ADG |
55 | devpriv->b_TimerSelectMode = ADDIDATA_TIMER; |
56 | if (data[1] == 1) { | |
2696fb57 | 57 | /* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */ |
9798df72 | 58 | outl(0x02, dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 59 | } else { |
9798df72 HS |
60 | /* disable Timer interrupt */ |
61 | outl(0x0, dev->iobase + APCI3501_TIMER_CTRL_REG); | |
c995fe94 ADG |
62 | } |
63 | ||
9798df72 HS |
64 | outl(data[2], dev->iobase + APCI3501_TIMER_TIMEBASE_REG); |
65 | outl(data[3], dev->iobase + APCI3501_TIMER_RELOAD_REG); | |
c995fe94 | 66 | |
9798df72 HS |
67 | /* mode 2 */ |
68 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); | |
c995fe94 ADG |
69 | ul_Command1 = |
70 | (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL; | |
9798df72 HS |
71 | outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
72 | } | |
c995fe94 ADG |
73 | |
74 | return insn->n; | |
75 | } | |
76 | ||
77 | /* | |
1ef0cfb1 HS |
78 | * (*insn_write) for the timer subdevice |
79 | * | |
80 | * Start / Stop The Selected Timer , Counter or Watchdog | |
81 | * Data Pointer contains configuration parameters as below | |
82 | * data[0] : 0 Timer | |
83 | * 1 Counter | |
84 | * 2 Watchdog | |
85 | * data[1] : 1 Start | |
86 | * 0 Stop | |
87 | * 2 Trigger | |
88 | */ | |
805077b9 FA |
89 | static int apci3501_write_insn_timer(struct comedi_device *dev, |
90 | struct comedi_subdevice *s, | |
91 | struct comedi_insn *insn, | |
92 | unsigned int *data) | |
c995fe94 | 93 | { |
015aebe7 | 94 | struct apci3501_private *devpriv = dev->private; |
82a6e2e7 | 95 | unsigned int ul_Command1 = 0; |
843690b7 | 96 | |
c995fe94 ADG |
97 | if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { |
98 | ||
99 | if (data[1] == 1) { | |
9798df72 | 100 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 101 | ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; |
2696fb57 | 102 | /* Enable the Watchdog */ |
9798df72 | 103 | outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
6015bd55 | 104 | } else if (data[1] == 0) { /* Stop The Watchdog */ |
9798df72 | 105 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 106 | ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; |
9798df72 | 107 | outl(0x0, dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 108 | } else if (data[1] == 2) { |
9798df72 | 109 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 110 | ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL; |
9798df72 HS |
111 | outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
112 | } | |
113 | } | |
c995fe94 ADG |
114 | |
115 | if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) { | |
116 | if (data[1] == 1) { | |
117 | ||
9798df72 | 118 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 119 | ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; |
2696fb57 | 120 | /* Enable the Timer */ |
9798df72 | 121 | outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 122 | } else if (data[1] == 0) { |
2696fb57 | 123 | /* Stop The Timer */ |
9798df72 | 124 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 125 | ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; |
9798df72 | 126 | outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 ADG |
127 | } |
128 | ||
129 | else if (data[1] == 2) { | |
2696fb57 | 130 | /* Trigger the Timer */ |
9798df72 | 131 | ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 132 | ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL; |
9798df72 | 133 | outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
c995fe94 | 134 | } |
9798df72 | 135 | } |
c995fe94 | 136 | |
451d61f9 | 137 | inl(dev->iobase + APCI3501_TIMER_STATUS_REG); |
c995fe94 ADG |
138 | return insn->n; |
139 | } | |
140 | ||
141 | /* | |
1ef0cfb1 HS |
142 | * (*insn_read) for the timer subdevice |
143 | * | |
144 | * Read The Selected Timer, Counter or Watchdog | |
145 | * Data Pointer contains configuration parameters as below | |
146 | * data[0] : 0 Timer | |
147 | * 1 Counter | |
148 | * 2 Watchdog | |
149 | * data[1] : Timer Counter Watchdog Number | |
150 | */ | |
805077b9 FA |
151 | static int apci3501_read_insn_timer(struct comedi_device *dev, |
152 | struct comedi_subdevice *s, | |
153 | struct comedi_insn *insn, | |
154 | unsigned int *data) | |
c995fe94 | 155 | { |
015aebe7 | 156 | struct apci3501_private *devpriv = dev->private; |
c995fe94 ADG |
157 | |
158 | if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { | |
9798df72 HS |
159 | data[0] = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1; |
160 | data[1] = inl(dev->iobase + APCI3501_TIMER_SYNC_REG); | |
161 | } | |
c995fe94 ADG |
162 | |
163 | else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) { | |
9798df72 HS |
164 | data[0] = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1; |
165 | data[1] = inl(dev->iobase + APCI3501_TIMER_SYNC_REG); | |
166 | } | |
c995fe94 ADG |
167 | |
168 | else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER) | |
169 | && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) { | |
2292d64c | 170 | dev_err(dev->class_dev, "Invalid subdevice.\n"); |
c995fe94 ADG |
171 | } |
172 | return insn->n; | |
173 | } |