/*
* Copyright (c) 2009-~ Lan Peng
*
* This source code is released for free distribution under the terms of the
* GNU General Public License
*
* Author: Lan Peng
* Created Time: 2009年09月23日 星期三 17时11分37秒
* File Name: led.c
*
* Description:
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#define GPO_5_SET (*(volatile unsigned int __force *)0xf4028004)
#define GPO_5_CLR (*(volatile unsigned int __force *)0xf4028008)
#define GPO_5 (1<<5)
#define DEV_NAME "cdevled"
#define IO_SET 1
#define IO_CLR 0
#define LED_MAJOR 2000
static int lan_led_open(struct inode *inode, struct file *file);
static int lan_led_release(struct inode *inode, struct file *file);
static ssize_t lan_led_write(struct file *file, const char __user *buff, ssize_t count, loff_t *ppos);
static ssize_t lan_led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
static struct file_operations lan_led_fops = {
.owner = THIS_MODULE,
.write = lan_led_write,
.ioctl = lan_led_ioctl,
.open = lan_led_open,
.release = lan_led_release,
};
static int lan_led_open(struct inode *inode, struct file *file)
{
printk("Open......\n");
try_module_get(THIS_MODULE);
GPO_5_SET |= GPO_5;
return 0;
}
static int lan_led_release(struct inode *inode, struct file *file)
{
printk("Release......\n");
module_put(THIS_MODULE);
return 0;
}
static ssize_t lan_led_write(struct file *file, const char __user *buff, ssize_t count, loff_t *ppos)
{
char ctrl;
get_user(ctrl, (unsigned char *)buff);
if(ctrl == '0')
GPO_5_CLR |= GPO_5;
else if(ctrl == '1')
GPO_5_SET |= GPO_5;
return count;
}
static ssize_t lan_led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
return 0;
}
static int led_start(void *p)
{
char i;
p = p;
for(i = 0; i < 10; i++){
GPO_5_CLR |= GPO_5;
mdelay(500);
GPO_5_SET |= GPO_5;
mdelay(500);
}
return 0;
}
static int __init led_init(void)
{
int ret;
printk("Hello, led cdev!\n");
ret = register_chrdev(LED_MAJOR, DEV_NAME, &lan_led_fops);
if(ret < 0){
printk("Cannot register led\n");
return ret;
}
kernel_thread(led_start, NULL, CLONE_KERNEL);
return 0;
}
static void __exit led_exit(void)
{
printk("Bye bye...\n");
unregister_chrdev(LED_MAJOR, DEV_NAME);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("LAN");
|