嵌入式笔记-背光控制驱动

背光控制驱动

说明

其实只是一个简单的gpio驱动,但是因为某些问题一直无法实现对背光灯的控制,最后发现原来是某些函数接口的更改,或者说是所支持的接口不一致导致的问题。
在驱动中,
irq_of_parse_and_map(BLgpio_node,0);
gpio_to_irq(blgpio_state2_pin);
原本一直使用的是gpio_to_irq,但是返回值为-22,
以为是硬件管脚相关的配置问题,后来检查没有发现任何问题
然后就尝试使用irq_of_parse_and_map这个接口
一开始我心里是恐惧的,不知道该如何调用以及相关参数是如何修改等等问题,一直迟迟不动,后来就像试试吧,并且在头文件中添加如下:
extern unsigned int irq_of_parse_and_map(struct device_node* dev, int index);
就是这简单的一句,就成功的把该接口调用起来了
但是问题还没有解决,还是没办法正常的,在设备树中只是做了上升沿或下降沿触发的方式中断,然后修改成如下即可:
注意:IRQ_TYPE_EDGE_RISING 
	find ./kernel-4.9/include/ -name "irq.h"
	vi ./kernel-4.9/include/dt-bindings/interrupt-controller/irq.h
//vi ./kernel-4.9/include/dt-bindings/interrupt-controller/irq.h
#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_IRQ_H
#define _DT_BINDINGS_INTERRUPT_CONTROLLER_IRQ_H

#define IRQ_TYPE_NONE           0
#define IRQ_TYPE_EDGE_RISING    1
#define IRQ_TYPE_EDGE_FALLING   2
#define IRQ_TYPE_EDGE_BOTH      (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH     4
#define IRQ_TYPE_LEVEL_LOW      8

#endif
#vi kernel-4.9/arch/arm64/boot/dts/mediatek/ac8257_demo.dts +108
flyrdgpio:flyrdgpio {
    
    
             compatible = "mediatek,flyrdgpio";
             apstate_scone_gpio=<&pio 152 0>;
             apstate_sctwo_gpio=<&pio 151 0>;
             apstate_acc_gpio=<&pio 0 0>;
             apstate_led_gpio=<&pio 4 0>;
             apstate_backlight_gpio=<&pio 164 0>;
             interrupt-parent = <&pio>;
             interrupts = <151 IRQ_TYPE_EDGE_RISING 151 0>;
             fly_amp_mute_=<&pio 165 0>;
             fly_dsi_irq=<&pio 3 0>;
             fly_gps_ant_en=<&pio 175 0>;
             fly_gpro_acc_in=<&pio 48 0>;
             fly_ek1=<&pio 9 0>;
             fly_ek3=<&pio 4 0>;
             fly_gyro_gry_int=<&pio 49 0>;
             fly_camera_power=<&pio 167 0>;
             status="okay";
       };

头文件

#ifndef   __BACKLIGHTGPIO_H_
#define   __BACKLIGHTGPIO_H_
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <generated/autoconf.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/spinlock.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/irq.h>
#include <asm/atomic.h>
#include <linux/of_gpio.h>
#include <linux/time.h>
#include <linux/types.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/delay.h>
//#include "rdflyled.h"
//#include "notegpiocfg.h"

#define AP_STATE1_H    "ap_state1_h"
#define AP_STATE2_H    "ap_state2_h"
#define AP_STATE3_H    "ap_state3_h"

#define AP_I2C_C2_L      "i2c_c2_h"
#define AP_I2C_C2        "i2c_c2_ch"
#define AP_PIN_NUM  2
#define AP_PIN_STRDES  30


#define TAG    "backlightgpio"

#define fly_pr_info(fmt, arg...) printk(KERN_WARNING fmt, ##arg)
#define FLYGPIO_DEBUG_ON    1

#define FLYGPIO_DEBUG(fmt, arg...)          do {\
					if (FLYGPIO_DEBUG_ON)\
						fly_pr_info("<<-DEBUG->> [%d]"fmt"\n", __LINE__, ##arg);\
			} while (0)

struct work_struct work;
enum AccStatus{
    
    
	IN_SLEEP_STATUS=0,
	WAKE_UP_STATUS ,
};
enum FLY_DRIVER_RETURN {
    
    
	FLY_DRIVER_RETURN_SUCCESS = 0,
	FLY_DRIVER_RETURN_ERROR   = -1,
};


static DECLARE_WAIT_QUEUE_HEAD(wq);
extern void Set_Camera_power(int value);
extern void driver_cfg_gpio_init(void);
extern void driver_cfg_gpio_exit(void);
extern void driver_cfg_led_init(void);
extern void driver_cfg_led_exit(void);
extern unsigned int irq_of_parse_and_map(struct device_node* dev, int index);
#endif 


背光控制驱动

#include "backlightgpio.h"

static struct device_node *BLgpio_node = NULL;

static int blgpio_state2_pin = -1;
static int rdgpio_acc_pin    = -1;
static int blgpio_backlight_pin = -1;

static int carback_state_old=-1;
static int carback_state_new=-1;

int condition = 0;
/
///
static int 		BL_gpio_open(struct inode *inode, struct file *file);
static int 		BL_gpio_release(struct inode *inode, struct file *file);
static ssize_t 		BL_gpio_read(struct file *filp, char __user *user_buffer, size_t count, loff_t *offset);
static ssize_t 		BL_gpio_write(struct file *pFile, const char __user *pBuffer, size_t Count, loff_t *p_off);
static unsigned int 	BL_gpio_poll(struct file *filp, struct poll_table_struct *p);
/
/
static void 		BLgpio_init(void);
static void 		tsk_work_handler(struct work_struct *work);
irqreturn_t 		BL_status_handler(int irq,void *date);
static int 		set_BLgpio_to_irq(void);
/
/
static void BLgpio_init(void)
{
    
    
	int ret = -1;	
#if 0
	ret = gpio_request(blgpio_state2_pin, "rdgpio_state2_pin");
	if (ret < 0) {
    
    
		FLYGPIO_DEBUG("@@blgpio_state2_pin gpio bc_failed\n");
	}
	gpio_direction_input(blgpio_state2_pin);
	FLYGPIO_DEBUG("@@blgpio_state2_pin gpio ok\n");
#endif

	ret = gpio_request(blgpio_backlight_pin, "apstate_backlight_gpio");
	if (ret < 0) {
    
    
		FLYGPIO_DEBUG("@@blgpio_backlight_pin gpio bc_failed\n");
	}
	FLYGPIO_DEBUG("@@blgpio_backlight_pin gpio ok\n");
	gpio_direction_output(blgpio_backlight_pin,1);
}

static void tsk_work_handler(struct work_struct *work)
{
    
    
	int val = -1;
	FLYGPIO_DEBUG("@@handler is running..\n");
	val = gpio_get_value(blgpio_state2_pin);
	carback_state_new = val;

	FLYGPIO_DEBUG("@@carback_state_new = %d, carback_state_old = %d.\n", carback_state_new, carback_state_old);
	if(carback_state_new != carback_state_old)
	{
    
    
		condition = 1;
		if(carback_state_new == WAKE_UP_STATUS)
		{
    
    
			FLYGPIO_DEBUG("@@handler is running set blgpio_backlight_pin HEIGHT\n");
			gpio_set_value(blgpio_backlight_pin ,1);
		}
		else if(carback_state_new == IN_SLEEP_STATUS)
		{
    
    
			FLYGPIO_DEBUG("@@handler is running set blgpio_backlight_pin LOW\n");
			gpio_set_value(blgpio_backlight_pin ,0);
		}
		wake_up_interruptible(&wq); 
	}
	FLYGPIO_DEBUG("@@handler is running end in outside\n");
}

irqreturn_t BL_status_handler(int irq,void *date)
{
    
    
	if(!work_pending(&work))
	{
    
    
		FLYGPIO_DEBUG("@@In BL_status_handler.\n");
		schedule_work(&work);
	}
	return IRQ_HANDLED;
}

static int set_BLgpio_to_irq(void)
{
    
    
	int ret = -1;
	int irq = -1;
	//ret = gpio_request(blgpio_state2_pin, "apstate_scone_gpio");
	ret = gpio_request(blgpio_state2_pin, "apstate_sctwo_gpio");
	if (ret < 0) {
    
    
		FLYGPIO_DEBUG("@@apstate_sctwo_gpio gpio bc_failed\n");
		return -1;
	}
	gpio_direction_input(blgpio_state2_pin);

	FLYGPIO_DEBUG("@@##blgpio_state2_pin %d\n", blgpio_state2_pin);
	irq = irq_of_parse_and_map(BLgpio_node,0);
	//irq = gpio_to_irq(blgpio_state2_pin);
	FLYGPIO_DEBUG("@@request irq is %d\n", irq);
	if(irq < 0)
	{
    
    
		FLYGPIO_DEBUG("@@request irq is failed \n");
		return -1;
	}
	else
	{
    
    
		FLYGPIO_DEBUG("@@@request irq apstate_sctwo_gpio.");
		ret = request_irq(irq, 
				BL_status_handler,
				IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
				"flyd-irq",
				NULL);
		FLYGPIO_DEBUG("@@refunction irq %d\n",ret);	
		ret = gpio_get_value(blgpio_state2_pin);
		FLYGPIO_DEBUG("@@carback_state_new = %d, carback_state_old = %d.\n", ret , carback_state_old);
	}
	return 0;
}
/
/
static const struct file_operations BL_gpio_fops = {
    
    
	.open = 	BL_gpio_open,
	.release = 	BL_gpio_release,
	.read = 	BL_gpio_read,
	.write = 	BL_gpio_write,
	.poll = 	BL_gpio_poll
};
 
static struct miscdevice BL_gpio_misc_device = {
    
    
	.minor = MISC_DYNAMIC_MINOR,		
	.name = "BLgpio",
	.fops = &BL_gpio_fops,
};
/
/
static int BL_gpio_open(struct inode *inode, struct file *file)
{
    
    
	FLYGPIO_DEBUG("@@BL_gpio_open. \r\n");
	return 0;
}
 
 
static int BL_gpio_release(struct inode *inode, struct file *file)
{
    
    
	FLYGPIO_DEBUG("@@BL_gpio_release. \r\n");
	return 0;
}
 
static ssize_t BL_gpio_read(struct file *filp, char __user *user_buffer, size_t count, loff_t *offset)
{
    
    
	int pin = 3;
	char buffer[30] = {
    
    0};
	if(carback_state_new == carback_state_old)
	{
    
    
		if(wait_event_interruptible(wq, carback_state_new != carback_state_old))
		{
    
    
			return -1;
		}
	}	
	carback_state_old = carback_state_new;	
	sprintf(buffer,"%d%5d",pin,carback_state_new);
	if(copy_to_user(user_buffer, buffer, count))
	{
    
    
		FLYGPIO_DEBUG("@@cp to user failed \r\n");
	}
	return count;
}

static ssize_t BL_gpio_write(struct file *pFile, const char __user *pBuffer, size_t Count, loff_t *p_off)
{
    
    
	char readbuf[30];
	int ret_cnt;
	int CopyBufSize = (Count < (sizeof(readbuf) - 1)) ? (Count) : (sizeof(readbuf) - 1);
	int pin,value;
	if (copy_from_user(readbuf, pBuffer, CopyBufSize)) 
	{
    
    
		FLYGPIO_DEBUG("@@copy_from_user() fail.\r\n");
		return -1;
	}

	FLYGPIO_DEBUG("@@hello write buffer :%s\n",readbuf);
	ret_cnt = sscanf(readbuf, "%d %d",&pin, &value);
	if(ret_cnt < 1) 
	{
    
    		
		FLYGPIO_DEBUG("@@ret_cnt != 2 fail.\r\n");
		return -1;
	}
	if((pin > AP_PIN_NUM )|| (pin <= 0) )
	{
    
    
		FLYGPIO_DEBUG("@@set pin is 1------8  please \r\n");
		return -1;
	}
	if(value > 1 || value < 0)
	{
    
    
		FLYGPIO_DEBUG("@@set pin value is 0 or 1\r\n");
		return -1;
	}
	FLYGPIO_DEBUG("@@you write pindes  %d,value = %d   \n",pin,value);
	if(pin == 1){
    
    
		;//gpio_set_value(rdgpio_state1_pin,1);
	}
	else if(pin == 2)
	{
    
    
		gpio_set_value(blgpio_state2_pin,value);
		FLYGPIO_DEBUG("@@##set pin value is %d\r\n", value);
	}
	return ((ssize_t)Count);

}
static unsigned int BL_gpio_poll(struct file *filp, struct poll_table_struct *p)
{
    
    
	unsigned int mask = 0;
	poll_wait(filp, &wq, p);
	if(condition == 1)
	{
    
    
		mask |= POLLIN | POLLRDNORM;
	}
	else
	{
    
    
		mask = 0;
	}
	condition = 0;
	return mask;
}
/
/
static int BL_gpio_probe(struct platform_device *pdev)
{
    
    
	int ret = 0;
	FLYGPIO_DEBUG("@@BL gpio Probe. \r\n");
	ret = misc_register(&BL_gpio_misc_device);
	if (ret != 0 )
		printk(": BL_gpio_misc_device flygpio_device register failed\n");
	INIT_WORK(&work, tsk_work_handler);
	return ret;
}
 
static int BL_gpio_remove(struct platform_device *pdev)
{
    
    
	FLYGPIO_DEBUG("@@BL gpio remove. \r\n");
	//gpio_free(blgpio_state1_pin);
	misc_deregister(&BL_gpio_misc_device);
	return 0;
}

static struct platform_driver BLgpio_driver = {
    
    
	.driver = {
    
    
			.name = "BLgpio-dev",
			.owner = THIS_MODULE,
	},
	.remove = BL_gpio_remove,
	.probe = BL_gpio_probe,
};

static struct platform_device BLgpio_device = {
    
    
	.name = "BLgpio-dev",
	.id = -1,
};

/
/
static int __init backlight_gpio_init(void)
{
    
    
	int ret = 0;
	//driver_cfg_led_init();
	//driver_cfg_gpio_init();
	FLYGPIO_DEBUG("@@backlight_gpio_init. \r\n");
	ret = gpio_get_value(blgpio_state2_pin);
	FLYGPIO_DEBUG("@@carback_state_new = %d, carback_state_old = %d.\n", ret , carback_state_old);
	//1
	ret = platform_device_register(&BLgpio_device);
	if(ret)
	{
    
    
		FLYGPIO_DEBUG("@@platform_device_register failed!");
		goto err;
	}
	FLYGPIO_DEBUG("@@platform_device_register ok!");

	//2
	ret = platform_driver_register(&BLgpio_driver);
	if(ret)
	{
    
    
		FLYGPIO_DEBUG("@@platform_driver_register failed!");
		platform_device_unregister(&BLgpio_device);
		return ret;
	}

	FLYGPIO_DEBUG("@@platform_driver_register ok!");
	
	//3
	BLgpio_node = of_find_compatible_node(NULL, NULL, "mediatek,flyrdgpio");
	if(BLgpio_node)
	{
    
    
		//blgpio_state2_pin = of_get_named_gpio(BLgpio_node, "apstate_scone_gpio", 0);
		blgpio_state2_pin = of_get_named_gpio(BLgpio_node, "apstate_sctwo_gpio", 0);
		if (!gpio_is_valid(blgpio_state2_pin)) 
		{
    
    
			FLYGPIO_DEBUG("@@rdgpio_state2_pin bc_failed\n");
		}
		FLYGPIO_DEBUG("@@rdgpio_state2_pin ok\n");
#if 0
		rdgpio_acc_pin =  of_get_named_gpio(BLgpio_node,"apstate_acc_gpio", 0);
		if (!gpio_is_valid(rdgpio_acc_pin)) {
    
    
			FLYGPIO_DEBUG("@@rdgpio_acc_pin bc_failed\n");
		}
		FLYGPIO_DEBUG("@@rdgpio_acc_pin ok\n");
#endif

		blgpio_backlight_pin = of_get_named_gpio(BLgpio_node,"apstate_backlight_gpio", 0);
		if (!gpio_is_valid(blgpio_backlight_pin)) {
    
    
			FLYGPIO_DEBUG("@@blgpio_backlight_pin bc_failed\n");
		}
		FLYGPIO_DEBUG("@@blgpio_backlight_pin ok\n");
	}
	FLYGPIO_DEBUG("@@my_find_ok blgpio_state2_pin=%d,rdgpio_acc_pin=%d,blgpio_backlight_pin=%d\r\n",
		blgpio_state2_pin, 
		rdgpio_acc_pin,
		blgpio_backlight_pin );

	ret = gpio_get_value(blgpio_state2_pin);
	FLYGPIO_DEBUG("@@carback_state_new = %d, carback_state_old = %d.\n", ret , carback_state_old);
	//4
	BLgpio_init();
	set_BLgpio_to_irq();

	ret = gpio_get_value(blgpio_state2_pin);
	FLYGPIO_DEBUG("@@carback_state_new = %d, carback_state_old = %d.\n", ret , carback_state_old);

	return 0;
err:
	FLYGPIO_DEBUG("backlight_gpio_init with err exit.");
	return ret;
}

static void __exit backlight_gpio_exit(void)
{
    
    
	FLYGPIO_DEBUG("@@backlight_gpio_exit. \r\n");
	//driver_cfg_led_exit();
	//driver_cfg_gpio_exit();
	platform_driver_unregister(&BLgpio_driver);
	platform_device_unregister(&BLgpio_device);
}

module_init(backlight_gpio_init);
module_exit(backlight_gpio_exit);
/
/
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MY General Purpose Driver (GPIO)");


猜你喜欢

转载自blog.csdn.net/qq_40904479/article/details/110225187