Loading drivers/staging/comedi/drivers/pcl816.c +129 −129 Original line number Diff line number Diff line Loading @@ -43,38 +43,38 @@ Configuration Options: #define DEBUG(x) x // boards constants // IO space len /* boards constants */ /* IO space len */ #define PCLx1x_RANGE 16 //#define outb(x,y) printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y) /* #define outb(x,y) printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y) */ // INTEL 8254 counters /* INTEL 8254 counters */ #define PCL816_CTR0 4 #define PCL816_CTR1 5 #define PCL816_CTR2 6 // R: counter read-back register W: counter control /* R: counter read-back register W: counter control */ #define PCL816_CTRCTL 7 // R: A/D high byte W: A/D range control /* R: A/D high byte W: A/D range control */ #define PCL816_RANGE 9 // W: clear INT request /* W: clear INT request */ #define PCL816_CLRINT 10 // R: next mux scan channel W: mux scan channel & range control pointer /* R: next mux scan channel W: mux scan channel & range control pointer */ #define PCL816_MUX 11 // R/W: operation control register /* R/W: operation control register */ #define PCL816_CONTROL 12 // R: return status byte W: set DMA/IRQ /* R: return status byte W: set DMA/IRQ */ #define PCL816_STATUS 13 #define PCL816_STATUS_DRDY_MASK 0x80 // R: low byte of A/D W: soft A/D trigger /* R: low byte of A/D W: soft A/D trigger */ #define PCL816_AD_LO 8 // R: high byte of A/D W: A/D range control /* R: high byte of A/D W: A/D range control */ #define PCL816_AD_HI 9 // type of interrupt handler /* type of interrupt handler */ #define INT_TYPE_AI1_INT 1 #define INT_TYPE_AI1_DMA 2 #define INT_TYPE_AI3_INT 4 Loading @@ -83,7 +83,7 @@ Configuration Options: #define INT_TYPE_AI1_DMA_RTC 9 #define INT_TYPE_AI3_DMA_RTC 10 // RTC stuff... /* RTC stuff... */ #define RTC_IRQ 8 #define RTC_IO_EXTENT 0x10 #endif Loading @@ -103,35 +103,35 @@ static const struct comedi_lrange range_pcl816 = { 8, { }; struct pcl816_board { const char *name; // board name int n_ranges; // len of range list int n_aichan; // num of A/D chans in diferencial mode unsigned int ai_ns_min; // minimal alllowed delay between samples (in ns) int n_aochan; // num of D/A chans int n_dichan; // num of DI chans int n_dochan; // num of DO chans const struct comedi_lrange *ai_range_type; // default A/D rangelist const struct comedi_lrange *ao_range_type; // dafault D/A rangelist unsigned int io_range; // len of IO space unsigned int IRQbits; // allowed interrupts unsigned int DMAbits; // allowed DMA chans int ai_maxdata; // maxdata for A/D int ao_maxdata; // maxdata for D/A int ai_chanlist; // allowed len of channel list A/D int ao_chanlist; // allowed len of channel list D/A int i8254_osc_base; // 1/frequency of on board oscilator in ns const char *name; /* board name */ int n_ranges; /* len of range list */ int n_aichan; /* num of A/D chans in diferencial mode */ unsigned int ai_ns_min; /* minimal alllowed delay between samples (in ns) */ int n_aochan; /* num of D/A chans */ int n_dichan; /* num of DI chans */ int n_dochan; /* num of DO chans */ const struct comedi_lrange *ai_range_type; /* default A/D rangelist */ const struct comedi_lrange *ao_range_type; /* dafault D/A rangelist */ unsigned int io_range; /* len of IO space */ unsigned int IRQbits; /* allowed interrupts */ unsigned int DMAbits; /* allowed DMA chans */ int ai_maxdata; /* maxdata for A/D */ int ao_maxdata; /* maxdata for D/A */ int ai_chanlist; /* allowed len of channel list A/D */ int ao_chanlist; /* allowed len of channel list D/A */ int i8254_osc_base; /* 1/frequency of on board oscilator in ns */ }; static const struct pcl816_board boardtypes[] = { {"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816, &range_pcl816, PCLx1x_RANGE, 0x00fc, // IRQ mask 0x0a, // DMA mask 0xffff, // 16-bit card 0xffff, // D/A maxdata 0x00fc, /* IRQ mask */ 0x0a, /* DMA mask */ 0xffff, /* 16-bit card */ 0xffff, /* D/A maxdata */ 1024, 1, // ao chan list 1, /* ao chan list */ 100}, {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816, &range_pcl816, PCLx1x_RANGE, Loading Loading @@ -170,42 +170,42 @@ COMEDI_INITCLEANUP(driver_pcl816); struct pcl816_private { unsigned int dma; // used DMA, 0=don't use DMA int dma_rtc; // 1=RTC used with DMA, 0=no RTC alloc unsigned int dma; /* used DMA, 0=don't use DMA */ int dma_rtc; /* 1=RTC used with DMA, 0=no RTC alloc */ #ifdef unused unsigned long rtc_iobase; // RTC port region unsigned long rtc_iobase; /* RTC port region */ unsigned int rtc_iosize; unsigned int rtc_irq; #endif unsigned long dmabuf[2]; // pointers to begin of DMA buffers unsigned int dmapages[2]; // len of DMA buffers in PAGE_SIZEs unsigned int hwdmaptr[2]; // hardware address of DMA buffers unsigned int hwdmasize[2]; // len of DMA buffers in Bytes unsigned int dmasamplsize; // size in samples hwdmasize[0]/2 unsigned int last_top_dma; // DMA pointer in last RTC int int next_dma_buf; // which DMA buffer will be used next round long dma_runs_to_end; // how many we must permorm DMA transfer to end of record unsigned long last_dma_run; // how many bytes we must transfer on last DMA page unsigned int ai_scans; // len of scanlist unsigned char ai_neverending; // if=1, then we do neverending record (you must use cancel()) int irq_free; // 1=have allocated IRQ int irq_blocked; // 1=IRQ now uses any subdev unsigned long dmabuf[2]; /* pointers to begin of DMA buffers */ unsigned int dmapages[2]; /* len of DMA buffers in PAGE_SIZEs */ unsigned int hwdmaptr[2]; /* hardware address of DMA buffers */ unsigned int hwdmasize[2]; /* len of DMA buffers in Bytes */ unsigned int dmasamplsize; /* size in samples hwdmasize[0]/2 */ unsigned int last_top_dma; /* DMA pointer in last RTC int */ int next_dma_buf; /* which DMA buffer will be used next round */ long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */ unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */ unsigned int ai_scans; /* len of scanlist */ unsigned char ai_neverending; /* if=1, then we do neverending record (you must use cancel()) */ int irq_free; /* 1=have allocated IRQ */ int irq_blocked; /* 1=IRQ now uses any subdev */ #ifdef unused int rtc_irq_blocked; // 1=we now do AI with DMA&RTC int rtc_irq_blocked; /* 1=we now do AI with DMA&RTC */ #endif int irq_was_now_closed; // when IRQ finish, there's stored int816_mode for last interrupt int int816_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma struct comedi_subdevice *last_int_sub; // ptr to subdevice which now finish int ai_act_scan; // how many scans we finished unsigned int ai_act_chanlist[16]; // MUX setting for actual AI operations unsigned int ai_act_chanlist_len; // how long is actual MUX list unsigned int ai_act_chanlist_pos; // actual position in MUX list unsigned int ai_poll_ptr; // how many sampes transfer poll struct comedi_subdevice *sub_ai; // ptr to AI subdevice int irq_was_now_closed; /* when IRQ finish, there's stored int816_mode for last interrupt */ int int816_mode; /* who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */ struct comedi_subdevice *last_int_sub; /* ptr to subdevice which now finish */ int ai_act_scan; /* how many scans we finished */ unsigned int ai_act_chanlist[16]; /* MUX setting for actual AI operations */ unsigned int ai_act_chanlist_len; /* how long is actual MUX list */ unsigned int ai_act_chanlist_pos; /* actual position in MUX list */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */ #ifdef unused struct timer_list rtc_irq_timer; // timer for RTC sanity check unsigned long rtc_freq; // RTC int freq struct timer_list rtc_irq_timer; /* timer for RTC sanity check */ unsigned long rtc_freq; /* RTC int freq */ #endif }; Loading Loading @@ -237,12 +237,12 @@ static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevi int timeout; DPRINTK("mode 0 analog input\n"); // software trigger, DMA and INT off /* software trigger, DMA and INT off */ outb(0, dev->iobase + PCL816_CONTROL); // clear INT (conversion end) flag /* clear INT (conversion end) flag */ outb(0, dev->iobase + PCL816_CLRINT); // Set the input channel /* Set the input channel */ outb(CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX); outb(CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE); /* select gain */ Loading @@ -254,7 +254,7 @@ static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevi while (timeout--) { if (!(inb(dev->iobase + PCL816_STATUS) & PCL816_STATUS_DRDY_MASK)) { // return read value /* return read value */ data[n] = ((inb(dev->iobase + PCL816_AD_HI) << 8) | Loading @@ -265,7 +265,7 @@ static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevi } comedi_udelay(1); } // Return timeout error /* Return timeout error */ if (!timeout) { comedi_error(dev, "A/D insn timeout\n"); data[0] = 0; Loading Loading @@ -295,7 +295,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) break; comedi_udelay(1); } if (!timeout) { // timeout, bail error if (!timeout) { /* timeout, bail error */ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */ comedi_error(dev, "A/D mode1/3 IRQ without DRDY!"); pcl816_ai_cancel(dev, s); Loading @@ -305,7 +305,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) } // get the sample /* get the sample */ low = inb(dev->iobase + PCL816_AD_LO); hi = inb(dev->iobase + PCL816_AD_HI); Loading Loading @@ -352,7 +352,7 @@ static void transfer_from_dma_buf(struct comedi_device * dev, struct comedi_subd } if (!devpriv->ai_neverending) if (devpriv->ai_act_scan >= devpriv->ai_scans) { // all data sampled if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */ pcl816_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_BLOCK; Loading @@ -374,12 +374,12 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) disable_dma(devpriv->dma); this_dma_buf = devpriv->next_dma_buf; if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) { // switch dma bufs if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) { /* switch dma bufs */ devpriv->next_dma_buf = 1 - devpriv->next_dma_buf; set_dma_mode(devpriv->dma, DMA_MODE_READ); dma_flags = claim_dma_lock(); // clear_dma_ff (devpriv->dma); /* clear_dma_ff (devpriv->dma); */ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]); if (devpriv->dma_runs_to_end) { Loading Loading @@ -433,7 +433,7 @@ static irqreturn_t interrupt_pcl816(int irq, void *d PT_REGS_ARG) (!devpriv->int816_mode)) { if (devpriv->irq_was_now_closed) { devpriv->irq_was_now_closed = 0; // comedi_error(dev,"last IRQ.."); /* comedi_error(dev,"last IRQ.."); */ return IRQ_HANDLED; } comedi_error(dev, "bad IRQ!"); Loading Loading @@ -610,7 +610,7 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s return -EINVAL; if (cmd->scan_end_arg != cmd->chanlist_len) return -EINVAL; // if(cmd->chanlist_len>MAX_CHANLIST_LEN) return -EINVAL; /* if(cmd->chanlist_len>MAX_CHANLIST_LEN) return -EINVAL; */ if (devpriv->irq_blocked) return -EBUSY; Loading @@ -621,7 +621,7 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1, &divisor2, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); if (divisor1 == 1) { // PCL816 crash if any divisor is set to 1 if (divisor1 == 1) { /* PCL816 crash if any divisor is set to 1 */ divisor1 = 2; divisor2 /= 2; } Loading @@ -631,7 +631,7 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s } } start_pacer(dev, -1, 0, 0); // stop pacer start_pacer(dev, -1, 0, 0); /* stop pacer */ if (!check_and_setup_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len)) Loading @@ -652,19 +652,19 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s devpriv->ai_neverending = 1; } if ((cmd->flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan? if ((cmd->flags & TRIG_WAKE_EOS)) { /* don't we want wake up every scan? */ printk("pl816: You wankt WAKE_EOS but I dont want handle it"); // devpriv->ai_eos=1; //if (devpriv->ai_n_chan==1) // devpriv->dma=0; // DMA is useless for this situation /* devpriv->ai_eos=1; */ /* if (devpriv->ai_n_chan==1) */ /* devpriv->dma=0; // DMA is useless for this situation */ } if (devpriv->dma) { bytes = devpriv->hwdmasize[0]; if (!devpriv->ai_neverending) { bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short); // how many devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fill devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short); /* how many */ devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; /* how many DMA pages we must fill */ devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; /* on last dma transfer must be moved */ devpriv->dma_runs_to_end--; if (devpriv->dma_runs_to_end >= 0) bytes = devpriv->hwdmasize[0]; Loading @@ -687,14 +687,14 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s switch (cmd->convert_src) { case TRIG_TIMER: devpriv->int816_mode = INT_TYPE_AI1_DMA; outb(0x32, dev->iobase + PCL816_CONTROL); // Pacer+IRQ+DMA outb(dmairq, dev->iobase + PCL816_STATUS); // write irq and DMA to card outb(0x32, dev->iobase + PCL816_CONTROL); /* Pacer+IRQ+DMA */ outb(dmairq, dev->iobase + PCL816_STATUS); /* write irq and DMA to card */ break; default: devpriv->int816_mode = INT_TYPE_AI3_DMA; outb(0x34, dev->iobase + PCL816_CONTROL); // Ext trig+IRQ+DMA outb(dmairq, dev->iobase + PCL816_STATUS); // write irq to card outb(0x34, dev->iobase + PCL816_CONTROL); /* Ext trig+IRQ+DMA */ outb(dmairq, dev->iobase + PCL816_STATUS); /* write irq to card */ break; } Loading @@ -708,12 +708,12 @@ static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * unsigned int top1, top2, i; if (!devpriv->dma) return 0; // poll is valid only for DMA transfer return 0; /* poll is valid only for DMA transfer */ comedi_spin_lock_irqsave(&dev->spinlock, flags); for (i = 0; i < 20; i++) { top1 = get_dma_residue(devpriv->dma); // where is now DMA top1 = get_dma_residue(devpriv->dma); /* where is now DMA */ top2 = get_dma_residue(devpriv->dma); if (top1 == top2) break; Loading @@ -723,10 +723,10 @@ static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * return 0; } top1 = devpriv->hwdmasize[0] - top1; // where is now DMA in buffer top1 >>= 1; // sample position top1 = devpriv->hwdmasize[0] - top1; /* where is now DMA in buffer */ top1 >>= 1; /* sample position */ top2 = top1 - devpriv->ai_poll_ptr; if (top2 < 1) { // no new samples if (top2 < 1) { /* no new samples */ comedi_spin_unlock_irqrestore(&dev->spinlock, flags); return 0; } Loading @@ -735,7 +735,7 @@ static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * (short *) devpriv->dmabuf[devpriv->next_dma_buf], devpriv->ai_poll_ptr, top2); devpriv->ai_poll_ptr = top1; // new buffer position devpriv->ai_poll_ptr = top1; /* new buffer position */ comedi_spin_unlock_irqrestore(&dev->spinlock, flags); return s->async->buf_write_count - s->async->buf_read_count; Loading @@ -747,14 +747,14 @@ static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * */ static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s) { // DEBUG(rt_printk("pcl816_ai_cancel()\n");) /* DEBUG(rt_printk("pcl816_ai_cancel()\n");) */ if (devpriv->irq_blocked > 0) { switch (devpriv->int816_mode) { #ifdef unused case INT_TYPE_AI1_DMA_RTC: case INT_TYPE_AI3_DMA_RTC: set_rtc_irq_bit(0); // stop RTC set_rtc_irq_bit(0); /* stop RTC */ del_timer(&devpriv->rtc_irq_timer); #endif case INT_TYPE_AI1_DMA: Loading @@ -776,7 +776,7 @@ static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice devpriv->irq_was_now_closed = devpriv->int816_mode; devpriv->int816_mode = 0; devpriv->last_int_sub = s; // s->busy = 0; /* s->busy = 0; */ break; } } Loading @@ -795,18 +795,18 @@ static int pcl816_check(unsigned long iobase) outb(0x00, iobase + PCL816_MUX); comedi_udelay(1); if (inb(iobase + PCL816_MUX) != 0x00) return 1; //there isn't card return 1; /* there isn't card */ outb(0x55, iobase + PCL816_MUX); comedi_udelay(1); if (inb(iobase + PCL816_MUX) != 0x55) return 1; //there isn't card return 1; /* there isn't card */ outb(0x00, iobase + PCL816_MUX); comedi_udelay(1); outb(0x18, iobase + PCL816_CONTROL); comedi_udelay(1); if (inb(iobase + PCL816_CONTROL) != 0x18) return 1; //there isn't card return 0; // ok, card exist return 1; /* there isn't card */ return 0; /* ok, card exist */ } /* Loading @@ -815,12 +815,12 @@ static int pcl816_check(unsigned long iobase) */ static void pcl816_reset(struct comedi_device * dev) { // outb (0, dev->iobase + PCL818_DA_LO); // DAC=0V // outb (0, dev->iobase + PCL818_DA_HI); // comedi_udelay (1); // outb (0, dev->iobase + PCL818_DO_HI); // DO=$0000 // outb (0, dev->iobase + PCL818_DO_LO); // comedi_udelay (1); /* outb (0, dev->iobase + PCL818_DA_LO); DAC=0V */ /* outb (0, dev->iobase + PCL818_DA_HI); */ /* comedi_udelay (1); */ /* outb (0, dev->iobase + PCL818_DO_HI); DO=$0000 */ /* outb (0, dev->iobase + PCL818_DO_LO); */ /* comedi_udelay (1); */ outb(0, dev->iobase + PCL816_CONTROL); outb(0, dev->iobase + PCL816_MUX); outb(0, dev->iobase + PCL816_CLRINT); Loading @@ -842,8 +842,8 @@ start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1, outb(0xff, dev->iobase + PCL816_CTR0); outb(0x00, dev->iobase + PCL816_CTR0); comedi_udelay(1); outb(0xb4, dev->iobase + PCL816_CTRCTL); // set counter 2 as mode 3 outb(0x74, dev->iobase + PCL816_CTRCTL); // set counter 1 as mode 3 outb(0xb4, dev->iobase + PCL816_CTRCTL); /* set counter 2 as mode 3 */ outb(0x74, dev->iobase + PCL816_CTRCTL); /* set counter 1 as mode 3 */ comedi_udelay(1); if (mode == 1) { Loading @@ -856,7 +856,7 @@ start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1, } /* clear pending interrupts (just in case) */ // outb(0, dev->iobase + PCL816_CLRINT); /* outb(0, dev->iobase + PCL816_CLRINT); */ } /* Loading @@ -871,35 +871,35 @@ check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice unsigned int chansegment[16]; unsigned int i, nowmustbechan, seglen, segpos; // correct channel and range number check itself comedi/range.c /* correct channel and range number check itself comedi/range.c */ if (chanlen < 1) { comedi_error(dev, "range/channel list is empty!"); return 0; } if (chanlen > 1) { chansegment[0] = chanlist[0]; // first channel is everytime ok chansegment[0] = chanlist[0]; /* first channel is everytime ok */ for (i = 1, seglen = 1; i < chanlen; i++, seglen++) { // build part of chanlist /* build part of chanlist */ DEBUG(rt_printk("%d. %d %d\n", i, CR_CHAN(chanlist[i]), CR_RANGE(chanlist[i])); ) if (chanlist[0] == chanlist[i]) break; // we detect loop, this must by finish break; /* we detect loop, this must by finish */ nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % chanlen; if (nowmustbechan != CR_CHAN(chanlist[i])) { // channel list isn't continous :-( /* channel list isn't continous :-( */ rt_printk ("comedi%d: pcl816: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n", dev->minor, i, CR_CHAN(chanlist[i]), nowmustbechan, CR_CHAN(chanlist[0])); return 0; } chansegment[i] = chanlist[i]; // well, this is next correct channel in list chansegment[i] = chanlist[i]; /* well, this is next correct channel in list */ } for (i = 0, segpos = 0; i < chanlen; i++) { // check whole chanlist for (i = 0, segpos = 0; i < chanlen; i++) { /* check whole chanlist */ DEBUG(rt_printk("%d %d=%d %d\n", CR_CHAN(chansegment[i % seglen]), CR_RANGE(chansegment[i % seglen]), Loading @@ -915,7 +915,7 @@ check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice CR_CHAN(chanlist[i % seglen]), CR_RANGE(chanlist[i % seglen]), CR_AREF(chansegment[i % seglen])); return 0; // chan/gain list is strange return 0; /* chan/gain list is strange */ } } } else { Loading @@ -925,7 +925,7 @@ check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice devpriv->ai_act_chanlist_len = seglen; devpriv->ai_act_chanlist_pos = 0; for (i = 0; i < seglen; i++) { // store range list to card for (i = 0; i < seglen; i++) { /* store range list to card */ devpriv->ai_act_chanlist[i] = CR_CHAN(chanlist[i]); outb(CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX); outb(CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE); /* select gain */ Loading @@ -935,7 +935,7 @@ check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */ return 1; // we can serve this with MUX logic return 1; /* we can serve this with MUX logic */ } #ifdef unused Loading Loading @@ -981,7 +981,7 @@ static int set_rtc_irq_bit(unsigned char bit) */ static void free_resources(struct comedi_device * dev) { //rt_printk("free_resource()\n"); /* rt_printk("free_resource()\n"); */ if (dev->private) { pcl816_ai_cancel(dev, devpriv->sub_ai); pcl816_reset(dev); Loading @@ -1006,7 +1006,7 @@ static void free_resources(struct comedi_device * dev) free_irq(dev->irq, dev); if (dev->iobase) release_region(dev->iobase, this_board->io_range); //rt_printk("free_resource() end\n"); /* rt_printk("free_resource() end\n"); */ } /* Loading @@ -1021,7 +1021,7 @@ static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * i unsigned long iobase; unsigned int irq, dma; unsigned long pages; //int i; /* int i; */ struct comedi_subdevice *s; /* claim our I/O space */ Loading Loading @@ -1084,7 +1084,7 @@ static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * i #ifdef unused /* grab RTC for DMA operations */ devpriv->dma_rtc = 0; if (it->options[2] > 0) { // we want to use DMA if (it->options[2] > 0) { /* we want to use DMA */ if (RTC_lock == 0) { if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "pcl816 (RTC)")) Loading Loading @@ -1152,9 +1152,9 @@ static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * i devpriv->dmapages[0] = pages; devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]); devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE; //rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); /* rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */ if (devpriv->dma_rtc == 0) { // we must do duble buff :-( if (devpriv->dma_rtc == 0) { /* we must do duble buff :-( */ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) { rt_printk Loading Loading @@ -1188,7 +1188,7 @@ static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * i s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan = this_board->n_aichan; s->subdev_flags |= SDF_DIFF; //printk (", %dchans DIFF DAC - %d", s->n_chan, i); /* printk (", %dchans DIFF DAC - %d", s->n_chan, i); */ s->maxdata = this_board->ai_maxdata; s->len_chanlist = this_board->ai_chanlist; s->range_table = this_board->ai_range_type; Loading Loading
drivers/staging/comedi/drivers/pcl816.c +129 −129 Original line number Diff line number Diff line Loading @@ -43,38 +43,38 @@ Configuration Options: #define DEBUG(x) x // boards constants // IO space len /* boards constants */ /* IO space len */ #define PCLx1x_RANGE 16 //#define outb(x,y) printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y) /* #define outb(x,y) printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y) */ // INTEL 8254 counters /* INTEL 8254 counters */ #define PCL816_CTR0 4 #define PCL816_CTR1 5 #define PCL816_CTR2 6 // R: counter read-back register W: counter control /* R: counter read-back register W: counter control */ #define PCL816_CTRCTL 7 // R: A/D high byte W: A/D range control /* R: A/D high byte W: A/D range control */ #define PCL816_RANGE 9 // W: clear INT request /* W: clear INT request */ #define PCL816_CLRINT 10 // R: next mux scan channel W: mux scan channel & range control pointer /* R: next mux scan channel W: mux scan channel & range control pointer */ #define PCL816_MUX 11 // R/W: operation control register /* R/W: operation control register */ #define PCL816_CONTROL 12 // R: return status byte W: set DMA/IRQ /* R: return status byte W: set DMA/IRQ */ #define PCL816_STATUS 13 #define PCL816_STATUS_DRDY_MASK 0x80 // R: low byte of A/D W: soft A/D trigger /* R: low byte of A/D W: soft A/D trigger */ #define PCL816_AD_LO 8 // R: high byte of A/D W: A/D range control /* R: high byte of A/D W: A/D range control */ #define PCL816_AD_HI 9 // type of interrupt handler /* type of interrupt handler */ #define INT_TYPE_AI1_INT 1 #define INT_TYPE_AI1_DMA 2 #define INT_TYPE_AI3_INT 4 Loading @@ -83,7 +83,7 @@ Configuration Options: #define INT_TYPE_AI1_DMA_RTC 9 #define INT_TYPE_AI3_DMA_RTC 10 // RTC stuff... /* RTC stuff... */ #define RTC_IRQ 8 #define RTC_IO_EXTENT 0x10 #endif Loading @@ -103,35 +103,35 @@ static const struct comedi_lrange range_pcl816 = { 8, { }; struct pcl816_board { const char *name; // board name int n_ranges; // len of range list int n_aichan; // num of A/D chans in diferencial mode unsigned int ai_ns_min; // minimal alllowed delay between samples (in ns) int n_aochan; // num of D/A chans int n_dichan; // num of DI chans int n_dochan; // num of DO chans const struct comedi_lrange *ai_range_type; // default A/D rangelist const struct comedi_lrange *ao_range_type; // dafault D/A rangelist unsigned int io_range; // len of IO space unsigned int IRQbits; // allowed interrupts unsigned int DMAbits; // allowed DMA chans int ai_maxdata; // maxdata for A/D int ao_maxdata; // maxdata for D/A int ai_chanlist; // allowed len of channel list A/D int ao_chanlist; // allowed len of channel list D/A int i8254_osc_base; // 1/frequency of on board oscilator in ns const char *name; /* board name */ int n_ranges; /* len of range list */ int n_aichan; /* num of A/D chans in diferencial mode */ unsigned int ai_ns_min; /* minimal alllowed delay between samples (in ns) */ int n_aochan; /* num of D/A chans */ int n_dichan; /* num of DI chans */ int n_dochan; /* num of DO chans */ const struct comedi_lrange *ai_range_type; /* default A/D rangelist */ const struct comedi_lrange *ao_range_type; /* dafault D/A rangelist */ unsigned int io_range; /* len of IO space */ unsigned int IRQbits; /* allowed interrupts */ unsigned int DMAbits; /* allowed DMA chans */ int ai_maxdata; /* maxdata for A/D */ int ao_maxdata; /* maxdata for D/A */ int ai_chanlist; /* allowed len of channel list A/D */ int ao_chanlist; /* allowed len of channel list D/A */ int i8254_osc_base; /* 1/frequency of on board oscilator in ns */ }; static const struct pcl816_board boardtypes[] = { {"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816, &range_pcl816, PCLx1x_RANGE, 0x00fc, // IRQ mask 0x0a, // DMA mask 0xffff, // 16-bit card 0xffff, // D/A maxdata 0x00fc, /* IRQ mask */ 0x0a, /* DMA mask */ 0xffff, /* 16-bit card */ 0xffff, /* D/A maxdata */ 1024, 1, // ao chan list 1, /* ao chan list */ 100}, {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816, &range_pcl816, PCLx1x_RANGE, Loading Loading @@ -170,42 +170,42 @@ COMEDI_INITCLEANUP(driver_pcl816); struct pcl816_private { unsigned int dma; // used DMA, 0=don't use DMA int dma_rtc; // 1=RTC used with DMA, 0=no RTC alloc unsigned int dma; /* used DMA, 0=don't use DMA */ int dma_rtc; /* 1=RTC used with DMA, 0=no RTC alloc */ #ifdef unused unsigned long rtc_iobase; // RTC port region unsigned long rtc_iobase; /* RTC port region */ unsigned int rtc_iosize; unsigned int rtc_irq; #endif unsigned long dmabuf[2]; // pointers to begin of DMA buffers unsigned int dmapages[2]; // len of DMA buffers in PAGE_SIZEs unsigned int hwdmaptr[2]; // hardware address of DMA buffers unsigned int hwdmasize[2]; // len of DMA buffers in Bytes unsigned int dmasamplsize; // size in samples hwdmasize[0]/2 unsigned int last_top_dma; // DMA pointer in last RTC int int next_dma_buf; // which DMA buffer will be used next round long dma_runs_to_end; // how many we must permorm DMA transfer to end of record unsigned long last_dma_run; // how many bytes we must transfer on last DMA page unsigned int ai_scans; // len of scanlist unsigned char ai_neverending; // if=1, then we do neverending record (you must use cancel()) int irq_free; // 1=have allocated IRQ int irq_blocked; // 1=IRQ now uses any subdev unsigned long dmabuf[2]; /* pointers to begin of DMA buffers */ unsigned int dmapages[2]; /* len of DMA buffers in PAGE_SIZEs */ unsigned int hwdmaptr[2]; /* hardware address of DMA buffers */ unsigned int hwdmasize[2]; /* len of DMA buffers in Bytes */ unsigned int dmasamplsize; /* size in samples hwdmasize[0]/2 */ unsigned int last_top_dma; /* DMA pointer in last RTC int */ int next_dma_buf; /* which DMA buffer will be used next round */ long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */ unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */ unsigned int ai_scans; /* len of scanlist */ unsigned char ai_neverending; /* if=1, then we do neverending record (you must use cancel()) */ int irq_free; /* 1=have allocated IRQ */ int irq_blocked; /* 1=IRQ now uses any subdev */ #ifdef unused int rtc_irq_blocked; // 1=we now do AI with DMA&RTC int rtc_irq_blocked; /* 1=we now do AI with DMA&RTC */ #endif int irq_was_now_closed; // when IRQ finish, there's stored int816_mode for last interrupt int int816_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma struct comedi_subdevice *last_int_sub; // ptr to subdevice which now finish int ai_act_scan; // how many scans we finished unsigned int ai_act_chanlist[16]; // MUX setting for actual AI operations unsigned int ai_act_chanlist_len; // how long is actual MUX list unsigned int ai_act_chanlist_pos; // actual position in MUX list unsigned int ai_poll_ptr; // how many sampes transfer poll struct comedi_subdevice *sub_ai; // ptr to AI subdevice int irq_was_now_closed; /* when IRQ finish, there's stored int816_mode for last interrupt */ int int816_mode; /* who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */ struct comedi_subdevice *last_int_sub; /* ptr to subdevice which now finish */ int ai_act_scan; /* how many scans we finished */ unsigned int ai_act_chanlist[16]; /* MUX setting for actual AI operations */ unsigned int ai_act_chanlist_len; /* how long is actual MUX list */ unsigned int ai_act_chanlist_pos; /* actual position in MUX list */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */ #ifdef unused struct timer_list rtc_irq_timer; // timer for RTC sanity check unsigned long rtc_freq; // RTC int freq struct timer_list rtc_irq_timer; /* timer for RTC sanity check */ unsigned long rtc_freq; /* RTC int freq */ #endif }; Loading Loading @@ -237,12 +237,12 @@ static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevi int timeout; DPRINTK("mode 0 analog input\n"); // software trigger, DMA and INT off /* software trigger, DMA and INT off */ outb(0, dev->iobase + PCL816_CONTROL); // clear INT (conversion end) flag /* clear INT (conversion end) flag */ outb(0, dev->iobase + PCL816_CLRINT); // Set the input channel /* Set the input channel */ outb(CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX); outb(CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE); /* select gain */ Loading @@ -254,7 +254,7 @@ static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevi while (timeout--) { if (!(inb(dev->iobase + PCL816_STATUS) & PCL816_STATUS_DRDY_MASK)) { // return read value /* return read value */ data[n] = ((inb(dev->iobase + PCL816_AD_HI) << 8) | Loading @@ -265,7 +265,7 @@ static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevi } comedi_udelay(1); } // Return timeout error /* Return timeout error */ if (!timeout) { comedi_error(dev, "A/D insn timeout\n"); data[0] = 0; Loading Loading @@ -295,7 +295,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) break; comedi_udelay(1); } if (!timeout) { // timeout, bail error if (!timeout) { /* timeout, bail error */ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */ comedi_error(dev, "A/D mode1/3 IRQ without DRDY!"); pcl816_ai_cancel(dev, s); Loading @@ -305,7 +305,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) } // get the sample /* get the sample */ low = inb(dev->iobase + PCL816_AD_LO); hi = inb(dev->iobase + PCL816_AD_HI); Loading Loading @@ -352,7 +352,7 @@ static void transfer_from_dma_buf(struct comedi_device * dev, struct comedi_subd } if (!devpriv->ai_neverending) if (devpriv->ai_act_scan >= devpriv->ai_scans) { // all data sampled if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */ pcl816_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_BLOCK; Loading @@ -374,12 +374,12 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) disable_dma(devpriv->dma); this_dma_buf = devpriv->next_dma_buf; if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) { // switch dma bufs if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) { /* switch dma bufs */ devpriv->next_dma_buf = 1 - devpriv->next_dma_buf; set_dma_mode(devpriv->dma, DMA_MODE_READ); dma_flags = claim_dma_lock(); // clear_dma_ff (devpriv->dma); /* clear_dma_ff (devpriv->dma); */ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]); if (devpriv->dma_runs_to_end) { Loading Loading @@ -433,7 +433,7 @@ static irqreturn_t interrupt_pcl816(int irq, void *d PT_REGS_ARG) (!devpriv->int816_mode)) { if (devpriv->irq_was_now_closed) { devpriv->irq_was_now_closed = 0; // comedi_error(dev,"last IRQ.."); /* comedi_error(dev,"last IRQ.."); */ return IRQ_HANDLED; } comedi_error(dev, "bad IRQ!"); Loading Loading @@ -610,7 +610,7 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s return -EINVAL; if (cmd->scan_end_arg != cmd->chanlist_len) return -EINVAL; // if(cmd->chanlist_len>MAX_CHANLIST_LEN) return -EINVAL; /* if(cmd->chanlist_len>MAX_CHANLIST_LEN) return -EINVAL; */ if (devpriv->irq_blocked) return -EBUSY; Loading @@ -621,7 +621,7 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1, &divisor2, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); if (divisor1 == 1) { // PCL816 crash if any divisor is set to 1 if (divisor1 == 1) { /* PCL816 crash if any divisor is set to 1 */ divisor1 = 2; divisor2 /= 2; } Loading @@ -631,7 +631,7 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s } } start_pacer(dev, -1, 0, 0); // stop pacer start_pacer(dev, -1, 0, 0); /* stop pacer */ if (!check_and_setup_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len)) Loading @@ -652,19 +652,19 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s devpriv->ai_neverending = 1; } if ((cmd->flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan? if ((cmd->flags & TRIG_WAKE_EOS)) { /* don't we want wake up every scan? */ printk("pl816: You wankt WAKE_EOS but I dont want handle it"); // devpriv->ai_eos=1; //if (devpriv->ai_n_chan==1) // devpriv->dma=0; // DMA is useless for this situation /* devpriv->ai_eos=1; */ /* if (devpriv->ai_n_chan==1) */ /* devpriv->dma=0; // DMA is useless for this situation */ } if (devpriv->dma) { bytes = devpriv->hwdmasize[0]; if (!devpriv->ai_neverending) { bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short); // how many devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fill devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short); /* how many */ devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; /* how many DMA pages we must fill */ devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; /* on last dma transfer must be moved */ devpriv->dma_runs_to_end--; if (devpriv->dma_runs_to_end >= 0) bytes = devpriv->hwdmasize[0]; Loading @@ -687,14 +687,14 @@ static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s switch (cmd->convert_src) { case TRIG_TIMER: devpriv->int816_mode = INT_TYPE_AI1_DMA; outb(0x32, dev->iobase + PCL816_CONTROL); // Pacer+IRQ+DMA outb(dmairq, dev->iobase + PCL816_STATUS); // write irq and DMA to card outb(0x32, dev->iobase + PCL816_CONTROL); /* Pacer+IRQ+DMA */ outb(dmairq, dev->iobase + PCL816_STATUS); /* write irq and DMA to card */ break; default: devpriv->int816_mode = INT_TYPE_AI3_DMA; outb(0x34, dev->iobase + PCL816_CONTROL); // Ext trig+IRQ+DMA outb(dmairq, dev->iobase + PCL816_STATUS); // write irq to card outb(0x34, dev->iobase + PCL816_CONTROL); /* Ext trig+IRQ+DMA */ outb(dmairq, dev->iobase + PCL816_STATUS); /* write irq to card */ break; } Loading @@ -708,12 +708,12 @@ static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * unsigned int top1, top2, i; if (!devpriv->dma) return 0; // poll is valid only for DMA transfer return 0; /* poll is valid only for DMA transfer */ comedi_spin_lock_irqsave(&dev->spinlock, flags); for (i = 0; i < 20; i++) { top1 = get_dma_residue(devpriv->dma); // where is now DMA top1 = get_dma_residue(devpriv->dma); /* where is now DMA */ top2 = get_dma_residue(devpriv->dma); if (top1 == top2) break; Loading @@ -723,10 +723,10 @@ static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * return 0; } top1 = devpriv->hwdmasize[0] - top1; // where is now DMA in buffer top1 >>= 1; // sample position top1 = devpriv->hwdmasize[0] - top1; /* where is now DMA in buffer */ top1 >>= 1; /* sample position */ top2 = top1 - devpriv->ai_poll_ptr; if (top2 < 1) { // no new samples if (top2 < 1) { /* no new samples */ comedi_spin_unlock_irqrestore(&dev->spinlock, flags); return 0; } Loading @@ -735,7 +735,7 @@ static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * (short *) devpriv->dmabuf[devpriv->next_dma_buf], devpriv->ai_poll_ptr, top2); devpriv->ai_poll_ptr = top1; // new buffer position devpriv->ai_poll_ptr = top1; /* new buffer position */ comedi_spin_unlock_irqrestore(&dev->spinlock, flags); return s->async->buf_write_count - s->async->buf_read_count; Loading @@ -747,14 +747,14 @@ static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * */ static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s) { // DEBUG(rt_printk("pcl816_ai_cancel()\n");) /* DEBUG(rt_printk("pcl816_ai_cancel()\n");) */ if (devpriv->irq_blocked > 0) { switch (devpriv->int816_mode) { #ifdef unused case INT_TYPE_AI1_DMA_RTC: case INT_TYPE_AI3_DMA_RTC: set_rtc_irq_bit(0); // stop RTC set_rtc_irq_bit(0); /* stop RTC */ del_timer(&devpriv->rtc_irq_timer); #endif case INT_TYPE_AI1_DMA: Loading @@ -776,7 +776,7 @@ static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice devpriv->irq_was_now_closed = devpriv->int816_mode; devpriv->int816_mode = 0; devpriv->last_int_sub = s; // s->busy = 0; /* s->busy = 0; */ break; } } Loading @@ -795,18 +795,18 @@ static int pcl816_check(unsigned long iobase) outb(0x00, iobase + PCL816_MUX); comedi_udelay(1); if (inb(iobase + PCL816_MUX) != 0x00) return 1; //there isn't card return 1; /* there isn't card */ outb(0x55, iobase + PCL816_MUX); comedi_udelay(1); if (inb(iobase + PCL816_MUX) != 0x55) return 1; //there isn't card return 1; /* there isn't card */ outb(0x00, iobase + PCL816_MUX); comedi_udelay(1); outb(0x18, iobase + PCL816_CONTROL); comedi_udelay(1); if (inb(iobase + PCL816_CONTROL) != 0x18) return 1; //there isn't card return 0; // ok, card exist return 1; /* there isn't card */ return 0; /* ok, card exist */ } /* Loading @@ -815,12 +815,12 @@ static int pcl816_check(unsigned long iobase) */ static void pcl816_reset(struct comedi_device * dev) { // outb (0, dev->iobase + PCL818_DA_LO); // DAC=0V // outb (0, dev->iobase + PCL818_DA_HI); // comedi_udelay (1); // outb (0, dev->iobase + PCL818_DO_HI); // DO=$0000 // outb (0, dev->iobase + PCL818_DO_LO); // comedi_udelay (1); /* outb (0, dev->iobase + PCL818_DA_LO); DAC=0V */ /* outb (0, dev->iobase + PCL818_DA_HI); */ /* comedi_udelay (1); */ /* outb (0, dev->iobase + PCL818_DO_HI); DO=$0000 */ /* outb (0, dev->iobase + PCL818_DO_LO); */ /* comedi_udelay (1); */ outb(0, dev->iobase + PCL816_CONTROL); outb(0, dev->iobase + PCL816_MUX); outb(0, dev->iobase + PCL816_CLRINT); Loading @@ -842,8 +842,8 @@ start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1, outb(0xff, dev->iobase + PCL816_CTR0); outb(0x00, dev->iobase + PCL816_CTR0); comedi_udelay(1); outb(0xb4, dev->iobase + PCL816_CTRCTL); // set counter 2 as mode 3 outb(0x74, dev->iobase + PCL816_CTRCTL); // set counter 1 as mode 3 outb(0xb4, dev->iobase + PCL816_CTRCTL); /* set counter 2 as mode 3 */ outb(0x74, dev->iobase + PCL816_CTRCTL); /* set counter 1 as mode 3 */ comedi_udelay(1); if (mode == 1) { Loading @@ -856,7 +856,7 @@ start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1, } /* clear pending interrupts (just in case) */ // outb(0, dev->iobase + PCL816_CLRINT); /* outb(0, dev->iobase + PCL816_CLRINT); */ } /* Loading @@ -871,35 +871,35 @@ check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice unsigned int chansegment[16]; unsigned int i, nowmustbechan, seglen, segpos; // correct channel and range number check itself comedi/range.c /* correct channel and range number check itself comedi/range.c */ if (chanlen < 1) { comedi_error(dev, "range/channel list is empty!"); return 0; } if (chanlen > 1) { chansegment[0] = chanlist[0]; // first channel is everytime ok chansegment[0] = chanlist[0]; /* first channel is everytime ok */ for (i = 1, seglen = 1; i < chanlen; i++, seglen++) { // build part of chanlist /* build part of chanlist */ DEBUG(rt_printk("%d. %d %d\n", i, CR_CHAN(chanlist[i]), CR_RANGE(chanlist[i])); ) if (chanlist[0] == chanlist[i]) break; // we detect loop, this must by finish break; /* we detect loop, this must by finish */ nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % chanlen; if (nowmustbechan != CR_CHAN(chanlist[i])) { // channel list isn't continous :-( /* channel list isn't continous :-( */ rt_printk ("comedi%d: pcl816: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n", dev->minor, i, CR_CHAN(chanlist[i]), nowmustbechan, CR_CHAN(chanlist[0])); return 0; } chansegment[i] = chanlist[i]; // well, this is next correct channel in list chansegment[i] = chanlist[i]; /* well, this is next correct channel in list */ } for (i = 0, segpos = 0; i < chanlen; i++) { // check whole chanlist for (i = 0, segpos = 0; i < chanlen; i++) { /* check whole chanlist */ DEBUG(rt_printk("%d %d=%d %d\n", CR_CHAN(chansegment[i % seglen]), CR_RANGE(chansegment[i % seglen]), Loading @@ -915,7 +915,7 @@ check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice CR_CHAN(chanlist[i % seglen]), CR_RANGE(chanlist[i % seglen]), CR_AREF(chansegment[i % seglen])); return 0; // chan/gain list is strange return 0; /* chan/gain list is strange */ } } } else { Loading @@ -925,7 +925,7 @@ check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice devpriv->ai_act_chanlist_len = seglen; devpriv->ai_act_chanlist_pos = 0; for (i = 0; i < seglen; i++) { // store range list to card for (i = 0; i < seglen; i++) { /* store range list to card */ devpriv->ai_act_chanlist[i] = CR_CHAN(chanlist[i]); outb(CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX); outb(CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE); /* select gain */ Loading @@ -935,7 +935,7 @@ check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */ return 1; // we can serve this with MUX logic return 1; /* we can serve this with MUX logic */ } #ifdef unused Loading Loading @@ -981,7 +981,7 @@ static int set_rtc_irq_bit(unsigned char bit) */ static void free_resources(struct comedi_device * dev) { //rt_printk("free_resource()\n"); /* rt_printk("free_resource()\n"); */ if (dev->private) { pcl816_ai_cancel(dev, devpriv->sub_ai); pcl816_reset(dev); Loading @@ -1006,7 +1006,7 @@ static void free_resources(struct comedi_device * dev) free_irq(dev->irq, dev); if (dev->iobase) release_region(dev->iobase, this_board->io_range); //rt_printk("free_resource() end\n"); /* rt_printk("free_resource() end\n"); */ } /* Loading @@ -1021,7 +1021,7 @@ static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * i unsigned long iobase; unsigned int irq, dma; unsigned long pages; //int i; /* int i; */ struct comedi_subdevice *s; /* claim our I/O space */ Loading Loading @@ -1084,7 +1084,7 @@ static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * i #ifdef unused /* grab RTC for DMA operations */ devpriv->dma_rtc = 0; if (it->options[2] > 0) { // we want to use DMA if (it->options[2] > 0) { /* we want to use DMA */ if (RTC_lock == 0) { if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "pcl816 (RTC)")) Loading Loading @@ -1152,9 +1152,9 @@ static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * i devpriv->dmapages[0] = pages; devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]); devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE; //rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); /* rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */ if (devpriv->dma_rtc == 0) { // we must do duble buff :-( if (devpriv->dma_rtc == 0) { /* we must do duble buff :-( */ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) { rt_printk Loading Loading @@ -1188,7 +1188,7 @@ static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * i s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan = this_board->n_aichan; s->subdev_flags |= SDF_DIFF; //printk (", %dchans DIFF DAC - %d", s->n_chan, i); /* printk (", %dchans DIFF DAC - %d", s->n_chan, i); */ s->maxdata = this_board->ai_maxdata; s->len_chanlist = this_board->ai_chanlist; s->range_table = this_board->ai_range_type; Loading