首页 > 系统相关 >按键 芯片型号clps711x linux 驱动程序

按键 芯片型号clps711x linux 驱动程序

时间:2024-11-22 20:48:40浏览次数:3  
标签:驱动程序 linux dev input clps711x poll data priv

/*

  • Cirrus Logic CLPS711X Keypad driver
  • This program is free software; you can redistribute it and/or modify
  • it under the terms of the GNU General Public License as published by
  • the Free Software Foundation; either version 2 of the License, or
  • (at your option) any later version.
    */

#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/sched.h>
#include <linux/input/matrix_keypad.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/clps711x.h>

#define CLPS711X_KEYPAD_COL_COUNT 8

struct clps711x_gpio_data {
struct gpio_desc *desc;
DECLARE_BITMAP(last_state, CLPS711X_KEYPAD_COL_COUNT);
};

struct clps711x_keypad_data {
struct regmap *syscon;
int row_count;
unsigned int row_shift;
struct clps711x_gpio_data *gpio_data;
};

static void clps711x_keypad_poll(struct input_polled_dev *dev)
{
const unsigned short *keycodes = dev->input->keycode;
struct clps711x_keypad_data *priv = dev->private;
bool sync = false;
int col, row;

for (col = 0; col < CLPS711X_KEYPAD_COL_COUNT; col++) {
	/* Assert column */
	regmap_update_bits(priv->syscon, SYSCON_OFFSET,
			   SYSCON1_KBDSCAN_MASK,
			   SYSCON1_KBDSCAN(8 + col));

	/* Scan rows */
	for (row = 0; row < priv->row_count; row++) {
		struct clps711x_gpio_data *data = &priv->gpio_data[row];
		bool state, state1;

		/* Read twice for protection against fluctuations */
		do {
			state = gpiod_get_value_cansleep(data->desc);
			cond_resched();
			state1 = gpiod_get_value_cansleep(data->desc);
		} while (state != state1);

		if (test_bit(col, data->last_state) != state) {
			int code = MATRIX_SCAN_CODE(row, col,
						    priv->row_shift);

			if (state) {
				set_bit(col, data->last_state);
				input_event(dev->input, EV_MSC,
					    MSC_SCAN, code);
			} else {
				clear_bit(col, data->last_state);
			}

			if (keycodes[code])
				input_report_key(dev->input,
						 keycodes[code], state);
			sync = true;
		}
	}

	/* Set all columns to low */
	regmap_update_bits(priv->syscon, SYSCON_OFFSET,
			   SYSCON1_KBDSCAN_MASK, SYSCON1_KBDSCAN(1));
}

if (sync)
	input_sync(dev->input);

}

static int clps711x_keypad_probe(struct platform_device *pdev)
{
struct clps711x_keypad_data *priv;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct input_polled_dev *poll_dev;
u32 poll_interval;
int i, err;

priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
	return -ENOMEM;

priv->syscon =
	syscon_regmap_lookup_by_compatible("cirrus,ep7209-syscon1");
if (IS_ERR(priv->syscon))
	return PTR_ERR(priv->syscon);

priv->row_count = of_gpio_named_count(np, "row-gpios");
if (priv->row_count < 1)
	return -EINVAL;

priv->gpio_data = devm_kcalloc(dev,
			priv->row_count, sizeof(*priv->gpio_data),
			GFP_KERNEL);
if (!priv->gpio_data)
	return -ENOMEM;

priv->row_shift = get_count_order(CLPS711X_KEYPAD_COL_COUNT);

for (i = 0; i < priv->row_count; i++) {
	struct clps711x_gpio_data *data = &priv->gpio_data[i];

	data->desc = devm_gpiod_get_index(dev, "row", i, GPIOD_IN);
	if (IS_ERR(data->desc))
		return PTR_ERR(data->desc);
}

err = of_property_read_u32(np, "poll-interval", &poll_interval);
if (err)
	return err;

poll_dev = input_allocate_polled_device();
if (!poll_dev)
	return -ENOMEM;

poll_dev->private		= priv;
poll_dev->poll			= clps711x_keypad_poll;
poll_dev->poll_interval		= poll_interval;
poll_dev->input->name		= pdev->name;
poll_dev->input->dev.parent	= dev;
poll_dev->input->id.bustype	= BUS_HOST;
poll_dev->input->id.vendor	= 0x0001;
poll_dev->input->id.product	= 0x0001;
poll_dev->input->id.version	= 0x0100;

err = matrix_keypad_build_keymap(NULL, NULL, priv->row_count,
				 CLPS711X_KEYPAD_COL_COUNT,
				 NULL, poll_dev->input);
if (err)
	goto out_err;

input_set_capability(poll_dev->input, EV_MSC, MSC_SCAN);
if (of_property_read_bool(np, "autorepeat"))
	__set_bit(EV_REP, poll_dev->input->evbit);

platform_set_drvdata(pdev, poll_dev);

/* Set all columns to low */
regmap_update_bits(priv->syscon, SYSCON_OFFSET, SYSCON1_KBDSCAN_MASK,
		   SYSCON1_KBDSCAN(1));

err = input_register_polled_device(poll_dev);
if (err)
	goto out_err;

return 0;

out_err:
input_free_polled_device(poll_dev);
return err;
}

static int clps711x_keypad_remove(struct platform_device *pdev)
{
struct input_polled_dev *poll_dev = platform_get_drvdata(pdev);

input_unregister_polled_device(poll_dev);
input_free_polled_device(poll_dev);

return 0;

}

static const struct of_device_id clps711x_keypad_of_match[] = {
{ .compatible = “cirrus,ep7209-keypad”, },
{ }
};
MODULE_DEVICE_TABLE(of, clps711x_keypad_of_match);

static struct platform_driver clps711x_keypad_driver = {
.driver = {
.name = “clps711x-keypad”,
.of_match_table = clps711x_keypad_of_match,
},
.probe = clps711x_keypad_probe,
.remove = clps711x_keypad_remove,
};
module_platform_driver(clps711x_keypad_driver);

MODULE_AUTHOR(“xxx”);
MODULE_DESCRIPTION(“Cirrus Logic CLPS711X Keypad driver”);
MODULE_LICENSE(“GPL”);

标签:驱动程序,linux,dev,input,clps711x,poll,data,priv
From: https://blog.csdn.net/baidu_37552881/article/details/143960884

相关文章

  • Linux: network: tcp: TCP: request_sock_TCP: Possible SYN flooding on port 3868.
    https://blog.csdn.net/qq_36428903/article/details/120923977这个情况也是和上面的情况一样。假如有两个VM(A和B)是互为备份,上面的IP地址是浮动的,假如其中一个VMA出现CPU的使用率太高,导致网络包堆积在网卡/驱动层。此时高可靠性导致浮动IP切换到另一端VMB,同时VM-ACPU使......
  • SELinux知识点
    SELinux软件安全性《关于UNIX的安全》中DennisRitchie提到:“首先要面对的事实是,UNIX的开发者并没有考虑安全问题,单这一点就单会引发大量的漏洞”。主要是因为防火墙通常不具备查杀病毒的能力,只能对数据包过滤,不会拆解数据包,无法确认数据安全安全防护机制访问控制防护:......
  • linux命令 echo 大文件名称,清空文件内容,释放磁盘空间
    linux命令echo大文件名称,清空文件内容,释放磁盘空间echo>1.loglinux命令echo>文件名称在Linux中,echo命令用于向标准输出(通常是终端/屏幕)输出文本,而重定向符号>用于将echo的输出写入文件,如果文件不存在则创建文件。如果文件已存在,则默认情况下会被覆盖。例如,如果你想......
  • 应急响应靶机——linux1
    载入虚拟机,打开虚拟机,上网获取到密码是defend:登录进去后发现桌面有个“题解”文件夹,里面有两个文件:需要收集以下信息:1、攻击者IP地址2、三个flagsu登录root用户(密码:defend),history命令查看历史命令列表:发现第一个flag:flag{thisismybaby}看到有人添加了执......
  • Linux之PCP工具
    PerformanceCo-Pilot(PCP)PCP是一个开源,分布式,指标收集和分析系统的工具,它包括CPU,内存,磁盘交换,网络,NFS,RPC,文件系统和每个进程统计信息等领域的活动覆盖率。PCP组件PMCD:性能度量收集器守护进程。PMDA:性能度量域代理,插件代理负责一组特定的指标。。多种客户端工具:例如pminf......
  • 【Linux工作记录】 grafana面板添加clickhouse数据源
    登录grafana的ui界面中添加clickhouse数据源发现没有找到clickhouse数据源操作步骤:1、到grafana节点机器中,找到grafana的bin目录2、安装clickhouse数据源插件./grafanaclipluginsinstallgrafana-clickhouse-datasourceError:✗pluginsDir(/var/lib/grafana/plugins)......
  • 毕设开题:Linux知识图谱智能问答
    我们是一家专业的软件毕设代做工作室,拥有丰富的经验和专业的技术团队。我们可以为您提供高质量的毕业设计服务,涵盖多种热门技术和领域,包括但不限于:编程语言:Python、Django、Flask等算法设计与实现知识图谱构建与应用开题报告选题背景近年来,随着信息技术的迅猛发展,L......
  • Linux-Cent7.9 redis路径查找 | 删除redis所有缓存
    查看redis端口命令[root@VM-20-17-centosetc]#ps-ef|grepredisredis125710Nov20?00:02:06/usr/bin/redis-server0.0.0.0:6379root63406653015:27pts/000:00:00grep--color=autoredis发现redis-server对应端口为1257查看r......
  • 腾讯通RTX手机和Linux版方案,兼容银河麒麟等国产系统
    一、继续使用腾讯通RTX面临的核心问题随着腾讯通RTX的停更以及官网下架,用户无法获得更新、技术支持和资源下载,暴露了几个显著的问题,影响了使用体验:●不兼容国产操作系统及移动端:腾讯通RTX仅支持Windows和Mac平台,不能在Linux内核国产操作系统及移动端使用。●组织架构同步不及......
  • Linux操作系统的安装、基本管理和常用命令(操作系统实验一)
    1.Linux操作系统(Centos)的安装安装VMware16在VMware16上创建虚拟机并安装Centos2.Linux系统的基本管理Linux的启动和退出启动Linux系统,输入用户名和密码后,登录系统;退出Linux系统,使用完毕后,退出系统。用户和用户组管理用户组管理。用户管理包括增加、修改和删除用......