aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-01-23 18:51:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-25 15:15:53 -0500
commit1445ea1545e07faf91ce05c470024b4ee74f0251 (patch)
treef0e1f9f3bf5a34aac94586a632106f54a3337e7e
parent9901a4d75d007686e8f6473189cafc4b216b7449 (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/Kconfig1
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1516.c105
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
600config COMEDI_ADDI_APCI_1516 600config 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
60struct apci1516_boardinfo { 54struct apci1516_boardinfo {
61 const char *name; 55 const char *name;
@@ -86,7 +80,6 @@ static const struct apci1516_boardinfo apci1516_boardtypes[] = {
86 80
87struct apci1516_private { 81struct apci1516_private {
88 unsigned long wdog_iobase; 82 unsigned long wdog_iobase;
89 unsigned int ctrl;
90}; 83};
91 84
92static int apci1516_di_insn_bits(struct comedi_device *dev, 85static 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 */
133static 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
163static 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
185static 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
199static int apci1516_reset(struct comedi_device *dev) 116static 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
313static struct comedi_driver apci1516_driver = { 228static struct comedi_driver apci1516_driver = {