LED驱动案例分析

【注】引脚可能会复用。

1,基础硬件原理:

就是通过配置GPIO(GPH0),把相应的GPIO设置成高电平或者低电平,达到电灯的目的。

2,驱动代码:

#include <linux/fs .h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/module .h>
#include <asm/uaccess .h>
#include <nach/map.h>

#include <rach/ regs-gpio .h>
#include <plat/gpio-cfg.h>

#define DEVICE_ NAME "qt210_ leds"

#define DEVICE_ COUNT 1

#define QT210_ LEDS_ MAJOR 0

#define QT210_ LEDS_ MINOR 234

#define PARAM SIZE 3

static unsigned char mem[4];  //保存4个LEDS的状态
static int major = QT210_LEDS_MAJOR;

static int minor = QT210_LEDS_MINOR;

static dev_t dev_ number; //设备号

static int leds_state = l;

static char *params[] = ("stringl", "string2", "string3");
static int param_size = PARAM_SIZE;

static struct class *leds_class = NULL;

static long qt210_leds_ioctl(struct file *filp, unsigned int cmd,unsigned long arg)
{

        switch (cmd)
    {
        case 0:

        case 1:

        if (arg » 3)

        {

            return -EINAL;

        if (cmd == 1)

        {

            gpio_set_ value (55PV210_ _GPH0(arg), 1);

        }
        else
        {
            gpio_ set_ value(S5PV210 GPH0(arg), 0);
        }
        return 0;

        default:

        return -EINVAL;
    }
}

static ssize_t qt210_leds_write(struct file *file, const char _user *buf,size_ t count, loff_t *ppos)
{

unsigned tmp - count;
unsigned long i =0;
memset(mem, e, 4);

if(count>4)
{
tmp = 4;
}
if (copy_from_user(mem, buf, tmp))
{
return -EFAULT;
}
else
{
    for(i=0;i<4;i++)
    {
        if (mem[i] == '1')
        {
            gpio_set_value(S5PV210_ GPH0(i), 1);
        }
        else
        {
            gpio_set_value(S5PV216_ GPH0(i), 0);
        }
    }
    return count;
}
}


static struct file_operations dev_fops =

{
 .owner = THIS MODULE,
 .unlocked_ioctl = qt210_leds_ioctl,
 .write = qt210_leds_write 
};

static struct cdev leds_cdev;

//创建设备文件 (/dev/qt210_ leds )

static int leds_create_device(void)
{
int ret = 0;
int err = 0;

//初始化cdev的成员,并建立cdev和file_operations之间的连接
cdev_init(&leds_cdev, &dev_fops);

leds_cdev .owner = THIS_MOOULE;

if (major > 0)
{
    
    //获取设备号和此设备号)
    dev_number = MKDEV(major, minor);

    err = register_chrdev_region(dev_number, DEVICE_COUNT, DEVICE_NAME);
    if (err < 0)
    {
        printk(KERN_ WIARNING "register. chrdev_ region() failed,n");return err;
        return err;
    }
    
    else
    {

        err = alloc_chrdev_region(&leds_cdev.dev, 10, DEVICE_COUNT,DEVICE_NAME);

        if (err < 0)

        {

            printk(KERN_WARNING "alloc_chrdev_ region() failed\n");
            return err;
        }

        major = MAJOR(leds_cdev.dev);
        minor = MINOR(leds_cdev.dev);
        //dev_ number = MKDEV(major, minor);
        dev_number = leds_cdev.dev;
    }

    ret = cdev_add(&leds_cdev, dev_number, DEVICE_COUNT);
    leds_class = class_create(THIS_MODULE, DEVICE_NAME);
    device_create(leds_class, NULL, dev_number, NULL, DEVICE_NAME);
    return ret;
    
}


static int leds_init_gpm(int leds_default)
{

int err;

int i;

err = gpio_request(S5PV210_GPH0(0), "LED0");
if (err)
{
    printk(KERN_ERR "failed to request GPH0(Ѳ) for "" LED0\n");
    return err;
}
err = gpio_request(S5PV210_GPH0(1), "LED1");
if (err)
{
    printk(KERN_ ERR "failed to request GPH0(1) for " "LED1\n");
    return err;
}
err = gpio_request(S5PV210_GPH0(2), "LED2");
if (err)
{
    printk(KERN_ERR "failed to request GPH0(2) for " "LED2\n");
    return err;
}
err = gpio_request(SSPV210_GPH0(3), “LED3");
if (err)
{
    printk(KERN_ERR "failed to request GPH0(3) for " "LED3\n");
    return err;
}

for(i=0;i<4;i++)
{
    gpio_direction_output(S5PV210_GPH0(i), 1);
    gpio_set_value(S5PV210_GPH0(i), leds_default);
    return 0;
}
}


// 初始化LED驱动

static int leds_ init(void)
{

int ret;

ret = leds_create_device();

Leds_init_gpm(~leds_state);

printk(DEVICE_NAME"\tinitializedk\n");

printk("param0\t%s\n",params[0]);
printk("paraml\t%s\n",params[1]);
printk("param2\t%s\n",params[2]);

return ret;
}


static void leds_destroy_device(void)
{

    device_destroy(leds_class, dev_number);

    if (leds_class)
    {
    class_destroy(leds_class);
    }
    unregister_chrdev_region(dev_number, DEVICE_COUNT);
    return;

}

static void leds_exit(void)
{
    int i;
    leds_destroy_device();
    for(i=0;i<4;i++)
    {
        gpio_free(S5PV210_GPH0(i));
        printk(DEVICE_NAME"texit!\n");
    }
}
    module_init(leds_init);
    module_exit(leds_exit);

    module_param(leds_state, int, S_IRUGO|S_IWUSR);
    module_param_array(params, charp, &param_size, S_IRUGO|S_TWUSR);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("HCJ");

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值