PageRenderTime 473ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/staging/comedi/drivers/das16.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 1791 lines | 1335 code | 182 blank | 274 comment | 230 complexity | 3c3127dd5a3c8f2641ef1a928ecc1737 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*
  2. comedi/drivers/das16.c
  3. DAS16 driver
  4. COMEDI - Linux Control and Measurement Device Interface
  5. Copyright (C) 2000 David A. Schleef <ds@schleef.org>
  6. Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
  7. Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. ************************************************************************
  20. */
  21. /*
  22. Driver: das16
  23. Description: DAS16 compatible boards
  24. Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
  25. Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
  26. DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
  27. DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
  28. DAS-1602 (das-1602),
  29. [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
  30. PC104-DAS16JR/16 (pc104-das16jr/16),
  31. CIO-DAS16JR/16 (cio-das16jr/16),
  32. CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
  33. CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
  34. CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
  35. CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
  36. Status: works
  37. Updated: 2003-10-12
  38. A rewrite of the das16 and das1600 drivers.
  39. Options:
  40. [0] - base io address
  41. [1] - irq (does nothing, irq is not used anymore)
  42. [2] - dma (optional, required for comedi_command support)
  43. [3] - master clock speed in MHz (optional, 1 or 10, ignored if
  44. board can probe clock, defaults to 1)
  45. [4] - analog input range lowest voltage in microvolts (optional,
  46. only useful if your board does not have software
  47. programmable gain)
  48. [5] - analog input range highest voltage in microvolts (optional,
  49. only useful if board does not have software programmable
  50. gain)
  51. [6] - analog output range lowest voltage in microvolts (optional)
  52. [7] - analog output range highest voltage in microvolts (optional)
  53. [8] - use timer mode for DMA. Timer mode is needed e.g. for
  54. buggy DMA controllers in NS CS5530A (Geode Companion), and for
  55. 'jr' cards that lack a hardware fifo. This option is no
  56. longer needed, since timer mode is _always_ used.
  57. Passing a zero for an option is the same as leaving it unspecified.
  58. */
  59. /*
  60. Testing and debugging help provided by Daniel Koch.
  61. Keithley Manuals:
  62. 2309.PDF (das16)
  63. 4919.PDF (das1400, 1600)
  64. 4922.PDF (das-1400)
  65. 4923.PDF (das1200, 1400, 1600)
  66. Computer boards manuals also available from their website
  67. www.measurementcomputing.com
  68. */
  69. #include <linux/pci.h>
  70. #include <linux/slab.h>
  71. #include <linux/interrupt.h>
  72. #include <asm/dma.h>
  73. #include "../comedidev.h"
  74. #include "8253.h"
  75. #include "8255.h"
  76. #include "comedi_fc.h"
  77. #undef DEBUG
  78. /* #define DEBUG */
  79. #ifdef DEBUG
  80. #define DEBUG_PRINT(format, args...) \
  81. printk(KERN_DEBUG "das16: " format, ## args)
  82. #else
  83. #define DEBUG_PRINT(format, args...)
  84. #endif
  85. #define DAS16_SIZE 20 /* number of ioports */
  86. #define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */
  87. /*
  88. cio-das16.pdf
  89. "das16"
  90. "das16/f"
  91. 0 a/d bits 0-3 start 12 bit
  92. 1 a/d bits 4-11 unused
  93. 2 mux read mux set
  94. 3 di 4 bit do 4 bit
  95. 4 unused ao0_lsb
  96. 5 unused ao0_msb
  97. 6 unused ao1_lsb
  98. 7 unused ao1_msb
  99. 8 status eoc uni/bip interrupt reset
  100. 9 dma, int, trig ctrl set dma, int
  101. a pacer control unused
  102. b reserved reserved
  103. cdef 8254
  104. 0123 8255
  105. */
  106. /*
  107. cio-das16jr.pdf
  108. "das16jr"
  109. 0 a/d bits 0-3 start 12 bit
  110. 1 a/d bits 4-11 unused
  111. 2 mux read mux set
  112. 3 di 4 bit do 4 bit
  113. 4567 unused unused
  114. 8 status eoc uni/bip interrupt reset
  115. 9 dma, int, trig ctrl set dma, int
  116. a pacer control unused
  117. b gain status gain control
  118. cdef 8254
  119. */
  120. /*
  121. cio-das16jr_16.pdf
  122. "das16jr_16"
  123. 0 a/d bits 0-7 start 16 bit
  124. 1 a/d bits 8-15 unused
  125. 2 mux read mux set
  126. 3 di 4 bit do 4 bit
  127. 4567 unused unused
  128. 8 status eoc uni/bip interrupt reset
  129. 9 dma, int, trig ctrl set dma, int
  130. a pacer control unused
  131. b gain status gain control
  132. cdef 8254
  133. */
  134. /*
  135. cio-das160x-1x.pdf
  136. "das1601/12"
  137. "das1602/12"
  138. "das1602/16"
  139. 0 a/d bits 0-3 start 12 bit
  140. 1 a/d bits 4-11 unused
  141. 2 mux read mux set
  142. 3 di 4 bit do 4 bit
  143. 4 unused ao0_lsb
  144. 5 unused ao0_msb
  145. 6 unused ao1_lsb
  146. 7 unused ao1_msb
  147. 8 status eoc uni/bip interrupt reset
  148. 9 dma, int, trig ctrl set dma, int
  149. a pacer control unused
  150. b gain status gain control
  151. cdef 8254
  152. 400 8255
  153. 404 unused conversion enable
  154. 405 unused burst enable
  155. 406 unused das1600 enable
  156. 407 status
  157. */
  158. /* size in bytes of a sample from board */
  159. static const int sample_size = 2;
  160. #define DAS16_TRIG 0
  161. #define DAS16_AI_LSB 0
  162. #define DAS16_AI_MSB 1
  163. #define DAS16_MUX 2
  164. #define DAS16_DIO 3
  165. #define DAS16_AO_LSB(x) ((x) ? 6 : 4)
  166. #define DAS16_AO_MSB(x) ((x) ? 7 : 5)
  167. #define DAS16_STATUS 8
  168. #define BUSY (1<<7)
  169. #define UNIPOLAR (1<<6)
  170. #define DAS16_MUXBIT (1<<5)
  171. #define DAS16_INT (1<<4)
  172. #define DAS16_CONTROL 9
  173. #define DAS16_INTE (1<<7)
  174. #define DAS16_IRQ(x) (((x) & 0x7) << 4)
  175. #define DMA_ENABLE (1<<2)
  176. #define PACING_MASK 0x3
  177. #define INT_PACER 0x03
  178. #define EXT_PACER 0x02
  179. #define DAS16_SOFT 0x00
  180. #define DAS16_PACER 0x0A
  181. #define DAS16_CTR0 (1<<1)
  182. #define DAS16_TRIG0 (1<<0)
  183. #define BURST_LEN_BITS(x) (((x) & 0xf) << 4)
  184. #define DAS16_GAIN 0x0B
  185. #define DAS16_CNTR0_DATA 0x0C
  186. #define DAS16_CNTR1_DATA 0x0D
  187. #define DAS16_CNTR2_DATA 0x0E
  188. #define DAS16_CNTR_CONTROL 0x0F
  189. #define DAS16_TERM_CNT 0x00
  190. #define DAS16_ONE_SHOT 0x02
  191. #define DAS16_RATE_GEN 0x04
  192. #define DAS16_CNTR_LSB_MSB 0x30
  193. #define DAS16_CNTR0 0x00
  194. #define DAS16_CNTR1 0x40
  195. #define DAS16_CNTR2 0x80
  196. #define DAS1600_CONV 0x404
  197. #define DAS1600_CONV_DISABLE 0x40
  198. #define DAS1600_BURST 0x405
  199. #define DAS1600_BURST_VAL 0x40
  200. #define DAS1600_ENABLE 0x406
  201. #define DAS1600_ENABLE_VAL 0x40
  202. #define DAS1600_STATUS_B 0x407
  203. #define DAS1600_BME 0x40
  204. #define DAS1600_ME 0x20
  205. #define DAS1600_CD 0x10
  206. #define DAS1600_WS 0x02
  207. #define DAS1600_CLK_10MHZ 0x01
  208. static const struct comedi_lrange range_das1x01_bip = { 4, {
  209. BIP_RANGE(10),
  210. BIP_RANGE(1),
  211. BIP_RANGE(0.1),
  212. BIP_RANGE(0.01),
  213. }
  214. };
  215. static const struct comedi_lrange range_das1x01_unip = { 4, {
  216. UNI_RANGE(10),
  217. UNI_RANGE(1),
  218. UNI_RANGE(0.1),
  219. UNI_RANGE(0.01),
  220. }
  221. };
  222. static const struct comedi_lrange range_das1x02_bip = { 4, {
  223. BIP_RANGE(10),
  224. BIP_RANGE(5),
  225. BIP_RANGE(2.5),
  226. BIP_RANGE(1.25),
  227. }
  228. };
  229. static const struct comedi_lrange range_das1x02_unip = { 4, {
  230. UNI_RANGE(10),
  231. UNI_RANGE(5),
  232. UNI_RANGE(2.5),
  233. UNI_RANGE(1.25),
  234. }
  235. };
  236. static const struct comedi_lrange range_das16jr = { 9, {
  237. /* also used by 16/330 */
  238. BIP_RANGE(10),
  239. BIP_RANGE(5),
  240. BIP_RANGE(2.5),
  241. BIP_RANGE(1.25),
  242. BIP_RANGE(0.625),
  243. UNI_RANGE(10),
  244. UNI_RANGE(5),
  245. UNI_RANGE(2.5),
  246. UNI_RANGE(1.25),
  247. }
  248. };
  249. static const struct comedi_lrange range_das16jr_16 = { 8, {
  250. BIP_RANGE(10),
  251. BIP_RANGE(5),
  252. BIP_RANGE(2.5),
  253. BIP_RANGE(1.25),
  254. UNI_RANGE(10),
  255. UNI_RANGE(5),
  256. UNI_RANGE(2.5),
  257. UNI_RANGE(1.25),
  258. }
  259. };
  260. static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
  261. static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
  262. static const int das1600_gainlist[] = { 0, 1, 2, 3 };
  263. enum {
  264. das16_pg_none = 0,
  265. das16_pg_16jr,
  266. das16_pg_16jr_16,
  267. das16_pg_1601,
  268. das16_pg_1602,
  269. };
  270. static const int *const das16_gainlists[] = {
  271. NULL,
  272. das16jr_gainlist,
  273. das16jr_16_gainlist,
  274. das1600_gainlist,
  275. das1600_gainlist,
  276. };
  277. static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
  278. &range_unknown,
  279. &range_das16jr,
  280. &range_das16jr_16,
  281. &range_das1x01_unip,
  282. &range_das1x02_unip,
  283. };
  284. static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
  285. &range_unknown,
  286. &range_das16jr,
  287. &range_das16jr_16,
  288. &range_das1x01_bip,
  289. &range_das1x02_bip,
  290. };
  291. struct munge_info {
  292. uint8_t byte;
  293. unsigned have_byte:1;
  294. };
  295. static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
  296. struct comedi_insn *insn, unsigned int *data);
  297. static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
  298. struct comedi_insn *insn, unsigned int *data);
  299. static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
  300. struct comedi_insn *insn, unsigned int *data);
  301. static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
  302. struct comedi_insn *insn, unsigned int *data);
  303. static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
  304. struct comedi_cmd *cmd);
  305. static int das16_cmd_exec(struct comedi_device *dev,
  306. struct comedi_subdevice *s);
  307. static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
  308. static void das16_ai_munge(struct comedi_device *dev,
  309. struct comedi_subdevice *s, void *array,
  310. unsigned int num_bytes,
  311. unsigned int start_chan_index);
  312. static void das16_reset(struct comedi_device *dev);
  313. static irqreturn_t das16_dma_interrupt(int irq, void *d);
  314. static void das16_timer_interrupt(unsigned long arg);
  315. static void das16_interrupt(struct comedi_device *dev);
  316. static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
  317. int flags);
  318. static int das1600_mode_detect(struct comedi_device *dev);
  319. static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
  320. struct comedi_cmd cmd);
  321. static void reg_dump(struct comedi_device *dev);
  322. struct das16_board {
  323. const char *name;
  324. void *ai;
  325. unsigned int ai_nbits;
  326. unsigned int ai_speed; /* max conversion speed in nanosec */
  327. unsigned int ai_pg;
  328. void *ao;
  329. unsigned int ao_nbits;
  330. void *di;
  331. void *do_;
  332. unsigned int i8255_offset;
  333. unsigned int i8254_offset;
  334. unsigned int size;
  335. unsigned int id;
  336. };
  337. static const struct das16_board das16_boards[] = {
  338. {
  339. .name = "das-16",
  340. .ai = das16_ai_rinsn,
  341. .ai_nbits = 12,
  342. .ai_speed = 15000,
  343. .ai_pg = das16_pg_none,
  344. .ao = das16_ao_winsn,
  345. .ao_nbits = 12,
  346. .di = das16_di_rbits,
  347. .do_ = das16_do_wbits,
  348. .i8255_offset = 0x10,
  349. .i8254_offset = 0x0c,
  350. .size = 0x14,
  351. .id = 0x00,
  352. },
  353. {
  354. .name = "das-16g",
  355. .ai = das16_ai_rinsn,
  356. .ai_nbits = 12,
  357. .ai_speed = 15000,
  358. .ai_pg = das16_pg_none,
  359. .ao = das16_ao_winsn,
  360. .ao_nbits = 12,
  361. .di = das16_di_rbits,
  362. .do_ = das16_do_wbits,
  363. .i8255_offset = 0x10,
  364. .i8254_offset = 0x0c,
  365. .size = 0x14,
  366. .id = 0x00,
  367. },
  368. {
  369. .name = "das-16f",
  370. .ai = das16_ai_rinsn,
  371. .ai_nbits = 12,
  372. .ai_speed = 8500,
  373. .ai_pg = das16_pg_none,
  374. .ao = das16_ao_winsn,
  375. .ao_nbits = 12,
  376. .di = das16_di_rbits,
  377. .do_ = das16_do_wbits,
  378. .i8255_offset = 0x10,
  379. .i8254_offset = 0x0c,
  380. .size = 0x14,
  381. .id = 0x00,
  382. },
  383. {
  384. .name = "cio-das16", /* cio-das16.pdf */
  385. .ai = das16_ai_rinsn,
  386. .ai_nbits = 12,
  387. .ai_speed = 20000,
  388. .ai_pg = das16_pg_none,
  389. .ao = das16_ao_winsn,
  390. .ao_nbits = 12,
  391. .di = das16_di_rbits,
  392. .do_ = das16_do_wbits,
  393. .i8255_offset = 0x10,
  394. .i8254_offset = 0x0c,
  395. .size = 0x14,
  396. .id = 0x80,
  397. },
  398. {
  399. .name = "cio-das16/f", /* das16.pdf */
  400. .ai = das16_ai_rinsn,
  401. .ai_nbits = 12,
  402. .ai_speed = 10000,
  403. .ai_pg = das16_pg_none,
  404. .ao = das16_ao_winsn,
  405. .ao_nbits = 12,
  406. .di = das16_di_rbits,
  407. .do_ = das16_do_wbits,
  408. .i8255_offset = 0x10,
  409. .i8254_offset = 0x0c,
  410. .size = 0x14,
  411. .id = 0x80,
  412. },
  413. {
  414. .name = "cio-das16/jr", /* cio-das16jr.pdf */
  415. .ai = das16_ai_rinsn,
  416. .ai_nbits = 12,
  417. .ai_speed = 7692,
  418. .ai_pg = das16_pg_16jr,
  419. .ao = NULL,
  420. .di = das16_di_rbits,
  421. .do_ = das16_do_wbits,
  422. .i8255_offset = 0,
  423. .i8254_offset = 0x0c,
  424. .size = 0x10,
  425. .id = 0x00,
  426. },
  427. {
  428. .name = "pc104-das16jr", /* pc104-das16jr_xx.pdf */
  429. .ai = das16_ai_rinsn,
  430. .ai_nbits = 12,
  431. .ai_speed = 3300,
  432. .ai_pg = das16_pg_16jr,
  433. .ao = NULL,
  434. .di = das16_di_rbits,
  435. .do_ = das16_do_wbits,
  436. .i8255_offset = 0,
  437. .i8254_offset = 0x0c,
  438. .size = 0x10,
  439. .id = 0x00,
  440. },
  441. {
  442. .name = "cio-das16jr/16", /* cio-das16jr_16.pdf */
  443. .ai = das16_ai_rinsn,
  444. .ai_nbits = 16,
  445. .ai_speed = 10000,
  446. .ai_pg = das16_pg_16jr_16,
  447. .ao = NULL,
  448. .di = das16_di_rbits,
  449. .do_ = das16_do_wbits,
  450. .i8255_offset = 0,
  451. .i8254_offset = 0x0c,
  452. .size = 0x10,
  453. .id = 0x00,
  454. },
  455. {
  456. .name = "pc104-das16jr/16", /* pc104-das16jr_xx.pdf */
  457. .ai = das16_ai_rinsn,
  458. .ai_nbits = 16,
  459. .ai_speed = 10000,
  460. .ai_pg = das16_pg_16jr_16,
  461. .ao = NULL,
  462. .di = das16_di_rbits,
  463. .do_ = das16_do_wbits,
  464. .i8255_offset = 0,
  465. .i8254_offset = 0x0c,
  466. .size = 0x10,
  467. .id = 0x00,
  468. },
  469. {
  470. .name = "das-1201", /* 4924.pdf (keithley user's manual) */
  471. .ai = das16_ai_rinsn,
  472. .ai_nbits = 12,
  473. .ai_speed = 20000,
  474. .ai_pg = das16_pg_none,
  475. .ao = NULL,
  476. .di = das16_di_rbits,
  477. .do_ = das16_do_wbits,
  478. .i8255_offset = 0x400,
  479. .i8254_offset = 0x0c,
  480. .size = 0x408,
  481. .id = 0x20,
  482. },
  483. {
  484. .name = "das-1202", /* 4924.pdf (keithley user's manual) */
  485. .ai = das16_ai_rinsn,
  486. .ai_nbits = 12,
  487. .ai_speed = 10000,
  488. .ai_pg = das16_pg_none,
  489. .ao = NULL,
  490. .di = das16_di_rbits,
  491. .do_ = das16_do_wbits,
  492. .i8255_offset = 0x400,
  493. .i8254_offset = 0x0c,
  494. .size = 0x408,
  495. .id = 0x20,
  496. },
  497. {
  498. /* 4919.pdf and 4922.pdf (keithley user's manual) */
  499. .name = "das-1401",
  500. .ai = das16_ai_rinsn,
  501. .ai_nbits = 12,
  502. .ai_speed = 10000,
  503. .ai_pg = das16_pg_1601,
  504. .ao = NULL,
  505. .di = das16_di_rbits,
  506. .do_ = das16_do_wbits,
  507. .i8255_offset = 0x0,
  508. .i8254_offset = 0x0c,
  509. .size = 0x408,
  510. .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
  511. },
  512. {
  513. /* 4919.pdf and 4922.pdf (keithley user's manual) */
  514. .name = "das-1402",
  515. .ai = das16_ai_rinsn,
  516. .ai_nbits = 12,
  517. .ai_speed = 10000,
  518. .ai_pg = das16_pg_1602,
  519. .ao = NULL,
  520. .di = das16_di_rbits,
  521. .do_ = das16_do_wbits,
  522. .i8255_offset = 0x0,
  523. .i8254_offset = 0x0c,
  524. .size = 0x408,
  525. .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
  526. },
  527. {
  528. .name = "das-1601", /* 4919.pdf */
  529. .ai = das16_ai_rinsn,
  530. .ai_nbits = 12,
  531. .ai_speed = 10000,
  532. .ai_pg = das16_pg_1601,
  533. .ao = das16_ao_winsn,
  534. .ao_nbits = 12,
  535. .di = das16_di_rbits,
  536. .do_ = das16_do_wbits,
  537. .i8255_offset = 0x400,
  538. .i8254_offset = 0x0c,
  539. .size = 0x408,
  540. .id = 0xc0},
  541. {
  542. .name = "das-1602", /* 4919.pdf */
  543. .ai = das16_ai_rinsn,
  544. .ai_nbits = 12,
  545. .ai_speed = 10000,
  546. .ai_pg = das16_pg_1602,
  547. .ao = das16_ao_winsn,
  548. .ao_nbits = 12,
  549. .di = das16_di_rbits,
  550. .do_ = das16_do_wbits,
  551. .i8255_offset = 0x400,
  552. .i8254_offset = 0x0c,
  553. .size = 0x408,
  554. .id = 0xc0},
  555. {
  556. .name = "cio-das1401/12", /* cio-das1400_series.pdf */
  557. .ai = das16_ai_rinsn,
  558. .ai_nbits = 12,
  559. .ai_speed = 6250,
  560. .ai_pg = das16_pg_1601,
  561. .ao = NULL,
  562. .di = das16_di_rbits,
  563. .do_ = das16_do_wbits,
  564. .i8255_offset = 0,
  565. .i8254_offset = 0x0c,
  566. .size = 0x408,
  567. .id = 0xc0},
  568. {
  569. .name = "cio-das1402/12", /* cio-das1400_series.pdf */
  570. .ai = das16_ai_rinsn,
  571. .ai_nbits = 12,
  572. .ai_speed = 6250,
  573. .ai_pg = das16_pg_1602,
  574. .ao = NULL,
  575. .di = das16_di_rbits,
  576. .do_ = das16_do_wbits,
  577. .i8255_offset = 0,
  578. .i8254_offset = 0x0c,
  579. .size = 0x408,
  580. .id = 0xc0},
  581. {
  582. .name = "cio-das1402/16", /* cio-das1400_series.pdf */
  583. .ai = das16_ai_rinsn,
  584. .ai_nbits = 16,
  585. .ai_speed = 10000,
  586. .ai_pg = das16_pg_1602,
  587. .ao = NULL,
  588. .di = das16_di_rbits,
  589. .do_ = das16_do_wbits,
  590. .i8255_offset = 0,
  591. .i8254_offset = 0x0c,
  592. .size = 0x408,
  593. .id = 0xc0},
  594. {
  595. .name = "cio-das1601/12", /* cio-das160x-1x.pdf */
  596. .ai = das16_ai_rinsn,
  597. .ai_nbits = 12,
  598. .ai_speed = 6250,
  599. .ai_pg = das16_pg_1601,
  600. .ao = das16_ao_winsn,
  601. .ao_nbits = 12,
  602. .di = das16_di_rbits,
  603. .do_ = das16_do_wbits,
  604. .i8255_offset = 0x400,
  605. .i8254_offset = 0x0c,
  606. .size = 0x408,
  607. .id = 0xc0},
  608. {
  609. .name = "cio-das1602/12", /* cio-das160x-1x.pdf */
  610. .ai = das16_ai_rinsn,
  611. .ai_nbits = 12,
  612. .ai_speed = 10000,
  613. .ai_pg = das16_pg_1602,
  614. .ao = das16_ao_winsn,
  615. .ao_nbits = 12,
  616. .di = das16_di_rbits,
  617. .do_ = das16_do_wbits,
  618. .i8255_offset = 0x400,
  619. .i8254_offset = 0x0c,
  620. .size = 0x408,
  621. .id = 0xc0},
  622. {
  623. .name = "cio-das1602/16", /* cio-das160x-1x.pdf */
  624. .ai = das16_ai_rinsn,
  625. .ai_nbits = 16,
  626. .ai_speed = 10000,
  627. .ai_pg = das16_pg_1602,
  628. .ao = das16_ao_winsn,
  629. .ao_nbits = 12,
  630. .di = das16_di_rbits,
  631. .do_ = das16_do_wbits,
  632. .i8255_offset = 0x400,
  633. .i8254_offset = 0x0c,
  634. .size = 0x408,
  635. .id = 0xc0},
  636. {
  637. .name = "cio-das16/330", /* ? */
  638. .ai = das16_ai_rinsn,
  639. .ai_nbits = 12,
  640. .ai_speed = 3030,
  641. .ai_pg = das16_pg_16jr,
  642. .ao = NULL,
  643. .di = das16_di_rbits,
  644. .do_ = das16_do_wbits,
  645. .i8255_offset = 0,
  646. .i8254_offset = 0x0c,
  647. .size = 0x14,
  648. .id = 0xf0},
  649. #if 0
  650. {
  651. .name = "das16/330i", /* ? */
  652. },
  653. {
  654. .name = "das16/jr/ctr5", /* ? */
  655. },
  656. {
  657. /* cio-das16_m1_16.pdf, this board is a bit quirky, no dma */
  658. .name = "cio-das16/m1/16",
  659. },
  660. #endif
  661. };
  662. static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it);
  663. static int das16_detach(struct comedi_device *dev);
  664. static struct comedi_driver driver_das16 = {
  665. .driver_name = "das16",
  666. .module = THIS_MODULE,
  667. .attach = das16_attach,
  668. .detach = das16_detach,
  669. .board_name = &das16_boards[0].name,
  670. .num_names = ARRAY_SIZE(das16_boards),
  671. .offset = sizeof(das16_boards[0]),
  672. };
  673. #define DAS16_TIMEOUT 1000
  674. /* Period for timer interrupt in jiffies. It's a function
  675. * to deal with possibility of dynamic HZ patches */
  676. static inline int timer_period(void)
  677. {
  678. return HZ / 20;
  679. }
  680. struct das16_private_struct {
  681. unsigned int ai_unipolar; /* unipolar flag */
  682. unsigned int ai_singleended; /* single ended flag */
  683. unsigned int clockbase; /* master clock speed in ns */
  684. volatile unsigned int control_state; /* dma, interrupt and trigger control bits */
  685. volatile unsigned long adc_byte_count; /* number of bytes remaining */
  686. /* divisor dividing master clock to get conversion frequency */
  687. unsigned int divisor1;
  688. /* divisor dividing master clock to get conversion frequency */
  689. unsigned int divisor2;
  690. unsigned int dma_chan; /* dma channel */
  691. uint16_t *dma_buffer[2];
  692. dma_addr_t dma_buffer_addr[2];
  693. unsigned int current_buffer;
  694. volatile unsigned int dma_transfer_size; /* target number of bytes to transfer per dma shot */
  695. /**
  696. * user-defined analog input and output ranges
  697. * defined from config options
  698. */
  699. struct comedi_lrange *user_ai_range_table;
  700. struct comedi_lrange *user_ao_range_table;
  701. struct timer_list timer; /* for timed interrupt */
  702. volatile short timer_running;
  703. volatile short timer_mode; /* true if using timer mode */
  704. };
  705. #define devpriv ((struct das16_private_struct *)(dev->private))
  706. #define thisboard ((struct das16_board *)(dev->board_ptr))
  707. static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
  708. struct comedi_cmd *cmd)
  709. {
  710. int err = 0, tmp;
  711. int gain, start_chan, i;
  712. int mask;
  713. /* make sure triggers are valid */
  714. tmp = cmd->start_src;
  715. cmd->start_src &= TRIG_NOW;
  716. if (!cmd->start_src || tmp != cmd->start_src)
  717. err++;
  718. tmp = cmd->scan_begin_src;
  719. mask = TRIG_FOLLOW;
  720. /* if board supports burst mode */
  721. if (thisboard->size > 0x400)
  722. mask |= TRIG_TIMER | TRIG_EXT;
  723. cmd->scan_begin_src &= mask;
  724. if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
  725. err++;
  726. tmp = cmd->convert_src;
  727. mask = TRIG_TIMER | TRIG_EXT;
  728. /* if board supports burst mode */
  729. if (thisboard->size > 0x400)
  730. mask |= TRIG_NOW;
  731. cmd->convert_src &= mask;
  732. if (!cmd->convert_src || tmp != cmd->convert_src)
  733. err++;
  734. tmp = cmd->scan_end_src;
  735. cmd->scan_end_src &= TRIG_COUNT;
  736. if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
  737. err++;
  738. tmp = cmd->stop_src;
  739. cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
  740. if (!cmd->stop_src || tmp != cmd->stop_src)
  741. err++;
  742. if (err)
  743. return 1;
  744. /**
  745. * step 2: make sure trigger sources are unique and
  746. * mutually compatible
  747. */
  748. if (cmd->scan_begin_src != TRIG_TIMER &&
  749. cmd->scan_begin_src != TRIG_EXT &&
  750. cmd->scan_begin_src != TRIG_FOLLOW)
  751. err++;
  752. if (cmd->convert_src != TRIG_TIMER &&
  753. cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
  754. err++;
  755. if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
  756. err++;
  757. /* make sure scan_begin_src and convert_src dont conflict */
  758. if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
  759. err++;
  760. if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
  761. err++;
  762. if (err)
  763. return 2;
  764. /* step 3: make sure arguments are trivially compatible */
  765. if (cmd->start_arg != 0) {
  766. cmd->start_arg = 0;
  767. err++;
  768. }
  769. if (cmd->scan_begin_src == TRIG_FOLLOW) {
  770. /* internal trigger */
  771. if (cmd->scan_begin_arg != 0) {
  772. cmd->scan_begin_arg = 0;
  773. err++;
  774. }
  775. }
  776. if (cmd->scan_end_arg != cmd->chanlist_len) {
  777. cmd->scan_end_arg = cmd->chanlist_len;
  778. err++;
  779. }
  780. /* check against maximum frequency */
  781. if (cmd->scan_begin_src == TRIG_TIMER) {
  782. if (cmd->scan_begin_arg <
  783. thisboard->ai_speed * cmd->chanlist_len) {
  784. cmd->scan_begin_arg =
  785. thisboard->ai_speed * cmd->chanlist_len;
  786. err++;
  787. }
  788. }
  789. if (cmd->convert_src == TRIG_TIMER) {
  790. if (cmd->convert_arg < thisboard->ai_speed) {
  791. cmd->convert_arg = thisboard->ai_speed;
  792. err++;
  793. }
  794. }
  795. if (cmd->stop_src == TRIG_NONE) {
  796. if (cmd->stop_arg != 0) {
  797. cmd->stop_arg = 0;
  798. err++;
  799. }
  800. }
  801. if (err)
  802. return 3;
  803. /* step 4: fix up arguments */
  804. if (cmd->scan_begin_src == TRIG_TIMER) {
  805. unsigned int tmp = cmd->scan_begin_arg;
  806. /* set divisors, correct timing arguments */
  807. i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
  808. &(devpriv->divisor1),
  809. &(devpriv->divisor2),
  810. &(cmd->scan_begin_arg),
  811. cmd->flags & TRIG_ROUND_MASK);
  812. err += (tmp != cmd->scan_begin_arg);
  813. }
  814. if (cmd->convert_src == TRIG_TIMER) {
  815. unsigned int tmp = cmd->convert_arg;
  816. /* set divisors, correct timing arguments */
  817. i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
  818. &(devpriv->divisor1),
  819. &(devpriv->divisor2),
  820. &(cmd->convert_arg),
  821. cmd->flags & TRIG_ROUND_MASK);
  822. err += (tmp != cmd->convert_arg);
  823. }
  824. if (err)
  825. return 4;
  826. /* check channel/gain list against card's limitations */
  827. if (cmd->chanlist) {
  828. gain = CR_RANGE(cmd->chanlist[0]);
  829. start_chan = CR_CHAN(cmd->chanlist[0]);
  830. for (i = 1; i < cmd->chanlist_len; i++) {
  831. if (CR_CHAN(cmd->chanlist[i]) !=
  832. (start_chan + i) % s->n_chan) {
  833. comedi_error(dev,
  834. "entries in chanlist must be "
  835. "consecutive channels, "
  836. "counting upwards\n");
  837. err++;
  838. }
  839. if (CR_RANGE(cmd->chanlist[i]) != gain) {
  840. comedi_error(dev,
  841. "entries in chanlist must all "
  842. "have the same gain\n");
  843. err++;
  844. }
  845. }
  846. }
  847. if (err)
  848. return 5;
  849. return 0;
  850. }
  851. static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
  852. {
  853. struct comedi_async *async = s->async;
  854. struct comedi_cmd *cmd = &async->cmd;
  855. unsigned int byte;
  856. unsigned long flags;
  857. int range;
  858. if (devpriv->dma_chan == 0 || (dev->irq == 0
  859. && devpriv->timer_mode == 0)) {
  860. comedi_error(dev,
  861. "irq (or use of 'timer mode') dma required to "
  862. "execute comedi_cmd");
  863. return -1;
  864. }
  865. if (cmd->flags & TRIG_RT) {
  866. comedi_error(dev, "isa dma transfers cannot be performed with "
  867. "TRIG_RT, aborting");
  868. return -1;
  869. }
  870. devpriv->adc_byte_count =
  871. cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
  872. /* disable conversions for das1600 mode */
  873. if (thisboard->size > 0x400)
  874. outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
  875. /* set scan limits */
  876. byte = CR_CHAN(cmd->chanlist[0]);
  877. byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
  878. outb(byte, dev->iobase + DAS16_MUX);
  879. /* set gain (this is also burst rate register but according to
  880. * computer boards manual, burst rate does nothing, even on
  881. * keithley cards) */
  882. if (thisboard->ai_pg != das16_pg_none) {
  883. range = CR_RANGE(cmd->chanlist[0]);
  884. outb((das16_gainlists[thisboard->ai_pg])[range],
  885. dev->iobase + DAS16_GAIN);
  886. }
  887. /* set counter mode and counts */
  888. cmd->convert_arg =
  889. das16_set_pacer(dev, cmd->convert_arg,
  890. cmd->flags & TRIG_ROUND_MASK);
  891. DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
  892. /* enable counters */
  893. byte = 0;
  894. /* Enable burst mode if appropriate. */
  895. if (thisboard->size > 0x400) {
  896. if (cmd->convert_src == TRIG_NOW) {
  897. outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
  898. /* set burst length */
  899. byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
  900. } else {
  901. outb(0, dev->iobase + DAS1600_BURST);
  902. }
  903. }
  904. outb(byte, dev->iobase + DAS16_PACER);
  905. /* set up dma transfer */
  906. flags = claim_dma_lock();
  907. disable_dma(devpriv->dma_chan);
  908. /* clear flip-flop to make sure 2-byte registers for
  909. * count and address get set correctly */
  910. clear_dma_ff(devpriv->dma_chan);
  911. devpriv->current_buffer = 0;
  912. set_dma_addr(devpriv->dma_chan,
  913. devpriv->dma_buffer_addr[devpriv->current_buffer]);
  914. /* set appropriate size of transfer */
  915. devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
  916. set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
  917. enable_dma(devpriv->dma_chan);
  918. release_dma_lock(flags);
  919. /* set up interrupt */
  920. if (devpriv->timer_mode) {
  921. devpriv->timer_running = 1;
  922. devpriv->timer.expires = jiffies + timer_period();
  923. add_timer(&devpriv->timer);
  924. devpriv->control_state &= ~DAS16_INTE;
  925. } else {
  926. /* clear interrupt bit */
  927. outb(0x00, dev->iobase + DAS16_STATUS);
  928. /* enable interrupts */
  929. devpriv->control_state |= DAS16_INTE;
  930. }
  931. devpriv->control_state |= DMA_ENABLE;
  932. devpriv->control_state &= ~PACING_MASK;
  933. if (cmd->convert_src == TRIG_EXT)
  934. devpriv->control_state |= EXT_PACER;
  935. else
  936. devpriv->control_state |= INT_PACER;
  937. outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
  938. /* Enable conversions if using das1600 mode */
  939. if (thisboard->size > 0x400)
  940. outb(0, dev->iobase + DAS1600_CONV);
  941. return 0;
  942. }
  943. static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
  944. {
  945. unsigned long flags;
  946. spin_lock_irqsave(&dev->spinlock, flags);
  947. /* disable interrupts, dma and pacer clocked conversions */
  948. devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
  949. outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
  950. if (devpriv->dma_chan)
  951. disable_dma(devpriv->dma_chan);
  952. /* disable SW timer */
  953. if (devpriv->timer_mode && devpriv->timer_running) {
  954. devpriv->timer_running = 0;
  955. del_timer(&devpriv->timer);
  956. }
  957. /* disable burst mode */
  958. if (thisboard->size > 0x400)
  959. outb(0, dev->iobase + DAS1600_BURST);
  960. spin_unlock_irqrestore(&dev->spinlock, flags);
  961. return 0;
  962. }
  963. static void das16_reset(struct comedi_device *dev)
  964. {
  965. outb(0, dev->iobase + DAS16_STATUS);
  966. outb(0, dev->iobase + DAS16_CONTROL);
  967. outb(0, dev->iobase + DAS16_PACER);
  968. outb(0, dev->iobase + DAS16_CNTR_CONTROL);
  969. }
  970. static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
  971. struct comedi_insn *insn, unsigned int *data)
  972. {
  973. int i, n;
  974. int range;
  975. int chan;
  976. int msb, lsb;
  977. /* disable interrupts and pacing */
  978. devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
  979. outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
  980. /* set multiplexer */
  981. chan = CR_CHAN(insn->chanspec);
  982. chan |= CR_CHAN(insn->chanspec) << 4;
  983. outb(chan, dev->iobase + DAS16_MUX);
  984. /* set gain */
  985. if (thisboard->ai_pg != das16_pg_none) {
  986. range = CR_RANGE(insn->chanspec);
  987. outb((das16_gainlists[thisboard->ai_pg])[range],
  988. dev->iobase + DAS16_GAIN);
  989. }
  990. for (n = 0; n < insn->n; n++) {
  991. /* trigger conversion */
  992. outb_p(0, dev->iobase + DAS16_TRIG);
  993. for (i = 0; i < DAS16_TIMEOUT; i++) {
  994. if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
  995. break;
  996. }
  997. if (i == DAS16_TIMEOUT) {
  998. printk("das16: timeout\n");
  999. return -ETIME;
  1000. }
  1001. msb = inb(dev->iobase + DAS16_AI_MSB);
  1002. lsb = inb(dev->iobase + DAS16_AI_LSB);
  1003. if (thisboard->ai_nbits == 12)
  1004. data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
  1005. else
  1006. data[n] = lsb | (msb << 8);
  1007. }
  1008. return n;
  1009. }
  1010. static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
  1011. struct comedi_insn *insn, unsigned int *data)
  1012. {
  1013. unsigned int bits;
  1014. bits = inb(dev->iobase + DAS16_DIO) & 0xf;
  1015. data[1] = bits;
  1016. data[0] = 0;
  1017. return 2;
  1018. }
  1019. static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
  1020. struct comedi_insn *insn, unsigned int *data)
  1021. {
  1022. unsigned int wbits;
  1023. /* only set bits that have been masked */
  1024. data[0] &= 0xf;
  1025. wbits = s->state;
  1026. /* zero bits that have been masked */
  1027. wbits &= ~data[0];
  1028. /* set masked bits */
  1029. wbits |= data[0] & data[1];
  1030. s->state = wbits;
  1031. data[1] = wbits;
  1032. outb(s->state, dev->iobase + DAS16_DIO);
  1033. return 2;
  1034. }
  1035. static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
  1036. struct comedi_insn *insn, unsigned int *data)
  1037. {
  1038. int i;
  1039. int lsb, msb;
  1040. int chan;
  1041. chan = CR_CHAN(insn->chanspec);
  1042. for (i = 0; i < insn->n; i++) {
  1043. if (thisboard->ao_nbits == 12) {
  1044. lsb = (data[i] << 4) & 0xff;
  1045. msb = (data[i] >> 4) & 0xff;
  1046. } else {
  1047. lsb = data[i] & 0xff;
  1048. msb = (data[i] >> 8) & 0xff;
  1049. }
  1050. outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
  1051. outb(msb, dev->iobase + DAS16_AO_MSB(chan));
  1052. }
  1053. return i;
  1054. }
  1055. static irqreturn_t das16_dma_interrupt(int irq, void *d)
  1056. {
  1057. int status;
  1058. struct comedi_device *dev = d;
  1059. status = inb(dev->iobase + DAS16_STATUS);
  1060. if ((status & DAS16_INT) == 0) {
  1061. DEBUG_PRINT("spurious interrupt\n");
  1062. return IRQ_NONE;
  1063. }
  1064. /* clear interrupt */
  1065. outb(0x00, dev->iobase + DAS16_STATUS);
  1066. das16_interrupt(dev);
  1067. return IRQ_HANDLED;
  1068. }
  1069. static void das16_timer_interrupt(unsigned long arg)
  1070. {
  1071. struct comedi_device *dev = (struct comedi_device *)arg;
  1072. das16_interrupt(dev);
  1073. if (devpriv->timer_running)
  1074. mod_timer(&devpriv->timer, jiffies + timer_period());
  1075. }
  1076. /* the pc104-das16jr (at least) has problems if the dma
  1077. transfer is interrupted in the middle of transferring
  1078. a 16 bit sample, so this function takes care to get
  1079. an even transfer count after disabling dma
  1080. channel.
  1081. */
  1082. static int disable_dma_on_even(struct comedi_device *dev)
  1083. {
  1084. int residue;
  1085. int i;
  1086. static const int disable_limit = 100;
  1087. static const int enable_timeout = 100;
  1088. disable_dma(devpriv->dma_chan);
  1089. residue = get_dma_residue(devpriv->dma_chan);
  1090. for (i = 0; i < disable_limit && (residue % 2); ++i) {
  1091. int j;
  1092. enable_dma(devpriv->dma_chan);
  1093. for (j = 0; j < enable_timeout; ++j) {
  1094. int new_residue;
  1095. udelay(2);
  1096. new_residue = get_dma_residue(devpriv->dma_chan);
  1097. if (new_residue != residue)
  1098. break;
  1099. }
  1100. disable_dma(devpriv->dma_chan);
  1101. residue = get_dma_residue(devpriv->dma_chan);
  1102. }
  1103. if (i == disable_limit) {
  1104. comedi_error(dev, "failed to get an even dma transfer, "
  1105. "could be trouble.");
  1106. }
  1107. return residue;
  1108. }
  1109. static void das16_interrupt(struct comedi_device *dev)
  1110. {
  1111. unsigned long dma_flags, spin_flags;
  1112. struct comedi_subdevice *s = dev->read_subdev;
  1113. struct comedi_async *async;
  1114. struct comedi_cmd *cmd;
  1115. int num_bytes, residue;
  1116. int buffer_index;
  1117. if (dev->attached == 0) {
  1118. comedi_error(dev, "premature interrupt");
  1119. return;
  1120. }
  1121. /* initialize async here to make sure it is not NULL */
  1122. async = s->async;
  1123. cmd = &async->cmd;
  1124. if (devpriv->dma_chan == 0) {
  1125. comedi_error(dev, "interrupt with no dma channel?");
  1126. return;
  1127. }
  1128. spin_lock_irqsave(&dev->spinlock, spin_flags);
  1129. if ((devpriv->control_state & DMA_ENABLE) == 0) {
  1130. spin_unlock_irqrestore(&dev->spinlock, spin_flags);
  1131. DEBUG_PRINT("interrupt while dma disabled?\n");
  1132. return;
  1133. }
  1134. dma_flags = claim_dma_lock();
  1135. clear_dma_ff(devpriv->dma_chan);
  1136. residue = disable_dma_on_even(dev);
  1137. /* figure out how many points to read */
  1138. if (residue > devpriv->dma_transfer_size) {
  1139. comedi_error(dev, "residue > transfer size!\n");
  1140. async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
  1141. num_bytes = 0;
  1142. } else
  1143. num_bytes = devpriv->dma_transfer_size - residue;
  1144. if (cmd->stop_src == TRIG_COUNT &&
  1145. num_bytes >= devpriv->adc_byte_count) {
  1146. num_bytes = devpriv->adc_byte_count;
  1147. async->events |= COMEDI_CB_EOA;
  1148. }
  1149. buffer_index = devpriv->current_buffer;
  1150. devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
  1151. devpriv->adc_byte_count -= num_bytes;
  1152. /* figure out how many bytes for next transfer */
  1153. if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
  1154. devpriv->dma_transfer_size > devpriv->adc_byte_count)
  1155. devpriv->dma_transfer_size = devpriv->adc_byte_count;
  1156. /* re-enable dma */
  1157. if ((async->events & COMEDI_CB_EOA) == 0) {
  1158. set_dma_addr(devpriv->dma_chan,
  1159. devpriv->dma_buffer_addr[devpriv->current_buffer]);
  1160. set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
  1161. enable_dma(devpriv->dma_chan);
  1162. /* reenable conversions for das1600 mode, (stupid hardware) */
  1163. if (thisboard->size > 0x400 && devpriv->timer_mode == 0)
  1164. outb(0x00, dev->iobase + DAS1600_CONV);
  1165. }
  1166. release_dma_lock(dma_flags);
  1167. spin_unlock_irqrestore(&dev->spinlock, spin_flags);
  1168. cfc_write_array_to_buffer(s,
  1169. devpriv->dma_buffer[buffer_index], num_bytes);
  1170. cfc_handle_events(dev, s);
  1171. }
  1172. static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
  1173. int rounding_flags)
  1174. {
  1175. i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
  1176. &(devpriv->divisor2), &ns,
  1177. rounding_flags & TRIG_ROUND_MASK);
  1178. /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
  1179. i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
  1180. i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
  1181. return ns;
  1182. }
  1183. static void reg_dump(struct comedi_device *dev)
  1184. {
  1185. DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
  1186. DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
  1187. DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
  1188. DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
  1189. DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
  1190. DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
  1191. DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
  1192. DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
  1193. inb(dev->iobase + DAS16_CNTR_CONTROL));
  1194. DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
  1195. DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
  1196. DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
  1197. DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
  1198. inb(dev->iobase + DAS1600_STATUS_B));
  1199. }
  1200. static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
  1201. {
  1202. int status;
  1203. int diobits;
  1204. /* status is available on all boards */
  1205. status = inb(dev->iobase + DAS16_STATUS);
  1206. if ((status & UNIPOLAR))
  1207. devpriv->ai_unipolar = 1;
  1208. else
  1209. devpriv->ai_unipolar = 0;
  1210. if ((status & DAS16_MUXBIT))
  1211. devpriv->ai_singleended = 1;
  1212. else
  1213. devpriv->ai_singleended = 0;
  1214. /* diobits indicates boards */
  1215. diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
  1216. printk(KERN_INFO " id bits are 0x%02x\n", diobits);
  1217. if (thisboard->id != diobits) {
  1218. printk(KERN_INFO " requested board's id bits are 0x%x (ignore)\n",
  1219. thisboard->id);
  1220. }
  1221. return 0;
  1222. }
  1223. static int das1600_mode_detect(struct comedi_device *dev)
  1224. {
  1225. int status = 0;
  1226. status = inb(dev->iobase + DAS1600_STATUS_B);
  1227. if (status & DAS1600_CLK_10MHZ) {
  1228. devpriv->clockbase = 100;
  1229. printk(KERN_INFO " 10MHz pacer clock\n");
  1230. } else {
  1231. devpriv->clockbase = 1000;
  1232. printk(KERN_INFO " 1MHz pacer clock\n");
  1233. }
  1234. reg_dump(dev);
  1235. return 0;
  1236. }
  1237. /*
  1238. *
  1239. * Options list:
  1240. * 0 I/O base
  1241. * 1 IRQ
  1242. * 2 DMA
  1243. * 3 Clock speed (in MHz)
  1244. */
  1245. static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
  1246. {
  1247. struct comedi_subdevice *s;
  1248. int ret;
  1249. unsigned int irq;
  1250. unsigned long iobase;
  1251. unsigned int dma_chan;
  1252. int timer_mode;
  1253. unsigned long flags;
  1254. struct comedi_krange *user_ai_range, *user_ao_range;
  1255. iobase = it->options[0];
  1256. #if 0
  1257. irq = it->options[1];
  1258. timer_mode = it->options[8];
  1259. #endif
  1260. /* always use time_mode since using irq can drop samples while
  1261. * waiting for dma done interrupt (due to hardware limitations) */
  1262. irq = 0;
  1263. timer_mode = 1;
  1264. if (timer_mode)
  1265. irq = 0;
  1266. printk(KERN_INFO "comedi%d: das16:", dev->minor);
  1267. /* check that clock setting is valid */
  1268. if (it->options[3]) {
  1269. if (it->options[3] != 0 &&
  1270. it->options[3] != 1 && it->options[3] != 10) {
  1271. printk
  1272. ("\n Invalid option. Master clock must be set "
  1273. "to 1 or 10 (MHz)\n");
  1274. return -EINVAL;
  1275. }
  1276. }
  1277. ret = alloc_private(dev, sizeof(struct das16_private_struct));
  1278. if (ret < 0)
  1279. return ret;
  1280. if (thisboard->size < 0x400) {
  1281. printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size);
  1282. if (!request_region(iobase, thisboard->size, "das16")) {
  1283. printk(KERN_ERR " I/O port conflict\n");
  1284. return -EIO;
  1285. }
  1286. } else {
  1287. printk(KERN_INFO " 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
  1288. iobase, iobase + 0x0f,
  1289. iobase + 0x400,
  1290. iobase + 0x400 + (thisboard->size & 0x3ff));
  1291. if (!request_region(iobase, 0x10, "das16")) {
  1292. printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n",
  1293. iobase, iobase + 0x0f);
  1294. return -EIO;
  1295. }
  1296. if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
  1297. "das16")) {
  1298. release_region(iobase, 0x10);
  1299. printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n",
  1300. iobase + 0x400,
  1301. iobase + 0x400 + (thisboard->size & 0x3ff));
  1302. return -EIO;
  1303. }
  1304. }
  1305. dev->iobase = iobase;
  1306. /* probe id bits to make sure they are consistent */
  1307. if (das16_probe(dev, it)) {
  1308. printk(KERN_ERR " id bits do not match selected board, aborting\n");
  1309. return -EINVAL;
  1310. }
  1311. dev->board_name = thisboard->name;
  1312. /* get master clock speed */
  1313. if (thisboard->size < 0x400) {
  1314. if (it->options[3])
  1315. devpriv->clockbase = 1000 / it->options[3];
  1316. else
  1317. devpriv->clockbase = 1000; /* 1 MHz default */
  1318. } else {
  1319. das1600_mode_detect(dev);
  1320. }
  1321. /* now for the irq */
  1322. if (irq > 1 && irq < 8) {
  1323. ret = request_irq(irq, das16_dma_interrupt, 0, "das16", dev);
  1324. if (ret < 0)
  1325. return ret;
  1326. dev->irq = irq;
  1327. printk(KERN_INFO " ( irq = %u )", irq);
  1328. } else if (irq == 0) {
  1329. printk(" ( no irq )");
  1330. } else {
  1331. printk(" invalid irq\n");
  1332. return -EINVAL;
  1333. }
  1334. /* initialize dma */
  1335. dma_chan = it->options[2];
  1336. if (dma_chan == 1 || dma_chan == 3) {
  1337. /* allocate dma buffers */
  1338. int i;
  1339. for (i = 0; i < 2; i++) {
  1340. devpriv->dma_buffer[i] = pci_alloc_consistent(
  1341. NULL, DAS16_DMA_SIZE,
  1342. &devpriv->dma_buffer_addr[i]);
  1343. if (devpriv->dma_buffer[i] == NULL)
  1344. return -ENOMEM;
  1345. }
  1346. if (request_dma(dma_chan, "das16")) {
  1347. printk(KERN_ERR " failed to allocate dma channel %i\n",
  1348. dma_chan);
  1349. return -EINVAL;
  1350. }
  1351. devpriv->dma_chan = dma_chan;
  1352. flags = claim_dma_lock();
  1353. disable_dma(devpriv->dma_chan);
  1354. set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
  1355. release_dma_lock(flags);
  1356. printk(KERN_INFO " ( dma = %u)\n", dma_chan);
  1357. } else if (dma_chan == 0) {
  1358. printk(KERN_INFO " ( no dma )\n");
  1359. } else {
  1360. printk(KERN_ERR " invalid dma channel\n");
  1361. return -EINVAL;
  1362. }
  1363. /* get any user-defined input range */
  1364. if (thisboard->ai_pg == das16_pg_none &&
  1365. (it->options[4] || it->options[5])) {
  1366. /* allocate single-range range table */
  1367. devpriv->user_ai_range_table =
  1368. kmalloc(sizeof(struct comedi_lrange) +
  1369. sizeof(struct comedi_krange), GFP_KERNEL);
  1370. /* initialize ai range */
  1371. devpriv->user_ai_range_table->length = 1;
  1372. user_ai_range = devpriv->user_ai_range_table->range;
  1373. user_ai_range->min = it->options[4];
  1374. user_ai_range->max = it->options[5];
  1375. user_ai_range->flags = UNIT_volt;
  1376. }
  1377. /* get any user-defined output range */
  1378. if (it->options[6] || it->options[7]) {
  1379. /* allocate single-range range table */
  1380. devpriv->user_ao_range_table =
  1381. kmalloc(sizeof(struct comedi_lrange) +
  1382. sizeof(struct comedi_krange), GFP_KERNEL);
  1383. /* initialize ao range */
  1384. devpriv->user_ao_range_table->length = 1;
  1385. user_ao_range = devpriv->user_ao_range_table->range;
  1386. user_ao_range->min = it->options[6];
  1387. user_ao_range->max = it->options[7];
  1388. user_ao_range->flags = UNIT_volt;
  1389. }
  1390. if (timer_mode) {
  1391. init_timer(&(devpriv->timer));
  1392. devpriv->timer.function = das16_timer_interrupt;
  1393. devpriv->timer.data = (unsigned long)dev;
  1394. }
  1395. devpriv->timer_mode = timer_mode ? 1 : 0;
  1396. ret = alloc_subdevices(dev, 5);
  1397. if (ret < 0)
  1398. return ret;
  1399. s = dev->subdevices + 0;
  1400. dev->read_subdev = s;
  1401. /* ai */
  1402. if (thisboard->ai) {
  1403. s->type = COMEDI_SUBD_AI;
  1404. s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
  1405. if (devpriv->ai_singleended) {
  1406. s->n_chan = 16;
  1407. s->len_chanlist = 16;
  1408. s->subdev_flags |= SDF_GROUND;
  1409. } else {
  1410. s->n_chan = 8;
  1411. s->len_chanlist = 8;
  1412. s->subdev_flags |= SDF_DIFF;
  1413. }
  1414. s->maxdata = (1 << thisboard->ai_nbits) - 1;
  1415. if (devpriv->user_ai_range_table) { /* user defined ai range */
  1416. s->range_table = devpriv->user_ai_range_table;
  1417. } else if (devpriv->ai_unipolar) {
  1418. s->range_table = das16_ai_uni_lranges[thisboard->ai_pg];
  1419. } else {
  1420. s->range_table = das16_ai_bip_lranges[thisboard->ai_pg];
  1421. }
  1422. s->insn_read = thisboard->ai;
  1423. s->do_cmdtest = das16_cmd_test;
  1424. s->do_cmd = das16_cmd_exec;
  1425. s->cancel = das16_cancel;
  1426. s->munge = das16_ai_munge;
  1427. } else {
  1428. s->type = COMEDI_SUBD_UNUSED;
  1429. }
  1430. s = dev->subdevices + 1;
  1431. /* ao */
  1432. if (thisboard->ao) {
  1433. s->type = COMEDI_SUBD_AO;
  1434. s->subdev_flags = SDF_WRITABLE;
  1435. s->n_chan = 2;
  1436. s->maxdata = (1 << thisboard->ao_nbits) - 1;
  1437. /* user defined ao range */
  1438. if (devpriv->user_ao_range_table)
  1439. s->range_table = devpriv->user_ao_range_table;
  1440. else
  1441. s->range_table = &range_unknown;
  1442. s->insn_write = thisboard->ao;
  1443. } else {
  1444. s->type = COMEDI_SUBD_UNUSED;
  1445. }
  1446. s = dev->subdevices + 2;
  1447. /* di */
  1448. if (thisboard->di) {
  1449. s->type = COMEDI_SUBD_DI;
  1450. s->subdev_flags = SDF_READABLE;
  1451. s->n_chan = 4;
  1452. s->maxdata = 1;
  1453. s->range_table = &range_digital;
  1454. s->insn_bits = thisboard->di;
  1455. } else {
  1456. s->type = COMEDI_SUBD_UNUSED;
  1457. }
  1458. s = dev->subdevices + 3;
  1459. /* do */
  1460. if (thisboard->do_) {
  1461. s->type = COMEDI_SUBD_DO;
  1462. s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
  1463. s->n_chan = 4;
  1464. s->maxdata = 1;
  1465. s->range_table = &range_digital;
  1466. s->insn_bits = thisboard->do_;
  1467. /* initialize digital output lines */
  1468. outb(s->state, dev->iobase + DAS16_DIO);
  1469. } else {
  1470. s->type = COMEDI_SUBD_UNUSED;
  1471. }
  1472. s = dev->subdevices + 4;
  1473. /* 8255 */
  1474. if (thisboard->i8255_offset != 0) {
  1475. subdev_8255_init(dev, s, NULL, (dev->iobase +
  1476. thisboard->i8255_offset));
  1477. } else {
  1478. s->type = COMEDI_SUBD_UNUSED;
  1479. }
  1480. das16_reset(dev);
  1481. /* set the interrupt level */
  1482. devpriv->control_state = DAS16_IRQ(dev->irq);
  1483. outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
  1484. /* turn on das1600 mode if available */
  1485. if (thisboard->size > 0x400) {
  1486. outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
  1487. outb(0, dev->iobase + DAS1600_CONV);
  1488. outb(0, dev->iobase + DAS1600_BURST);
  1489. }
  1490. return 0;
  1491. }
  1492. static int das16_detach(struct comedi_device *dev)
  1493. {
  1494. printk(KERN_INFO "comedi%d: das16: remove\n", dev->minor);
  1495. das16_reset(dev);
  1496. if (dev->subdevices)
  1497. subdev_8255_cleanup(dev, dev->subdevices + 4);
  1498. if (devpriv) {
  1499. int i;
  1500. for (i = 0; i < 2; i++) {
  1501. if (devpriv->dma_buffer[i])
  1502. pci_free_consistent(NULL, DAS16_DMA_SIZE,
  1503. devpriv->dma_buffer[i],
  1504. devpriv->
  1505. dma_buffer_addr[i]);
  1506. }
  1507. if (devpriv->dma_chan)
  1508. free_dma(devpriv->dma_chan);
  1509. kfree(devpriv->user_ai_range_table);
  1510. kfree(devpriv->user_ao_range_table);
  1511. }
  1512. if (dev->irq)
  1513. free_irq(dev->irq, dev);
  1514. if (dev->iobase) {
  1515. if (thisboard->size < 0x400) {
  1516. release_region(dev->iobase, thisboard->size);
  1517. } else {
  1518. release_region(dev->iobase, 0x10);
  1519. release_region(dev->iobase + 0x400,
  1520. thisboard->size & 0x3ff);
  1521. }
  1522. }
  1523. return 0;
  1524. }
  1525. static int __init driver_das16_init_module(void)
  1526. {
  1527. return comedi_driver_register(&driver_das16);
  1528. }
  1529. static void __exit driver_das16_cleanup_module(void)
  1530. {
  1531. comedi_driver_unregister(&driver_das16);
  1532. }
  1533. module_init(driver_das16_init_module);
  1534. module_exit(driver_das16_cleanup_module);
  1535. /* utility function that suggests a dma transfer size in bytes */
  1536. static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
  1537. struct comedi_cmd cmd)
  1538. {
  1539. unsigned int size;
  1540. unsigned int freq;
  1541. /* if we are using timer interrupt, we don't care how long it
  1542. * will take to complete transfer since it will be interrupted
  1543. * by timer interrupt */
  1544. if (devpriv->timer_mode)
  1545. return DAS16_DMA_SIZE;
  1546. /* otherwise, we are relying on dma terminal count interrupt,
  1547. * so pick a reasonable size */
  1548. if (cmd.convert_src == TRIG_TIMER)
  1549. freq = 1000000000 / cmd.convert_arg;
  1550. else if (cmd.scan_begin_src == TRIG_TIMER)
  1551. freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
  1552. /* return some default value */
  1553. else
  1554. freq = 0xffffffff;
  1555. if (cmd.flags & TRIG_WAKE_EOS) {
  1556. size = sample_size * cmd.chanlist_len;
  1557. } else {
  1558. /* make buffer fill in no more than 1/3 second */
  1559. size = (freq / 3) * sample_size;
  1560. }
  1561. /* set a minimum and maximum size allowed */
  1562. if (size > DAS16_DMA_SIZE)
  1563. size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
  1564. else if (size < sample_size)
  1565. size = sample_size;
  1566. if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
  1567. size = devpriv->adc_byte_count;
  1568. return size;
  1569. }
  1570. static void das16_ai_munge(struct comedi_device *dev,
  1571. struct comedi_subdevice *s, void *array,
  1572. unsigned int num_bytes,
  1573. unsigned int start_chan_index)
  1574. {
  1575. unsigned int i, num_samples = num_bytes / sizeof(short);
  1576. short *data = array;
  1577. for (i = 0; i < num_samples; i++) {
  1578. data[i] = le16_to_cpu(data[i]);
  1579. if (thisboard->ai_nbits == 12)
  1580. data[i] = (data[i] >> 4) & 0xfff;
  1581. }
  1582. }
  1583. MODULE_AUTHOR("Comedi http://www.comedi.org");
  1584. MODULE_DESCRIPTION("Comedi low-level driver");
  1585. MODULE_LICENSE("GPL");