📄 swmod.c
字号:
/******************************************************************************
Copyright (c) 2005, Infineon Technologies. All rights reserved.
No Warranty
Because the program is licensed free of charge, there is no warranty for
the program, to the extent permitted by applicable law. Except when
otherwise stated in writing the copyright holders and/or other parties
provide the program "as is" without warranty of any kind, either
expressed or implied, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose. The
entire risk as to the quality and performance of the program is with
you. should the program prove defective, you assume the cost of all
necessary servicing, repair or correction.
In no event unless required by applicable law or agreed to in writing
will any copyright holder, or any other party who may modify and/or
redistribute the program as permitted above, be liable to you for
damages, including any general, special, incidental or consequential
damages arising out of the use or inability to use the program
(including but not limited to loss of data or data being rendered
inaccurate or losses sustained by you or third parties or a failure of
the program to operate with any other programs), even if such holder or
other party has been advised of the possibility of such damages.
******************************************************************************
Module : swmod.c
Date : 2005-06-23
Creator : Bolo Tsai
Description :
Remarks:
*****************************************************************************/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/kmod.h>
#include <linux/delay.h>
#include <asm/io.h>
#include "ifx_swioctl.h"
#include "swfct.h"
#include "ifx_gpio.h"
#include "ifx_swdrv.h"
int adm_open(struct inode *node, struct file *filp)
{
MOD_INC_USE_COUNT;
return 0;
}
ssize_t adm_read(struct file *filep, char *buf, size_t count, loff_t *ppos)
{
return count;
}
ssize_t adm_write(struct file *filep, const char *buf, size_t count, loff_t *ppos)
{
return count;
}
/* close */
int adm_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
return 0;
}
/* IOCTL function */
int adm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args)
{
PREGRW uREGRW;
unsigned int rtval;
unsigned int val = 0xff;
if (_IOC_TYPE(cmd) != ADM_MAGIC)
{
printk("adm_ioctl: IOC_TYPE(%x) != ADM_MAGIC(%x)! \n", _IOC_TYPE(cmd), ADM_MAGIC);
return (-EINVAL);
}
if(_IOC_NR(cmd) >= KEY_IOCTL_MAX_KEY)
{
printk(KERN_WARNING "adm_ioctl: IOC_NR(%x) invalid! \n", _IOC_NR(cmd));
return (-EINVAL);
}
switch (cmd)
{
#ifdef EEPROM
case ADM_SWI_IOC_READEEPROM:
uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL);
rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW));
if (rtval != 0)
{
printk("ADM_SWI_IOC_READEEPROM: copy from user FAILED !\n");
kfree(uREGRW);
return (-EFAULT);
}
ifx_sw_readeep(uREGRW->regAddr, &val);
uREGRW->regVal = val;
copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW));
kfree(uREGRW);
break;
case ADM_SWI_IOC_WRITEEEPROM:
uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL);
rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW));
if (rtval != 0)
{
printk("ADM_SWI_IOC_WRITEEEPROM: copy from user FAILED !\n");
kfree(uREGRW);
return (-EFAULT);
}
ifx_sw_writeep(uREGRW->regAddr, uREGRW->regVal);
kfree(uREGRW);
break;
#endif
case ADM_SWI_IOC_READSMI:
uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL);
rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW));
if (rtval != 0)
{
printk("ADM_SWI_IOC_READSMI: copy from user FAILED !\n");
kfree(uREGRW);
return (-EFAULT);
}
ifx_sw_read(uREGRW->regAddr, &val);
uREGRW->regVal = val;
copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW));
kfree(uREGRW);
break;
case ADM_SWI_IOC_WRITESMI:
uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL);
rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW));
if (rtval != 0)
{
printk("ADM_SWI_IOC_WRITESMI: copy from user FAILED !\n");
kfree(uREGRW);
return (-EFAULT);
}
ifx_sw_write(uREGRW->regAddr, uREGRW->regVal);
kfree(uREGRW);
break;
case ADM_SWI_IOC_INIT:
ifx_sw_init();
break;
case ADM_SWI_IOC_RESET:
ifx_sw_reset();
break;
default:
printk("No such register read/write function ! \n");
return (-EFAULT);
} /* end of switch */
return 0;
}
struct file_operations adm_ops = {
read: adm_read,
write: adm_write,
open: adm_open,
release: adm_release,
ioctl: adm_ioctl
};
int adm_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data)
{
int len = 0;
len += sprintf(buf+len, " ************ Registers ************ \n");
*eof = 1;
return len;
}
int __init init_module(void)
{
printk("Loading ADM6996I/M device driver...\n");
/* if running on adm5120 */
/* set GPIO 0~2 as adm6996 control pins */
outl(0x003f3f00, 0x12000028);
/* enable switch port 5 (MII) as RMII mode (5120MAC <-> 6996MAC) */
outl(0x18a, 0x12000030);
/* group adm5120 port 1 ~ 5 as VLAN0, port 5 & 6(CPU) as VLAN1 */
outl(0x417e, 0x12000040);
/* end adm5120 fixup */
register_chrdev(SWI_MAJOR_DEVICE_NUMBER, SWI_DEVICE_MODULE_NAME, &adm_ops);
/* create proc entries */
// create_proc_read_entry("admide", 0, NULL, admide_proc, NULL);
return 0;
}
void __exit cleanup_module(void)
{
printk("Unloading ADM6996I/M device driver...\n");
unregister_chrdev(SWI_MAJOR_DEVICE_NUMBER, SWI_DEVICE_MODULE_NAME);
/* remove proc entries */
// remove_proc_entry("admide", NULL);
}
MODULE_DESCRIPTION("ADMtek 6996I/M Driver");
MODULE_AUTHOR("Bolo Tsai <bolo.tsai@infineon.com>");
MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -