MTK6833平台按键上报

项目场景:MTK6833平台按键上报

提示:只记录学习笔记,仅供参考


一、问题描述

问题:在调试的过程中发现MTK的上电log很容易被冲掉,所以加了delay_work做调试
延时代码:

#include <linux/workqueue.h>

static struct workqueue_struct *test_wq;
static struct delayed_work test_work;

static void test_power_delay_work_func(struct work_struct *work)
{
    // 延迟执行的代码逻辑
    printk(KERN_INFO "YSJDelayed work start\n");
}
//在需要延时的函数中添加
	test_wq = alloc_ordered_workqueue("%s",
						 WQ_MEM_RECLAIM |
						 WQ_FREEZABLE,
						 "test-wq");

	INIT_DELAYED_WORK(&test_work, test_power_delay_work_func);

	queue_delayed_work(test_wq, &test_work,
				   msecs_to_jiffies(10000));

原因分析:

延时进入函数时间,可以打印需要的调试信息排查问题

例如:用dmesg | grep xx,来查看printk打印信息,同时要打开debug学会使用dev打印。


二、键值上报和中断函数:

配置好dts和dws之后,在驱动函数解析引脚的中断和中断函数的键值上报,下面是驱动文件:

#include <linux/of.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/interrupt.h>   //for DECLARE_TASKLET compile
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>  //add by zhuguanglei 
#include <linux/platform_device.h>
#include <linux/yft_include/yft_project_all_config.h>
#include <linux/delay.h>

#ifdef __YFT_CUSTOMKEY_F3_SUPPORT__
#if __YFT_CUSTOMKEY_F3_SUPPORT__

#if 0 //def  __YFT_CUSTOMKEY_CHANGE__
#undef KEY_F3
#define KEY_F3		KEY_HIRAGANA
#endif

#define CUSTOMKEY_F3_GPIO_NAME  "customkey_f3_gpio"           
#define CUSTOMKEY_F3_NUM 		KEY_F3

static int yft_customkey_f3_irqnum;
static struct class *custom_key3_class;

static unsigned int yft_customkey_f3_gpio_num;
static unsigned int handle_3v3_gpio_num;
static unsigned int handle_1v8_gpio_num;

//static unsigned int yft_customkey_state_pin;
//static struct pinctrl *yft_customkey_pinctrl1;
//static struct pinctrl_state *yft_customkey_pins_eint_int;
//static struct pinctrl_state *pins_default;

static void kpd_customkey_f3_handler(unsigned long data);
static DECLARE_TASKLET(kpd_customkey_f3_tasklet,kpd_customkey_f3_handler,0);

extern void customkey_handler(bool pressed, int key_value);					//In kpd.c achieve add by zhuguanglei
//extern int yft_parse_dts(struct device_node *node, const char *gpio_name, bool gpio_mode);
#if 0
static unsigned int yft_parse_dts1(struct device_node *node, const char *gpio_name, bool gpio_mode)
{
	unsigned int gpio_num = 0;
//	struct gpio_desc *desc;
//	int ret = 0;
		if (node)
	{
		if (of_property_read_u32_index(node, gpio_name, 1, &gpio_num)) {
            pr_err("f3 read_irq_registration fail~~~\n");
        }

//		gpio_num = of_get_named_gpio(node, gpio_name, 0);
		if (gpio_num < 0)
		{
			printk("%s: f3 of_get_named_gpio fail. \n", __func__);
			return -1;
		}
		else //获取GPIO成功
		{
			printk("%s: f3 of_get_named_gpio GPIO is %d.\n", __func__, gpio_num);



		}
	}
	else
	{
		printk("%s: f3  get gpio num fail. \n", __func__);
		
	}


return gpio_num;
}
#endif
static int yft_parse_dts(struct device_node *node, const char *gpio_name, bool gpio_mode)
{
	int gpio_num = 0;
	struct gpio_desc *desc;
	int ret = 0;
	unsigned int  debounce11;
	
	if (node)
	{
		gpio_num = of_get_named_gpio(node, gpio_name, 0);
		if (gpio_num < 0)
		{
			printk("%s: of_get_named_gpio fail. \n", __func__);
			return -1;
		}
		else //获取GPIO成功
		{
			printk("%s: of_get_named_gpio GPIO is %d.\n", __func__, gpio_num);
			desc = gpio_to_desc(gpio_num);
			if (!desc)
			{
				printk("%s: gpio_desc is null.\n", __func__);
				return -1;
			}
			else //获取描述成功
				printk("%s: gpio_desc is not null.\n", __func__);

			if (gpio_is_valid(gpio_num))
				printk("%s: gpio number %d is valid. \n", __func__ ,gpio_num);

			ret = gpio_request(gpio_num, gpio_name);
			if (ret)
			{
				printk("%s: gpio_request fail. \n", __func__);
				return -1;
			}
			else //gpio_request 成功
			{
				if (!gpio_mode) //中断模式
				{
					ret = gpio_direction_input(gpio_num);
					if (ret)
					{
						printk("%s: gpio_direction_input fail. \n", __func__);
						return -1;
					}
					of_property_read_u32_index(node, "debounce", 1, &debounce11);
	                gpio_set_debounce(gpio_num,debounce11*1000);
 	      	        printk("zcy add for gpio_num = (%d) debug debounce = (%d)\n",gpio_num,debounce11);
				}
				else //GPIO 模式
				{
					ret = gpio_direction_output(gpio_num, 0);
					if (ret)
					{
						printk("%s: gpio_direction_output failed. \n", __func__);
						return -1;
					}

					gpio_set_value(gpio_num, 0);
					printk("%s: gpio_get_value =%d. \n", __func__, gpio_get_value(gpio_num));
				}

				return gpio_num; //返回GPIO num
			}
		}
	}
	else
	{
		printk("%s: get gpio num fail. \n", __func__);
		return -1;
	}
}
static void kpd_customkey_f3_handler(unsigned long data)
{
	bool pressed;
	int customkey_f3_state = 0;

	printk("%s: f3 enter. \n", __func__);

	customkey_f3_state = gpio_get_value(yft_customkey_f3_gpio_num);//__gpio_get_value(yft_customkey_f3_gpio_num);
	if(customkey_f3_state < 0)
		return;
	printk("%s: f3_num = (%d) customkey_f3_state = (%d) gpio_get_value end. \n", __func__,yft_customkey_f3_gpio_num,customkey_f3_state);

	pressed = !customkey_f3_state;

    customkey_handler(pressed, CUSTOMKEY_F3_NUM);

	printk("%s: %s HW keycode(%u) using EINT =%d.\n", __func__, pressed ? "pressed" : "released", CUSTOMKEY_F3_NUM, customkey_f3_state);

	if (pressed)
	{
		printk("%s: key %s. \n", __func__, pressed ? "pressed" : "released");
		irq_set_irq_type(yft_customkey_f3_irqnum, IRQF_TRIGGER_RISING);
	}
	else
	{
		printk("%s: key %s. \n", __func__, pressed ? "pressed" : "released");
		irq_set_irq_type(yft_customkey_f3_irqnum, IRQF_TRIGGER_FALLING);
	}

	enable_irq(yft_customkey_f3_irqnum);
}

static irqreturn_t yft_customkey_f3_isr(int irqnum, void *data)
{
	printk("%s: enter.\n", __func__);

	disable_irq_nosync(yft_customkey_f3_irqnum);
	tasklet_schedule(&kpd_customkey_f3_tasklet);
	return IRQ_HANDLED;
}


static ssize_t key3_ctrl_show(struct class *class, struct class_attribute *attr, char *buf)
{
	int handle_1v8_state = 0;
	int handle_3v3_state = 0;
	
	handle_1v8_state = gpio_get_value(handle_1v8_gpio_num);
	handle_3v3_state = gpio_get_value(handle_3v3_gpio_num);
	
	printk("%s:  handle_1v8_state=%d;  handle_3v3_state=%d. \n", __func__, handle_1v8_state, handle_3v3_state);
	return sprintf(buf, "pin27=%d;  pin28=%d\n",handle_3v3_state, handle_1v8_state);
}

static ssize_t key3_ctrl_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count)
{ 
	if ((buf[0] == '1') )
	{
	    printk("echo on\n",__func__);
		gpio_direction_output(handle_1v8_gpio_num, 1);
		gpio_direction_output(handle_3v3_gpio_num, 1);
	}
	else if ((buf[0] == '0') )
	{
		printk("echo off\n",__func__);
		gpio_direction_output(handle_3v3_gpio_num, 0);
		gpio_direction_output(handle_1v8_gpio_num, 0);
	}else{
		printk("echo fail\n",__func__);
	}

	return count;
}

static struct class_attribute class_attr_custom_key3[] = {
	__ATTR(key3_ctrl, 0664, key3_ctrl_show, key3_ctrl_store),
	__ATTR_NULL
};


/*
 初始化, 获取dts中相关的配置信息
 pdev 由 yft_intercom_plat_probe 传进来
 */
int yft_customkey_f3_init(struct platform_device *pdev)
{
	int retval;
	int i = 0;
	//int err = -EIO;
	struct device_node *node;

    printk("+++++++++++ %s: begin +++++++++++\n",__func__);

	/*get the node*/
	node = of_find_compatible_node(NULL, NULL, "mediatek,yft_customkey3");
	if (node) {
        printk("%s: node = (%d) not null.\n", __func__,node);

		yft_customkey_f3_irqnum = irq_of_parse_and_map(node, 0);
		printk("%s: f3  yft_customkey_f3_irqnum = %d\n", __func__, yft_customkey_f3_irqnum);
	}
	else {
		printk("%s: f3  cannot get the node: 'mediatek,yft_customkey'.\n", __func__);
		return -ENODEV;
	}
	
	handle_1v8_gpio_num = yft_parse_dts(node, "handle_1v8_gpio", true);
	if(handle_1v8_gpio_num < 0){
		printk("%s: yft_parse_dts get gpio fail.\n", __func__);
		return -ENODEV;	
	} else {
		printk("handle_1v8_gpio = %d. \n", handle_1v8_gpio_num);
	}
	
	handle_3v3_gpio_num = yft_parse_dts(node, "handle_3v3_gpio", true);
	if(handle_3v3_gpio_num < 0) {
		printk("%s: yft_parse_dts get gpio fail.\n", __func__);
		return -ENODEV;	
	} else {
		printk("handle_3v3_gpio = %d. \n", handle_3v3_gpio_num);
	}	
	

	//call key_parse_dts_and_get_pin_status to get gpio num 
	yft_customkey_f3_gpio_num = yft_parse_dts(node, CUSTOMKEY_F3_GPIO_NAME, false);


	if(yft_customkey_f3_gpio_num < 0)
	{   //获取GPIO num 失败
		printk("%s: yft_parse_dts get gpio fail.\n", __func__);
		return -ENODEV;	
	}
	else
	{	//打印出GPIO num的值
		printk("%s = %d. \n",CUSTOMKEY_F3_GPIO_NAME, yft_customkey_f3_gpio_num);
	}

	/*irq register*/
	retval = request_irq(yft_customkey_f3_irqnum, yft_customkey_f3_isr, IRQF_TRIGGER_FALLING, "customkeyf3", NULL);
	if (retval != 0) {
		printk("%s: request_irq fail, ret %d, irqnum %d.\n", __func__, retval, yft_customkey_f3_irqnum);
		return retval;
	}
	enable_irq(yft_customkey_f3_irqnum);
	enable_irq_wake(yft_customkey_f3_irqnum);

	custom_key3_class = class_create(THIS_MODULE, "custom_key3");
	if (IS_ERR(custom_key3_class)) {
		retval = PTR_ERR(custom_key3_class);
		printk("%s: create class, err = %d\n",__func__, retval);
		return retval;
	}
	for (i = 0; class_attr_custom_key3[i].attr.name; i++) {
		retval = class_create_file(custom_key3_class, &class_attr_custom_key3[i]);
		if (retval) {
			printk("%s: Fail class_create_file\n", __func__);
			return retval;
		}
	}

	printk("+++++++++++ yft_customkey_f3_init end +++++++++++");
	return retval;
}

#endif
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值