Removed timer_type globally, moved to comedi_get_device_by_minor(),
authorDavid Schleef <ds@schleef.org>
Mon, 6 Mar 2000 01:18:41 +0000 (01:18 +0000)
committerDavid Schleef <ds@schleef.org>
Mon, 6 Mar 2000 01:18:41 +0000 (01:18 +0000)
removed VER08 conf option, made all timers TIMER_nanosec (ni_mio_common,
pcl711, pcl812), pcl812 changes, pcl812 indent

19 files changed:
comedi/Config.in
comedi/comedi_fops.c
comedi/comedi_module.h
comedi/drivers.c
comedi/drivers/das1600.c
comedi/drivers/das6402.c
comedi/drivers/dt2814.c
comedi/drivers/dt282x.c
comedi/drivers/dt3000.c
comedi/drivers/ni_mio_common.c
comedi/drivers/ni_pcidio.c
comedi/drivers/pcl711.c
comedi/drivers/pcl812.c
comedi/kcomedilib/dio.c
comedi/kcomedilib/kcomedilib_main.c
comedi/proc.c
comedi/range.c
comedi/realtime/vd_dds.c
comedi/realtime/vd_timer.c

index 7a35ca85a3b55582b8d3876606c9b03a18062329..db770625b6eb1dba760e3a17b1f2e8002299d3fd 100644 (file)
@@ -27,7 +27,7 @@ if [ "$CONFIG_RTHAL" = "y" ];then
 fi
 
 bool 'Verbose Debugging' CONFIG_COMEDI_DEBUG
-bool 'Version 0.8 support' CONFIG_COMEDI_VER08
+#bool 'Version 0.8 support' CONFIG_COMEDI_VER08
 
 comment 'Hardware device drivers'
 
index 83ee653fc19f8add1414f1b521ae85a1c5e80146..b4859b605ce5b78553ebc9ec54f5328560371b40 100644 (file)
@@ -59,8 +59,7 @@ static void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s);
 static int comedi_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)
 {
        kdev_t minor=MINOR(inode->i_rdev);
-       comedi_device *dev=comedi_devices+minor;
-
+       comedi_device *dev=comedi_get_device_by_minor(minor);
        
        switch(cmd)
        {
@@ -200,7 +199,8 @@ static int do_subdinfo_ioctl(comedi_device *dev,comedi_subdinfo *arg,void *file)
                us->type                = s->type;
                us->n_chan              = s->n_chan;
                us->subd_flags          = s->subdev_flags;
-               us->timer_type          = s->timer_type;
+#define TIMER_nanosec 5        /* backwards compatibility */
+               us->timer_type          = TIMER_nanosec;
                us->len_chanlist        = s->len_chanlist;
                us->maxdata             = s->maxdata;
                us->range_type          = (dev->minor<<24)|(i<<20)|(0<<16)|
@@ -893,7 +893,7 @@ static int do_cancel(comedi_device *dev,comedi_subdevice *s)
 static int comedi_mmap_v22(struct file * file, struct vm_area_struct *vma)
 {
        kdev_t minor=MINOR(RDEV_OF_FILE(file));
-       comedi_device *dev=comedi_devices+minor;
+       comedi_device *dev=comedi_get_device_by_minor(minor);
        comedi_subdevice *s;
        int size;
        unsigned long offset;
@@ -961,7 +961,7 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes,
        void *buf_ptr;
        unsigned int buf_len;
 
-       dev=comedi_devices+MINOR(RDEV_OF_FILE(file));
+       dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file)));
        s=dev->subdevices+file->f_pos;
 
        if(s->subdev_flags&SDF_LSAMPL){
@@ -1050,7 +1050,7 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t
        DECLARE_WAITQUEUE(wait,current);
        int sample_size;
 
-       dev=comedi_devices+MINOR(RDEV_OF_FILE(file));
+       dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file)));
        if(file->f_pos>=dev->n_subdevices)
                return -EIO;
        s=dev->subdevices+file->f_pos;
@@ -1178,7 +1178,7 @@ static loff_t comedi_lseek_v22(struct file *file,loff_t offset,int origin)
        comedi_device *dev;
        loff_t new_offset;
        
-       dev=comedi_devices+MINOR(RDEV_OF_FILE(file));
+       dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file)));
 
        switch(origin){
        case SEEK_SET:
@@ -1208,7 +1208,7 @@ static int comedi_open(struct inode *inode,struct file *file)
 
        if(minor>=COMEDI_NDEVICES)return -ENODEV;
 
-       dev=comedi_devices+minor;
+       dev=comedi_get_device_by_minor(minor);
        if(dev->attached)
                goto ok;
        if(in_comedi_open && suser())
@@ -1237,7 +1237,7 @@ ok:
 
 static int comedi_close_v22(struct inode *inode,struct file *file)
 {
-       comedi_device *dev=comedi_devices+MINOR(inode->i_rdev);
+       comedi_device *dev=comedi_get_device_by_minor(MINOR(inode->i_rdev));
        comedi_subdevice *s;
        int i;
 
@@ -1375,8 +1375,11 @@ void cleanup_module(void)
        comedi_polling_cleanup();
 #endif
        for(i=0;i<COMEDI_NDEVICES;i++){
-               if(comedi_devices[i].attached)
-                       comedi_device_detach(comedi_devices+i);
+               comedi_device *dev;
+
+               dev=comedi_get_device_by_minor(i);
+               if(dev->attached)
+                       comedi_device_detach(dev);
        }
        kfree(comedi_devices);
 
index 4df8b65e982370d60eb09f885ab078e917b2f8f7..967fcdaa8d3627bce67e4772056dacd26feb8fba 100644 (file)
@@ -103,7 +103,6 @@ struct comedi_subdevice_struct{
        int type;
        int n_chan;
        int subdev_flags;
-       int timer_type;
        int len_chanlist;               /* length of channel/gain list, if available */
 
        void            *private;
@@ -171,7 +170,6 @@ struct comedi_device_struct{
        comedi_driver *driver;
        void *private;
        kdev_t minor;
-       //char *driver_name;
        char *board_name;
        int board;
        void *board_ptr;
@@ -203,6 +201,13 @@ void comedi_eos(comedi_device *dev,comedi_subdevice *s);
 void comedi_eobuf(comedi_device *dev,comedi_subdevice *s);
 void comedi_bufcheck(comedi_device *dev,comedi_subdevice *s);
 
+comedi_device * comedi_get_device_by_minor(kdev_t minor);
+
+extern inline comedi_device * comedi_get_device_by_minor(kdev_t minor)
+{
+       return comedi_devices+minor;
+}
+
 int comedi_device_detach(comedi_device *dev);
 int comedi_device_attach(comedi_device *dev,comedi_devconfig *it);
 int comedi_driver_register(comedi_driver *);
@@ -265,16 +270,6 @@ struct comedi_lrange_struct{
 };
 
 
-/* timer types */
-/* these *must* agree with lib/timer.c */
-
-#define TIMER_dt282x                   1
-#define TIMER_dt2814                   2
-#define TIMER_atmio                    3
-#define TIMER_acl8112                  4
-#define TIMER_nanosec                  5
-#define TIMER_pcl812                   6       
-
 
 /* some silly little inline functions */
 
index d3b9e2c1d46ad98d0c94f0f663792bd07489d45e..c64192ec57b3c457cfbbb352f60fd5cc135028d7 100644 (file)
 #include <asm/io.h>
 
 static void postconfig(comedi_device *dev);
-#ifdef CONFIG_COMEDI_VER08
 static int command_trig(comedi_device *dev,comedi_subdevice *s,comedi_trig *it);
 static int mode_to_command(comedi_cmd *cmd,comedi_trig *it);
-#endif
 
 comedi_driver *comedi_drivers;
 
@@ -141,7 +139,7 @@ int comedi_driver_unregister(comedi_driver *driver)
        for(i=0;i<COMEDI_NDEVICES;i++){
                comedi_device *dev;
 
-               dev=comedi_devices+i;
+               dev=comedi_get_device_by_minor(i);
                if(dev->attached && dev->driver==driver){
                        if(dev->use_count)
                                printk("BUG! detaching device with use_count=%d\n",dev->use_count);
@@ -183,14 +181,12 @@ static void postconfig(comedi_device *dev)
                if(s->trig[1] || s->trig[2] || s->trig[3] ||s->trig[4])
                        have_trig=1;
 
-#ifdef CONFIG_COMEDI_VER08
                if(s->do_cmd && !have_trig){
                        s->trig[1]=command_trig;
                        s->trig[2]=command_trig;
                        s->trig[3]=command_trig;
                        s->trig[4]=command_trig;
                }
-#endif
                if(s->do_cmd || have_trig){
                        s->prealloc_bufsz=1024*128;
                }else{
@@ -243,7 +239,6 @@ int do_pack(unsigned int *bits,comedi_trig *it)
        return i;
 }
 
-#ifdef CONFIG_COMEDI_VER08
 static int command_trig(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
 {
        int ret;
@@ -320,7 +315,6 @@ static int mode_to_command(comedi_cmd *cmd,comedi_trig *it)
 
        return 0;
 }
-#endif
 
 
 #define REG(x) {extern comedi_driver (x);comedi_driver_register(&(x));}
index 64530c43821d6644ed9b5a3b40febc89ed85e949..421fe69f571a4d3169fc8354695ef7b547be19e6 100644 (file)
@@ -373,7 +373,6 @@ static int das1600_attach(comedi_device * dev, comedi_devconfig * it)
        s->subdev_flags = SDF_READABLE;
        s->n_chan = (devpriv->adc_mux == adc_singleended) ? 16 : 8;
        s->maxdata = (board == card_1602_16) ? 0xffff : 0xfff;
-       s->timer_type = 0;      /* XXX need timer */
        s->trig[0] = das1600_ai;
        switch (board) {
        case card_1601_12:
index a589256e04f837024988c2bf5a7efa707f956bef..7dc7599d0c8be074582d4daa7e3f8c298bf9bf12 100644 (file)
@@ -363,7 +363,6 @@ static int das6402_attach(comedi_device *dev,comedi_devconfig *it)
        s->maxdata=(1<<12)-1;
        s->len_chanlist=16;     /* ? */
        s->range_table = &range_unknown;
-       s->timer_type = TIMER_nanosec;
 
        board_init(dev);
 
index 88abd96e140707713fe7cfe1c8343415dd9e989e..6b506b945904674c69ce9c6f23433c9664f26a88 100644 (file)
@@ -178,7 +178,6 @@ static int dt2814_attach(comedi_device *dev,comedi_devconfig *it)
        s->trig[1]=dt2814_ai_mode1;
        s->maxdata=0xfff;
        s->range_table=&range_unknown;  /* XXX */
-       s->timer_type=0;                /* XXX */
 
        return 0;
 }
index 785bdca93cee807ab7e60c0569ea19dab7a61d25..b6c65c9bad04337c79e1a6e43c4bbb5c09ca2e88 100644 (file)
@@ -668,7 +668,6 @@ static int dt282x_ai_mode0(comedi_device * dev, comedi_subdevice * s, comedi_tri
        return 1;
 }
 
-#ifdef CONFIG_COMEDI_VER08
 static int dt282x_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,comedi_cmd *cmd)
 {
        int err=0;
@@ -820,7 +819,6 @@ static int dt282x_ai_cmd(comedi_device * dev, comedi_subdevice * s)
 
        return 0;
 }
-#endif
 
 static int dt282x_ai_mode1(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
 {
@@ -1272,15 +1270,12 @@ static int dt282x_attach(comedi_device * dev, comedi_devconfig * it)
        s->trig[0]=dt282x_ai_mode0;
        s->trig[1]=dt282x_ai_mode1;
        s->trig[4]=dt282x_ai_mode4;
-#if CONFIG_COMEDI_VER08
        s->do_cmdtest=dt282x_ai_cmdtest;
        s->do_cmd=dt282x_ai_cmd;
-#endif
        s->cancel=dt282x_ai_cancel;
        s->maxdata=(1<<boardtype.adbits)-1;
        s->len_chanlist=16;
        s->range_table = opt_ai_range_lkup(boardtype.ispgl,it->options[opt_ai_range]);
-       s->timer_type=TIMER_nanosec;
        devpriv->ad_2scomp=it->options[opt_ai_twos];
 
        s++;
@@ -1294,7 +1289,6 @@ static int dt282x_attach(comedi_device * dev, comedi_devconfig * it)
                s->maxdata=(1<<boardtype.dabits)-1;
                s->len_chanlist=1;                      /* XXX could do 2 */
                s->range_table_list=devpriv->darangelist;
-               s->timer_type=TIMER_nanosec;
                devpriv->darangelist[0]=
                        opt_ao_range_lkup(it->options[opt_ao0_range]);
                devpriv->darangelist[1]=
index 71778227a7fdda93d282f0478eb202d0012588e2..f634c3d268f2b789675da17857ed4a45d6a4bab1 100644 (file)
@@ -439,7 +439,6 @@ static int dt3000_attach(comedi_device *dev,comedi_devconfig *it)
        s->maxdata=(1<<dt3k_boardtypes[dev->board].adbits)-1;
        s->len_chanlist=512;
        s->range_table=&range_dt3000_ai; /* XXX */
-       s->timer_type=TIMER_nanosec;
 
        s++;
        /* ao subsystem */
index ab6f2a4fcaf59e3c319d8df555ea16ee17130aff..b1de1fff11bd84862c13529085c1029658535b25 100644 (file)
@@ -156,6 +156,8 @@ static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s);
 
 static int ni_8255_callback(int dir,int port,int data,void *arg);
 
+static int ni_ns_to_timer(int *nanosec,int round_mode);
+
 #undef DEBUG
 
 #define AIMODE_NONE            0
@@ -553,7 +555,6 @@ static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,unsi
        rt_printk("ni_E: timeout 1\n");
 }
 
-#ifdef CONFIG_COMEDI_VER08
 #define TIMER_BASE 50 /* 20 Mhz base */
 
 static int ni_ns_to_timer(int *nanosec,int round_mode)
@@ -839,7 +840,6 @@ static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)
        win_restore(wsave);
        return 0;
 }
-#endif
 
 /*
        mode 2 is timed, multi-channel
@@ -847,11 +847,16 @@ static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)
 static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
 {
        int wsave;
+       int trigvar;
+       int trigvar1;
 
        wsave=win_save();
 
        win_out(1,ADC_FIFO_Clear);
 
+       trigvar = ni_ns_to_timer(&it->trigvar,TRIG_ROUND_NEAREST);
+       trigvar1 = ni_ns_to_timer(&it->trigvar1,TRIG_ROUND_NEAREST);
+
        ni_load_channelgain_list(dev,it->n_chan,it->chanlist,(it->flags&TRIG_DITHER)==TRIG_DITHER);
        
        /* start configuration */
@@ -881,19 +886,19 @@ static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
                AI_STOP_Select(19)|AI_STOP_Sync,
                AI_START_STOP_Select_Register);
 
-       win_out((it->trigvar>>16),AI_SI_Load_A_Registers);
-       win_out((it->trigvar&0xffff),AI_SI_Load_A_Registers+1);
+       win_out((trigvar>>16),AI_SI_Load_A_Registers);
+       win_out((trigvar&0xffff),AI_SI_Load_A_Registers+1);
        /* AI_SI_Initial_Load_Source=A */
        win_out(0,AI_Mode_2_Register);
        /* load SI */
        win_out(0x200,AI_Command_1_Register);
 
        /* stage freq. counter into SI B */
-       win_out((it->trigvar>>16),AI_SI_Load_B_Registers);
-       win_out((it->trigvar&0xffff),AI_SI_Load_B_Registers+1);
+       win_out((trigvar>>16),AI_SI_Load_B_Registers);
+       win_out((trigvar&0xffff),AI_SI_Load_B_Registers+1);
 
-       win_out(it->trigvar1,AI_SI2_Load_A_Register); /* 0,0 does not work. */
-       win_out(it->trigvar1,AI_SI2_Load_B_Register);
+       win_out(trigvar1,AI_SI2_Load_A_Register); /* 0,0 does not work. */
+       win_out(trigvar1,AI_SI2_Load_B_Register);
 
        /* AI_SI2_Reload_Mode = alternate */
        /* AI_SI2_Initial_Load_Source = A */
@@ -978,11 +983,13 @@ rt_printk("START1 pulse\n");
 static int ni_ai_mode4(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
 {
        int wsave;
+       int trigvar1;
 
        wsave=win_save();
 
        win_out(1,ADC_FIFO_Clear);
 
+       trigvar1 = ni_ns_to_timer(&it->trigvar1,TRIG_ROUND_NEAREST);
        ni_load_channelgain_list(dev,it->n_chan,it->chanlist,(it->flags&TRIG_DITHER)==TRIG_DITHER);
        
        /* start configuration */
@@ -1025,8 +1032,8 @@ static int ni_ai_mode4(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
        win_out((it->trigvar&0xffff),AI_SI_Load_B_Registers+1);
 #endif
 
-       win_out(it->trigvar1,AI_SI2_Load_A_Register); /* 0,0 does not work. */
-       win_out(it->trigvar1,AI_SI2_Load_B_Register);
+       win_out(trigvar1,AI_SI2_Load_A_Register); /* 0,0 does not work. */
+       win_out(trigvar1,AI_SI2_Load_B_Register);
 
        /* AI_SI2_Reload_Mode = alternate */
        /* AI_SI2_Initial_Load_Source = A */
@@ -1221,7 +1228,10 @@ static int ni_ao_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
        unsigned int conf;
        unsigned int chan;
        unsigned int range;
+       int trigvar;
        
+       trigvar = ni_ns_to_timer(&it->trigvar,TRIG_ROUND_NEAREST);
+
        chan=CR_CHAN(it->chanlist[0]);
 
        conf=chan<<8;
@@ -1300,8 +1310,8 @@ static int ni_ao_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
        win_out(0,AO_UI_Load_A_Register_High);
        win_out(1,AO_UI_Load_A_Register_Low);
        win_out(AO_UI_Load,AO_Command_1_Register);
-       win_out((it->trigvar>>16),AO_UI_Load_A_Register_High);
-       win_out((it->trigvar&0xffff),AO_UI_Load_A_Register_Low);
+       win_out((trigvar>>16),AO_UI_Load_A_Register_High);
+       win_out((trigvar&0xffff),AO_UI_Load_A_Register_Low);
 
        devpriv->ao_mode1&=~AO_Multiple_Channels;
        win_out(devpriv->ao_mode1,AO_Mode_1_Register);
@@ -1396,15 +1406,12 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
        s->n_chan=boardtype.n_adchan;
        s->len_chanlist=512;    /* XXX is this the same for PCI-MIO ? */
        s->maxdata=(1<<boardtype.adbits)-1;
-       s->timer_type=TIMER_atmio;
        s->range_table=ni_range_lkup[boardtype.gainlkup];
        s->trig[0]=ni_ai_mode0;
        s->trig[2]=ni_ai_mode2;
        s->trig[4]=ni_ai_mode4;
-#ifdef CONFIG_COMEDI_VER08
        s->do_cmdtest=ni_ai_cmdtest;
        s->do_cmd=ni_ai_cmd;
-#endif
        s->cancel=ni_ai_reset;
        s->do_lock=ni_ai_lock;
        s->do_unlock=ni_ai_unlock;
@@ -1418,7 +1425,6 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
                s->subdev_flags=SDF_WRITEABLE|SDF_RT|SDF_DEGLITCH|SDF_GROUND|SDF_OTHER;
                s->n_chan=boardtype.n_aochan;
                s->maxdata=(1<<boardtype.aobits)-1;
-               s->timer_type=TIMER_atmio;
                s->range_table=&range_ni_E_ao_ext;      /* XXX wrong for some boards */
                s->trig[0]=ni_ao_mode0;
                s->len_chanlist = 2;
index 8ace19cdfaea918c99e2f20ddf36aa5509514a1c..35ff479ce722aa5fd9b359305ebe74201d6a4616 100644 (file)
@@ -367,7 +367,6 @@ static int nidio_attach(comedi_device *dev,comedi_devconfig *it)
                s->maxdata=1;
                s->trig[0]=nidio_dio;
                s->trig[2]=nidio_dio_mode2;
-               s->timer_type=TIMER_nanosec;
                s->len_chanlist=32;             /* XXX */
 
                writel(0,dev->iobase+Port_IO(0));
index 5975cbc8e7bb06db26adc4fb364bb6da7454dbc4..cbf8bf0d74b019814b14edf57f5699cad4618891 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/timer.h>
 #include <asm/io.h>
 #include <comedi_module.h>
+#include <8253.h>
 
 
 
@@ -137,6 +138,7 @@ typedef int bool;
 #define PCL711_TIMEOUT 100
 #define PCL711_DRDY 0x10
 
+int i8253_osc_base = 500;      /* 2 Mhz */
 
 typedef struct {
        char *name;
@@ -148,18 +150,14 @@ typedef struct {
        int n_aochan;
        int maxirq;
        comedi_lrange * ai_range_type;
-       int ai_timer_type;
 } boardtype;
 
 static boardtype boardtypes[] =
 {
-       {"pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5, 0},
-       {"pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai,
-        TIMER_acl8112},
-       {"acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai,
-        TIMER_acl8112},
-       {"acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai,
-        TIMER_acl8112},
+       {"pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5},
+       {"pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai},
+       {"acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai},
+       {"acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai},
 };
 #define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
 
@@ -291,6 +289,8 @@ static int pcl711_ai_mode4(comedi_device * dev, comedi_subdevice * s, comedi_tri
 
 static int pcl711_ai_mode1(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
 {
+       int timer1,timer2;
+
        if (!dev->irq)
                return -EINVAL;
 
@@ -306,13 +306,14 @@ static int pcl711_ai_mode1(comedi_device * dev, comedi_subdevice * s, comedi_tri
         *  0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
         */
 
+       i8253_cascade_ns_to_timer(&timer1,&timer2,&it->trigvar,TRIG_ROUND_NEAREST);
 
        outb(0x74, dev->iobase + PCL711_CTRCTL);
-       outb((it->trigvar >> 16) & 0xff, dev->iobase + PCL711_CTR1);
-       outb((it->trigvar >> 24) & 0xff, dev->iobase + PCL711_CTR1);
+       outb(timer1 & 0xff, dev->iobase + PCL711_CTR1);
+       outb((timer1 >> 8) & 0xff, dev->iobase + PCL711_CTR1);
        outb(0xb4, dev->iobase + PCL711_CTRCTL);
-       outb(it->trigvar & 0xff, dev->iobase + PCL711_CTR2);
-       outb((it->trigvar >> 8) & 0xff, dev->iobase + PCL711_CTR2);
+       outb(timer2 & 0xff, dev->iobase + PCL711_CTR2);
+       outb((timer2 >> 8) & 0xff, dev->iobase + PCL711_CTR2);
 
        /* clear pending interrupts (just in case) */
        outb(0, dev->iobase + PCL711_CLRINTR);
@@ -457,7 +458,6 @@ static int pcl711_attach(comedi_device * dev, comedi_devconfig * it)
        s->n_chan = this_board->n_aichan;
        s->maxdata = 0xfff;
        s->len_chanlist = 1;
-       s->timer_type = this_board->ai_timer_type;
        s->range_table = this_board->ai_range_type;
        s->trig[0] = pcl711_ai_mode0;
        s->trig[1] = pcl711_ai_mode1;
index bc018bf83714d3dd9f51bc554553043a5eaade0d..dcee88db9aa072e7b52197fbdcb4d226c335cd1e 100644 (file)
@@ -1,30 +1,31 @@
-    /*
-   module/pcl812.c
-   hardware driver for Advantech cards
-    card:   PCL-812PG, PCL-813B
-    driver: pcl812pg,  pcl813b
-    
-   Michal Dobes <majkl@tesnet.cz>  
-   Based on 711.c 
-   
-   Options for PCL-812PG:
-    [0] - IO Base
-    [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
-    [2] - 0=trigger source is internal 8253 with 2MHz clock
-          1=trigger source is external 
-    [3] - 0=A/D have max +/-5V input
-          1=A/D have max +/-10V input
-    [4] - 0=D/A outputs 0-5V  (internal reference -5V)
-          1=D/A outputs 0-10V (internal reference -10V)
-         2=D/A outputs unknow (external reference)
-
-  Options for PCL-813B:
-    [0] - IO Base
-    [1] - 0= bipolar inputs
-          1= unipolar inputs
-    [2] - max number of samples in ai_mode0 (defaul=1scan)
-
-       
+// *INDENT-OFF*
+/*
+ * module/pcl812.c
+ * hardware driver for Advantech cards
+ *  card:   PCL-812PG, PCL-813B
+ *  driver: pcl812pg,  pcl813b
+ *  
+ * Michal Dobes <majkl@tesnet.cz>  
+ * Based on 711.c 
+ * 
+ * Options for PCL-812PG:
+ *  [0] - IO Base
+ *  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+ *  [2] - 0=trigger source is internal 8253 with 2MHz clock
+ *        1=trigger source is external 
+ *  [3] - 0=A/D have max +/-5V input
+ *        1=A/D have max +/-10V input
+ *  [4] - 0=D/A outputs 0-5V  (internal reference -5V)
+ *        1=D/A outputs 0-10V (internal reference -10V)
+ *        2=D/A outputs unknow (external reference)
+ *
+ * Options for PCL-813B:
+ *  [0] - IO Base
+ *  [1] - 0= bipolar inputs
+ *        1= unipolar inputs
+ *  [2] - max number of samples in ai_mode0 (defaul=1scan)
+ *
+ *     
  */
 
 #include <linux/kernel.h>
@@ -41,6 +42,7 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <comedi_module.h>
+#include <8253.h>
 
 /* #define MD_DEBUG */
 
@@ -117,6 +119,9 @@ static int pcl812_attach(comedi_device *dev,comedi_devconfig *it);
 static int pcl812_detach(comedi_device *dev);
 static int pcl812_recognize(char *name);
 
+static int i8253_osc_base = 500;       /* 2 Mhz */
+
+
 comedi_driver driver_pcl812={
        driver_name:    "pcl812",
        module:         &__this_module,
@@ -134,11 +139,12 @@ typedef struct {
        int n_dichan;
        int n_dochan;
        comedi_lrange *ai_range_type;
-       int ai_timer_type;
        comedi_lrange *ao_range_type;
        int io_range;
        unsigned int IRQbits;
-/*     unsigned int DMAbits; */
+#ifdef USE_DMA
+       unsigned int DMAbits;
+#endif
 /*     void *ai_mode[4];*/
        
 } boardtype;
@@ -154,11 +160,12 @@ static boardtype boardtypes[] =
        n_dichan:       16,
        n_dochan:       16,
        ai_range_type:  &range_pcl812pg_ai,
-       ai_timer_type:  TIMER_pcl812,
        ao_range_type:  &range_unipolar5,
        io_range:       PCLx1x_RANGE,
        IRQbits:        0xdcfc,
-//     DMAbits:        0x00,
+#ifdef USE_DMA
+       DMAbits:        0x00,
+#endif
        },
        {
        name:           "pcl813b",
@@ -169,24 +176,27 @@ static boardtype boardtypes[] =
        n_dichan:       0,
        n_dochan:       0,
        ai_range_type:  &range_pcl813b_ai,
-       ai_timer_type:  0,
        ao_range_type:  NULL,
        io_range:       PCLx1x_RANGE,
        IRQbits:        0x0000
-//     DMAbits:        0x00,
+#ifdef USE_DMA
+       DMAbits:        0x00,
+#endif
        },
 };
 
 #define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
 
 typedef struct {
-/*     int dma;
+#ifdef USE_DMA
+       int dma;
        unsigned long dmabuf[2];
        unsigned int dmapages[2];
        unsigned int hwdmaptr[2];
        unsigned int hwdmasize[2];
        int next_dma_buf;
-       unsigned long dma_runs_to_end; */
+       unsigned long dma_runs_to_end;
+#endif
        int irq_free;
        int irq_blocked;
        int irq_was_now_closed;
@@ -203,52 +213,57 @@ typedef struct {
 #define devpriv ((pcl812_private *)dev->private)
 #define this_board (boardtypes+dev->board)
 
+// *INDENT-ON*
 /* 
 ==============================================================================
    ANALOG INPUT MODE0, 812pg and 813b card
 */
-static int pcl812_ai_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) {
- int nmax;
- int i, n, p;
- int timeout, hi; 
-  
-  nmax=devpriv->max_812_ai_mode0_samples; /* block for max cca 1ms  (812) */
-  
-  if ((it->n*it->n_chan)<=nmax) nmax=it->n*it->n_chan;
-
-  nmax=nmax/it->n_chan;
-  if (!nmax) nmax++;
-  
-  outb(1, dev->iobase+PCL812_MODE); /* select software trigger */
-  
-  p=0; /* ptr to buff */
-  
-  for (n=0; n<nmax; n++) {
-    for (i=0; i<it->n_chan; i++) {      
-      outb(CR_RANGE(it->chanlist[i]), dev->iobase+PCL812_GAIN); /* select gain */
-      udelay(devpriv->max_812_ai_mode0_rangewait); 
-      outb(CR_CHAN(it->chanlist[i]), dev->iobase+PCL812_MUX); /* select channel */
-      udelay(devpriv->max_812_ai_mode0_chanset); 
-      outb(255, dev->iobase+PCL812_SOFTTRIG); /* start conversion */
-      udelay(devpriv->max_812_ai_mode0_convstart); 
-      timeout=20; /* wait max 100us, it must finish under 33us */
-      while (timeout--) {
-       hi=inb(dev->iobase + PCL812_AD_HI);
-       if (!(hi & PCL812_DRDY)) goto conv_finish;
-       udelay(5);
-       }
-      rt_printk("comedi%d: pcl812: (%s at 0x%x) A/D mode0 timeout\n", dev->minor, dev->board_name, dev->iobase);
-      it->data[p++]=0;
-      outb(0, dev->iobase+PCL812_MODE);
-      return -ETIME;
-
-conv_finish:
-      it->data[p++] = ((hi & 0xf) << 8) | inb(dev->iobase + PCL812_AD_LO);;
-     }
-   }
-
-  outb(0, dev->iobase+PCL812_MODE);
-  return p;
+static int pcl812_ai_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+{
+       int nmax;
+       int i, n, p;
+       int timeout, hi;
+
+       nmax = devpriv->max_812_ai_mode0_samples;       /* block for max cca 1ms  (812) */
+
+       if ((it->n * it->n_chan) <= nmax)
+               nmax = it->n * it->n_chan;
+
+       nmax = nmax / it->n_chan;
+       if (!nmax)
+               nmax++;
+
+       outb(1, dev->iobase + PCL812_MODE);     /* select software trigger */
+
+       p = 0;                  /* ptr to buff */
+
+       for (n = 0; n < nmax; n++) {
+               for (i = 0; i < it->n_chan; i++) {
+                       outb(CR_RANGE(it->chanlist[i]), dev->iobase + PCL812_GAIN);     /* select gain */
+                       udelay(devpriv->max_812_ai_mode0_rangewait);
+                       outb(CR_CHAN(it->chanlist[i]), dev->iobase + PCL812_MUX);       /* select channel */
+                       udelay(devpriv->max_812_ai_mode0_chanset);
+                       outb(255, dev->iobase + PCL812_SOFTTRIG);       /* start conversion */
+                       udelay(devpriv->max_812_ai_mode0_convstart);
+                       timeout = 20;   /* wait max 100us, it must finish under 33us */
+                       while (timeout--) {
+                               hi = inb(dev->iobase + PCL812_AD_HI);
+                               if (!(hi & PCL812_DRDY))
+                                       goto conv_finish;
+                               udelay(5);
+                       }
+                       rt_printk("comedi%d: pcl812: (%s at 0x%x) A/D mode0 timeout\n", dev->minor, dev->board_name, dev->iobase);
+                       it->data[p++] = 0;
+                       outb(0, dev->iobase + PCL812_MODE);
+                       return -ETIME;
+
+                     conv_finish:
+                       it->data[p++] = ((hi & 0xf) << 8) | inb(dev->iobase + PCL812_AD_LO);;
+               }
+       }
+
+       outb(0, dev->iobase + PCL812_MODE);
+       return p;
 }
 
 /* 
@@ -256,14 +271,21 @@ conv_finish:
    ANALOG OUTPUT MODE0, 812pg card
    only one sample per call is supported
 */
-static int pcl812_ao_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) {
-  int chan = CR_CHAN(it->chanlist[0]);
-  sampl_t data = it->data[0];
+static int pcl812_ao_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+{
+       int chan;
+       sampl_t data;
+       int i;
+
+       for(i=0;i<it->n_chan;i++){
+               chan = CR_CHAN(it->chanlist[i]);
+               data = it->data[i];
 
-  outb((data & 0xff), dev->iobase + (chan ? PCL812_DA2_LO : PCL812_DA1_LO));
-  outb(((data& 0xf) >> 8), dev->iobase + (chan ? PCL812_DA2_HI : PCL812_DA1_HI));
+               outb((data & 0xff), dev->iobase + (chan ? PCL812_DA2_LO : PCL812_DA1_LO));
+               outb(((data & 0xf) >> 8), dev->iobase + (chan ? PCL812_DA2_HI : PCL812_DA1_HI));
+       }
 
-  return 0;
+       return i;
 }
 
 /* 
@@ -272,20 +294,13 @@ static int pcl812_ao_mode0(comedi_device * dev, comedi_subdevice * s, comedi_tri
    
    only one sample per call is supported
 */
-static int pcl812_di_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) { 
-  int data;
-  int chan;
-  int i;
-
-  data = inb(dev->iobase + PCL812_DI_LO) |
-         (inb(dev->iobase + PCL812_DI_HI) << 8);
+static int pcl812_di_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+{
+       int data;
 
-  for(i=0;i<it->n_chan;i++) {
-    chan=CR_CHAN(it->chanlist[i]);
-    it->data[i]=(data>>chan)&1;
-   }
+       data = inb(dev->iobase + PCL812_DI_LO) | (inb(dev->iobase + PCL812_DI_HI) << 8);
 
-  return it->n_chan;
+       return di_unpack(data,it);
 }
 
 /* 
@@ -294,24 +309,13 @@ static int pcl812_di_mode0(comedi_device * dev, comedi_subdevice * s, comedi_tri
    
    only one sample per call is supported
 */
-static int pcl812_do_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) {
-  int mask, data;
-  int chan;
-  int i;
-
-  data=s->state;
-  for(i=0;i<it->n_chan;i++) {
-    chan=CR_CHAN(it->chanlist[i]);
-    mask=(1<<chan);
-    data &= ~mask;
-    if(it->data[i])
-      data |= mask;
-   }
-  outb(data & 0xff, dev->iobase + PCL812_DO_LO);
-  outb((data >> 8), dev->iobase + PCL812_DO_HI);
-  s->state = data;
-
-  return it->n_chan;
+static int pcl812_do_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+{
+       do_pack(&s->state,it);
+       outb(s->state & 0xff, dev->iobase + PCL812_DO_LO);
+       outb((s->state >> 8), dev->iobase + PCL812_DO_HI);
+
+       return it->n_chan;
 }
 
 /* 
@@ -319,63 +323,67 @@ static int pcl812_do_mode0(comedi_device * dev, comedi_subdevice * s, comedi_tri
    analog input interrupt mode 1 & 3, 812pg card
    one sample per interrupt version   
 */
-static void interrupt_pcl812_ai_mode13_int(int irq, void *d, struct pt_regs *regs) {
-
- int hi;
- comedi_device *dev = d;
- comedi_subdevice *s = dev->subdevices + 0;
-  
-  int timeout=20; /* wait max 100us, it must finish under 33us */
-  while (timeout--) {
-  hi=inb(dev->iobase + PCL812_AD_HI);
-  if (!(hi & PCL812_DRDY)) goto conv_finish;
-    udelay(5);
-   }
-  hi=inb(dev->iobase+PCL812_AD_LO);
-  outb(0,dev->iobase+PCL812_CLRINT); /* clear INT request */
-  rt_printk("comedi%d: pcl812: (%s at 0x%x) A/D mode1/3 IRQ without DRDY!\n", dev->minor, dev->board_name, dev->iobase);
-  return;
-
-conv_finish:
-  
-  s->cur_trig.data[s->buf_int_ptr++]=((hi<<8)|inb(dev->iobase+PCL812_AD_LO))&0xfff;
-
-  outb(0,dev->iobase+PCL812_CLRINT); /* clear INT request */
-
-  s->buf_int_count+=sizeof(sampl_t);
-  
-  if ((++devpriv->int13_act_chan)>=s->cur_trig.n_chan) { /* one scan done */
-    devpriv->int13_act_chan=0;
-    outb(CR_RANGE(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase+PCL812_GAIN); /* select next gain */
-    outb(CR_CHAN(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase+PCL812_MUX); /* select next channel */
-    if (s->cur_trig.flags & TRIG_WAKE_EOS) comedi_eos(dev,s);  
-    devpriv->int13_act_scan++;
-   } else {
-    outb(CR_RANGE(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase+PCL812_GAIN); /* select next gain */
-    outb(CR_CHAN(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase+PCL812_MUX); /* select next channel */
-   }
-
-  if (s->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
-    s->buf_int_ptr=0;
-    //devpriv->int13_act_ptr=0;
-    comedi_eobuf(dev,s);    
-   }
-
-  if ( devpriv->int13_act_scan>=s->cur_trig.n ) { /* all data sampled */
-    outb(0, dev->iobase+PCL812_MODE); /* Stop A/D */
-    outb(0,dev->iobase+PCL812_CLRINT); /* clear INT request */
-    if (devpriv->int812_mode==1) {
-      /* Stop pacer */
-      outb(0xb4, dev->iobase + PCL812_CTRCTL);
-      outb(0x74, dev->iobase + PCL812_CTRCTL);
-     }
-    s->busy = 0;
-    devpriv->irq_blocked=0;
-    devpriv->int812_mode=0;
-    devpriv->irq_was_now_closed=1;
-     /* printk("comedi_done\n"); */
-    comedi_done(dev,s); 
-   }
+static void interrupt_pcl812_ai_mode13_int(int irq, void *d, struct pt_regs *regs)
+{
+
+       int hi;
+       comedi_device *dev = d;
+       comedi_subdevice *s = dev->subdevices + 0;
+
+       int timeout = 20;       /* wait max 100us, it must finish under 33us */
+       while (timeout--) {
+               hi = inb(dev->iobase + PCL812_AD_HI);
+               if (!(hi & PCL812_DRDY))
+                       goto conv_finish;
+               udelay(5);
+       }
+       hi = inb(dev->iobase + PCL812_AD_LO);
+       outb(0, dev->iobase + PCL812_CLRINT);   /* clear INT request */
+       rt_printk("comedi%d: pcl812: (%s at 0x%x) A/D mode1/3 IRQ without DRDY!\n", dev->minor, dev->board_name, dev->iobase);
+       comedi_done(dev,s);
+       return;
+
+      conv_finish:
+
+       s->cur_trig.data[s->buf_int_ptr++] = ((hi << 8) | inb(dev->iobase + PCL812_AD_LO)) & 0xfff;
+
+       outb(0, dev->iobase + PCL812_CLRINT);   /* clear INT request */
+
+       s->buf_int_count += sizeof(sampl_t);
+
+       if ((++devpriv->int13_act_chan) >= s->cur_trig.n_chan) {        /* one scan done */
+               devpriv->int13_act_chan = 0;
+               outb(CR_RANGE(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_GAIN);       /* select next gain */
+               outb(CR_CHAN(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_MUX); /* select next channel */
+               if (s->cur_trig.flags & TRIG_WAKE_EOS)
+                       comedi_eos(dev, s);
+               devpriv->int13_act_scan++;
+       } else {
+               outb(CR_RANGE(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_GAIN);       /* select next gain */
+               outb(CR_CHAN(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_MUX); /* select next channel */
+       }
+
+       if (s->buf_int_ptr >= s->cur_trig.data_len) {   /* buffer rollover */
+               s->buf_int_ptr = 0;
+               //devpriv->int13_act_ptr=0;
+               comedi_eobuf(dev, s);
+       }
+
+       if (devpriv->int13_act_scan >= s->cur_trig.n) { /* all data sampled */
+               outb(0, dev->iobase + PCL812_MODE);     /* Stop A/D */
+               outb(0, dev->iobase + PCL812_CLRINT);   /* clear INT request */
+               if (devpriv->int812_mode == 1) {
+                       /* Stop pacer */
+                       outb(0xb4, dev->iobase + PCL812_CTRCTL);
+                       outb(0x74, dev->iobase + PCL812_CTRCTL);
+               }
+               s->busy = 0;
+               devpriv->irq_blocked = 0;
+               devpriv->int812_mode = 0;
+               devpriv->irq_was_now_closed = 1;
+               /* printk("comedi_done\n"); */
+               comedi_done(dev, s);
+       }
 }
 
 
@@ -383,35 +391,38 @@ conv_finish:
 ==============================================================================
     INT procedure
 */
-static void interrupt_pcl812(int irq, void *d, struct pt_regs *regs) {
-
- comedi_device *dev = d;
-
-  if ((!dev->irq)|(!devpriv->irq_free)|(!devpriv->irq_blocked)|(!devpriv->int812_mode)) {
-    if (devpriv->irq_was_now_closed) {
-      devpriv->irq_was_now_closed=0;
-      outb(0,dev->iobase+PCL812_CLRINT); /* clear INT request */
-      rt_printk("comedi%d: pcl812: (%s at 0x%x) too much IRQs!\n", dev->minor, dev->board_name, dev->iobase);
-      return;
-     } 
-    rt_printk("comedi%d: pcl812: (%s at 0x%x) bad IRQ!\n", dev->minor, dev->board_name, dev->iobase);
-    return;
-   }
-
-  switch (devpriv->int812_mode) {
-    case INT_TYPE_AI1_INT:
-      interrupt_pcl812_ai_mode13_int(irq, d, regs);
-      return;
-    case INT_TYPE_AI3_INT:
-      interrupt_pcl812_ai_mode13_int(irq, d, regs);
-      return;
-/*    case INT_TYPE_AI1_DMA:
-      interrupt_pcl812_ai_mode13_dma(irq, d, regs);
-      return;
-    case INT_TYPE_AI3_DMA:
-      interrupt_pcl812_ai_mode13_dma(irq, d, regs);
-      return; */
-   }
+static void interrupt_pcl812(int irq, void *d, struct pt_regs *regs)
+{
+
+       comedi_device *dev = d;
+
+       if ((!dev->irq) | (!devpriv->irq_free) | (!devpriv->irq_blocked) | (!devpriv->int812_mode)) {
+               if (devpriv->irq_was_now_closed) {
+                       devpriv->irq_was_now_closed = 0;
+                       outb(0, dev->iobase + PCL812_CLRINT);   /* clear INT request */
+                       rt_printk("comedi%d: pcl812: (%s at 0x%x) too much IRQs!\n", dev->minor, dev->board_name, dev->iobase);
+                       return;
+               }
+               rt_printk("comedi%d: pcl812: (%s at 0x%x) bad IRQ!\n", dev->minor, dev->board_name, dev->iobase);
+               return;
+       }
+
+       switch (devpriv->int812_mode) {
+       case INT_TYPE_AI1_INT:
+               interrupt_pcl812_ai_mode13_int(irq, d, regs);
+               return;
+       case INT_TYPE_AI3_INT:
+               interrupt_pcl812_ai_mode13_int(irq, d, regs);
+               return;
+#if USE_DMA
+       case INT_TYPE_AI1_DMA:
+               interrupt_pcl812_ai_mode13_dma(irq, d, regs);
+               return;
+       case INT_TYPE_AI3_DMA:
+               interrupt_pcl812_ai_mode13_dma(irq, d, regs);
+               return;
+#endif
+       }
 }
 
 /* 
@@ -419,130 +430,156 @@ static void interrupt_pcl812(int irq, void *d, struct pt_regs *regs) {
    ANALOG INPUT MODE 1, 812pg card
    interrupt pacer pooling
 */
-static int pcl812_ai_mode1_int(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) {
-  /*
-   *  Set timers
-   *   timer chip is an 8253, with timers 1 and 2
-   *   cascaded
-   *  0x74 = Select Counter 1 | LSB/MSB | Mode=2 | Binary
-   *        Mode 2 = Rate generator
-   *
-   *  0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
-   */
-
-  outb(0x74, dev->iobase + PCL812_CTRCTL);
-  outb((it->trigvar >> 16) & 0xff, dev->iobase + PCL812_CTR1);
-  outb((it->trigvar >> 24) & 0xff, dev->iobase + PCL812_CTR1);
-  outb(0xb4, dev->iobase + PCL812_CTRCTL);
-  outb(it->trigvar & 0xff, dev->iobase + PCL812_CTR2);
-  outb((it->trigvar >> 8) & 0xff, dev->iobase + PCL812_CTR2);
-
-  /* clear pending interrupts (just in case) */
-  outb(0, dev->iobase + PCL812_CLRINT);
-
-  //devpriv->int13_act_ptr=0;
-  devpriv->int13_act_scan=0;
-  devpriv->int13_act_chan=0;
-  devpriv->int812_mode=INT_TYPE_AI1_INT; /* analog in, mode 0, int driven */
-  devpriv->irq_blocked=1;
-  devpriv->irq_was_now_closed=0;
-
-  outb(6, dev->iobase + PCL812_MODE); /* Pacer+IRQ */
-
-  return 0;
+static int pcl812_ai_mode1_int(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+{
+       int timer1,timer2;
+
+       /*
+        *  Set timers
+        *    timer chip is an 8253, with timers 1 and 2
+        *    cascaded
+        *  0x74 = Select Counter 1 | LSB/MSB | Mode=2 | Binary
+        *        Mode 2 = Rate generator
+        *
+        *  0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
+        */
+
+       i8253_cascade_ns_to_timer(&timer1,&timer2,&it->trigvar,TRIG_ROUND_NEAREST);
+
+       outb(0x74, dev->iobase + PCL812_CTRCTL);
+       outb((timer1) & 0xff, dev->iobase + PCL812_CTR1);
+       outb((timer1 >> 8) & 0xff, dev->iobase + PCL812_CTR1);
+       outb(0xb4, dev->iobase + PCL812_CTRCTL);
+       outb(timer2 & 0xff, dev->iobase + PCL812_CTR2);
+       outb((timer2 >> 8) & 0xff, dev->iobase + PCL812_CTR2);
+
+       /* clear pending interrupts (just in case) */
+       outb(0, dev->iobase + PCL812_CLRINT);
+
+       //devpriv->int13_act_ptr=0;
+       devpriv->int13_act_scan = 0;
+       devpriv->int13_act_chan = 0;
+       devpriv->int812_mode = INT_TYPE_AI1_INT;        /* analog in, mode 0, int driven */
+       devpriv->irq_blocked = 1;
+       devpriv->irq_was_now_closed = 0;
+
+       outb(6, dev->iobase + PCL812_MODE);     /* Pacer+IRQ */
+
+       return 0;
 }
 
 /* 
 ==============================================================================
    ANALOG INPUT MODE 1, 812pg card
 */
-static int pcl812_ai_mode1(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) {
-
-  if (!dev->irq)
-    return -EINVAL;
-  if (devpriv->irq_blocked)
-    return -EBUSY;
-  if (it->n_chan<0) return -1;
-
-//  if (devpriv->dma) { /* check if we can use DMA? */
-//    if (it->n_chan==1) {
-//      return pcl812_ai_mode1_dma(dev, s, it); /* we scanning only one chan, we can */
-//     } else  {
-//      fst=it->chanlist[0];
-//      for (i=1; i<it->n_chan; i++)
-//        if (fst!=it->chanlist[0]) { i=-1; break; }
-//      if (i==-1) { return pcl812_ai_mode1_int(dev, s, it); }
-//            else { return pcl812_ai_mode1_dma(dev, s, it); }
-//     }
-// }
-  return pcl812_ai_mode1_int(dev, s, it); /* no, we can only int driven */
+static int pcl812_ai_mode1(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+{
+
+       if (!dev->irq)
+               return -EINVAL;
+       if (devpriv->irq_blocked)
+               return -EBUSY;
+       if (it->n_chan < 0)
+               return -1;
+
+#ifdef USE_DMA
+       if (devpriv->dma) {     /* check if we can use DMA? */
+               if (it->n_chan == 1) {
+                       return pcl812_ai_mode1_dma(dev, s, it); /* we scanning only one chan, we can */
+               } else {
+                       fst = it->chanlist[0];
+                       for (i = 1; i < it->n_chan; i++) {
+                               if (fst != it->chanlist[0]) {
+                                       i = -1;
+                                       break;
+                               }
+                       }
+                       if (i == -1) {
+                               return pcl812_ai_mode1_int(dev, s, it);
+                       } else {
+                               return pcl812_ai_mode1_dma(dev, s, it);
+                       }
+               }
+       }
+#endif
+       return pcl812_ai_mode1_int(dev, s, it); /* no, we can only int driven */
 }
 
 /* 
 ==============================================================================
    ANALOG INPUT MODE 3, 812pg card
 */
-static int pcl812_ai_mode3_int(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) {
+static int pcl812_ai_mode3_int(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+{
 
-  if (!dev->irq)
-    return -EINVAL;
-  if (devpriv->irq_blocked)
-    return -EBUSY;
+       if (!dev->irq)
+               return -EINVAL;
+       if (devpriv->irq_blocked)
+               return -EBUSY;
 
-  /* clear pending interrupts (just in case) */
-  outb(0, dev->iobase + PCL812_CLRINT);
+       /* clear pending interrupts (just in case) */
+       outb(0, dev->iobase + PCL812_CLRINT);
 
-  //devpriv->int13_act_ptr=0;
-  devpriv->int13_act_scan=0;
-  devpriv->int13_act_chan=0;
-  devpriv->int812_mode=3; /* analog in, mode 3, int driven */
-  devpriv->irq_blocked=1;
+       //devpriv->int13_act_ptr=0;
+       devpriv->int13_act_scan = 0;
+       devpriv->int13_act_chan = 0;
+       devpriv->int812_mode = 3;       /* analog in, mode 3, int driven */
+       devpriv->irq_blocked = 1;
 
-  outb(6, dev->iobase + PCL812_MODE); /* external trigger+IRQ */
+       outb(6, dev->iobase + PCL812_MODE);     /* external trigger+IRQ */
 
-  return 0;
+       return 0;
 }
 
 /* 
 ==============================================================================
   Free any resources that we have claimed  
 */
-static void free_resources(comedi_device * dev) {
-
-  if (dev->irq) free_irq(dev->irq, dev);
-  if (dev->iobase) release_region(dev->iobase, dev->iosize);
-/*  if(dev->private) {
-    if (devpriv->dmabuf[0]) free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
-    if (devpriv->dmabuf[1]) free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
-    if (devpriv->dma) free_dma(devpriv->dma);
-   } */
+static void free_resources(comedi_device * dev)
+{
+
+       if (dev->irq)
+               free_irq(dev->irq, dev);
+       if (dev->iobase)
+               release_region(dev->iobase, dev->iosize);
+#ifdef USE_DMA
+       if (dev->private) {
+               if (devpriv->dmabuf[0])
+                       free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+               if (devpriv->dmabuf[1])
+                       free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+               if (devpriv->dma)
+                       free_dma(devpriv->dma);
+       }
+#endif
 }
 
 /* 
 ==============================================================================
  reset whole PCL-812 or PCL-813 
 */
-static void pcl812_reset(comedi_device * dev) {
-  if (dev->board==boardPCL812PG) {
-    outb(0, dev->iobase + PCL812_DA1_LO);
-    outb(0, dev->iobase + PCL812_DA1_HI);
-    outb(0, dev->iobase + PCL812_DA2_LO);
-    outb(0, dev->iobase + PCL812_DA2_HI);
-    outb(0, dev->iobase + PCL812_DO_HI);
-    outb(0, dev->iobase + PCL812_DO_LO);
-    outb(0, dev->iobase + PCL812_MODE);
-    outb(0, dev->iobase + PCL812_CLRINT);
-   }    
-  outb(0, dev->iobase + PCL812_GAIN);
-  outb(0, dev->iobase + PCL812_MUX);
-  udelay(5);
-  if (dev->board==boardPCL813B) {
+static void pcl812_reset(comedi_device * dev)
+{
+       if (dev->board == boardPCL812PG) {
+               outb(0, dev->iobase + PCL812_DA1_LO);
+               outb(0, dev->iobase + PCL812_DA1_HI);
+               outb(0, dev->iobase + PCL812_DA2_LO);
+               outb(0, dev->iobase + PCL812_DA2_HI);
+               outb(0, dev->iobase + PCL812_DO_HI);
+               outb(0, dev->iobase + PCL812_DO_LO);
+               outb(0, dev->iobase + PCL812_MODE);
+               outb(0, dev->iobase + PCL812_CLRINT);
+       }
+       outb(0, dev->iobase + PCL812_GAIN);
+       outb(0, dev->iobase + PCL812_MUX);
+       udelay(5);
+       if (dev->board == boardPCL813B) {
 #ifdef PCL813_MICROSECS
-    udelay(5);
+               udelay(5);
 #else
-    udelay(5000);
+               udelay(5000);
 #endif
-   }
+       }
 }
 
 
@@ -552,215 +589,251 @@ static void pcl812_reset(comedi_device * dev) {
    Initialization 
 
 */
-static int pcl812_attach(comedi_device * dev, comedi_devconfig * it) {
-
- int ret;
- int iobase;
- int irq/*,dma*/;
-/* unsigned long pages;*/
- int i;
- int board;
- comedi_subdevice *s;
- int num_of_subdevs, subdevs[5];
-       
-  board = dev->board; /* inicialized from pcl812_recognize()? */
-
-  /* claim our I/O space */
-  iobase = it->options[0];
-  printk("comedi%d: pcl812:  board=%s, ioport=0x%03x", dev->minor, boardtypes[board].name, iobase);
-  if (check_region(iobase, boardtypes[board].io_range) < 0) {
-    printk("I/O port conflict\n");
-    return -EIO;
-   }
-  request_region(dev->iobase, boardtypes[board].io_range, "pcl812");
-  dev->iobase=iobase;
-  dev->iosize=boardtypes[board].io_range;
-
-  /* there should be a sanity check here */
-
-  if((ret=alloc_private(dev,sizeof(pcl812_private)))<0)
-    return ret; /* Can't alloc mem */
-
-  /* set up some name stuff */
-  dev->board_name = boardtypes[board].name;
-
-  /* grab our IRQ */
-  irq=0;
-  if (boardtypes[board].IRQbits!=0) { /* board support IRQ */
-    irq=it->options[1];
-    if (irq)  {/* we want to use IRQ */
-      if (((1<<irq)&boardtypes[board].IRQbits)==0) {
-        printk(", IRQ %d is out of allowed range, DISABLING IT",irq);
-        irq=0; /* Bad IRQ */
-       } else { 
-        if (request_irq(irq, interrupt_pcl812, SA_INTERRUPT, "pcl812", dev)) {
-          printk(", unable to allocate IRQ %d, DISABLING IT", irq);
-          irq=0; /* Can't use IRQ */
-         } else {
-          printk(", irq=%d", irq);
-         }    
-       }  
-     }
-   }
-
-  dev->irq = irq;
-  if (irq) { devpriv->irq_free=1; } /* 1=we have allocated irq */
-      else { devpriv->irq_free=0; } 
-  devpriv->irq_blocked=0; /* number of subdevice which use IRQ */
-  devpriv->int812_mode=0; /* mode of irq */
-       
-  /* grab our DMA */
-//  dma=0;
-//  devpriv->dma=dma;
-//  if (!devpriv->irq_free) goto no_dma; /* if we haven't IRQ, we can't use DMA */
-//  if (boardtypes[board].DMAbits!=0) { /* board support DMA */
-//    dma=it->options[2];
-//    if (((1<<dma)&boardtypes[board].DMAbits)==0) {
-//      printk(", DMA is out of allowed range, FAIL!\n");
-//      return -EINVAL; /* Bad DMA */
-//     } 
-//    ret=request_dma(dma, "pcl812");
-//    if (ret) {
-//      printk(", unable to allocate DMA %d, FAIL!\n",dma);
-//      return -EBUSY; /* DMA isn't free */
-//     } 
-//    devpriv->dma=dma;
-//    printk(", dma=%d", dma);
-//    pages=1; /* we need 8KB */
-//    devpriv->dmabuf[0]= __get_dma_pages(GFP_KERNEL, pages);
-//    if (!devpriv->dmabuf[0]) {
-//      printk(", unable to allocate DMA buffer, FAIL!\n");
-//      /* maybe experiment with try_to_free_pages() will help .... */
-//      return -EBUSY; /* no buffer :-( */
-//     }
-//    devpriv->dmapages[0]=pages;
-//    devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
-//    devpriv->hwdmasize[0]=PAGE_SIZE*2;
-//    devpriv->dmabuf[1]= __get_dma_pages(GFP_KERNEL, pages);
-//    if (!devpriv->dmabuf[1]) {
-//      printk(", unable to allocate DMA buffer, FAIL!\n");
-//      return -EBUSY;
-//     }
-//    devpriv->dmapages[1]=pages;
-//    devpriv->hwdmaptr[1] = virt_to_bus((void *)devpriv->dmabuf[1]);
-//    devpriv->hwdmasize[1]=PAGE_SIZE*2;
-//   }
-
-//no_dma:
-   
-  num_of_subdevs=0;
-
-  /*if (!((board==boardPCL812PG)&&(it->options[3]==1))) {*/
-  if (this_board->n_aichan>0) subdevs[num_of_subdevs++]=COMEDI_SUBD_AI;
-  /* }*/
-  if (this_board->n_aochan>0) subdevs[num_of_subdevs++]=COMEDI_SUBD_AO;
-  if (this_board->n_dichan>0) subdevs[num_of_subdevs++]=COMEDI_SUBD_DI;
-  if (this_board->n_dochan>0) subdevs[num_of_subdevs++]=COMEDI_SUBD_DO;
-
-  dev->n_subdevices = num_of_subdevs;
-  if((ret=alloc_subdevices(dev))<0)
-    return ret;
-
-  s = dev->subdevices + 0;
-  for (i = 0; i < num_of_subdevs; i++) {
-    s->type = subdevs[i];
-    switch (s->type) {
-      case COMEDI_SUBD_AI:
-        s->subdev_flags = SDF_READABLE;
-        s->n_chan = this_board->n_aichan;
-        s->maxdata = 0xfff;
-        s->len_chanlist = 1024;
-        s->timer_type = this_board->ai_timer_type;
-        s->range_table = this_board->ai_range_type;
-        switch (board) {
-          case boardPCL812PG:
-           s->subdev_flags|=SDF_GROUND;
-            s->trig[0] = pcl812_ai_mode0;
-           if (it->options[3]==1) s->range_table=&range_pcl812pg2_ai;
-           if (dev->irq) {
-             if (it->options[2]!=1) { s->trig[1] = pcl812_ai_mode1; }
-                               else { s->trig[3] = pcl812_ai_mode3_int; }
-             }
-            break;
-         case boardPCL813B:
-           s->subdev_flags|=SDF_GROUND;
-           if (it->options[1]==1) s->range_table=&range_pcl813b2_ai; 
-           s->trig[0] = pcl812_ai_mode0;
-           break;
-        }
-         break;
-      case COMEDI_SUBD_AO:
-        s->subdev_flags = SDF_WRITEABLE;
-        s->n_chan = this_board->n_aochan;
-        s->maxdata = 0xfff;
-        s->len_chanlist = 1;
-        //s->timer_type = this_board->ai_timer_type;
-        s->range_table = this_board->ao_range_type;
-        switch (board) {
-          case boardPCL812PG:
-           s->subdev_flags|=SDF_GROUND;
-           s->trig[0] = pcl812_ao_mode0;
-            //s->trig[1] = pcl812_ao_mode1;
-           if (it->options[4]==1) s->range_table=&range_unipolar5; 
-           if (it->options[4]==2) s->range_table=&range_unknown; 
-           break;
-         }     
-       break;
-      case COMEDI_SUBD_DI:
-        s->subdev_flags = SDF_READABLE;
-        s->n_chan = this_board->n_dichan;
-        s->maxdata = 1;
-        s->len_chanlist = this_board->n_dichan;
-        s->range_table = &range_digital;
-        switch (board) {
-          case boardPCL812PG:
-           s->trig[0] = pcl812_di_mode0;
-           break;
-         }     
-        break;
-      case COMEDI_SUBD_DO:
-        s->subdev_flags = SDF_WRITEABLE;
-        s->n_chan = this_board->n_dochan;
-        s->maxdata = 1;
-        s->len_chanlist = this_board->n_dochan;
-        s->range_table = &range_digital;
-        switch (board) {
-          case boardPCL812PG:
-            s->trig[0] = pcl812_do_mode0;
-           break;
-         }     
-       break;
-      }
-     s++;
-   }
-         
-  /*dev->rem = pcl812_rem;*/
-       
-  switch (dev->board) {
-    case boardPCL812PG: 
-     pcl812_reset(dev); 
-     devpriv->max_812_ai_mode0_samples=32;
-     devpriv->max_812_ai_mode0_rangewait=1;
-     devpriv->max_812_ai_mode0_chanset=1;
-     devpriv->max_812_ai_mode0_convstart=5;
-     break;
-    case boardPCL813B: 
-     pcl812_reset(dev); 
-     if (it->options[2]<2) { devpriv->max_812_ai_mode0_samples=1; }
-                      else { devpriv->max_812_ai_mode0_samples=it->options[2]; }
+static int pcl812_attach(comedi_device * dev, comedi_devconfig * it)
+{
+
+       int ret;
+       int iobase;
+       int irq;
+#ifdef USE_DMA
+       int dma;
+       unsigned long pages;
+#endif
+       int board;
+       comedi_subdevice *s;
+       int num_of_subdevs, subdevs[5];
+
+       board = dev->board;     /* inicialized from pcl812_recognize()? */
+
+       /* claim our I/O space */
+       iobase = it->options[0];
+       printk("comedi%d: pcl812:  board=%s, ioport=0x%03x", dev->minor, boardtypes[board].name, iobase);
+       if (check_region(iobase, boardtypes[board].io_range) < 0) {
+               printk("I/O port conflict\n");
+               return -EIO;
+       }
+       request_region(dev->iobase, boardtypes[board].io_range, "pcl812");
+       dev->iobase = iobase;
+       dev->iosize = boardtypes[board].io_range;
+
+       /* there should be a sanity check here */
+
+       if ((ret = alloc_private(dev, sizeof(pcl812_private))) < 0)
+               return ret;     /* Can't alloc mem */
+
+       /* set up some name stuff */
+       dev->board_name = boardtypes[board].name;
+
+       /* grab our IRQ */
+       irq = 0;
+       if (boardtypes[board].IRQbits != 0) {   /* board support IRQ */
+               irq = it->options[1];
+               if (irq) {      /* we want to use IRQ */
+                       if (((1 << irq) & boardtypes[board].IRQbits) == 0) {
+                               printk(", IRQ %d is out of allowed range, DISABLING IT", irq);
+                               irq = 0;        /* Bad IRQ */
+                       } else {
+                               if (request_irq(irq, interrupt_pcl812, SA_INTERRUPT, "pcl812", dev)) {
+                                       printk(", unable to allocate IRQ %d, DISABLING IT", irq);
+                                       irq = 0;        /* Can't use IRQ */
+                               } else {
+                                       printk(", irq=%d", irq);
+                               }
+                       }
+               }
+       }
+
+       dev->irq = irq;
+       if (irq) {
+               devpriv->irq_free = 1;
+       } /* 1=we have allocated irq */
+       else {
+               devpriv->irq_free = 0;
+       }
+       devpriv->irq_blocked = 0;       /* number of subdevice which use IRQ */
+       devpriv->int812_mode = 0;       /* mode of irq */
+
+#ifdef USE_DMA
+       /* grab our DMA */
+       dma = 0;
+       devpriv->dma = dma;
+       if (!devpriv->irq_free)
+               goto no_dma;    /* if we haven't IRQ, we can't use DMA */
+       if (boardtypes[board].DMAbits != 0) {   /* board support DMA */
+               dma = it->options[2];
+               if (((1 << dma) & boardtypes[board].DMAbits) == 0) {
+                       printk(", DMA is out of allowed range, FAIL!\n");
+                       return -EINVAL; /* Bad DMA */
+               }
+               ret = request_dma(dma, "pcl812");
+               if (ret) {
+                       printk(", unable to allocate DMA %d, FAIL!\n", dma);
+                       return -EBUSY;  /* DMA isn't free */
+               }
+               devpriv->dma = dma;
+               printk(", dma=%d", dma);
+               pages = 1;      /* we need 8KB */
+               devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+               if (!devpriv->dmabuf[0]) {
+                       printk(", unable to allocate DMA buffer, FAIL!\n");
+                       /* maybe experiment with try_to_free_pages() will help .... */
+                       return -EBUSY;  /* no buffer :-( */
+               }
+               devpriv->dmapages[0] = pages;
+               devpriv->hwdmaptr[0] = virt_to_bus((void *) devpriv->dmabuf[0]);
+               devpriv->hwdmasize[0] = PAGE_SIZE * 2;
+               devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+               if (!devpriv->dmabuf[1]) {
+                       printk(", unable to allocate DMA buffer, FAIL!\n");
+                       return -EBUSY;
+               }
+               devpriv->dmapages[1] = pages;
+               devpriv->hwdmaptr[1] = virt_to_bus((void *) devpriv->dmabuf[1]);
+               devpriv->hwdmasize[1] = PAGE_SIZE * 2;
+       }
+      no_dma:
+#endif
+
+       num_of_subdevs = 0;
+
+       /*if (!((board==boardPCL812PG)&&(it->options[3]==1))) { */
+       subdevs[num_of_subdevs++] = COMEDI_SUBD_AI;
+       /* } */
+       if (this_board->n_aochan > 0)
+               subdevs[num_of_subdevs++] = COMEDI_SUBD_AO;
+       if (this_board->n_dichan > 0)
+               subdevs[num_of_subdevs++] = COMEDI_SUBD_DI;
+       if (this_board->n_dochan > 0)
+               subdevs[num_of_subdevs++] = COMEDI_SUBD_DO;
+
+       dev->n_subdevices = 4;
+       if ((ret = alloc_subdevices(dev)) < 0)
+               return ret;
+
+       /* analog input */
+       s = dev->subdevices + 0;
+       if (this_board->n_aichan == 0) {
+               s->type = COMEDI_SUBD_UNUSED;
+       } else {
+               s->type = COMEDI_SUBD_AI;
+               s->subdev_flags = SDF_READABLE;
+               s->n_chan = this_board->n_aichan;
+               s->maxdata = 0xfff;
+               s->len_chanlist = 1024;
+               s->range_table = this_board->ai_range_type;
+               switch (board) {
+               case boardPCL812PG:
+                       s->subdev_flags |= SDF_GROUND;
+                       s->trig[0] = pcl812_ai_mode0;
+                       if (it->options[3] == 1)
+                               s->range_table = &range_pcl812pg2_ai;
+                       if (dev->irq) {
+                               if (it->options[2] != 1) {
+                                       s->trig[1] = pcl812_ai_mode1;
+                               } else {
+                                       s->trig[3] = pcl812_ai_mode3_int;
+                               }
+                       }
+                       break;
+               case boardPCL813B:
+                       s->subdev_flags |= SDF_GROUND;
+                       if (it->options[1] == 1)
+                               s->range_table = &range_pcl813b2_ai;
+                       s->trig[0] = pcl812_ai_mode0;
+                       break;
+               }
+       }
+
+       /* analog output */
+       s = dev->subdevices + 1;
+       if (this_board->n_aochan == 0) {
+               s->type = COMEDI_SUBD_UNUSED;
+       } else {
+               s->type = COMEDI_SUBD_AO;
+               s->subdev_flags = SDF_WRITEABLE;
+               s->n_chan = this_board->n_aochan;
+               s->maxdata = 0xfff;
+               s->len_chanlist = 1;
+               s->range_table = this_board->ao_range_type;
+               switch (board) {
+               case boardPCL812PG:
+                       s->subdev_flags |= SDF_GROUND;
+                       s->trig[0] = pcl812_ao_mode0;
+                       //s->trig[1] = pcl812_ao_mode1;
+                       if (it->options[4] == 1)
+                               s->range_table = &range_unipolar5;
+                       if (it->options[4] == 2)
+                               s->range_table = &range_unknown;
+                       break;
+               }
+       }
+
+       /* digital input */
+       s = dev->subdevices + 2;
+       if (this_board->n_dichan == 0) {
+               s->type = COMEDI_SUBD_UNUSED;
+       } else {
+               s->type = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE;
+               s->n_chan = this_board->n_dichan;
+               s->maxdata = 1;
+               s->len_chanlist = this_board->n_dichan;
+               s->range_table = &range_digital;
+               switch (board) {
+               case boardPCL812PG:
+                       s->trig[0] = pcl812_di_mode0;
+                       break;
+               }
+       }
+
+       /* digital output */
+       s = dev->subdevices + 3;
+       if (this_board->n_dochan == 0) {
+               s->type = COMEDI_SUBD_UNUSED;
+       } else {
+               s->type = COMEDI_SUBD_DO;
+               s->subdev_flags = SDF_WRITEABLE;
+               s->n_chan = this_board->n_dochan;
+               s->maxdata = 1;
+               s->len_chanlist = this_board->n_dochan;
+               s->range_table = &range_digital;
+               switch (board) {
+               case boardPCL812PG:
+                       s->trig[0] = pcl812_do_mode0;
+                       break;
+               }
+       }
+
+       /*dev->rem = pcl812_rem; */
+
+       switch (dev->board) {
+       case boardPCL812PG:
+               pcl812_reset(dev);
+               devpriv->max_812_ai_mode0_samples = 32;
+               devpriv->max_812_ai_mode0_rangewait = 1;
+               devpriv->max_812_ai_mode0_chanset = 1;
+               devpriv->max_812_ai_mode0_convstart = 5;
+               break;
+       case boardPCL813B:
+               pcl812_reset(dev);
+               if (it->options[2] < 2) {
+                       devpriv->max_812_ai_mode0_samples = 1;
+               } else {
+                       devpriv->max_812_ai_mode0_samples = it->options[2];
+               }
 #ifdef PCL813_MICROSECS
-     devpriv->max_812_ai_mode0_rangewait=1; /* maybe there must by greatest timeout */
-     devpriv->max_812_ai_mode0_chanset=5;
-     devpriv->max_812_ai_mode0_convstart=20;
+               devpriv->max_812_ai_mode0_rangewait = 1;        /* maybe there must by greatest timeout */
+               devpriv->max_812_ai_mode0_chanset = 5;
+               devpriv->max_812_ai_mode0_convstart = 20;
 #else
-     devpriv->max_812_ai_mode0_rangewaint=1;
-     devpriv->max_812_ai_mode0_chanset=5000;
-     devpriv->max_812_ai_mode0_convstart=20000;
+               devpriv->max_812_ai_mode0_rangewaint = 1;
+               devpriv->max_812_ai_mode0_chanset = 5000;
+               devpriv->max_812_ai_mode0_convstart = 20000;
 #endif
-     break;
-   }
-  printk("\n");
-  return 0;
+               break;
+       }
+       printk("\n");
+       return 0;
 }
 
 
@@ -768,31 +841,33 @@ static int pcl812_attach(comedi_device * dev, comedi_devconfig * it) {
 ==============================================================================
   Removes device
  */
-static int pcl812_detach(comedi_device * dev) {
+static int pcl812_detach(comedi_device * dev)
+{
 
 #ifdef MD_DEBUG
-  printk("comedi%d: pcl812: remove\n", dev->minor);
+       printk("comedi%d: pcl812: remove\n", dev->minor);
 #endif
-  free_resources(dev);
-  return 0;
+       free_resources(dev);
+       return 0;
 }
 
-static int pcl812_recognize(char *name) {
+static int pcl812_recognize(char *name)
+{
 
- int i;
      int i;
 
 #ifdef MD_DEBUG
-  printk("comedi: pcl812: recognize code '%s'\n",name);
+       printk("comedi: pcl812: recognize code '%s'\n", name);
 #endif
-  for (i = 0; i < n_boardtypes; i++) {
-    if (!strcmp(boardtypes[i].name, name)) {
+       for (i = 0; i < n_boardtypes; i++) {
+               if (!strcmp(boardtypes[i].name, name)) {
 #ifdef MD_DEBUG
-      printk("comedi: pcl812: recognize found '%s'\n", boardtypes[i].name);
+                       printk("comedi: pcl812: recognize found '%s'\n", boardtypes[i].name);
 #endif
-      return i;
-     }
-   }
-  return -1;
+                       return i;
+               }
+       }
+       return -1;
 }
 
 /*  
@@ -802,7 +877,7 @@ static int pcl812_recognize(char *name) {
 int init_module(void)
 {
        comedi_driver_register(&driver_pcl812);
-       
+
        return 0;
 }
 
@@ -810,6 +885,7 @@ void cleanup_module(void)
 {
        comedi_driver_unregister(&driver_pcl812);
 }
+
 #endif
 
 
@@ -818,135 +894,58 @@ void cleanup_module(void)
    that work identicaly under C and TP :-) */
 static void Zisti_Div8254(long celk, long *d1, long *d2)
 {
-       long minch,chyba,mini,i;
+       long minch, chyba, mini, i;
 
-       minch=32000;
-       mini=1;
-       if (celk<=(65536*2)) {
-               i=2;
+       minch = 32000;
+       mini = 1;
+       if (celk <= (65536 * 2)) {
+               i = 2;
        } else {
-               i=celk / 65536;
+               i = celk / 65536;
        }
        do {
-               *d1=i;
-               *d2=celk / *d1;
-               if (*d2<65536) {
-                       chyba=celk- *d1* *d2;
-                       if (chyba<0) {
-                               chyba=-chyba;
+               *d1 = i;
+               *d2 = celk / *d1;
+               if (*d2 < 65536) {
+                       chyba = celk - *d1 * *d2;
+                       if (chyba < 0) {
+                               chyba = -chyba;
                        }
-                       if (chyba<minch) {
-                               minch=chyba;
-                               mini=i;
-                               if (chyba==0) break;
+                       if (chyba < minch) {
+                               minch = chyba;
+                               mini = i;
+                               if (chyba == 0)
+                                       break;
                        }
                }
                i++;
-       } while ((i<65536)&&(*d2>2)&&(*d2> *d1));
-       i=mini;
-       *d1 =i;
-       *d2=celk/ *d1;
+       } while ((i < 65536) && (*d2 > 2) && (*d2 > *d1));
+       i = mini;
+       *d1 = i;
+       *d2 = celk / *d1;
 }
 
-static int pcl812_timer(double freq,unsigned int *trigvar,double *actual_freq)
+static int pcl812_timer(double freq, unsigned int *trigvar, double *actual_freq)
 {
-       long divisor1,divisor2,divid;
-       double Oscilator=2e6;
-
-       if (freq<0.0004) { freq=0.0004; }
-       if (freq>30000) { freq=30000; }
-       divid=rint(Oscilator/freq);
-       Zisti_Div8254(divid,&divisor1,&divisor2);
-       divid=rint(Oscilator/freq+0.5*(divid-divisor1*divisor2));
-       Zisti_Div8254(divid,&divisor1,&divisor2);
-       *actual_freq=Oscilator/(divisor1*divisor2);
-
-       *trigvar = (divisor1<<16) | divisor2;
-       return 0;
-}
-#endif
-
-static int osc_base = 500;     /* 2 Mhz */
-
-static void pcl812_ns_to_timer_2div(int *d1,int *d2,int *nanosec,int round_mode)
-{
-       int divider;
-       int div1,div2;
-       int div1_glb,div2_glb,ns_glb;
-       int div1_lub,div2_lub,ns_lub;
-       int ns;
-
-       divider=(*nanosec+osc_base/2)/osc_base;
-
-       /* find 2 integers 1<={x,y}<=65536 such that x*y is
-          close to divider */
-
-       div1_lub=div2_lub=0;
-       div1_glb=div2_glb=0;
+       long divisor1, divisor2, divid;
+       double Oscilator = 2e6;
 
-       ns_glb=0;
-       ns_lub=0xffffffff;
-
-       div2=0;
-       for(div1 = divider/65536;div1<div2;div1++){
-               div2 = *nanosec/(osc_base*div1);
-
-               ns = osc_base*div1*div2;
-               if(ns<=*nanosec && ns>ns_glb){
-                       ns_glb=ns;
-                       div1_glb=div1;
-                       div2_glb=div2;
-               }
-
-               div2++;
-               if(div2<=65536){
-                       ns = osc_base*div1*div2;
-                       if(ns>*nanosec && ns<ns_lub){
-                               ns_lub=ns;
-                               div1_lub=div1;
-                               div2_lub=div2;
-                       }
-               }
+       if (freq < 0.0004) {
+               freq = 0.0004;
        }
-
-       *d1 = div1_lub;
-       *d2 = div2_lub;
-}
-
-static void pcl812_ns_to_timer_power(int *d1,int *d2,int *nanosec,int round_mode)
-{
-       int div1,div2;
-       int base;
-
-       for(div1=1;div1<=(1<<16);div1<<=1){
-               base = osc_base*div1;
-               switch(round_mode){
-               case TRIG_ROUND_NEAREST:
-               default:
-                       div2=(*nanosec+base/2)/base;
-                       break;
-               case TRIG_ROUND_DOWN:
-                       div2=(*nanosec)/base;
-                       break;
-               case TRIG_ROUND_UP:
-                       div2=(*nanosec+base-1)/base;
-                       break;
-               }
-               if(div2<=65536){
-                       *nanosec=div2*base;
-                       *d1 = div1&0xffff;
-                       *d2 = div2&0xffff;
-                       return;
-               }
+       if (freq > 30000) {
+               freq = 30000;
        }
+       divid = rint(Oscilator / freq);
+       Zisti_Div8254(divid, &divisor1, &divisor2);
+       divid = rint(Oscilator / freq + 0.5 * (divid - divisor1 * divisor2));
+       Zisti_Div8254(divid, &divisor1, &divisor2);
+       *actual_freq = Oscilator / (divisor1 * divisor2);
 
-       /* shouldn't get here */
-       div1 = 0x10000;
-       div2 = 0x10000;
-       *nanosec=div1*div2*osc_base;
-       *d1 = div1&0xffff;
-       *d2 = div2&0xffff;
+       *trigvar = (divisor1 << 16) | divisor2;
+       return 0;
 }
 
+#endif
 
 
index fae086b6d5503a4c1339ee3c267b92b10ba1fcb5..44a2c9350ccaaaa985b8e54fba1e8b2f9fe90310 100644 (file)
@@ -104,7 +104,7 @@ int comedi_dio_write(unsigned int dev,unsigned int subdev,unsigned int chan,
        return ret;
 }
 
-int comedi_dio_bitfield(unsigned int dev,unsigned int subdev,unsigned int mask,
+int comedi_dio_bitfield(unsigned int minor,unsigned int subdev,unsigned int mask,
        unsigned int *bits)
 {
        int ret;
@@ -112,7 +112,7 @@ int comedi_dio_bitfield(unsigned int dev,unsigned int subdev,unsigned int mask,
        unsigned int m,bit;
        comedi_subdevice *s;
 
-       s=comedi_devices[dev].subdevices+subdev;
+       s=comedi_get_device_by_minor(minor)->subdevices+subdev;
 
        n_chan=s->n_chan;
        if(n_chan>32)n_chan=32;
@@ -120,9 +120,9 @@ int comedi_dio_bitfield(unsigned int dev,unsigned int subdev,unsigned int mask,
        for(i=0,m=1;i<n_chan;i++,m<<=1){
                if(mask&m){
                        bit=(*bits&m)?1:0;
-                       ret=comedi_dio_write(dev,subdev,i,bit);
+                       ret=comedi_dio_write(minor,subdev,i,bit);
                }else{
-                       ret=comedi_dio_read(dev,subdev,i,&bit);
+                       ret=comedi_dio_read(minor,subdev,i,&bit);
                        if(bit) *bits|=m;
                        else (*bits)&=~m;
                }
index 6c9a546c242e71eaa0e937a96d2d4df1ba396dc5..f20715e21cd466b36469094a7547a74f3721ea41 100644 (file)
@@ -58,7 +58,7 @@ static inline int minor_to_dev(unsigned int minor,comedi_device **dev)
        if(minor>=COMEDI_NDEVICES)
                return -ENODEV;
 
-       *dev=comedi_devices+minor;
+       *dev=comedi_get_device_by_minor(minor);
 
        if(!(*dev)->attached)
                return -ENODEV;
@@ -330,7 +330,7 @@ int __comedi_trig_ioctl(unsigned int minor,unsigned int subdev,comedi_trig *it)
        comedi_subdevice *s;
        int ret=0;
 
-       dev=comedi_devices+minor;
+       dev=comedi_get_device_by_minor(minor);
        s=dev->subdevices+subdev;
 
        s->cur_trig=*it;
index 559449645b9402e6a29ee644bcd4616e3525fc9c..20eed70ee88f5ae3934ea5d194fb9cd5a322d68f 100644 (file)
@@ -70,13 +70,16 @@ int comedi_read_procmem(char *buf,char **start,off_t offset,int len,int *eof,voi
                "\"%2d: %-20s %-20s %4d\",i,driver_name,board_name,n_subdevices");
 
        for(i=0;i<COMEDI_NDEVICES;i++){
-               if(comedi_devices[i].attached){
+               comedi_device *dev;
+
+               dev=comedi_get_device_by_minor(i);
+               if(dev->attached){
                        devices_q=1;
                        l+=sprintf(buf+l,"%2d: %-20s %-20s %4d\n",
                                i,
-                               comedi_devices[i].driver->driver_name,
-                               comedi_devices[i].board_name,
-                               comedi_devices[i].n_subdevices
+                               dev->driver->driver_name,
+                               dev->board_name,
+                               dev->n_subdevices
                                );
                }
        }
index 136ed044394fae11ced76e77cfa5b10fc5a1941b..eba0aed1cbe545744c62b53de910889896e04b45 100644 (file)
@@ -63,7 +63,7 @@ int do_rangeinfo_ioctl(comedi_device *dev,comedi_rangeinfo *arg)
 
        if(minor>COMEDI_NDEVICES)
                return -EINVAL;
-       dev=comedi_devices+minor;
+       dev=comedi_get_device_by_minor(minor);
        if(!dev->attached)return -EINVAL;
        if(subd>=dev->n_subdevices)return -EINVAL;
        s=dev->subdevices+subd;
index d4778577ae62abdc993d2db100ce89a9516da8b1..bab70f41cfe68b86c024a321a872b906d3395238 100644 (file)
@@ -115,7 +115,7 @@ static void dds_ao_task_func(int d)
                if(ret<0){
                        /* eek! */
                }
-#ifdef CONFIG_COMEDI_RTL
+#ifdef CONFIG_COMEDI_RTAI
                rt_task_wait();
 #endif
 #ifdef CONFIG_COMEDI_RTL
@@ -204,7 +204,7 @@ int dds_attach(comedi_device *dev,comedi_devconfig *it)
        devpriv->device=it->options[0];
        devpriv->subd=it->options[1];
 
-       devpriv->dev=comedi_devices+devpriv->device;
+       devpriv->dev=comedi_get_device_by_minor(devpriv->device);
        devpriv->s=devpriv->dev->subdevices+devpriv->subd;
 
        s=dev->subdevices+0;
@@ -217,7 +217,6 @@ int dds_attach(comedi_device *dev,comedi_devconfig *it)
        s->maxdata=devpriv->s->maxdata;
        s->range_table=devpriv->s->range_table;
        s->range_table_list=devpriv->s->range_table_list;
-       s->timer_type=TIMER_nanosec;
 
        devpriv->soft_irq=rtl_get_soft_irq(dds_interrupt,"dds");
        broken_rtl_dev=dev;
index e45c7f4d8e57e4df43450ee5f864bccfa2376e05..dffe1091ea1a18ebda53187a554f2dc89142ab6c 100644 (file)
@@ -135,7 +135,6 @@ static int timer_ai_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *it
        return comedi_trig_ioctl(devpriv->device,devpriv->subd,it);
 }
 
-#ifdef CONFIG_COMEDI_VER08
 static int timer_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
 {
        if(cmd->scan_start_arg<100000)  /* 10 khz */
@@ -181,7 +180,6 @@ unlock:
        comedi_unlock_ioctl(devpriv->device,devpriv->subd);
        return ret;
 }
-#endif
 
 static int timer_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
 {
@@ -257,7 +255,7 @@ static int timer_attach(comedi_device *dev,comedi_devconfig *it)
        devpriv->device=it->options[0];
        devpriv->subd=it->options[1];
 
-       devpriv->dev=comedi_devices+devpriv->device;
+       devpriv->dev=comedi_get_device_by_minor(devpriv->device);
        devpriv->s=devpriv->dev->subdevices+devpriv->subd;
 
        s=dev->subdevices+0;
@@ -267,15 +265,12 @@ static int timer_attach(comedi_device *dev,comedi_devconfig *it)
        s->len_chanlist=1024;
        s->trig[0]=timer_ai_mode0;
        s->trig[2]=timer_ai_mode2;
-#ifdef CONFIG_COMEDI_VER08
        s->do_cmd=timer_cmd;
        s->do_cmdtest=timer_cmdtest;
-#endif
        s->cancel=timer_cancel;
        s->maxdata=devpriv->s->maxdata;
        s->range_table=devpriv->s->range_table;
        s->range_table_list=devpriv->s->range_table_list;
-       s->timer_type=TIMER_nanosec;
 
        devpriv->soft_irq=rtl_get_soft_irq(timer_interrupt,"timer");
        broken_rtl_dev=dev;