📄 can_sja1000_dev.c
字号:
/*
****************************************Copyright (c)**************************************************
** 广州致远电子有限公司
** CAN开发组
** http://www.zyinside.com
**
**
**--------------File Info-------------------------------------------------------------------------------
** File name: can_sja1000-dev.c
** Last modified Date: 2006-02-16
** Last Version: V1.0
** Descriptions: can_sja1000-dev.c, S3C2410 SJA1000 CAN 控制器设备驱动程序
** can_sja1000-dev.c, S3C2410 SJA1000 CAN-bus controller driver
**------------------------------------------------------------------------------------------------------
** Created by: 滕欣欣 Xingxing Teng
** Created date: 2006-02-16
** Version: V1.0
** Descriptions: 初始版本 The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by: Chenxibing
** Modified date: 2007-03-05
** Version: V1.1
** Descriptions: For MagicARM270 Linux 2.6.18
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "config.h"
#include "print_DEBUG.h"
#define SJA_ALE_PADR 0x14000008 //SJA1000锁存器端口物理地址
#define SJA_DAT_PADR 0x14000004 //SJA1000数据端口物理地址
#define SJA_SRC_LEN 0x04 //SJA1000数据长度,4字节
static int major = CAN_MAJOR_NR;
stcSJA1000_BufInfo SJA1000_RxBuf;
void *sja1000_ale;
void *sja1000_dat;
static DECLARE_WAIT_QUEUE_HEAD(can_wait);
EXPORT_SYMBOL(sja1000_ale);
EXPORT_SYMBOL(sja1000_dat);
static int can_init(void);
static void can_cleanup(void);
static int can_open(struct inode *p_inode, struct file *p_file);
static int can_release(struct inode *p_inode, struct file *p_flie);
static ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos);
static ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos);
static int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param);
static void can_interrupt(int irq , void* dev_id, struct pt_regs *regs);
MODULE_DESCRIPTION("Guangzhou Zhiyuan Electronic Co.,LTD.\ngraduate school\nhttp://www.embedtools.com");
MODULE_SUPPORTED_DEVICE("Linux 2.6.18 & MagicARM270");
MODULE_AUTHOR("Chenxibing");
#define MAJOR_NR major
struct file_operations sja1000_can_fops =
{
.owner = THIS_MODULE,
.ioctl = can_ioctl,
.open = can_open,
.write = can_write,
.read = can_read,
.release = can_release,
};
/*
********************************************************************************************************************
**函数原型 : int can_open(struct inode *p_inode, struct file *p_file)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
int can_open(struct inode *p_inode, struct file *p_file)
{
if(TRUE != SJA1000Init(PELI_CAN,BTR_1000K,0x00000000,0xFFFFFFFF))
{
printk("<0>SJA1000 Init Error!\n");
return -ENODEV;
}
try_module_get(THIS_MODULE);
printk("<0>" DEVICE_NAME " Opened!\n");
return(0);
}
/*
********************************************************************************************************************
**函数原型 : int can_release(struct inode *p_inode, struct file *p_flie)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
int can_release(struct inode *p_inode, struct file *p_flie)
{
module_put(THIS_MODULE);
printk("MagicARM270 SJA1000_CAN released!\n");
return(0);
}
/*
********************************************************************************************************************
**函数原型 : ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos)
{
interruptible_sleep_on(&can_wait);
if(count != sizeof(stcSJA1000_BufInfo))
{
return (-EINVAL);
}
if(copy_to_user(p_buf,(void*)(&SJA1000_RxBuf),sizeof(stcSJA1000_BufInfo)))
{
printk("Copy to usr Error!\n");
return -EFAULT;
}
return(sizeof(SJA1000_RxBuf));
}
/*
********************************************************************************************************************
**函数原型 : ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos)
{
stcSJA1000_BufInfo TxBuf;
if(count != sizeof(stcSJA1000_BufInfo))
{
printk("count = %d not %d\n",count,sizeof(stcSJA1000_BufInfo));
return (-EINVAL);
}
if(copy_from_user((void*)&TxBuf,(void*)p_buf,sizeof(stcSJA1000_BufInfo)))
{
printk("copy_from_user Error!\n");
return -EFAULT;
}
SetTxBuf(&TxBuf);
SetCommand(CMR_NOM_SD);
return(sizeof(SJA1000_RxBuf));
}
/*
********************************************************************************************************************
**函数原型 : int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param)
{
int val = 0;
switch(cmd)
{
case IOCTL_BAUD:
SJA_SoftRst(TRUE);
if(TRUE != SetBaudRate((uint16)param))
{
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
case IOCTL_ACR:
SJA_SoftRst(TRUE);
if(TRUE != ACRCode(param))
{
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
case IOCTL_AMR:
SJA_SoftRst(TRUE);
if(TRUE != AMRCode(param))
{
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
default:
val = -ENOTTY;
break;
}
return(val);
}
/*
********************************************************************************************************************
**函数原型 : int can_init(void)
**参数说明 : NULL
**返回值 : 返回赋值表示调用出错
**说 明 : CAN驱动的初始化函数函数
********************************************************************************************************************
*/
int can_init(void)
{
int i,result;
int bak,tmp;
PDEBUG("CAll init_module.\n");
MSC2 = 0xFFFF7FF8; //BANK5 NOR Flash
bak = MSC2;
//映射IO
sja1000_dat = ioremap(SJA_DAT_PADR,SJA_SRC_LEN);
sja1000_ale = ioremap(SJA_ALE_PADR,SJA_SRC_LEN);
//测试硬件连接
for (i=0 ; i<0x8; i++)
{
iowrite8(0x09,sja1000_ale);
iowrite8(1<<i,sja1000_dat);
iowrite8(0x09,sja1000_ale);
if(ioread8(sja1000_dat) != 1<<i)
{
printk("Abing : read tmp = %d\n", ioread8(sja1000_dat));
iounmap(sja1000_ale);
iounmap(sja1000_dat);
printk("SJA1000 Hardware Connection Error!!");
return -ENODEV;
}
}
//中断初始化
pxa_gpio_mode(1 | GPIO_IN);
if (request_irq(IRQ_GPIO(1), can_interrupt, IRQF_DISABLED|IRQF_TRIGGER_FALLING, "MagicARM270 Can", NULL))
printk(KERN_WARNING "mgc270can: Can't get SJA1000_CAN IRQ: %d!\n", IRQ_GPIO(1));
//注册设备
result = register_chrdev(MAJOR_NR, DEVICE_NAME, &sja1000_can_fops);
if (result < 0)
{
printk("<0>" DEVICE_NAME ": Unable to get major %d\n", MAJOR_NR );
return(result);
}
if (MAJOR_NR == 0)
{
MAJOR_NR = result; /* dynamic */
}
printk(KERN_INFO DEVICE_NAME ": init OK\n");
return(0);
}
/*
********************************************************************************************************************
**函数原型 : void can_cleanup(void)
**参数说明 : NULL
**返回值 : NULL
**说 明 : CAN驱动的清除函数
********************************************************************************************************************
*/
void can_cleanup(void)
{
PDEBUG("CAll cleanup_module.\n");
printk("Unloading MagicARM270 CAN Device Controller Driver\n");
//关闭CAN设备控制器
if(TRUE != SJA_SoftRst(TRUE))
{
printk("<0>" "SJA_SoftRst Failed!.\n");
}
//取消IO映射
iounmap(sja1000_ale);
iounmap(sja1000_dat);
free_irq(IRQ_GPIO(1),NULL);
//注销设备
unregister_chrdev(MAJOR_NR, DEVICE_NAME);
}
void can_interrupt(int irq , void* dev_id, struct pt_regs *regs)
{
IntEnty();
wake_up_interruptible(&can_wait);
}
module_init(can_init);
module_exit(can_cleanup);
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -