Commit 924f4685 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: refactor pcmda12 driver to remove forward declarations

Move the module_init/module_exit routines and the associated
struct comedi_driver and other variables to the end of the source.
This is more typical of how other drivers are written and removes
the need for the forward declarations.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Cc: Mori Hess <fmhess@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3496cb9f
......@@ -80,12 +80,6 @@ static const struct comedi_lrange pcmda12_ranges = {
}
};
static const struct pcmda12_board pcmda12_boards[] = {
{
.name = "pcmda12",
},
};
/*
* Useful for shorthand access to the particular board structure
*/
......@@ -99,57 +93,77 @@ struct pcmda12_private {
#define devpriv ((struct pcmda12_private *)(dev->private))
/*
* The struct comedi_driver structure tells the Comedi core module
* which functions to call to configure/deconfigure (attach/detach)
* the board, and also about the kernel module that contains
* the device code.
*/
static int pcmda12_attach(struct comedi_device *dev,
struct comedi_devconfig *it);
static int pcmda12_detach(struct comedi_device *dev);
static void zero_chans(struct comedi_device *dev)
{ /* sets up an
ASIC chip to defaults */
int i;
for (i = 0; i < CHANS; ++i) {
/* /\* do this as one instruction?? *\/ */
/* outw(0, LSB_PORT(chan)); */
outb(0, LSB_PORT(i));
outb(0, MSB_PORT(i));
}
inb(LSB_PORT(0)); /* update chans. */
}
static void zero_chans(struct comedi_device *dev);
static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
static struct comedi_driver driver = {
.driver_name = "pcmda12",
.module = THIS_MODULE,
.attach = pcmda12_attach,
.detach = pcmda12_detach,
/* It is not necessary to implement the following members if you are
* writing a driver for a ISA PnP or PCI card */
/* Most drivers will support multiple types of boards by
* having an array of board structures. These were defined
* in pcmda12_boards[] above. Note that the element 'name'
* was first in the structure -- Comedi uses this fact to
* extract the name of the board without knowing any details
* about the structure except for its length.
* When a device is attached (by comedi_config), the name
* of the device is given to Comedi, and Comedi tries to
* match it by going through the list of board names. If
* there is a match, the address of the pointer is put
* into dev->board_ptr and driver->attach() is called.
*
* Note that these are not necessary if you can determine
* the type of board in software. ISA PnP, PCI, and PCMCIA
* devices are such boards.
*/
.board_name = &pcmda12_boards[0].name,
.offset = sizeof(struct pcmda12_board),
.num_names = ARRAY_SIZE(pcmda12_boards),
};
/* Writing a list of values to an AO channel is probably not
* very useful, but that's how the interface is defined. */
for (i = 0; i < insn->n; ++i) {
static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data);
/* /\* do this as one instruction?? *\/ */
/* outw(data[i], LSB_PORT(chan)); */
/* Need to do this as two instructions due to 8-bit bus?? */
/* first, load the low byte */
outb(LSB(data[i]), LSB_PORT(chan));
/* next, write the high byte */
outb(MSB(data[i]), MSB_PORT(chan));
/* save shadow register */
devpriv->ao_readback[chan] = data[i];
if (!devpriv->simultaneous_xfer_mode)
inb(LSB_PORT(chan));
}
/* return the number of samples written */
return i;
}
/* AO subdevices should have a read insn as well as a write insn.
Usually this means copying a value stored in devpriv->ao_readback.
However, since this driver supports simultaneous xfer then sometimes
this function actually accomplishes work.
Simultaneaous xfer mode is accomplished by loading ALL the values
you want for AO in all the channels, then READing off one of the AO
registers to initiate the instantaneous simultaneous update of all
DAC outputs, which makes all AO channels update simultaneously.
This is useful for some control applications, I would imagine.
*/
static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data);
struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
for (i = 0; i < insn->n; i++) {
if (devpriv->simultaneous_xfer_mode)
inb(LSB_PORT(chan));
/* read back shadow register */
data[i] = devpriv->ao_readback[chan];
}
return i;
}
/*
* Attach is called by the Comedi core to configure the driver
* for a particular board. If you specified a board_name array
* in the driver structure, dev->board_ptr contains that
* address.
*/
static int pcmda12_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
......@@ -213,14 +227,6 @@ static int pcmda12_attach(struct comedi_device *dev,
return 1;
}
/*
* _detach is called to deconfigure a device. It should deallocate
* resources.
* This function is also called when _attach() fails, so it should be
* careful not to release resources that were not necessarily
* allocated by _attach(). dev->private and dev->subdevices are
* deallocated automatically by the core.
*/
static int pcmda12_detach(struct comedi_device *dev)
{
printk(KERN_INFO
......@@ -230,92 +236,32 @@ static int pcmda12_detach(struct comedi_device *dev)
return 0;
}
static void zero_chans(struct comedi_device *dev)
{ /* sets up an
ASIC chip to defaults */
int i;
for (i = 0; i < CHANS; ++i) {
/* /\* do this as one instruction?? *\/ */
/* outw(0, LSB_PORT(chan)); */
outb(0, LSB_PORT(i));
outb(0, MSB_PORT(i));
}
inb(LSB_PORT(0)); /* update chans. */
}
static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
/* Writing a list of values to an AO channel is probably not
* very useful, but that's how the interface is defined. */
for (i = 0; i < insn->n; ++i) {
/* /\* do this as one instruction?? *\/ */
/* outw(data[i], LSB_PORT(chan)); */
/* Need to do this as two instructions due to 8-bit bus?? */
/* first, load the low byte */
outb(LSB(data[i]), LSB_PORT(chan));
/* next, write the high byte */
outb(MSB(data[i]), MSB_PORT(chan));
/* save shadow register */
devpriv->ao_readback[chan] = data[i];
if (!devpriv->simultaneous_xfer_mode)
inb(LSB_PORT(chan));
}
/* return the number of samples written */
return i;
}
/* AO subdevices should have a read insn as well as a write insn.
Usually this means copying a value stored in devpriv->ao_readback.
However, since this driver supports simultaneous xfer then sometimes
this function actually accomplishes work.
Simultaneaous xfer mode is accomplished by loading ALL the values
you want for AO in all the channels, then READing off one of the AO
registers to initiate the instantaneous simultaneous update of all
DAC outputs, which makes all AO channels update simultaneously.
This is useful for some control applications, I would imagine.
*/
static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
for (i = 0; i < insn->n; i++) {
if (devpriv->simultaneous_xfer_mode)
inb(LSB_PORT(chan));
/* read back shadow register */
data[i] = devpriv->ao_readback[chan];
}
static const struct pcmda12_board pcmda12_boards[] = {
{
.name = "pcmda12",
},
};
return i;
}
static struct comedi_driver driver = {
.driver_name = "pcmda12",
.module = THIS_MODULE,
.attach = pcmda12_attach,
.detach = pcmda12_detach,
.board_name = &pcmda12_boards[0].name,
.offset = sizeof(struct pcmda12_board),
.num_names = ARRAY_SIZE(pcmda12_boards),
};
/*
* A convenient macro that defines init_module() and cleanup_module(),
* as necessary.
*/
static int __init driver_init_module(void)
{
return comedi_driver_register(&driver);
}
module_init(driver_init_module);
static void __exit driver_cleanup_module(void)
{
comedi_driver_unregister(&driver);
}
module_init(driver_init_module);
module_exit(driver_cleanup_module);
MODULE_AUTHOR("Comedi http://www.comedi.org");
......
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