diff options
author | H Hartley Sweeten <hsweeten@visionengravers.com> | 2013-04-22 21:33:22 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-23 13:41:38 -0400 |
commit | 0a8fc08910cfec7713801b7097e9a31c960339b8 (patch) | |
tree | 14e26bb698161d1496dbe27e4182268a063af1f0 | |
parent | fe9b0850ab8f6f5a91a170cca07d24a2afb4ceb9 (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.c | 62 |
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 | ||
231 | static 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 | |||
242 | static 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 */ |
232 | static void enable_das800(struct comedi_device *dev) | 253 | static 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) | |||
250 | static void disable_das800(struct comedi_device *dev) | 271 | static 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; |