Added support for reading eeprom on m-series boards. Added partial
authorFrank Mori Hess <fmhess@speakeasy.net>
Mon, 2 Jan 2006 21:53:00 +0000 (21:53 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Mon, 2 Jan 2006 21:53:00 +0000 (21:53 +0000)
support for CR_ALT_SOURCE with m-series boards.

comedi/drivers/mite.c
comedi/drivers/mite.h
comedi/drivers/ni_mio_common.c
comedi/drivers/ni_pcimio.c
comedi/drivers/ni_stc.h

index fe00bf7c3a1ac90fbced988670b74965da65af38..d4330994deaa9c297bb160732b69e74c35f794c1 100644 (file)
@@ -144,9 +144,9 @@ int mite_setup(struct mite_struct *mite)
        // The 6602 board needs different initalisation, see the
        // _updated_ (nov 2002) reg. Level Manual (filename 370505b.pdf) p. 3.55
        if (mite->pcidev->device == 0x1310 ){
-               printk("mite: detected NI6602, using other I/O Window Base Size register\n");
-               writel((mite->daq_phys_addr & 0xffffff00L) | WENAB_6602 , mite->mite_io_addr + MITE_IODWBSR_NI6602);
-               writel(0 , mite->mite_io_addr + MITE_IODWCR_NI6602);
+               printk("mite: detected NI6602, using other I/O Window Base Size register\n");
+               writel((mite->daq_phys_addr & 0xffffff00L) | WENAB_6602 , mite->mite_io_addr + MITE_IODWBSR_1);
+               writel(0 , mite->mite_io_addr + MITE_IODWCR_1);
        }
        else writel(mite->daq_phys_addr | WENAB , mite->mite_io_addr + MITE_IODWBSR);
 
index caa2254964136f971f2112925535df3683ec38fa..44cfe44c3d917e312b9291714f4520876f877bc7 100644 (file)
@@ -122,8 +122,8 @@ enum mite_registers
 {
        MITE_IODWBSR = 0xc0, //IO Device Window Base Size Register
        MITE_CSIGR = 0x460,     //chip signature
-       MITE_IODWBSR_NI6602 = 0xc4, // IODWBSR for 6602 boards
-       MITE_IODWCR_NI6602 = 0xf4
+       MITE_IODWBSR_1 = 0xc4, // IO Device Window Base Size Register 1 (used by 6602 boards)
+       MITE_IODWCR_1 = 0xf4
 };
 static inline int MITE_CHOR(int channel)       // channel operation
 {
index f8d0fe247468b36a0f913ea3855c3234a732f7c3..302ebe511e35ece26146f5cdb6e978d1c6b4bee8 100644 (file)
@@ -204,6 +204,8 @@ static int ni_calib_insn_write(comedi_device *dev,comedi_subdevice *s,
 
 static int ni_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,
        comedi_insn *insn,lsampl_t *data);
+static int ni_m_series_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,
+       comedi_insn *insn,lsampl_t *data);
 
 static int ni_pfi_insn_bits(comedi_device *dev,comedi_subdevice *s,
        comedi_insn *insn,lsampl_t *data);
@@ -1266,6 +1268,91 @@ static int ni_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *i
        return insn->n;
 }
 
+void ni_prime_channelgain_list(comedi_device *dev)
+{
+       int i;
+       devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
+       for(i = 0; i < NI_TIMEOUT; ++i)
+       {
+               if(!(devpriv->stc_readw(dev, AI_Status_1_Register) & AI_FIFO_Empty_St))
+               {
+                       devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+                       return;
+               }
+               comedi_udelay(1);
+       }
+       rt_printk("ni_mio_common: timeout loading channel/gain list\n");
+}
+
+/* m series boards have new ai_config_fifo_data register which replaces
+ * old configuration_memory_low and high registers.  But the old registers still
+ * seem to work, so I'm not going to bother to change it yet. */
+static void ni_m_series_load_channelgain_list(comedi_device *dev,unsigned int n_chan,
+       unsigned int *list)
+{
+       unsigned int chan, range, aref;
+       unsigned int i;
+       unsigned int hi,lo;
+       unsigned offset;
+       unsigned int dither;
+       unsigned int use_alt_src;
+       unsigned range_code;
+       
+       devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+
+       offset = 1 << (boardtype.adbits - 1);
+       for(i = 0; i < n_chan; i++)
+       {
+               chan = CR_CHAN(list[i]);
+               aref = CR_AREF(list[i]);
+               range = CR_RANGE(list[i]);
+               dither = ((list[i] & CR_ALT_FILTER) != 0);
+               use_alt_src = ((list[i] & CR_ALT_SOURCE) != 0);
+               
+               range_code = ni_gainlkup[boardtype.gainlkup][range];
+               devpriv->ai_offset[i] = offset;
+
+               hi = 0;
+               if(use_alt_src)
+               {
+                       unsigned bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit;
+                       bypass_bits |= chan;
+                       bypass_bits |= MSeries_AI_Bypass_Cal_Sel_Pos_Bits(devpriv->ai_calib_source);
+                       bypass_bits |= MSeries_AI_Bypass_Gain_Bits(range_code);
+                       if(dither)
+                               bypass_bits |= MSeries_AI_Bypass_Dither_Bit;
+                       ni_writel(bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
+               }else
+               {
+                       ni_writel(0, M_Offset_AI_Config_FIFO_Bypass);
+                       switch( aref )
+                       {
+                               case AREF_DIFF:
+                                       hi |= AI_DIFFERENTIAL;
+                                       break;
+                               case AREF_COMMON:
+                                       hi |= AI_COMMON;
+                                       break;
+                               case AREF_GROUND:
+                                       hi |= AI_GROUND;
+                                       break;
+                               case AREF_OTHER:
+                                       break;
+                       }
+               }
+               hi |= AI_CONFIG_CHANNEL( chan );
+
+               ni_writew(hi,Configuration_Memory_High);
+
+               lo = range_code;
+               if(i == n_chan - 1) lo |= AI_LAST_CHANNEL;
+               if( dither ) lo |= AI_DITHER;
+
+               ni_writew(lo,Configuration_Memory_Low);
+       }
+       ni_prime_channelgain_list(dev);
+}
+
 /*
  * Notes on the 6110 and 6111:
  * These boards a slightly different than the rest of the series, since
@@ -1304,6 +1391,11 @@ static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,
        unsigned offset;
        unsigned int dither;
 
+       if(boardtype.reg_type == ni_reg_m_series)
+       {
+               ni_m_series_load_channelgain_list(dev, n_chan, list);
+               return;
+       }
        if(n_chan == 1 && boardtype.reg_type != ni_reg_611x){
                if(devpriv->changain_state && devpriv->changain_spec==list[0]){
                        // ready to go.
@@ -1372,15 +1464,7 @@ static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,
 
        /* prime the channel/gain list */
        if(boardtype.reg_type != ni_reg_611x){
-               devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
-               for(i=0;i<NI_TIMEOUT;i++){
-                       if(!(devpriv->stc_readw(dev, AI_Status_1_Register)&AI_FIFO_Empty_St)){
-                               devpriv->stc_writew(dev, 1,ADC_FIFO_Clear);
-                               return;
-                       }
-                       comedi_udelay(1);
-               }
-               rt_printk("ni_mio_common: timeout loading channel/gain list\n");
+               ni_prime_channelgain_list(dev);
        }
 }
 
@@ -2888,10 +2972,16 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
        s=dev->subdevices+6;
        s->type=COMEDI_SUBD_MEMORY;
        s->subdev_flags=SDF_READABLE|SDF_INTERNAL;
-       s->n_chan=512;
        s->maxdata=0xff;
-       s->insn_read=ni_eeprom_insn_read;
-
+       if(boardtype.reg_type == ni_reg_m_series)
+       {
+               s->n_chan = M_SERIES_EEPROM_SIZE;
+               s->insn_read = &ni_m_series_eeprom_insn_read;
+       }else
+       {
+               s->n_chan = 512;
+               s->insn_read = &ni_eeprom_insn_read;
+       }
        /* PFI */
        s=dev->subdevices+7;
        s->type=COMEDI_SUBD_DIO;
@@ -3045,6 +3135,14 @@ static int ni_read_eeprom(comedi_device *dev,int addr)
        return bitstring;
 }
 
+static int ni_m_series_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,
+       comedi_insn *insn,lsampl_t *data)
+{
+       data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
+
+       return 1;
+}
+
 static void ni_write_caldac(comedi_device *dev,int addr,int val);
 /*
        calibration subdevice
index 072508eccfced960ff33ca21c8fb8b35b9ec0987..0e302584fca2ca82e9b659769e48464cab7a36c7 100644 (file)
@@ -1233,6 +1233,33 @@ static int pcimio_ai_change(comedi_device *dev, comedi_subdevice *s,
 static int pcimio_ao_change(comedi_device *dev, comedi_subdevice *s,
        unsigned long new_size);
 
+static void m_series_init_eeprom_buffer(comedi_device *dev)
+{
+       static const int Start_Cal_EEPROM = 0x400;
+       static const unsigned window_size = 10;
+       unsigned old_iodwbsr_bits;
+       unsigned old_iodwbsr1_bits;
+       unsigned old_iodwcr1_bits;
+       int i;
+       
+       old_iodwbsr_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR);
+       old_iodwbsr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+       old_iodwcr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+       writel(0x0, devpriv->mite->mite_io_addr + MITE_IODWBSR);
+       writel(((0x80 | window_size) | devpriv->mite->daq_phys_addr), devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+       writel(0x0, devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+       writel(0xf, devpriv->mite->mite_io_addr + 0x30);
+       
+       for(i = 0; i < M_SERIES_EEPROM_SIZE; ++i)
+       {
+               devpriv->eeprom_buffer[i] = ni_readb(Start_Cal_EEPROM + i);
+       }
+    
+       writel(old_iodwbsr1_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+       writel(old_iodwbsr_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR);
+       writel(old_iodwcr1_bits, devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+       writel(0x0, devpriv->mite->mite_io_addr + 0x30);
+}
 
 /* cleans up allocated resources */
 static int pcimio_detach(comedi_device *dev)
@@ -1282,6 +1309,8 @@ static int pcimio_attach(comedi_device *dev,comedi_devconfig *it)
                printk(" error setting up mite\n");
                return ret;
        }
+       if(boardtype.reg_type == ni_reg_m_series)
+               m_series_init_eeprom_buffer(dev);
 
        dev->irq=mite_irq(devpriv->mite);
 
index 741c6edf394f0d888f960cfa465715d73eee2901..5d73e911df35497fd994e446fe8b79a65bd6dc08 100644 (file)
@@ -962,6 +962,32 @@ static inline int M_Offset_AO_Reference_Attenuation(int channel)
        return offset[channel];
 };
 
+enum MSeries_AI_Config_FIFO_Bypass_Bits
+{
+       MSeries_AI_Bypass_Channel_Mask = 0x7,
+       MSeries_AI_Bypass_Bank_Mask = 0x38,
+       MSeries_AI_Bypass_Cal_Sel_Pos_Mask = 0x380,
+       MSeries_AI_Bypass_Cal_Sel_Neg_Mask = 0x1c00,
+       MSeries_AI_Bypass_Mode_Mux_Mask = 0x6000,
+       MSeries_AO_Bypass_AO_Cal_Sel_Mask = 0x38000,
+       MSeries_AI_Bypass_Gain_Mask = 0x1c0000,
+       MSeries_AI_Bypass_Dither_Bit = 0x200000,
+       MSeries_AI_Bypass_Polarity_Bit = 0x400000,
+       MSeries_AI_Bypass_Config_FIFO_Bit = 0x80000000
+};
+static inline unsigned MSeries_AI_Bypass_Cal_Sel_Pos_Bits(int calibration_source)
+{
+       return (calibration_source << 7) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
+}
+static inline unsigned MSeries_AI_Bypass_Cal_Sel_Neg_Bits(int calibration_source)
+{
+       return (calibration_source << 10) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
+}
+static inline unsigned MSeries_AI_Bypass_Gain_Bits(int gain)
+{
+       return (gain << 18) & MSeries_AI_Bypass_Gain_Mask;
+}
+
 enum MSeries_AO_Config_Bank_Bits
 {
        MSeries_AO_DAC_Offset_Select_Mask = 0x7,
@@ -979,6 +1005,8 @@ enum MSeries_AO_Reference_Attenuation_Bits
        MSeries_Attenuate_x5_Bit = 0x1
 };
 
+#define M_SERIES_EEPROM_SIZE 1024
+
 typedef struct ni_board_struct{
        int device_id;
        int isapnp_id;
@@ -1072,6 +1100,7 @@ static ni_board ni_boards[];
        unsigned short atrig_low;                               \
                                                                \
        sampl_t ai_fifo_buffer[0x2000];                         \
-
+       uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE];
+       
 #endif /* _COMEDI_NI_STC_H */