Android燈光系統 框架分析 , Linux的led class驅動

 

 

 

 

 

 

root@android-virtual-machine:/sys/class/leds# cd /
root@android-virtual-machine:/# find ./ -name 'leds_4412*'
./work/linux-3.0.86/drivers/char/leds_4412.o
./work/linux-3.0.86/drivers/char/leds_4412.c
root@android-virtual-machine:/# 

#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"},
        {EXYNOS4212_GPM4(3),"led4"},
};

//struct led_classdev_4412 {
//    struct led_classdev cdev;
//    int gpio;
//};

    struct led_classdev_4412 {
        struct led_classdev cdev;
        int gpio;
    }

//static  struct led_classdev_4412 *led_devs;
  static  struct led_classdev_4412 *led_devs;

//static void     brightness_set_4412(struct led_classdev *led_cdev,
        //      enum led_brightness brightness)
        
        static struct brightness_set_4412 (struct led_classdev *led_cdev,
          enum led_brightness brightness
        ) 
{
    //struct led_classdev_4412 *dev = (struct led_classdev_4412 *)led_cdev;
    //struct led_classdev_4412 *dev = (struct led_classdev_4412 *)led_cdev;
    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);
        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);
    
    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\n");
        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_devs[i].cdev.brightness_set = brightness_set_4412;
        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");

把 leds_4412.c 放到drivers/leds
修改 drivers/leds/Makefile:
obj-y += leds_4412.o

make menuconfig


./work/linux-3.0.86/drivers


drivers/leds/leds_4412.c:47:11: error: two or more data types in declaration specifiers
drivers/leds/leds_4412.c:52:38: error: expected identifier or '(' before 'struct'
drivers/leds/leds_4412.c: In function 'leds_init':
drivers/leds/leds_4412.c:95:37: error: 'brightness_set_4412' undeclared (first use in this function)
drivers/leds/leds_4412.c:95:37: note: each undeclared identifier is reported only once for each function it appears in
make[2]: *** [drivers/leds/leds_4412.o] Error 1
make[1]: *** [drivers/leds] Error 2
make: *** [drivers] Error 2
root@android-virtual-machine:/work/linux-3.0.86# 
 

 

 

 

drivers/leds/leds_4412.c:47:11: error: two or more data types in declaration specifiers
drivers/leds/leds_4412.c:52:38: error: expected identifier or '(' before 'struct'
drivers/leds/leds_4412.c: In function 'leds_init':
drivers/leds/leds_4412.c:95:37: error: 'brightness_set_4412' undeclared (first use in this function)
drivers/leds/leds_4412.c:95:37: note: each undeclared identifier is reported only once for each function it appears in
make[2]: *** [drivers/leds/leds_4412.o] Error 1
make[1]: *** [drivers/leds] Error 2
make: *** [drivers] Error 2

  SYSMAP  System.map
  SYSMAP  .tmp_System.map
  OBJCOPY arch/arm/boot/Image
  Kernel: arch/arm/boot/Image is ready
  GZIP    arch/arm/boot/compressed/piggy.gzip
  AS      arch/arm/boot/compressed/piggy.gzip.o
  SHIPPED arch/arm/boot/compressed/lib1funcs.S
  AS      arch/arm/boot/compressed/lib1funcs.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
root@android-virtual-machine:/work/linux-3.0.86# ^C
root@android-virtual-machine:/work/linux-3.0.86# 


bootp  compressed  Image  install.sh  Makefile  zImage
root@android-virtual-machine:/work/linux-3.0.86/arch/arm/boot# 
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章