staging: comedi: remove inline alloc_private()
[deliverable/linux.git] / drivers / staging / comedi / drivers / ni_pcidio.c
1 /*
2 comedi/drivers/ni_pcidio.c
3 driver for National Instruments PCI-DIO-32HS
4
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
7
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
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23 /*
24 Driver: ni_pcidio
25 Description: National Instruments PCI-DIO32HS, PCI-6533
26 Author: ds
27 Status: works
28 Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio)
29 [National Instruments] PXI-6533, PCI-6533 (pxi-6533)
30 [National Instruments] PCI-6534 (pci-6534)
31 Updated: Mon, 09 Jan 2012 14:27:23 +0000
32
33 The DIO32HS board appears as one subdevice, with 32 channels.
34 Each channel is individually I/O configurable. The channel order
35 is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only
36 supports simple digital I/O; no handshaking is supported.
37
38 DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
39
40 The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
41 scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting
42 scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the
43 trailing edge.
44
45 This driver could be easily modified to support AT-MIO32HS and
46 AT-MIO96.
47
48 The PCI-6534 requires a firmware upload after power-up to work, the
49 firmware data and instructions for loading it with comedi_config
50 it are contained in the
51 comedi_nonfree_firmware tarball available from http://www.comedi.org
52 */
53
54 #define USE_DMA
55 /* #define DEBUG 1 */
56 /* #define DEBUG_FLAGS */
57
58 #include <linux/interrupt.h>
59 #include <linux/sched.h>
60 #include <linux/firmware.h>
61 #include "../comedidev.h"
62
63 #include "comedi_fc.h"
64 #include "mite.h"
65
66 #undef DPRINTK
67 #ifdef DEBUG
68 #define DPRINTK(format, args...) pr_debug(format, ## args)
69 #else
70 #define DPRINTK(format, args...) do { } while (0)
71 #endif
72
73 #define PCI_DIO_SIZE 4096
74 #define PCI_MITE_SIZE 4096
75
76 /* defines for the PCI-DIO-32HS */
77
78 #define Window_Address 4 /* W */
79 #define Interrupt_And_Window_Status 4 /* R */
80 #define IntStatus1 (1<<0)
81 #define IntStatus2 (1<<1)
82 #define WindowAddressStatus_mask 0x7c
83
84 #define Master_DMA_And_Interrupt_Control 5 /* W */
85 #define InterruptLine(x) ((x)&3)
86 #define OpenInt (1<<2)
87 #define Group_Status 5 /* R */
88 #define DataLeft (1<<0)
89 #define Req (1<<2)
90 #define StopTrig (1<<3)
91
92 #define Group_1_Flags 6 /* R */
93 #define Group_2_Flags 7 /* R */
94 #define TransferReady (1<<0)
95 #define CountExpired (1<<1)
96 #define Waited (1<<5)
97 #define PrimaryTC (1<<6)
98 #define SecondaryTC (1<<7)
99 /* #define SerialRose */
100 /* #define ReqRose */
101 /* #define Paused */
102
103 #define Group_1_First_Clear 6 /* W */
104 #define Group_2_First_Clear 7 /* W */
105 #define ClearWaited (1<<3)
106 #define ClearPrimaryTC (1<<4)
107 #define ClearSecondaryTC (1<<5)
108 #define DMAReset (1<<6)
109 #define FIFOReset (1<<7)
110 #define ClearAll 0xf8
111
112 #define Group_1_FIFO 8 /* W */
113 #define Group_2_FIFO 12 /* W */
114
115 #define Transfer_Count 20
116 #define Chip_ID_D 24
117 #define Chip_ID_I 25
118 #define Chip_ID_O 26
119 #define Chip_Version 27
120 #define Port_IO(x) (28+(x))
121 #define Port_Pin_Directions(x) (32+(x))
122 #define Port_Pin_Mask(x) (36+(x))
123 #define Port_Pin_Polarities(x) (40+(x))
124
125 #define Master_Clock_Routing 45
126 #define RTSIClocking(x) (((x)&3)<<4)
127
128 #define Group_1_Second_Clear 46 /* W */
129 #define Group_2_Second_Clear 47 /* W */
130 #define ClearExpired (1<<0)
131
132 #define Port_Pattern(x) (48+(x))
133
134 #define Data_Path 64
135 #define FIFOEnableA (1<<0)
136 #define FIFOEnableB (1<<1)
137 #define FIFOEnableC (1<<2)
138 #define FIFOEnableD (1<<3)
139 #define Funneling(x) (((x)&3)<<4)
140 #define GroupDirection (1<<7)
141
142 #define Protocol_Register_1 65
143 #define OpMode Protocol_Register_1
144 #define RunMode(x) ((x)&7)
145 #define Numbered (1<<3)
146
147 #define Protocol_Register_2 66
148 #define ClockReg Protocol_Register_2
149 #define ClockLine(x) (((x)&3)<<5)
150 #define InvertStopTrig (1<<7)
151 #define DataLatching(x) (((x)&3)<<5)
152
153 #define Protocol_Register_3 67
154 #define Sequence Protocol_Register_3
155
156 #define Protocol_Register_14 68 /* 16 bit */
157 #define ClockSpeed Protocol_Register_14
158
159 #define Protocol_Register_4 70
160 #define ReqReg Protocol_Register_4
161 #define ReqConditioning(x) (((x)&7)<<3)
162
163 #define Protocol_Register_5 71
164 #define BlockMode Protocol_Register_5
165
166 #define FIFO_Control 72
167 #define ReadyLevel(x) ((x)&7)
168
169 #define Protocol_Register_6 73
170 #define LinePolarities Protocol_Register_6
171 #define InvertAck (1<<0)
172 #define InvertReq (1<<1)
173 #define InvertClock (1<<2)
174 #define InvertSerial (1<<3)
175 #define OpenAck (1<<4)
176 #define OpenClock (1<<5)
177
178 #define Protocol_Register_7 74
179 #define AckSer Protocol_Register_7
180 #define AckLine(x) (((x)&3)<<2)
181 #define ExchangePins (1<<7)
182
183 #define Interrupt_Control 75
184 /* bits same as flags */
185
186 #define DMA_Line_Control_Group1 76
187 #define DMA_Line_Control_Group2 108
188 /* channel zero is none */
189 static inline unsigned primary_DMAChannel_bits(unsigned channel)
190 {
191 return channel & 0x3;
192 }
193
194 static inline unsigned secondary_DMAChannel_bits(unsigned channel)
195 {
196 return (channel << 2) & 0xc;
197 }
198
199 #define Transfer_Size_Control 77
200 #define TransferWidth(x) ((x)&3)
201 #define TransferLength(x) (((x)&3)<<3)
202 #define RequireRLevel (1<<5)
203
204 #define Protocol_Register_15 79
205 #define DAQOptions Protocol_Register_15
206 #define StartSource(x) ((x)&0x3)
207 #define InvertStart (1<<2)
208 #define StopSource(x) (((x)&0x3)<<3)
209 #define ReqStart (1<<6)
210 #define PreStart (1<<7)
211
212 #define Pattern_Detection 81
213 #define DetectionMethod (1<<0)
214 #define InvertMatch (1<<1)
215 #define IE_Pattern_Detection (1<<2)
216
217 #define Protocol_Register_9 82
218 #define ReqDelay Protocol_Register_9
219
220 #define Protocol_Register_10 83
221 #define ReqNotDelay Protocol_Register_10
222
223 #define Protocol_Register_11 84
224 #define AckDelay Protocol_Register_11
225
226 #define Protocol_Register_12 85
227 #define AckNotDelay Protocol_Register_12
228
229 #define Protocol_Register_13 86
230 #define Data1Delay Protocol_Register_13
231
232 #define Protocol_Register_8 88 /* 32 bit */
233 #define StartDelay Protocol_Register_8
234
235 /* Firmware files for PCI-6524 */
236 #define FW_PCI_6534_MAIN "ni6534a.bin"
237 #define FW_PCI_6534_SCARAB_DI "niscrb01.bin"
238 #define FW_PCI_6534_SCARAB_DO "niscrb02.bin"
239 MODULE_FIRMWARE(FW_PCI_6534_MAIN);
240 MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DI);
241 MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DO);
242
243 enum pci_6534_firmware_registers { /* 16 bit */
244 Firmware_Control_Register = 0x100,
245 Firmware_Status_Register = 0x104,
246 Firmware_Data_Register = 0x108,
247 Firmware_Mask_Register = 0x10c,
248 Firmware_Debug_Register = 0x110,
249 };
250 /* main fpga registers (32 bit)*/
251 enum pci_6534_fpga_registers {
252 FPGA_Control1_Register = 0x200,
253 FPGA_Control2_Register = 0x204,
254 FPGA_Irq_Mask_Register = 0x208,
255 FPGA_Status_Register = 0x20c,
256 FPGA_Signature_Register = 0x210,
257 FPGA_SCALS_Counter_Register = 0x280, /*write-clear */
258 FPGA_SCAMS_Counter_Register = 0x284, /*write-clear */
259 FPGA_SCBLS_Counter_Register = 0x288, /*write-clear */
260 FPGA_SCBMS_Counter_Register = 0x28c, /*write-clear */
261 FPGA_Temp_Control_Register = 0x2a0,
262 FPGA_DAR_Register = 0x2a8,
263 FPGA_ELC_Read_Register = 0x2b8,
264 FPGA_ELC_Write_Register = 0x2bc,
265 };
266 enum FPGA_Control_Bits {
267 FPGA_Enable_Bit = 0x8000,
268 };
269
270 #define TIMER_BASE 50 /* nanoseconds */
271
272 #ifdef USE_DMA
273 #define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
274 #else
275 #define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
276 #endif
277
278 static int ni_pcidio_cancel(struct comedi_device *dev,
279 struct comedi_subdevice *s);
280
281 struct nidio_board {
282 int dev_id;
283 const char *name;
284 unsigned int uses_firmware:1;
285 };
286
287 static const struct nidio_board nidio_boards[] = {
288 {
289 .dev_id = 0x1150,
290 .name = "pci-dio-32hs",
291 }, {
292 .dev_id = 0x1320,
293 .name = "pxi-6533",
294 }, {
295 .dev_id = 0x12b0,
296 .name = "pci-6534",
297 .uses_firmware = 1,
298 },
299 };
300
301 #define n_nidio_boards ARRAY_SIZE(nidio_boards)
302 #define this_board ((const struct nidio_board *)dev->board_ptr)
303
304 struct nidio96_private {
305 struct mite_struct *mite;
306 int boardtype;
307 int dio;
308 unsigned short OpModeBits;
309 struct mite_channel *di_mite_chan;
310 struct mite_dma_descriptor_ring *di_mite_ring;
311 spinlock_t mite_channel_lock;
312 };
313
314 static int ni_pcidio_cmdtest(struct comedi_device *dev,
315 struct comedi_subdevice *s,
316 struct comedi_cmd *cmd);
317 static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
318 static int ni_pcidio_inttrig(struct comedi_device *dev,
319 struct comedi_subdevice *s, unsigned int trignum);
320 static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
321 static int setup_mite_dma(struct comedi_device *dev,
322 struct comedi_subdevice *s);
323
324 #ifdef DEBUG_FLAGS
325 static void ni_pcidio_print_flags(unsigned int flags);
326 static void ni_pcidio_print_status(unsigned int status);
327 #else
328 #define ni_pcidio_print_flags(x)
329 #define ni_pcidio_print_status(x)
330 #endif
331
332 static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
333 {
334 struct nidio96_private *devpriv = dev->private;
335 unsigned long flags;
336
337 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
338 BUG_ON(devpriv->di_mite_chan);
339 devpriv->di_mite_chan =
340 mite_request_channel_in_range(devpriv->mite,
341 devpriv->di_mite_ring, 1, 2);
342 if (devpriv->di_mite_chan == NULL) {
343 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
344 comedi_error(dev, "failed to reserve mite dma channel.");
345 return -EBUSY;
346 }
347 devpriv->di_mite_chan->dir = COMEDI_INPUT;
348 writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
349 secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
350 devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
351 mmiowb();
352 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
353 return 0;
354 }
355
356 static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
357 {
358 struct nidio96_private *devpriv = dev->private;
359 unsigned long flags;
360
361 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
362 if (devpriv->di_mite_chan) {
363 mite_dma_disarm(devpriv->di_mite_chan);
364 mite_dma_reset(devpriv->di_mite_chan);
365 mite_release_channel(devpriv->di_mite_chan);
366 devpriv->di_mite_chan = NULL;
367 writeb(primary_DMAChannel_bits(0) |
368 secondary_DMAChannel_bits(0),
369 devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
370 mmiowb();
371 }
372 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
373 }
374
375 static void ni_pcidio_event(struct comedi_device *dev,
376 struct comedi_subdevice *s)
377 {
378 if (s->
379 async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
380 COMEDI_CB_OVERFLOW)) {
381 ni_pcidio_cancel(dev, s);
382 }
383 comedi_event(dev, s);
384 }
385
386 static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
387 {
388 struct nidio96_private *devpriv = dev->private;
389 unsigned long irq_flags;
390 int count;
391
392 spin_lock_irqsave(&dev->spinlock, irq_flags);
393 spin_lock(&devpriv->mite_channel_lock);
394 if (devpriv->di_mite_chan)
395 mite_sync_input_dma(devpriv->di_mite_chan, s->async);
396 spin_unlock(&devpriv->mite_channel_lock);
397 count = s->async->buf_write_count - s->async->buf_read_count;
398 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
399 return count;
400 }
401
402 static irqreturn_t nidio_interrupt(int irq, void *d)
403 {
404 struct comedi_device *dev = d;
405 struct nidio96_private *devpriv = dev->private;
406 struct comedi_subdevice *s = &dev->subdevices[0];
407 struct comedi_async *async = s->async;
408 struct mite_struct *mite = devpriv->mite;
409
410 /* int i, j; */
411 long int AuxData = 0;
412 short data1 = 0;
413 short data2 = 0;
414 int flags;
415 int status;
416 int work = 0;
417 unsigned int m_status = 0;
418
419 /* interrupcions parasites */
420 if (dev->attached == 0) {
421 /* assume it's from another card */
422 return IRQ_NONE;
423 }
424
425 /* Lock to avoid race with comedi_poll */
426 spin_lock(&dev->spinlock);
427
428 status = readb(devpriv->mite->daq_io_addr +
429 Interrupt_And_Window_Status);
430 flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
431
432 DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
433 status, flags);
434 ni_pcidio_print_flags(flags);
435 ni_pcidio_print_status(status);
436
437 spin_lock(&devpriv->mite_channel_lock);
438 if (devpriv->di_mite_chan)
439 m_status = mite_get_status(devpriv->di_mite_chan);
440 #ifdef MITE_DEBUG
441 mite_print_chsr(m_status);
442 #endif
443
444 /* mite_dump_regs(mite); */
445 if (m_status & CHSR_INT) {
446 if (m_status & CHSR_LINKC) {
447 writel(CHOR_CLRLC,
448 mite->mite_io_addr +
449 MITE_CHOR(devpriv->di_mite_chan->channel));
450 mite_sync_input_dma(devpriv->di_mite_chan, s->async);
451 /* XXX need to byteswap */
452 }
453 if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
454 CHSR_DRQ1 | CHSR_MRDY)) {
455 DPRINTK("unknown mite interrupt, disabling IRQ\n");
456 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
457 disable_irq(dev->irq);
458 }
459 }
460 spin_unlock(&devpriv->mite_channel_lock);
461
462 while (status & DataLeft) {
463 work++;
464 if (work > 20) {
465 DPRINTK("too much work in interrupt\n");
466 writeb(0x00,
467 devpriv->mite->daq_io_addr +
468 Master_DMA_And_Interrupt_Control);
469 break;
470 }
471
472 flags &= IntEn;
473
474 if (flags & TransferReady) {
475 /* DPRINTK("TransferReady\n"); */
476 while (flags & TransferReady) {
477 work++;
478 if (work > 100) {
479 DPRINTK("too much work in interrupt\n");
480 writeb(0x00,
481 devpriv->mite->daq_io_addr +
482 Master_DMA_And_Interrupt_Control
483 );
484 goto out;
485 }
486 AuxData =
487 readl(devpriv->mite->daq_io_addr +
488 Group_1_FIFO);
489 data1 = AuxData & 0xffff;
490 data2 = (AuxData & 0xffff0000) >> 16;
491 comedi_buf_put(async, data1);
492 comedi_buf_put(async, data2);
493 /* DPRINTK("read:%d, %d\n",data1,data2); */
494 flags = readb(devpriv->mite->daq_io_addr +
495 Group_1_Flags);
496 }
497 /* DPRINTK("buf_int_count: %d\n",
498 async->buf_int_count); */
499 /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",
500 IntEn,flags,status); */
501 /* ni_pcidio_print_flags(flags); */
502 /* ni_pcidio_print_status(status); */
503 async->events |= COMEDI_CB_BLOCK;
504 }
505
506 if (flags & CountExpired) {
507 DPRINTK("CountExpired\n");
508 writeb(ClearExpired,
509 devpriv->mite->daq_io_addr +
510 Group_1_Second_Clear);
511 async->events |= COMEDI_CB_EOA;
512
513 writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
514 break;
515 } else if (flags & Waited) {
516 DPRINTK("Waited\n");
517 writeb(ClearWaited,
518 devpriv->mite->daq_io_addr +
519 Group_1_First_Clear);
520 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
521 break;
522 } else if (flags & PrimaryTC) {
523 DPRINTK("PrimaryTC\n");
524 writeb(ClearPrimaryTC,
525 devpriv->mite->daq_io_addr +
526 Group_1_First_Clear);
527 async->events |= COMEDI_CB_EOA;
528 } else if (flags & SecondaryTC) {
529 DPRINTK("SecondaryTC\n");
530 writeb(ClearSecondaryTC,
531 devpriv->mite->daq_io_addr +
532 Group_1_First_Clear);
533 async->events |= COMEDI_CB_EOA;
534 }
535 #if 0
536 else {
537 DPRINTK("ni_pcidio: unknown interrupt\n");
538 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
539 writeb(0x00,
540 devpriv->mite->daq_io_addr +
541 Master_DMA_And_Interrupt_Control);
542 }
543 #endif
544 flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
545 status = readb(devpriv->mite->daq_io_addr +
546 Interrupt_And_Window_Status);
547 /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,"
548 "status=0x%02x\n", IntEn, flags, status); */
549 /* ni_pcidio_print_flags(flags); */
550 /* ni_pcidio_print_status(status); */
551 }
552
553 out:
554 ni_pcidio_event(dev, s);
555 #if 0
556 if (!tag) {
557 writeb(0x03,
558 devpriv->mite->daq_io_addr +
559 Master_DMA_And_Interrupt_Control);
560 }
561 #endif
562
563 spin_unlock(&dev->spinlock);
564 return IRQ_HANDLED;
565 }
566
567 #ifdef DEBUG_FLAGS
568 static const char *bit_set_string(unsigned int bits, unsigned int bit,
569 const char *const strings[])
570 {
571 return (bits & (1U << bit)) ? strings[bit] : "";
572 }
573
574 static const char *const flags_strings[] = {
575 " TransferReady", " CountExpired", " 2", " 3",
576 " 4", " Waited", " PrimaryTC", " SecondaryTC",
577 };
578
579
580 static void ni_pcidio_print_flags(unsigned int flags)
581 {
582 pr_debug("group_1_flags:%s%s%s%s%s%s%s%s\n",
583 bit_set_string(flags, 7, flags_strings),
584 bit_set_string(flags, 6, flags_strings),
585 bit_set_string(flags, 5, flags_strings),
586 bit_set_string(flags, 4, flags_strings),
587 bit_set_string(flags, 3, flags_strings),
588 bit_set_string(flags, 2, flags_strings),
589 bit_set_string(flags, 1, flags_strings),
590 bit_set_string(flags, 0, flags_strings));
591 }
592
593 static const char *const status_strings[] = {
594 " DataLeft1", " Reserved1", " Req1", " StopTrig1",
595 " DataLeft2", " Reserved2", " Req2", " StopTrig2",
596 };
597
598 static void ni_pcidio_print_status(unsigned int flags)
599 {
600 pr_debug("group_status:%s%s%s%s%s%s%s%s\n",
601 bit_set_string(flags, 7, status_strings),
602 bit_set_string(flags, 6, status_strings),
603 bit_set_string(flags, 5, status_strings),
604 bit_set_string(flags, 4, status_strings),
605 bit_set_string(flags, 3, status_strings),
606 bit_set_string(flags, 2, status_strings),
607 bit_set_string(flags, 1, status_strings),
608 bit_set_string(flags, 0, status_strings));
609 }
610 #endif
611
612 #ifdef unused
613 static void debug_int(struct comedi_device *dev)
614 {
615 struct nidio96_private *devpriv = dev->private;
616 int a, b;
617 static int n_int;
618 struct timeval tv;
619
620 do_gettimeofday(&tv);
621 a = readb(devpriv->mite->daq_io_addr + Group_Status);
622 b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
623
624 if (n_int < 10) {
625 DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
626 (int)tv.tv_usec);
627 }
628
629 while (b & 1) {
630 writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
631 b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
632 }
633
634 b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
635
636 if (n_int < 10) {
637 DPRINTK("new status 0x%02x\n", b);
638 n_int++;
639 }
640 }
641 #endif
642
643 static int ni_pcidio_insn_config(struct comedi_device *dev,
644 struct comedi_subdevice *s,
645 struct comedi_insn *insn, unsigned int *data)
646 {
647 struct nidio96_private *devpriv = dev->private;
648
649 if (insn->n != 1)
650 return -EINVAL;
651 switch (data[0]) {
652 case INSN_CONFIG_DIO_OUTPUT:
653 s->io_bits |= 1 << CR_CHAN(insn->chanspec);
654 break;
655 case INSN_CONFIG_DIO_INPUT:
656 s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
657 break;
658 case INSN_CONFIG_DIO_QUERY:
659 data[1] =
660 (s->
661 io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
662 COMEDI_INPUT;
663 return insn->n;
664 break;
665 default:
666 return -EINVAL;
667 }
668 writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
669
670 return 1;
671 }
672
673 static int ni_pcidio_insn_bits(struct comedi_device *dev,
674 struct comedi_subdevice *s,
675 struct comedi_insn *insn, unsigned int *data)
676 {
677 struct nidio96_private *devpriv = dev->private;
678
679 if (data[0]) {
680 s->state &= ~data[0];
681 s->state |= (data[0] & data[1]);
682 writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
683 }
684 data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
685
686 return insn->n;
687 }
688
689 static int ni_pcidio_cmdtest(struct comedi_device *dev,
690 struct comedi_subdevice *s, struct comedi_cmd *cmd)
691 {
692 int err = 0;
693 int tmp;
694
695 /* Step 1 : check if triggers are trivially valid */
696
697 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
698 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
699 TRIG_TIMER | TRIG_EXT);
700 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
701 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
702 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
703
704 if (err)
705 return 1;
706
707 /* Step 2a : make sure trigger sources are unique */
708
709 err |= cfc_check_trigger_is_unique(cmd->start_src);
710 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
711 err |= cfc_check_trigger_is_unique(cmd->stop_src);
712
713 /* Step 2b : and mutually compatible */
714
715 if (err)
716 return 2;
717
718 /* step 3: make sure arguments are trivially compatible */
719
720 if (cmd->start_arg != 0) {
721 /* same for both TRIG_INT and TRIG_NOW */
722 cmd->start_arg = 0;
723 err++;
724 }
725 #define MAX_SPEED (TIMER_BASE) /* in nanoseconds */
726
727 if (cmd->scan_begin_src == TRIG_TIMER) {
728 if (cmd->scan_begin_arg < MAX_SPEED) {
729 cmd->scan_begin_arg = MAX_SPEED;
730 err++;
731 }
732 /* no minimum speed */
733 } else {
734 /* TRIG_EXT */
735 /* should be level/edge, hi/lo specification here */
736 if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) {
737 cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
738 err++;
739 }
740 }
741 if (cmd->convert_arg != 0) {
742 cmd->convert_arg = 0;
743 err++;
744 }
745
746 if (cmd->scan_end_arg != cmd->chanlist_len) {
747 cmd->scan_end_arg = cmd->chanlist_len;
748 err++;
749 }
750 if (cmd->stop_src == TRIG_COUNT) {
751 /* no limit */
752 } else {
753 /* TRIG_NONE */
754 if (cmd->stop_arg != 0) {
755 cmd->stop_arg = 0;
756 err++;
757 }
758 }
759
760 if (err)
761 return 3;
762
763 /* step 4: fix up any arguments */
764
765 if (cmd->scan_begin_src == TRIG_TIMER) {
766 tmp = cmd->scan_begin_arg;
767 ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
768 cmd->flags & TRIG_ROUND_MASK);
769 if (tmp != cmd->scan_begin_arg)
770 err++;
771 }
772
773 if (err)
774 return 4;
775
776 return 0;
777 }
778
779 static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
780 {
781 int divider, base;
782
783 base = TIMER_BASE;
784
785 switch (round_mode) {
786 case TRIG_ROUND_NEAREST:
787 default:
788 divider = (*nanosec + base / 2) / base;
789 break;
790 case TRIG_ROUND_DOWN:
791 divider = (*nanosec) / base;
792 break;
793 case TRIG_ROUND_UP:
794 divider = (*nanosec + base - 1) / base;
795 break;
796 }
797
798 *nanosec = base * divider;
799 return divider;
800 }
801
802 static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
803 {
804 struct nidio96_private *devpriv = dev->private;
805 struct comedi_cmd *cmd = &s->async->cmd;
806
807 /* XXX configure ports for input */
808 writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
809
810 if (1) {
811 /* enable fifos A B C D */
812 writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
813
814 /* set transfer width a 32 bits */
815 writeb(TransferWidth(0) | TransferLength(0),
816 devpriv->mite->daq_io_addr + Transfer_Size_Control);
817 } else {
818 writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
819 writeb(TransferWidth(3) | TransferLength(0),
820 devpriv->mite->daq_io_addr + Transfer_Size_Control);
821 }
822
823 /* protocol configuration */
824 if (cmd->scan_begin_src == TRIG_TIMER) {
825 /* page 4-5, "input with internal REQs" */
826 writeb(0, devpriv->mite->daq_io_addr + OpMode);
827 writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
828 writeb(1, devpriv->mite->daq_io_addr + Sequence);
829 writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
830 writeb(4, devpriv->mite->daq_io_addr + BlockMode);
831 writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
832 writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
833 writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
834 TRIG_ROUND_NEAREST),
835 devpriv->mite->daq_io_addr + StartDelay);
836 writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
837 writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
838 writeb(1, devpriv->mite->daq_io_addr + AckDelay);
839 writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
840 writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
841 /* manual, page 4-5: ClockSpeed comment is incorrectly listed
842 * on DAQOptions */
843 writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
844 writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
845 } else {
846 /* TRIG_EXT */
847 /* page 4-5, "input with external REQs" */
848 writeb(0, devpriv->mite->daq_io_addr + OpMode);
849 writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
850 writeb(0, devpriv->mite->daq_io_addr + Sequence);
851 writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
852 writeb(4, devpriv->mite->daq_io_addr + BlockMode);
853 if (!(cmd->scan_begin_arg & CR_INVERT)) {
854 /* Leading Edge pulse mode */
855 writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
856 } else {
857 /* Trailing Edge pulse mode */
858 writeb(2, devpriv->mite->daq_io_addr + LinePolarities);
859 }
860 writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
861 writel(1, devpriv->mite->daq_io_addr + StartDelay);
862 writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
863 writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
864 writeb(1, devpriv->mite->daq_io_addr + AckDelay);
865 writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
866 writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
867 writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
868 writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
869 }
870
871 if (cmd->stop_src == TRIG_COUNT) {
872 writel(cmd->stop_arg,
873 devpriv->mite->daq_io_addr + Transfer_Count);
874 } else {
875 /* XXX */
876 }
877
878 #ifdef USE_DMA
879 writeb(ClearPrimaryTC | ClearSecondaryTC,
880 devpriv->mite->daq_io_addr + Group_1_First_Clear);
881
882 {
883 int retval = setup_mite_dma(dev, s);
884 if (retval)
885 return retval;
886 }
887 #else
888 writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
889 #endif
890 writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
891
892 /* clear and enable interrupts */
893 writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
894 /* writeb(ClearExpired,
895 devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
896
897 writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
898 writeb(0x03,
899 devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
900
901 if (cmd->stop_src == TRIG_NONE) {
902 devpriv->OpModeBits = DataLatching(0) | RunMode(7);
903 } else { /* TRIG_TIMER */
904 devpriv->OpModeBits = Numbered | RunMode(7);
905 }
906 if (cmd->start_src == TRIG_NOW) {
907 /* start */
908 writeb(devpriv->OpModeBits,
909 devpriv->mite->daq_io_addr + OpMode);
910 s->async->inttrig = NULL;
911 } else {
912 /* TRIG_INT */
913 s->async->inttrig = ni_pcidio_inttrig;
914 }
915
916 DPRINTK("ni_pcidio: command started\n");
917 return 0;
918 }
919
920 static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
921 {
922 struct nidio96_private *devpriv = dev->private;
923 int retval;
924 unsigned long flags;
925
926 retval = ni_pcidio_request_di_mite_channel(dev);
927 if (retval)
928 return retval;
929
930 /* write alloc the entire buffer */
931 comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
932
933 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
934 if (devpriv->di_mite_chan) {
935 mite_prep_dma(devpriv->di_mite_chan, 32, 32);
936 mite_dma_arm(devpriv->di_mite_chan);
937 } else
938 retval = -EIO;
939 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
940
941 return retval;
942 }
943
944 static int ni_pcidio_inttrig(struct comedi_device *dev,
945 struct comedi_subdevice *s, unsigned int trignum)
946 {
947 struct nidio96_private *devpriv = dev->private;
948
949 if (trignum != 0)
950 return -EINVAL;
951
952 writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
953 s->async->inttrig = NULL;
954
955 return 1;
956 }
957
958 static int ni_pcidio_cancel(struct comedi_device *dev,
959 struct comedi_subdevice *s)
960 {
961 struct nidio96_private *devpriv = dev->private;
962
963 writeb(0x00,
964 devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
965 ni_pcidio_release_di_mite_channel(dev);
966
967 return 0;
968 }
969
970 static int ni_pcidio_change(struct comedi_device *dev,
971 struct comedi_subdevice *s, unsigned long new_size)
972 {
973 struct nidio96_private *devpriv = dev->private;
974 int ret;
975
976 ret = mite_buf_change(devpriv->di_mite_ring, s->async);
977 if (ret < 0)
978 return ret;
979
980 memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
981
982 return 0;
983 }
984
985 static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
986 const u8 *data, size_t data_len)
987 {
988 struct nidio96_private *devpriv = dev->private;
989 static const int timeout = 1000;
990 int i;
991 size_t j;
992
993 writew(0x80 | fpga_index,
994 devpriv->mite->daq_io_addr + Firmware_Control_Register);
995 writew(0xc0 | fpga_index,
996 devpriv->mite->daq_io_addr + Firmware_Control_Register);
997 for (i = 0;
998 (readw(devpriv->mite->daq_io_addr +
999 Firmware_Status_Register) & 0x2) == 0 && i < timeout; ++i) {
1000 udelay(1);
1001 }
1002 if (i == timeout) {
1003 dev_warn(dev->class_dev,
1004 "ni_pcidio: failed to load fpga %i, waiting for status 0x2\n",
1005 fpga_index);
1006 return -EIO;
1007 }
1008 writew(0x80 | fpga_index,
1009 devpriv->mite->daq_io_addr + Firmware_Control_Register);
1010 for (i = 0;
1011 readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
1012 0x3 && i < timeout; ++i) {
1013 udelay(1);
1014 }
1015 if (i == timeout) {
1016 dev_warn(dev->class_dev,
1017 "ni_pcidio: failed to load fpga %i, waiting for status 0x3\n",
1018 fpga_index);
1019 return -EIO;
1020 }
1021 for (j = 0; j + 1 < data_len;) {
1022 unsigned int value = data[j++];
1023 value |= data[j++] << 8;
1024 writew(value,
1025 devpriv->mite->daq_io_addr + Firmware_Data_Register);
1026 for (i = 0;
1027 (readw(devpriv->mite->daq_io_addr +
1028 Firmware_Status_Register) & 0x2) == 0
1029 && i < timeout; ++i) {
1030 udelay(1);
1031 }
1032 if (i == timeout) {
1033 dev_warn(dev->class_dev,
1034 "ni_pcidio: failed to load word into fpga %i\n",
1035 fpga_index);
1036 return -EIO;
1037 }
1038 if (need_resched())
1039 schedule();
1040 }
1041 writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1042 return 0;
1043 }
1044
1045 static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
1046 {
1047 return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
1048 }
1049
1050 static int pci_6534_reset_fpgas(struct comedi_device *dev)
1051 {
1052 struct nidio96_private *devpriv = dev->private;
1053 int ret;
1054 int i;
1055
1056 writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1057 for (i = 0; i < 3; ++i) {
1058 ret = pci_6534_reset_fpga(dev, i);
1059 if (ret < 0)
1060 break;
1061 }
1062 writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
1063 return ret;
1064 }
1065
1066 static void pci_6534_init_main_fpga(struct comedi_device *dev)
1067 {
1068 struct nidio96_private *devpriv = dev->private;
1069
1070 writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
1071 writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
1072 writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
1073 writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
1074 writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
1075 writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
1076 }
1077
1078 static int pci_6534_upload_firmware(struct comedi_device *dev)
1079 {
1080 struct nidio96_private *devpriv = dev->private;
1081 int ret;
1082 const struct firmware *fw;
1083 static const char *const fw_file[3] = {
1084 FW_PCI_6534_SCARAB_DI, /* loaded into scarab A for DI */
1085 FW_PCI_6534_SCARAB_DO, /* loaded into scarab B for DO */
1086 FW_PCI_6534_MAIN, /* loaded into main FPGA */
1087 };
1088 int n;
1089
1090 ret = pci_6534_reset_fpgas(dev);
1091 if (ret < 0)
1092 return ret;
1093 /* load main FPGA first, then the two scarabs */
1094 for (n = 2; n >= 0; n--) {
1095 ret = request_firmware(&fw, fw_file[n],
1096 &devpriv->mite->pcidev->dev);
1097 if (ret == 0) {
1098 ret = pci_6534_load_fpga(dev, n, fw->data, fw->size);
1099 if (ret == 0 && n == 2)
1100 pci_6534_init_main_fpga(dev);
1101 release_firmware(fw);
1102 }
1103 if (ret < 0)
1104 break;
1105 }
1106 return ret;
1107 }
1108
1109 static const struct nidio_board *
1110 nidio_find_boardinfo(struct pci_dev *pcidev)
1111 {
1112 unsigned int dev_id = pcidev->device;
1113 unsigned int n;
1114
1115 for (n = 0; n < ARRAY_SIZE(nidio_boards); n++) {
1116 const struct nidio_board *board = &nidio_boards[n];
1117 if (board->dev_id == dev_id)
1118 return board;
1119 }
1120 return NULL;
1121 }
1122
1123 static int __devinit nidio_attach_pci(struct comedi_device *dev,
1124 struct pci_dev *pcidev)
1125 {
1126 struct nidio96_private *devpriv;
1127 struct comedi_subdevice *s;
1128 int ret;
1129 unsigned int irq;
1130
1131 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1132 if (!devpriv)
1133 return -ENOMEM;
1134 dev->private = devpriv;
1135
1136 spin_lock_init(&devpriv->mite_channel_lock);
1137
1138 dev->board_ptr = nidio_find_boardinfo(pcidev);
1139 if (!dev->board_ptr)
1140 return -ENODEV;
1141 devpriv->mite = mite_alloc(pcidev);
1142 if (!devpriv->mite)
1143 return -ENOMEM;
1144
1145 ret = mite_setup(devpriv->mite);
1146 if (ret < 0) {
1147 dev_warn(dev->class_dev, "error setting up mite\n");
1148 return ret;
1149 }
1150 comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
1151 devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
1152 if (devpriv->di_mite_ring == NULL)
1153 return -ENOMEM;
1154
1155 dev->board_name = this_board->name;
1156 irq = mite_irq(devpriv->mite);
1157 if (this_board->uses_firmware) {
1158 ret = pci_6534_upload_firmware(dev);
1159 if (ret < 0)
1160 return ret;
1161 }
1162
1163 ret = comedi_alloc_subdevices(dev, 1);
1164 if (ret)
1165 return ret;
1166
1167 dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name,
1168 readb(devpriv->mite->daq_io_addr + Chip_Version));
1169
1170 s = &dev->subdevices[0];
1171
1172 dev->read_subdev = s;
1173 s->type = COMEDI_SUBD_DIO;
1174 s->subdev_flags =
1175 SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
1176 SDF_CMD_READ;
1177 s->n_chan = 32;
1178 s->range_table = &range_digital;
1179 s->maxdata = 1;
1180 s->insn_config = &ni_pcidio_insn_config;
1181 s->insn_bits = &ni_pcidio_insn_bits;
1182 s->do_cmd = &ni_pcidio_cmd;
1183 s->do_cmdtest = &ni_pcidio_cmdtest;
1184 s->cancel = &ni_pcidio_cancel;
1185 s->len_chanlist = 32; /* XXX */
1186 s->buf_change = &ni_pcidio_change;
1187 s->async_dma_dir = DMA_BIDIRECTIONAL;
1188 s->poll = &ni_pcidio_poll;
1189
1190 writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
1191 writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
1192 writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
1193
1194 /* disable interrupts on board */
1195 writeb(0x00,
1196 devpriv->mite->daq_io_addr +
1197 Master_DMA_And_Interrupt_Control);
1198
1199 ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
1200 "ni_pcidio", dev);
1201 if (ret < 0)
1202 dev_warn(dev->class_dev, "irq not available\n");
1203
1204 dev->irq = irq;
1205
1206 return 0;
1207 }
1208
1209 static void nidio_detach(struct comedi_device *dev)
1210 {
1211 struct nidio96_private *devpriv = dev->private;
1212
1213 if (dev->irq)
1214 free_irq(dev->irq, dev);
1215 if (devpriv) {
1216 if (devpriv->di_mite_ring) {
1217 mite_free_ring(devpriv->di_mite_ring);
1218 devpriv->di_mite_ring = NULL;
1219 }
1220 if (devpriv->mite) {
1221 mite_unsetup(devpriv->mite);
1222 mite_free(devpriv->mite);
1223 }
1224 }
1225 }
1226
1227 static struct comedi_driver ni_pcidio_driver = {
1228 .driver_name = "ni_pcidio",
1229 .module = THIS_MODULE,
1230 .attach_pci = nidio_attach_pci,
1231 .detach = nidio_detach,
1232 };
1233
1234 static int __devinit ni_pcidio_pci_probe(struct pci_dev *dev,
1235 const struct pci_device_id *ent)
1236 {
1237 return comedi_pci_auto_config(dev, &ni_pcidio_driver);
1238 }
1239
1240 static void __devexit ni_pcidio_pci_remove(struct pci_dev *dev)
1241 {
1242 comedi_pci_auto_unconfig(dev);
1243 }
1244
1245 static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
1246 { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150) },
1247 { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320) },
1248 { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0) },
1249 { 0 }
1250 };
1251 MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
1252
1253 static struct pci_driver ni_pcidio_pci_driver = {
1254 .name = "ni_pcidio",
1255 .id_table = ni_pcidio_pci_table,
1256 .probe = ni_pcidio_pci_probe,
1257 .remove = __devexit_p(ni_pcidio_pci_remove),
1258 };
1259 module_comedi_pci_driver(ni_pcidio_driver, ni_pcidio_pci_driver);
1260
1261 MODULE_AUTHOR("Comedi http://www.comedi.org");
1262 MODULE_DESCRIPTION("Comedi low-level driver");
1263 MODULE_LICENSE("GPL");
This page took 0.112913 seconds and 5 git commands to generate.