Commit 2b70a4f4 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: addi_apci_3xxx: fix digital output 'insn_bits' function

This driver does not follow the comedi API. The digital output 'insn_bits'
function is passed a mask value in data[0] indicating which output bits in
data[1] are changing. The function is then supposed to update the outputs
accordingly and then return the current state of the outputs in data[1].

Fix the 'insn_bits' function so it works like the comedi core expects. The
core can then use the function to emulate the 'insn_read' and 'insn_write'
functions for individual channels.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 10f71c78
No related merge requests found
......@@ -1288,257 +1288,26 @@ static int apci3xxx_di_insn_bits(struct comedi_device *dev,
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| DIGITAL OUTPUT SUBDEVICE |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
| (struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Write the selected output mask and read the status from|
| all digital output channles |
+----------------------------------------------------------------------------+
| Input Parameters : dw_ChannelMask = data [0]; |
| dw_BitMask = data [1]; |
+----------------------------------------------------------------------------+
| Output Parameters : data[1] : All digital output channles states |
+----------------------------------------------------------------------------+
| Return Value : >0 : No error |
| -4 : Channel mask error |
| -101 : Data size error |
+----------------------------------------------------------------------------+
*/
static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_ChannelCpt = 0;
unsigned int dw_ChannelMask = 0;
unsigned int dw_BitMask = 0;
unsigned int dw_Status = 0;
/************************/
/* Test the buffer size */
/************************/
if (insn->n >= 2) {
/*******************************/
/* Get the channe and bit mask */
/*******************************/
dw_ChannelMask = data[0];
dw_BitMask = data[1];
/*************************/
/* Test the channel mask */
/*************************/
if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
/*********************************/
/* Test if set/reset any channel */
/*********************************/
if (dw_ChannelMask & 0xF) {
/********************************/
/* Read the digital output port */
/********************************/
dw_Status = inl(devpriv->iobase + 48);
for (b_ChannelCpt = 0; b_ChannelCpt < 4;
b_ChannelCpt++) {
if ((dw_ChannelMask >> b_ChannelCpt) &
1) {
dw_Status =
(dw_Status & (0xF -
(1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
}
}
outl(dw_Status, devpriv->iobase + 48);
}
/********************************/
/* Read the digital output port */
/********************************/
data[1] = inl(devpriv->iobase + 48);
} else {
/************************/
/* Config command error */
/************************/
printk("Channel mask error\n");
i_ReturnValue = -4;
}
} else {
/*******************/
/* Data size error */
/*******************/
printk("Buffer size error\n");
i_ReturnValue = -101;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
| (struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Set the state from digital output channel |
+----------------------------------------------------------------------------+
| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
| b_State = data [0] |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : >0 : No error |
| -3 : Channel selection error |
| -101 : Data size error |
+----------------------------------------------------------------------------+
*/
static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
static int apci3xxx_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_Channel = CR_CHAN(insn->chanspec);
unsigned char b_State = 0;
unsigned int dw_Status = 0;
/************************/
/* Test the buffer size */
/************************/
unsigned int mask = data[0];
unsigned int bits = data[1];
if (insn->n >= 1) {
/***************************/
/* Test the channel number */
/***************************/
if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
/*******************/
/* Get the command */
/*******************/
b_State = (unsigned char) data[0];
s->state = inl(devpriv->iobase + 48) & 0xf;
if (mask) {
s->state &= ~mask;
s->state |= (bits & mask);
/********************************/
/* Read the digital output port */
/********************************/
dw_Status = inl(devpriv->iobase + 48);
dw_Status =
(dw_Status & (0xF -
(1 << b_Channel))) | ((b_State & 1) <<
b_Channel);
outl(dw_Status, devpriv->iobase + 48);
} else {
/***************************/
/* Channel selection error */
/***************************/
printk("Channel selection error\n");
i_ReturnValue = -3;
}
} else {
/*******************/
/* Data size error */
/*******************/
printk("Buffer size error\n");
i_ReturnValue = -101;
outl(s->state, devpriv->iobase + 48);
}
return i_ReturnValue;
}
data[1] = s->state;
/*
+----------------------------------------------------------------------------+
| Function name :int i_APCI3XXX_InsnReadDigitalOutput |
| (struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Read the state from digital output channel |
+----------------------------------------------------------------------------+
| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
+----------------------------------------------------------------------------+
| Output Parameters : b_State = data [0] |
+----------------------------------------------------------------------------+
| Return Value : >0 : No error |
| -3 : Channel selection error |
| -101 : Data size error |
+----------------------------------------------------------------------------+
*/
static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_Channel = CR_CHAN(insn->chanspec);
unsigned int dw_Status = 0;
/************************/
/* Test the buffer size */
/************************/
if (insn->n >= 1) {
/***************************/
/* Test the channel number */
/***************************/
if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
/********************************/
/* Read the digital output port */
/********************************/
dw_Status = inl(devpriv->iobase + 48);
dw_Status = (dw_Status >> b_Channel) & 1;
*data = dw_Status;
} else {
/***************************/
/* Channel selection error */
/***************************/
printk("Channel selection error\n");
i_ReturnValue = -3;
}
} else {
/*******************/
/* Data size error */
/*******************/
printk("Buffer size error\n");
i_ReturnValue = -101;
}
return i_ReturnValue;
return insn->n;
}
/*
......
......@@ -191,9 +191,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -224,9 +222,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -257,9 +253,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -290,9 +284,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -323,9 +315,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -356,9 +346,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -513,9 +501,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -550,9 +536,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -587,9 +571,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -624,9 +606,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
.ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
......@@ -655,9 +635,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
}, {
.pc_DriverName = "apci3002-16",
.i_VendorId = PCI_VENDOR_ID_ADDIDATA,
......@@ -682,9 +660,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
}, {
.pc_DriverName = "apci3002-8",
.i_VendorId = PCI_VENDOR_ID_ADDIDATA,
......@@ -709,9 +685,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
}, {
.pc_DriverName = "apci3002-4",
.i_VendorId = PCI_VENDOR_ID_ADDIDATA,
......@@ -736,9 +710,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_config = i_APCI3XXX_InsnConfigAnalogInput,
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_write = i_APCI3XXX_InsnWriteDigitalOutput,
.do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
.do_read = i_APCI3XXX_InsnReadDigitalOutput,
.do_bits = apci3xxx_do_insn_bits,
}, {
.pc_DriverName = "apci3500",
.i_VendorId = PCI_VENDOR_ID_ADDIDATA,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment