📄 led_module.c
字号:
/***********************************************************************
* www.csugds.cn
***********************************************************************/
#include <linux/kernel.h> /* */
#include <linux/module.h> /* Specifically, a module */
#include <linux/init.h> /* for __initfunc */
#include <asm/uaccess.h> /* for put_user */
#include <asm/io.h> /* for ioremap */
#include <asm/arch/hardware.h> /* atmel RM9200 */
#include <asm/arch/pio.h>
#define DEBUG 1
#ifdef DEBUG
# define debugk(fmt,args...) printk(fmt ,##args)
#else
# define debugk(fmt,args...)
#endif
#if CONFIG_MODVERSIONS==1
/* # define MODVERSIONS */
# include <linux/modversions.h>
#endif
MODULE_LICENSE("GPL");
/*
* For character devices
*/
#include <linux/fs.h> /* character device definitions */
#include <linux/wrapper.h> /* wrapper for compatibility with future versions */
#ifndef KERNEL_VERSION
# define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif
#define SUCCESS 0
#define LED_MAJOR 43 /* 定义主设备号 */
/* 根据板子的具体情况设置 */
#define SYS_LED AT91C_PIO_PB0
#define ACT_LED AT91C_PIO_PB1
#define TEL_LED AT91C_PIO_PB2
#define PCM_LED AT91C_PIO_PB3
#define DEVICE_NAME "sys_led"
AT91PS_SYS va_sys = (AT91PS_SYS) AT91C_VA_BASE_SYS;
static int Device_Open = 0;
static int __init led_init (void );
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
struct file_operations led_ops =
{
read: device_read,
write: device_write,
open: device_open,
release: device_release,
};
static int Major;
static int __init led_init(void)
{
va_sys -> PMC_PCER = (1 << AT91C_ID_PIOB);
va_sys -> PIOB_PER = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
va_sys -> PIOB_OER = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
va_sys -> PIOB_PPUDR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
va_sys -> PIOB_OWDR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
va_sys -> PIOB_CODR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
Major = register_chrdev (LED_MAJOR, DEVICE_NAME, &led_ops);
/* Negative values signify an error */
if (Major < 0)
{
printk ("SYS_LED init_module: failed with %d\n", Major);
return Major;
}
Major = LED_MAJOR;
debugk ("SYS_LED registred: major = %d\n", Major);
return 0;
}
static int device_open (struct inode *inode, struct file *file)
{
debugk ("device_open(%p,%p)\n", inode, file);
debugk ("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);
if (Device_Open)
{
return -EBUSY;
}
Device_Open++;
MOD_INC_USE_COUNT;
return SUCCESS;
}
static int device_release (struct inode *inode, struct file *file)
{
debugk ("device_release(%p,%p)\n", inode, file);
Device_Open--;
MOD_DEC_USE_COUNT;
va_sys -> PIOB_SODR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
return 0;
}
static ssize_t device_read (struct file *file,
char *buffer, /* The buffer to fill with data */
size_t length, /* The length of the buffer */
loff_t * offset) /* Our offset in the file */
{
unsigned int i;
i = va_sys -> PIOB_ODSR;
i &= SYS_LED;
i &= ACT_LED;
i &= TEL_LED;
i &= PCM_LED;
copy_to_user (buffer, (void *) &i, 4);
debugk ("Read: value = 0x%08X\n", i);
return (4); /* read() always returns exactly 4 bytes */
}
static ssize_t device_write (struct file *file,
const char *buffer, /* buffer */
size_t length, /* length of buffer */
loff_t * offset) /* offset in the file */
{
int i;
int err;
if(length > 4)
return -9;
err = copy_from_user ( (void *) &i, buffer, length);
if (i=0xffffffff)
{
va_sys -> PIOB_SODR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
}
else
{
va_sys -> PIOB_CODR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
}
debugk ("Write: value = 0x%08X\n", i);
return (length);
}
/******************************
**** Module Declarations *****
**************************** */
#ifdef MODULE
static void __exit cleanup_led_module (void)
{
int ret;
ret = unregister_chrdev (Major, DEVICE_NAME);
if (ret < 0) {
printk ("unregister_chrdev: error %d\n", ret);
}
}
module_init(led_init);
module_exit(cleanup_led_module);
MODULE_AUTHOR("Wang longfeng");
MODULE_DESCRIPTION("led driver for AT9200");
#endif /* MODULE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -