aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/drivers/comedi_parport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/comedi_parport.c')
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c86
1 files changed, 39 insertions, 47 deletions
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index 9a63cac2434..22ef9424259 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -85,6 +85,8 @@ pin, which can be used to wake up tasks.
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include "comedi_fc.h"
+
#define PARPORT_SIZE 3
#define PARPORT_A 0
@@ -96,11 +98,12 @@ struct parport_private {
unsigned int c_data;
int enable_irq;
};
-#define devpriv ((struct parport_private *)(dev->private))
static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct parport_private *devpriv = dev->private;
+
if (data[0]) {
devpriv->a_data &= ~data[0];
devpriv->a_data |= (data[0] & data[1]);
@@ -117,6 +120,8 @@ static int parport_insn_config_a(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct parport_private *devpriv = dev->private;
+
if (data[0]) {
s->io_bits = 0xff;
devpriv->c_data &= ~(1 << 5);
@@ -145,6 +150,8 @@ static int parport_insn_b(struct comedi_device *dev, struct comedi_subdevice *s,
static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct parport_private *devpriv = dev->private;
+
data[0] &= 0x0f;
if (data[0]) {
devpriv->c_data &= ~data[0];
@@ -171,39 +178,20 @@ static int parport_intr_cmdtest(struct comedi_device *dev,
struct comedi_cmd *cmd)
{
int err = 0;
- int tmp;
-
- /* step 1 */
- tmp = cmd->start_src;
- cmd->start_src &= TRIG_NOW;
- if (!cmd->start_src || tmp != cmd->start_src)
- err++;
+ /* Step 1 : check if triggers are trivially valid */
- tmp = cmd->scan_begin_src;
- cmd->scan_begin_src &= TRIG_EXT;
- if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
- err++;
-
- tmp = cmd->convert_src;
- cmd->convert_src &= TRIG_FOLLOW;
- if (!cmd->convert_src || tmp != cmd->convert_src)
- err++;
-
- tmp = cmd->scan_end_src;
- cmd->scan_end_src &= TRIG_COUNT;
- if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
- err++;
-
- tmp = cmd->stop_src;
- cmd->stop_src &= TRIG_NONE;
- if (!cmd->stop_src || tmp != cmd->stop_src)
- err++;
+ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
if (err)
return 1;
- /* step 2: ignored */
+ /* Step 2a : make sure trigger sources are unique */
+ /* Step 2b : and mutually compatible */
if (err)
return 2;
@@ -245,6 +233,8 @@ static int parport_intr_cmdtest(struct comedi_device *dev,
static int parport_intr_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct parport_private *devpriv = dev->private;
+
devpriv->c_data |= 0x10;
outb(devpriv->c_data, dev->iobase + PARPORT_C);
@@ -256,7 +246,7 @@ static int parport_intr_cmd(struct comedi_device *dev,
static int parport_intr_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- printk(KERN_DEBUG "parport_intr_cancel()\n");
+ struct parport_private *devpriv = dev->private;
devpriv->c_data &= ~0x10;
outb(devpriv->c_data, dev->iobase + PARPORT_C);
@@ -269,12 +259,11 @@ static int parport_intr_cancel(struct comedi_device *dev,
static irqreturn_t parport_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->subdevices + 3;
+ struct parport_private *devpriv = dev->private;
+ struct comedi_subdevice *s = &dev->subdevices[3];
- if (!devpriv->enable_irq) {
- printk(KERN_ERR "comedi_parport: bogus irq, ignored\n");
+ if (!devpriv->enable_irq)
return IRQ_NONE;
- }
comedi_buf_put(s->async, 0);
s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
@@ -286,41 +275,42 @@ static irqreturn_t parport_interrupt(int irq, void *d)
static int parport_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ struct parport_private *devpriv;
int ret;
unsigned int irq;
unsigned long iobase;
struct comedi_subdevice *s;
+ dev->board_name = dev->driver->driver_name;
+
iobase = it->options[0];
- printk(KERN_INFO "comedi%d: parport: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, PARPORT_SIZE, "parport (comedi)")) {
- printk(KERN_ERR "I/O port conflict\n");
+ if (!request_region(iobase, PARPORT_SIZE, dev->board_name)) {
+ dev_err(dev->class_dev, "I/O port conflict\n");
return -EIO;
}
dev->iobase = iobase;
irq = it->options[1];
if (irq) {
- printk(KERN_INFO " irq=%u", irq);
- ret = request_irq(irq, parport_interrupt, 0, "comedi_parport",
+ ret = request_irq(irq, parport_interrupt, 0, dev->board_name,
dev);
if (ret < 0) {
- printk(KERN_ERR " irq not available\n");
+ dev_err(dev->class_dev, "irq not available\n");
return -EINVAL;
}
dev->irq = irq;
}
- dev->board_name = "parport";
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(struct parport_private));
+ ret = alloc_private(dev, sizeof(*devpriv));
if (ret < 0)
return ret;
+ devpriv = dev->private;
- s = dev->subdevices + 0;
+ s = &dev->subdevices[0];
s->type = COMEDI_SUBD_DIO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
s->n_chan = 8;
@@ -329,7 +319,7 @@ static int parport_attach(struct comedi_device *dev,
s->insn_bits = parport_insn_a;
s->insn_config = parport_insn_config_a;
- s = dev->subdevices + 1;
+ s = &dev->subdevices[1];
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE;
s->n_chan = 5;
@@ -337,7 +327,7 @@ static int parport_attach(struct comedi_device *dev,
s->range_table = &range_digital;
s->insn_bits = parport_insn_b;
- s = dev->subdevices + 2;
+ s = &dev->subdevices[2];
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITABLE;
s->n_chan = 4;
@@ -345,7 +335,7 @@ static int parport_attach(struct comedi_device *dev,
s->range_table = &range_digital;
s->insn_bits = parport_insn_c;
- s = dev->subdevices + 3;
+ s = &dev->subdevices[3];
if (irq) {
dev->read_subdev = s;
s->type = COMEDI_SUBD_DI;
@@ -366,8 +356,10 @@ static int parport_attach(struct comedi_device *dev,
devpriv->c_data = 0;
outb(devpriv->c_data, dev->iobase + PARPORT_C);
- printk(KERN_INFO "\n");
- return 1;
+ dev_info(dev->class_dev, "%s: iobase=0x%04lx, irq %sabled",
+ dev->board_name, dev->iobase, dev->irq ? "en" : "dis");
+
+ return 0;
}
static void parport_detach(struct comedi_device *dev)