Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2     comedi/drivers/gsc_hpdi.c
  3     This is a driver for the General Standards Corporation High
  4     Speed Parallel Digital Interface rs485 boards.
  5 
  6     Author:  Frank Mori Hess <fmhess@users.sourceforge.net>
  7     Copyright (C) 2003 Coherent Imaging Systems
  8 
  9     COMEDI - Linux Control and Measurement Device Interface
 10     Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
 11 
 12     This program is free software; you can redistribute it and/or modify
 13     it under the terms of the GNU General Public License as published by
 14     the Free Software Foundation; either version 2 of the License, or
 15     (at your option) any later version.
 16 
 17     This program is distributed in the hope that it will be useful,
 18     but WITHOUT ANY WARRANTY; without even the implied warranty of
 19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20     GNU General Public License for more details.
 21 
 22     You should have received a copy of the GNU General Public License
 23     along with this program; if not, write to the Free Software
 24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 25 
 26 ************************************************************************/
 27 
 28 /*
 29 
 30 Driver: gsc_hpdi
 31 Description: General Standards Corporation High
 32     Speed Parallel Digital Interface rs485 boards
 33 Author: Frank Mori Hess <fmhess@users.sourceforge.net>
 34 Status: only receive mode works, transmit not supported
 35 Updated: 2003-02-20
 36 Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
 37   PMC-HPDI32
 38 
 39 Configuration options:
 40    [0] - PCI bus of device (optional)
 41    [1] - PCI slot of device (optional)
 42 
 43 There are some additional hpdi models available from GSC for which
 44 support could be added to this driver.
 45 
 46 */
 47 
 48 #include <linux/interrupt.h>
 49 #include "../comedidev.h"
 50 #include <linux/delay.h>
 51 
 52 #include "comedi_pci.h"
 53 #include "plx9080.h"
 54 #include "comedi_fc.h"
 55 
 56 static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it);
 57 static int hpdi_detach(struct comedi_device *dev);
 58 void abort_dma(struct comedi_device *dev, unsigned int channel);
 59 static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
 60 static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 61         struct comedi_cmd *cmd);
 62 static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
 63 static irqreturn_t handle_interrupt(int irq, void *d);
 64 static int dio_config_block_size(struct comedi_device *dev, unsigned int *data);
 65 
 66 #undef HPDI_DEBUG               /*  disable debugging messages */
 67 /* #define HPDI_DEBUG      enable debugging code */
 68 
 69 #ifdef HPDI_DEBUG
 70 #define DEBUG_PRINT(format, args...)  printk(format , ## args)
 71 #else
 72 #define DEBUG_PRINT(format, args...)
 73 #endif
 74 
 75 #define TIMER_BASE 50           /*  20MHz master clock */
 76 #define DMA_BUFFER_SIZE 0x10000
 77 #define NUM_DMA_BUFFERS 4
 78 #define NUM_DMA_DESCRIPTORS 256
 79 
 80 /* indices of base address regions */
 81 enum base_address_regions {
 82         PLX9080_BADDRINDEX = 0,
 83         HPDI_BADDRINDEX = 2,
 84 };
 85 
 86 enum hpdi_registers {
 87         FIRMWARE_REV_REG = 0x0,
 88         BOARD_CONTROL_REG = 0x4,
 89         BOARD_STATUS_REG = 0x8,
 90         TX_PROG_ALMOST_REG = 0xc,
 91         RX_PROG_ALMOST_REG = 0x10,
 92         FEATURES_REG = 0x14,
 93         FIFO_REG = 0x18,
 94         TX_STATUS_COUNT_REG = 0x1c,
 95         TX_LINE_VALID_COUNT_REG = 0x20,
 96         TX_LINE_INVALID_COUNT_REG = 0x24,
 97         RX_STATUS_COUNT_REG = 0x28,
 98         RX_LINE_COUNT_REG = 0x2c,
 99         INTERRUPT_CONTROL_REG = 0x30,
100         INTERRUPT_STATUS_REG = 0x34,
101         TX_CLOCK_DIVIDER_REG = 0x38,
102         TX_FIFO_SIZE_REG = 0x40,
103         RX_FIFO_SIZE_REG = 0x44,
104         TX_FIFO_WORDS_REG = 0x48,
105         RX_FIFO_WORDS_REG = 0x4c,
106         INTERRUPT_EDGE_LEVEL_REG = 0x50,
107         INTERRUPT_POLARITY_REG = 0x54,
108 };
109 
110 int command_channel_valid(unsigned int channel)
111 {
112         if (channel == 0 || channel > 6) {
113                 printk("gsc_hpdi: bug! invalid cable command channel\n");
114                 return 0;
115         }
116         return 1;
117 }
118 
119 /* bit definitions */
120 
121 enum firmware_revision_bits {
122         FEATURES_REG_PRESENT_BIT = 0x8000,
123 };
124 int firmware_revision(uint32_t fwr_bits)
125 {
126         return fwr_bits & 0xff;
127 }
128 
129 int pcb_revision(uint32_t fwr_bits)
130 {
131         return (fwr_bits >> 8) & 0xff;
132 }
133 
134 int hpdi_subid(uint32_t fwr_bits)
135 {
136         return (fwr_bits >> 16) & 0xff;
137 }
138 
139 enum board_control_bits {
140         BOARD_RESET_BIT = 0x1,  /* wait 10usec before accessing fifos */
141         TX_FIFO_RESET_BIT = 0x2,
142         RX_FIFO_RESET_BIT = 0x4,
143         TX_ENABLE_BIT = 0x10,
144         RX_ENABLE_BIT = 0x20,
145         DEMAND_DMA_DIRECTION_TX_BIT = 0x40,     /* for channel 0, channel 1 can only transmit (when present) */
146         LINE_VALID_ON_STATUS_VALID_BIT = 0x80,
147         START_TX_BIT = 0x10,
148         CABLE_THROTTLE_ENABLE_BIT = 0x20,
149         TEST_MODE_ENABLE_BIT = 0x80000000,
150 };
151 uint32_t command_discrete_output_bits(unsigned int channel, int output,
152         int output_value)
153 {
154         uint32_t bits = 0;
155 
156         if (command_channel_valid(channel) == 0)
157                 return 0;
158         if (output) {
159                 bits |= 0x1 << (16 + channel);
160                 if (output_value)
161                         bits |= 0x1 << (24 + channel);
162         } else
163                 bits |= 0x1 << (24 + channel);
164 
165         return bits;
166 }
167 
168 enum board_status_bits {
169         COMMAND_LINE_STATUS_MASK = 0x7f,
170         TX_IN_PROGRESS_BIT = 0x80,
171         TX_NOT_EMPTY_BIT = 0x100,
172         TX_NOT_ALMOST_EMPTY_BIT = 0x200,
173         TX_NOT_ALMOST_FULL_BIT = 0x400,
174         TX_NOT_FULL_BIT = 0x800,
175         RX_NOT_EMPTY_BIT = 0x1000,
176         RX_NOT_ALMOST_EMPTY_BIT = 0x2000,
177         RX_NOT_ALMOST_FULL_BIT = 0x4000,
178         RX_NOT_FULL_BIT = 0x8000,
179         BOARD_JUMPER0_INSTALLED_BIT = 0x10000,
180         BOARD_JUMPER1_INSTALLED_BIT = 0x20000,
181         TX_OVERRUN_BIT = 0x200000,
182         RX_UNDERRUN_BIT = 0x400000,
183         RX_OVERRUN_BIT = 0x800000,
184 };
185 
186 uint32_t almost_full_bits(unsigned int num_words)
187 {
188 /* XXX need to add or subtract one? */
189         return (num_words << 16) & 0xff0000;
190 }
191 
192 uint32_t almost_empty_bits(unsigned int num_words)
193 {
194         return num_words & 0xffff;
195 }
196 unsigned int almost_full_num_words(uint32_t bits)
197 {
198 /* XXX need to add or subtract one? */
199         return (bits >> 16) & 0xffff;
200 }
201 unsigned int almost_empty_num_words(uint32_t bits)
202 {
203         return bits & 0xffff;
204 }
205 
206 enum features_bits {
207         FIFO_SIZE_PRESENT_BIT = 0x1,
208         FIFO_WORDS_PRESENT_BIT = 0x2,
209         LEVEL_EDGE_INTERRUPTS_PRESENT_BIT = 0x4,
210         GPIO_SUPPORTED_BIT = 0x8,
211         PLX_DMA_CH1_SUPPORTED_BIT = 0x10,
212         OVERRUN_UNDERRUN_SUPPORTED_BIT = 0x20,
213 };
214 
215 enum interrupt_sources {
216         FRAME_VALID_START_INTR = 0,
217         FRAME_VALID_END_INTR = 1,
218         TX_FIFO_EMPTY_INTR = 8,
219         TX_FIFO_ALMOST_EMPTY_INTR = 9,
220         TX_FIFO_ALMOST_FULL_INTR = 10,
221         TX_FIFO_FULL_INTR = 11,
222         RX_EMPTY_INTR = 12,
223         RX_ALMOST_EMPTY_INTR = 13,
224         RX_ALMOST_FULL_INTR = 14,
225         RX_FULL_INTR = 15,
226 };
227 int command_intr_source(unsigned int channel)
228 {
229         if (command_channel_valid(channel) == 0)
230                 channel = 1;
231         return channel + 1;
232 }
233 
234 uint32_t intr_bit(int interrupt_source)
235 {
236         return 0x1 << interrupt_source;
237 }
238 
239 uint32_t tx_clock_divisor_bits(unsigned int divisor)
240 {
241         return divisor & 0xff;
242 }
243 
244 unsigned int fifo_size(uint32_t fifo_size_bits)
245 {
246         return fifo_size_bits & 0xfffff;
247 }
248 
249 unsigned int fifo_words(uint32_t fifo_words_bits)
250 {
251         return fifo_words_bits & 0xfffff;
252 }
253 
254 uint32_t intr_edge_bit(int interrupt_source)
255 {
256         return 0x1 << interrupt_source;
257 }
258 
259 uint32_t intr_active_high_bit(int interrupt_source)
260 {
261         return 0x1 << interrupt_source;
262 }
263 
264 struct hpdi_board {
265 
266         char *name;
267         int device_id;          /*  pci device id */
268         int subdevice_id;       /*  pci subdevice id */
269 };
270 
271 
272 static const struct hpdi_board hpdi_boards[] = {
273         {
274         .name = "pci-hpdi32",
275         .device_id = PCI_DEVICE_ID_PLX_9080,
276         .subdevice_id = 0x2400,
277                 },
278 #if 0
279         {
280         .name = "pxi-hpdi32",
281         .device_id = 0x9656,
282         .subdevice_id = 0x2705,
283                 },
284 #endif
285 };
286 
287 static DEFINE_PCI_DEVICE_TABLE(hpdi_pci_table) = {
288         {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, 0x2400,
289                 0, 0, 0},
290         {0}
291 };
292 
293 MODULE_DEVICE_TABLE(pci, hpdi_pci_table);
294 
295 static inline struct hpdi_board *board(const struct comedi_device * dev)
296 {
297         return (struct hpdi_board *) dev->board_ptr;
298 }
299 
300 struct hpdi_private {
301 
302         struct pci_dev *hw_dev; /*  pointer to board's pci_dev struct */
303         /*  base addresses (physical) */
304         resource_size_t plx9080_phys_iobase;
305         resource_size_t hpdi_phys_iobase;
306         /*  base addresses (ioremapped) */
307         void *plx9080_iobase;
308         void *hpdi_iobase;
309         uint32_t *dio_buffer[NUM_DMA_BUFFERS];  /*  dma buffers */
310         dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];       /*  physical addresses of dma buffers */
311         struct plx_dma_desc *dma_desc;  /*  array of dma descriptors read by plx9080, allocated to get proper alignment */
312         dma_addr_t dma_desc_phys_addr;  /*  physical address of dma descriptor array */
313         unsigned int num_dma_descriptors;
314         uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS]; /*  pointer to start of buffers indexed by descriptor */
315         volatile unsigned int dma_desc_index;   /*  index of the dma descriptor that is currently being used */
316         unsigned int tx_fifo_size;
317         unsigned int rx_fifo_size;
318         volatile unsigned long dio_count;
319         volatile uint32_t bits[24];     /*  software copies of values written to hpdi registers */
320         volatile unsigned int block_size;       /*  number of bytes at which to generate COMEDI_CB_BLOCK events */
321         unsigned dio_config_output:1;
322 };
323 
324 
325 static inline struct hpdi_private *priv(struct comedi_device * dev)
326 {
327         return dev->private;
328 }
329 
330 static struct comedi_driver driver_hpdi = {
331         .driver_name = "gsc_hpdi",
332         .module = THIS_MODULE,
333         .attach = hpdi_attach,
334         .detach = hpdi_detach,
335 };
336 
337 COMEDI_PCI_INITCLEANUP(driver_hpdi, hpdi_pci_table);
338 
339 static int dio_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
340         struct comedi_insn *insn, unsigned int *data)
341 {
342         switch (data[0]) {
343         case INSN_CONFIG_DIO_OUTPUT:
344                 priv(dev)->dio_config_output = 1;
345                 return insn->n;
346                 break;
347         case INSN_CONFIG_DIO_INPUT:
348                 priv(dev)->dio_config_output = 0;
349                 return insn->n;
350                 break;
351         case INSN_CONFIG_DIO_QUERY:
352                 data[1] =
353                         priv(dev)->
354                         dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
355                 return insn->n;
356                 break;
357         case INSN_CONFIG_BLOCK_SIZE:
358                 return dio_config_block_size(dev, data);
359                 break;
360         default:
361                 break;
362         }
363 
364         return -EINVAL;
365 }
366 
367 static void disable_plx_interrupts(struct comedi_device *dev)
368 {
369         writel(0, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
370 }
371 
372 /* initialize plx9080 chip */
373 static void init_plx9080(struct comedi_device *dev)
374 {
375         uint32_t bits;
376         void *plx_iobase = priv(dev)->plx9080_iobase;
377 
378         /*  plx9080 dump */
379         DEBUG_PRINT(" plx interrupt status 0x%x\n",
380                 readl(plx_iobase + PLX_INTRCS_REG));
381         DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
382         DEBUG_PRINT(" plx control reg 0x%x\n",
383                 readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
384 
385         DEBUG_PRINT(" plx revision 0x%x\n",
386                 readl(plx_iobase + PLX_REVISION_REG));
387         DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
388                 readl(plx_iobase + PLX_DMA0_MODE_REG));
389         DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
390                 readl(plx_iobase + PLX_DMA1_MODE_REG));
391         DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
392                 readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
393         DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
394                 readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
395         DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
396                 readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
397         DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
398                 readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
399         DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
400                 readb(plx_iobase + PLX_DMA0_CS_REG));
401         DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
402                 readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
403         DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
404 #ifdef __BIG_ENDIAN
405         bits = BIGEND_DMA0 | BIGEND_DMA1;
406 #else
407         bits = 0;
408 #endif
409         writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
410 
411         disable_plx_interrupts(dev);
412 
413         abort_dma(dev, 0);
414         abort_dma(dev, 1);
415 
416         /*  configure dma0 mode */
417         bits = 0;
418         /*  enable ready input */
419         bits |= PLX_DMA_EN_READYIN_BIT;
420         /*  enable dma chaining */
421         bits |= PLX_EN_CHAIN_BIT;
422         /*  enable interrupt on dma done (probably don't need this, since chain never finishes) */
423         bits |= PLX_EN_DMA_DONE_INTR_BIT;
424         /*  don't increment local address during transfers (we are transferring from a fixed fifo register) */
425         bits |= PLX_LOCAL_ADDR_CONST_BIT;
426         /*  route dma interrupt to pci bus */
427         bits |= PLX_DMA_INTR_PCI_BIT;
428         /*  enable demand mode */
429         bits |= PLX_DEMAND_MODE_BIT;
430         /*  enable local burst mode */
431         bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
432         bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
433         writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
434 }
435 
436 /* Allocate and initialize the subdevice structures.
437  */
438 static int setup_subdevices(struct comedi_device *dev)
439 {
440         struct comedi_subdevice *s;
441 
442         if (alloc_subdevices(dev, 1) < 0)
443                 return -ENOMEM;
444 
445         s = dev->subdevices + 0;
446         /* analog input subdevice */
447         dev->read_subdev = s;
448 /*      dev->write_subdev = s; */
449         s->type = COMEDI_SUBD_DIO;
450         s->subdev_flags =
451                 SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
452         s->n_chan = 32;
453         s->len_chanlist = 32;
454         s->maxdata = 1;
455         s->range_table = &range_digital;
456         s->insn_config = dio_config_insn;
457         s->do_cmd = hpdi_cmd;
458         s->do_cmdtest = hpdi_cmd_test;
459         s->cancel = hpdi_cancel;
460 
461         return 0;
462 }
463 
464 static int init_hpdi(struct comedi_device *dev)
465 {
466         uint32_t plx_intcsr_bits;
467 
468         writel(BOARD_RESET_BIT, priv(dev)->hpdi_iobase + BOARD_CONTROL_REG);
469         udelay(10);
470 
471         writel(almost_empty_bits(32) | almost_full_bits(32),
472                 priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
473         writel(almost_empty_bits(32) | almost_full_bits(32),
474                 priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG);
475 
476         priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
477                         TX_FIFO_SIZE_REG));
478         priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
479                         RX_FIFO_SIZE_REG));
480 
481         writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
482 
483         /*  enable interrupts */
484         plx_intcsr_bits =
485                 ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
486                 ICS_DMA0_E;
487         writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
488 
489         return 0;
490 }
491 
492 /* setup dma descriptors so a link completes every 'transfer_size' bytes */
493 static int setup_dma_descriptors(struct comedi_device *dev,
494         unsigned int transfer_size)
495 {
496         unsigned int buffer_index, buffer_offset;
497         uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
498                 PLX_XFER_LOCAL_TO_PCI;
499         unsigned int i;
500 
501         if (transfer_size > DMA_BUFFER_SIZE)
502                 transfer_size = DMA_BUFFER_SIZE;
503         transfer_size -= transfer_size % sizeof(uint32_t);
504         if (transfer_size == 0)
505                 return -1;
506 
507         DEBUG_PRINT(" transfer_size %i\n", transfer_size);
508         DEBUG_PRINT(" descriptors at 0x%lx\n",
509                 (unsigned long)priv(dev)->dma_desc_phys_addr);
510 
511         buffer_offset = 0;
512         buffer_index = 0;
513         for (i = 0; i < NUM_DMA_DESCRIPTORS &&
514                 buffer_index < NUM_DMA_BUFFERS; i++) {
515                 priv(dev)->dma_desc[i].pci_start_addr =
516                         cpu_to_le32(priv(dev)->
517                         dio_buffer_phys_addr[buffer_index] + buffer_offset);
518                 priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
519                 priv(dev)->dma_desc[i].transfer_size =
520                         cpu_to_le32(transfer_size);
521                 priv(dev)->dma_desc[i].next =
522                         cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i +
523                                         1) *
524                                 sizeof(priv(dev)->dma_desc[0])) | next_bits);
525 
526                 priv(dev)->desc_dio_buffer[i] =
527                         priv(dev)->dio_buffer[buffer_index] +
528                         (buffer_offset / sizeof(uint32_t));
529 
530                 buffer_offset += transfer_size;
531                 if (transfer_size + buffer_offset > DMA_BUFFER_SIZE) {
532                         buffer_offset = 0;
533                         buffer_index++;
534                 }
535 
536                 DEBUG_PRINT(" desc %i\n", i);
537                 DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n",
538                         priv(dev)->desc_dio_buffer[i],
539                         (unsigned long)priv(dev)->dma_desc[i].pci_start_addr);
540                 DEBUG_PRINT(" next 0x%lx\n",
541                         (unsigned long)priv(dev)->dma_desc[i].next);
542         }
543         priv(dev)->num_dma_descriptors = i;
544         /*  fix last descriptor to point back to first */
545         priv(dev)->dma_desc[i - 1].next =
546                 cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits);
547         DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1,
548                 (unsigned long)priv(dev)->dma_desc[i - 1].next);
549 
550         priv(dev)->block_size = transfer_size;
551 
552         return transfer_size;
553 }
554 
555 static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
556 {
557         struct pci_dev *pcidev;
558         int i;
559         int retval;
560 
561         printk("comedi%d: gsc_hpdi\n", dev->minor);
562 
563         if (alloc_private(dev, sizeof(struct hpdi_private)) < 0)
564                 return -ENOMEM;
565 
566         pcidev = NULL;
567         for (i = 0; i < ARRAY_SIZE(hpdi_boards) && dev->board_ptr == NULL; i++) {
568                 do {
569                         pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
570                                 hpdi_boards[i].device_id, PCI_VENDOR_ID_PLX,
571                                 hpdi_boards[i].subdevice_id, pcidev);
572                         /*  was a particular bus/slot requested? */
573                         if (it->options[0] || it->options[1]) {
574                                 /*  are we on the wrong bus/slot? */
575                                 if (pcidev->bus->number != it->options[0] ||
576                                         PCI_SLOT(pcidev->devfn) !=
577                                         it->options[1])
578                                         continue;
579                         }
580                         if (pcidev) {
581                                 priv(dev)->hw_dev = pcidev;
582                                 dev->board_ptr = hpdi_boards + i;
583                                 break;
584                         }
585                 } while (pcidev != NULL);
586         }
587         if (dev->board_ptr == NULL) {
588                 printk("gsc_hpdi: no hpdi card found\n");
589                 return -EIO;
590         }
591 
592         printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
593                 pcidev->bus->number, PCI_SLOT(pcidev->devfn));
594 
595         if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) {
596                 printk(KERN_WARNING
597                         " failed enable PCI device and request regions\n");
598                 return -EIO;
599         }
600         pci_set_master(pcidev);
601 
602         /* Initialize dev->board_name */
603         dev->board_name = board(dev)->name;
604 
605         priv(dev)->plx9080_phys_iobase =
606                 pci_resource_start(pcidev, PLX9080_BADDRINDEX);
607         priv(dev)->hpdi_phys_iobase =
608                 pci_resource_start(pcidev, HPDI_BADDRINDEX);
609 
610         /*  remap, won't work with 2.0 kernels but who cares */
611         priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
612                 pci_resource_len(pcidev, PLX9080_BADDRINDEX));
613         priv(dev)->hpdi_iobase = ioremap(priv(dev)->hpdi_phys_iobase,
614                 pci_resource_len(pcidev, HPDI_BADDRINDEX));
615         if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) {
616                 printk(" failed to remap io memory\n");
617                 return -ENOMEM;
618         }
619 
620         DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
621         DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase);
622 
623         init_plx9080(dev);
624 
625         /*  get irq */
626         if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
627                         driver_hpdi.driver_name, dev)) {
628                 printk(" unable to allocate irq %u\n", pcidev->irq);
629                 return -EINVAL;
630         }
631         dev->irq = pcidev->irq;
632 
633         printk(" irq %u\n", dev->irq);
634 
635         /*  alocate pci dma buffers */
636         for (i = 0; i < NUM_DMA_BUFFERS; i++) {
637                 priv(dev)->dio_buffer[i] =
638                         pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
639                         &priv(dev)->dio_buffer_phys_addr[i]);
640                 DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n",
641                         priv(dev)->dio_buffer[i],
642                         (unsigned long)priv(dev)->dio_buffer_phys_addr[i]);
643         }
644         /*  allocate dma descriptors */
645         priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev,
646                 sizeof(struct plx_dma_desc) * NUM_DMA_DESCRIPTORS,
647                 &priv(dev)->dma_desc_phys_addr);
648         if (priv(dev)->dma_desc_phys_addr & 0xf) {
649                 printk(" dma descriptors not quad-word aligned (bug)\n");
650                 return -EIO;
651         }
652 
653         retval = setup_dma_descriptors(dev, 0x1000);
654         if (retval < 0)
655                 return retval;
656 
657         retval = setup_subdevices(dev);
658         if (retval < 0)
659                 return retval;
660 
661         return init_hpdi(dev);
662 }
663 
664 static int hpdi_detach(struct comedi_device *dev)
665 {
666         unsigned int i;
667 
668         printk("comedi%d: gsc_hpdi: remove\n", dev->minor);
669 
670         if (dev->irq)
671                 free_irq(dev->irq, dev);
672         if (priv(dev)) {
673                 if (priv(dev)->hw_dev) {
674                         if (priv(dev)->plx9080_iobase) {
675                                 disable_plx_interrupts(dev);
676                                 iounmap((void *)priv(dev)->plx9080_iobase);
677                         }
678                         if (priv(dev)->hpdi_iobase)
679                                 iounmap((void *)priv(dev)->hpdi_iobase);
680                         /*  free pci dma buffers */
681                         for (i = 0; i < NUM_DMA_BUFFERS; i++) {
682                                 if (priv(dev)->dio_buffer[i])
683                                         pci_free_consistent(priv(dev)->hw_dev,
684                                                 DMA_BUFFER_SIZE,
685                                                 priv(dev)->dio_buffer[i],
686                                                 priv(dev)->
687                                                 dio_buffer_phys_addr[i]);
688                         }
689                         /*  free dma descriptors */
690                         if (priv(dev)->dma_desc)
691                                 pci_free_consistent(priv(dev)->hw_dev,
692                                         sizeof(struct plx_dma_desc) *
693                                         NUM_DMA_DESCRIPTORS,
694                                         priv(dev)->dma_desc,
695                                         priv(dev)->dma_desc_phys_addr);
696                         if (priv(dev)->hpdi_phys_iobase) {
697                                 comedi_pci_disable(priv(dev)->hw_dev);
698                         }
699                         pci_dev_put(priv(dev)->hw_dev);
700                 }
701         }
702         return 0;
703 }
704 
705 static int dio_config_block_size(struct comedi_device *dev, unsigned int *data)
706 {
707         unsigned int requested_block_size;
708         int retval;
709 
710         requested_block_size = data[1];
711 
712         retval = setup_dma_descriptors(dev, requested_block_size);
713         if (retval < 0)
714                 return retval;
715 
716         data[1] = retval;
717 
718         return 2;
719 }
720 
721 static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
722         struct comedi_cmd *cmd)
723 {
724         int err = 0;
725         int tmp;
726         int i;
727 
728         /* step 1: make sure trigger sources are trivially valid */
729 
730         tmp = cmd->start_src;
731         cmd->start_src &= TRIG_NOW;
732         if (!cmd->start_src || tmp != cmd->start_src)
733                 err++;
734 
735         tmp = cmd->scan_begin_src;
736         cmd->scan_begin_src &= TRIG_EXT;
737         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
738                 err++;
739 
740         tmp = cmd->convert_src;
741         cmd->convert_src &= TRIG_NOW;
742         if (!cmd->convert_src || tmp != cmd->convert_src)
743                 err++;
744 
745         tmp = cmd->scan_end_src;
746         cmd->scan_end_src &= TRIG_COUNT;
747         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
748                 err++;
749 
750         tmp = cmd->stop_src;
751         cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
752         if (!cmd->stop_src || tmp != cmd->stop_src)
753                 err++;
754 
755         if (err)
756                 return 1;
757 
758         /* step 2: make sure trigger sources are unique and mutually compatible */
759 
760         /*  uniqueness check */
761         if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
762                 err++;
763 
764         if (err)
765                 return 2;
766 
767         /* step 3: make sure arguments are trivially compatible */
768 
769         if (!cmd->chanlist_len) {
770                 cmd->chanlist_len = 32;
771                 err++;
772         }
773         if (cmd->scan_end_arg != cmd->chanlist_len) {
774                 cmd->scan_end_arg = cmd->chanlist_len;
775                 err++;
776         }
777 
778         switch (cmd->stop_src) {
779         case TRIG_COUNT:
780                 if (!cmd->stop_arg) {
781                         cmd->stop_arg = 1;
782                         err++;
783                 }
784                 break;
785         case TRIG_NONE:
786                 if (cmd->stop_arg != 0) {
787                         cmd->stop_arg = 0;
788                         err++;
789                 }
790                 break;
791         default:
792                 break;
793         }
794 
795         if (err)
796                 return 3;
797 
798         /* step 4: fix up any arguments */
799 
800         if (err)
801                 return 4;
802 
803         if (cmd->chanlist) {
804                 for (i = 1; i < cmd->chanlist_len; i++) {
805                         if (CR_CHAN(cmd->chanlist[i]) != i) {
806                                 /*  XXX could support 8 channels or 16 channels */
807                                 comedi_error(dev,
808                                         "chanlist must be channels 0 to 31 in order");
809                                 err++;
810                                 break;
811                         }
812                 }
813         }
814 
815         if (err)
816                 return 5;
817 
818         return 0;
819 }
820 
821 static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
822         struct comedi_cmd *cmd)
823 {
824         if (priv(dev)->dio_config_output) {
825                 return -EINVAL;
826         } else
827                 return di_cmd_test(dev, s, cmd);
828 }
829 
830 static inline void hpdi_writel(struct comedi_device *dev, uint32_t bits,
831         unsigned int offset)
832 {
833         writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)],
834                 priv(dev)->hpdi_iobase + offset);
835 }
836 
837 static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
838 {
839         uint32_t bits;
840         unsigned long flags;
841         struct comedi_async *async = s->async;
842         struct comedi_cmd *cmd = &async->cmd;
843 
844         hpdi_writel(dev, RX_FIFO_RESET_BIT, BOARD_CONTROL_REG);
845 
846         DEBUG_PRINT("hpdi: in di_cmd\n");
847 
848         abort_dma(dev, 0);
849 
850         priv(dev)->dma_desc_index = 0;
851 
852         /* These register are supposedly unused during chained dma,
853          * but I have found that left over values from last operation
854          * occasionally cause problems with transfer of first dma
855          * block.  Initializing them to zero seems to fix the problem. */
856         writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
857         writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
858         writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
859         /*  give location of first dma descriptor */
860         bits = priv(dev)->
861                 dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
862                 PLX_XFER_LOCAL_TO_PCI;
863         writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
864 
865         /*  spinlock for plx dma control/status reg */
866         spin_lock_irqsave(&dev->spinlock, flags);
867         /*  enable dma transfer */
868         writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
869                 priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
870         spin_unlock_irqrestore(&dev->spinlock, flags);
871 
872         if (cmd->stop_src == TRIG_COUNT)
873                 priv(dev)->dio_count = cmd->stop_arg;
874         else
875                 priv(dev)->dio_count = 1;
876 
877         /*  clear over/under run status flags */
878         writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
879                 priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
880         /*  enable interrupts */
881         writel(intr_bit(RX_FULL_INTR),
882                 priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
883 
884         DEBUG_PRINT("hpdi: starting rx\n");
885         hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
886 
887         return 0;
888 }
889 
890 static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
891 {
892         if (priv(dev)->dio_config_output) {
893                 return -EINVAL;
894         } else
895                 return di_cmd(dev, s);
896 }
897 
898 static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
899 {
900         struct comedi_async *async = dev->read_subdev->async;
901         uint32_t next_transfer_addr;
902         int j;
903         int num_samples = 0;
904         void *pci_addr_reg;
905 
906         if (channel)
907                 pci_addr_reg =
908                         priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
909         else
910                 pci_addr_reg =
911                         priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
912 
913         /*  loop until we have read all the full buffers */
914         j = 0;
915         for (next_transfer_addr = readl(pci_addr_reg);
916                 (next_transfer_addr <
917                         le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
918                                         dma_desc_index].pci_start_addr)
919                         || next_transfer_addr >=
920                         le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
921                                         dma_desc_index].pci_start_addr) +
922                         priv(dev)->block_size)
923                 && j < priv(dev)->num_dma_descriptors; j++) {
924                 /*  transfer data from dma buffer to comedi buffer */
925                 num_samples = priv(dev)->block_size / sizeof(uint32_t);
926                 if (async->cmd.stop_src == TRIG_COUNT) {
927                         if (num_samples > priv(dev)->dio_count)
928                                 num_samples = priv(dev)->dio_count;
929                         priv(dev)->dio_count -= num_samples;
930                 }
931                 cfc_write_array_to_buffer(dev->read_subdev,
932                         priv(dev)->desc_dio_buffer[priv(dev)->dma_desc_index],
933                         num_samples * sizeof(uint32_t));
934                 priv(dev)->dma_desc_index++;
935                 priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors;
936 
937                 DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long)
938                         priv(dev)->dma_desc[priv(dev)->dma_desc_index].next);
939                 DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
940         }
941         /*  XXX check for buffer overrun somehow */
942 }
943 
944 static irqreturn_t handle_interrupt(int irq, void *d)
945 {
946         struct comedi_device *dev = d;
947         struct comedi_subdevice *s = dev->read_subdev;
948         struct comedi_async *async = s->async;
949         uint32_t hpdi_intr_status, hpdi_board_status;
950         uint32_t plx_status;
951         uint32_t plx_bits;
952         uint8_t dma0_status, dma1_status;
953         unsigned long flags;
954 
955         if (!dev->attached) {
956                 return IRQ_NONE;
957         }
958 
959         plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
960         if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) {
961                 return IRQ_NONE;
962         }
963 
964         hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
965         hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
966 
967         async->events = 0;
968 
969         if (hpdi_intr_status) {
970                 DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
971                 writel(hpdi_intr_status,
972                         priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
973         }
974         /*  spin lock makes sure noone else changes plx dma control reg */
975         spin_lock_irqsave(&dev->spinlock, flags);
976         dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
977         if (plx_status & ICS_DMA0_A) {  /*  dma chan 0 interrupt */
978                 writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
979                         priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
980 
981                 DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
982                 if (dma0_status & PLX_DMA_EN_BIT) {
983                         drain_dma_buffers(dev, 0);
984                 }
985                 DEBUG_PRINT(" cleared dma ch0 interrupt\n");
986         }
987         spin_unlock_irqrestore(&dev->spinlock, flags);
988 
989         /*  spin lock makes sure noone else changes plx dma control reg */
990         spin_lock_irqsave(&dev->spinlock, flags);
991         dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
992         if (plx_status & ICS_DMA1_A)    /*  XXX */
993         {                       /*  dma chan 1 interrupt */
994                 writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
995                         priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
996                 DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
997 
998                 DEBUG_PRINT(" cleared dma ch1 interrupt\n");
999         }
1000         spin_unlock_irqrestore(&dev->spinlock, flags);
1001 
1002         /*  clear possible plx9080 interrupt sources */
1003         if (plx_status & ICS_LDIA) {    /*  clear local doorbell interrupt */
1004                 plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
1005                 writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
1006                 DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
1007         }
1008 
1009         if (hpdi_board_status & RX_OVERRUN_BIT) {
1010                 comedi_error(dev, "rx fifo overrun");
1011                 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1012                 DEBUG_PRINT("dma0_status 0x%x\n",
1013                         (int)readb(priv(dev)->plx9080_iobase +
1014                                 PLX_DMA0_CS_REG));
1015         }
1016 
1017         if (hpdi_board_status & RX_UNDERRUN_BIT) {
1018                 comedi_error(dev, "rx fifo underrun");
1019                 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1020         }
1021 
1022         if (priv(dev)->dio_count == 0)
1023                 async->events |= COMEDI_CB_EOA;
1024 
1025         DEBUG_PRINT("board status 0x%x, ", hpdi_board_status);
1026         DEBUG_PRINT("plx status 0x%x\n", plx_status);
1027         if (async->events)
1028                 DEBUG_PRINT(" events 0x%x\n", async->events);
1029 
1030         cfc_handle_events(dev, s);
1031 
1032         return IRQ_HANDLED;
1033 }
1034 
1035 void abort_dma(struct comedi_device *dev, unsigned int channel)
1036 {
1037         unsigned long flags;
1038 
1039         /*  spinlock for plx dma control/status reg */
1040         spin_lock_irqsave(&dev->spinlock, flags);
1041 
1042         plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
1043 
1044         spin_unlock_irqrestore(&dev->spinlock, flags);
1045 }
1046 
1047 static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1048 {
1049         hpdi_writel(dev, 0, BOARD_CONTROL_REG);
1050 
1051         writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
1052 
1053         abort_dma(dev, 0);
1054 
1055         return 0;
1056 }
1057 
  This page was automatically generated by the LXR engine.