我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 1487|回复: 0

瑞芯微RK3188 内核心跳灯

[复制链接]

该用户从未签到

11

主题

117

回帖

344

积分

二级逆天

积分
344

社区居民忠实会员终身成就奖

QQ
发表于 2015-3-16 09:54:09 | 显示全部楼层 |阅读模式
  1. /*  //file  -> drivers/leds/leds-gpio.c
  2. * LEDs driver for GPIOs
  3. *  author by jiangdou  qq:344283973
  4. * Copyright (C) 2007 8D Technologies inc.
  5. * Raphael Assenat <raph@8d.com>
  6. * Copyright (C) 2008 Freescale Semiconductor, Inc.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. *
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/init.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/leds.h>
  17. #include <linux/of_platform.h>
  18. #include <linux/of_gpio.h>
  19. #include <linux/slab.h>
  20. #include <linux/workqueue.h>
  21. #include <asm/gpio.h>
  22. //###############add by jiangdou ################
  23. //#define    RK30_PIN1_PA5   197
  24. static struct gpio_led gpio_leds = {
  25.         
  26.                 .name   = "HB_A5",
  27.                 .default_trigger = "heartbeat",
  28.                 .gpio   = RK30_PIN1_PA5,//modify for board LED gpio
  29.                 .active_low = 0,//1,//初始化为0
  30.                 .default_state = LEDS_GPIO_DEFSTATE_OFF,
  31.                
  32. };
  33. static struct gpio_led_platform_data gpio_led_info = {
  34.         .leds           = &gpio_leds,
  35.         .num_leds       = 1,//ARRAY_SIZE(gpio_leds),
  36. };
  37. static struct platform_device leds_gpio = {
  38.         .name   = "leds-gpio",
  39.         .id     = -1,
  40.         .dev    = {
  41.                 .platform_data  = &gpio_led_info,
  42.         },
  43. };
  44. //##################add end#############################
  45. struct gpio_led_data {
  46.     struct led_classdev cdev;
  47.     unsigned gpio;
  48.     struct work_struct work;
  49.     u8 new_level;
  50.     u8 can_sleep;
  51.     u8 active_low;
  52.     u8 blinking;
  53.     int (*platform_gpio_blink_set)(unsigned gpio, int state,
  54.             unsigned long *delay_on, unsigned long *delay_off);
  55. };
  56. static void gpio_led_work(struct work_struct *work)
  57. {
  58.     struct gpio_led_data    *led_dat =
  59.         container_of(work, struct gpio_led_data, work);
  60.     if (led_dat->blinking) {
  61.         led_dat->platform_gpio_blink_set(led_dat->gpio,
  62.                          led_dat->new_level,
  63.                          NULL, NULL);
  64.         led_dat->blinking = 0;
  65.     } else
  66.         gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
  67. }
  68. static void gpio_led_set(struct led_classdev *led_cdev,
  69.     enum led_brightness value)
  70. {
  71.     struct gpio_led_data *led_dat =
  72.         container_of(led_cdev, struct gpio_led_data, cdev);
  73.     int level;
  74.     if (value == LED_OFF)
  75.         level = 0;
  76.     else
  77.         level = 1;
  78.     if (led_dat->active_low)
  79.         level = !level;
  80.     /* Setting GPIOs with I2C/etc requires a task context, and we don't
  81.      * seem to have a reliable way to know if we're already in one; so
  82.      * let's just assume the worst.
  83.      */
  84.     if (led_dat->can_sleep) {
  85.         led_dat->new_level = level;
  86.         schedule_work(&led_dat->work);
  87.     } else {
  88.         if (led_dat->blinking) {
  89.             led_dat->platform_gpio_blink_set(led_dat->gpio, level,
  90.                              NULL, NULL);
  91.             led_dat->blinking = 0;
  92.         } else
  93.             gpio_set_value(led_dat->gpio, level);
  94.     }
  95. }
  96. static int gpio_blink_set(struct led_classdev *led_cdev,
  97.     unsigned long *delay_on, unsigned long *delay_off)
  98. {
  99.     struct gpio_led_data *led_dat =
  100.         container_of(led_cdev, struct gpio_led_data, cdev);
  101.     led_dat->blinking = 1;
  102.     return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK,
  103.                         delay_on, delay_off);
  104. }
  105. static int __devinit create_gpio_led(const struct gpio_led *template,
  106.     struct gpio_led_data *led_dat, struct device *parent,
  107.     int (*blink_set)(unsigned, int, unsigned long *, unsigned long *))
  108. {
  109.     int ret, state;
  110.     led_dat->gpio = -1;
  111.     /* skip leds that aren't available */
  112.     if (!gpio_is_valid(template->gpio)) {
  113.         printk(KERN_INFO "Skipping unavailable LED gpio %d (%s)\n",
  114.                 template->gpio, template->name);
  115.         return 0;
  116.     }
  117.     ret = gpio_request(template->gpio, template->name);
  118.     if (ret < 0)
  119.         return ret;
  120.     led_dat->cdev.name = template->name;
  121.     led_dat->cdev.default_trigger = template->default_trigger;
  122.     led_dat->gpio = template->gpio;
  123.     led_dat->can_sleep = gpio_cansleep(template->gpio);
  124.     led_dat->active_low = template->active_low;
  125.     led_dat->blinking = 0;
  126.     if (blink_set) {
  127.         led_dat->platform_gpio_blink_set = blink_set;
  128.         led_dat->cdev.blink_set = gpio_blink_set;
  129.     }
  130.     led_dat->cdev.brightness_set = gpio_led_set;
  131.     if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP)
  132.         state = !!gpio_get_value(led_dat->gpio) ^ led_dat->active_low;
  133.     else
  134.         state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
  135.     led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
  136.     if (!template->retain_state_suspended)
  137.         led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
  138.     ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
  139.     if (ret < 0)
  140.         goto err;
  141.         
  142.     INIT_WORK(&led_dat->work, gpio_led_work);
  143.     ret = led_classdev_register(parent, &led_dat->cdev);
  144.     if (ret < 0)
  145.         goto err;
  146.     return 0;
  147. err:
  148.     gpio_free(led_dat->gpio);
  149.     return ret;
  150. }
  151. static void delete_gpio_led(struct gpio_led_data *led)
  152. {
  153.     if (!gpio_is_valid(led->gpio))
  154.         return;
  155.     led_classdev_unregister(&led->cdev);
  156.     cancel_work_sync(&led->work);
  157.     gpio_free(led->gpio);
  158. }
  159. struct gpio_leds_priv {
  160.     int num_leds;
  161.     struct gpio_led_data leds[];
  162. };
  163. static inline int sizeof_gpio_leds_priv(int num_leds)
  164. {
  165.     return sizeof(struct gpio_leds_priv) +
  166.         (sizeof(struct gpio_led_data) * num_leds);
  167. }
  168. /* Code to create from OpenFirmware platform devices */
  169. #ifdef CONFIG_LEDS_GPIO_OF
  170. static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev)
  171. {
  172.     struct device_node *np = pdev->dev.of_node, *child;
  173.     struct gpio_leds_priv *priv;
  174.     int count = 0, ret;
  175.     /* count LEDs in this device, so we know how much to allocate */
  176.     for_each_child_of_node(np, child)
  177.         count++;
  178.     if (!count)
  179.         return NULL;
  180.     priv = kzalloc(sizeof_gpio_leds_priv(count), GFP_KERNEL);
  181.     if (!priv)
  182.         return NULL;
  183.     for_each_child_of_node(np, child) {
  184.         struct gpio_led led = {};
  185.         enum of_gpio_flags flags;
  186.         const char *state;
  187.         led.gpio = of_get_gpio_flags(child, 0, &flags);
  188.         led.active_low = flags & OF_GPIO_ACTIVE_LOW;
  189.         led.name = of_get_property(child, "label", NULL) ? : child->name;
  190.         led.default_trigger =
  191.             of_get_property(child, "linux,default-trigger", NULL);
  192.         state = of_get_property(child, "default-state", NULL);
  193.         if (state) {
  194.             if (!strcmp(state, "keep"))
  195.                 led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
  196.             else if (!strcmp(state, "on"))
  197.                 led.default_state = LEDS_GPIO_DEFSTATE_ON;
  198.             else
  199.                 led.default_state = LEDS_GPIO_DEFSTATE_OFF;
  200.         }
  201.         ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
  202.                       &pdev->dev, NULL);
  203.         if (ret < 0) {
  204.             of_node_put(child);
  205.             goto err;
  206.         }
  207.     }
  208.     return priv;
  209. err:
  210.     for (count = priv->num_leds - 2; count >= 0; count--)
  211.         delete_gpio_led(&priv->leds[count]);
  212.     kfree(priv);
  213.     return NULL;
  214. }
  215. static const struct of_device_id of_gpio_leds_match[] = {
  216.     { .compatible = "gpio-leds", },
  217.     {},
  218. };
  219. #else
  220. static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev)
  221. {
  222.     return NULL;
  223. }
  224. #define of_gpio_leds_match NULL
  225. #endif
  226. static int __devinit gpio_led_probe(struct platform_device *pdev)
  227. {
  228.     struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
  229.     struct gpio_leds_priv *priv;
  230.     int i, ret = 0;
  231.     //gpio_led_info;
  232.     if (pdata && pdata->num_leds) {
  233.         priv = kzalloc(sizeof_gpio_leds_priv(pdata->num_leds),
  234.                 GFP_KERNEL);
  235.         if (!priv)
  236.             return -ENOMEM;
  237.         priv->num_leds = pdata->num_leds;
  238.         for (i = 0; i < priv->num_leds; i++) {
  239.             ret = create_gpio_led(&pdata->leds[i],
  240.                           &priv->leds[i],
  241.                           &pdev->dev, pdata->gpio_blink_set);
  242.             if (ret < 0) {
  243.                 /* On failure: unwind the led creations */
  244.                 for (i = i - 1; i >= 0; i--)
  245.                     delete_gpio_led(&priv->leds[i]);
  246.                 kfree(priv);
  247.                 return ret;
  248.             }
  249.         }
  250.     } else {
  251.         priv = gpio_leds_create_of(pdev);
  252.         if (!priv)
  253.             return -ENODEV;
  254.     }
  255.     platform_set_drvdata(pdev, priv);
  256.     return 0;
  257. }
  258. static int __devexit gpio_led_remove(struct platform_device *pdev)
  259. {
  260.     struct gpio_leds_priv *priv = dev_get_drvdata(&pdev->dev);
  261.     int i;
  262.     for (i = 0; i < priv->num_leds; i++)
  263.         delete_gpio_led(&priv->leds[i]);
  264.     dev_set_drvdata(&pdev->dev, NULL);
  265.     kfree(priv);
  266.     return 0;
  267. }
  268. static struct platform_driver gpio_led_driver = {
  269.     .probe        = gpio_led_probe,
  270.     .remove        = __devexit_p(gpio_led_remove),
  271.     .driver        = {
  272.         .name    = "leds-gpio",
  273.         .owner    = THIS_MODULE,
  274.         .of_match_table = of_gpio_leds_match,
  275.     },
  276. };
  277. struct platform_device *pdev;
  278. MODULE_ALIAS("platform:leds-gpio");
  279. static int __init gpio_led_init(void)
  280. {
  281. //**** add by jiangou ******
  282.     int err = 0;
  283.     pdev = platform_device_alloc("leds-gpio", -1);
  284.     if (!pdev)
  285.         return err;
  286.     err = platform_device_add_data(pdev, &gpio_led_info,
  287.                     sizeof(gpio_led_info));
  288.     if (err)
  289.         return err;
  290.     err = platform_device_add(pdev);
  291.     if (err)
  292.         return err;
  293.         
  294. //**** add end by jiangou ******
  295.     return platform_driver_register(&gpio_led_driver);
  296.         
  297. }
  298. static void __exit gpio_led_exit(void)
  299. {
  300.     platform_driver_unregister(&gpio_led_driver);
  301. }
  302. module_init(gpio_led_init);
  303. module_exit(gpio_led_exit);
  304. MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
  305. MODULE_DESCRIPTION("GPIO LED driver");
  306. MODULE_LICENSE("GPL");
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

论坛开启做任务可以
额外奖励金币快速赚
积分升级了


Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

平平安安
TOP
快速回复 返回顶部 返回列表