- From: Salvador Eduardo Tropea <salvador_at_inti.gov.ar>
- Date: Fri, 09 Jan 2004 18:38:58 -0300
Frank Mori Hess wrote: >Ideally, you should split out the 8253/4 support into a separate module >that can be used by any driver (similar to the 8255 module). > > Ok, I´ll try to do it. Here is a very preliminar patch just to show some details. I´m currently coding the 8254 code inside the das08 code just for testing purposes. The first detail for a generic code is that no all boards have all channels of the 8254 usable. For this reason, and others, I´m using a table to translate the channel into an "8254 channel". The patch only implements read and write, not config yet. Please take a look at the patch and tell me if it looks ok. The code works, I tested it connecting one of the DO of the board to one of the clocks and then loaded the counter and then send some pulses and read the counter value. I´m separating the routines in low/high level because some drivers could need to use the channels internally and avoid the channels translation. I also put spinlocks to avoid concurrents reads/writes to the same channel, but I don´t know if that isn´t too much. SET -- Salvador Eduardo Tropea (SET). (Electronics Engineer) Visit my home page: http://welcome.to/SetSoft or http://www.geocities.com/SiliconValley/Vista/6552/ Alternative e-mail: set_at_computer.org set_at_ieee.org Address: Curapaligue 2124, Caseros, 3 de Febrero Buenos Aires, (1678), ARGENTINA Phone: +(5411) 4759 0013
Index: das08.c
===================================================================
RCS file: /var/cvs/comedi/comedi/drivers/das08.c,v
retrieving revision 1.47
diff -u -r1.47 das08.c
--- das08.c 4 Jul 2003 20:00:26 -0000 1.47
+++ das08.c 9 Jan 2004 21:28:20 -0000
_at__at_ -5,6 +5,7 _at__at_
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 2000 David A. Schleef <ds_at_schleef.org>
Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess_at_users.sourceforge.net>
+ Copyright (C) 2004 Salvador E. Tropea <set_at_users.sf.net> <set_at_ieee.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
_at__at_ -667,6 +668,86 _at__at_
return n;
}
+
+static unsigned int i8254_read_channel_low(unsigned int base, spinlock_t *sp, int chan)
+{
+ unsigned int msb, lsb;
+
+ spin_lock(sp);
+ outb(chan<<6,base+I8254_CTRL);
+ base+=chan;
+ lsb=inb(base);
+ msb=inb(base);
+ spin_unlock(sp);
+
+ return lsb | (msb<<8);
+}
+
+static void i8254_write_channel_low(unsigned int base, spinlock_t *sp, int chan, unsigned int value)
+{
+ unsigned int msb, lsb;
+
+ lsb=value & 0xFF;
+ msb=value>>8;
+
+ /* write lsb, then msb */
+ base+=chan;
+ spin_lock(sp);
+ outb(lsb,base);
+ outb(msb,base);
+ spin_unlock(sp);
+}
+
+static unsigned int i8254_read_channel(struct i8254_struct *st, spinlock_t *sp, int channel)
+{
+ int chan=st->logic2phys[channel];
+
+ return i8254_read_channel_low(st->iobase,sp,chan);
+}
+
+static void i8254_write_channel(struct i8254_struct *st, spinlock_t *sp, int channel, unsigned int value)
+{
+ int chan=st->logic2phys[channel];
+
+ i8254_write_channel_low(st->iobase,sp,chan,value);
+}
+
+#define I8254_CH0_LM 0x30
+#define I8254_CH1_LM 0x60
+#define I8254_CH2_LM 0x80
+
+static void i8254_initialize(struct i8254_struct *st)
+{
+ unsigned int port=st->iobase+I8254_CTRL;
+ outb(I8254_CH0_LM | st->mode[0],port);
+ outb(I8254_CH1_LM | st->mode[1],port);
+ outb(I8254_CH2_LM | st->mode[2],port);
+}
+
+static int das08_counter_read(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data)
+{
+ int chan=insn->chanspec;
+
+ //printk("Reading counter channel %d ",chan);
+ data[0]=i8254_read_channel(&devpriv->i8254,&dev->spinlock,chan);
+ //printk("=> 0x%08X\n",data[0]);
+
+ return 1;
+}
+
+
+static int das08_counter_write(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data)
+{
+ int chan=insn->chanspec;
+
+ //printk("Writing counter channel %d with 0x%04X\n",chan,data[0]);
+ i8254_write_channel(&devpriv->i8254,&dev->spinlock,chan,data[0]);
+
+ return 1;
+}
+
+
+
static int das08_attach(comedi_device *dev,comedi_devconfig *it);
static comedi_driver driver_das08={
_at__at_ -698,7 +779,7 _at__at_
dev->board_name = thisboard->name;
- if((ret=alloc_subdevices(dev, 5))<0)
+ if((ret=alloc_subdevices(dev, 6))<0)
return ret;
s=dev->subdevices+0;
_at__at_ -762,6 +843,30 _at__at_
if(thisboard->i8255_offset!=0){
subdev_8255_init(dev,s,NULL,(unsigned long)(dev->iobase+
thisboard->i8255_offset));
+ }else{
+ s->type=COMEDI_SUBD_UNUSED;
+ }
+
+ s=dev->subdevices+5;
+ /* 8254 */
+ if(thisboard->i8254_offset!=0){
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 0xFFFF;
+ s->insn_read = das08_counter_read;
+ s->insn_write = das08_counter_write;
+ s->insn_config = NULL;
+ /* Set-up the 8254 structure */
+ devpriv->i8254.channels=3;
+ devpriv->i8254.logic2phys[0]=0;
+ devpriv->i8254.logic2phys[1]=1;
+ devpriv->i8254.logic2phys[2]=2;
+ devpriv->i8254.iobase=iobase+thisboard->i8254_offset;
+ devpriv->i8254.mode[0]=
+ devpriv->i8254.mode[1]=
+ devpriv->i8254.mode[2]=0;
+ i8254_initialize(&devpriv->i8254);
}else{
s->type=COMEDI_SUBD_UNUSED;
}
Index: das08.h
===================================================================
RCS file: /var/cvs/comedi/comedi/drivers/das08.h,v
retrieving revision 1.2
diff -u -r1.2 das08.h
--- das08.h 21 Nov 2003 02:27:34 -0000 1.2
+++ das08.h 9 Jan 2004 21:28:26 -0000
_at__at_ -47,12 +47,26 _at__at_
unsigned int iosize; // number of ioports used
} das08_board;
+struct i8254_struct
+{
+ int channels; // available channels. Some could be used internally.
+ int logic2phys[3]; // to know which physical channel is.
+ int mode[3]; // the index is the real counter.
+ unsigned int iobase;
+};
+
+#define I8254_CNT0 0
+#define I8254_CNT1 1
+#define I8254_CNT2 2
+#define I8254_CTRL 3
+
struct das08_private_struct{
unsigned int do_mux_bits; // bits for do/mux register on boards without seperate do register
unsigned int do_bits; // bits for do register on boards with register dedicated to digital out only
unsigned int *pg_gainlist;
struct pci_dev *pdev; // struct for pci-das08
unsigned int pci_iobase; // additional base address for pci-das08
+ struct i8254_struct i8254;
};
#define NUM_DAS08_CS_BOARDS 2
Received on 2004-01-09Z21:38:58