PageRenderTime 112ms CodeModel.GetById 52ms RepoModel.GetById 3ms app.codeStats 0ms

/drivers/staging/comedi/drivers/rti802.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 167 lines | 102 code | 26 blank | 39 comment | 9 complexity | 0bd4df3c885f3d858186e4e0736b443f MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*
  2. comedi/drivers/rti802.c
  3. Hardware driver for Analog Devices RTI-802 board
  4. COMEDI - Linux Control and Measurement Device Interface
  5. Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. /*
  19. Driver: rti802
  20. Description: Analog Devices RTI-802
  21. Author: Anders Blomdell <anders.blomdell@control.lth.se>
  22. Devices: [Analog Devices] RTI-802 (rti802)
  23. Status: works
  24. Configuration Options:
  25. [0] - i/o base
  26. [1] - unused
  27. [2] - dac#0 0=two's comp, 1=straight
  28. [3] - dac#0 0=bipolar, 1=unipolar
  29. [4] - dac#1 ...
  30. ...
  31. [17] - dac#7 ...
  32. */
  33. #include "../comedidev.h"
  34. #include <linux/ioport.h>
  35. #define RTI802_SIZE 4
  36. #define RTI802_SELECT 0
  37. #define RTI802_DATALOW 1
  38. #define RTI802_DATAHIGH 2
  39. static int rti802_attach(struct comedi_device *dev,
  40. struct comedi_devconfig *it);
  41. static int rti802_detach(struct comedi_device *dev);
  42. static struct comedi_driver driver_rti802 = {
  43. .driver_name = "rti802",
  44. .module = THIS_MODULE,
  45. .attach = rti802_attach,
  46. .detach = rti802_detach,
  47. };
  48. static int __init driver_rti802_init_module(void)
  49. {
  50. return comedi_driver_register(&driver_rti802);
  51. }
  52. static void __exit driver_rti802_cleanup_module(void)
  53. {
  54. comedi_driver_unregister(&driver_rti802);
  55. }
  56. module_init(driver_rti802_init_module);
  57. module_exit(driver_rti802_cleanup_module);
  58. struct rti802_private {
  59. enum {
  60. dac_2comp, dac_straight
  61. } dac_coding[8];
  62. const struct comedi_lrange *range_type_list[8];
  63. unsigned int ao_readback[8];
  64. };
  65. #define devpriv ((struct rti802_private *)dev->private)
  66. static int rti802_ao_insn_read(struct comedi_device *dev,
  67. struct comedi_subdevice *s,
  68. struct comedi_insn *insn, unsigned int *data)
  69. {
  70. int i;
  71. for (i = 0; i < insn->n; i++)
  72. data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
  73. return i;
  74. }
  75. static int rti802_ao_insn_write(struct comedi_device *dev,
  76. struct comedi_subdevice *s,
  77. struct comedi_insn *insn, unsigned int *data)
  78. {
  79. int i, d;
  80. int chan = CR_CHAN(insn->chanspec);
  81. for (i = 0; i < insn->n; i++) {
  82. d = devpriv->ao_readback[chan] = data[i];
  83. if (devpriv->dac_coding[chan] == dac_2comp)
  84. d ^= 0x800;
  85. outb(chan, dev->iobase + RTI802_SELECT);
  86. outb(d & 0xff, dev->iobase + RTI802_DATALOW);
  87. outb(d >> 8, dev->iobase + RTI802_DATAHIGH);
  88. }
  89. return i;
  90. }
  91. static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
  92. {
  93. struct comedi_subdevice *s;
  94. int i;
  95. unsigned long iobase;
  96. iobase = it->options[0];
  97. printk(KERN_INFO "comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
  98. if (!request_region(iobase, RTI802_SIZE, "rti802")) {
  99. printk(KERN_WARNING "I/O port conflict\n");
  100. return -EIO;
  101. }
  102. dev->iobase = iobase;
  103. dev->board_name = "rti802";
  104. if (alloc_subdevices(dev, 1) < 0
  105. || alloc_private(dev, sizeof(struct rti802_private))) {
  106. return -ENOMEM;
  107. }
  108. s = dev->subdevices;
  109. /* ao subdevice */
  110. s->type = COMEDI_SUBD_AO;
  111. s->subdev_flags = SDF_WRITABLE;
  112. s->maxdata = 0xfff;
  113. s->n_chan = 8;
  114. s->insn_read = rti802_ao_insn_read;
  115. s->insn_write = rti802_ao_insn_write;
  116. s->range_table_list = devpriv->range_type_list;
  117. for (i = 0; i < 8; i++) {
  118. devpriv->dac_coding[i] = (it->options[3 + 2 * i])
  119. ? (dac_straight)
  120. : (dac_2comp);
  121. devpriv->range_type_list[i] = (it->options[2 + 2 * i])
  122. ? &range_unipolar10 : &range_bipolar10;
  123. }
  124. return 0;
  125. }
  126. static int rti802_detach(struct comedi_device *dev)
  127. {
  128. printk(KERN_INFO "comedi%d: rti802: remove\n", dev->minor);
  129. if (dev->iobase)
  130. release_region(dev->iobase, RTI802_SIZE);
  131. return 0;
  132. }
  133. MODULE_AUTHOR("Comedi http://www.comedi.org");
  134. MODULE_DESCRIPTION("Comedi low-level driver");
  135. MODULE_LICENSE("GPL");