Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 304588
b: refs/heads/master
c: d79fc8e
h: refs/heads/master
v: v3
  • Loading branch information
H Hartley Sweeten authored and Greg Kroah-Hartman committed May 9, 2012
1 parent e4b77ba commit 076f91a
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 178 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: df61178c5159747be663a7a74116f1d68557fc5d
refs/heads/master: d79fc8e161c56626b67226198871c16aa0fcad15
279 changes: 102 additions & 177 deletions trunk/drivers/staging/comedi/drivers/icp_multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,6 @@ static const struct comedi_lrange range_analog = { 4, {

static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };

/*
==============================================================================
Forward declarations
==============================================================================
*/
static int icp_multi_attach(struct comedi_device *dev,
struct comedi_devconfig *it);
static int icp_multi_detach(struct comedi_device *dev);

/*
==============================================================================
Data & Structure declarations
Expand All @@ -154,48 +145,6 @@ struct boardtype {
const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */
};

static const struct boardtype boardtypes[] = {
{"icp_multi", /* Driver name */
DEVICE_ID, /* PCI device ID */
IORANGE_ICP_MULTI, /* I/O range length */
1, /* 1=Card supports interrupts */
TYPE_ICP_MULTI, /* Card type = ICP MULTI */
16, /* Num of A/D channels */
8, /* Num of A/D channels in diff mode */
4, /* Num of D/A channels */
16, /* Num of digital inputs */
8, /* Num of digital outputs */
4, /* Num of counters */
0x0fff, /* Resolution of A/D */
0x0fff, /* Resolution of D/A */
&range_analog, /* Rangelist for A/D */
range_codes_analog, /* Range codes for programming */
&range_analog}, /* Rangelist for D/A */
};

static struct comedi_driver driver_icp_multi = {
.driver_name = "icp_multi",
.module = THIS_MODULE,
.attach = icp_multi_attach,
.detach = icp_multi_detach,
.num_names = ARRAY_SIZE(boardtypes),
.board_name = &boardtypes[0].name,
.offset = sizeof(struct boardtype),
};

static int __init driver_icp_multi_init_module(void)
{
return comedi_driver_register(&driver_icp_multi);
}

static void __exit driver_icp_multi_cleanup_module(void)
{
comedi_driver_unregister(&driver_icp_multi);
}

module_init(driver_icp_multi_init_module);
module_exit(driver_icp_multi_cleanup_module);

struct icp_multi_private {
struct pcilst_struct *card; /* pointer to card */
char valid; /* card is usable */
Expand All @@ -220,25 +169,81 @@ struct icp_multi_private {

/*
==============================================================================
More forward declarations
Name: setup_channel_list
Description:
This function sets the appropriate channel selection,
differential input mode and range bits in the ADC Command/
Status register.
Parameters:
struct comedi_device *dev Pointer to current service structure
struct comedi_subdevice *s Pointer to current subdevice structure
unsigned int *chanlist Pointer to packed channel list
unsigned int n_chan Number of channels to scan
Returns:Void
==============================================================================
*/

#if 0
static int check_channel_list(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan);
#endif
static void setup_channel_list(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan);
static int icp_multi_reset(struct comedi_device *dev);
unsigned int *chanlist, unsigned int n_chan)
{
unsigned int i, range, chanprog;
unsigned int diff;

/*
==============================================================================
Functions
==============================================================================
*/
#ifdef ICP_MULTI_EXTDEBUG
printk(KERN_DEBUG
"icp multi EDBG: setup_channel_list(...,%d)\n", n_chan);
#endif
devpriv->act_chanlist_len = n_chan;
devpriv->act_chanlist_pos = 0;

for (i = 0; i < n_chan; i++) {
/* Get channel */
chanprog = CR_CHAN(chanlist[i]);

/* Determine if it is a differential channel (Bit 15 = 1) */
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
diff = 1;
chanprog &= 0x0007;
} else {
diff = 0;
chanprog &= 0x000f;
}

/* Clear channel, range and input mode bits
* in A/D command/status register */
devpriv->AdcCmdStatus &= 0xf00f;

/* Set channel number and differential mode status bit */
if (diff) {
/* Set channel number, bits 9-11 & mode, bit 6 */
devpriv->AdcCmdStatus |= (chanprog << 9);
devpriv->AdcCmdStatus |= ADC_DI;
} else
/* Set channel number, bits 8-11 */
devpriv->AdcCmdStatus |= (chanprog << 8);

/* Get range for current channel */
range = this_board->rangecode[CR_RANGE(chanlist[i])];
/* Set range. bits 4-5 */
devpriv->AdcCmdStatus |= range;

/* Output channel, range, mode to ICP Multi */
writew(devpriv->AdcCmdStatus,
devpriv->io_addr + ICP_MULTI_ADC_CSR);

#ifdef ICP_MULTI_EXTDEBUG
printk(KERN_DEBUG
"GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
devpriv->act_chanlist[i]);
#endif
}

}

/*
==============================================================================
Expand Down Expand Up @@ -762,84 +767,6 @@ static int check_channel_list(struct comedi_device *dev,
/*
==============================================================================
Name: setup_channel_list
Description:
This function sets the appropriate channel selection,
differential input mode and range bits in the ADC Command/
Status register.
Parameters:
struct comedi_device *dev Pointer to current service structure
struct comedi_subdevice *s Pointer to current subdevice structure
unsigned int *chanlist Pointer to packed channel list
unsigned int n_chan Number of channels to scan
Returns:Void
==============================================================================
*/
static void setup_channel_list(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan)
{
unsigned int i, range, chanprog;
unsigned int diff;

#ifdef ICP_MULTI_EXTDEBUG
printk(KERN_DEBUG
"icp multi EDBG: setup_channel_list(...,%d)\n", n_chan);
#endif
devpriv->act_chanlist_len = n_chan;
devpriv->act_chanlist_pos = 0;

for (i = 0; i < n_chan; i++) {
/* Get channel */
chanprog = CR_CHAN(chanlist[i]);

/* Determine if it is a differential channel (Bit 15 = 1) */
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
diff = 1;
chanprog &= 0x0007;
} else {
diff = 0;
chanprog &= 0x000f;
}

/* Clear channel, range and input mode bits
* in A/D command/status register */
devpriv->AdcCmdStatus &= 0xf00f;

/* Set channel number and differential mode status bit */
if (diff) {
/* Set channel number, bits 9-11 & mode, bit 6 */
devpriv->AdcCmdStatus |= (chanprog << 9);
devpriv->AdcCmdStatus |= ADC_DI;
} else
/* Set channel number, bits 8-11 */
devpriv->AdcCmdStatus |= (chanprog << 8);

/* Get range for current channel */
range = this_board->rangecode[CR_RANGE(chanlist[i])];
/* Set range. bits 4-5 */
devpriv->AdcCmdStatus |= range;

/* Output channel, range, mode to ICP Multi */
writew(devpriv->AdcCmdStatus,
devpriv->io_addr + ICP_MULTI_ADC_CSR);

#ifdef ICP_MULTI_EXTDEBUG
printk(KERN_DEBUG
"GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
devpriv->act_chanlist[i]);
#endif
}

}

/*
==============================================================================
Name: icp_multi_reset
Description:
Expand Down Expand Up @@ -895,23 +822,6 @@ static int icp_multi_reset(struct comedi_device *dev)
return 0;
}

/*
==============================================================================
Name: icp_multi_attach
Description:
This function sets up all the appropriate data for the current
device.
Parameters:
struct comedi_device *dev Pointer to current device structure
struct comedi_devconfig *it Pointer to current device configuration
Returns:int 0 = success
==============================================================================
*/
static int icp_multi_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
Expand Down Expand Up @@ -1097,25 +1007,8 @@ static int icp_multi_attach(struct comedi_device *dev,
return 0;
}

/*
==============================================================================
Name: icp_multi_detach
Description:
This function releases all the resources used by the current
device.
Parameters:
struct comedi_device *dev Pointer to current device structure
Returns:int 0 = success
==============================================================================
*/
static int icp_multi_detach(struct comedi_device *dev)
{

if (dev->private)
if (devpriv->valid)
icp_multi_reset(dev);
Expand All @@ -1135,6 +1028,38 @@ static int icp_multi_detach(struct comedi_device *dev)
return 0;
}

static const struct boardtype boardtypes[] = {
{
.name = "icp_multi",
.device_id = DEVICE_ID,
.iorange = IORANGE_ICP_MULTI,
.have_irq = 1,
.cardtype = TYPE_ICP_MULTI,
.n_aichan = 16,
.n_aichand = 8,
.n_aochan = 4,
.n_dichan = 16,
.n_dochan = 8,
.n_ctrs = 4,
.ai_maxdata = 0x0fff,
.ao_maxdata = 0x0fff,
.rangelist_ai = &range_analog,
.rangecode = range_codes_analog,
.rangelist_ao = &range_analog,
},
};

static struct comedi_driver icp_multi_driver = {
.driver_name = "icp_multi",
.module = THIS_MODULE,
.attach = icp_multi_attach,
.detach = icp_multi_detach,
.num_names = ARRAY_SIZE(boardtypes),
.board_name = &boardtypes[0].name,
.offset = sizeof(struct boardtype),
};
module_comedi_driver(icp_multi_driver);

MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");

0 comments on commit 076f91a

Please sign in to comment.