PageRenderTime 69ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/staging/comedi/drivers/das1800.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 1817 lines | 1385 code | 169 blank | 263 comment | 253 complexity | ee784d09a372628d64cc300092716983 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*
  2. comedi/drivers/das1800.c
  3. Driver for Keitley das1700/das1800 series boards
  4. Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
  5. COMEDI - Linux Control and Measurement Device Interface
  6. Copyright (C) 2000 David A. Schleef <ds@schleef.org>
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ************************************************************************
  19. */
  20. /*
  21. Driver: das1800
  22. Description: Keithley Metrabyte DAS1800 (& compatibles)
  23. Author: Frank Mori Hess <fmhess@users.sourceforge.net>
  24. Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
  25. DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
  26. DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
  27. DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
  28. DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
  29. DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
  30. DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
  31. DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
  32. DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
  33. DAS-1802AO (das-1802ao)
  34. Status: works
  35. The waveform analog output on the 'ao' cards is not supported.
  36. If you need it, send me (Frank Hess) an email.
  37. Configuration options:
  38. [0] - I/O port base address
  39. [1] - IRQ (optional, required for timed or externally triggered conversions)
  40. [2] - DMA0 (optional, requires irq)
  41. [3] - DMA1 (optional, requires irq and dma0)
  42. */
  43. /*
  44. This driver supports the following Keithley boards:
  45. das-1701st
  46. das-1701st-da
  47. das-1701ao
  48. das-1702st
  49. das-1702st-da
  50. das-1702hr
  51. das-1702hr-da
  52. das-1702ao
  53. das-1801st
  54. das-1801st-da
  55. das-1801hc
  56. das-1801ao
  57. das-1802st
  58. das-1802st-da
  59. das-1802hr
  60. das-1802hr-da
  61. das-1802hc
  62. das-1802ao
  63. Options:
  64. [0] - base io address
  65. [1] - irq (optional, required for timed or externally triggered conversions)
  66. [2] - dma0 (optional, requires irq)
  67. [3] - dma1 (optional, requires irq and dma0)
  68. irq can be omitted, although the cmd interface will not work without it.
  69. analog input cmd triggers supported:
  70. start_src: TRIG_NOW | TRIG_EXT
  71. scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
  72. scan_end_src: TRIG_COUNT
  73. convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
  74. stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE
  75. scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
  76. 'burst mode' which limits the valid conversion time to 64 microseconds
  77. (convert_arg <= 64000). This limitation does not apply if scan_begin_src
  78. is TRIG_FOLLOW.
  79. NOTES:
  80. Only the DAS-1801ST has been tested by me.
  81. Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
  82. TODO:
  83. Make it automatically allocate irq and dma channels if they are not specified
  84. Add support for analog out on 'ao' cards
  85. read insn for analog out
  86. */
  87. #include <linux/interrupt.h>
  88. #include <linux/slab.h>
  89. #include "../comedidev.h"
  90. #include <linux/ioport.h>
  91. #include <asm/dma.h>
  92. #include "8253.h"
  93. #include "comedi_fc.h"
  94. /* misc. defines */
  95. #define DAS1800_SIZE 16 /* uses 16 io addresses */
  96. #define FIFO_SIZE 1024 /* 1024 sample fifo */
  97. #define TIMER_BASE 200 /* 5 Mhz master clock */
  98. #define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */
  99. #define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
  100. /* Registers for the das1800 */
  101. #define DAS1800_FIFO 0x0
  102. #define DAS1800_QRAM 0x0
  103. #define DAS1800_DAC 0x0
  104. #define DAS1800_SELECT 0x2
  105. #define ADC 0x0
  106. #define QRAM 0x1
  107. #define DAC(a) (0x2 + a)
  108. #define DAS1800_DIGITAL 0x3
  109. #define DAS1800_CONTROL_A 0x4
  110. #define FFEN 0x1
  111. #define CGEN 0x4
  112. #define CGSL 0x8
  113. #define TGEN 0x10
  114. #define TGSL 0x20
  115. #define ATEN 0x80
  116. #define DAS1800_CONTROL_B 0x5
  117. #define DMA_CH5 0x1
  118. #define DMA_CH6 0x2
  119. #define DMA_CH7 0x3
  120. #define DMA_CH5_CH6 0x5
  121. #define DMA_CH6_CH7 0x6
  122. #define DMA_CH7_CH5 0x7
  123. #define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */
  124. #define DMA_DUAL 0x4
  125. #define IRQ3 0x8
  126. #define IRQ5 0x10
  127. #define IRQ7 0x18
  128. #define IRQ10 0x28
  129. #define IRQ11 0x30
  130. #define IRQ15 0x38
  131. #define FIMD 0x40
  132. #define DAS1800_CONTROL_C 0X6
  133. #define IPCLK 0x1
  134. #define XPCLK 0x3
  135. #define BMDE 0x4
  136. #define CMEN 0x8
  137. #define UQEN 0x10
  138. #define SD 0x40
  139. #define UB 0x80
  140. #define DAS1800_STATUS 0x7
  141. /* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
  142. #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
  143. #define INT 0x1
  144. #define DMATC 0x2
  145. #define CT0TC 0x8
  146. #define OVF 0x10
  147. #define FHF 0x20
  148. #define FNE 0x40
  149. #define CVEN_MASK 0x40 /* masks CVEN on write */
  150. #define CVEN 0x80
  151. #define DAS1800_BURST_LENGTH 0x8
  152. #define DAS1800_BURST_RATE 0x9
  153. #define DAS1800_QRAM_ADDRESS 0xa
  154. #define DAS1800_COUNTER 0xc
  155. #define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */
  156. enum {
  157. das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
  158. das1702hr_da,
  159. das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
  160. das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
  161. };
  162. static int das1800_attach(struct comedi_device *dev,
  163. struct comedi_devconfig *it);
  164. static int das1800_detach(struct comedi_device *dev);
  165. static int das1800_probe(struct comedi_device *dev);
  166. static int das1800_cancel(struct comedi_device *dev,
  167. struct comedi_subdevice *s);
  168. static irqreturn_t das1800_interrupt(int irq, void *d);
  169. static int das1800_ai_poll(struct comedi_device *dev,
  170. struct comedi_subdevice *s);
  171. static void das1800_ai_handler(struct comedi_device *dev);
  172. static void das1800_handle_dma(struct comedi_device *dev,
  173. struct comedi_subdevice *s, unsigned int status);
  174. static void das1800_flush_dma(struct comedi_device *dev,
  175. struct comedi_subdevice *s);
  176. static void das1800_flush_dma_channel(struct comedi_device *dev,
  177. struct comedi_subdevice *s,
  178. unsigned int channel, uint16_t * buffer);
  179. static void das1800_handle_fifo_half_full(struct comedi_device *dev,
  180. struct comedi_subdevice *s);
  181. static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
  182. struct comedi_subdevice *s);
  183. static int das1800_ai_do_cmdtest(struct comedi_device *dev,
  184. struct comedi_subdevice *s,
  185. struct comedi_cmd *cmd);
  186. static int das1800_ai_do_cmd(struct comedi_device *dev,
  187. struct comedi_subdevice *s);
  188. static int das1800_ai_rinsn(struct comedi_device *dev,
  189. struct comedi_subdevice *s,
  190. struct comedi_insn *insn, unsigned int *data);
  191. static int das1800_ao_winsn(struct comedi_device *dev,
  192. struct comedi_subdevice *s,
  193. struct comedi_insn *insn, unsigned int *data);
  194. static int das1800_di_rbits(struct comedi_device *dev,
  195. struct comedi_subdevice *s,
  196. struct comedi_insn *insn, unsigned int *data);
  197. static int das1800_do_wbits(struct comedi_device *dev,
  198. struct comedi_subdevice *s,
  199. struct comedi_insn *insn, unsigned int *data);
  200. static int das1800_set_frequency(struct comedi_device *dev);
  201. static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode);
  202. static unsigned int suggest_transfer_size(struct comedi_cmd *cmd);
  203. /* analog input ranges */
  204. static const struct comedi_lrange range_ai_das1801 = {
  205. 8,
  206. {
  207. RANGE(-5, 5),
  208. RANGE(-1, 1),
  209. RANGE(-0.1, 0.1),
  210. RANGE(-0.02, 0.02),
  211. RANGE(0, 5),
  212. RANGE(0, 1),
  213. RANGE(0, 0.1),
  214. RANGE(0, 0.02),
  215. }
  216. };
  217. static const struct comedi_lrange range_ai_das1802 = {
  218. 8,
  219. {
  220. RANGE(-10, 10),
  221. RANGE(-5, 5),
  222. RANGE(-2.5, 2.5),
  223. RANGE(-1.25, 1.25),
  224. RANGE(0, 10),
  225. RANGE(0, 5),
  226. RANGE(0, 2.5),
  227. RANGE(0, 1.25),
  228. }
  229. };
  230. struct das1800_board {
  231. const char *name;
  232. int ai_speed; /* max conversion period in nanoseconds */
  233. int resolution; /* bits of ai resolution */
  234. int qram_len; /* length of card's channel / gain queue */
  235. int common; /* supports AREF_COMMON flag */
  236. int do_n_chan; /* number of digital output channels */
  237. int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
  238. int ao_n_chan; /* number of analog out channels */
  239. const struct comedi_lrange *range_ai; /* available input ranges */
  240. };
  241. /* Warning: the maximum conversion speeds listed below are
  242. * not always achievable depending on board setup (see
  243. * user manual.)
  244. */
  245. static const struct das1800_board das1800_boards[] = {
  246. {
  247. .name = "das-1701st",
  248. .ai_speed = 6250,
  249. .resolution = 12,
  250. .qram_len = 256,
  251. .common = 1,
  252. .do_n_chan = 4,
  253. .ao_ability = 0,
  254. .ao_n_chan = 0,
  255. .range_ai = &range_ai_das1801,
  256. },
  257. {
  258. .name = "das-1701st-da",
  259. .ai_speed = 6250,
  260. .resolution = 12,
  261. .qram_len = 256,
  262. .common = 1,
  263. .do_n_chan = 4,
  264. .ao_ability = 1,
  265. .ao_n_chan = 4,
  266. .range_ai = &range_ai_das1801,
  267. },
  268. {
  269. .name = "das-1702st",
  270. .ai_speed = 6250,
  271. .resolution = 12,
  272. .qram_len = 256,
  273. .common = 1,
  274. .do_n_chan = 4,
  275. .ao_ability = 0,
  276. .ao_n_chan = 0,
  277. .range_ai = &range_ai_das1802,
  278. },
  279. {
  280. .name = "das-1702st-da",
  281. .ai_speed = 6250,
  282. .resolution = 12,
  283. .qram_len = 256,
  284. .common = 1,
  285. .do_n_chan = 4,
  286. .ao_ability = 1,
  287. .ao_n_chan = 4,
  288. .range_ai = &range_ai_das1802,
  289. },
  290. {
  291. .name = "das-1702hr",
  292. .ai_speed = 20000,
  293. .resolution = 16,
  294. .qram_len = 256,
  295. .common = 1,
  296. .do_n_chan = 4,
  297. .ao_ability = 0,
  298. .ao_n_chan = 0,
  299. .range_ai = &range_ai_das1802,
  300. },
  301. {
  302. .name = "das-1702hr-da",
  303. .ai_speed = 20000,
  304. .resolution = 16,
  305. .qram_len = 256,
  306. .common = 1,
  307. .do_n_chan = 4,
  308. .ao_ability = 1,
  309. .ao_n_chan = 2,
  310. .range_ai = &range_ai_das1802,
  311. },
  312. {
  313. .name = "das-1701ao",
  314. .ai_speed = 6250,
  315. .resolution = 12,
  316. .qram_len = 256,
  317. .common = 1,
  318. .do_n_chan = 4,
  319. .ao_ability = 2,
  320. .ao_n_chan = 2,
  321. .range_ai = &range_ai_das1801,
  322. },
  323. {
  324. .name = "das-1702ao",
  325. .ai_speed = 6250,
  326. .resolution = 12,
  327. .qram_len = 256,
  328. .common = 1,
  329. .do_n_chan = 4,
  330. .ao_ability = 2,
  331. .ao_n_chan = 2,
  332. .range_ai = &range_ai_das1802,
  333. },
  334. {
  335. .name = "das-1801st",
  336. .ai_speed = 3000,
  337. .resolution = 12,
  338. .qram_len = 256,
  339. .common = 1,
  340. .do_n_chan = 4,
  341. .ao_ability = 0,
  342. .ao_n_chan = 0,
  343. .range_ai = &range_ai_das1801,
  344. },
  345. {
  346. .name = "das-1801st-da",
  347. .ai_speed = 3000,
  348. .resolution = 12,
  349. .qram_len = 256,
  350. .common = 1,
  351. .do_n_chan = 4,
  352. .ao_ability = 0,
  353. .ao_n_chan = 4,
  354. .range_ai = &range_ai_das1801,
  355. },
  356. {
  357. .name = "das-1802st",
  358. .ai_speed = 3000,
  359. .resolution = 12,
  360. .qram_len = 256,
  361. .common = 1,
  362. .do_n_chan = 4,
  363. .ao_ability = 0,
  364. .ao_n_chan = 0,
  365. .range_ai = &range_ai_das1802,
  366. },
  367. {
  368. .name = "das-1802st-da",
  369. .ai_speed = 3000,
  370. .resolution = 12,
  371. .qram_len = 256,
  372. .common = 1,
  373. .do_n_chan = 4,
  374. .ao_ability = 1,
  375. .ao_n_chan = 4,
  376. .range_ai = &range_ai_das1802,
  377. },
  378. {
  379. .name = "das-1802hr",
  380. .ai_speed = 10000,
  381. .resolution = 16,
  382. .qram_len = 256,
  383. .common = 1,
  384. .do_n_chan = 4,
  385. .ao_ability = 0,
  386. .ao_n_chan = 0,
  387. .range_ai = &range_ai_das1802,
  388. },
  389. {
  390. .name = "das-1802hr-da",
  391. .ai_speed = 10000,
  392. .resolution = 16,
  393. .qram_len = 256,
  394. .common = 1,
  395. .do_n_chan = 4,
  396. .ao_ability = 1,
  397. .ao_n_chan = 2,
  398. .range_ai = &range_ai_das1802,
  399. },
  400. {
  401. .name = "das-1801hc",
  402. .ai_speed = 3000,
  403. .resolution = 12,
  404. .qram_len = 64,
  405. .common = 0,
  406. .do_n_chan = 8,
  407. .ao_ability = 1,
  408. .ao_n_chan = 2,
  409. .range_ai = &range_ai_das1801,
  410. },
  411. {
  412. .name = "das-1802hc",
  413. .ai_speed = 3000,
  414. .resolution = 12,
  415. .qram_len = 64,
  416. .common = 0,
  417. .do_n_chan = 8,
  418. .ao_ability = 1,
  419. .ao_n_chan = 2,
  420. .range_ai = &range_ai_das1802,
  421. },
  422. {
  423. .name = "das-1801ao",
  424. .ai_speed = 3000,
  425. .resolution = 12,
  426. .qram_len = 256,
  427. .common = 1,
  428. .do_n_chan = 4,
  429. .ao_ability = 2,
  430. .ao_n_chan = 2,
  431. .range_ai = &range_ai_das1801,
  432. },
  433. {
  434. .name = "das-1802ao",
  435. .ai_speed = 3000,
  436. .resolution = 12,
  437. .qram_len = 256,
  438. .common = 1,
  439. .do_n_chan = 4,
  440. .ao_ability = 2,
  441. .ao_n_chan = 2,
  442. .range_ai = &range_ai_das1802,
  443. },
  444. };
  445. /*
  446. * Useful for shorthand access to the particular board structure
  447. */
  448. #define thisboard ((const struct das1800_board *)dev->board_ptr)
  449. struct das1800_private {
  450. volatile unsigned int count; /* number of data points left to be taken */
  451. unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
  452. unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
  453. int do_bits; /* digital output bits */
  454. int irq_dma_bits; /* bits for control register b */
  455. /* dma bits for control register b, stored so that dma can be
  456. * turned on and off */
  457. int dma_bits;
  458. unsigned int dma0; /* dma channels used */
  459. unsigned int dma1;
  460. volatile unsigned int dma_current; /* dma channel currently in use */
  461. uint16_t *ai_buf0; /* pointers to dma buffers */
  462. uint16_t *ai_buf1;
  463. uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
  464. unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
  465. unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
  466. short ao_update_bits; /* remembers the last write to the 'update' dac */
  467. };
  468. #define devpriv ((struct das1800_private *)dev->private)
  469. /* analog out range for boards with basic analog out */
  470. static const struct comedi_lrange range_ao_1 = {
  471. 1,
  472. {
  473. RANGE(-10, 10),
  474. }
  475. };
  476. /* analog out range for 'ao' boards */
  477. /*
  478. static const struct comedi_lrange range_ao_2 = {
  479. 2,
  480. {
  481. RANGE(-10, 10),
  482. RANGE(-5, 5),
  483. }
  484. };
  485. */
  486. static struct comedi_driver driver_das1800 = {
  487. .driver_name = "das1800",
  488. .module = THIS_MODULE,
  489. .attach = das1800_attach,
  490. .detach = das1800_detach,
  491. .num_names = ARRAY_SIZE(das1800_boards),
  492. .board_name = &das1800_boards[0].name,
  493. .offset = sizeof(struct das1800_board),
  494. };
  495. /*
  496. * A convenient macro that defines init_module() and cleanup_module(),
  497. * as necessary.
  498. */
  499. static int __init driver_das1800_init_module(void)
  500. {
  501. return comedi_driver_register(&driver_das1800);
  502. }
  503. static void __exit driver_das1800_cleanup_module(void)
  504. {
  505. comedi_driver_unregister(&driver_das1800);
  506. }
  507. module_init(driver_das1800_init_module);
  508. module_exit(driver_das1800_cleanup_module);
  509. static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
  510. unsigned int dma1)
  511. {
  512. unsigned long flags;
  513. /* need an irq to do dma */
  514. if (dev->irq && dma0) {
  515. /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
  516. switch ((dma0 & 0x7) | (dma1 << 4)) {
  517. case 0x5: /* dma0 == 5 */
  518. devpriv->dma_bits |= DMA_CH5;
  519. break;
  520. case 0x6: /* dma0 == 6 */
  521. devpriv->dma_bits |= DMA_CH6;
  522. break;
  523. case 0x7: /* dma0 == 7 */
  524. devpriv->dma_bits |= DMA_CH7;
  525. break;
  526. case 0x65: /* dma0 == 5, dma1 == 6 */
  527. devpriv->dma_bits |= DMA_CH5_CH6;
  528. break;
  529. case 0x76: /* dma0 == 6, dma1 == 7 */
  530. devpriv->dma_bits |= DMA_CH6_CH7;
  531. break;
  532. case 0x57: /* dma0 == 7, dma1 == 5 */
  533. devpriv->dma_bits |= DMA_CH7_CH5;
  534. break;
  535. default:
  536. printk(" only supports dma channels 5 through 7\n"
  537. " Dual dma only allows the following combinations:\n"
  538. " dma 5,6 / 6,7 / or 7,5\n");
  539. return -EINVAL;
  540. break;
  541. }
  542. if (request_dma(dma0, driver_das1800.driver_name)) {
  543. printk(" failed to allocate dma channel %i\n", dma0);
  544. return -EINVAL;
  545. }
  546. devpriv->dma0 = dma0;
  547. devpriv->dma_current = dma0;
  548. if (dma1) {
  549. if (request_dma(dma1, driver_das1800.driver_name)) {
  550. printk(" failed to allocate dma channel %i\n",
  551. dma1);
  552. return -EINVAL;
  553. }
  554. devpriv->dma1 = dma1;
  555. }
  556. devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
  557. if (devpriv->ai_buf0 == NULL)
  558. return -ENOMEM;
  559. devpriv->dma_current_buf = devpriv->ai_buf0;
  560. if (dma1) {
  561. devpriv->ai_buf1 =
  562. kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
  563. if (devpriv->ai_buf1 == NULL)
  564. return -ENOMEM;
  565. }
  566. flags = claim_dma_lock();
  567. disable_dma(devpriv->dma0);
  568. set_dma_mode(devpriv->dma0, DMA_MODE_READ);
  569. if (dma1) {
  570. disable_dma(devpriv->dma1);
  571. set_dma_mode(devpriv->dma1, DMA_MODE_READ);
  572. }
  573. release_dma_lock(flags);
  574. }
  575. return 0;
  576. }
  577. static int das1800_attach(struct comedi_device *dev,
  578. struct comedi_devconfig *it)
  579. {
  580. struct comedi_subdevice *s;
  581. unsigned long iobase = it->options[0];
  582. unsigned int irq = it->options[1];
  583. unsigned int dma0 = it->options[2];
  584. unsigned int dma1 = it->options[3];
  585. unsigned long iobase2;
  586. int board;
  587. int retval;
  588. /* allocate and initialize dev->private */
  589. if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
  590. return -ENOMEM;
  591. printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
  592. iobase);
  593. if (irq) {
  594. printk(", irq %u", irq);
  595. if (dma0) {
  596. printk(", dma %u", dma0);
  597. if (dma1)
  598. printk(" and %u", dma1);
  599. }
  600. }
  601. printk("\n");
  602. if (iobase == 0) {
  603. printk(" io base address required\n");
  604. return -EINVAL;
  605. }
  606. /* check if io addresses are available */
  607. if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) {
  608. printk
  609. (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
  610. iobase, iobase + DAS1800_SIZE - 1);
  611. return -EIO;
  612. }
  613. dev->iobase = iobase;
  614. board = das1800_probe(dev);
  615. if (board < 0) {
  616. printk(" unable to determine board type\n");
  617. return -ENODEV;
  618. }
  619. dev->board_ptr = das1800_boards + board;
  620. dev->board_name = thisboard->name;
  621. /* if it is an 'ao' board with fancy analog out then we need extra io ports */
  622. if (thisboard->ao_ability == 2) {
  623. iobase2 = iobase + IOBASE2;
  624. if (!request_region(iobase2, DAS1800_SIZE,
  625. driver_das1800.driver_name)) {
  626. printk
  627. (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
  628. iobase2, iobase2 + DAS1800_SIZE - 1);
  629. return -EIO;
  630. }
  631. devpriv->iobase2 = iobase2;
  632. }
  633. /* grab our IRQ */
  634. if (irq) {
  635. if (request_irq(irq, das1800_interrupt, 0,
  636. driver_das1800.driver_name, dev)) {
  637. printk(" unable to allocate irq %u\n", irq);
  638. return -EINVAL;
  639. }
  640. }
  641. dev->irq = irq;
  642. /* set bits that tell card which irq to use */
  643. switch (irq) {
  644. case 0:
  645. break;
  646. case 3:
  647. devpriv->irq_dma_bits |= 0x8;
  648. break;
  649. case 5:
  650. devpriv->irq_dma_bits |= 0x10;
  651. break;
  652. case 7:
  653. devpriv->irq_dma_bits |= 0x18;
  654. break;
  655. case 10:
  656. devpriv->irq_dma_bits |= 0x28;
  657. break;
  658. case 11:
  659. devpriv->irq_dma_bits |= 0x30;
  660. break;
  661. case 15:
  662. devpriv->irq_dma_bits |= 0x38;
  663. break;
  664. default:
  665. printk(" irq out of range\n");
  666. return -EINVAL;
  667. break;
  668. }
  669. retval = das1800_init_dma(dev, dma0, dma1);
  670. if (retval < 0)
  671. return retval;
  672. if (devpriv->ai_buf0 == NULL) {
  673. devpriv->ai_buf0 =
  674. kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
  675. if (devpriv->ai_buf0 == NULL)
  676. return -ENOMEM;
  677. }
  678. if (alloc_subdevices(dev, 4) < 0)
  679. return -ENOMEM;
  680. /* analog input subdevice */
  681. s = dev->subdevices + 0;
  682. dev->read_subdev = s;
  683. s->type = COMEDI_SUBD_AI;
  684. s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
  685. if (thisboard->common)
  686. s->subdev_flags |= SDF_COMMON;
  687. s->n_chan = thisboard->qram_len;
  688. s->len_chanlist = thisboard->qram_len;
  689. s->maxdata = (1 << thisboard->resolution) - 1;
  690. s->range_table = thisboard->range_ai;
  691. s->do_cmd = das1800_ai_do_cmd;
  692. s->do_cmdtest = das1800_ai_do_cmdtest;
  693. s->insn_read = das1800_ai_rinsn;
  694. s->poll = das1800_ai_poll;
  695. s->cancel = das1800_cancel;
  696. /* analog out */
  697. s = dev->subdevices + 1;
  698. if (thisboard->ao_ability == 1) {
  699. s->type = COMEDI_SUBD_AO;
  700. s->subdev_flags = SDF_WRITABLE;
  701. s->n_chan = thisboard->ao_n_chan;
  702. s->maxdata = (1 << thisboard->resolution) - 1;
  703. s->range_table = &range_ao_1;
  704. s->insn_write = das1800_ao_winsn;
  705. } else {
  706. s->type = COMEDI_SUBD_UNUSED;
  707. }
  708. /* di */
  709. s = dev->subdevices + 2;
  710. s->type = COMEDI_SUBD_DI;
  711. s->subdev_flags = SDF_READABLE;
  712. s->n_chan = 4;
  713. s->maxdata = 1;
  714. s->range_table = &range_digital;
  715. s->insn_bits = das1800_di_rbits;
  716. /* do */
  717. s = dev->subdevices + 3;
  718. s->type = COMEDI_SUBD_DO;
  719. s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
  720. s->n_chan = thisboard->do_n_chan;
  721. s->maxdata = 1;
  722. s->range_table = &range_digital;
  723. s->insn_bits = das1800_do_wbits;
  724. das1800_cancel(dev, dev->read_subdev);
  725. /* initialize digital out channels */
  726. outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
  727. /* initialize analog out channels */
  728. if (thisboard->ao_ability == 1) {
  729. /* select 'update' dac channel for baseAddress + 0x0 */
  730. outb(DAC(thisboard->ao_n_chan - 1),
  731. dev->iobase + DAS1800_SELECT);
  732. outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
  733. }
  734. return 0;
  735. };
  736. static int das1800_detach(struct comedi_device *dev)
  737. {
  738. /* only free stuff if it has been allocated by _attach */
  739. if (dev->iobase)
  740. release_region(dev->iobase, DAS1800_SIZE);
  741. if (dev->irq)
  742. free_irq(dev->irq, dev);
  743. if (dev->private) {
  744. if (devpriv->iobase2)
  745. release_region(devpriv->iobase2, DAS1800_SIZE);
  746. if (devpriv->dma0)
  747. free_dma(devpriv->dma0);
  748. if (devpriv->dma1)
  749. free_dma(devpriv->dma1);
  750. kfree(devpriv->ai_buf0);
  751. kfree(devpriv->ai_buf1);
  752. }
  753. printk("comedi%d: %s: remove\n", dev->minor,
  754. driver_das1800.driver_name);
  755. return 0;
  756. };
  757. /* probes and checks das-1800 series board type
  758. */
  759. static int das1800_probe(struct comedi_device *dev)
  760. {
  761. int id;
  762. int board;
  763. id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
  764. board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
  765. switch (id) {
  766. case 0x3:
  767. if (board == das1801st_da || board == das1802st_da ||
  768. board == das1701st_da || board == das1702st_da) {
  769. printk(" Board model: %s\n",
  770. das1800_boards[board].name);
  771. return board;
  772. }
  773. printk
  774. (" Board model (probed, not recommended): das-1800st-da series\n");
  775. return das1801st;
  776. break;
  777. case 0x4:
  778. if (board == das1802hr_da || board == das1702hr_da) {
  779. printk(" Board model: %s\n",
  780. das1800_boards[board].name);
  781. return board;
  782. }
  783. printk
  784. (" Board model (probed, not recommended): das-1802hr-da\n");
  785. return das1802hr;
  786. break;
  787. case 0x5:
  788. if (board == das1801ao || board == das1802ao ||
  789. board == das1701ao || board == das1702ao) {
  790. printk(" Board model: %s\n",
  791. das1800_boards[board].name);
  792. return board;
  793. }
  794. printk
  795. (" Board model (probed, not recommended): das-1800ao series\n");
  796. return das1801ao;
  797. break;
  798. case 0x6:
  799. if (board == das1802hr || board == das1702hr) {
  800. printk(" Board model: %s\n",
  801. das1800_boards[board].name);
  802. return board;
  803. }
  804. printk(" Board model (probed, not recommended): das-1802hr\n");
  805. return das1802hr;
  806. break;
  807. case 0x7:
  808. if (board == das1801st || board == das1802st ||
  809. board == das1701st || board == das1702st) {
  810. printk(" Board model: %s\n",
  811. das1800_boards[board].name);
  812. return board;
  813. }
  814. printk
  815. (" Board model (probed, not recommended): das-1800st series\n");
  816. return das1801st;
  817. break;
  818. case 0x8:
  819. if (board == das1801hc || board == das1802hc) {
  820. printk(" Board model: %s\n",
  821. das1800_boards[board].name);
  822. return board;
  823. }
  824. printk
  825. (" Board model (probed, not recommended): das-1800hc series\n");
  826. return das1801hc;
  827. break;
  828. default:
  829. printk
  830. (" Board model: probe returned 0x%x (unknown, please report)\n",
  831. id);
  832. return board;
  833. break;
  834. }
  835. return -1;
  836. }
  837. static int das1800_ai_poll(struct comedi_device *dev,
  838. struct comedi_subdevice *s)
  839. {
  840. unsigned long flags;
  841. /* prevent race with interrupt handler */
  842. spin_lock_irqsave(&dev->spinlock, flags);
  843. das1800_ai_handler(dev);
  844. spin_unlock_irqrestore(&dev->spinlock, flags);
  845. return s->async->buf_write_count - s->async->buf_read_count;
  846. }
  847. static irqreturn_t das1800_interrupt(int irq, void *d)
  848. {
  849. struct comedi_device *dev = d;
  850. unsigned int status;
  851. if (dev->attached == 0) {
  852. comedi_error(dev, "premature interrupt");
  853. return IRQ_HANDLED;
  854. }
  855. /* Prevent race with das1800_ai_poll() on multi processor systems.
  856. * Also protects indirect addressing in das1800_ai_handler */
  857. spin_lock(&dev->spinlock);
  858. status = inb(dev->iobase + DAS1800_STATUS);
  859. /* if interrupt was not caused by das-1800 */
  860. if (!(status & INT)) {
  861. spin_unlock(&dev->spinlock);
  862. return IRQ_NONE;
  863. }
  864. /* clear the interrupt status bit INT */
  865. outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
  866. /* handle interrupt */
  867. das1800_ai_handler(dev);
  868. spin_unlock(&dev->spinlock);
  869. return IRQ_HANDLED;
  870. }
  871. /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
  872. static void das1800_ai_handler(struct comedi_device *dev)
  873. {
  874. struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */
  875. struct comedi_async *async = s->async;
  876. struct comedi_cmd *cmd = &async->cmd;
  877. unsigned int status = inb(dev->iobase + DAS1800_STATUS);
  878. async->events = 0;
  879. /* select adc for base address + 0 */
  880. outb(ADC, dev->iobase + DAS1800_SELECT);
  881. /* dma buffer full */
  882. if (devpriv->irq_dma_bits & DMA_ENABLED) {
  883. /* look for data from dma transfer even if dma terminal count hasn't happened yet */
  884. das1800_handle_dma(dev, s, status);
  885. } else if (status & FHF) { /* if fifo half full */
  886. das1800_handle_fifo_half_full(dev, s);
  887. } else if (status & FNE) { /* if fifo not empty */
  888. das1800_handle_fifo_not_empty(dev, s);
  889. }
  890. async->events |= COMEDI_CB_BLOCK;
  891. /* if the card's fifo has overflowed */
  892. if (status & OVF) {
  893. /* clear OVF interrupt bit */
  894. outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
  895. comedi_error(dev, "DAS1800 FIFO overflow");
  896. das1800_cancel(dev, s);
  897. async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
  898. comedi_event(dev, s);
  899. return;
  900. }
  901. /* stop taking data if appropriate */
  902. /* stop_src TRIG_EXT */
  903. if (status & CT0TC) {
  904. /* clear CT0TC interrupt bit */
  905. outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
  906. /* make sure we get all remaining data from board before quitting */
  907. if (devpriv->irq_dma_bits & DMA_ENABLED)
  908. das1800_flush_dma(dev, s);
  909. else
  910. das1800_handle_fifo_not_empty(dev, s);
  911. das1800_cancel(dev, s); /* disable hardware conversions */
  912. async->events |= COMEDI_CB_EOA;
  913. } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
  914. das1800_cancel(dev, s); /* disable hardware conversions */
  915. async->events |= COMEDI_CB_EOA;
  916. }
  917. comedi_event(dev, s);
  918. return;
  919. }
  920. static void das1800_handle_dma(struct comedi_device *dev,
  921. struct comedi_subdevice *s, unsigned int status)
  922. {
  923. unsigned long flags;
  924. const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
  925. flags = claim_dma_lock();
  926. das1800_flush_dma_channel(dev, s, devpriv->dma_current,
  927. devpriv->dma_current_buf);
  928. /* re-enable dma channel */
  929. set_dma_addr(devpriv->dma_current,
  930. virt_to_bus(devpriv->dma_current_buf));
  931. set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
  932. enable_dma(devpriv->dma_current);
  933. release_dma_lock(flags);
  934. if (status & DMATC) {
  935. /* clear DMATC interrupt bit */
  936. outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
  937. /* switch dma channels for next time, if appropriate */
  938. if (dual_dma) {
  939. /* read data from the other channel next time */
  940. if (devpriv->dma_current == devpriv->dma0) {
  941. devpriv->dma_current = devpriv->dma1;
  942. devpriv->dma_current_buf = devpriv->ai_buf1;
  943. } else {
  944. devpriv->dma_current = devpriv->dma0;
  945. devpriv->dma_current_buf = devpriv->ai_buf0;
  946. }
  947. }
  948. }
  949. return;
  950. }
  951. static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
  952. uint16_t sample)
  953. {
  954. sample += 1 << (thisboard->resolution - 1);
  955. return sample;
  956. }
  957. static void munge_data(struct comedi_device *dev, uint16_t * array,
  958. unsigned int num_elements)
  959. {
  960. unsigned int i;
  961. int unipolar;
  962. /* see if card is using a unipolar or bipolar range so we can munge data correctly */
  963. unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
  964. /* convert to unsigned type if we are in a bipolar mode */
  965. if (!unipolar) {
  966. for (i = 0; i < num_elements; i++) {
  967. array[i] = munge_bipolar_sample(dev, array[i]);
  968. }
  969. }
  970. }
  971. /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
  972. * Assumes dma lock is held */
  973. static void das1800_flush_dma_channel(struct comedi_device *dev,
  974. struct comedi_subdevice *s,
  975. unsigned int channel, uint16_t * buffer)
  976. {
  977. unsigned int num_bytes, num_samples;
  978. struct comedi_cmd *cmd = &s->async->cmd;
  979. disable_dma(channel);
  980. /* clear flip-flop to make sure 2-byte registers
  981. * get set correctly */
  982. clear_dma_ff(channel);
  983. /* figure out how many points to read */
  984. num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
  985. num_samples = num_bytes / sizeof(short);
  986. /* if we only need some of the points */
  987. if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
  988. num_samples = devpriv->count;
  989. munge_data(dev, buffer, num_samples);
  990. cfc_write_array_to_buffer(s, buffer, num_bytes);
  991. if (s->async->cmd.stop_src == TRIG_COUNT)
  992. devpriv->count -= num_samples;
  993. return;
  994. }
  995. /* flushes remaining data from board when external trigger has stopped acquisition
  996. * and we are using dma transfers */
  997. static void das1800_flush_dma(struct comedi_device *dev,
  998. struct comedi_subdevice *s)
  999. {
  1000. unsigned long flags;
  1001. const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
  1002. flags = claim_dma_lock();
  1003. das1800_flush_dma_channel(dev, s, devpriv->dma_current,
  1004. devpriv->dma_current_buf);
  1005. if (dual_dma) {
  1006. /* switch to other channel and flush it */
  1007. if (devpriv->dma_current == devpriv->dma0) {
  1008. devpriv->dma_current = devpriv->dma1;
  1009. devpriv->dma_current_buf = devpriv->ai_buf1;
  1010. } else {
  1011. devpriv->dma_current = devpriv->dma0;
  1012. devpriv->dma_current_buf = devpriv->ai_buf0;
  1013. }
  1014. das1800_flush_dma_channel(dev, s, devpriv->dma_current,
  1015. devpriv->dma_current_buf);
  1016. }
  1017. release_dma_lock(flags);
  1018. /* get any remaining samples in fifo */
  1019. das1800_handle_fifo_not_empty(dev, s);
  1020. return;
  1021. }
  1022. static void das1800_handle_fifo_half_full(struct comedi_device *dev,
  1023. struct comedi_subdevice *s)
  1024. {
  1025. int numPoints = 0; /* number of points to read */
  1026. struct comedi_cmd *cmd = &s->async->cmd;
  1027. numPoints = FIFO_SIZE / 2;
  1028. /* if we only need some of the points */
  1029. if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
  1030. numPoints = devpriv->count;
  1031. insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
  1032. munge_data(dev, devpriv->ai_buf0, numPoints);
  1033. cfc_write_array_to_buffer(s, devpriv->ai_buf0,
  1034. numPoints * sizeof(devpriv->ai_buf0[0]));
  1035. if (cmd->stop_src == TRIG_COUNT)
  1036. devpriv->count -= numPoints;
  1037. return;
  1038. }
  1039. static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
  1040. struct comedi_subdevice *s)
  1041. {
  1042. short dpnt;
  1043. int unipolar;
  1044. struct comedi_cmd *cmd = &s->async->cmd;
  1045. unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
  1046. while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
  1047. if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
  1048. break;
  1049. dpnt = inw(dev->iobase + DAS1800_FIFO);
  1050. /* convert to unsigned type if we are in a bipolar mode */
  1051. if (!unipolar) ;
  1052. dpnt = munge_bipolar_sample(dev, dpnt);
  1053. cfc_write_to_buffer(s, dpnt);
  1054. if (cmd->stop_src == TRIG_COUNT)
  1055. devpriv->count--;
  1056. }
  1057. return;
  1058. }
  1059. static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
  1060. {
  1061. outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
  1062. outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
  1063. outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
  1064. if (devpriv->dma0)
  1065. disable_dma(devpriv->dma0);
  1066. if (devpriv->dma1)
  1067. disable_dma(devpriv->dma1);
  1068. return 0;
  1069. }
  1070. /* test analog input cmd */
  1071. static int das1800_ai_do_cmdtest(struct comedi_device *dev,
  1072. struct comedi_subdevice *s,
  1073. struct comedi_cmd *cmd)
  1074. {
  1075. int err = 0;
  1076. int tmp;
  1077. unsigned int tmp_arg;
  1078. int i;
  1079. int unipolar;
  1080. /* step 1: make sure trigger sources are trivially valid */
  1081. tmp = cmd->start_src;
  1082. cmd->start_src &= TRIG_NOW | TRIG_EXT;
  1083. if (!cmd->start_src || tmp != cmd->start_src)
  1084. err++;
  1085. tmp = cmd->scan_begin_src;
  1086. cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
  1087. if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
  1088. err++;
  1089. tmp = cmd->convert_src;
  1090. cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
  1091. if (!cmd->convert_src || tmp != cmd->convert_src)
  1092. err++;
  1093. tmp = cmd->scan_end_src;
  1094. cmd->scan_end_src &= TRIG_COUNT;
  1095. if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
  1096. err++;
  1097. tmp = cmd->stop_src;
  1098. cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
  1099. if (!cmd->stop_src || tmp != cmd->stop_src)
  1100. err++;
  1101. if (err)
  1102. return 1;
  1103. /* step 2: make sure trigger sources are unique and mutually compatible */
  1104. /* uniqueness check */
  1105. if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
  1106. err++;
  1107. if (cmd->scan_begin_src != TRIG_FOLLOW &&
  1108. cmd->scan_begin_src != TRIG_TIMER &&
  1109. cmd->scan_begin_src != TRIG_EXT)
  1110. err++;
  1111. if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
  1112. err++;
  1113. if (cmd->stop_src != TRIG_COUNT &&
  1114. cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
  1115. err++;
  1116. /* compatibility check */
  1117. if (cmd->scan_begin_src != TRIG_FOLLOW &&
  1118. cmd->convert_src != TRIG_TIMER)
  1119. err++;
  1120. if (err)
  1121. return 2;
  1122. /* step 3: make sure arguments are trivially compatible */
  1123. if (cmd->start_arg != 0) {
  1124. cmd->start_arg = 0;
  1125. err++;
  1126. }
  1127. if (cmd->convert_src == TRIG_TIMER) {
  1128. if (cmd->convert_arg < thisboard->ai_speed) {
  1129. cmd->convert_arg = thisboard->ai_speed;
  1130. err++;
  1131. }
  1132. }
  1133. if (!cmd->chanlist_len) {
  1134. cmd->chanlist_len = 1;
  1135. err++;
  1136. }
  1137. if (cmd->scan_end_arg != cmd->chanlist_len) {
  1138. cmd->scan_end_arg = cmd->chanlist_len;
  1139. err++;
  1140. }
  1141. switch (cmd->stop_src) {
  1142. case TRIG_COUNT:
  1143. if (!cmd->stop_arg) {
  1144. cmd->stop_arg = 1;
  1145. err++;
  1146. }
  1147. break;
  1148. case TRIG_NONE:
  1149. if (cmd->stop_arg != 0) {
  1150. cmd->stop_arg = 0;
  1151. err++;
  1152. }
  1153. break;
  1154. default:
  1155. break;
  1156. }
  1157. if (err)
  1158. return 3;
  1159. /* step 4: fix up any arguments */
  1160. if (cmd->convert_src == TRIG_TIMER) {
  1161. /* if we are not in burst mode */
  1162. if (cmd->scan_begin_src == TRIG_FOLLOW) {
  1163. tmp_arg = cmd->convert_arg;
  1164. /* calculate counter values that give desired timing */
  1165. i8253_cascade_ns_to_timer_2div(TIMER_BASE,
  1166. &(devpriv->divisor1),
  1167. &(devpriv->divisor2),
  1168. &(cmd->convert_arg),
  1169. cmd->
  1170. flags & TRIG_ROUND_MASK);
  1171. if (tmp_arg != cmd->convert_arg)
  1172. err++;
  1173. }
  1174. /* if we are in burst mode */
  1175. else {
  1176. /* check that convert_arg is compatible */
  1177. tmp_arg = cmd->convert_arg;
  1178. cmd->convert_arg =
  1179. burst_convert_arg(cmd->convert_arg,
  1180. cmd->flags & TRIG_ROUND_MASK);
  1181. if (tmp_arg != cmd->convert_arg)
  1182. err++;
  1183. if (cmd->scan_begin_src == TRIG_TIMER) {
  1184. /* if scans are timed faster than conversion rate allows */
  1185. if (cmd->convert_arg * cmd->chanlist_len >
  1186. cmd->scan_begin_arg) {
  1187. cmd->scan_begin_arg =
  1188. cmd->convert_arg *
  1189. cmd->chanlist_len;
  1190. err++;
  1191. }
  1192. tmp_arg = cmd->scan_begin_arg;
  1193. /* calculate counter values that give desired timing */
  1194. i8253_cascade_ns_to_timer_2div(TIMER_BASE,
  1195. &(devpriv->
  1196. divisor1),
  1197. &(devpriv->
  1198. divisor2),
  1199. &(cmd->
  1200. scan_begin_arg),
  1201. cmd->
  1202. flags &
  1203. TRIG_ROUND_MASK);
  1204. if (tmp_arg != cmd->scan_begin_arg)
  1205. err++;
  1206. }
  1207. }
  1208. }
  1209. if (err)
  1210. return 4;
  1211. /* make sure user is not trying to mix unipolar and bipolar ranges */
  1212. if (cmd->chanlist) {
  1213. unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
  1214. for (i = 1; i < cmd->chanlist_len; i++) {
  1215. if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
  1216. comedi_error(dev,
  1217. "unipolar and bipolar ranges cannot be mixed in the chanlist");
  1218. err++;
  1219. break;
  1220. }
  1221. }
  1222. }
  1223. if (err)
  1224. return 5;
  1225. return 0;
  1226. }
  1227. /* analog input cmd interface */
  1228. /* first, some utility functions used in the main ai_do_cmd() */
  1229. /* returns appropriate bits for control register a, depending on command */
  1230. static int control_a_bits(struct comedi_cmd cmd)
  1231. {
  1232. int control_a;
  1233. control_a = FFEN; /* enable fifo */
  1234. if (cmd.stop_src == TRIG_EXT) {
  1235. control_a |= ATEN;
  1236. }
  1237. switch (cmd.start_src) {
  1238. case TRIG_EXT:
  1239. control_a |= TGEN | CGSL;
  1240. break;
  1241. case TRIG_NOW:
  1242. control_a |= CGEN;
  1243. break;
  1244. default:
  1245. break;
  1246. }
  1247. return control_a;
  1248. }
  1249. /* returns appropriate bits for control register c, depending on command */
  1250. static int control_c_bits(struct comedi_cmd cmd)
  1251. {
  1252. int control_c;
  1253. int aref;
  1254. /* set clock source to internal or external, select analog reference,
  1255. * select unipolar / bipolar
  1256. */
  1257. aref = CR_AREF(cmd.chanlist[0]);
  1258. control_c = UQEN; /* enable upper qram addresses */
  1259. if (aref != AREF_DIFF)
  1260. control_c |= SD;
  1261. if (aref == AREF_COMMON)
  1262. control_c |= CMEN;
  1263. /* if a unipolar range was selected */
  1264. if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
  1265. control_c |= UB;
  1266. switch (cmd.scan_begin_src) {
  1267. case TRIG_FOLLOW: /* not in burst mode */
  1268. switch (cmd.convert_src) {
  1269. case TRIG_TIMER:
  1270. /* trig on cascaded counters */
  1271. control_c |= IPCLK;
  1272. break;
  1273. case TRIG_EXT:
  1274. /* trig on falling edge of external trigger */
  1275. control_c |= XPCLK;
  1276. break;
  1277. default:
  1278. break;
  1279. }
  1280. break;
  1281. case TRIG_TIMER:
  1282. /* burst mode with internal pacer clock */
  1283. control_c |= BMDE | IPCLK;
  1284. break;
  1285. case TRIG_EXT:
  1286. /* burst mode with external trigger */
  1287. control_c |= BMDE | XPCLK;
  1288. break;
  1289. default:
  1290. break;
  1291. }
  1292. return control_c;
  1293. }
  1294. /* sets up counters */
  1295. static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
  1296. {
  1297. /* setup cascaded counters for conversion/scan frequency */
  1298. switch (cmd.scan_begin_src) {
  1299. case TRIG_FOLLOW: /* not in burst mode */
  1300. if (cmd.convert_src == TRIG_TIMER) {
  1301. /* set conversion frequency */
  1302. i8253_cascade_ns_to_timer_2div(TIMER_BASE,
  1303. &(devpriv->divisor1),
  1304. &(devpriv->divisor2),
  1305. &(cmd.convert_arg),
  1306. cmd.
  1307. flags & TRIG_ROUND_MASK);
  1308. if (das1800_set_frequency(dev) < 0) {
  1309. return -1;
  1310. }
  1311. }
  1312. break;
  1313. case TRIG_TIMER: /* in burst mode */
  1314. /* set scan frequency */
  1315. i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
  1316. &(devpriv->divisor2),
  1317. &(cmd.scan_begin_arg),
  1318. cmd.flags & TRIG_ROUND_MASK);
  1319. if (das1800_set_frequency(dev) < 0) {
  1320. return -1;
  1321. }
  1322. break;
  1323. default:
  1324. break;
  1325. }
  1326. /* setup counter 0 for 'about triggering' */
  1327. if (cmd.stop_src == TRIG_EXT) {
  1328. /* load counter 0 in mode 0 */
  1329. i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
  1330. }
  1331. return 0;
  1332. }
  1333. /* sets up dma */
  1334. static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
  1335. {
  1336. unsigned long lock_flags;
  1337. const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
  1338. if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
  1339. return;
  1340. /* determine a reasonable dma transfer size */
  1341. devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
  1342. lock_flags = claim_dma_lock();
  1343. disable_dma(devpriv->dma0);
  1344. /* clear flip-flop to make sure 2-byte registers for
  1345. * count and address get set correctly */
  1346. clear_dma_ff(devpriv->dma0);
  1347. set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
  1348. /* set appropriate size of transfer */
  1349. set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
  1350. devpriv->dma_current = devpriv->dma0;
  1351. devpriv->dma_current_buf = devpriv->ai_buf0;
  1352. enable_dma(devpriv->dma0);
  1353. /* set up dual dma if appropriate */
  1354. if (dual_dma) {
  1355. disable_dma(devpriv->dma1);
  1356. /* clear flip-flop to make sure 2-byte registers for
  1357. * count and address get set correctly */
  1358. clear_dma_ff(devpriv->dma1);
  1359. set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
  1360. /* set appropriate size of transfer */
  1361. set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
  1362. enable_dma(devpriv->dma1);
  1363. }
  1364. release_dma_lock(lock_flags);
  1365. return;
  1366. }
  1367. /* programs channel/gain list into card */
  1368. static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
  1369. {
  1370. int i, n, chan_range;
  1371. unsigned long irq_flags;
  1372. const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
  1373. const int range_bitshift = 8;
  1374. n = cmd.chanlist_len;
  1375. /* spinlock protects indirect addressing */
  1376. spin_lock_irqsave(&dev->spinlock, irq_flags);
  1377. outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
  1378. outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
  1379. /* make channel / gain list */
  1380. for (i = 0; i < n; i++) {
  1381. chan_range =
  1382. CR_CHAN(cmd.
  1383. chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) &
  1384. range_mask) << range_bitshift);
  1385. outw(chan_range, dev->iobase + DAS1800_QRAM);
  1386. }
  1387. outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
  1388. spin_unlock_irqrestore(&dev->spinlock, irq_flags);
  1389. return;
  1390. }
  1391. /* analog input do_cmd */
  1392. static int das1800_ai_do_cmd(struct comedi_device *dev,
  1393. struct comedi_subdevice *s)
  1394. {
  1395. int ret;
  1396. int control_a, control_c;
  1397. struct comedi_async *async = s->async;
  1398. struct comedi_cmd cmd = async->cmd;
  1399. if (!dev->irq) {
  1400. comedi_error(dev,
  1401. "no irq assigned for das-1800, cannot do hardware conversions");
  1402. return -1;
  1403. }
  1404. /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
  1405. * (because dma in handler is unsafe at hard real-time priority) */
  1406. if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) {
  1407. devpriv->irq_dma_bits &= ~DMA_ENABLED;
  1408. } else {
  1409. devpriv->irq_dma_bits |= devpriv->dma_bits;
  1410. }
  1411. /* interrupt on end of conversion for TRIG_WAKE_EOS */
  1412. if (cmd.flags & TRIG_WAKE_EOS) {
  1413. /* interrupt fifo not empty */
  1414. devpriv->irq_dma_bits &= ~FIMD;
  1415. } else {
  1416. /* interrupt fifo half full */
  1417. devpriv->irq_dma_bits |= FIMD;
  1418. }
  1419. /* determine how many conversions we need */
  1420. if (cmd.stop_src == TRIG_COUNT) {
  1421. devpriv->count = cmd.stop_arg * cmd.chanlist_len;
  1422. }
  1423. das1800_cancel(dev, s);
  1424. /* determine proper bits for control registers */
  1425. control_a = control_a_bits(cmd);
  1426. control_c = control_c_bits(cmd);
  1427. /* setup card and start */
  1428. program_chanlist(dev, cmd);
  1429. ret = setup_counters(dev, cmd);
  1430. if (ret < 0) {
  1431. comedi_error(dev, "Error setting up counters");
  1432. return ret;
  1433. }
  1434. setup_dma(dev, cmd);
  1435. outb(control_c, dev->iobase + DAS1800_CONTROL_C);
  1436. /* set conversion rate and length for burst mode */
  1437. if (control_c & BMDE) {
  1438. /* program conversion period with number of microseconds minus 1 */
  1439. outb(cmd.convert_arg / 1000 - 1,
  1440. dev->iobase + DAS1800_BURST_RATE);
  1441. outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
  1442. }
  1443. outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
  1444. outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
  1445. outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
  1446. return 0;
  1447. }
  1448. /* read analog input */
  1449. static int das1800_ai_rinsn(struct comedi_device *dev,
  1450. struct comedi_subdevice *s,
  1451. struct comedi_insn *insn, unsigned int *data)
  1452. {
  1453. int i, n;
  1454. int chan, range, aref, chan_range;
  1455. int timeout = 1000;
  1456. short dpnt;
  1457. int conv_flags = 0;
  1458. unsigned long irq_flags;
  1459. /* set up analog reference and unipolar / bipolar mode */
  1460. aref = CR_AREF(insn->chanspec);
  1461. conv_flags |= UQEN;
  1462. if (aref != AREF_DIFF)
  1463. conv_flags |= SD;
  1464. if (aref == AREF_COMMON)
  1465. conv_flags |= CMEN;
  1466. /* if a unipolar range was selected */
  1467. if (CR_RANGE(insn->chanspec) & UNIPOLAR)
  1468. conv_flags |= UB;
  1469. outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
  1470. outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
  1471. outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
  1472. outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
  1473. chan = CR_CHAN(insn->chanspec);
  1474. /* mask of unipolar/bipolar bit from range */
  1475. range = CR_RANGE(insn->chanspec) & 0x3;
  1476. chan_range = chan | (range << 8);
  1477. spin_lock_irqsave(&dev->spinlock, irq_flags);
  1478. outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
  1479. outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
  1480. outw(chan_range, dev->iobase + DAS1800_QRAM);
  1481. outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
  1482. outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
  1483. for (n = 0; n < insn->n; n++) {
  1484. /* trigger conversion */
  1485. outb(0, dev->iobase + DAS1800_FIFO);
  1486. for (i = 0; i < timeout; i++) {
  1487. if (inb(dev->iobase + DAS1800_STATUS) & FNE)
  1488. break;
  1489. }
  1490. if (i == timeout) {
  1491. comedi_error(dev, "timeout");
  1492. n = -ETIME;
  1493. goto exit;
  1494. }
  1495. dpnt = inw(dev->iobase + DAS1800_FIFO);
  1496. /* shift data to offset binary for bipolar ranges */
  1497. if ((conv_flags & UB) == 0)
  1498. dpnt += 1 << (thisboard->resolution - 1);
  1499. data[n] = dpnt;
  1500. }
  1501. exit:
  1502. spin_unlock_irqrestore(&dev->spinlock, irq_flags);
  1503. return n;
  1504. }
  1505. /* writes to an analog output channel */
  1506. static int das1800_ao_winsn(struct comedi_device *dev,
  1507. struct comedi_subdevice *s,
  1508. struct comedi_insn *insn, unsigned int *data)
  1509. {
  1510. int chan = CR_CHAN(insn->chanspec);
  1511. /* int range = CR_RANGE(insn->chanspec); */
  1512. int update_chan = thisboard->ao_n_chan - 1;
  1513. short output;
  1514. unsigned long irq_flags;
  1515. /* card expects two's complement data */
  1516. output = data[0] - (1 << (thisboard->resolution - 1));
  1517. /* if the write is to the 'update' channel, we need to remember its value */
  1518. if (chan == update_chan)
  1519. devpriv->ao_update_bits = output;
  1520. /* write to channel */
  1521. spin_lock_irqsave(&dev->spinlock, irq_flags);
  1522. outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
  1523. outw(output, dev->iobase + DAS1800_DAC);
  1524. /* now we need to write to 'update' channel to update all dac channels */
  1525. if (chan != update_chan) {
  1526. outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
  1527. outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
  1528. }
  1529. spin_unlock_irqrestore(&dev->spinlock, irq_flags);
  1530. return 1;
  1531. }
  1532. /* reads from digital input channels */
  1533. static int das1800_di_rbits(struct comedi_device *dev,
  1534. struct comedi_subdevice *s,
  1535. struct comedi_insn *insn, unsigned int *data)
  1536. {
  1537. data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
  1538. data[0] = 0;
  1539. return 2;
  1540. }
  1541. /* writes to digital output channels */
  1542. static int das1800_do_wbits(struct comedi_device *dev,
  1543. struct comedi_subdevice *s,
  1544. struct comedi_insn *insn, unsigned int *data)
  1545. {
  1546. unsigned int wbits;
  1547. /* only set bits that have been masked */
  1548. data[0] &= (1 << s->n_chan) - 1;
  1549. wbits = devpriv->do_bits;
  1550. wbits &= ~data[0];
  1551. wbits |= data[0] & data[1];
  1552. devpriv->do_bits = wbits;
  1553. outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
  1554. data[1] = devpriv->do_bits;
  1555. return 2;
  1556. }
  1557. /* loads counters with divisor1, divisor2 from private structure */
  1558. static int das1800_set_frequency(struct comedi_device *dev)
  1559. {
  1560. int err = 0;
  1561. /* counter 1, mode 2 */
  1562. if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
  1563. 2))
  1564. err++;
  1565. /* counter 2, mode 2 */
  1566. if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
  1567. 2))
  1568. err++;
  1569. if (err)
  1570. return -1;
  1571. return 0;
  1572. }
  1573. /* converts requested conversion timing to timing compatible with
  1574. * hardware, used only when card is in 'burst mode'
  1575. */
  1576. static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
  1577. {
  1578. unsigned int micro_sec;
  1579. /* in burst mode, the maximum conversion time is 64 microseconds */
  1580. if (convert_arg > 64000)
  1581. convert_arg = 64000;
  1582. /* the conversion time must be an integral number of microseconds */
  1583. switch (round_mode) {
  1584. case TRIG_ROUND_NEAREST:
  1585. default:
  1586. micro_sec = (convert_arg + 500) / 1000;
  1587. break;
  1588. case TRIG_ROUND_DOWN:
  1589. micro_sec = convert_arg / 1000;
  1590. break;
  1591. case TRIG_ROUND_UP:
  1592. micro_sec = (convert_arg - 1) / 1000 + 1;
  1593. break;
  1594. }
  1595. /* return number of nanoseconds */
  1596. return micro_sec * 1000;
  1597. }
  1598. /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
  1599. static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
  1600. {
  1601. unsigned int size = DMA_BUF_SIZE;
  1602. static const int sample_size = 2; /* size in bytes of one sample from board */
  1603. unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */
  1604. unsigned int max_size; /* maximum size we will allow for a transfer */
  1605. /* make dma buffer fill in 0.3 seconds for timed modes */
  1606. switch (cmd->scan_begin_src) {
  1607. case TRIG_FOLLOW: /* not in burst mode */
  1608. if (cmd->convert_src == TRIG_TIMER)
  1609. size = (fill_time / cmd->convert_arg) * sample_size;
  1610. break;
  1611. case TRIG_TIMER:
  1612. size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
  1613. sample_size;
  1614. break;
  1615. default:
  1616. size = DMA_BUF_SIZE;
  1617. break;
  1618. }
  1619. /* set a minimum and maximum size allowed */
  1620. max_size = DMA_BUF_SIZE;
  1621. /* if we are taking limited number of conversions, limit transfer size to that */
  1622. if (cmd->stop_src == TRIG_COUNT &&
  1623. cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
  1624. max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
  1625. if (size > max_size)
  1626. size = max_size;
  1627. if (size < sample_size)
  1628. size = sample_size;
  1629. return size;
  1630. }
  1631. MODULE_AUTHOR("Comedi http://www.comedi.org");
  1632. MODULE_DESCRIPTION("Comedi low-level driver");
  1633. MODULE_LICENSE("GPL");