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

📄 em104_can.c

📁 ARM S3C2410 USB slave 驱动
💻 C
字号:
#include <linux/version.h>#include <linux/module.h>#include <linux/init.h>#include <linux/ioport.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/arch/regs-mem.h>#include "trace.h"#include "sja1000.h"#include "canbus4linux.h"MODULE_LICENSE("GPL");static void em104_sja1000_writereg(void * data, u8 reg, u8 val);static u8 em104_sja1000_readreg(void * data, u8 reg);static int em104_sja1000_register_isr(void * data, sja1000_isr chip_isr, struct sja1000_admin * chip_isr_data);static int em104_sja1000_unregister_isr(void * data);static int em104_sja1000_open(void * data);static int em104_sja1000_close(void * data);struct EM104_SJA1000_CHIP{	unsigned long			addr;	unsigned long			data;	char					name[MAX_DEVICE_NAME_LENGTH];	int						num;	spinlock_t				lock;	int						open;	sja1000_isr				chip_isr;	struct sja1000_admin *	chip_isr_data;};static struct EM104_SJA1000_CHIP chip[2] = {	[0] = {		addr:		(0xE0000000+0x00800000),		data:		(0xE0000000+0x00A00000),		name:		"can0",		num:		-1,		lock:		SPIN_LOCK_UNLOCKED,		open:		0	},	[1] = {		addr:		(0xE0000000+0x00800000),		data:		(0xE0000000+0x00C00000),		name:		"can1",		num:		-1,		lock:		SPIN_LOCK_UNLOCKED,		open:		0			}};static struct sja1000_access access[2] = {	[0] = {		pOpenCanDevice:				em104_sja1000_open,		pCloseCanDevice:			em104_sja1000_close,		pWriteToRegister:			em104_sja1000_writereg,		pReadFromRegister:			em104_sja1000_readreg,		pRegisterIsr:				em104_sja1000_register_isr,		pUnregisterIsr:				em104_sja1000_unregister_isr,		bCanChipsetFlags:			CANBUS_CFS_CAN_2_0_B | CANBUS_CFS_EXT_FRAME,		chipset_frequency:			16000000,		output_control_register:	0x1b	},	[1] = {		pOpenCanDevice:				em104_sja1000_open,		pCloseCanDevice:			em104_sja1000_close,		pWriteToRegister:			em104_sja1000_writereg,		pReadFromRegister:			em104_sja1000_readreg,		pRegisterIsr:				em104_sja1000_register_isr,		pUnregisterIsr:				em104_sja1000_unregister_isr,		bCanChipsetFlags:			CANBUS_CFS_CAN_2_0_B | CANBUS_CFS_EXT_FRAME,		chipset_frequency:			16000000,		output_control_register:	0x1b			}};static void em104_sja1000_writereg(void * data, u8 reg, u8 val){	struct EM104_SJA1000_CHIP * self = (struct EM104_SJA1000_CHIP *) data;	TRACE("writereg(0x%2.2x,0x%2.2x)", reg, val);	outb(reg, self->addr);	outb(val, self->data);}static u8 em104_sja1000_readreg(void * data, u8 reg){		u8 val;	struct EM104_SJA1000_CHIP * self = (struct EM104_SJA1000_CHIP *) data;	outb(reg, self->addr);	val = inb(self->data);	TRACE("readreg(0x%2.2x) = 0x%2.2x", reg, val);	return val;}static int em104_sja1000_register_isr(void * data, sja1000_isr chip_isr, struct sja1000_admin * chip_isr_data){	struct EM104_SJA1000_CHIP * self = (struct EM104_SJA1000_CHIP *) data;	TRACE("register_isr()");	if (!self)		return -EINVAL;	self->chip_isr		= chip_isr;	self->chip_isr_data	= chip_isr_data;	return 0;}static int em104_sja1000_unregister_isr(void * data){	struct EM104_SJA1000_CHIP * self = (struct EM104_SJA1000_CHIP *) data;	TRACE("unregister_isr()");	if (!self)		return -EINVAL;	self->chip_isr		= 0;	self->chip_isr_data	= 0;	return 0;}static int em104_sja1000_open(void * data){	struct EM104_SJA1000_CHIP * self = (struct EM104_SJA1000_CHIP *) data;	int err;	TRACE("open()");	spin_lock(&self->lock);	do {		if (self->open) {			err = -EBUSY;			break;		}		self->open++;		em104_sja1000_writereg(self, 0x1e, 0x00);		// reset, check it!!	} while (0);	spin_unlock(&self->lock);		return 0;}static int em104_sja1000_close(void * data){	TRACE("close()");	return 0;}static irqreturn_t em104_sja1000_isr(int irq, void *dev_id, struct pt_regs *regs){	struct EM104_SJA1000_CHIP * self = (struct EM104_SJA1000_CHIP *) dev_id;		static unsigned char vector;	vector = inb(0xE0000000 + 0x02200000);	if((vector&0x10)==0x00)	{		TRACE("can0 isr()");		if (!self)			return IRQ_NONE;		if (self->chip_isr)			self->chip_isr(self,self->chip_isr_data);	}	else if((vector&0x20)==0x00)	{		TRACE("can1 isr()");		if (!self)			return IRQ_NONE;		if (self->chip_isr)			self->chip_isr(self,self->chip_isr_data);	}	return IRQ_HANDLED;	}int __init em104_sja1000_init(void){	unsigned int bswcon = inl((unsigned int)S3C2410_BWSCON);	bswcon = (bswcon & 0xFFFCFFFF) | 0x00000000;	outl(bswcon,(unsigned int)S3C2410_BWSCON);	bswcon = inl((unsigned int)S3C2410_BWSCON);		outb(~0xFF,0xE0000000+0x02600000);		set_irq_type(IRQ_EINT9,IRQT_FALLING);	if(request_irq(IRQ_EINT9, em104_sja1000_isr, SA_SHIRQ, "can isr", &chip[0]))	{		TRACE("request_irq(%d) failed", IRQ_EINT9);		return -ENOMEM;	}		if(request_irq(IRQ_EINT9, em104_sja1000_isr, SA_SHIRQ, "can isr", &chip[1]))	{		TRACE("request_irq(%d) failed", IRQ_EINT9);		return -ENOMEM;	}		TRACE("registering device %s", chip[0].name);	chip[0].num = sja1000_register_device(chip[0].name, CANBUS4LINUX_VERSION, &chip[0], &access[0], 0, 0);	if (chip[0].num == -1) {		TRACE("can0 sja1000_register_device() failed");		return -ENOMEM;	}	TRACE("registering device %s", chip[1].name);	chip[1].num = sja1000_register_device(chip[1].name, CANBUS4LINUX_VERSION, &chip[1], &access[1], 0, 1);	if (chip[1].num == -1) {		TRACE("can1 sja1000_register_device() failed");		return -ENOMEM;	}		return 0;}void __exit em104_sja1000_cleanup(void){	free_irq(IRQ_EINT9, &chip[0]);}module_init(em104_sja1000_init);module_exit(em104_sja1000_cleanup);MODULE_AUTHOR("JJJ <jiangjj@embedinfo.com>");MODULE_DESCRIPTION("CAN driver for EM104 SJA1000");

⌨️ 快捷键说明

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