mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-01 00:36:40 +09:00
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: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
10f71c7845
commit
2b70a4f4f9
@@ -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)
|
||||
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_ChannelCpt = 0;
|
||||
unsigned int dw_ChannelMask = 0;
|
||||
unsigned int dw_BitMask = 0;
|
||||
unsigned int dw_Status = 0;
|
||||
unsigned int mask = data[0];
|
||||
unsigned int bits = data[1];
|
||||
|
||||
/************************/
|
||||
/* Test the buffer size */
|
||||
/************************/
|
||||
s->state = inl(devpriv->iobase + 48) & 0xf;
|
||||
if (mask) {
|
||||
s->state &= ~mask;
|
||||
s->state |= (bits & mask);
|
||||
|
||||
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;
|
||||
outl(s->state, devpriv->iobase + 48);
|
||||
}
|
||||
|
||||
return i_ReturnValue;
|
||||
}
|
||||
data[1] = s->state;
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| 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)
|
||||
{
|
||||
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 */
|
||||
/************************/
|
||||
|
||||
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];
|
||||
|
||||
/********************************/
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return i_ReturnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| 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,
|
||||
|
||||
Reference in New Issue
Block a user