Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3310157
  • 博文数量: 754
  • 博客积分: 10132
  • 博客等级: 上将
  • 技术积分: 7780
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-14 23:36
文章分类

全部博文(754)

文章存档

2012年(3)

2011年(39)

2010年(66)

2009年(167)

2008年(479)

我的朋友

分类: LINUX

2009-03-18 11:05:27

/*********************************************
*  *GEC2410-BOX
*  *date: created at 2007-09-18 by baibj
*  led驱动
*********************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef MYDEBUG
#include
#include
#include
#include
#endif
#define DEVICE_NAME "led"  //驱动名
#define LEDRAW_MINOR 1      //子设备号
#define CMD_OFF  0  //关led命令
#define CMD_ON  1  //开led命令

static int ledMajor = 0;
static int ledMinor = 0;
//led驱动结构
struct led_dev{
 struct cdev cdev ;
 char data[1] ;
};
static struct led_dev *myled ;
module_param(ledMajor,int,S_IRUGO) ;
MODULE_LICENSE("Dual BSD/GPL") ;
void __exit led_driver_exit(void) ;
void s3c2410_led_gpio_init(void)
{
  __raw_writel((__raw_readl(S3C2410_GPFCON)|0xFF00)&0xFFFF55FF,S3C2410_GPFCON) ;
  __raw_writel(__raw_readl(S3C2410_GPFUP)|0xF0,S3C2410_GPFUP);
  __raw_writel((__raw_readl(S3C2410_GPFDAT)|0xF0)&0xAF,S3C2410_GPFDAT);
}
void s3c2410_led_light(char c)
{
  __raw_writel((__raw_readl(S3C2410_GPFDAT)|0xF0)&(c|0xF),S3C2410_GPFDAT) ;
}
int s3c2410_led_open(struct inode *inode, struct file *filp)
{
 //GPE11,GPE12---output
 //__raw_writel(__raw_readl(S3C2410_GPECON) & (~(0x0f<<22)) | (0x05<<22), S3C2410_GPECON);
 //__raw_writel(__raw_readl(S3C2410_GPEDAT) | (0x03<<11), S3C2410_GPEDAT);    //output--H
 struct led_dev *dev ;
 printk(KERN_INFO DEVICE_NAME ": opened.\n");
 dev=container_of(inode->i_cdev,struct led_dev,cdev) ;
 filp->private_data=dev;
 return 0;
}
int s3c2410_led_ioctl(struct inode *inode, struct file *file,
       unsigned int cmd, unsigned long arg)
{
 int ret=0 ;
 int v=0 ;
 struct led_dev *dev=(struct led_dev*)file->private_data ;
 switch(cmd){
   case CMD_OFF:
  v=0 ;
  dev->data[0]=__raw_readl(S3C2410_GPFDAT)&~(1<  break ;
   case CMD_ON :
  v=1 ;
  dev->data[0]=__raw_readl(S3C2410_GPFDAT)|(1<  break ;
   default:
  printk(KERN_INFO" command %d is not support!\n",cmd) ;
  return -EFAULT ;
  break ;
 }
 s3c2410_led_light(dev->data[0]) ;
 return 0 ;
}
ssize_t s3c2410_led_read(struct file *filp,char __user *buf,size_t count,
 loff_t *f_pos)
{
  ssize_t retval = 0 ;
  struct led_dev *dev=(struct led_dev*)filp->private_data ;
  if(copy_to_user(buf,(void*)(dev->data),count))
 return -EFAULT ;
  return retval ;
}
ssize_t s3c2410_led_write(struct file *filp,const char __user *buf,size_t count,
 loff_t *f_pos)
{
  ssize_t retval = 0 ;
  struct led_dev *dev=filp->private_data ;
  if(copy_from_user((void*)(dev->data),buf,count))
 return -EFAULT ;
  s3c2410_led_light(dev->data[0]) ;
  return retval ;
}
int s3c2410_led_release(struct inode *inode, struct file *filp)
{
 printk(KERN_INFO DEVICE_NAME ": released.\n");
 return 0;
}
struct file_operations s3c2410_fops = {
 owner: THIS_MODULE,
 open: s3c2410_led_open,
 ioctl: s3c2410_led_ioctl,
 release: s3c2410_led_release,
 read: s3c2410_led_read ,
 write: s3c2410_led_write,
};
int led_setup_cdev(struct led_dev *dev,int index)
{
 int err,devno=MKDEV(ledMajor,ledMinor) ;
 cdev_init(&dev->cdev,&s3c2410_fops) ;
 dev->cdev.owner = THIS_MODULE ;
 err = cdev_add(&dev->cdev,devno,1) ;
 if(err)
  printk(KERN_INFO"Error:add cdev fail:%d\n",err) ;
 return err ;
}
int __init led_driver_init(void)
{
 int ret;
 dev_t dev = 0 ;
 if(ledMajor){
  dev=MKDEV(ledMajor,ledMinor) ;
  ret=register_chrdev_region(dev,1,DEVICE_NAME) ;
 }else{
  ret=alloc_chrdev_region(&dev,ledMinor,1,DEVICE_NAME) ;
  ledMajor=MAJOR(dev) ;
 }
 if(ret<0){
  printk(KERN_INFO DEVICE_NAME " can't get major number\n") ;
  return ret ;
 }
 myled=kmalloc(sizeof (struct led_dev),GFP_KERNEL) ;
 if(!myled){
  ret =-ENOMEM ;
  goto fail ;
 }
 memset(myled,0,sizeof(struct led_dev)) ;
 led_setup_cdev(myled,0) ;
 s3c2410_led_gpio_init() ;
 return 0  ;
 fail:
 led_driver_exit() ;
 return ret ;
}

void __exit led_driver_exit(void)
{
 dev_t devno=MKDEV(ledMajor,ledMinor) ;
 cdev_del(&myled->cdev) ;
 kfree(myled) ;
 unregister_chrdev_region(devno,1) ;
}
//模块加载
module_init(led_driver_init);
//模块卸载
module_exit(led_driver_exit);
 
阅读(1372) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~