Added INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE and implemented for
authorFrank Mori Hess <fmhess@speakeasy.net>
Fri, 28 Mar 2008 15:15:59 +0000 (15:15 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Fri, 28 Mar 2008 15:15:59 +0000 (15:15 +0000)
analog output of NI boards.

comedi/comedi_fops.c
comedi/drivers/mite.c
comedi/drivers/mite.h
comedi/drivers/ni_mio_common.c
include/linux/comedi.h

index 56123a04dd10455220efec759150790f4c9a55ca..972231d30bf11fed80adbbe2ae8ad71f43481e84 100644 (file)
@@ -666,6 +666,8 @@ static int do_insnlist_ioctl(comedi_device * dev, void *arg, void *file)
 
 static int check_insn_config_length(comedi_insn * insn, lsampl_t * data)
 {
+       if(insn->n < 1) return -EINVAL;
+
        switch (data[0]) {
        case INSN_CONFIG_DIO_OUTPUT:
        case INSN_CONFIG_DIO_INPUT:
@@ -685,7 +687,7 @@ static int check_insn_config_length(comedi_insn * insn, lsampl_t * data)
        case INSN_CONFIG_8254_READ_STATUS:
        case INSN_CONFIG_SET_ROUTING:
        case INSN_CONFIG_GET_ROUTING:
-       case INSN_GET_PWM_STATUS:
+       case INSN_CONFIG_GET_PWM_STATUS:
        case INSN_CONFIG_PWM_SET_PERIOD:
        case INSN_CONFIG_PWM_GET_PERIOD:
                if (insn->n == 2)
@@ -699,6 +701,7 @@ static int check_insn_config_length(comedi_insn * insn, lsampl_t * data)
        case INSN_CONFIG_GET_COUNTER_STATUS:
        case INSN_CONFIG_PWM_SET_H_BRIDGE:
        case INSN_CONFIG_PWM_GET_H_BRIDGE:
+       case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
                if (insn->n == 3)
                        return 0;
                break;
index c0d1fa2d745c41e39ae7e7d140a32094c89147eb..962b364ae41a38302fc8c2960db1d94f30dddc9c 100644 (file)
@@ -103,6 +103,15 @@ static void dump_chip_signature(u32 csigr_bits)
        printk("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n", mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
 }
 
+unsigned mite_fifo_size(struct mite_struct * mite, unsigned channel)
+{
+       unsigned fcr_bits = readl(mite->mite_io_addr +
+               MITE_FCR(channel));
+       unsigned empty_count = (fcr_bits >> 16) & 0xff;
+       unsigned full_count = fcr_bits & 0xff;
+       return empty_count + full_count;
+}
+
 int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
 {
        unsigned long length;
@@ -178,6 +187,8 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
                        CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
                        mite->mite_io_addr + MITE_CHCR(i));
        }
+       mite->fifo_size = mite_fifo_size(mite, 0);
+       printk("mite: fifo size is %i.\n", mite->fifo_size);
        mite->used = 1;
 
        return 0;
index f47db61a88769a7468cde8bde5f6c96d0b78200c..8348bb31eeeb8db2e651fa0de4c6fac48b41174c 100644 (file)
@@ -75,6 +75,7 @@ struct mite_struct {
        struct mite_channel channels[MAX_MITE_DMA_CHANNELS];
        short channel_allocated[MAX_MITE_DMA_CHANNELS];
        int num_channels;
+       unsigned fifo_size;
        spinlock_t lock;
 };
 
index 9718703ee7a99323b350f565d837d834a4f1acfb..61907fa93e996b5955019fa896f1514306a1aafe 100644 (file)
@@ -1552,7 +1552,6 @@ static int ni_ai_setup_MITE_dma(comedi_device * dev)
        /* write alloc the entire buffer */
        comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
 
-
        comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
        if(devpriv->ai_mite_chan == NULL)
        {
@@ -2961,6 +2960,32 @@ static int ni_ao_insn_write_671x(comedi_device * dev, comedi_subdevice * s,
        return 1;
 }
 
+static int ni_ao_insn_config(comedi_device * dev, comedi_subdevice * s,
+       comedi_insn * insn, lsampl_t * data)
+{
+       switch (data[0]) {
+       case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
+               switch(data[1])
+               {
+               case COMEDI_OUTPUT:
+                       data[2] = 1 + boardtype.ao_fifo_depth;
+                       if(devpriv->mite) data[2] += devpriv->mite->fifo_size;
+                       break;
+               case COMEDI_INPUT:
+                       data[2] = 0;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+               }
+               return 0;
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
 static int ni_ao_inttrig(comedi_device * dev, comedi_subdevice * s,
        unsigned int trignum)
 {
@@ -4269,6 +4294,7 @@ static int ni_E_init(comedi_device * dev, comedi_devconfig * it)
                } else {
                        s->insn_write = &ni_ao_insn_write;
                }
+               s->insn_config = &ni_ao_insn_config;
 #ifdef PCIDMA
                if (boardtype.n_aochan) {
                        s->async_dma_dir = DMA_TO_DEVICE;
index ca9496a69dcc8d4a6520ec276e9a47604c27eb24..4f64572df593de4e140bbc2d811f4a2f97b02c11 100644 (file)
@@ -256,6 +256,7 @@ extern "C" {
                INSN_CONFIG_GET_CLOCK_SRC = 2004,       // Get master clock source
                INSN_CONFIG_SET_OTHER_SRC = 2005,       // Set other source
 //      INSN_CONFIG_GET_OTHER_SRC = 2006,       // Get other source
+               INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE,   // Get size in bytes of subdevice's on-board fifos used during streaming input/output
                INSN_CONFIG_SET_COUNTER_MODE = 4097,
                INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE,       /* deprecated */
                INSN_CONFIG_8254_READ_STATUS = 4098,