diff options
author | H Hartley Sweeten <hsweeten@visionengravers.com> | 2013-01-23 18:51:01 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-25 15:15:53 -0500 |
commit | 1445ea1545e07faf91ce05c470024b4ee74f0251 (patch) | |
tree | f0e1f9f3bf5a34aac94586a632106f54a3337e7e | |
parent | 9901a4d75d007686e8f6473189cafc4b216b7449 (diff) |
staging: comedi: addi_apci_1516: use addi_watchdog module
Use the addi_watchdog module to provide support for the watchdog
subdevice.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/comedi/Kconfig | 1 | ||||
-rw-r--r-- | drivers/staging/comedi/drivers/addi_apci_1516.c | 105 |
2 files changed, 11 insertions, 95 deletions
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 815c20a13248..4c80ac935ee2 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig | |||
@@ -599,6 +599,7 @@ config COMEDI_ADDI_APCI_1500 | |||
599 | 599 | ||
600 | config COMEDI_ADDI_APCI_1516 | 600 | config COMEDI_ADDI_APCI_1516 |
601 | tristate "ADDI-DATA APCI-1016/1516/2016 support" | 601 | tristate "ADDI-DATA APCI-1016/1516/2016 support" |
602 | select COMEDI_ADDI_WATCHDOG | ||
602 | ---help--- | 603 | ---help--- |
603 | Enable support for ADDI-DATA APCI-1016, APCI-1516 and APCI-2016 boards. | 604 | Enable support for ADDI-DATA APCI-1016, APCI-1516 and APCI-2016 boards. |
604 | These are 16 channel, optically isolated, digital I/O boards. The 1516 | 605 | These are 16 channel, optically isolated, digital I/O boards. The 1516 |
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 0911516a220c..1721ba7f4e53 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c | |||
@@ -30,6 +30,7 @@ | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include "../comedidev.h" | 32 | #include "../comedidev.h" |
33 | #include "addi_watchdog.h" | ||
33 | #include "comedi_fc.h" | 34 | #include "comedi_fc.h" |
34 | 35 | ||
35 | /* | 36 | /* |
@@ -49,13 +50,6 @@ | |||
49 | * PCI bar 2 I/O Register map - Watchdog (APCI-1516 and APCI-2016) | 50 | * PCI bar 2 I/O Register map - Watchdog (APCI-1516 and APCI-2016) |
50 | */ | 51 | */ |
51 | #define APCI1516_WDOG_REG 0x00 | 52 | #define APCI1516_WDOG_REG 0x00 |
52 | #define APCI1516_WDOG_RELOAD_REG 0x04 | ||
53 | #define APCI1516_WDOG_CTRL_REG 0x0c | ||
54 | #define APCI1516_WDOG_CTRL_ENABLE (1 << 0) | ||
55 | #define APCI1516_WDOG_CTRL_SW_TRIG (1 << 9) | ||
56 | #define APCI1516_WDOG_STATUS_REG 0x10 | ||
57 | #define APCI1516_WDOG_STATUS_ENABLED (1 << 0) | ||
58 | #define APCI1516_WDOG_STATUS_SW_TRIG (1 << 1) | ||
59 | 53 | ||
60 | struct apci1516_boardinfo { | 54 | struct apci1516_boardinfo { |
61 | const char *name; | 55 | const char *name; |
@@ -86,7 +80,6 @@ static const struct apci1516_boardinfo apci1516_boardtypes[] = { | |||
86 | 80 | ||
87 | struct apci1516_private { | 81 | struct apci1516_private { |
88 | unsigned long wdog_iobase; | 82 | unsigned long wdog_iobase; |
89 | unsigned int ctrl; | ||
90 | }; | 83 | }; |
91 | 84 | ||
92 | static int apci1516_di_insn_bits(struct comedi_device *dev, | 85 | static int apci1516_di_insn_bits(struct comedi_device *dev, |
@@ -120,82 +113,6 @@ static int apci1516_do_insn_bits(struct comedi_device *dev, | |||
120 | return insn->n; | 113 | return insn->n; |
121 | } | 114 | } |
122 | 115 | ||
123 | /* | ||
124 | * The watchdog subdevice is configured with two INSN_CONFIG instructions: | ||
125 | * | ||
126 | * Enable the watchdog and set the reload timeout: | ||
127 | * data[0] = INSN_CONFIG_ARM | ||
128 | * data[1] = timeout reload value | ||
129 | * | ||
130 | * Disable the watchdog: | ||
131 | * data[0] = INSN_CONFIG_DISARM | ||
132 | */ | ||
133 | static int apci1516_wdog_insn_config(struct comedi_device *dev, | ||
134 | struct comedi_subdevice *s, | ||
135 | struct comedi_insn *insn, | ||
136 | unsigned int *data) | ||
137 | { | ||
138 | struct apci1516_private *devpriv = dev->private; | ||
139 | unsigned int reload; | ||
140 | |||
141 | switch (data[0]) { | ||
142 | case INSN_CONFIG_ARM: | ||
143 | devpriv->ctrl = APCI1516_WDOG_CTRL_ENABLE; | ||
144 | reload = data[1] & s->maxdata; | ||
145 | outw(reload, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG); | ||
146 | |||
147 | /* Time base is 20ms, let the user know the timeout */ | ||
148 | dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n", | ||
149 | 20 * reload + 20); | ||
150 | break; | ||
151 | case INSN_CONFIG_DISARM: | ||
152 | devpriv->ctrl = 0; | ||
153 | break; | ||
154 | default: | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | outw(devpriv->ctrl, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); | ||
159 | |||
160 | return insn->n; | ||
161 | } | ||
162 | |||
163 | static int apci1516_wdog_insn_write(struct comedi_device *dev, | ||
164 | struct comedi_subdevice *s, | ||
165 | struct comedi_insn *insn, | ||
166 | unsigned int *data) | ||
167 | { | ||
168 | struct apci1516_private *devpriv = dev->private; | ||
169 | int i; | ||
170 | |||
171 | if (devpriv->ctrl == 0) { | ||
172 | dev_warn(dev->class_dev, "watchdog is disabled\n"); | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | |||
176 | /* "ping" the watchdog */ | ||
177 | for (i = 0; i < insn->n; i++) { | ||
178 | outw(devpriv->ctrl | APCI1516_WDOG_CTRL_SW_TRIG, | ||
179 | devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); | ||
180 | } | ||
181 | |||
182 | return insn->n; | ||
183 | } | ||
184 | |||
185 | static int apci1516_wdog_insn_read(struct comedi_device *dev, | ||
186 | struct comedi_subdevice *s, | ||
187 | struct comedi_insn *insn, | ||
188 | unsigned int *data) | ||
189 | { | ||
190 | struct apci1516_private *devpriv = dev->private; | ||
191 | int i; | ||
192 | |||
193 | for (i = 0; i < insn->n; i++) | ||
194 | data[i] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG); | ||
195 | |||
196 | return insn->n; | ||
197 | } | ||
198 | |||
199 | static int apci1516_reset(struct comedi_device *dev) | 116 | static int apci1516_reset(struct comedi_device *dev) |
200 | { | 117 | { |
201 | const struct apci1516_boardinfo *this_board = comedi_board(dev); | 118 | const struct apci1516_boardinfo *this_board = comedi_board(dev); |
@@ -205,8 +122,8 @@ static int apci1516_reset(struct comedi_device *dev) | |||
205 | return 0; | 122 | return 0; |
206 | 123 | ||
207 | outw(0x0, dev->iobase + APCI1516_DO_REG); | 124 | outw(0x0, dev->iobase + APCI1516_DO_REG); |
208 | outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); | 125 | |
209 | outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG); | 126 | addi_watchdog_reset(devpriv->wdog_iobase); |
210 | 127 | ||
211 | return 0; | 128 | return 0; |
212 | } | 129 | } |
@@ -285,13 +202,9 @@ static int apci1516_auto_attach(struct comedi_device *dev, | |||
285 | /* Initialize the watchdog subdevice */ | 202 | /* Initialize the watchdog subdevice */ |
286 | s = &dev->subdevices[2]; | 203 | s = &dev->subdevices[2]; |
287 | if (this_board->has_wdog) { | 204 | if (this_board->has_wdog) { |
288 | s->type = COMEDI_SUBD_TIMER; | 205 | ret = addi_watchdog_init(s, devpriv->wdog_iobase); |
289 | s->subdev_flags = SDF_WRITEABLE; | 206 | if (ret) |
290 | s->n_chan = 1; | 207 | return ret; |
291 | s->maxdata = 0xff; | ||
292 | s->insn_write = apci1516_wdog_insn_write; | ||
293 | s->insn_read = apci1516_wdog_insn_read; | ||
294 | s->insn_config = apci1516_wdog_insn_config; | ||
295 | } else { | 208 | } else { |
296 | s->type = COMEDI_SUBD_UNUSED; | 209 | s->type = COMEDI_SUBD_UNUSED; |
297 | } | 210 | } |
@@ -304,10 +217,12 @@ static void apci1516_detach(struct comedi_device *dev) | |||
304 | { | 217 | { |
305 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); | 218 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); |
306 | 219 | ||
307 | if (dev->iobase) { | 220 | if (dev->iobase) |
308 | apci1516_reset(dev); | 221 | apci1516_reset(dev); |
222 | if (dev->subdevices) | ||
223 | addi_watchdog_cleanup(&dev->subdevices[2]); | ||
224 | if (dev->iobase) | ||
309 | comedi_pci_disable(pcidev); | 225 | comedi_pci_disable(pcidev); |
310 | } | ||
311 | } | 226 | } |
312 | 227 | ||
313 | static struct comedi_driver apci1516_driver = { | 228 | static struct comedi_driver apci1516_driver = { |