现在的位置: 首页 > 综合 > 正文

LED灯显示字符驱动程序-linux2.6LED显示驱动

2013年09月10日 ⁄ 综合 ⁄ 共 9179字 ⁄ 字号 评论关闭

/****************************************************************
    Copyright(c) 2009-2010,Newkoom Net Tech.Co,.Ltd
   
    模块名称(Filename):        led_s3c2410.c 
    项目名称(Projectname):        RPM(Remote Power Manager System)
    版本号(Version):         1.0.0
    创建日期(Date):             2009-8-22       
    作者(Author):                ZMF(Zheng meifu)
    功能描述(Description):     led driver for linux2.6.14.1
    其他说明(Others):           
    修改记录(History):   
****************************************************************/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/hardware.h>
#include <linux/devfs_fs_kernel.h>

//#define CONFIG_TARGET_RPM  // 注释掉则led 驱动程序为YL2410开发板。
// 此参数已在内核配置里定义了,此处为调试目的
//定义则为RPM实际目标板

#define DEVICE_NAME "ledrpm"
#define LEDRPM_MAJOR 223

#ifndef CONFIG_TARGET_RPM
#define LEDRPM_NUM  4  //ledrpm num
#else
#define LEDRPM_NUM  6  //ledrpm num
#endif
#define LEDRPM_ON  0
#define LEDRPM_OFF  1
#define LEDRPM_DELAYMS(X)  (HZ/(1000/(X)))
//#define LEDRPM_DEBUG
#ifdef LEDRPM_DEBUG
#define PRINTK(arg...)  printk(arg)
#else
#define PRINTK(arg...)  do{}while(0)
#endif
typedef unsigned int LEDRPM_RET;
struct ledrpm_dev_t{
     struct cdev cdev; 
 struct timer_list timer;
 #ifdef CONFIG_DEVFS_FS
 int  devfs;
 #endif
};
struct ledrpm_info{
    unsigned int pin;//gpio port
    unsigned int pin_setting;
    int ledrpm_code;//ledrpm value
};
static dev_t ledrpm_major=LEDRPM_MAJOR;
struct ledrpm_dev_t ledrpm_dev;
static const struct ledrpm_info ledrpm_info_tab[] = {
#ifndef CONFIG_TARGET_RPM
 { S3C2410_GPF4,S3C2410_GPF4_OUTP,LEDRPM_ON},   
 {   S3C2410_GPF5,S3C2410_GPF5_OUTP,LEDRPM_OFF},   
 {     S3C2410_GPF6,S3C2410_GPF6_OUTP,LEDRPM_ON},   
 {     S3C2410_GPF7,S3C2410_GPF7_OUTP,LEDRPM_OFF},   
#else
 { S3C2410_GPD0,S3C2410_GPD0_OUTP,LEDRPM_ON},   
 {   S3C2410_GPD1,S3C2410_GPD1_OUTP,LEDRPM_ON},   
 {     S3C2410_GPD2,S3C2410_GPD2_OUTP,LEDRPM_ON},   
 {     S3C2410_GPD3,S3C2410_GPD3_OUTP,LEDRPM_ON},   
 { S3C2410_GPD4,S3C2410_GPD4_OUTP,LEDRPM_ON},   
 {   S3C2410_GPD5,S3C2410_GPD5_OUTP,LEDRPM_ON},   
#endif
};
#ifndef CONFIG_TARGET_RPM
#define GPIO_LEDPOWER       (S3C2410_GPB0)
#define GPIO_LEDPOWER_INP       (S3C2410_GPB0_INP)
#define GPIO_LEDPOWER_OUTP      (S3C2410_GPB0_OUTP)
#define GPIO_LED01        (S3C2410_GPF4)
#define GPIO_LED01IN  (S3C2410_GPF4_INP)
#define GPIO_LED01OU  (S3C2410_GPF4_OUTP)
#define GPIO_LED02       (S3C2410_GPF5)
#define GPIO_LED02IN  (S3C2410_GPF5_INP)
#define GPIO_LED02OU  (S3C2410_GPF5_OUTP)
#define GPIO_LED03       (S3C2410_GPF6)
#define GPIO_LED03IN  (S3C2410_GPF6_INP)
#define GPIO_LED03OU  (S3C2410_GPF6_OUTP)
#define GPIO_LED04       (S3C2410_GPF7)
#define GPIO_LED04IN  (S3C2410_GPF7_INP)
#define GPIO_LED04OU  (S3C2410_GPF7_OUTP)
#define GPIO_LED05       (S3C2410_GPB0)
#define GPIO_LED05IN  (S3C2410_GPB0_INP)
#define GPIO_LED05OU  (S3C2410_GPB0_OUTP)
#define GPIO_LED06       (S3C2410_GPB0)
#define GPIO_LED06IN  (S3C2410_GPB0_INP)
#define GPIO_LED06OU  (S3C2410_GPB0_OUTP)

#else
#define GPIO_LEDPOWER       (S3C2410_GPG10)
#define GPIO_LEDPOWER_INP       (S3C2410_GPG10_INP)
#define GPIO_LEDPOWER_OUTP      (S3C2410_GPG10_OUTP)
#define GPIO_LED01        (S3C2410_GPD0)
#define GPIO_LED01IN  (S3C2410_GPD0_INP)
#define GPIO_LED01OU  (S3C2410_GPD0_OUTP)
#define GPIO_LED02       (S3C2410_GPD1)
#define GPIO_LED02IN  (S3C2410_GPD1_INP)
#define GPIO_LED02OU  (S3C2410_GPD1_OUTP)
#define GPIO_LED03       (S3C2410_GPD2)
#define GPIO_LED03IN  (S3C2410_GPD2_INP)
#define GPIO_LED03OU  (S3C2410_GPD2_OUTP)
#define GPIO_LED04       (S3C2410_GPD3)
#define GPIO_LED04IN  (S3C2410_GPD3_INP)
#define GPIO_LED04OU  (S3C2410_GPD3_OUTP)
#define GPIO_LED05       (S3C2410_GPD4)
#define GPIO_LED05IN  (S3C2410_GPD4_INP)
#define GPIO_LED05OU  (S3C2410_GPD4_OUTP)
#define GPIO_LED06       (S3C2410_GPD5)
#define GPIO_LED06IN  (S3C2410_GPD5_INP)
#define GPIO_LED06OU  (S3C2410_GPD5_OUTP)
#endif
static void ledrpm_timer_handler(unsigned long data);
static int ledrpm_control(u32 command, u8 data);
static int ledrpm_open(struct inode *inode, struct file *filp);
static int ledrpm_release(struct inode *inode, struct file *filp);
static ssize_t ledrpm_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
static ssize_t ledrpm_read(struct file *file,char __user *buffer, size_t count, loff_t *ppos);
static int  ledrpm_ioctl(struct inode *inode, struct file *filp, unsigned int command, unsigned long arg);

static const struct file_operations ledrpm_fops ={
    .owner = THIS_MODULE,
    .read  = ledrpm_read,
    .write = ledrpm_write,
    .open  = ledrpm_open,
    .release = ledrpm_release,
    .ioctl = ledrpm_ioctl,
};
static int ledrpm_control(u32 command, u8 data){
 int err = 0;
 if(command==0x01) { // write
  switch(data) {
   case 0x01:  s3c2410_gpio_setpin(GPIO_LED01, LEDRPM_ON);  break;
   case 0x81: s3c2410_gpio_setpin(GPIO_LED01, LEDRPM_OFF); break;
   case 0x02: s3c2410_gpio_setpin(GPIO_LED02, LEDRPM_ON);  break;
   case 0x82: s3c2410_gpio_setpin(GPIO_LED02, LEDRPM_OFF); break;
   case 0x03: s3c2410_gpio_setpin(GPIO_LED03, LEDRPM_ON);  break;
   case 0x83: s3c2410_gpio_setpin(GPIO_LED03, LEDRPM_OFF); break;
   case 0x04: s3c2410_gpio_setpin(GPIO_LED04, LEDRPM_ON);  break;
   case 0x84: s3c2410_gpio_setpin(GPIO_LED04, LEDRPM_OFF); break;
   case 0x05: s3c2410_gpio_setpin(GPIO_LED05, LEDRPM_ON);  break;
   case 0x85: s3c2410_gpio_setpin(GPIO_LED05, LEDRPM_OFF); break;
   case 0x06: s3c2410_gpio_setpin(GPIO_LED06, LEDRPM_ON);  break;
   case 0x86: s3c2410_gpio_setpin(GPIO_LED06, LEDRPM_OFF); break;
   default:  err = -1;  break;
  }
 }else if(command==0x00) { // read
  switch(data) {
   case 0x01: err=s3c2410_gpio_getpin(GPIO_LED01);   break;
   case 0x02: err=s3c2410_gpio_getpin(GPIO_LED02);   break;
   case 0x03: err=s3c2410_gpio_getpin(GPIO_LED03);   break;
   case 0x04: err=s3c2410_gpio_getpin(GPIO_LED04); break;
   case 0x05: err=s3c2410_gpio_getpin(GPIO_LED05); break;
   case 0x06: err=s3c2410_gpio_getpin(GPIO_LED06); break;
   default:  err = -1;  break;
  }
 }
 return err;
}
static int ledrpm_open(struct inode *inode, struct file *filp){
    filp->private_data = &ledrpm_dev;
    PRINTK(KERN_NOTICE "ledrpm opened/n");
    return 0;
}
static int ledrpm_release(struct inode *inode, struct file *filp){
    PRINTK(KERN_NOTICE "ledrpm released/n");
    return 0;
}
// 写参数为:count要写的灯数量,ppos为从第几个灯(小于灯数)开始写,
// buffer:要写的灯的数据:01-06亮81-86灭
static ssize_t ledrpm_write(struct file *filp, const char __user *buffer, size_t count, loff_t *ppos){
    u8 ledrpm_ret[LEDRPM_NUM];
 int ri;
 if (count>LEDRPM_NUM)
  return -1;
 copy_from_user(ledrpm_ret, buffer, count);
 PRINTK(KERN_NOTICE "ledrpm write data count:%d/n",count);
 for(ri=0; ri<count; ri++){
  if(ledrpm_control(1, ledrpm_ret[ri])==-1)
   return -1;
 }
        return count;
}
// 读函数带入参数: count:为读灯个数,要为LEDRPM_NUM;   buffer:读回数据
//         ppos:为从第一个灯算起第几个灯开始读。要为0。
static ssize_t ledrpm_read(struct file *filp,char __user *buffer, size_t count, loff_t *ppos){
    u8 ledrpm_ret[LEDRPM_NUM];
 int ri,rj;
 if (count>LEDRPM_NUM)
  return -1;
 for(ri=0; ri<count; ri++){
  rj=ledrpm_control(0, ri+1);
  if (rj==-1) return -1;
  ledrpm_ret[ri]=(rj ? 1: 0);
 }
        copy_to_user(buffer,(char*)&ledrpm_ret,count);
 PRINTK(KERN_NOTICE "ledrpm read data count:%d/n",count);
        return count;
}
static int  ledrpm_ioctl(struct inode *inode, struct file *filp, unsigned int command, unsigned long arg){
 return ledrpm_control(arg, command);
}
static void ledrpm_timer_handler(unsigned long data){
 mod_timer(&ledrpm_dev.timer, jiffies+ LEDRPM_DELAYMS(500));
 s3c2410_gpio_setpin(GPIO_LEDPOWER, (s3c2410_gpio_getpin(GPIO_LEDPOWER))?0:1);
}
static void ledrpm_init_config(void)
{
 int result;
 for (result=0; result<LEDRPM_NUM; result++){
  s3c2410_gpio_cfgpin(ledrpm_info_tab[result].pin, ledrpm_info_tab[result].pin_setting);
  s3c2410_gpio_setpin(ledrpm_info_tab[result].pin, ledrpm_info_tab[result].ledrpm_code);
 }
 s3c2410_gpio_cfgpin(GPIO_LEDPOWER, GPIO_LEDPOWER_OUTP);
 init_timer(&ledrpm_dev.timer);
 ledrpm_dev.timer.expires = jiffies + LEDRPM_DELAYMS(500);
 ledrpm_dev.timer.function = ledrpm_timer_handler;
        ledrpm_dev.timer.data = 0x00;
 add_timer(&ledrpm_dev.timer);
}

static int __init ledrpm_init(void)
{
 int result,err;
 dev_t devno = MKDEV(ledrpm_major,0);
 if (ledrpm_major)    {
  result = register_chrdev_region(devno, 1, DEVICE_NAME);
 }else    {
  result = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);
  ledrpm_major = MAJOR(devno);
 }
 if (result < 0)    {
  printk("ledrpm can't get major number:%d/n",result);
  return result;
 }
 devno = MKDEV(ledrpm_major,0);
 cdev_init((struct cdev *)&(ledrpm_dev.cdev),(struct file_operations *)&ledrpm_fops);
 ledrpm_dev.cdev.owner = THIS_MODULE;
 ledrpm_dev.cdev.ops = (struct file_operations *)&ledrpm_fops;
 err = cdev_add(&ledrpm_dev.cdev, devno, 1);
 if (err) {
  printk(KERN_NOTICE "Error %d adding ledrpm fail",err);       
  return -1;
 }
 ledrpm_init_config();
#ifdef CONFIG_DEVFS_FS
 devfs_mk_cdev(MKDEV(ledrpm_major, 0), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, DEVICE_NAME);

 ledrpm_dev.devfs = devfs_register_tape(DEVICE_NAME);
#endif
 printk(KERN_NOTICE "/dev/ledrpm inited: newkoom company:zhengmeifu@sina.com/n");
 return 0;
}
static void __exit ledrpm_exit(void)
{
 cdev_del(&ledrpm_dev.cdev);
 unregister_chrdev_region(MKDEV(ledrpm_major,0),1);
#ifdef CONFIG_DEVFS_FS
 devfs_remove(DEVICE_NAME);
 devfs_unregister_tape(ledrpm_dev.devfs);
#endif
 del_timer(&ledrpm_dev.timer);
}

module_init(ledrpm_init);
module_exit(ledrpm_exit);

MODULE_AUTHOR("zhengmeifu@sina.com");
MODULE_DESCRIPTION("RPM or (yls3c2410 devlp board) led driver");
MODULE_LICENSE("Dual BSD/GPL");

抱歉!评论已关闭.