x6818开发板安卓驱动开发(1)-LED-driver
x6818开发板安卓驱动开发(1)-LED-driver
redstone5 发表于7个月前
x6818开发板安卓驱动开发(1)-LED-driver
  • 发表于 7个月前
  • 阅读 17
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

通过sysfs,即kobject实现LED灯的控制。
x6818_led_drv.c:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <linux/gpio.h>
#include <mach/platform.h>
#include <mach/soc.h>

#define X6818_LEDS_MODULE_NAME	"x6818-leds"

/*
* X6818 LED:
* LED1 -> D22 -> GPIO_B26
* LED2 -> D23 -> GPIOC11
* LED3 -> D24 -> GPIOC7
* LED4 -> D25 -> GPIOC12
* 4个LED为供阳极LED,相关的GPIO电压拉低灯亮,拉高灯灭
*/
#define X6818_LEDS_NUMBER	4
#define X6818_LED1_GPIO		(PAD_GPIO_B + 26)
#define X6818_LED2_GPIO		(PAD_GPIO_C + 11)
#define X6818_LED3_GPIO		(PAD_GPIO_C + 7)
#define X6818_LED4_GPIO		(PAD_GPIO_C + 12)

#define X6818_LED_ON		0
#define X6818_LED_OFF		1

typedef struct __led{
	char * name;
	unsigned gpio;
	int status;
}led;
static led x6818_leds[X6818_LEDS_NUMBER] ={
	{ .name = "led1", .gpio = X6818_LED1_GPIO, .status = 0},
	{ .name = "led2", .gpio = X6818_LED2_GPIO, .status = 0},
	{ .name = "led3", .gpio = X6818_LED3_GPIO, .status = 0},
	{ .name = "led4", .gpio = X6818_LED4_GPIO, .status = 0},
}; 


static void __x6818_leds_probe(void)       //初始化LED对应GPIO口
{
	int ret = 0;
	int i;
	for(i = 0; i < X6818_LEDS_NUMBER; i++){
		nxp_soc_gpio_set_io_func(x6818_leds[i].gpio, NX_GPIO_PADFUNC_1); //gpio mode
		nxp_soc_gpio_set_io_dir(x6818_leds[i].gpio, 1);		 //output mode
		nxp_soc_gpio_set_io_pull_sel(x6818_leds[i].gpio, 1); // pull up select
		nxp_soc_gpio_set_io_pull_enb(x6818_leds[i].gpio, 1); // pull up  enable
		nxp_soc_gpio_set_out_value(x6818_leds[i].gpio,X6818_LED_OFF); //默认led关
		x6818_leds[i].status = 0;
	}

}
static void __x6818_leds_remove(void)    
{

}
static ssize_t x6818_leds_read(struct device *dev, struct device_attribute *attr, char *buf)
{
	int i;
	for(i = 0; i < X6818_LEDS_NUMBER; i++){
		if(!strcmp(attr->attr.name, x6818_leds[i].name)){
			if(x6818_leds[i].status)
				return strlcpy(buf, "1\n", 3);
			else
				return strlcpy(buf, "0\n", 3);
					
		}

	}
	return strlcpy(buf, "\n", 3);
}
static ssize_t x6818_leds_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	int i;
	unsigned long on = simple_strtoul(buf, NULL, 10);//convert a string to an unsigned long 从应用读取需要写入的数据 10进制
	for(i = 0; i < X6818_LEDS_NUMBER; i++){
		if(!strcmp(attr->attr.name, x6818_leds[i].name)){
			if(on){
				nxp_soc_gpio_set_out_value(x6818_leds[i].gpio,X6818_LED_ON); //默认led关
				x6818_leds[i].status = 1;
			}
			else{
				nxp_soc_gpio_set_out_value(x6818_leds[i].gpio,X6818_LED_OFF); //默认led关
				x6818_leds[i].status = 0;
			}
			break;
		}
	}	
	return count;
}



//kobject目录下的四个文件对应的属性,读写函数
static DEVICE_ATTR(led1, 0666, x6818_leds_read, x6818_leds_write);
static DEVICE_ATTR(led2, 0666, x6818_leds_read, x6818_leds_write);
static DEVICE_ATTR(led3, 0666, x6818_leds_read, x6818_leds_write);
static DEVICE_ATTR(led4, 0666, x6818_leds_read, x6818_leds_write);
static struct attribute * x6818_leds_sysfs_entries[] = {		  //对应kobject目录下的四个文件
		 &dev_attr_led1.attr,
		 &dev_attr_led2.attr,
		 &dev_attr_led3.attr,
		 &dev_attr_led4.attr,
		 NULL,
};

static struct attribute_group x6818_leds_attr_group = {
         .name   = NULL,
         .attrs  = x6818_leds_sysfs_entries,   //指定注册的kobject对应的文件属性接入点
};
static int x6818_leds_probe(struct platform_device *pdev)
{
         __x6818_leds_probe();                                       //初始化LED对应GPIO口
         return sysfs_create_group(&pdev->dev.kobj, &x6818_leds_attr_group);//注册kobject
}
static int x6818_leds_remove(struct platform_device *pdev)
{
         __x6818_leds_remove();                                     //释放GPIO
         sysfs_remove_group(&pdev->dev.kobj, &x6818_leds_attr_group);//注销kobject
         return 0;
}


static struct platform_driver x6818_leds_driver = {
	.probe		= x6818_leds_probe,
	.remove 	= x6818_leds_remove,
	.driver 	= {
		.name	= X6818_LEDS_MODULE_NAME,
	},
};
		
static struct platform_device x6818_leds_device = {
	.name      = X6818_LEDS_MODULE_NAME,
	.id        = -1,
};		
	
static int __devinit x6818_leds_init(void)
{
	int ret;

	printk("x6818 leds driver\r\n");

	ret = platform_device_register(&x6818_leds_device);
	if(ret)
		printk("failed to register x6818 leds device\n");

	ret = platform_driver_register(&x6818_leds_driver);
	if(ret)
		printk("failed to register x6818 leds driver\n");

	return ret;
}

static void x6818_leds_exit(void)
{
	platform_device_unregister(&x6818_leds_device);
	platform_driver_unregister(&x6818_leds_driver);
}

module_init(x6818_leds_init);
module_exit(x6818_leds_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("x6818 leds driver");

Makefile:

KERN_DIR = /home/wzs/Android/x6818/kernel/
all:
	make -C $(KERN_DIR) M=`pwd` modules 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

obj-m	+= x6818_led_drv.o

通过adb上传驱动文件到安卓文件系统:

adb push ./x6818_led_drv.ko /data/local/tmp

内核加载驱动:

insmod x6818_led_drv.ko

相关目录下将自动产生设备节点:

测试:

开启led1:

echo 1 > /sys/devices/platform/x6818-leds/led1

关闭led1:

echo 0 > /sys/devices/platform/x6818-leds/led1

读取led1当前状态:

cat /sys/devices/platform/x6818-leds/led1

其余led类似。

标签: 安卓 linux 驱动 x6818
共有 人打赏支持
粉丝 3
博文 22
码字总数 37304
×
redstone5
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: