⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtd520.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Set burst start source select (write only) */#define RtdBurstStartSource(dev,v) \    writel (v, devpriv->las0+LAS0_BURST_START)/* Set Pacer start source select (write only) */#define RtdPacerStartSource(dev,v) \    writel (v, devpriv->las0+LAS0_PACER_START)/* Set Pacer stop source select (write only) */#define RtdPacerStopSource(dev,v) \    writel (v, devpriv->las0+LAS0_PACER_STOP)/* Set Pacer clock source select (write only) 0=external 1=internal */#define RtdPacerClockSource(dev,v) \    writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT)/* Set sample counter source select (write only) */#define RtdAdcSampleCounterSource(dev,v) \    writel (v, devpriv->las0+LAS0_ADC_SCNT_SRC)/* Set Pacer trigger mode select (write only) 0=single cycle, 1=repeat */#define RtdPacerTriggerMode(dev,v) \    writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT)/* Set About counter stop enable (write only) */#define RtdAboutStopEnable(dev,v) \    writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE)/* Set external trigger polarity (write only) 0=positive edge, 1=negative */#define RtdTriggerPolarity(dev,v) \    writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY)/* Start single ADC conversion */#define RtdAdcStart(dev) \    writew (0, devpriv->las0+LAS0_ADC)/* Read one ADC data value (12bit (with sign extend) as 16bit) *//* Note: matches what DMA would get.  Actual value >> 3 */#define RtdAdcFifoGet(dev) \    readw (devpriv->las1+LAS1_ADC_FIFO)/* Read two ADC data values (DOESNT WORK) */#define RtdAdcFifoGet2(dev) \    readl (devpriv->las1+LAS1_ADC_FIFO)/* FIFO status */#define RtdFifoStatus(dev) \    readl (devpriv->las0+LAS0_ADC)/* pacer start/stop read=start, write=stop*/#define RtdPacerStart(dev) \    readl (devpriv->las0+LAS0_PACER)#define RtdPacerStop(dev) \    writel (0, devpriv->las0+LAS0_PACER)/* Interrupt status */#define RtdInterruptStatus(dev) \    readw (devpriv->las0+LAS0_IT)/* Interrupt mask */#define RtdInterruptMask(dev,v) \    writew ((devpriv->intMask = (v)),devpriv->las0+LAS0_IT)/* Interrupt status clear (only bits set in mask) */#define RtdInterruptClear(dev) \    readw (devpriv->las0+LAS0_CLEAR)/* Interrupt clear mask */#define RtdInterruptClearMask(dev,v) \    writew ((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR)/* Interrupt overrun status */#define RtdInterruptOverrunStatus(dev) \    readl (devpriv->las0+LAS0_OVERRUN)/* Interrupt overrun clear */#define RtdInterruptOverrunClear(dev) \    writel (0, devpriv->las0+LAS0_OVERRUN)/* Pacer counter, 24bit */#define RtdPacerCount(dev) \    readl (devpriv->las0+LAS0_PCLK)#define RtdPacerCounter(dev,v) \    writel ((v) & 0xffffff,devpriv->las0+LAS0_PCLK)/* Burst counter, 10bit */#define RtdBurstCount(dev) \    readl (devpriv->las0+LAS0_BCLK)#define RtdBurstCounter(dev,v) \    writel ((v) & 0x3ff,devpriv->las0+LAS0_BCLK)/* Delay counter, 16bit */#define RtdDelayCount(dev) \    readl (devpriv->las0+LAS0_DCLK)#define RtdDelayCounter(dev,v) \    writel ((v) & 0xffff, devpriv->las0+LAS0_DCLK)/* About counter, 16bit */#define RtdAboutCount(dev) \    readl (devpriv->las0+LAS0_ACNT)#define RtdAboutCounter(dev,v) \    writel ((v) & 0xffff, devpriv->las0+LAS0_ACNT)/* ADC sample counter, 10bit */#define RtdAdcSampleCount(dev) \    readl (devpriv->las0+LAS0_ADC_SCNT)#define RtdAdcSampleCounter(dev,v) \    writel ((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT)/* User Timer/Counter (8254) */#define RtdUtcCounterGet(dev,n) \    readb (devpriv->las0 \        + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))#define RtdUtcCounterPut(dev,n,v) \    writeb ((v) & 0xff, devpriv->las0 \        + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))/* Set UTC (8254) control byte  */#define RtdUtcCtrlPut(dev,n,v) \    writeb (devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \      devpriv->las0 + LAS0_UTC_CTRL)/* Set UTCn clock source (write only) */#define RtdUtcClockSource(dev,n,v) \    writew (v, devpriv->las0 \        + ((n <= 0) ? LAS0_UTC0_CLOCK : \           ((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK)))/* Set UTCn gate source (write only) */#define RtdUtcGateSource(dev,n,v) \    writew (v, devpriv->las0 \        + ((n <= 0) ? LAS0_UTC0_GATE : \           ((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE)))/* User output N source select (write only) */#define RtdUsrOutSource(dev,n,v) \    writel (v,devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))/* Digital IO */#define RtdDio0Read(dev) \    (readw (devpriv->las0+LAS0_DIO0) & 0xff)#define RtdDio0Write(dev,v) \    writew ((v) & 0xff, devpriv->las0+LAS0_DIO0)#define RtdDio1Read(dev) \    (readw (devpriv->las0+LAS0_DIO1) & 0xff)#define RtdDio1Write(dev,v) \    writew ((v) & 0xff, devpriv->las0+LAS0_DIO1)#define RtdDioStatusRead(dev) \    (readw (devpriv->las0+LAS0_DIO_STATUS) & 0xff)#define RtdDioStatusWrite(dev,v) \    writew ((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS)#define RtdDio0CtrlRead(dev) \    (readw (devpriv->las0+LAS0_DIO0_CTRL) & 0xff)#define RtdDio0CtrlWrite(dev,v) \    writew ((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL)/* Digital to Analog converter *//* Write one data value (sign + 12bit + marker bits) *//* Note: matches what DMA would put.  Actual value << 3 */#define RtdDacFifoPut(dev,n,v) \    writew ((v), devpriv->las1 +(((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO))/* Start single DAC conversion */#define RtdDacUpdate(dev,n) \    writew (0, devpriv->las0 +(((n) == 0) ? LAS0_DAC1 : LAS0_DAC2))/* Start single DAC conversion on both DACs */#define RtdDacBothUpdate(dev) \    writew (0, devpriv->las0+LAS0_DAC)/* Set DAC output type and range */#define RtdDacRange(dev,n,v) \    writew ((v) & 7, devpriv->las0 \	+(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL))/* Reset DAC FIFO */#define RtdDacClearFifo(dev,n) \    writel (0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET))/* Set source for DMA 0 (write only, shadow?) */#define RtdDma0Source(dev,n) \    writel ((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC)/* Set source for DMA 1 (write only, shadow?) */#define RtdDma1Source(dev,n) \    writel ((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC)/* Reset board state for DMA 0 */#define RtdDma0Reset(dev) \    writel (0, devpriv->las0+LAS0_DMA0_RESET)/* Reset board state for DMA 1 */#define RtdDma1Reset(dev) \    writel (0, devpriv->las0+LAS0_DMA1_SRC)/* PLX9080 interrupt mask and status */#define RtdPlxInterruptRead(dev) \    readl (devpriv->lcfg+LCFG_ITCSR)#define RtdPlxInterruptWrite(dev,v) \    writel (v, devpriv->lcfg+LCFG_ITCSR)/* Set  mode for DMA 0 */#define RtdDma0Mode(dev,m) \    writel ((m), devpriv->lcfg+LCFG_DMAMODE0)/* Set PCI address for DMA 0 */#define RtdDma0PciAddr(dev,a) \    writel ((a), devpriv->lcfg+LCFG_DMAPADR0)/* Set local address for DMA 0 */#define RtdDma0LocalAddr(dev,a) \    writel ((a), devpriv->lcfg+LCFG_DMALADR0)/* Set byte count for DMA 0 */#define RtdDma0Count(dev,c) \    writel ((c), devpriv->lcfg+LCFG_DMASIZ0)/* Set next descriptor for DMA 0 */#define RtdDma0Next(dev,a) \    writel ((a), devpriv->lcfg+LCFG_DMADPR0)/* Set  mode for DMA 1 */#define RtdDma1Mode(dev,m) \    writel ((m), devpriv->lcfg+LCFG_DMAMODE1)/* Set PCI address for DMA 1 */#define RtdDma1PciAddr(dev,a) \    writel ((a), devpriv->lcfg+LCFG_DMAADR1)/* Set local address for DMA 1 */#define RtdDma1LocalAddr(dev,a) \    writel ((a), devpriv->lcfg+LCFG_DMALADR1)/* Set byte count for DMA 1 */#define RtdDma1Count(dev,c) \    writel ((c), devpriv->lcfg+LCFG_DMASIZ1)/* Set next descriptor for DMA 1 */#define RtdDma1Next(dev,a) \    writel ((a), devpriv->lcfg+LCFG_DMADPR1)/* Set control for DMA 0 (write only, shadow?) */#define RtdDma0Control(dev,n) \    writeb (devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0)/* Get status for DMA 0 */#define RtdDma0Status(dev) \    readb (devpriv->lcfg+LCFG_DMACSR0)/* Set control for DMA 1 (write only, shadow?) */#define RtdDma1Control(dev,n) \    writeb (devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1)/* Get status for DMA 1 */#define RtdDma1Status(dev) \    readb (devpriv->lcfg+LCFG_DMACSR1)/* * The comedi_driver structure tells the Comedi core module * which functions to call to configure/deconfigure (attac/detach) * the board, and also about the kernel module that contains * the device code. */static int rtd_attach (comedi_device *dev, comedi_devconfig *it);static int rtd_detach (comedi_device *dev);static comedi_driver rtd520Driver={    driver_name:	"rtd520",    module:		THIS_MODULE,    attach:		rtd_attach,    detach:		rtd_detach,    board_name:		rtd520Boards,    offset:		sizeof(rtdBoard),    num_names:		sizeof(rtd520Boards) / sizeof(rtdBoard),};static int rtd_ai_rinsn (comedi_device *dev, comedi_subdevice *s,			 comedi_insn *insn, lsampl_t *data);static int rtd_ao_winsn (comedi_device *dev, comedi_subdevice *s,			 comedi_insn *insn, lsampl_t *data);static int rtd_ao_rinsn (comedi_device *dev, comedi_subdevice *s,			 comedi_insn *insn, lsampl_t *data);static int rtd_dio_insn_bits (comedi_device *dev, comedi_subdevice *s,			      comedi_insn *insn, lsampl_t *data);static int rtd_dio_insn_config (comedi_device *dev, comedi_subdevice *s,				comedi_insn *insn, lsampl_t *data);static int rtd_ai_cmdtest (comedi_device *dev,comedi_subdevice *s,			   comedi_cmd *cmd);static int rtd_ai_cmd ( comedi_device *dev, comedi_subdevice *s);static int rtd_ai_cancel ( comedi_device *dev, comedi_subdevice *s);//static int rtd_ai_poll (comedi_device *dev,comedi_subdevice *s);static int rtd_ns_to_timer (unsigned int *ns, int roundMode);static void rtd_interrupt ( int irq, void *d, struct pt_regs *regs);/* * Attach is called by the Comedi core to configure the driver * for a particular board.  If you specified a board_name array * in the driver structure, dev->board_ptr contains that * address. */static int rtd_attach (    comedi_device *dev,    comedi_devconfig *it)		/* board name and options flags */{    comedi_subdevice *s;    struct pci_dev* pcidev;    int	ret;    unsigned long physLas0;		/* configuation */    unsigned long physLas1;		/* data area */    unsigned long physLcfg;		/* PLX9080 */#ifdef USE_DMA    int index;#endif    printk ("comedi%d: rtd520 attaching.\n", dev->minor);#if defined (CONFIG_COMEDI_DEBUG) && defined (USE_DMA)    /* You can set this a load time: modprobe comedi comedi_debug=1 */    if (0 == comedi_debug)		/* force DMA debug printks */	comedi_debug = 1;#endif    /*     * Allocate the private structure area.  alloc_private() is a     * convenient macro defined in comedidev.h.     */    if (alloc_private (dev, sizeof(rtdPrivate))<0)	return -ENOMEM;    /*     * Probe the device to determine what device in the series it is.     */    pci_for_each_dev (pcidev) {	if (pcidev->vendor == PCI_VENDOR_ID_RTD) {	    if (it->options[0] || it->options[1]) {		if (pcidev->bus->number == it->options[0]		    && PCI_SLOT(pcidev->devfn) == it->options[1]) {		    DPRINTK("rtd520: found bus=%d slot=%d\n",			   it->options[0], it->options[1]);		    break;		/* found it */		}	    } else {		/* specific board/slot not specified */		break;		/* found one */	    }	}    }    if (!pcidev) {	if (it->options[0] && it->options[1]) {	    printk ("No RTD card at bus=%d slot=%d.\n",		    it->options[0], it->options[1]);	} else {	    printk ("No RTD card found.\n");	}	return -EIO;    }    if (pcidev->device != thisboard->device_id) {	printk ("Found an RTD card, but not the supported type (%x).\n",		pcidev->device);	return -EIO;    }    devpriv->pci_dev = pcidev;    dev->board_name = thisboard->name;    if((ret=pci_enable_device(pcidev))<0){	return ret;    }    /*     * Initialize base addresses     */    /* Get the physical address from PCI config */	physLas0 = pci_resource_start(devpriv->pci_dev, LAS0_PCIINDEX); 	physLas1 = pci_resource_start(devpriv->pci_dev, LAS1_PCIINDEX); 	physLcfg = pci_resource_start(devpriv->pci_dev, LCFG_PCIINDEX);     /* Now have the kernel map this into memory */					/* ASSUME page aligned */    devpriv->las0 = ioremap_nocache(physLas0, LAS0_PCISIZE);    devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE);    devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE);    DPRINTK ("%s: LAS0=%lx, LAS1=%lx, CFG=%lx.\n", dev->board_name,	     physLas0, physLas1, physLcfg);    {					/* The RTD driver does this */	unsigned char pci_latency;	u16 revision;	/*uint32_t epld_version;*/	pci_read_config_word(devpriv->pci_dev, PCI_REVISION_ID, &revision);   	DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision);	pci_read_config_byte(devpriv->pci_dev,			     PCI_LATENCY_TIMER, &pci_latency);	if (pci_latency < 32) {	    printk ("%s: PCI latency changed from %d to %d\n", dev->board_name,		    pci_latency, 32);	    pci_write_config_byte(devpriv->pci_dev, PCI_LATENCY_TIMER, 32);	} else {	    DPRINTK ("rtd520: PCI latency = %d\n", pci_latency);	}	/* Undocumented EPLD version (doesnt match RTD driver results) */	/*DPRINTK ("rtd520: Reading epld from %p\n",		 devpriv->las0+0);	epld_version = readl (devpriv->las0+0);	if ((epld_version & 0xF0) >> 4 == 0x0F) {	    DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version);	} else {	    DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4);	    }*/    }    /* Show board configuration */    /* It is critical that the FIFO length matches the board.  Otherwise,       data transfers and DMA will either read 0s or overwrite memory!       It is possible to probe for FIFO size. */    printk ("%s: ( fifoLen=%d )" , dev->board_name, thisboard->fifoLen);    /*     * Allocate the subdevice structures.  alloc_subdevice() is a     * convenient macro defined in comedidev.h.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -