文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Mini2440 LED灯驱动模块一

Mini2440 LED灯驱动模块一

时间:2009-03-25  来源:niutao.linux

本模块是基于s3c2440 ARM开发板编写的,功能是控制开发板上的4个led灯,可以单个点亮或者熄灭,也可以全体点亮或者熄灭,内核模块代码如下:
led.h

#ifndef _LED_H
#define _LED_H

#define LED1 5
#define LED2 6
#define LED3 7
#define LED4 8

#define LED_CTRL_ON 0
#define LED_CTRL_OFF 1
#define LEDS_CTRL_ON 2
#define LEDS_CTRL_OFF 3
#endif

mini2440_niutao_led.c

#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<asm/io.h>
#include <asm/system.h>
#include<asm/uaccess.h>
#include <asm/arch/regs-gpio.h>
#include "led.h"

#define LED_NUM 4
#define LED_ON 0
#define LED_OFF (!LED_ON)
#define IS_LEDS(led) ((led) >= LED1 && (led) <= LED4)
#define IS_CTRL(cmd) ((cmd) >= LED_CTRL_ON && (cmd) <= LEDS_CTRL_OFF)

#define LED_MAJOR 212 /*预设的led的主设备号*/

#define led_print(num) printk("%s = 0x%x\n", #num, num)
#define led_printk() printk(KERN_INFO"func %s line = %d\n", __FUNCTION__, __LINE__)

static int led_major = LED_MAJOR;
struct led_dev {
    struct cdev cdev;
    struct semaphore sem;
};
struct led_dev *led_devp;
static unsigned int led_port[LED_NUM] = {
    S3C2410_GPB5,
    S3C2410_GPB6,
    S3C2410_GPB7,
    S3C2410_GPB8
};
static unsigned int led_out[LED_NUM] = {
    S3C2410_GPB5_OUTP,
    S3C2410_GPB6_OUTP,
    S3C2410_GPB7_OUTP,
    S3C2410_GPB8_OUTP
};
int led_open(struct inode *inode,struct file *filp)
{
    int i;

    for (i = 0; i < LED_NUM; i++)
        s3c2410_gpio_cfgpin(led_port[i], led_out[i]);
    for (i = 0; i < LED_NUM; i++)
        s3c2410_gpio_setpin(led_port[i], LED_OFF);
    filp->private_data = led_devp;
    printk(KERN_INFO"led open driver\n");
    return 0;
}

int led_release(struct inode *inode,struct file *filp)
{
    int i;

    for (i = 0; i < LED_NUM; i++)
        s3c2410_gpio_setpin(led_port[i], LED_ON);
    filp->private_data = NULL;
    return 0;
}

static int led_ioctl(struct inode *inodep,struct file *filp, unsigned int cmd,unsigned long arg)
{
    struct led_dev *dev = filp->private_data;
    int i;
    printk(KERN_INFO"cmd = %d arg = %ld\n", cmd, arg);
    if (!IS_CTRL(cmd))
        return -1;
    down(&dev->sem);
    switch (cmd) {
    case LED_CTRL_ON:
    case LED_CTRL_OFF:
        if (!IS_LEDS(arg))
            return -1;
        s3c2410_gpio_setpin(led_port[arg - 5], cmd);
        for (i = 0; i < LED_NUM; i++)
            if (i != arg - 5)
                s3c2410_gpio_setpin(led_port[i], !cmd);
        break;
    case LEDS_CTRL_ON:
        for (i = 0; i < LED_NUM; i++)
            s3c2410_gpio_setpin(led_port[i], LED_ON);
        break;
    case LEDS_CTRL_OFF:
        for (i = 0; i < LED_NUM; i++)
            s3c2410_gpio_setpin(led_port[i], LED_OFF);
        break;
    }
    up(&dev->sem);
    return 0;
}

static ssize_t led_read(struct file *filp,char __user *buf, size_t size,loff_t *ppos)
{
    struct led_dev *dev =filp->private_data;
    char tmp[4];
    int i;
    down(&dev->sem);
    for (i = 0; i < LED_NUM; i++)
        tmp[i] = s3c2410_gpio_getpin(led_port[i]);
    up(&dev->sem);
    if (copy_to_user(buf, (void *)tmp, 4))
        return -EFAULT;
    return 4;
}

static ssize_t led_write(struct file *filp,const char __user *buf, size_t size,loff_t *ppos)
{
    struct led_dev *dev = filp->private_data;
    char tmp[5];
    int i;

    if (copy_from_user(tmp, buf, 5))
        return -EFAULT;
    down(&dev->sem);
    for (i = 0; i < LED_NUM; i++)
        s3c2410_gpio_setpin(led_port[i], !!(int)(tmp[i] - '0'));
    up(&dev->sem);
    return size;
}

static struct file_operations led_fops = {
    .owner = THIS_MODULE,
    .read = led_read,
    .write = led_write,
    .ioctl = led_ioctl,
    .open = led_open,
    .release = led_release
};

static void led_setup_cdev(struct led_dev *dev,int index)
{
    int err,devno = MKDEV(led_major,index);

    cdev_init(&dev->cdev,&led_fops);
    dev->cdev.owner = led_fops.owner;
    err = cdev_add(&dev->cdev,devno,1);
    if (err)
        printk(KERN_NOTICE"Error %d adding LED %d\n",err,index);
}

int led_init(void)
{
    int result;
    dev_t devno = MKDEV(led_major,0);
    led_printk();
    if (led_major)
        result = register_chrdev_region(devno,1,"led");
    else {
        result = alloc_chrdev_region(&devno,0,1,"led");
        led_major = MAJOR(devno);
    }
    if(result < 0)
        return result;
    led_devp=kmalloc(sizeof(struct led_dev),GFP_KERNEL);
    if(!led_devp)
    {
        result=-ENOMEM;
        goto fail_malloc;
    }
    memset(led_devp ,0,sizeof(struct led_dev));
    led_setup_cdev(led_devp,0);
    init_MUTEX(&led_devp->sem);
    led_printk();
    return 0;
fail_malloc:
    unregister_chrdev_region(devno,1);
    return result;
}

void led_exit(void)
{
    cdev_del(&led_devp->cdev);
    kfree(led_devp);
    unregister_chrdev_region(MKDEV(led_major,0),1);
    led_printk();
}

MODULE_AUTHOR("Niu Tao");
MODULE_LICENSE("Dual BSD/GPL");

module_param(led_major,int,S_IRUGO);

module_init(led_init);
module_exit(led_exit);

相关阅读 更多 +
排行榜 更多 +
日更计划漫画

日更计划漫画

浏览阅读 下载
浮生忆玲珑

浮生忆玲珑

角色扮演 下载
摩托追击

摩托追击

赛车竞速 下载