aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-04-22 21:33:22 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-23 13:41:38 -0400
commit0a8fc08910cfec7713801b7097e9a31c960339b8 (patch)
tree14e26bb698161d1496dbe27e4182268a063af1f0
parentfe9b0850ab8f6f5a91a170cca07d24a2afb4ceb9 (diff)
staging: comedi: das800: introduce das800_ind_{write, read}()
The GAS800_GAIN register contains some bits that enable indirect writing to additional registers on the board through iobase + 2 and indirect reading of addition registers through iobase + 7. Introduce some helper functions to handle the indirect register write/read. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/comedi/drivers/das800.c62
1 files changed, 39 insertions, 23 deletions
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index 18e2ac02aff1..bc8a23e8a5d7 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -228,6 +228,27 @@ struct das800_private {
228 volatile int do_bits; /* digital output bits */ 228 volatile int do_bits; /* digital output bits */
229}; 229};
230 230
231static void das800_ind_write(struct comedi_device *dev,
232 unsigned val, unsigned reg)
233{
234 /*
235 * Select dev->iobase + 2 to be desired register
236 * then write to that register.
237 */
238 outb(reg, dev->iobase + DAS800_GAIN);
239 outb(val, dev->iobase + 2);
240}
241
242static unsigned das800_ind_read(struct comedi_device *dev, unsigned reg)
243{
244 /*
245 * Select dev->iobase + 7 to be desired register
246 * then read from that register.
247 */
248 outb(reg, dev->iobase + DAS800_GAIN);
249 return inb(dev->iobase + 7);
250}
251
231/* enable_das800 makes the card start taking hardware triggered conversions */ 252/* enable_das800 makes the card start taking hardware triggered conversions */
232static void enable_das800(struct comedi_device *dev) 253static void enable_das800(struct comedi_device *dev)
233{ 254{
@@ -239,10 +260,10 @@ static void enable_das800(struct comedi_device *dev)
239 /* enable fifo-half full interrupts for cio-das802/16 */ 260 /* enable fifo-half full interrupts for cio-das802/16 */
240 if (thisboard->resolution == 16) 261 if (thisboard->resolution == 16)
241 outb(CIO_ENHF, dev->iobase + DAS800_GAIN); 262 outb(CIO_ENHF, dev->iobase + DAS800_GAIN);
242 outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */ 263 /* enable hardware triggering */
243 outb(CONV_HCEN, dev->iobase + DAS800_CONV_CONTROL); /* enable hardware triggering */ 264 das800_ind_write(dev, CONV_HCEN, CONV_CONTROL);
244 outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */ 265 /* enable card's interrupt */
245 outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1); /* enable card's interrupt */ 266 das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1);
246 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 267 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
247} 268}
248 269
@@ -250,9 +271,10 @@ static void enable_das800(struct comedi_device *dev)
250static void disable_das800(struct comedi_device *dev) 271static void disable_das800(struct comedi_device *dev)
251{ 272{
252 unsigned long irq_flags; 273 unsigned long irq_flags;
274
253 spin_lock_irqsave(&dev->spinlock, irq_flags); 275 spin_lock_irqsave(&dev->spinlock, irq_flags);
254 outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */ 276 /* disable hardware triggering of conversions */
255 outb(0x0, dev->iobase + DAS800_CONV_CONTROL); /* disable hardware triggering of conversions */ 277 das800_ind_write(dev, 0x0, CONV_CONTROL);
256 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 278 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
257} 279}
258 280
@@ -398,8 +420,8 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
398 scan = (endChan << 3) | startChan; 420 scan = (endChan << 3) | startChan;
399 421
400 spin_lock_irqsave(&dev->spinlock, irq_flags); 422 spin_lock_irqsave(&dev->spinlock, irq_flags);
401 outb(SCAN_LIMITS, dev->iobase + DAS800_GAIN); /* select base address + 2 to be scan limits register */ 423 /* set scan limits */
402 outb(scan, dev->iobase + DAS800_SCAN_LIMITS); /* set scan limits */ 424 das800_ind_write(dev, scan, SCAN_LIMITS);
403 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 425 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
404 426
405 /* set gain */ 427 /* set gain */
@@ -450,9 +472,9 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
450 } 472 }
451 473
452 spin_lock_irqsave(&dev->spinlock, irq_flags); 474 spin_lock_irqsave(&dev->spinlock, irq_flags);
453 outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */ 475 das800_ind_write(dev, conv_bits, CONV_CONTROL);
454 outb(conv_bits, dev->iobase + DAS800_CONV_CONTROL);
455 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 476 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
477
456 async->events = 0; 478 async->events = 0;
457 enable_das800(dev); 479 enable_das800(dev);
458 return 0; 480 return 0;
@@ -488,8 +510,7 @@ static irqreturn_t das800_interrupt(int irq, void *d)
488 510
489 /* if hardware conversions are not enabled, then quit */ 511 /* if hardware conversions are not enabled, then quit */
490 spin_lock_irqsave(&dev->spinlock, irq_flags); 512 spin_lock_irqsave(&dev->spinlock, irq_flags);
491 outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select base address + 7 to be STATUS2 register */ 513 status = das800_ind_read(dev, CONTROL1) & STATUS2_HCEN;
492 status = inb(dev->iobase + DAS800_STATUS2) & STATUS2_HCEN;
493 /* don't release spinlock yet since we want to make sure no one else disables hardware conversions */ 514 /* don't release spinlock yet since we want to make sure no one else disables hardware conversions */
494 if (status == 0) { 515 if (status == 0) {
495 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 516 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
@@ -542,9 +563,8 @@ static irqreturn_t das800_interrupt(int irq, void *d)
542 if (devpriv->count > 0 || devpriv->forever == 1) { 563 if (devpriv->count > 0 || devpriv->forever == 1) {
543 /* Re-enable card's interrupt. 564 /* Re-enable card's interrupt.
544 * We already have spinlock, so indirect addressing is safe */ 565 * We already have spinlock, so indirect addressing is safe */
545 outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */ 566 das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits,
546 outb(CONTROL1_INTE | devpriv->do_bits, 567 CONTROL1);
547 dev->iobase + DAS800_CONTROL1);
548 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 568 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
549 /* otherwise, stop taking data */ 569 /* otherwise, stop taking data */
550 } else { 570 } else {
@@ -576,8 +596,7 @@ static int das800_ai_rinsn(struct comedi_device *dev,
576 chan = CR_CHAN(insn->chanspec); 596 chan = CR_CHAN(insn->chanspec);
577 597
578 spin_lock_irqsave(&dev->spinlock, irq_flags); 598 spin_lock_irqsave(&dev->spinlock, irq_flags);
579 outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */ 599 das800_ind_write(dev, chan | devpriv->do_bits, CONTROL1);
580 outb(chan | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
581 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 600 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
582 601
583 /* set gain / range */ 602 /* set gain / range */
@@ -644,8 +663,7 @@ static int das800_do_wbits(struct comedi_device *dev,
644 devpriv->do_bits = wbits << 4; 663 devpriv->do_bits = wbits << 4;
645 664
646 spin_lock_irqsave(&dev->spinlock, irq_flags); 665 spin_lock_irqsave(&dev->spinlock, irq_flags);
647 outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */ 666 das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1);
648 outb(devpriv->do_bits | CONTROL1_INTE, dev->iobase + DAS800_CONTROL1);
649 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 667 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
650 668
651 data[1] = wbits; 669 data[1] = wbits;
@@ -661,8 +679,7 @@ static int das800_probe(struct comedi_device *dev)
661 int board; 679 int board;
662 680
663 spin_lock_irqsave(&dev->spinlock, irq_flags); 681 spin_lock_irqsave(&dev->spinlock, irq_flags);
664 outb(ID, dev->iobase + DAS800_GAIN); 682 id_bits = das800_ind_read(dev, ID) & 0x3;
665 id_bits = inb(dev->iobase + DAS800_ID) & 0x3;
666 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 683 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
667 684
668 board = thisboard - das800_boards; 685 board = thisboard - das800_boards;
@@ -801,8 +818,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
801 818
802 /* initialize digital out channels */ 819 /* initialize digital out channels */
803 spin_lock_irqsave(&dev->spinlock, irq_flags); 820 spin_lock_irqsave(&dev->spinlock, irq_flags);
804 outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */ 821 das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1);
805 outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
806 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 822 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
807 823
808 return 0; 824 return 0;