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

📄 rtd-dm6430.c

📁 rt 6430 采集卡 linux下驱动源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    int irq,    struct Dm6430hrDevice *device_p,    struct pt_regs *regs_p) {    static short	mask[] = {DM6430_CL_IRQ1, DM6430_CL_IRQ2};    if (device_p) {        	int		channel;	unsigned long	flags;#ifdef DEBUG	if (debug & DBG_INT)	    printk(KERN_INFO "dm6430: hardware int\n");#endif	if (	    (device_p->irq[channel = 0] == irq)	    ||	    (device_p->irq[channel = 1] == irq)	) {	    if (dm_inw_p(device_p->io + r_STATUS_6430) & (0x2000 << channel)) {		spin_lock_irqsave(&device_p->lock, flags);		// fixme tmp		//	    printk(KERN_INFO "STATUS = 0x%04x, residue0=%d, residue1=%d\n", dm_inw_p(dev->io + r_STATUS_6430), get_dma_residue(dev->dma[0]), get_dma_residue(dev->dma[1]) );#ifdef DEBUG		if (debug & DBG_INT)		    printk(KERN_INFO "dm6430: int ch=%d\n", channel);#endif		device_p->irq_count[channel]++;	    		/* clear interrupts */		DM6430HRClear(device_p, mask[channel]);			if (		    (device_p->callback[channel].signo != 0)		    &&		    (device_p->callback[channel].process != 0)		) {		    struct siginfo	info;#ifdef DEBUG		    if (debug & DBG_INT)			printk(			    KERN_INFO "sending %d to %d\n",			    device_p->callback[channel].signo,			    device_p->callback[channel].process->pid			);#endif		    info.si_signo = device_p->callback[channel].signo;		    info.si_errno = channel;		    // must be < 0 for info.si_ptr		    info.si_code = DM6430HR_SI_CODE;		    /* sending from kernel */		    info.si_pid = 0;		    info.si_uid = 0;		    info.si_ptr = device_p->callback[channel].context;		    send_sig_info(			info.si_signo,			&info,			device_p->callback[channel].process		    );		}		spin_unlock_irqrestore(&device_p->lock, flags);	    }	}    }}static inline intdm6430hr_detect(struct Dm6430hrDevice *device_p) {    return 1;    /* return dm_inb_p(device_p->io + 2) != 0xFF; */}static voiddm6430hr_unregister_device(struct Dm6430hrDevice *device_p) {    int	i;#ifdef DEBUG    if (debug & DBG_REG_DEVS)	printk(KERN_INFO "dm6430hr_unregister_device()\n");#endif    if (device_p && (device_p->flags & INITIALIZED)) {	spin_lock(&device_p->lock);	for (i = 0; i < DM6430HR_DMAS; i++) {	    if (device_p->dma[i])		free_dma(device_p->dma[i]);	    if (device_p->dmabuf[i].addr) {		dm_dma_mem_free(		    (unsigned long) device_p->dmabuf[i].addr,		    device_p->dmabuf[i].length		);		device_p->dmabuf[i].length = 0;		device_p->dmabuf[i].addr = 0;	    }	}	for (i = 0; i < DM6430HR_IRQS; i++) {	    if (device_p->irq[i]) {		free_irq(device_p->irq[i], device_p);	    }	}	if (device_p->io)	    release_region(device_p->io, DM6430HR_IO_EXTENT);	for (i = 0; i < DM6430HR_IRQS; ++i) {	    device_p->callback[i].signo = 0;	    device_p->callback[i].process = 0;	    device_p->callback[i].context = 0;	}	atomic_set(&device_p->counter, 0);    	device_p->flags &= ~INITIALIZED;	/*	 * Free streaming read buffer memory.	 */	if (device_p->stream_buff_p != NULL) {	    kfree(device_p->stream_buff_p);	}	spin_unlock(&device_p->lock);    }}static intdm6430hr_register_device(struct Dm6430hrDevice *device_p) {    int		rc = 0, i;    void	*stream_p;    EXPORT_NO_SYMBOLS;#ifdef DEBUG    if (debug & DBG_REG_DEVS)	printk(	    KERN_INFO	    "dm6430hr_register_device(io=%#x irq=%d,%d dma=%d,%d)\n",	    device_p->io,	    device_p->irq[0],	    device_p->irq[1],	    device_p->dma[0],	    device_p->dma[1]	);#endif    if ((device_p->flags & INITIALIZED) || !device_p->io)	return 0;    /*     * Allocate memory for streaming read buffer.  Maximum size is 2048 bytes     * because it can hold 1024 8-bit samples or 1024 16-bit samples.  Get the     * memory while no spinlock is held.     */    stream_p = kmalloc(2048, GFP_KERNEL);    if (stream_p == NULL) {	return -ENOMEM;    }    spin_lock(&device_p->lock);    if (request_region(device_p->io, DM6430HR_IO_EXTENT, name) == NULL) {	printk(	    KERN_ERR "Unable get IO port range %#x-%#x: resource busy\n",	    device_p->io,	    (device_p->io + DM6430HR_IO_EXTENT - 1)	);	spin_unlock(&device_p->lock);	kfree(stream_p);	return -EBUSY;    }    if (dm6430hr_detect(device_p) == 0) {	printk(KERN_ERR "No dm6430 device found at %#x\n", device_p->io);	release_region(device_p->io, DM6430HR_IO_EXTENT); 	spin_unlock(&device_p->lock);	kfree(stream_p);	return -ENXIO;    }    for (i = 0; i < DM6430HR_IRQS; i++) {	if (	    device_p->irq[i]	    &&	    (		rc		=		request_irq(		    device_p->irq[i],		    (isr_handler) dm6430hr_interrupt,		    0,		    name,		    device_p		)	    )	) {	    printk(		KERN_ERR		"dm6430hr: unable to get IRQ %#x (error = %d)\n",		device_p->irq[i],		-rc	    );	    while (--i >= 0) {		if (device_p->irq[i]) {		    free_irq(device_p->irq[i], device_p);		}	    }	    release_region(device_p->io, DM6430HR_IO_EXTENT);	    spin_unlock(&device_p->lock);	    kfree(stream_p);	    return rc;	}    }    for (i = 0; i < DM6430HR_DMAS; i++) {	if (device_p->dma[i] && (rc = request_dma(device_p->dma[i], name))) {	    printk(		KERN_ERR		"dm6430hr: unable to get DMA channel %#x (error = %d)\n",		device_p->dma[i],		-rc	    );	    while (--i >= 0) {		if (device_p->dma[i]) {		    free_dma(device_p->dma[i]);		}	    }	    i = 2;	    while (--i >= 0) {		if (device_p->irq[i]) {		    free_irq(device_p->irq[i], device_p);		}	    }	    release_region(device_p->io, DM6430HR_IO_EXTENT);	    spin_unlock(&device_p->lock);	    kfree(stream_p);	    return -EBUSY;	}    }    printk(	KERN_INFO	"dm6430hr device successfully registered at io=%#x, "	"irq=%d,%d dma=%d,%d\n",	device_p->io,	device_p->irq[0],	device_p->irq[1],	device_p->dma[0],	device_p->dma[1]    );    DM6430HR_Initdev(device_p);    device_p->flags |= INITIALIZED;    device_p->stream_buff_p = stream_p;    spin_unlock(&device_p->lock);    return rc;}#ifdef MODULEstatic unsigned short io[DM6430HR_MAX_DEVS];static int irq1[DM6430HR_MAX_DEVS];static int irq2[DM6430HR_MAX_DEVS];static int dma1[DM6430HR_MAX_DEVS];static int dma2[DM6430HR_MAX_DEVS];MODULE_AUTHOR(DRIVER_COPYRIGHT);MODULE_DESCRIPTION(DRIVER_DESCRIPTION);MODULE_SUPPORTED_DEVICE(DRIVER_NAME);MODULE_PARM(force, "i" );MODULE_PARM_DESC(force, "allocate resources on driver load");MODULE_PARM(buflength, "i");MODULE_PARM_DESC(buflength, "DMA buffer length");MODULE_PARM(io, "1-" __MODULE_STRING(DM6430HR_MAX_DEVS) "h");MODULE_PARM_DESC(io, "I/O port base address");MODULE_PARM(irq1, "1-" __MODULE_STRING(DM6430HR_MAX_DEVS) "i");MODULE_PARM_DESC(irq1, "IRQ line #1");MODULE_PARM(irq2, "1-" __MODULE_STRING(DM6430HR_MAX_DEVS) "i");MODULE_PARM_DESC(irq2, "IRQ line #2");MODULE_PARM(dma1, "1-" __MODULE_STRING(DM6430HR_MAX_DEVS) "i");MODULE_PARM_DESC(dma1, "DMA channel #1");MODULE_PARM(dma2, "1-" __MODULE_STRING(DM6430HR_MAX_DEVS) "i");MODULE_PARM_DESC(dma2, "DMA channel #2");#ifdef DEBUGMODULE_PARM(debug , "i");MODULE_PARM_DESC(debug  , "Debug level, bits field");#endif/******************************************************************************validate_irq()    Purpose:        Determine if an IRQ number given on the insmod command line is valid        for our purposes.  Called from init_module() only.    Parameters:        irq_num => IRQ number to validate.    Return Value:        0            Success or irq_num is 0.        EINVAL            irq_num is not valid.*******************************************************************************/static intvalidate_irq(int irq_num) {    /* Acceptable irq, first is IRQ3 */    static int	irqs[] = {3, 0, 5, 0, 0, 0, 9, 10, 11, 12, 0, 0, 15};    if (irq_num == 0) {	return 0;    }    if ((irq_num < 3) || (irq_num > 15) || !irqs[irq_num - 3]) {	printk(KERN_ERR "Invalid dm6430 device IRQ %u\n", irq_num);	return -EINVAL;    }    return 0;}/******************************************************************************validate_dma()    Purpose:        Determine if a DMA channel number given on the insmod command line is        valid for our purposes.  Called from init_module() only.    Parameters:        dma_channel => DMA channel number to validate.    Return Value:        0            Success or dma_channel is 0.        EINVAL            dma_channel is not valid.*******************************************************************************/static intvalidate_dma_channel(int dma_channel) {    if (dma_channel == 0) {	return 0;    }    if ((dma_channel < 5) || (dma_channel > 7)) {	printk(KERN_ERR "Invalid dm6430 device DMA channel %u\n", dma_channel);	return -EINVAL;    }    return 0;}intinit_module(void) {    int	device_num;    int	rc;    int	device_present = 0;#ifdef DEBUG    if (debug & DBG_LOAD)	printk(KERN_INFO "dm6430hr init_module()\n");#endif    /*     * Validate base I/O addresses, IRQs, and DMA channels before making any     * changes.  This makes it easier to keep the driver in a consistent state     * in case something goes wrong.     */    for (device_num = 0; device_num < DM6430HR_MAX_DEVS; device_num++) {	unsigned short		io_addr;	/*	 * No base I/O address means no device present	 */	io_addr = io[device_num];	if (!io_addr)	    continue;	device_present = 1;	/*	 * Validate base I/O address	 */	if ((io_addr < 0x200) || (io_addr > 0x3E0) || (io_addr & 0xF)) {	    printk(		KERN_ERR "Invalid dm6430 device base I/O address 0x%04x\n",		io_addr	    );	    return -EINVAL;	}	/*	 * Validate IRQ numbers	 */	rc = validate_irq(irq1[device_num]);	if (rc != 0) {	    return rc;	}	rc = validate_irq(irq2[device_num]);	if (rc != 0) {	    return rc;	}	/*	 * Validate DMA channels	 */	rc = validate_dma_channel(dma1[device_num]);	if (rc != 0) {	    return rc;	}	rc = validate_dma_channel(dma2[device_num]);	if (rc != 0) {	    return rc;	}    }    if (device_present == 0) {	printk(KERN_ERR "No DM6430 devices configured.\n");	return -ENODEV;    }    /*     * We've done as much validation as possible, now reserve a character major     * number     */    rc = register_chrdev(major, name, &driver_fops);    if (rc < 0) {	printk(	    KERN_ERR	    "Major %u character device registration failed, errno = %d\n",	    major,	    -rc	);	return rc;    }    /*     * rc contains character device major number from register_chrdev(), so     * save it for use when device is unregistered     */    major = rc;#ifdef DEBUG    if (debug & DBG_LOAD)	printk(KERN_INFO "Registered dm6430 device with major %d\n", major);#endif    /*     * Set up the device structure for each possible board and register each     * device     */    for (device_num = 0; device_num < DM6430HR_MAX_DEVS; device_num++) {	struct Dm6430hrDevice	*device_p = &devices[device_num];	atomic_set(&device_p->counter, 0);	device_p->lock = SPIN_LOCK_UNLOCKED;	device_p->io = io[device_num];	device_p->irq[0] = irq1[device_num];	device_p->irq[1] = irq2[device_num];	device_p->dma[0] = dma1[device_num];	device_p->dma[1] = dma2[device_num];	device_p->stream_buff_p = NULL;	if (force) {	    rc = dm6430hr_register_device(device_p);	    if (rc != 0) {		/*		 * Registration of current device failed, so completely		 * clean up by unregistering any device successfully registered		 * so far and unreserving the character major number		 */		printk(		    KERN_ERR		    "dm6430 device #%d registration failed.\n",		    device_num		);		while (--device_num > 0) {		    (void) dm6430hr_unregister_device(&devices[device_num]);		}		unregister_chrdev(major, name);		return rc;	    }	}    }#ifdef DEBUG    if (debug & DBG_LOAD)	printk(KERN_INFO "dm6430hr init_module() done\n");#endif    return 0;}voidcleanup_module(void) {    int	devno;#ifdef DEBUG    if (debug & DBG_LOAD)	printk(KERN_INFO "dm6430hr cleanup_module()\n");#endif    unregister_chrdev(major, name);    for (devno = 0; devno < DM6430HR_MAX_DEVS; devno++)	dm6430hr_unregister_device(&devices[devno]);#ifdef DEBUG    if (debug & DBG_LOAD)	printk(KERN_INFO "dm6430hr cleanup_module() done\n");#endif}#endif /* MODULE */

⌨️ 快捷键说明

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