Index: comedi/drivers/ni_mio_common.c
===================================================================
RCS file: /cvs/comedi/comedi/comedi/drivers/ni_mio_common.c,v
retrieving revision 1.251
diff -u -r1.251 ni_mio_common.c
--- comedi/drivers/ni_mio_common.c	8 Jan 2006 16:37:27 -0000	1.251
+++ comedi/drivers/ni_mio_common.c	1 Mar 2006 15:40:28 -0000
@@ -53,6 +53,9 @@
 
 	 - the interrupt routine needs to be cleaned up
 	 - many printk's need to be changed to rt_printk()
+
+	2006-02-07: S-Series PCI-6143: Support has been added but is not
+		fully tested as yet. Terry Barnaby, BEAM Ltd.
 */
 
 //#define DEBUG_INTERRUPT
@@ -88,7 +91,9 @@
 	/* ai_gain_622x */
 	{ 0, 1, 4, 5},
 	/* ai_gain_628x */
-	{ 1, 2, 3, 4, 5, 6, 7}
+	{ 1, 2, 3, 4, 5, 6, 7},
+	/* ai_gain_6143 */
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 };
 
 static comedi_lrange range_ni_E_ai={	16, {
@@ -166,6 +171,9 @@
 	RANGE( -0.2,	0.2	),
 	RANGE( -0.1,	0.1	),
 }};
+static comedi_lrange range_ni_S_ai_6143 = { 1, {
+	RANGE( -5,	+5	),
+}};
 static comedi_lrange range_ni_E_ao_ext = { 4, {
 	RANGE( -10,	10	),
 	RANGE( 0,	10	),
@@ -180,7 +188,8 @@
 	&range_ni_E_ai_bipolar4,
 	&range_ni_E_ai_611x,
 	&range_ni_M_ai_622x,
-	&range_ni_M_ai_628x
+	&range_ni_M_ai_628x,
+	&range_ni_S_ai_6143
 };
 
 
@@ -212,6 +221,12 @@
 static int ni_pfi_insn_config(comedi_device *dev,comedi_subdevice *s,
 	comedi_insn *insn,lsampl_t *data);
 
+static void ni_rtsi_init(comedi_device *dev);
+static int ni_rtsi_insn_bits(comedi_device *dev,comedi_subdevice *s,
+	comedi_insn *insn,lsampl_t *data);
+static int ni_rtsi_insn_config(comedi_device *dev,comedi_subdevice *s,
+	comedi_insn *insn,lsampl_t *data);
+
 static void caldac_setup(comedi_device *dev,comedi_subdevice *s);
 static int ni_read_eeprom(comedi_device *dev,int addr);
 
@@ -276,6 +291,8 @@
 
 static int ni_m_series_pwm_config(comedi_device *dev, comedi_subdevice *s,
 	comedi_insn *insn,lsampl_t *data);
+static int ni_6143_pwm_config(comedi_device *dev, comedi_subdevice *s,
+	comedi_insn *insn, lsampl_t *data);
 	
 enum aimodes
 {
@@ -297,11 +314,24 @@
 static void handle_b_interrupt(comedi_device *dev,unsigned short status,
 	unsigned int m_status);
 static void get_last_sample_611x( comedi_device *dev );
+static void get_last_sample_6143( comedi_device *dev );
 #ifdef PCIDMA
 //static void mite_handle_interrupt(comedi_device *dev,unsigned int status);
 static int ni_ai_drain_dma(comedi_device *dev );
 #endif
 
+static void ni_flush_ai_fifo(comedi_device *dev){
+	if(boardtype.reg_type == ni_reg_6143){
+		// Flush the 6143 data FIFO
+		ni_writel(0x10, AIFIFO_Control_6143);		// Flush fifo
+		ni_writel(0x00, AIFIFO_Control_6143);		// Flush fifo
+		while(ni_readl(AIFIFO_Status_6143) & 0x10);	// Wait for complete
+	}
+	else {
+		devpriv->stc_writew(dev, 1,ADC_FIFO_Clear);
+	}
+}
+
 static void win_out2(comedi_device *dev, uint32_t data, int reg)
 {
 	devpriv->stc_writew(dev, data >> 16, reg);
@@ -563,6 +593,7 @@
 #endif
 	ni_handle_fifo_dregs(dev);
 	get_last_sample_611x(dev);
+	get_last_sample_6143(dev);
 
 	ni_set_bits(dev, Interrupt_A_Enable_Register,
 		AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
@@ -931,7 +962,26 @@
 			data[0] = dl & 0xffff;
 			cfc_write_to_buffer(s, data[0]);
 		}
-	}else{
+	} else if(boardtype.reg_type == ni_reg_6143){
+		sampl_t	data[2];
+		u32	dl;
+
+		// This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed
+		for(i = 0; i < n / 2; i++){
+			dl = ni_readl(AIFIFO_Data_6143);
+
+			data[0] = (dl >> 16) & 0xffff;
+			data[1] = dl & 0xffff;
+			cfc_write_array_to_buffer(s, data, sizeof(data));
+		}
+		if(n % 2){
+			/* Assume there is a single sample stuck in the FIFO */
+			ni_writel(0x01, AIFIFO_Control_6143);	// Get stranded sample into FIFO
+			dl = ni_readl(AIFIFO_Data_6143);
+			data[0] = (dl >> 16) & 0xffff;
+			cfc_write_to_buffer(s, data[0]);
+		}
+	} else{
 		if( n > sizeof(devpriv->ai_fifo_buffer) / sizeof(devpriv->ai_fifo_buffer[0]))
 		{
 			comedi_error( dev, "bug! ai_fifo_buffer too small" );
@@ -1004,6 +1054,25 @@
 			data[1] = (dl&0xffff);
 			cfc_write_array_to_buffer(s, data, sizeof(data));
 		}
+	}else if(boardtype.reg_type == ni_reg_6143){
+		i = 0;
+		while(ni_readl(AIFIFO_Status_6143) & 0x04){
+			dl = ni_readl(AIFIFO_Data_6143);
+
+			/* This may get the hi/lo data in the wrong order */
+			data[0] = (dl >> 16);
+			data[1] = (dl & 0xffff);
+			cfc_write_array_to_buffer(s, data, sizeof(data));
+			i += 2;
+		}
+		// Check if stranded sample is present
+		if(ni_readl(AIFIFO_Status_6143) & 0x01){
+			ni_writel(0x01, AIFIFO_Control_6143);	// Get stranded sample into FIFO
+			dl = ni_readl(AIFIFO_Data_6143);
+			data[0] = (dl >> 16) & 0xffff;
+			cfc_write_to_buffer(s, data[0]);
+		}
+
 	}else{
 		fifo_empty = devpriv->stc_readw(dev, AI_Status_1_Register) & AI_FIFO_Empty_St;
 		while(fifo_empty == 0)
@@ -1036,6 +1105,25 @@
 	}
 }
 
+static void get_last_sample_6143(comedi_device* dev)
+{
+	comedi_subdevice*	s = dev->subdevices + 0;
+	sampl_t			data;
+	u32			dl;
+
+	if(boardtype.reg_type != ni_reg_6143) return;
+
+	/* Check if there's a single sample stuck in the FIFO */
+	if(ni_readl(AIFIFO_Status_6143) & 0x01){
+		ni_writel(0x01, AIFIFO_Control_6143);	// Get stranded sample into FIFO
+		dl = ni_readl(AIFIFO_Data_6143);
+
+		/* This may get the hi/lo data in the wrong order */
+		data = (dl >> 16) & 0xffff;
+		cfc_write_to_buffer(s, data);
+	}
+}
+
 static void ni_ai_munge(comedi_device *dev, comedi_subdevice *s,
 	void *data, unsigned int num_bytes, unsigned int chan_index )
 {
@@ -1078,6 +1166,7 @@
 	switch(boardtype.reg_type)
 	{
 	case ni_reg_611x:
+	case ni_reg_6143:
 		mite_prep_dma(mite, AI_DMA_CHAN, 32, 16);
 		break;
 	case ni_reg_m_series:
@@ -1135,9 +1224,10 @@
 		AI_STOP_Interrupt_Enable|   AI_Error_Interrupt_Enable|
 		AI_FIFO_Interrupt_Enable,0);
 
-	devpriv->stc_writew(dev, 1,ADC_FIFO_Clear);
+	ni_flush_ai_fifo(dev);
 
-	ni_writeb(0, Misc_Command);
+	if(boardtype.reg_type != ni_reg_6143)
+		ni_writeb(0, Misc_Command);
 
 	devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
 	devpriv->stc_writew(dev, AI_Start_Stop | AI_Mode_1_Reserved /*| AI_Trigger_Once */,
@@ -1154,6 +1244,15 @@
 			AI_LOCALMUX_CLK_Output_Select(2) |
 			AI_SC_TC_Output_Select(3) |
 			AI_CONVERT_Output_Select(3),AI_Output_Control_Register);
+	}else if(boardtype.reg_type == ni_reg_6143){
+		devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+			AI_SOC_Polarity |
+			AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+		devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) |
+			AI_EXTMUX_CLK_Output_Select(0) |
+			AI_LOCALMUX_CLK_Output_Select(2) |
+			AI_SC_TC_Output_Select(3) |
+			AI_CONVERT_Output_Select(2),AI_Output_Control_Register);
 	}else{
 		devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
 			AI_SOC_Polarity |
@@ -1210,10 +1309,11 @@
 	unsigned int mask;
 	unsigned signbits;
 	unsigned short d;
+	unsigned long dl;
 
 	ni_load_channelgain_list(dev,1,&insn->chanspec);
 
-	devpriv->stc_writew(dev, 1,ADC_FIFO_Clear);
+	ni_flush_ai_fifo(dev);
 
 	mask=(1<<boardtype.adbits)-1;
 	signbits=devpriv->ai_offset[0];
@@ -1245,6 +1345,26 @@
 			d += signbits;
 			data[ n ] = d;
 		}
+	}else if(boardtype.reg_type == ni_reg_6143){
+		for(n = 0; n < insn->n; n++){
+			devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
+
+			/* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
+			dl = 0;
+			for(i = 0; i < NI_TIMEOUT; i++){
+				if(ni_readl(AIFIFO_Status_6143) & 0x01)
+				{
+					ni_writel(0x01, AIFIFO_Control_6143);	// Get stranded sample into FIFO
+					dl = ni_readl(AIFIFO_Data_6143);
+					break;
+				}
+			}
+			if(i == NI_TIMEOUT){
+				rt_printk("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
+				return -ETIME;
+			}
+			data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
+		}
 	}else{
 		for(n=0;n<insn->n;n++){
 			devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
@@ -1401,7 +1521,7 @@
 		ni_m_series_load_channelgain_list(dev, n_chan, list);
 		return;
 	}
-	if(n_chan == 1 && boardtype.reg_type != ni_reg_611x){
+	if(n_chan == 1 && (boardtype.reg_type != ni_reg_611x) && (boardtype.reg_type != ni_reg_6143)){
 		if(devpriv->changain_state && devpriv->changain_spec==list[0]){
 			// ready to go.
 			return;
@@ -1414,9 +1534,27 @@
 
 	devpriv->stc_writew(dev, 1,Configuration_Memory_Clear);
 
+	// Set up Calibration mode if required
+	if(boardtype.reg_type == ni_reg_6143){
+		if((list[0] & CR_ALT_SOURCE) && !devpriv->ai_calib_source_enabled){
+			// Strobe Relay enable bit
+			ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOn, Calibration_Channel_6143);
+			ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
+			devpriv->ai_calib_source_enabled = 1;
+			msleep_interruptible(100);	// Allow relays to change
+		}
+		else if(!(list[0] & CR_ALT_SOURCE) && devpriv->ai_calib_source_enabled){
+			// Strobe Relay disable bit
+			ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff, Calibration_Channel_6143);
+			ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
+			devpriv->ai_calib_source_enabled = 0;
+			msleep_interruptible(100);	// Allow relays to change
+		}
+	}
+
 	offset=1<<(boardtype.adbits-1);
 	for(i=0;i<n_chan;i++){
-		if(list[i]&CR_ALT_SOURCE){
+		if((boardtype.reg_type != ni_reg_6143) && (list[i] & CR_ALT_SOURCE)){
 			chan=devpriv->ai_calib_source;
 		}else{
 			chan=CR_CHAN(list[i]);
@@ -1441,6 +1579,8 @@
 		{
 			if(boardtype.reg_type == ni_reg_611x)
 				aref = AREF_DIFF;
+			else if(boardtype.reg_type == ni_reg_6143)
+				aref = AREF_OTHER;
 			switch( aref )
 			{
 				case AREF_DIFF:
@@ -1460,15 +1600,17 @@
 
 		ni_writew(hi,Configuration_Memory_High);
 
-		lo = range;
-		if(i == n_chan - 1) lo |= AI_LAST_CHANNEL;
-		if( dither ) lo |= AI_DITHER;
+		if(boardtype.reg_type != ni_reg_6143){
+			lo = range;
+			if(i == n_chan - 1) lo |= AI_LAST_CHANNEL;
+			if( dither ) lo |= AI_DITHER;
 
-		ni_writew(lo,Configuration_Memory_Low);
+			ni_writew(lo,Configuration_Memory_Low);
+		}
 	}
 
 	/* prime the channel/gain list */
-	if(boardtype.reg_type != ni_reg_611x){
+	if((boardtype.reg_type != ni_reg_611x) && (boardtype.reg_type != ni_reg_6143)){
 		ni_prime_channelgain_list(dev);
 	}
 }
@@ -1553,7 +1695,7 @@
 		/* external trigger */
 		unsigned int tmp = CR_CHAN(cmd->start_arg);
 
-		if(tmp > 9) tmp = 9;
+		if(tmp > 16) tmp = 16;
 		tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
 		if(cmd->start_arg != tmp){
 			cmd->start_arg = tmp;
@@ -1579,7 +1721,7 @@
 		/* external trigger */
 		unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
 
-		if(tmp>9)tmp=9;
+		if(tmp>16)tmp=16;
 		tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
 		if(cmd->scan_begin_arg!=tmp){
 			cmd->scan_begin_arg = tmp;
@@ -1611,7 +1753,7 @@
 		/* external trigger */
 		unsigned int tmp = CR_CHAN(cmd->convert_arg);
 
-		if(tmp>9)tmp=9;
+		if(tmp>16)tmp=16;
 		tmp |= (cmd->convert_arg&(CR_ALT_FILTER|CR_INVERT));
 		if(cmd->convert_arg!=tmp){
 			cmd->convert_arg = tmp;
@@ -1692,7 +1834,7 @@
 		comedi_error(dev, "cannot run command without an irq");
 		return -EIO;
 	}
-	devpriv->stc_writew(dev, 1,ADC_FIFO_Clear);
+	ni_flush_ai_fifo(dev);
 
 	ni_load_channelgain_list(dev,cmd->chanlist_len,cmd->chanlist);
 
@@ -1732,7 +1874,7 @@
 	mode2 &= ~AI_SC_Reload_Mode;
 	devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
 
-	if(cmd->chanlist_len == 1 || boardtype.reg_type == ni_reg_611x){
+	if(cmd->chanlist_len == 1 || (boardtype.reg_type == ni_reg_611x) || (boardtype.reg_type == ni_reg_6143)){
 		start_stop_select |= AI_STOP_Polarity;
 		start_stop_select |= AI_STOP_Select( 31 ); // logic low
 		start_stop_select |= AI_STOP_Sync;
@@ -1989,6 +2131,18 @@
 				return -EINVAL;
 			}
 			devpriv->ai_calib_source = data[1];
+		} else if(boardtype.reg_type == ni_reg_6143)
+		{
+			unsigned int calib_source;
+
+			calib_source = data[1] & 0xf;
+	
+	
+			if(calib_source > 0xF)
+				return -EINVAL;
+			
+			devpriv->ai_calib_source = calib_source;
+			ni_writew(calib_source, Calibration_Channel_6143);
 		}else
 		{
 			unsigned int calib_source;
@@ -2875,7 +3029,7 @@
 		return -EINVAL;
 	}
 	
-	if(alloc_subdevices(dev, 10) < 0)
+	if(alloc_subdevices(dev, 11) < 0)
 		return -ENOMEM;
 
 	/* analog input subdevice */
@@ -2903,7 +3057,7 @@
 	}else{
 		s->type=COMEDI_SUBD_UNUSED;
 	}
-
+		
 	/* analog output subdevice */
 
 	s=dev->subdevices+1;
@@ -2986,6 +3140,13 @@
 		s->n_chan = 1;
 		s->maxdata = 0;
 		ni_writel(0x0, M_Offset_Cal_PWM);
+	} else if(boardtype.reg_type == ni_reg_6143)
+	{
+		// internal PWM analog output used for AI nonlinearity calibration
+		s->subdev_flags = SDF_INTERNAL;
+		s->insn_config = &ni_6143_pwm_config;
+		s->n_chan = 1;
+		s->maxdata = 0;
 	}else
 	{
 		s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
@@ -3046,9 +3207,20 @@
 	devpriv->serial_interval_ns = 0;
 	devpriv->serial_hw_mode = 0;
 
+	/* RTSI */
+	s=dev->subdevices+10;
+	s->type=COMEDI_SUBD_DIO;
+	s->subdev_flags=SDF_READABLE|SDF_WRITABLE|SDF_INTERNAL;
+	s->n_chan=8;
+	s->maxdata=1;
+	s->insn_bits = ni_rtsi_insn_bits;
+	s->insn_config = ni_rtsi_insn_config;
+	ni_rtsi_init(dev);
+
 	/* ai configuration */
 	ni_ai_reset(dev,dev->subdevices+0);
 	if((boardtype.reg_type & ni_reg_6xxx_mask) == 0){
+		// BEAM is this needed for PCI-6143 ??
 		devpriv->clock_and_fout =
 			Slow_Internal_Time_Divide_By_2 |
 			Slow_Internal_Timebase |
@@ -3211,6 +3383,49 @@
 	return 0;
 }
 
+static int ni_6143_pwm_config(comedi_device *dev, comedi_subdevice *s,
+	comedi_insn *insn, lsampl_t *data)
+{
+	unsigned up_count, down_count;
+	switch(data[0])
+	{
+	case INSN_CONFIG_PWM_OUTPUT:
+		switch(data[1])
+		{
+		case TRIG_ROUND_NEAREST:
+			up_count = (data[2] + TIMER_BASE / 2) / TIMER_BASE; 
+			down_count = (data[3] + TIMER_BASE / 2) / TIMER_BASE;
+			break;
+		case TRIG_ROUND_DOWN:
+			up_count = data[2] / TIMER_BASE;
+			down_count = data[3] / TIMER_BASE;
+			break;
+		case TRIG_ROUND_UP:
+			up_count = (data[2] + TIMER_BASE - 1) / TIMER_BASE;
+			down_count = (data[3] + TIMER_BASE - 1) / TIMER_BASE;
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		if(up_count * TIMER_BASE != data[2] ||
+			down_count * TIMER_BASE != data[3])
+		{
+			data[2] = up_count * TIMER_BASE;
+			data[3] = down_count * TIMER_BASE;
+			return -EAGAIN;
+		}
+		ni_writel(up_count, Calibration_HighTime_6143);
+		ni_writel(down_count, Calibration_LowTime_6143);
+		return 4;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
 static void ni_write_caldac(comedi_device *dev,int addr,int val);
 /*
 	calibration subdevice
@@ -3968,7 +4183,7 @@
 {
 	unsigned int chan;
 
-	if(insn->n!=1)return -EINVAL;
+	if(insn->n < 1)return -EINVAL;
 
 	chan = CR_CHAN(insn->chanspec);
 	if(chan>10)return -EINVAL;
@@ -3991,6 +4206,79 @@
 	return 1;
 }
 
+/*
+ *
+ *  NI RTSI Bus Functions
+ *
+ */
+static void ni_rtsi_init(comedi_device *dev)
+{
+	// Initialises the RTSI bus signal switch to a default state
+	
+	// Set clock mode to internal
+	devpriv->stc_writew(dev, COMEDI_RTSI_CLOCK_MODE_INTERNAL, RTSI_Trig_Direction_Register);
+
+	// Standard internal lines are routed to standard RTSI bus lines
+	devpriv->stc_writew(dev, 0x3210, RTSI_Trig_A_Output_Register);
+	devpriv->stc_writew(dev, 0x0654, RTSI_Trig_B_Output_Register);
+	
+	// Sets the source and direction of the 4 on board lines
+//	devpriv->stc_writew(dev, 0x0000, RTSI_Board_Register);
+}
+
+static int ni_rtsi_insn_bits(comedi_device *dev,comedi_subdevice *s,
+	comedi_insn *insn,lsampl_t *data)
+{
+	if(insn->n != 2) return -EINVAL;
+
+	data[1] = 0;
+
+	return 2;
+}
+
+static int ni_rtsi_insn_config(comedi_device *dev,comedi_subdevice *s,
+	comedi_insn *insn,lsampl_t *data)
+{
+	unsigned int chan;
+	unsigned int bit;
+
+	if(insn->n < 1) return -EINVAL;
+
+	if(data[0] == INSN_CONFIG_SET_RTSI_CLOCK_MODE){
+		if(data[1] > 3)
+			return -EINVAL;
+
+		devpriv->rtsi_trig_direction_reg &= ~0x03;
+		devpriv->rtsi_trig_direction_reg |= data[1];
+		devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg, RTSI_Trig_Direction_Register);
+	}
+	else {
+		chan = CR_CHAN(insn->chanspec);
+		if(chan > 6) return -EINVAL;
+		
+		bit = 9 + chan;
+
+		switch(data[0]){
+		case INSN_CONFIG_DIO_OUTPUT:
+			devpriv->rtsi_trig_direction_reg |= (1 << bit);
+			devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg, RTSI_Trig_Direction_Register);
+			break;
+		case INSN_CONFIG_DIO_INPUT:
+			devpriv->rtsi_trig_direction_reg &= ~(1 << bit);
+			devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg, RTSI_Trig_Direction_Register);
+			break;
+		case INSN_CONFIG_DIO_QUERY:
+			data[1] = (devpriv->rtsi_trig_direction_reg & (1<<bit)) ? INSN_CONFIG_DIO_OUTPUT : INSN_CONFIG_DIO_INPUT;
+			return 2;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	return 1;
+}
+
 static int cs5529_wait_for_idle(comedi_device *dev)
 {
 	unsigned short status;
Index: comedi/drivers/ni_pcimio.c
===================================================================
RCS file: /cvs/comedi/comedi/comedi/drivers/ni_pcimio.c,v
retrieving revision 1.112
diff -u -r1.112 ni_pcimio.c
--- comedi/drivers/ni_pcimio.c	2 Jan 2006 21:53:00 -0000	1.112
+++ comedi/drivers/ni_pcimio.c	1 Mar 2006 15:40:29 -0000
@@ -35,6 +35,7 @@
   PCI-6711, PXI-6711, PCI-6713, PXI-6713,
   PXI-6071E, PXI-6070E,
   PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733
+  PCI-6143
 Updated: Mon Jan 19 11:00:27 EST 2004
 
 These boards are almost identical to the AT-MIO E series, except that
@@ -54,6 +55,9 @@
 incorrect.  Please check this and submit a bug if there are problems
 for your device.
 
+2006-02-07: S-Series PCI-6143: Support has been added but is not
+	fully tested as yet. Terry Barnaby, BEAM Ltd.
+
 Bugs:
  - When DMA is enabled, COMEDI_EV_SCAN_END and COMEDI_EV_CONVERT do
    not work correctly.
@@ -158,6 +162,7 @@
 	{ PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_NATINST, 0x70C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, ni_pci_table);
@@ -958,6 +963,21 @@
 		.caldac = {caldac_none},
 		has_8255:	0,
 	},
+	{       device_id:      0x70C0,
+		name:           "pci-6143",
+		n_adchan:       8,
+		adbits:         16,
+		ai_fifo_depth:  1024,
+		alwaysdither:   0,
+		gainlkup:       ai_gain_6143,
+		ai_speed:	4000,
+		n_aochan:       0,
+		aobits:         0,
+		reg_type:	ni_reg_6143,
+		ao_unipolar:    0,
+		ao_fifo_depth:  0,
+		caldac:         {ad8804,ad8804},
+	},
 };
 #define n_pcimio_boards ((sizeof(ni_boards)/sizeof(ni_boards[0])))
 
@@ -1261,6 +1281,24 @@
 	writel(0x0, devpriv->mite->mite_io_addr + 0x30);
 }
 
+static void init_6143(comedi_device *dev)
+{
+	// Disable interrupts
+	devpriv->stc_writew(dev, 0, Interrupt_Control_Register);
+
+	// Initialise 6143 AI specific bits
+	ni_writeb(0x00, Magic_6143);		// Set G0,G1 DMA mode to E series version
+	ni_writeb(0x80, PipelineDelay_6143);	// Set EOCMode, ADCMode and pipelinedelay
+	ni_writeb(0x00, EOC_Set_6143);		// Set EOC Delay
+	
+	ni_writel(boardtype.ai_fifo_depth / 2, AIFIFO_Flag_6143);	// Set the FIFO half full level
+
+	// Strobe Relay disable bit
+	devpriv->ai_calib_source_enabled = 0;
+	ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff, Calibration_Channel_6143);
+	ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
+}
+
 /* cleans up allocated resources */
 static int pcimio_detach(comedi_device *dev)
 {
@@ -1309,8 +1347,11 @@
 		printk(" error setting up mite\n");
 		return ret;
 	}
+
 	if(boardtype.reg_type == ni_reg_m_series)
 		m_series_init_eeprom_buffer(dev);
+	if(boardtype.reg_type == ni_reg_6143)
+		init_6143(dev);
 
 	dev->irq=mite_irq(devpriv->mite);
 
Index: comedi/drivers/ni_stc.h
===================================================================
RCS file: /cvs/comedi/comedi/comedi/drivers/ni_stc.h,v
retrieving revision 1.83
diff -u -r1.83 ni_stc.h
--- comedi/drivers/ni_stc.h	8 Jan 2006 16:37:27 -0000	1.83
+++ comedi/drivers/ni_stc.h	1 Mar 2006 15:40:31 -0000
@@ -304,6 +304,7 @@
 #define FOUT_Divider(x)				(((x) & 0xf) << 0)
 
 #define IO_Bidirection_Pin_Register	57
+#define	RTSI_Trig_Direction_Register	58
 
 #define Interrupt_Control_Register	59
 #define Interrupt_B_Enable			_bit15
@@ -440,6 +441,9 @@
 	AO_TMRDACWR_Pulse_Width = 1 << 12,
 	AO_Number_Of_DAC_Packages = 1 << 14,	// 1 for "single" mode, 0 for "dual"
 };
+#define	RTSI_Trig_A_Output_Register	79
+#define	RTSI_Trig_B_Output_Register	80
+#define	RTSI_Board_Register		81
 #define Write_Strobe_0_Register		82
 #define Write_Strobe_1_Register		83
 #define Write_Strobe_2_Register		84
@@ -664,6 +668,36 @@
 #define AO_Window_Address_611x		0x18
 #define AO_Window_Data_611x		0x1e
 
+/* 6143 registers */
+#define Magic_6143			0x19 /* w8 */
+#define G0G1_DMA_Select_6143		0x0B /* w8 */
+#define PipelineDelay_6143		0x1f /* w8 */
+#define EOC_Set_6143			0x1D /* w8 */
+#define AIDMA_Select_6143		0x09 /* w8 */
+#define AIFIFO_Data_6143		0x8C /* w32 */
+#define AIFIFO_Flag_6143		0x84 /* w32 */
+#define AIFIFO_Control_6143		0x88 /* w32 */
+#define AIFIFO_Status_6143		0x88 /* w32 */
+#define AIFIFO_DMAThreshold_6143	0x90 /* w32 */
+#define AIFIFO_Words_Available_6143	0x94 /* w32 */
+
+#define Calibration_Channel_6143	0x42 /* w16 */
+#define Calibration_LowTime_6143	0x20 /* w16 */
+#define Calibration_HighTime_6143	0x22 /* w16 */
+#define Relay_Counter_Load_Val__6143	0x4C /* w32 */
+#define Signature_6143			0x50 /* w32 */
+#define Release_Date_6143		0x54 /* w32 */
+#define Release_Oldest_Date_6143	0x58 /* w32 */
+
+#define Calibration_Channel_6143_RelayOn	0x8000	/* Calibration relay switch On */
+#define Calibration_Channel_6143_RelayOff	0x4000	/* Calibration relay switch Off */
+#define Calibration_Channel_Gnd_Gnd	0x00	/* Offset Calibration */
+#define Calibration_Channel_2v5_Gnd	0x02	/* 2.5V Reference */
+#define Calibration_Channel_Pwm_Gnd	0x05	/* +/- 5V Self Cal */
+#define Calibration_Channel_2v5_Pwm	0x0a	/* PWM Calibration */
+#define Calibration_Channel_Pwm_Pwm	0x0d	/* CMRR */
+#define Calibration_Channel_Gnd_Pwm	0x0e	/* PWM Calibration */
+
 /* 671x, 611x registers */
 
 /* 671xi, 611x windowed ao registers */
@@ -757,7 +791,7 @@
 	GPC1_DMA_CHAN = 3,
 };
 
-enum{ ai_gain_16=0, ai_gain_8, ai_gain_14, ai_gain_4, ai_gain_611x, ai_gain_622x, ai_gain_628x };
+enum{ ai_gain_16=0, ai_gain_8, ai_gain_14, ai_gain_4, ai_gain_611x, ai_gain_622x, ai_gain_628x,  ai_gain_6143};
 enum caldac_enum { caldac_none=0, mb88341, dac8800, dac8043, ad8522,
 	ad8804, ad8842, ad8804_debug };
 enum ni_reg_type {
@@ -767,7 +801,8 @@
 	ni_reg_6713 = 0x4,
 	ni_reg_67xx_mask = 0x6,
 	ni_reg_6xxx_mask = 0x7,
-	ni_reg_m_series = 0x8
+	ni_reg_m_series = 0x8,
+	ni_reg_6143 = 0x10
 };
 
 static comedi_lrange range_ni_E_ao_ext;
@@ -1069,6 +1104,7 @@
 	int blocksize;						\
 	int n_left;						\
 	unsigned int ai_calib_source;				\
+	unsigned int ai_calib_source_enabled;			\
 	spinlock_t window_lock; \
 								\
 	int changain_state;					\
@@ -1104,6 +1140,7 @@
 	volatile unsigned short int_a_enable_reg;			\
 	volatile unsigned short int_b_enable_reg;			\
 	unsigned short io_bidirection_pin_reg;			\
+	unsigned short rtsi_trig_direction_reg;			\
 								\
 	unsigned short atrig_mode;				\
 	unsigned short atrig_high;				\
Index: include/linux/comedi.h
===================================================================
RCS file: /cvs/comedi/comedi/include/linux/comedi.h,v
retrieving revision 1.49
diff -u -r1.49 comedi.h
--- include/linux/comedi.h	8 Jan 2006 16:37:28 -0000	1.49
+++ include/linux/comedi.h	1 Mar 2006 15:40:31 -0000
@@ -246,9 +246,11 @@
 	INSN_CONFIG_SET_CLOCK_SRC = 2003,	// Set CTR clock source
 	INSN_CONFIG_GET_CLOCK_SRC = 2004,	// Get CTR clock source
 	INSN_CONFIG_8254_SET_MODE = 4097,
-	INSN_CONFIG_8254_READ_STATUS = 4098
+	INSN_CONFIG_8254_READ_STATUS = 4098,
+	INSN_CONFIG_SET_RTSI_CLOCK_MODE = 5000	// Set RTSI bus clock mode
 };
 
+
 /* ioctls */
 
 #define CIO 'd'
@@ -516,6 +518,54 @@
 	I8254_BCD = 1, /* use binary-coded decimal instead of binary (pretty useless) */
 	I8254_BINARY = 0
 };
+
+/* RTSI Clock mode */
+#define COMEDI_RTSI_CLOCK_MODE_INTERNAL	0x00	// Internal clock mode
+#define COMEDI_RTSI_CLOCK_MODE_OUTPUT	0x01	// Outputs clock to RTSI
+#define COMEDI_RTSI_CLOCK_MODE_SLAVE	0x02	// Runs from RTSI clock
+#define COMEDI_RTSI_CLOCK_MODE_MASTER	0x03	// Outputs clock to RTSI and runs from this external clock
+
+/* RTSI BUS pins */
+#define NI_RTSI_0		0
+#define NI_RTSI_1		1
+#define NI_RTSI_2		2
+#define NI_RTSI_3		3
+#define NI_RTSI_4		4
+#define NI_RTSI_5		5
+#define NI_RTSI_6		6
+#define NI_RTSI_7		7
+
+/* RTSI BUS pin usage in standard configuration */
+#define NI_RTSI_STD_AI_START1		0
+#define NI_RTSI_STD_AI_START2		1
+#define NI_RTSI_STD_AI_CONV		2
+#define NI_RTSI_STD_CT1_SRC		3
+#define NI_RTSI_STD_CT1_GATE		4
+#define NI_RTSI_STD_AO_SAMP_CLOCK	5
+#define NI_RTSI_STD_AO_START_TRIG	6
+#define NI_RTSI_STD_AI_SAMP_CLOCK	7
+#define NI_RTSI_STD_CTR0_SRC		8
+#define NI_RTSI_STD_CTR0_GATE		9
+
+/* NI External Trigger lines */
+#define NI_EXT_PFI_0			0
+#define NI_EXT_PFI_1			1
+#define NI_EXT_PFI_2			2
+#define NI_EXT_PFI_3			3
+#define NI_EXT_PFI_4			4
+#define NI_EXT_PFI_5			5
+#define NI_EXT_PFI_6			6
+#define NI_EXT_PFI_7			7
+#define NI_EXT_PFI_8			8
+#define NI_EXT_PFI_9			9
+#define NI_EXT_RTSI_0			10
+#define NI_EXT_RTSI_1			11
+#define NI_EXT_RTSI_2			12
+#define NI_EXT_RTSI_3			13
+#define NI_EXT_RTSI_4			14
+#define NI_EXT_RTSI_5			15
+#define NI_EXT_RTSI_6			16
+
 #ifdef __cplusplus
 }
 #endif
