Android MTK平台使用设备树的方式操作GPIO

一.在设备树添加一个GPIO

DTS路径:

mt9679_an14/kernel/mtktv-modules/arch/arm64/boot/dts/mediatek/common_ctrl.dtsi

配置gpio358:

ist_hall: ist-hall{

    status ="okay";

    compatible = "ist_hall";  

    ist_hall-gpios = <&pm_gpio0 58 0>;

};

在kernel里面,添加一个驱动定时读取gpio的状态:

#include <linux/miscdevice.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/compat.h>
#include <linux/printk.h>
#include <linux/kobject.h>
#include <linux/version.h>

#include <linux/kthread.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>


#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x00)
#define DRIVER_NAME "IST_HALL"



/*define logging*/
#define IST_TEMP_DEBUG	0
#if IST_TEMP_DEBUG
#define DBG(format, args...)					\
	printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ##args)
#define ERR(format, args...)					\
	printk(KERN_ERR "%s: " format, DRIVER_NAME, ##args)
#define WARNING(format, args...)				\
	printk(KERN_WARN "%s: " format, DRIVER_NAME, ##args)
#define INFO(format, args...)					\
	printk(KERN_INFO "%s: " format, DRIVER_NAME, ##args)
#else
#define DBG(format, args...)
#define ERR(format, args...)
#define WARNING(format, args...)
#define INFO(format, args...)
#endif

struct ist_hall_dev {
	uint32_t value;
	struct device *dev;
	struct miscdevice miscdev;
	struct gpio_desc *hall_gpio;
	struct delayed_work check_status_work;
};

struct ist_hall_dev *g_ist_hall;
struct ist_hall_dev *ist_hall;
static int last_value = 0;//char


static long ist_hall_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
{
	return 0;
}

static ssize_t ist_hall_write(struct file *file, const char __user *buf,
			     size_t size, loff_t *ppos)
{
	return 1;
}

static ssize_t ist_hall_read(struct file *file, char __user *buf, size_t size,
			    loff_t *ppos)
{
	return 1;
}

static ssize_t ist_hall_value_read(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct ist_hall_dev *ist_hall = g_ist_hall;

	pr_info("ist_hall_value_read ist_hall->value:%d\n",ist_hall->value);

	return sprintf(buf, "%d\n", ist_hall->value);
}

static ssize_t ist_hall_value_write(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	return count;
}

static DEVICE_ATTR(value, 0644,
		ist_hall_value_read, ist_hall_value_write);

static const struct file_operations ist_hall_fops = {
	.owner = THIS_MODULE,
	.read = ist_hall_read,
	.write = ist_hall_write,
	.unlocked_ioctl = ist_hall_ioctl,
};

struct miscdevice ist_hall_miscdev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "ist_hall_dev",
	.fops = &ist_hall_fops,
};

static void check_link_status(struct work_struct *work)
{
    gpiod_direction_input(g_ist_hall->hall_gpio);
	g_ist_hall->value = gpiod_get_value(g_ist_hall->hall_gpio);
	pr_info("check_link_status g_ist_hall->value:%d\n",g_ist_hall->value);

	schedule_delayed_work(&g_ist_hall->check_status_work, msecs_to_jiffies(500));
}

static int ist_hall_probe(struct platform_device *pdev)
{
    
    struct ist_hall_dev *ist_hall;
	int ret;

	ist_hall = devm_kzalloc(&pdev->dev, sizeof(struct ist_hall_dev), GFP_KERNEL);
	if (!ist_hall)
		return -ENOMEM;

	ist_hall->dev = &pdev->dev;

	ist_hall->hall_gpio = devm_gpiod_get_optional(ist_hall->dev,
						     "ist_hall", GPIOD_OUT_HIGH);
	if (IS_ERR(ist_hall->hall_gpio)) {
		pr_info("Could not get hall_gpio",ist_hall->hall_gpio);
		ist_hall->hall_gpio = NULL;
	}

	ret = misc_register(&ist_hall_miscdev);
	if (ret) {
		ERR(" ist_hall ERROR: could not register ist_hall device\n");
		return ret;
	}

	ret = device_create_file(ist_hall_miscdev.this_device,
				&dev_attr_value);
	if (ret) {
		dev_err(ist_hall->dev, " failed to create attr hdmirxsel!\n");
		return ret;
	}
	g_ist_hall = ist_hall;

	INIT_DELAYED_WORK(&ist_hall->check_status_work, check_link_status);
	schedule_delayed_work(&ist_hall->check_status_work, msecs_to_jiffies(500));
		
    return 0;
}

static int ist_hall_remove(struct platform_device *client)
{

    return 0;
}

static const struct of_device_id ist_hall_of_match[] = {
    { .compatible = "ist_hall" },
    {}
};
MODULE_DEVICE_TABLE(of, ist_hall_of_match);

static struct platform_driver ist_hall_driver = {
    .probe = ist_hall_probe,
    .remove = ist_hall_remove,
    .driver = {
        .owner = THIS_MODULE,
        .name = DRIVER_NAME,
        .of_match_table = of_match_ptr(ist_hall_of_match),
    },
};

static int __init ist_hall_driver_init(void)
{
    int ret = platform_driver_register(&ist_hall_driver);
    if (ret != 0) {
        pr_info("rtl8309_init Failed to register example driver: %d\n", ret);
        return ret;
    }
    return 0;
}

static void __exit ist_hall_driver_exit(void)
{
    platform_driver_unregister(&ist_hall_driver);
    pr_info("Example driver exited\n");
}

module_init(ist_hall_driver_init);
module_exit(ist_hall_driver_exit);


MODULE_DESCRIPTION("rtl8309 GPIO Switch");
MODULE_AUTHOR("Zewei Ye <yezw@ist.com.hk>");
MODULE_LICENSE("GPL v2");

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嵌入式_笔记

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

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

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

打赏作者

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

抵扣说明:

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

余额充值