瑞芯微rockchip PX30 GPIO的使用

系列文章目录

瑞芯微rockchip PX30 串口调试记录
瑞芯微rockchip PX30 显示屏调试
瑞芯微rockchip PX30触摸屏调试记录
瑞芯微rockchip PX30 QT环境搭建
瑞芯微rockchip PX30 GPIO的使用


前言

  前段时间用QT搞了个简单界面到屏幕上,现在要做个息屏的按钮。目前的想法只是简单的按键下后屏幕熄灭,再按一下屏幕亮起,没有对界面控件做屏蔽操作(相当于眼不见为净doge)。
  具体做法是,设备树中对引脚进行配置,写一个简单的io驱动,将操作接口通过sysfs开放到命令行,再写个简单脚本检测按键操作以及控制屏幕背光的PWM。

1、开发环境

  系统:ubuntu 18.04
  芯片:瑞芯微PX30
  SDK:rk官方SDK V1.5.0
  内核版本:Linux 4.4.194
  按键IO:GPIO2_C3
  屏幕背光:PWM1

2、设备树修改

  在backlight节点增加GPIO属性(screenlock-io),GPIO的pinctrl配置为上拉输入:

	backlight: backlight {
		compatible = "pwm-backlight";
		screenlock-io = <&gpio2 RK_PC3 GPIO_ACTIVE_HIGH>;
		pinctrl-names = "gpio";
		pinctrl-0 = <&screenlock>;
		pwms = <&pwm1 0 10000 0>;
		enable-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; 
		brightness-levels = <
			  0   1   2   3   4   5   6   7
			...
			248 249 250 251 252 253 254 255>;
		default-brightness-level = <10>;
	};
...
&pinctrl {
	backlight {
		screenlock: screenlock {
            rockchip,pins = <2 RK_PC3 RK_FUNC_GPIO &pcfg_input_high>; 
    	};
	};
};

3、编写IO驱动程序

  直接贴代码:

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <asm/io.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>

#define BLIO_NAME       "blio"
#define BLIO_MINOR      100

#define LOG(x...)   printk(KERN_INFO "[backlight io]: "x)

typedef struct blio_type {
	struct device_node *nd; 
	int gpio;
	enum of_gpio_flags flags;
}blio_t;

blio_t blio;

static ssize_t blio_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	buf[0] = gpio_get_value(blio.gpio) + 48;
	buf[1] = '\0';
    return strlen(buf);
}
static ssize_t blio_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t size)
{
/* 必须return size,如果return 0会一直循环执行 */
	 return size;
}
static DEVICE_ATTR(blio, 0444, blio_show,blio_store);


static int blio_open(struct inode *inode, struct file *filp)
{
	return 0;
}
static int blio_release(struct inode *inode, struct file *filp)
{
	return 0;
}
static const struct file_operations blio_fileops = {
	.owner = THIS_MODULE,
	.open = blio_open,
	.release = blio_release,
};

static struct miscdevice blio_device = {
	.minor		= BLIO_MINOR,
	.name		= BLIO_NAME,
	.fops		= &blio_fileops,
};

static int __init blio_init(void)
{
    int ret = 0,err = 0;

    ret = misc_register(&blio_device);
	if (ret) {
		LOG("%s(%d): CHAR registration failed of px30 backlight driver\n",
			__func__, __LINE__);
		LOG("%s(%d): Error value returned: %d\n",
			__func__, __LINE__, ret);
		ret = -EINVAL;
		goto fail_chrdev_regist;
	}
    
    err = device_create_file(blio_device.this_device, &dev_attr_blio);
    if (err) {
        LOG("Unable to register sysdev entry for gpio");
		ret = -EINVAL;
        goto fail_create_attr;
    }
	blio.nd = of_find_node_by_path("/backlight");

    if (blio.nd == NULL)
    {
        LOG("backlight node not find!\r\n");
		ret = -EINVAL;
        goto fail_get_blionode;
    }
    LOG("backlight node found!\n");

    blio.gpio = of_get_named_gpio_flags(blio.nd, "screenlock-io",0,&blio.flags);
	LOG("%s: get property: screenlock-io= %d.\n", __func__, blio.gpio);
    if (gpio_is_valid(blio.gpio)) {
        // ret = devm_gpio_request_one(blio_device.this_device, blio.gpio ,GPIOF_DIR_OUT, "blio");
        // if (ret) {
        //     LOG("Failed to get screenlock-io\n");
        // }else{
        //     LOG("Succeed to get screenlock-io.\n");
        // }
		// gpio_set_value(blio.gpio,1);
		// gpio_direction_input
		// gpio_direction_output
		LOG("Succeed to get screenlock-io.\n");
    }else{
        LOG("%s: screenlock-io is no avaliable.\n", __func__);
		ret = -EINVAL;
	 	goto fail_gpio_request;
    }
   return 0;
    
fail_gpio_request:
fail_get_blionode:
	device_remove_file(blio_device.this_device, &dev_attr_blio);
fail_create_attr:
    misc_deregister(&blio_device);
fail_chrdev_regist:
    return ret;
}

static void __exit blio_exit(void)
{
    device_remove_file(blio_device.this_device, &dev_attr_blio);
    misc_deregister(&blio_device);
}

module_init(blio_init);
module_exit(blio_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhang");

  代码没什么特别,就是misc设备注册,然后在sysfs中创建读写接口,IO口的输入输出方式通过pinctrl另外配置,这里不需要进行配置,只需要正常获取IO号就可以。

4、修改PWM背光驱动

  瑞芯微的pinctl配置需要自己在驱动中进行配置,找到背光驱动代码drivers/video/backlight/pwm_bl.c ,在驱动中添加以下代码配置引脚属性:

static int pwm_backlight_probe(struct platform_device *pdev)
{
	...
	struct pinctrl *pinctrl;
	struct pinctrl_state * gpio_state = NULL;
	...
	pinctrl = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR(pinctrl)) {
		printk( "[----------------]failed to find pwm pinctrl\n");
		// return PTR_ERR(sub->pinctrl);
	}
	printk( "[----------------]successed to find pwm pinctrl\n");

	gpio_state = pinctrl_lookup_state(pinctrl, "gpio");
	pinctrl_select_state(pinctrl, gpio_state);
	...
	return ret;
}

5、编写脚本

5.1、按键的检测方法

  命令行输入命令:

[root@px30_64:/]# cat /sys/class/misc/blio/blio
1

  由于设置了上拉输入,没按下时输出1,按下后输出0.

5.2、背光的控制方法

  命令行输入命令:

echo xxx >/sys/class/backlight/backlight/brightness

  xxx数值为0~255,0表示熄灭。

5.3、编写检测和控制脚本

  脚本内容如下:

#!/bin/sh

SCREEN_LOCK_FILE=/sys/class/misc/blio/blio
BACKLIGNT_FILE=/sys/class/backlight/backlight/brightness
BUTTON_STATUS=1
BUTTON_LASTSTATUS=1
PRESSED=0
SCREEN_LOCK=0

screen_lock()
{
        echo 0 > $BACKLIGNT_FILE;
}

screen_unlock()
{
        echo 100 > $BACKLIGNT_FILE;
}

button_detect()
{
        BUTTON_LASTSTATUS=$BUTTON_STATUS;
        BUTTON_STATUS=$(cat $SCREEN_LOCK_FILE);
        if [ $BUTTON_STATUS = 0 ]
        then
                if [ $BUTTON_LASTSTATUS = 1 ]
                then
                        PRESSED=1;
                        if [ $SCREEN_LOCK = 0 ]
                        then
                                screen_lock;
                                SCREEN_LOCK=1;
                        else
                                screen_unlock;
                                SCREEN_LOCK=0;
                        fi
                else
                        PRESSED=0;
                fi
        fi

}

printf "Starting screen lock control\n"
while [[ -f "$SCREEN_LOCK_FILE" ]] && [[ -f "$BACKLIGNT_FILE" ]]
do
        button_detect;
        sleep 0.05;
done
echo "warning! File [ $SCREEN_LOCK_FILE or $BACKLIGNT_FILE] not found"
exit 0

  没写过复杂的脚本,写的时候感觉像C风格,尴尬。
  最后,在/etc/init.d的启动脚本中将这个脚本后台运行起来即可。

6、总结

  这部分没什么复杂的,主要学习到的是pinctrl部分。pinctrl驱动的代码是半导体厂商自己根据自身情况设计的,imx6ull貌似不需要自己去驱动代码中再进行配置,而瑞芯微这边是需要自己在代码中进行配置的,否则没有效果。
  
  
  
  
  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr_zhangsq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值