From: Frank Mori Hess Date: Thu, 18 Oct 2007 21:40:34 +0000 (+0000) Subject: Got rid of fragile checks of specific device ids in mite.c (fixed problems X-Git-Tag: r0_7_75~14 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=b7fa77c12ff9682d5ad9766ce595384b2107907a;p=comedi.git Got rid of fragile checks of specific device ids in mite.c (fixed problems with pxi-6602 support). Added device id for pxi-6608. Made sure the "window base size register" is disabled when using the "window base size register 1", since it causes problems if both are enabled simultaneously. --- diff --git a/comedi/drivers/mite.c b/comedi/drivers/mite.c index 62a5fce6..acdd0d35 100644 --- a/comedi/drivers/mite.c +++ b/comedi/drivers/mite.c @@ -110,7 +110,7 @@ static void dump_chip_signature(u32 csigr_bits) mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits)); } -int mite_setup(struct mite_struct *mite) +int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1) { unsigned long length; resource_size_t addr; @@ -139,13 +139,8 @@ int mite_setup(struct mite_struct *mite) addr=pci_resource_start(mite->pcidev, 1); mite->daq_phys_addr=addr; - + length = pci_resource_len(mite->pcidev, 1); // In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output) - if ((mite->pcidev->device == 0x1310) || (mite->pcidev->device == 0x2c60)){ - length = PCI_DAQ_SIZE_660X; - printk("mite: detected NI660X board, using PCI DAQ SIZE of 8k\n"); - } - else length = PCI_DAQ_SIZE; mite->daq_io_addr = ioremap(mite->daq_phys_addr, length); if( !mite->daq_io_addr ) { printk("failed to remap daq io memory address\n"); @@ -153,15 +148,12 @@ int mite_setup(struct mite_struct *mite) } printk("DAQ:0x%08llx mapped to %p\n",(unsigned long long)mite->daq_phys_addr,mite->daq_io_addr); - // 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 ){ - unsigned window_size_order; - - printk("mite: detected NI6602, using other I/O Window Base Size register\n"); - window_size_order = 13; // 8 kbyte - writel(mite->daq_phys_addr | WENAB | MITE_IODWBSR_1_WSIZE_bits(window_size_order), mite->mite_io_addr + MITE_IODWBSR_1); - writel(0 ,mite->mite_io_addr + MITE_IODWCR_1); + if(use_iodwbsr_1) + { + writel(0, mite->mite_io_addr + MITE_IODWBSR); + printk("mite: using I/O Window Base Size register 1\n"); + writel(mite->daq_phys_addr | WENAB | MITE_IODWBSR_1_WSIZE_bits(length), 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); @@ -197,6 +189,10 @@ int mite_setup(struct mite_struct *mite) return 0; } +int mite_setup(struct mite_struct *mite) +{ + return mite_setup2(mite, 0); +} void mite_cleanup(void) { @@ -769,6 +765,7 @@ EXPORT_SYMBOL(mite_dma_disarm); EXPORT_SYMBOL(mite_sync_input_dma); EXPORT_SYMBOL(mite_sync_output_dma); EXPORT_SYMBOL(mite_setup); +EXPORT_SYMBOL(mite_setup2); EXPORT_SYMBOL(mite_unsetup); #if 0 EXPORT_SYMBOL(mite_kvmem_segment_load); diff --git a/comedi/drivers/mite.h b/comedi/drivers/mite.h index 5c28e502..b810fc86 100644 --- a/comedi/drivers/mite.h +++ b/comedi/drivers/mite.h @@ -124,6 +124,7 @@ static inline unsigned int mite_device_id(struct mite_struct *mite) void mite_init(void); void mite_cleanup(void); int mite_setup(struct mite_struct *mite); +int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1); void mite_unsetup(struct mite_struct *mite); void mite_list_devices(void); struct mite_channel* mite_request_channel_in_range( @@ -253,9 +254,11 @@ enum MITE_IODWBSR_bits { WENAB = 0x80, // window enable }; -// sets window size to 2 raised to the power "order" -static inline unsigned MITE_IODWBSR_1_WSIZE_bits(unsigned order) + +static inline unsigned MITE_IODWBSR_1_WSIZE_bits(unsigned size) { + unsigned order = 0; + while(size >>= 1) ++order; BUG_ON(order < 1); return (order - 1) & 0x1f; } diff --git a/comedi/drivers/ni_660x.c b/comedi/drivers/ni_660x.c index 075bd09c..50f94e97 100644 --- a/comedi/drivers/ni_660x.c +++ b/comedi/drivers/ni_660x.c @@ -21,26 +21,23 @@ Driver: ni_660x Description: National Instruments 660x counter/timer boards Devices: -[National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602 +[National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602, + PXI-6608 Author: J.P. Mellor , Herman.Bruyninckx@mech.kuleuven.ac.be, Wim.Meeussen@mech.kuleuven.ac.be, Klaas.Gadeyne@mech.kuleuven.ac.be, Frank Mori Hess -Updated: Sun Nov 16 18:46:11 UTC 2003 +Updated: Thu Oct 18 12:56:06 EDT 2007 Status: experimental -Encoders work, but only with instructions, commands are not -supported yet. PulseGeneration (both single pulse and pulse train) -works. DIO is experimental (8 channels only). Interrupts do not -work. +Encoders work. PulseGeneration (both single pulse and pulse train) +works. Buffered commands work for input but not output. References: DAQ 660x Register-Level Programmer Manual (NI 370505A-01) DAQ 6601/6602 User Manual (NI 322137B-01) -Things to do: -- Add commands (see ni_tio.c and ni_mio_common.c) */ #include @@ -218,18 +215,18 @@ static const NI_660xRegisterData registerData[NumRegisters] = {"G1 Status Register", 0x006, NI_660x_READ, DATA_2B}, {"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B}, {"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B}, - {"STD DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B}, + {"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B}, {"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B}, {"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B}, {"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B}, - {"STD DIO Output", 0x014, NI_660x_WRITE, DATA_2B}, - {"STD DIO Control", 0x016, NI_660x_WRITE, DATA_2B}, + {"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B}, + {"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B}, {"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B}, {"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B}, {"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B}, {"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B}, {"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B}, - {"STD DIO Serial Input", 0x038, NI_660x_READ, DATA_2B}, + {"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B}, {"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B}, {"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B}, {"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B}, @@ -385,7 +382,7 @@ enum global_interrupt_config_register_bits }; // Offset of the GPCT chips from the base-adress of the card -static const unsigned GPCT_OFFSET[2] = {0x0, 0x800}; /* First chip is at base-adress + +static const unsigned GPCT_OFFSET[2] = {0x0, 0x800}; /* First chip is at base-address + 0x00, etc. */ /* Board description*/ @@ -413,6 +410,11 @@ static const ni_660x_board ni_660x_boards[] = name : "PXI-6602", n_chips : 2, }, + { + dev_id : 0x2cc0, + name : "PXI-6608", + n_chips : 2, + }, }; #define NI_660X_MAX_NUM_CHIPS 2 #define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip) @@ -421,6 +423,7 @@ static struct pci_device_id ni_660x_pci_table[] __devinitdata = { { PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); @@ -874,6 +877,18 @@ static int ni_660x_cancel(comedi_device *dev, comedi_subdevice *s) return retval; } +static void set_tio_counterswap(comedi_device *dev, int chipset) +{ + /* See P. 3.5 of the Register-Level Programming manual. The + CounterSwap bit has to be set on the second chip, otherwise + it will try to use the same pins as the first chip. + */ + if(chipset) + ni_660x_write_register(dev, chipset, CounterSwap, ClockConfigRegister); + else + ni_660x_write_register(dev, chipset, 0, ClockConfigRegister); +} + static void ni_660x_handle_gpct_interrupt(comedi_device *dev, comedi_subdevice *s) { ni_tio_handle_interrupt(subdev_to_counter(s), s); @@ -978,7 +993,7 @@ static int ni_660x_attach(comedi_device *dev,comedi_devconfig *it) dev->board_name = board(dev)->name; - ret = mite_setup(private(dev)->mite); + ret = mite_setup2(private(dev)->mite, 1); if (ret < 0) { printk("error setting up mite\n"); return ret; @@ -1057,6 +1072,12 @@ static int ni_660x_attach(comedi_device *dev,comedi_devconfig *it) ni_660x_set_pfi_routing(dev, i, pfi_output_select_counter); ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); } + /* to be safe, set counterswap bits on tio chips after all the counter + outputs have been set to high impedance mode */ + for(i = 0; i < board(dev)->n_chips; ++i) + { + set_tio_counterswap(dev, i); + } if((ret = comedi_request_irq(mite_irq(private(dev)->mite), &ni_660x_interrupt, IRQF_SHARED, "ni_660x", dev)) < 0) { printk(" irq not available\n"); @@ -1066,7 +1087,6 @@ static int ni_660x_attach(comedi_device *dev,comedi_devconfig *it) global_interrupt_config_bits = Global_Int_Enable_Bit; if(board(dev)->n_chips > 1) global_interrupt_config_bits |= Cascade_Int_Enable_Bit; - ni_660x_write_register(dev, 0, global_interrupt_config_bits, GlobalInterruptConfigRegister); printk("attached\n"); @@ -1106,14 +1126,6 @@ static void init_tio_chip(comedi_device *dev, int chipset) { unsigned i; - /* See P. 3.5 of the Register-Level Programming manual. The - CounterSwap bit has to be set on the second chip, otherwise - it will try to use the same pins as the first chip. - */ - if(chipset) - ni_660x_write_register(dev, chipset, CounterSwap, ClockConfigRegister); - else - ni_660x_write_register(dev, chipset, 0, ClockConfigRegister); // init dma configuration register private(dev)->dma_configuration_soft_copies[chipset] = 0; for(i = 0; i < MAX_DMA_CHANNEL; ++i)