static int das16cs_timer_insn_config(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
static int get_prodid(comedi_device * dev, struct pcmcia_device *link)
{
tuple_t tuple;
return prodid;
}
+#endif
static const das16cs_board *das16cs_probe(comedi_device * dev,
struct pcmcia_device *link)
int id;
int i;
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ id = link->card_id;
+#else
id = get_prodid(dev, link);
+#endif
for (i = 0; i < n_boards; i++) {
if (das16cs_boards[i].device_id == id) {
/* Initialize the pcmcia_device structure */
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+#endif
link->irq.Handler = NULL;
link->conf.Attributes = 0;
kfree(link->priv);
} /* das16cs_pcmcia_detach */
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->index == 0)
+ return -EINVAL;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
+
+ return 0;
+}
+#endif
+
static void das16cs_pcmcia_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
+ int last_ret;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
tuple_t tuple;
cisparse_t parse;
- int last_fn, last_ret;
+ int last_fn;
u_char buf[64];
cistpl_cftable_entry_t dflt = { 0 };
+#endif
DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
+ if (last_ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto cs_failed;
+ }
+#else
/*
This reads the card's CONFIG tuple to find its configuration
registers.
if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0)
goto cs_failed;
}
+#endif
/*
Allocate an interrupt line. Note that this does not assign a
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
last_fn = RequestIRQ;
+#endif
if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0)
goto cs_failed;
}
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
last_fn = RequestConfiguration;
+#endif
if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0)
goto cs_failed;
return;
cs_failed:
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
cs_error(link, last_fn, last_ret);
+#endif
das16cs_pcmcia_release(link);
} /* das16cs_pcmcia_config */
link->priv = local;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+#endif
link->irq.Handler = NULL;
/*
======================================================================*/
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->index == 0)
+ return -ENODEV;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
+ return 0;
+}
+#endif
+
static void das08_pcmcia_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
+ int last_ret;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
tuple_t tuple;
cisparse_t parse;
- int last_fn, last_ret;
+ int last_fn;
u_char buf[64];
cistpl_cftable_entry_t dflt = { 0 };
+#endif
DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
+ if (last_ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto cs_failed;
+ }
+#else
/*
This reads the card's CONFIG tuple to find its configuration
registers.
if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0)
goto cs_failed;
}
+#endif
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
last_fn = RequestIRQ;
+#endif
if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0)
goto cs_failed;
}
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
last_fn = RequestConfiguration;
+#endif
if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0)
goto cs_failed;
return;
cs_failed:
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
cs_error(link, last_fn, last_ret);
+#endif
das08_pcmcia_release(link);
} /* das08_pcmcia_config */
link->priv = local;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+#endif
link->irq.Handler = NULL;
/*
======================================================================*/
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ win_req_t *req = priv_data;
+ memreq_t map;
+
+ if (cfg->index == 0)
+ return -ENODEV;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+ p_dev->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ return -ENODEV;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+ req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req->Attributes |= WIN_ENABLE;
+ req->Base = mem->win[0].host_addr;
+ req->Size = mem->win[0].len;
+ if (req->Size < 0x1000)
+ req->Size = 0x1000;
+ req->AccessSpeed = 0;
+ if (pcmcia_request_window(p_dev, req, &p_dev->win))
+ return -ENODEV;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+ return -ENODEV;
+ }
+ /* If we got this far, we're cool! */
+ return 0;
+}
+#endif
+
static void dio700_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
+ int last_ret;
+ win_req_t req;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
tuple_t tuple;
cisparse_t parse;
- int last_ret;
+ int last_fn;
u_char buf[64];
- win_req_t req;
memreq_t map;
cistpl_cftable_entry_t dflt = { 0 };
+#endif
printk(KERN_INFO "ni_daq_700: cs-config\n");
DEBUG(0, "dio700_config(0x%p)\n", link);
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, &req);
+ if (last_ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto cs_failed;
+ }
+#else
/*
This reads the card's CONFIG tuple to find its configuration
registers.
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
+ last_fn = GetFirstTuple;
if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
- cs_error(link, GetFirstTuple, last_ret);
goto cs_failed;
}
+ last_fn = GetTupleData;
if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
- cs_error(link, GetTupleData, last_ret);
goto cs_failed;
}
+ last_fn = ParseTuple;
if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
- cs_error(link, ParseTuple, last_ret);
goto cs_failed;
}
link->conf.ConfigBase = parse.config.base;
will only use the CIS to fill in implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ last_fn = GetFirstTuple;
if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
- cs_error(link, GetFirstTuple, last_ret);
goto cs_failed;
}
while (1) {
break;
next_entry:
+ last_fn = GetNextTuple;
if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
- cs_error(link, GetNextTuple, last_ret);
goto cs_failed;
}
}
+#endif
/*
Allocate an interrupt line. Note that this does not assign a
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_fn = RequestIRQ;
+#endif
if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
- cs_error(link, RequestIRQ, last_ret);
goto cs_failed;
}
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_fn = RequestConfiguration;
+#endif
if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
- cs_error(link, RequestConfiguration, last_ret);
goto cs_failed;
}
return;
cs_failed:
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ cs_error(link, last_fn, last_ret);
+#endif
printk(KERN_INFO "ni_daq_700 cs failed");
dio700_release(link);
link->priv = local;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+#endif
link->irq.Handler = NULL;
/*
======================================================================*/
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ win_req_t *req = priv_data;
+ memreq_t map;
+
+ if (cfg->index == 0)
+ return -ENODEV;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+ p_dev->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ return -ENODEV;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+ req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req->Attributes |= WIN_ENABLE;
+ req->Base = mem->win[0].host_addr;
+ req->Size = mem->win[0].len;
+ if (req->Size < 0x1000)
+ req->Size = 0x1000;
+ req->AccessSpeed = 0;
+ if (pcmcia_request_window(p_dev, req, &p_dev->win))
+ return -ENODEV;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+ return -ENODEV;
+ }
+ /* If we got this far, we're cool! */
+ return 0;
+}
+#endif
+
static void dio24_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
+ int last_ret;
+ win_req_t req;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
tuple_t tuple;
cisparse_t parse;
- int last_ret;
+ int last_fn;
u_char buf[64];
- win_req_t req;
memreq_t map;
cistpl_cftable_entry_t dflt = { 0 };
+#endif
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
DEBUG(0, "dio24_config(0x%p)\n", link);
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, &req);
+ if (last_ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto cs_failed;
+ }
+#else
/*
This reads the card's CONFIG tuple to find its configuration
registers.
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
+ last_fn = GetFirstTuple;
if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
- cs_error(link, GetFirstTuple, last_ret);
goto cs_failed;
}
+ last_fn = GetTupleData;
if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
- cs_error(link, GetTupleData, last_ret);
goto cs_failed;
}
+ last_fn = ParseTuple;
if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
- cs_error(link, ParseTuple, last_ret);
goto cs_failed;
}
link->conf.ConfigBase = parse.config.base;
will only use the CIS to fill in implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ last_fn = GetFirstTuple;
if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
- cs_error(link, GetFirstTuple, last_ret);
goto cs_failed;
}
while (1) {
break;
next_entry:
+ last_fn = GetNextTuple;
if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
- cs_error(link, GetNextTuple, last_ret);
goto cs_failed;
}
}
+#endif
/*
Allocate an interrupt line. Note that this does not assign a
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_fn = RequestIRQ;
+#endif
if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
- cs_error(link, RequestIRQ, last_ret);
goto cs_failed;
}
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_fn = RequestConfiguration;
+#endif
if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
- cs_error(link, RequestConfiguration, last_ret);
goto cs_failed;
}
return;
cs_failed:
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ cs_error(link, last_fn, last_ret);
+#endif
printk(KERN_INFO "Fallo");
dio24_release(link);
link->priv = local;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID;
+#endif
link->irq.Handler = NULL;
/*
======================================================================*/
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ win_req_t *req = priv_data;
+ memreq_t map;
+
+ if (cfg->index == 0)
+ return -ENODEV;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+ p_dev->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ return -ENODEV;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+ req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req->Attributes |= WIN_ENABLE;
+ req->Base = mem->win[0].host_addr;
+ req->Size = mem->win[0].len;
+ if (req->Size < 0x1000)
+ req->Size = 0x1000;
+ req->AccessSpeed = 0;
+ if (pcmcia_request_window(p_dev, req, &p_dev->win))
+ return -ENODEV;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+ return -ENODEV;
+ }
+ /* If we got this far, we're cool! */
+ return 0;
+}
+#endif
+
static void labpc_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
+ int last_ret;
+ win_req_t req;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
tuple_t tuple;
cisparse_t parse;
- int last_ret;
+ int last_fn;
u_char buf[64];
- win_req_t req;
memreq_t map;
cistpl_cftable_entry_t dflt = { 0 };
+#endif
DEBUG(0, "labpc_config(0x%p)\n", link);
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, &req);
+ if (last_ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto cs_failed;
+ }
+#else
/*
This reads the card's CONFIG tuple to find its configuration
registers.
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
+ last_fn = GetFirstTuple;
if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
- cs_error(link, GetFirstTuple, last_ret);
goto cs_failed;
}
+ last_fn = GetTupleData;
if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
- cs_error(link, GetTupleData, last_ret);
goto cs_failed;
}
+ last_fn = ParseTuple;
if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
- cs_error(link, ParseTuple, last_ret);
goto cs_failed;
}
link->conf.ConfigBase = parse.config.base;
will only use the CIS to fill in implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ last_fn = GetFirstTuple;
if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
- cs_error(link, GetFirstTuple, last_ret);
goto cs_failed;
}
while (1) {
break;
next_entry:
+ last_fn = GetNextTuple;
if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
- cs_error(link, GetNextTuple, last_ret);
goto cs_failed;
}
}
+#endif
/*
Allocate an interrupt line. Note that this does not assign a
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_fn = RequestIRQ;
+#endif
if ((last_ret = pcmcia_request_irq(link, &link->irq))) {
- cs_error(link, RequestIRQ, last_ret);
goto cs_failed;
}
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_fn = RequestConfiguration;
+#endif
if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
- cs_error(link, RequestConfiguration, last_ret);
goto cs_failed;
}
return;
cs_failed:
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ cs_error(link, last_fn, last_ret);
+#endif
labpc_release(link);
} /* labpc_config */
{
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
link->io.NumPorts1 = 16;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+#endif
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return 0;
}
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ int base, ret;
+
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.NumPorts2 = 0;
+
+ for (base = 0x000; base < 0x400; base += 0x20) {
+ p_dev->io.BasePort1 = base;
+ ret = pcmcia_request_io(p_dev, &p_dev->io);
+ if (!ret)
+ return 0;
+ }
+ return -ENODEV;
+}
+#endif
+
static void mio_cs_config(struct pcmcia_device *link)
{
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
tuple_t tuple;
u_short buf[128];
cisparse_t parse;
int manfid = 0, prodid = 0;
+#endif
int ret;
DPRINTK("mio_cs_config(link=%p)\n", link);
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ return;
+ }
+#else
tuple.TupleData = (cisdata_t *) buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2;
+#endif
ret = pcmcia_request_irq(link, &link->irq);
if (ret) {
printk("pcmcia_request_irq() returned error: %i\n", ret);
}
//printk("RequestIRQ 0x%02x\n",ret);
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->conf.ConfigIndex = 1;
+#endif
ret = pcmcia_request_configuration(link, &link->conf);
//printk("RequestConfiguration %d\n",ret);
return 0;
}
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
static int get_prodid(comedi_device * dev, struct pcmcia_device *link)
{
tuple_t tuple;
return prodid;
}
+#endif
static int ni_getboardtype(comedi_device * dev, struct pcmcia_device *link)
{
int id;
int i;
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ id = link->card_id;
+#else
id = get_prodid(dev, link);
+#endif
for (i = 0; i < n_ni_boards; i++) {
if (ni_boards[i].device_id == id) {
* comedi kernel module, and signal various comedi callback routines,
* which run pretty quick.
*/
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+typedef irqreturn_t my_irqreturn_t;
+#define MY_IRQ_NONE IRQ_NONE
+#define MY_IRQ_HANDLED IRQ_HANDLED
+#define MY_IRQ_RETVAL(x) IRQ_RETVAL(x)
+#else
+typedef void my_irqreturn_t;
+#define MY_IRQ_NONE
+#define MY_IRQ_HANDLED
+#define MY_IRQ_RETVAL(x) ((void)(x))
+#endif
-static void daqp_interrupt(int irq, void *dev_id PT_REGS_ARG)
+static my_irqreturn_t daqp_interrupt(int irq, void *dev_id PT_REGS_ARG)
{
local_info_t *local = (local_info_t *) dev_id;
comedi_device *dev;
if (local == NULL) {
printk(KERN_WARNING
"daqp_interrupt(): irq %d for unknown device.\n", irq);
- return;
+ return MY_IRQ_NONE;
}
dev = local->dev;
if (dev == NULL) {
printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n");
- return;
+ return MY_IRQ_NONE;
}
if (!dev->attached) {
printk(KERN_WARNING
"daqp_interrupt(): comedi_device not yet attached.\n");
- return;
+ return MY_IRQ_NONE;
}
s = local->s;
if (s == NULL) {
printk(KERN_WARNING
"daqp_interrupt(): NULL comedi_subdevice.\n");
- return;
+ return MY_IRQ_NONE;
}
if ((local_info_t *) s->private != local) {
printk(KERN_WARNING
"daqp_interrupt(): invalid comedi_subdevice.\n");
- return;
+ return MY_IRQ_NONE;
}
switch (local->interrupt_mode) {
comedi_event(dev, s);
}
+ return MY_IRQ_HANDLED;
}
/* One-shot analog data acquisition routine */
{
int ret;
local_info_t *local = dev_table[it->options[0]];
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
tuple_t tuple;
int i;
+#endif
comedi_subdevice *s;
if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) {
strcpy(local->board_name, "DAQP");
dev->board_name = local->board_name;
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ if (local->link->prod_id[2]) {
+ if (strncmp(local->link->prod_id[2], "DAQP", 4) == 0) {
+ strncpy(local->board_name, local->link->prod_id[2],
+ sizeof(local->board_name));
+ }
+ }
+#else
tuple.DesiredTuple = CISTPL_VERS_1;
if (pcmcia_get_first_tuple(local->link, &tuple) == 0) {
u_char buf[128];
}
}
}
+#endif
dev->iobase = local->link->io.BasePort1;
link->priv = local;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+#endif
link->irq.Handler = daqp_interrupt;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
link->irq.Instance = local;
+#endif
/*
General socket configuration defaults can go here. In this
======================================================================*/
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->index == 0)
+ return -ENODEV;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ }
+
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+}
+#endif
+
static void daqp_cs_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
+ int last_ret;
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
tuple_t tuple;
cisparse_t parse;
- int last_ret;
+ int last_fn;
u_char buf[64];
+#endif
DEBUG(0, "daqp_cs_config(0x%p)\n", link);
+#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL);
+ if (last_ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto cs_failed;
+ }
+#else
/*
This reads the card's CONFIG tuple to find its configuration
registers.
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
+ last_fn = GetFirstTuple;
if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
- cs_error(link, GetFirstTuple, last_ret);
goto cs_failed;
}
+ last_fn = GetTupleData;
if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
- cs_error(link, GetTupleData, last_ret);
goto cs_failed;
}
+ last_fn = ParseTuple;
if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
- cs_error(link, ParseTuple, last_ret);
goto cs_failed;
}
link->conf.ConfigBase = parse.config.base;
will only use the CIS to fill in implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ last_fn = GetFirstTuple;
if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
- cs_error(link, GetFirstTuple, last_ret);
goto cs_failed;
}
while (1) {
break;
next_entry:
+ last_fn = GetNextTuple;
if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
- cs_error(link, GetNextTuple, last_ret);
goto cs_failed;
}
}
+#endif
/*
Allocate an interrupt line. Note that this does not assign a
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_fn = RequestIRQ;
+#endif
if ((last_ret = pcmcia_request_irq(link, &link->irq))) {
- cs_error(link, RequestIRQ, last_ret);
goto cs_failed;
}
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ last_fn = RequestConfiguration;
+#endif
if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
- cs_error(link, RequestConfiguration, last_ret);
goto cs_failed;
}
return;
cs_failed:
+#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE
+ cs_error(link, last_fn, last_ret);
+#endif
daqp_cs_release(link);
} /* daqp_cs_config */
fi
AM_CONDITIONAL([CONFIG_COMEDI_PCMCIA],[test "$USE_PCMCIA" = "yes"])
+COMEDI_CHECK_PCMCIA_LOOP_TUPLE([$LINUX_SRC_DIR],
+ [HAVE_PCMCIA_LOOP_TUPLE="yes"], [HAVE_PCMCIA_LOOP_TUPLE="no"])
+if test "$HAVE_PCMCIA_LOOP_TUPLE" = "yes" ; then
+ AC_DEFINE([CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE],[true],[Define if Linux kernel source has pcmcia_loop_tuple function])
+fi
+
AS_CHECK_LINUX_CONFIG_OPTION([CONFIG_USB],[HAVE_USB="yes"],[HAVE_USB="yes"],[HAVE_USB="no"])
AM_CONDITIONAL([CONFIG_USB],[test "$HAVE_USB" = "yes"])
AC_ARG_ENABLE([usb],[ --disable-usb Disable support for USB devices],
fi
])
+# COMEDI_CHECK_PCMCIA_LOOP_TUPLE([LINUX_SOURCE_PATH], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# -------------------------------------------------------------
+#
+# Check if kernel pcmcia support is new enough to have the pcmcia_loop_tuple
+# function.
+AC_DEFUN([COMEDI_CHECK_PCMCIA_LOOP_TUPLE],
+[
+ AC_MSG_CHECKING([$1 for pcmcia_loop_tuple function])
+ if [grep -q 'int[[:space:]]\+pcmcia_loop_tuple[[:space:]]*(' "$1/include/pcmcia/ds.h"] 2>/dev/null ; then
+ AC_MSG_RESULT([yes])
+ $2
+ else
+ AC_MSG_RESULT([no])
+ $3
+ fi
+])
+
# COMEDI_CHECK_HAVE_MUTEX_H([LINUX_SOURCE_PATH], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -------------------------------------------------------------
#