CPU:RK3288

系统:Android 5.1

功能:上层 app 控制 led 亮灭

开发板:Firefly RK3288

1、在dts文件中增加 led 设备

path:kernel/arch/arm/boot/dts/firefly-rk3288.dts

firefly-led{
//匹配内容
compatible = "firefly,led";
//led引脚及有效电平
led-work = <&gpio8 GPIO_A2 GPIO_ACTIVE_LOW>;
status = "okay";
};

2、led 驱动

path:kernel/drivers/firefly/leds.c

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/miscdevice.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h> #define DEBUG #ifdef DEBUG
#define LED_DBG(fmt,arg...) do{\
printk("<LED-DEBUG> [%d]"fmt"\n", __LINE__, ##arg);\
}while()
#else
#define LED_DBG(fmt,arg...)
#endif struct led_data {
int work_pin; //led引脚
int work_status; //led状态
int work_enable; //led使能电平
}; struct led_data *led_info; static int led_drv_open(struct inode *inode, struct file *filp)
{
LED_DBG("--%s()--", __func__);
return ;
} static int led_drv_release(struct inode *inode, struct file *filp)
{
LED_DBG("--%s()--", __func__);
return ;
} static ssize_t led_drv_read(struct file *filp, char __user *buf, size_t len, loff_t *pos)
{
int ret; LED_DBG("--%s()--", __func__);
ret = copy_to_user(buf, &(led_info->work_status), len);
if(ret > )
{
LED_DBG("copy to user failed.");
return ret;
} return len;
} static ssize_t led_drv_write(struct file *filp, const char __user *buf, size_t len, loff_t *pos)
{
int on;
int ret; LED_DBG("--%s()--", __func__);
ret = copy_from_user(&on, buf, len);
if(ret > )
{
LED_DBG("copy from user failed.");
return ret;
} gpio_direction_output(led_info->work_pin, !on);
led_info->work_status = on; return ret;
} //上层没添加此函数api
static long led_drv_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
LED_DBG("--%s()--", __func__);
return ;
} struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = led_drv_open,
.release = led_drv_release,
.write = led_drv_write,
.read = led_drv_read,
.unlocked_ioctl = led_drv_ioctl,
}; //注册为杂项设备
struct miscdevice led_dev =
{
.minor = MISC_DYNAMIC_MINOR,
.fops = &led_fops,
.name = "firefly_leds",
}; static int led_drv_probe(struct platform_device *pdev)
{
int ret = -;
enum of_gpio_flags work_flags;
struct device_node *led_node = pdev->dev.of_node; LED_DBG("--%s()--", __func__); led_info = kzalloc(sizeof(struct led_data), GFP_KERNEL);
if(led_info == NULL)
{
LED_DBG("Alloc GFP_KERNEL memory failed.");
return -ENOMEM;
} //从dts中获取led的引脚,和有效电平
led_info->work_pin = of_get_named_gpio_flags(led_node, "led-work", , &work_flags);
if(!gpio_is_valid(led_info->work_pin))
{
LED_DBG("Work pin is invaild.");
ret = -ENODEV;
goto dev_fail;
} led_info->work_enable = (work_flags == OF_GPIO_ACTIVE_LOW) ? : ; ret = gpio_request(led_info->work_pin, "work_led");
if(ret < )
{
LED_DBG("Work led request failed.");
goto dev_fail;
} gpio_direction_output(led_info->work_pin, !(led_info->work_enable));
led_info->work_status = ; misc_register(&led_dev); return ; request_fail:
gpio_free(led_info->work_pin);
dev_fail:
kfree(led_info); return ret;
} static int led_drv_remove(struct platform_device *pdev)
{
misc_deregister(&led_dev);
LED_DBG("--%s()--", __func__);
gpio_free(led_info->work_pin);
kfree(led_info);
} int led_drv_suspend(struct device *dev)
{
LED_DBG("--%s()--", __func__);
return ;
} int led_drv_resume(struct device *dev)
{
LED_DBG("--%s()--", __func__);
return ;
} //suspend和resume暂时没调试成功
const struct dev_pm_ops led_pm_ops = {
.suspend = led_drv_suspend,
.resume = led_drv_resume,
}; static const struct of_device_id of_gpio_leds_match[] = {
{.compatible = "firefly,led", },
{},
}; static struct platform_driver led_drv = {
.probe = led_drv_probe,
.remove = led_drv_remove,
.driver = {
.name = "leds",
.owner = THIS_MODULE,
.pm = &led_pm_ops,
.of_match_table = of_match_ptr(of_gpio_leds_match),
},
}; module_platform_driver(led_drv); MODULE_LICENSE("GPL");
MODULE_AUTHOR("AaronLee");

3、Makefile

path:kernel/drivers/firefly/Makefile

obj-$(CONFIG_FIREFLY_RK3288_LEDS)                += leds.o

4.Kconfig

path:kernel/drivers/firefly/Kconfig

menu "Firefly Device Options"

config FIREFLY_RK3288_LEDS
bool "select firefly rk3288 leds"
default y endmenu

5、defconfig文件中增加led

path:kernel/arch/arm/configs/firefly-rk3288_defconfig

CONFIG_FIREFLY_RK3288_LEDS=y

6、修改led节点的权限

path:device/rockchip/common/ueventd.rockchip.rc

/dev/firefly_leds            system        system

Android 从上层到底层-----hal层

Android 从上层到底层-----jni层

Android 从上层到底层-----app层

最新文章

  1. [WCF编程]4.契约概述
  2. linux学习笔记2-linux的常用命令
  3. ASP.NET MVC过滤器中权限过滤器ValidateAntiForgeryToken的用法(Post-Only)
  4. Windows Azure Web Site (16) Azure Web Site HTTPS
  5. MySQL: LEAVE Statement
  6. ExtJs布局之border
  7. git some cookies
  8. Socket小结
  9. 初识前端HTML
  10. 安装 Kali Linux 后需要做的 20 件事
  11. RSA密码系统 基于大数环境编写 密码学课程设计
  12. js与android webview交互
  13. Servlet--HttpServletRequest接口,HttpServletResponse接口
  14. UNIX网络编程——信号驱动式I/O
  15. MyBatis返回map数据
  16. 2 Class类
  17. log4j修改SMTPAppender支持ssl
  18. js 变量声明 (var使用与不使用的区别)
  19. fullPage的使用
  20. 如何区分USB 2.0 和USB 3.0插口

热门文章

  1. Date类型
  2. python使用tkinter做界面之颜色
  3. Ansible 开发调试 之【模块调试】
  4. 2016年度,这40项IT技能年薪轻松超过10万美元
  5. Server.Transfer 页面之间传值
  6. Ti IPNC Web网页之ActiveX控件
  7. SQL语句中各个部分的执行顺序(转)
  8. New Concept English there (2)Typing speed exercise
  9. tableView 三级展开 嵌入collocationView
  10. OPEN(SAP) UI5 学习入门系列之三:MVC (下) - 视图与控制器