From: Frank Mori Hess Date: Mon, 2 Jan 2006 21:53:00 +0000 (+0000) Subject: Added support for reading eeprom on m-series boards. Added partial X-Git-Tag: r0_7_71~82 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c612519ce06b40f0f3cdc735f23fa6b5ddfe42d5;p=comedi.git Added support for reading eeprom on m-series boards. Added partial support for CR_ALT_SOURCE with m-series boards. --- diff --git a/comedi/drivers/mite.c b/comedi/drivers/mite.c index fe00bf7c..d4330994 100644 --- a/comedi/drivers/mite.c +++ b/comedi/drivers/mite.c @@ -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); diff --git a/comedi/drivers/mite.h b/comedi/drivers/mite.h index caa22549..44cfe44c 100644 --- a/comedi/drivers/mite.h +++ b/comedi/drivers/mite.h @@ -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 { diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index f8d0fe24..302ebe51 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -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;istc_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 diff --git a/comedi/drivers/ni_pcimio.c b/comedi/drivers/ni_pcimio.c index 072508ec..0e302584 100644 --- a/comedi/drivers/ni_pcimio.c +++ b/comedi/drivers/ni_pcimio.c @@ -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); diff --git a/comedi/drivers/ni_stc.h b/comedi/drivers/ni_stc.h index 741c6edf..5d73e911 100644 --- a/comedi/drivers/ni_stc.h +++ b/comedi/drivers/ni_stc.h @@ -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 */