aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-01-30 17:23:27 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-31 04:40:41 -0500
commit2bdaef1afc15ae675a1d26e19d2b77bde215ef4a (patch)
tree2cf778a2cff894093589e3095a12e7b5d8d941a3
parent1f021e1f3b187586e457b4584d0e5f0f5ca5fa15 (diff)
staging: comedi: cb_das16_cs: convert to auto attach
Convert this pcmcia driver to the comedi auto attach mechanism. This allows getting rid of the "hack" needed to pass the pcmcia_device pointer from the pcmcia_driver to the comedi_driver. 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>
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c115
1 files changed, 49 insertions, 66 deletions
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index e253fc03cefa..efff05954133 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -40,9 +40,10 @@ Status: experimental
40 40
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include "../comedidev.h"
44#include <linux/delay.h> 43#include <linux/delay.h>
45 44
45#include "../comedidev.h"
46
46#include <pcmcia/cistpl.h> 47#include <pcmcia/cistpl.h>
47#include <pcmcia/ds.h> 48#include <pcmcia/ds.h>
48 49
@@ -89,8 +90,6 @@ struct das16cs_private {
89 unsigned short status2; 90 unsigned short status2;
90}; 91};
91 92
92static struct pcmcia_device *cur_dev;
93
94static const struct comedi_lrange das16cs_ai_range = { 93static const struct comedi_lrange das16cs_ai_range = {
95 4, { 94 4, {
96 BIP_RANGE(10), 95 BIP_RANGE(10),
@@ -383,45 +382,62 @@ static int das16cs_dio_insn_config(struct comedi_device *dev,
383 return insn->n; 382 return insn->n;
384} 383}
385 384
386static const struct das16cs_board *das16cs_probe(struct comedi_device *dev, 385static const void *das16cs_find_boardinfo(struct comedi_device *dev,
387 struct pcmcia_device *link) 386 struct pcmcia_device *link)
388{ 387{
388 const struct das16cs_board *board;
389 int i; 389 int i;
390 390
391 for (i = 0; i < ARRAY_SIZE(das16cs_boards); i++) { 391 for (i = 0; i < ARRAY_SIZE(das16cs_boards); i++) {
392 if (das16cs_boards[i].device_id == link->card_id) 392 board = &das16cs_boards[i];
393 return das16cs_boards + i; 393 if (board->device_id == link->card_id)
394 return board;
394 } 395 }
395 396
396 dev_dbg(dev->class_dev, "unknown board!\n");
397
398 return NULL; 397 return NULL;
399} 398}
400 399
401static int das16cs_attach(struct comedi_device *dev, 400static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
402 struct comedi_devconfig *it) 401 void *priv_data)
402{
403 if (p_dev->config_index == 0)
404 return -EINVAL;
405
406 return pcmcia_request_io(p_dev);
407}
408
409static int das16cs_auto_attach(struct comedi_device *dev,
410 unsigned long context)
403{ 411{
404 const struct das16cs_board *thisboard; 412 struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
413 const struct das16cs_board *board;
405 struct das16cs_private *devpriv; 414 struct das16cs_private *devpriv;
406 struct pcmcia_device *link;
407 struct comedi_subdevice *s; 415 struct comedi_subdevice *s;
408 int ret; 416 int ret;
409 417
410 link = cur_dev; /* XXX hack */ 418 board = das16cs_find_boardinfo(dev, link);
411 if (!link) 419 if (!board)
412 return -EIO; 420 return -ENODEV;
421 dev->board_ptr = board;
422 dev->board_name = board->name;
413 423
414 dev->board_ptr = das16cs_probe(dev, link); 424 /* Do we need to allocate an interrupt? */
415 if (!dev->board_ptr) 425 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
416 return -EIO;
417 thisboard = comedi_board(dev);
418 426
419 dev->board_name = thisboard->name; 427 ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
428 if (ret)
429 return ret;
430
431 if (!link->irq)
432 return -EINVAL;
420 433
434 ret = pcmcia_enable_device(link);
435 if (ret)
436 return ret;
421 dev->iobase = link->resource[0]->start; 437 dev->iobase = link->resource[0]->start;
422 438
423 ret = request_irq(link->irq, das16cs_interrupt, 439 ret = request_irq(link->irq, das16cs_interrupt, IRQF_SHARED,
424 IRQF_SHARED, "cb_das16_cs", dev); 440 dev->board_name, dev);
425 if (ret < 0) 441 if (ret < 0)
426 return ret; 442 return ret;
427 dev->irq = link->irq; 443 dev->irq = link->irq;
@@ -450,10 +466,10 @@ static int das16cs_attach(struct comedi_device *dev,
450 466
451 s = &dev->subdevices[1]; 467 s = &dev->subdevices[1];
452 /* analog output subdevice */ 468 /* analog output subdevice */
453 if (thisboard->n_ao_chans) { 469 if (board->n_ao_chans) {
454 s->type = COMEDI_SUBD_AO; 470 s->type = COMEDI_SUBD_AO;
455 s->subdev_flags = SDF_WRITABLE; 471 s->subdev_flags = SDF_WRITABLE;
456 s->n_chan = thisboard->n_ao_chans; 472 s->n_chan = board->n_ao_chans;
457 s->maxdata = 0xffff; 473 s->maxdata = 0xffff;
458 s->range_table = &range_bipolar10; 474 s->range_table = &range_bipolar10;
459 s->insn_write = &das16cs_ao_winsn; 475 s->insn_write = &das16cs_ao_winsn;
@@ -481,56 +497,24 @@ static int das16cs_attach(struct comedi_device *dev,
481 497
482static void das16cs_detach(struct comedi_device *dev) 498static void das16cs_detach(struct comedi_device *dev)
483{ 499{
500 struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
501
484 if (dev->irq) 502 if (dev->irq)
485 free_irq(dev->irq, dev); 503 free_irq(dev->irq, dev);
504 if (dev->iobase)
505 pcmcia_disable_device(link);
486} 506}
487 507
488static struct comedi_driver driver_das16cs = { 508static struct comedi_driver driver_das16cs = {
489 .driver_name = "cb_das16_cs", 509 .driver_name = "cb_das16_cs",
490 .module = THIS_MODULE, 510 .module = THIS_MODULE,
491 .attach = das16cs_attach, 511 .auto_attach = das16cs_auto_attach,
492 .detach = das16cs_detach, 512 .detach = das16cs_detach,
493}; 513};
494 514
495static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
496 void *priv_data)
497{
498 if (p_dev->config_index == 0)
499 return -EINVAL;
500
501 return pcmcia_request_io(p_dev);
502}
503
504static int das16cs_pcmcia_attach(struct pcmcia_device *link) 515static int das16cs_pcmcia_attach(struct pcmcia_device *link)
505{ 516{
506 int ret; 517 return comedi_pcmcia_auto_config(link, &driver_das16cs);
507
508 /* Do we need to allocate an interrupt? */
509 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
510
511 ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
512 if (ret)
513 goto failed;
514
515 if (!link->irq)
516 goto failed;
517
518 ret = pcmcia_enable_device(link);
519 if (ret)
520 goto failed;
521
522 cur_dev = link;
523 return 0;
524
525failed:
526 pcmcia_disable_device(link);
527 return ret;
528}
529
530static void das16cs_pcmcia_detach(struct pcmcia_device *link)
531{
532 pcmcia_disable_device(link);
533 cur_dev = NULL;
534} 518}
535 519
536static const struct pcmcia_device_id das16cs_id_table[] = { 520static const struct pcmcia_device_id das16cs_id_table[] = {
@@ -543,11 +527,10 @@ MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table);
543static struct pcmcia_driver das16cs_driver = { 527static struct pcmcia_driver das16cs_driver = {
544 .name = "cb_das16_cs", 528 .name = "cb_das16_cs",
545 .owner = THIS_MODULE, 529 .owner = THIS_MODULE,
546 .probe = das16cs_pcmcia_attach,
547 .remove = das16cs_pcmcia_detach,
548 .id_table = das16cs_id_table, 530 .id_table = das16cs_id_table,
531 .probe = das16cs_pcmcia_attach,
532 .remove = comedi_pcmcia_auto_unconfig,
549}; 533};
550
551module_comedi_pcmcia_driver(driver_das16cs, das16cs_driver); 534module_comedi_pcmcia_driver(driver_das16cs, das16cs_driver);
552 535
553MODULE_AUTHOR("David A. Schleef <ds@schleef.org>"); 536MODULE_AUTHOR("David A. Schleef <ds@schleef.org>");