/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c

https://bitbucket.org/wisechild/galaxy-nexus · C · 287 lines · 112 code · 15 blank · 160 comment · 13 complexity · 2985b622a7ac8836caafd010fd4f663d MD5 · raw file

  1. /**
  2. @verbatim
  3. Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
  4. ADDI-DATA GmbH
  5. Dieselstrasse 3
  6. D-77833 Ottersweier
  7. Tel: +19(0)7223/9493-0
  8. Fax: +49(0)7223/9493-92
  9. http://www.addi-data.com
  10. info@addi-data.com
  11. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
  12. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. You should also find the complete GPL in the COPYING file accompanying this source code.
  15. @endverbatim
  16. */
  17. /*
  18. +-----------------------------------------------------------------------+
  19. | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
  20. +-----------------------------------------------------------------------+
  21. | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
  22. | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
  23. +-------------------------------+---------------------------------------+
  24. | Project : APCI-1032 | Compiler : GCC |
  25. | Module name : hwdrv_apci1032.c| Version : 2.96 |
  26. +-------------------------------+---------------------------------------+
  27. | Project manager: Eric Stolz | Date : 02/12/2002 |
  28. +-------------------------------+---------------------------------------+
  29. | Description : Hardware Layer Access For APCI-1032 |
  30. +-----------------------------------------------------------------------+
  31. | UPDATES |
  32. +----------+-----------+------------------------------------------------+
  33. | Date | Author | Description of updates |
  34. +----------+-----------+------------------------------------------------+
  35. | | | |
  36. | | | |
  37. | | | |
  38. +----------+-----------+------------------------------------------------+
  39. */
  40. /*
  41. +----------------------------------------------------------------------------+
  42. | Included files |
  43. +----------------------------------------------------------------------------+
  44. */
  45. #include "hwdrv_apci1032.h"
  46. #include <linux/delay.h>
  47. static unsigned int ui_InterruptStatus;
  48. /*
  49. +----------------------------------------------------------------------------+
  50. | Function Name : int i_APCI1032_ConfigDigitalInput |
  51. | (struct comedi_device *dev,struct comedi_subdevice *s, |
  52. | struct comedi_insn *insn,unsigned int *data) |
  53. +----------------------------------------------------------------------------+
  54. | Task : Configures the digital input Subdevice |
  55. +----------------------------------------------------------------------------+
  56. | Input Parameters : struct comedi_device *dev : Driver handle |
  57. | unsigned int *data : Data Pointer contains |
  58. | configuration parameters as below |
  59. | |
  60. | data[0] : 1 Enable Digital Input Interrupt |
  61. | 0 Disable Digital Input Interrupt |
  62. | data[1] : 0 ADDIDATA Interrupt OR LOGIC |
  63. | : 1 ADDIDATA Interrupt AND LOGIC |
  64. | data[2] : Interrupt mask for the mode 1 |
  65. | data[3] : Interrupt mask for the mode 2 |
  66. | |
  67. +----------------------------------------------------------------------------+
  68. | Output Parameters : -- |
  69. +----------------------------------------------------------------------------+
  70. | Return Value : TRUE : No error occur |
  71. | : FALSE : Error occur. Return the error |
  72. | |
  73. +----------------------------------------------------------------------------+
  74. */
  75. int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
  76. struct comedi_insn *insn, unsigned int *data)
  77. {
  78. unsigned int ui_TmpValue;
  79. unsigned int ul_Command1 = 0;
  80. unsigned int ul_Command2 = 0;
  81. devpriv->tsk_Current = current;
  82. /*******************************/
  83. /* Set the digital input logic */
  84. /*******************************/
  85. if (data[0] == ADDIDATA_ENABLE) {
  86. ul_Command1 = ul_Command1 | data[2];
  87. ul_Command2 = ul_Command2 | data[3];
  88. outl(ul_Command1,
  89. devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
  90. outl(ul_Command2,
  91. devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
  92. if (data[1] == ADDIDATA_OR) {
  93. outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
  94. ui_TmpValue =
  95. inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
  96. } /* if (data[1] == ADDIDATA_OR) */
  97. else
  98. outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
  99. /* else if(data[1] == ADDIDATA_OR) */
  100. } /* if( data[0] == ADDIDATA_ENABLE) */
  101. else {
  102. ul_Command1 = ul_Command1 & 0xFFFF0000;
  103. ul_Command2 = ul_Command2 & 0xFFFF0000;
  104. outl(ul_Command1,
  105. devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
  106. outl(ul_Command2,
  107. devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
  108. outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
  109. } /* else if ( data[0] == ADDIDATA_ENABLE) */
  110. return insn->n;
  111. }
  112. /*
  113. +----------------------------------------------------------------------------+
  114. | Function Name : int i_APCI1032_Read1DigitalInput |
  115. | (struct comedi_device *dev,struct comedi_subdevice *s, |
  116. | struct comedi_insn *insn,unsigned int *data) |
  117. +----------------------------------------------------------------------------+
  118. | Task : Return the status of the digital input |
  119. +----------------------------------------------------------------------------+
  120. | Input Parameters : struct comedi_device *dev : Driver handle |
  121. | unsigned int ui_Channel : Channel number to read |
  122. | unsigned int *data : Data Pointer to read status |
  123. +----------------------------------------------------------------------------+
  124. | Output Parameters : -- |
  125. +----------------------------------------------------------------------------+
  126. | Return Value : TRUE : No error occur |
  127. | : FALSE : Error occur. Return the error |
  128. | |
  129. +----------------------------------------------------------------------------+
  130. */
  131. int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
  132. struct comedi_insn *insn, unsigned int *data)
  133. {
  134. unsigned int ui_TmpValue = 0;
  135. unsigned int ui_Channel;
  136. ui_Channel = CR_CHAN(insn->chanspec);
  137. if (ui_Channel <= 31) {
  138. ui_TmpValue = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
  139. /*
  140. * since only 1 channel reqd to bring it to last bit it is rotated 8
  141. * +(chan - 1) times then ANDed with 1 for last bit.
  142. */
  143. *data = (ui_TmpValue >> ui_Channel) & 0x1;
  144. } /* if(ui_Channel >= 0 && ui_Channel <=31) */
  145. else {
  146. /* comedi_error(dev," \n chan spec wrong\n"); */
  147. return -EINVAL; /* "sorry channel spec wrong " */
  148. } /* else if(ui_Channel >= 0 && ui_Channel <=31) */
  149. return insn->n;
  150. }
  151. /*
  152. +----------------------------------------------------------------------------+
  153. | Function Name : int i_APCI1032_ReadMoreDigitalInput |
  154. | (struct comedi_device *dev,struct comedi_subdevice *s, |
  155. | struct comedi_insn *insn,unsigned int *data) |
  156. +----------------------------------------------------------------------------+
  157. | Task : Return the status of the Requested digital inputs |
  158. +----------------------------------------------------------------------------+
  159. | Input Parameters : struct comedi_device *dev : Driver handle |
  160. | unsigned int ui_NoOfChannels : No Of Channels To be Read |
  161. | unsigned int *data : Data Pointer to read status |
  162. +----------------------------------------------------------------------------+
  163. | Output Parameters : -- |
  164. +----------------------------------------------------------------------------+
  165. | Return Value : TRUE : No error occur |
  166. | : FALSE : Error occur. Return the error |
  167. | |
  168. +----------------------------------------------------------------------------+
  169. */
  170. int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
  171. struct comedi_insn *insn, unsigned int *data)
  172. {
  173. unsigned int ui_PortValue = data[0];
  174. unsigned int ui_Mask = 0;
  175. unsigned int ui_NoOfChannels;
  176. ui_NoOfChannels = CR_CHAN(insn->chanspec);
  177. if (data[1] == 0) {
  178. *data = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
  179. switch (ui_NoOfChannels) {
  180. case 2:
  181. ui_Mask = 3;
  182. *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
  183. break;
  184. case 4:
  185. ui_Mask = 15;
  186. *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
  187. break;
  188. case 8:
  189. ui_Mask = 255;
  190. *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
  191. break;
  192. case 16:
  193. ui_Mask = 65535;
  194. *data = (*data >> (16 * ui_PortValue)) & ui_Mask;
  195. break;
  196. case 31:
  197. break;
  198. default:
  199. /* comedi_error(dev," \nchan spec wrong\n"); */
  200. return -EINVAL; /* "sorry channel spec wrong " */
  201. break;
  202. } /* switch(ui_NoOfChannels) */
  203. } /* if(data[1]==0) */
  204. else {
  205. if (data[1] == 1)
  206. *data = ui_InterruptStatus;
  207. /* if(data[1]==1) */
  208. } /* else if(data[1]==0) */
  209. return insn->n;
  210. }
  211. /*
  212. +----------------------------------------------------------------------------+
  213. | Function Name : static void v_APCI1032_Interrupt |
  214. | (int irq , void *d) |
  215. +----------------------------------------------------------------------------+
  216. | Task : Interrupt handler for the interruptible digital inputs |
  217. +----------------------------------------------------------------------------+
  218. | Input Parameters : int irq : irq number |
  219. | void *d : void pointer |
  220. +----------------------------------------------------------------------------+
  221. | Output Parameters : -- |
  222. +----------------------------------------------------------------------------+
  223. | Return Value : TRUE : No error occur |
  224. | : FALSE : Error occur. Return the error |
  225. | |
  226. +----------------------------------------------------------------------------+
  227. */
  228. static void v_APCI1032_Interrupt(int irq, void *d)
  229. {
  230. struct comedi_device *dev = d;
  231. unsigned int ui_Temp;
  232. /* disable the interrupt */
  233. ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
  234. outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE,
  235. devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
  236. ui_InterruptStatus =
  237. inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS);
  238. ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF;
  239. send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
  240. outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* enable the interrupt */
  241. return;
  242. }
  243. /*
  244. +----------------------------------------------------------------------------+
  245. | Function Name : int i_APCI1032_Reset(struct comedi_device *dev) | |
  246. +----------------------------------------------------------------------------+
  247. | Task :resets all the registers |
  248. +----------------------------------------------------------------------------+
  249. | Input Parameters : struct comedi_device *dev
  250. +----------------------------------------------------------------------------+
  251. | Output Parameters : -- |
  252. +----------------------------------------------------------------------------+
  253. | Return Value : |
  254. | |
  255. +----------------------------------------------------------------------------+
  256. */
  257. int i_APCI1032_Reset(struct comedi_device *dev)
  258. {
  259. outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* disable the interrupts */
  260. inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */
  261. outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */
  262. outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
  263. return 0;
  264. }