zoukankan      html  css  js  c++  java
  • 第2课第1节_Android灯光系统_led_class驱动


    2. Linux的led class驱动
    android-5.0.2hardwarelibhardwareincludehardwarelights.h


    怎么写驱动:
    a1. 分配led_classdev
    a2. 设置 :
    led_cdev->max_brightness
    led_cdev->brightness_set
    led_cdev->flags
    led_cdev->brightness
    led_cdev->name

    驱动放入Linux内核:

    v1:
    放入内核 drivers/char
    修改 drivers/char/Makefile,添加:
    obj-y += leds_4412.o
    
    重新编译内核
    
    v2:
    把 leds_4412.c 放到drivers/leds
    修改 drivers/leds/Makefile:
    obj-y += leds_4412.o
    
    重新配置内核
    make menuconfig
    
    CONFIG_LEDS_CLASS
    CONFIG_LEDS_TRIGGERS
    CONFIG_LEDS_TRIGGER_TIMER
    
    -> Device Drivers
      -> LED Support
       [*]   LED Class Support    
       [*]   LED Trigger support
       <*>   LED Timer Trigger
       
    重新编译内核
    make zImage
    开发板从SD卡启动,烧写zImage

     


    echo 255 > /sys/class/leds/led1/brightness
    cat /sys/class/leds/led1/brightness
    cat /sys/class/leds/led1/max_brightness

    闪烁
    echo timer > /sys/class/leds/led1/trigger
    echo 100 > /sys/class/leds/led1/delay_on
    echo 200 > /sys/class/leds/led1/delay_off

    关闭
    echo 0 > /sys/class/leds/led1/delay_on

    echo 0 > /sys/class/leds/led1/brightness

    分析闪烁功能:
    echo timer > /sys/class/leds/led1/trigger // timer对应 ledtrig-timer.c

    led_trigger_store // 1. 从trigger_list找出名为"timer"的trigger
    list_for_each_entry(trig, &trigger_list, next_trig) {
    if (!strcmp(trigger_name, trig->name)) {
    // 2. 调用
    led_trigger_set(led_cdev, trig);
    // 3. 把trigger放入led_classdev的trig_list链表里
    list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs);
    led_cdev->trigger = trigger;
    // 4.
    trigger->activate(led_cdev);
    // 5. 对于"timer"
    timer_trig_activate
    // 6. 创建2个文件: delay_on, delay_off
    device_create_file
    device_create_file
    led_blink_set // 让LED闪烁
    led_set_software_blink


    }
    }


    echo 100 > /sys/class/leds/led1/delay_on
    led_delay_on_store
    state = simple_strtoul(buf, &after, 10);
    led_blink_set // // 让LED闪烁
    led_cdev->blink_delay_on = state;

    echo 200 > /sys/class/leds/led1/delay_off
    led_delay_off_store
    state = simple_strtoul(buf, &after, 10);
    led_blink_set // 让LED闪烁
    led_cdev->blink_delay_off = state;

     

     leds_4412.c

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/miscdevice.h>
    #include <linux/device.h>
    #include <linux/fs.h>
    #include <linux/types.h>
    #include <linux/moduleparam.h>
    #include <linux/slab.h>
    #include <linux/ioctl.h>
    #include <linux/cdev.h>
    #include <linux/delay.h>
     
    #include <linux/gpio.h>
    #include <mach/gpio.h>
    #include <plat/gpio-cfg.h>
    
    #include <linux/leds.h>
    
    struct led_desc {
        int gpio;
        char *name;
    };
    
    static struct led_desc led_gpios[] = {
        {EXYNOS4212_GPM4(0), "led1"},
        {EXYNOS4212_GPM4(1), "led2"},
        {EXYNOS4212_GPM4(2), "led3"},
        {EXYNOS4212_GPM4(3), "led4"},
    };
    
    struct led_classdev_4412 {
        struct led_classdev cdev;
        int gpio;
    };
    
    
    static struct led_classdev_4412 *led_devs;
    static void     brightness_set_4412(struct led_classdev *led_cdev,
                  enum led_brightness brightness)
    {
        struct led_classdev_4412 *dev = (struct led_classdev_4412 *)led_cdev;
    
        led_cdev->brightness = brightness;
    
        if (brightness != LED_OFF)
            gpio_set_value(dev->gpio, 0);
        else
            gpio_set_value(dev->gpio, 1);
    }
    
    
    static int leds_init(void)
    {
        int i;
        int ret;
        
        /* 1. alloc led_classdev */
        led_devs = kzalloc(sizeof(struct led_classdev_4412) * sizeof(led_gpios)/sizeof(led_gpios[0]), GFP_KERNEL);
        if (led_devs == NULL) {
            printk("No memory for device
    ");
            return -ENOMEM;
        }
        
        for (i = 0; i < sizeof(led_gpios)/sizeof(led_gpios[0]); i++)
        {
    
            s3c_gpio_cfgpin(led_gpios[i].gpio, S3C_GPIO_OUTPUT);
            gpio_set_value(led_gpios[i].gpio, 1);
    
            /* 2. set */
            led_devs[i].cdev.max_brightness = LED_FULL;   //LED_FULL=255
            led_devs[i].cdev.brightness_set = brightness_set_4412;
            led_devs[i].cdev.flags = LED_CORE_SUSPENDRESUME;
            led_devs[i].cdev.brightness = LED_OFF;
            led_devs[i].cdev.name = led_gpios[i].name;
            //led_devs[i].cdev.default_trigger = "timer";
            led_devs[i].gpio = led_gpios[i].gpio;
    
            /* 3. led_classdev_register */
            ret = led_classdev_register(NULL, &led_devs[i].cdev);
            if (ret) {
                i--;
                while (i >= 0) {
                    led_classdev_unregister(&led_devs[i].cdev);
                    i--;
                }
                kfree(led_devs);
                return -EIO;
            }
        }
        
        return 0;
    }
    
    static void leds_exit(void)
    {
        int i;
        for (i = 0; i < sizeof(led_gpios)/sizeof(led_gpios[0]); i++)
        {
            led_classdev_unregister(&led_devs[i].cdev);
        }
        kfree(led_devs);
    }
    
    module_init(leds_init);
    module_exit(leds_exit);
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("www.100ask.net");
  • 相关阅读:
    TPLINK TLWR710N设置详解
    hehe.....
    AS3写FTP登录过程
    QQ
    网页设计标准尺寸:
    女孩,你愿意做他的第几个女朋友
    監聽一個變量的值變化
    dispatchEvent
    10
    C#常用代码
  • 原文地址:https://www.cnblogs.com/zhulinhaibao/p/7065507.html
Copyright © 2011-2022 走看看