<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>练习实操 on Luoj`s Markdown</title>
    <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/</link>
    <description>Recent content in 练习实操 on Luoj`s Markdown</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Tue, 09 Jun 2026 16:04:00 +0800</lastBuildDate>
    <atom:link href="https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Level 3：加一个 native 服务开机自启动</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-3-native%E6%9C%8D%E5%8A%A1/</link>
      <pubDate>Tue, 09 Jun 2026 16:04:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-3-native%E6%9C%8D%E5%8A%A1/</guid>
      <description>&lt;h1 id=&#34;level-3加一个-native-服务开机自启动&#34;&gt;Level 3：加一个 native 服务开机自启动&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;在系统里加一个自己的可执行文件，开机自动跑起来，&lt;code&gt;logcat&lt;/code&gt; 能看到它的输出。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;为什么要先做这个再做驱动？因为它最快让你体验完整的&amp;quot;加代码→配构建→配 init.rc→写 SELinux policy→编译→烧录→验证&amp;quot;闭环。不到你手写驱动的时间的 1/10，但建立的操作习惯后面每个 Level 都在用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Android 系统启动后，用户态的入口是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;init 进程是所有用户态进程的祖先（PID 1）&lt;/li&gt;
&lt;li&gt;init 解析 &lt;code&gt;init.rc&lt;/code&gt; 文件，按规则启动服务&lt;/li&gt;
&lt;li&gt;厂商自己的服务可以通过 &lt;code&gt;init_rc&lt;/code&gt; 属性添加到 vendor 分区&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;vendor 分区和 system 分区是什么关系？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;system 分区存 Android 通用组件&lt;/li&gt;
&lt;li&gt;vendor 分区存厂商（Amlogic/你的公司）的专有部分&lt;/li&gt;
&lt;li&gt;Treble 架构强制隔离二者——你的服务应该放 vendor 分区&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;为什么加了服务还要写 SELinux policy？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android 的 SELinux 默认不让任何未定义的进程运行&lt;/li&gt;
&lt;li&gt;不加 .te 文件，你的服务一启动就被 kernel 杀掉&lt;/li&gt;
&lt;li&gt;不是 bug，是机制&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;需要懂的知识&#34;&gt;需要懂的知识&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Android.bp（Soong 构建）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;AOSP 从 Android 7 开始引入 Soong 替代 Makefile，配置文件是 &lt;code&gt;Android.bp&lt;/code&gt;。常用模块类型：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-bp&#34; data-lang=&#34;bp&#34;&gt;cc_binary {           // 编译为可执行文件
    name: &amp;#34;luojService&amp;#34;,
    srcs: [&amp;#34;luojService.cpp&amp;#34;],
    shared_libs: [
        &amp;#34;liblog&amp;#34;,
    ],
    vendor: true,      // 安装到 vendor 分区
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;vendor: true&lt;/code&gt; 决定了产物的安装路径。&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 2：编译自己的固件并烧录</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-2-%E7%BC%96%E8%AF%91%E7%83%A7%E5%BD%95/</link>
      <pubDate>Tue, 09 Jun 2026 16:03:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-2-%E7%BC%96%E8%AF%91%E7%83%A7%E5%BD%95/</guid>
      <description>&lt;h1 id=&#34;level-2编译自己的固件并烧录&#34;&gt;Level 2：编译自己的固件并烧录&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;从源码完整编译出一版固件，烧到板子里，确认跑的是我自己编译的系统。&lt;/p&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;你的项目用什么方式编译？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;标准 AOSP：&lt;code&gt;source build/envsetup.sh&lt;/code&gt; → &lt;code&gt;lunch&lt;/code&gt; → &lt;code&gt;make&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;本项目（ross）：用 &lt;code&gt;build.cfg&lt;/code&gt; + &lt;code&gt;./mk&lt;/code&gt; 脚本&lt;/li&gt;
&lt;li&gt;两者的区别是什么？&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;一个固件由哪些东西组成？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;boot.img（内核 + ramdisk）&lt;/li&gt;
&lt;li&gt;super.img（system + vendor + product）&lt;/li&gt;
&lt;li&gt;dtb/dtbo（设备树）&lt;/li&gt;
&lt;li&gt;这些镜像文件在 &lt;code&gt;out/target/product/ross/&lt;/code&gt; 下&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;怎么判断编译成功了？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最后一行：&lt;code&gt;#### build completed successfully ####&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;关键镜像文件生成且大小合理&lt;/li&gt;
&lt;li&gt;烧录后 &lt;code&gt;ro.build.date&lt;/code&gt; 是你刚才的编译时间&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;需要懂的知识&#34;&gt;需要懂的知识&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AOSP 构建系统骨架&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个 Android 固件的编译最终是一系列 Makefile 规则的执行，但 AOSP 用了一整套包装：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;build/envsetup.sh&lt;/code&gt; ——设置环境变量，提供 &lt;code&gt;lunch&lt;/code&gt;、&lt;code&gt;mmm&lt;/code&gt;、&lt;code&gt;make&lt;/code&gt; 等命令&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lunch&lt;/code&gt; ——选择产品+编译类型，本质是设置 &lt;code&gt;TARGET_PRODUCT&lt;/code&gt; 和 &lt;code&gt;TARGET_BUILD_VARIANT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make&lt;/code&gt; ——根据产品配置读取所有 &lt;code&gt;Android.mk&lt;/code&gt;/&lt;code&gt;Android.bp&lt;/code&gt;，编译出完整系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 ross 项目中，&lt;code&gt;build.cfg&lt;/code&gt; 代替了 &lt;code&gt;lunch&lt;/code&gt; 的手动选择：&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 1：确认板子是活的</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-1-%E8%AE%A4%E8%AF%86%E6%9D%BF%E5%AD%90/</link>
      <pubDate>Tue, 09 Jun 2026 16:02:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-1-%E8%AE%A4%E8%AF%86%E6%9D%BF%E5%AD%90/</guid>
      <description>&lt;h1 id=&#34;level-1确认板子是活的&#34;&gt;Level 1：确认板子是活的&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;拿到一块 S905X5M 板子，通电，确认它能正常工作，搞清楚&amp;quot;我手里有什么&amp;quot;。&lt;/p&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;板子需要哪些物理连接才能工作？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;电源（看板子丝印，12V/5V？DC 口还是接线柱？）&lt;/li&gt;
&lt;li&gt;串口（TX/RX/GND 三根线，接 TTL-USB 转接板）&lt;/li&gt;
&lt;li&gt;显示（HDMI 接显示器）&lt;/li&gt;
&lt;li&gt;网络或 USB（用来 adb 连接）&lt;/li&gt;
&lt;li&gt;找出你的板子上每个接口的位置&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;怎么判断板子&amp;quot;活着&amp;quot;？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;串口有输出（bootloader 启动日志）&lt;/li&gt;
&lt;li&gt;HDMI 有画面（Android 启动动画或桌面）&lt;/li&gt;
&lt;li&gt;adb 能连上（&lt;code&gt;adb devices&lt;/code&gt; 看到设备）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;什么是 Android 的板级信息？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ro.board.platform&lt;/code&gt;——芯片平台代号（S905X5M 是什么？）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ro.build.version.release&lt;/code&gt;——Android 版本号&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ro.build.fingerprint&lt;/code&gt;——完整构建指纹（包含厂商/产品/版本/编译号）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ro.build.date&lt;/code&gt;——固件编译时间&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/proc/version&lt;/code&gt;——内核版本和编译工具链&lt;/li&gt;
&lt;li&gt;这些信息由谁写入的？→ build.prop 文件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;需要懂的知识&#34;&gt;需要懂的知识&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;adb 基础命令&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;adb（Android Debug Bridge）是 Android 调试的核心工具，三个组件：adb client（你输入命令的终端）、adb server（后台进程）、adbd（板子上跑的守护进程）。只需要记住：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;adb shell &amp;lt;cmd&amp;gt;&lt;/code&gt; ——在板子上执行命令&lt;/li&gt;
&lt;li&gt;&lt;code&gt;adb devices&lt;/code&gt; ——查看连接的设备列表&lt;/li&gt;
&lt;li&gt;&lt;code&gt;adb push/pull&lt;/code&gt; ——传文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Linux 虚拟文件系统&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/proc/&lt;/code&gt; ——内核暴露的运行信息（进程、内存、版本），不是真实文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/sys/&lt;/code&gt; ——内核暴露的设备参数，可以读写来配置驱动&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getprop&lt;/code&gt; ——读取 Android 系统的属性，底层就是读取 &lt;code&gt;/&lt;/code&gt; 下的属性文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;分区概念&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>实操问题记录</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/debug/</link>
      <pubDate>Tue, 09 Jun 2026 16:01:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/debug/</guid>
      <description>&lt;h1 id=&#34;实操问题记录&#34;&gt;实操问题记录&lt;/h1&gt;
&lt;p&gt;按 &lt;code&gt;target.md&lt;/code&gt; 的 Level 对应，只记录实操中遇到的&lt;strong&gt;编译/运行错误&lt;/strong&gt;和&lt;strong&gt;异常现象&lt;/strong&gt;。知识点类内容归属各 Level 文档本身。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;level-3加一个-native-服务开机自启动&#34;&gt;Level 3：加一个 native 服务开机自启动&lt;/h2&gt;
&lt;p&gt;对应学习文档：&lt;a href=&#34;level-3-native%E6%9C%8D%E5%8A%A1.md&#34;&gt;level-3-native服务.md&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;l3-01-checkpolicy-unrecognized-character&#34;&gt;[L3-01] checkpolicy unrecognized character&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;现象：&lt;/strong&gt; &lt;code&gt;ERROR &#39;unrecognized character&#39; at token &#39;&lt;/code&gt;，指向新建的 &lt;code&gt;.te&lt;/code&gt; 文件&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根因：&lt;/strong&gt; &lt;code&gt;.te&lt;/code&gt; 文件是 Windows CRLF（&lt;code&gt;\r\n&lt;/code&gt;）换行符，Linux 的 checkpolicy 不识别 &lt;code&gt;\r&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修复：&lt;/strong&gt; &lt;code&gt;sed -i &#39;s/\r$//&#39; vendor/giec/common/sepolicy/luojService.te&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;验证：&lt;/strong&gt; &lt;code&gt;cat -A file.te&lt;/code&gt; → 看到 &lt;code&gt;$&lt;/code&gt;（LF）而非 &lt;code&gt;^M$&lt;/code&gt;（CRLF）&lt;/p&gt;
&lt;h3 id=&#34;l3-02-neverallow-违规dac_override&#34;&gt;[L3-02] neverallow 违规：dac_override&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;现象：&lt;/strong&gt; &lt;code&gt;neverallow check failed ... allow luojService self:capability { dac_override }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根因：&lt;/strong&gt; &lt;code&gt;dac_override&lt;/code&gt;（绕过文件权限）被系统核心策略（&lt;code&gt;domain.te:470&lt;/code&gt;）全局禁止，任何 domain 不可申请&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修复：&lt;/strong&gt; 从 &lt;code&gt;.te&lt;/code&gt; 中删除 &lt;code&gt;allow luojService self:capability { dac_override };&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 6 总结与扩展：逐函数拆解 GPIO 按键驱动</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-6-%E6%80%BB%E7%BB%93%E4%B8%8E%E6%89%A9%E5%B1%95/</link>
      <pubDate>Tue, 09 Jun 2026 15:04:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-6-%E6%80%BB%E7%BB%93%E4%B8%8E%E6%89%A9%E5%B1%95/</guid>
      <description>&lt;h1 id=&#34;level-6-总结与扩展逐函数拆解-gpio-按键驱动&#34;&gt;Level 6 总结与扩展：逐函数拆解 GPIO 按键驱动&lt;/h1&gt;
&lt;p&gt;本文是 &lt;a href=&#34;level-6-%E6%8C%89%E9%94%AE.md&#34;&gt;level-6-按键.md&lt;/a&gt; 的延伸，以 Amlogic &lt;code&gt;gpio_keypad.c&lt;/code&gt;（557 行）为样本，&lt;strong&gt;按照代码的物理顺序，逐函数解释它干了什么&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;读完本文你会：能自己读懂一个陌生驱动，知道每个函数在做什么。&lt;/p&gt;
&lt;p&gt;驱动源文件：&lt;code&gt;common/common_drivers/drivers/input/keyboard/gpio_keypad.c&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;代码总览完整源码&#34;&gt;代码总览（完整源码）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;以下是 &lt;code&gt;gpio_keypad.c&lt;/code&gt; 的完整代码。每个函数后面跟着逐行解释。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/module.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/init.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/types.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/string.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/kstrtox.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/input.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/platform_device.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/of.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/gpio/consumer.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/interrupt.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/slab.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/amlogic/pm.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/irq.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/amlogic/power_domain.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;linux/amlogic/gpiolib.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define DEFAULT_SCAN_PERION	20
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define	DEFAULT_POLL_MODE	0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define KEY_JITTER_COUNT	1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; pin_desc {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; current_status;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_desc &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;desc;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; irq_num;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	u32 code;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	u32 key_type;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;name;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; count;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; ignore;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; key_size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; use_irq;&lt;span style=&#34;color:#75715e&#34;&gt;/* 1:irq mode ; 0:polling mode */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; scan_period;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; pin_desc &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; pin_desc &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;current_key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; timer_list polling_timer;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; input_dev &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;input_dev;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class kp_class;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class resetkey_class;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; reset_count;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;irqreturn_t&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;gpio_irq_handler&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; irq, &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;data)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;mod_timer&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		  jiffies &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;msecs_to_jiffies&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; IRQ_HANDLED;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;report_key_code&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; gpio_val)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; pin_desc &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;current_key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;count &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt; KEY_JITTER_COUNT) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;current_status &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; gpio_val;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;current_status) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;input_event&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev, key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_type,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				    key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;code, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_dbg&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key %d up.&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;code);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;input_event&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev, key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_type,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				    key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;code, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#75715e&#34;&gt;// Count key press
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;strcmp&lt;/span&gt;(key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;name, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bluetooth&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;reset_count&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_dbg&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key %d down.&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;code);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;input_sync&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;polling_timer_handler&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; timer_list &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;t)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; gpio_val;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; is_pressing &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;from_timer&lt;/span&gt;(keypad, t, polling_timer);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;use_irq) {&lt;span style=&#34;color:#75715e&#34;&gt;/* irq mode */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			gpio_val &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;gpiod_get_value&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].desc);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			gpio_val &lt;span style=&#34;color:#f92672&#34;&gt;|=&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].ignore;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].current_status &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; gpio_val) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].count&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;current_key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;report_key_code&lt;/span&gt;(keypad, gpio_val);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (gpio_val &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].current_status &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				is_pressing &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (is_pressing)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;mod_timer&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				  jiffies &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				  &lt;span style=&#34;color:#a6e22e&#34;&gt;msecs_to_jiffies&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;scan_period));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {&lt;span style=&#34;color:#75715e&#34;&gt;/* polling mode */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			gpio_val &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;gpiod_get_value&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].desc);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			gpio_val &lt;span style=&#34;color:#f92672&#34;&gt;|=&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].ignore;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].current_status &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; gpio_val) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].count&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;current_key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;report_key_code&lt;/span&gt;(keypad, gpio_val);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;mod_timer&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			  jiffies &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;msecs_to_jiffies&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;scan_period));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ssize_t&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;table_show&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;cls, &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class_attribute &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;attr,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			  &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;buf)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;container_of&lt;/span&gt;(cls,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad, kp_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; len &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		len &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sprintf&lt;/span&gt;(buf &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; len,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[%d]: name = %-21s status = %-5d&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, i,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].name,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].current_status);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; len;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ssize_t&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ignore_show&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;cls, &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class_attribute &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;attr, &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;buf)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;container_of&lt;/span&gt;(cls, &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad, kp_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; index;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; len &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; index &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; index&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		len &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sysfs_emit_at&lt;/span&gt;(buf, len, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%s,%d: %c&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				     keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].name,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				     keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].code,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				     keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].ignore &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Y&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;N&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; len;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ssize_t&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ignore_store&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;cls, &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class_attribute &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;attr,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			    &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;buf, &lt;span style=&#34;color:#66d9ef&#34;&gt;size_t&lt;/span&gt; count)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;container_of&lt;/span&gt;(cls, &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad, kp_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; device &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;dev &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.parent;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; nbuf[&lt;span style=&#34;color:#ae81ff&#34;&gt;128&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; tmp[&lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; index;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;value &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nbuf;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;name;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; ignore;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; found;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (count &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(nbuf)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;data is too long&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;memcpy&lt;/span&gt;(nbuf, buf, count);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;strreplace&lt;/span&gt;(nbuf, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;strsep&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;value, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; err;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;strcmp&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;all&amp;#34;&lt;/span&gt;, name)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; index &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; index&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].ignore &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; true;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_dbg&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ignore all keys&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;strcmp&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;, name)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; index &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; index&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].ignore &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_dbg&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;enable all keys&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;value)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; err;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;kstrtobool&lt;/span&gt;(value, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;ignore)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;invalid &amp;#39;%s&amp;#39;, please use Y/N instead&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, value);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;/* search key */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		found &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; index &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; index&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;snprintf&lt;/span&gt;(tmp, &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(tmp), &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%s,%d&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				 keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].name,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				 keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].code);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;strcmp&lt;/span&gt;(tmp, name)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				found &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; true;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;found) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;invalid key &amp;#39;%s&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, name);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].ignore &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ignore;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_dbg&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ignore %s: %s&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, name, value);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; count;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;err:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;the correct format is: [name],[code] [ignore]&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CLASS_ATTR_RO&lt;/span&gt;(table);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CLASS_ATTR_RW&lt;/span&gt;(ignore);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; attribute &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;meson_gpiokey_attrs[] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;class_attr_table.attr,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;class_attr_ignore.attr,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	NULL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ATTRIBUTE_GROUPS&lt;/span&gt;(meson_gpiokey);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Add show function for reset count
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ssize_t&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;count_show&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;cls, &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; class_attribute &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;attr,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;buf)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;container_of&lt;/span&gt;(cls,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad, resetkey_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sprintf&lt;/span&gt;(buf, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%u&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;reset_count);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CLASS_ATTR_RO&lt;/span&gt;(count);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; attribute &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;resetkey_attrs[] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;class_attr_count.attr,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    NULL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ATTRIBUTE_GROUPS&lt;/span&gt;(resetkey);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_probe&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; platform_device &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;pdev)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_desc &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;desc;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; ret, i;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; input_dev &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;input_dev;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; irq_desc &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;d;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; number;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; wakeup_source &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; register_flag &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;(pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.of_node)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pdev-&amp;gt;dev.of_node == NULL!&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;devm_kzalloc&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			      &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad), GFP_KERNEL);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;keypad)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;of_property_read_u32&lt;/span&gt;(pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.of_node,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;detect_mode&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;use_irq);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;/* The default mode is polling. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;use_irq &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; DEFAULT_POLL_MODE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;of_property_read_u32&lt;/span&gt;(pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.of_node,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;scan_period&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;scan_period);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;/* he default scan period is 20. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;scan_period &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; DEFAULT_SCAN_PERION;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;of_property_read_bool&lt;/span&gt;(pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.of_node, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;wakeup-source&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		wakeup_source &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;of_property_read_u32&lt;/span&gt;(pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.of_node,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key_num&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to get key_num!&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;devm_kzalloc&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				   (keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size) &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				   GFP_KERNEL);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;/* get all gpio desc. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		desc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;devm_gpiod_get_index&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key&amp;#34;&lt;/span&gt;, i, GPIOD_IN);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;IS_ERR_OR_NULL&lt;/span&gt;(desc))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].desc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; desc;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;/* The gpio default is high level. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].current_status &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;of_property_read_u32_index&lt;/span&gt;(pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.of_node,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;						 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key_code&amp;#34;&lt;/span&gt;, i,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;						 &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].code);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;find key_code=%d finished&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, i);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;of_property_read_u32_index&lt;/span&gt;(pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.of_node,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;						 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key_type&amp;#34;&lt;/span&gt;, i,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;						 &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].key_type);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].key_type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; EV_KEY;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;of_property_read_string_index&lt;/span&gt;(pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.of_node,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;						    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key_name&amp;#34;&lt;/span&gt;, i,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;						    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].name);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;find key_name=%d finished&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, i);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;gpiod_direction_input&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].desc);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;gpiod_set_pull&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].desc, GPIOD_PULL_UP);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;kp_class.name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gpio_keypad&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;kp_class.owner &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; THIS_MODULE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;kp_class.class_groups &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpiokey_groups;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class_register&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;kp_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fail to create gpio keypad class.&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// After registering kp_class, add resetkey class registration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;resetkey_class.name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;resetkey&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;resetkey_class.owner &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; THIS_MODULE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;resetkey_class.class_groups &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; resetkey_groups;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;reset_count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class_register&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;resetkey_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fail to create resetkey class.&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;class_unregister&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;kp_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;/* input */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;input_allocate_device&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;input_dev)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;input_set_capability&lt;/span&gt;(input_dev, keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].key_type,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				     keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].code);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_dbg&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%s key(%d) type(0x%x) registered.&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			 keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].name, keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].code,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			 keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].key_type);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gpio_keypad&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;phys &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gpio_keypad/input0&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev.parent &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;id.bustype &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; BUS_ISA;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;id.vendor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0001&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;id.product &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0001&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;id.version &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0100&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;rep[REP_DELAY] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xffffffff&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;rep[REP_PERIOD] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xffffffff&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;keycodesize &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;short&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input_dev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;keycodemax &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x1ff&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; input_dev;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;input_register_device&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;input_free_device&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;platform_set_drvdata&lt;/span&gt;(pdev, keypad);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;timer_setup&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		    polling_timer_handler, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;use_irq) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].irq_num &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;gpiod_to_irq&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].desc);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;devm_request_irq&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					       keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].irq_num,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					       gpio_irq_handler,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					       IRQF_TRIGGER_FALLING,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					       &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gpio_keypad&amp;#34;&lt;/span&gt;, keypad);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Requesting irq failed!&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;input_free_device&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;del_timer&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].code &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; KEY_POWER) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				d &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;irq_to_desc&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].irq_num);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (d) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					number &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					 d&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;irq_data.parent_data&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;hwirq &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					&lt;span style=&#34;color:#a6e22e&#34;&gt;pwr_ctrl_irq_set&lt;/span&gt;(number, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					register_flag &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;mod_timer&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			  jiffies &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;msecs_to_jiffies&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;scan_period));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (wakeup_source) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (register_flag)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_dbg&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;succeed to register wakeup source!&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdev&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to register wakeup source!&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_remove&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; platform_device &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;pdev)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;platform_get_drvdata&lt;/span&gt;(pdev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;class_unregister&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;resetkey_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;class_unregister&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;kp_class);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;input_unregister_device&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;input_free_device&lt;/span&gt;(keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;del_timer&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; of_device_id key_dt_match[] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	{ .compatible &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;amlogic, gpio_keypad&amp;#34;&lt;/span&gt;, },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	{}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_suspend&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; device &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;dev)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;pdata;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	pdata &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_get_drvdata&lt;/span&gt;(dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;use_irq)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;del_timer&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_resume&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; device &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;dev)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;pdata;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	pdata &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_get_drvdata&lt;/span&gt;(dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;use_irq)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;mod_timer&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;polling_timer,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			  jiffies &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;msecs_to_jiffies&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;get_resume_method&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; POWER_KEY_WAKEUP) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[i].code &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; KEY_POWER) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_dbg&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gpio keypad wakeup&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;input_report_key&lt;/span&gt;(pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;						 KEY_POWER,  &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;input_sync&lt;/span&gt;(pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;input_report_key&lt;/span&gt;(pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;						 KEY_POWER,  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;input_sync&lt;/span&gt;(pdata&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;input_dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_restore&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; device &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;dev)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dev_get_drvdata&lt;/span&gt;(dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_desc &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;desc;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; index;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; index &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; index&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		desc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;devm_gpiod_get_index&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key&amp;#34;&lt;/span&gt;, index, GPIOD_IN);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;IS_ERR_OR_NULL&lt;/span&gt;(desc)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;dev_err&lt;/span&gt;(dev, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to request to gpio while restore&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;gpiod_direction_input&lt;/span&gt;(desc);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;gpiod_set_pull&lt;/span&gt;(desc, GPIOD_PULL_UP);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].desc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; desc;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_resume&lt;/span&gt;(dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_freeze&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; device &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;dev)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; gpio_keypad &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;keypad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dev_get_drvdata&lt;/span&gt;(dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; index;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; ret;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_suspend&lt;/span&gt;(dev);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; ret;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; index &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key_size; index&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;devm_gpiod_put&lt;/span&gt;(dev, keypad&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key[index].desc);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; dev_pm_ops meson_gpio_kp_pm_ops &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.suspend &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpio_kp_suspend,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.resume &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpio_kp_resume,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.freeze &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpio_kp_freeze,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.thaw &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpio_kp_resume,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.poweroff &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpio_kp_suspend,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.restore &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpio_kp_restore,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; platform_driver meson_gpio_kp_driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.probe &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpio_kp_probe,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.remove &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; meson_gpio_kp_remove,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	.driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		.name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gpio-keypad&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		.pm &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;meson_gpio_kp_pm_ops,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		.of_match_table &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; key_dt_match,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	},
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; __init &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_init&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;platform_driver_register&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;meson_gpio_kp_driver);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; __exit &lt;span style=&#34;color:#a6e22e&#34;&gt;meson_gpio_kp_exit&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;platform_driver_unregister&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;meson_gpio_kp_driver);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id=&#34;逐函数解释&#34;&gt;逐函数解释&lt;/h1&gt;
&lt;p&gt;以下按代码物理顺序，逐个函数解释它干了什么。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 5 扩展与总结：GPIO 子系统深度分析</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-5-%E6%80%BB%E7%BB%93%E4%B8%8E%E6%89%A9%E5%B1%95/</link>
      <pubDate>Tue, 09 Jun 2026 15:03:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-5-%E6%80%BB%E7%BB%93%E4%B8%8E%E6%89%A9%E5%B1%95/</guid>
      <description>&lt;h1 id=&#34;level-5-扩展与总结gpio-子系统深度分析&#34;&gt;Level 5 扩展与总结：GPIO 子系统深度分析&lt;/h1&gt;
&lt;p&gt;本文是 &lt;a href=&#34;level-5-GPIO.md&#34;&gt;level-5-GPIO.md&lt;/a&gt; 的延伸，记录从编写 &lt;code&gt;fun_led.c&lt;/code&gt; 到发现 &lt;code&gt;leds-gpio&lt;/code&gt; 现成方案过程中，对 GPIO 子系统的深度分析。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;1-驱动分析硬编码-gpio-的问题&#34;&gt;1. 驱动分析：硬编码 GPIO 的问题&lt;/h2&gt;
&lt;p&gt;当前 &lt;code&gt;fun_led.c&lt;/code&gt; 采用的是&lt;strong&gt;硬编码 GPIO 编号&lt;/strong&gt;方式：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define LED_GPIO  28   &lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* 写死在代码里的 GPIO 编号 */&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;gpio_request&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;28&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fun_led&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;gpio_set_value&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;28&lt;/span&gt;, val);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;硬编码带来的三个风险&#34;&gt;硬编码带来的三个风险&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;风险 1：内核升级，编号体系变化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;LED_GPIO 28&lt;/code&gt; 对应 S7D 的 GPIOD_4。这个 28 来自 &lt;code&gt;meson-s7d-gpio.h&lt;/code&gt; 中 pins 数组的排列顺序。如果 Amlogic 在新内核 BSP 中调整了 pins 数组顺序（例如把 E 组排到 D 组之后），GPIOD_4 的编号就不再是 28 了。驱动里写死的 28 会指向错误的 pin。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;风险 2：换板子不可用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;同一份 &lt;code&gt;fun_led.c&lt;/code&gt; 源码，想在另一个 S905 型号（比如 S6、S4D）上使用。S6 的 GPIOD_4 = 4，S4D 的 GPIOD_4 可能又是另一个编号。驱动里写着 28，换板子必炸。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 5：操作 GPIO</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-5-gpio/</link>
      <pubDate>Tue, 09 Jun 2026 15:02:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-5-gpio/</guid>
      <description>&lt;h1 id=&#34;level-5操作-gpio&#34;&gt;Level 5：操作 GPIO&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;控制板子上的一个物理引脚，让它输出高/低电平，用万用表或 LED 确认电平变化。&lt;/p&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GPIO 在系统里是以什么方式呈现的？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;物理上：芯片的一个管脚，可以设置输出高/低电平或读取输入电平&lt;/li&gt;
&lt;li&gt;代码上：GPIO controller 是一个硬件模块，通过寄存器操作&lt;/li&gt;
&lt;li&gt;给用户的接口：sysfs 或 libgpiod，或者自己写驱动操作寄存器&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;设备树（DTS）和驱动是什么关系？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DTS 描述硬件有什么、接在哪个总线、地址/中断号是什么&lt;/li&gt;
&lt;li&gt;驱动根据 DTS 的信息来初始化硬件&lt;/li&gt;
&lt;li&gt;同一个驱动可以支持多个 DTS 描述的实例&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;你的板子的 GPIO 信息从哪儿来？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原理图（PDF）——告诉你在板子上哪个排针/接口引出了哪个 GPIO&lt;/li&gt;
&lt;li&gt;DTS——告诉内核哪个 GPIO controller 对应哪个基地址&lt;/li&gt;
&lt;li&gt;datasheet——详细到每个寄存器的位定义&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;需要懂的知识&#34;&gt;需要懂的知识&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;GPIO 子系统&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;内核用 gpiolib 统一管理 GPIO。用户态访问 GPIO 有两种方式：&lt;/p&gt;
&lt;p&gt;旧方式（sysfs，kernel &amp;lt; 5.10）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt; &amp;gt; /sys/class/gpio/export
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo out &amp;gt; /sys/class/gpio/gpio100/direction
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &amp;gt; /sys/class/gpio/gpio100/value
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;新方式（libgpiod，kernel &amp;gt;= 5.10）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpioinfo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpioset gpiochip0 100&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;你的内核是 5.15，优先用 libgpiod。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ioremap 的作用&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 4 总结与扩展</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-4-%E6%80%BB%E7%BB%93%E4%B8%8E%E6%89%A9%E5%B1%95/</link>
      <pubDate>Tue, 09 Jun 2026 15:01:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-4-%E6%80%BB%E7%BB%93%E4%B8%8E%E6%89%A9%E5%B1%95/</guid>
      <description>&lt;h1 id=&#34;level-4-总结与扩展&#34;&gt;Level 4 总结与扩展&lt;/h1&gt;
&lt;h2 id=&#34;总结一个字符驱动的完整生命周期&#34;&gt;总结：一个字符驱动的完整生命周期&lt;/h2&gt;
&lt;p&gt;Level 4 的核心命题——&amp;ldquo;写一个内核模块，用户态能读能写&amp;rdquo;——拆解为三层：&lt;strong&gt;内核侧（驱动代码）→ 构建侧（编译系统）→ 运行侧（板子验证）&lt;/strong&gt;。下面逐层复盘，标注优先级。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;第一层内核侧--驱动代码本身&#34;&gt;第一层：内核侧 —— 驱动代码本身&lt;/h3&gt;
&lt;p&gt;这层是&lt;strong&gt;跨平台通用&lt;/strong&gt;的 Linux 驱动知识，与 Android 构建系统无关。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;🔴 核心必懂&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;知识点&lt;/th&gt;
          &lt;th&gt;一句话&lt;/th&gt;
          &lt;th&gt;关联的坑&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;file_operations&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;驱动的&amp;quot;函数表&amp;quot;——把用户态的系统调用（open/read/write）映射成驱动函数&lt;/td&gt;
          &lt;td&gt;多态机制，所有字符驱动公用&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;register_chrdev(0, name, &amp;amp;fops)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;向内核注册字符设备，参数 0 让内核自动分配主设备号&lt;/td&gt;
          &lt;td&gt;返回值是主设备号，mknod 需要它&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;copy_from_user&lt;/code&gt; / &lt;code&gt;copy_to_user&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;内核与用户空间之间的安全数据拷贝&lt;/td&gt;
          &lt;td&gt;不能直接用 &lt;code&gt;memcpy&lt;/code&gt;——见下方说明&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;dev_read&lt;/code&gt; 必须返回 0 表示 EOF&lt;/td&gt;
          &lt;td&gt;VFS 规范：当数据读完时必须返回 &lt;code&gt;0&lt;/code&gt;，否则 &lt;code&gt;cat&lt;/code&gt; 等工具无限循环&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;L4-05 bug&lt;/strong&gt;：忘记返回 0，cat 死循环&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;module_init&lt;/code&gt; / &lt;code&gt;module_exit&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;模块加载/卸载的入口和出口&lt;/td&gt;
          &lt;td&gt;卸载时未 &lt;code&gt;unregister_chrdev&lt;/code&gt; 会导致空悬设备节点&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;为什么不能用 &lt;code&gt;memcpy&lt;/code&gt; 替代 &lt;code&gt;copy_to_user&lt;/code&gt;？&lt;/strong&gt; 三个原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;安全校验&lt;/strong&gt;：&lt;code&gt;copy_to_user&lt;/code&gt; 会检查用户态指针是否在当前进程的地址空间内，防止内核被伪造指针攻击&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺页处理&lt;/strong&gt;：用户态内存可能被换出（swap），&lt;code&gt;copy_to_user&lt;/code&gt; 能触发缺页中断把页面换回来，&lt;code&gt;memcpy&lt;/code&gt; 做不到&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SMAP/PAN 硬件保护&lt;/strong&gt;：ARMv8.1+ 有 PAN（Privileged Access Never）特性，内核态默认禁止直接访问用户态内存，&lt;code&gt;copy_to_user&lt;/code&gt; 会临时关闭此保护&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;VFS 调用链路&lt;/strong&gt;（用户态 &lt;code&gt;open(&amp;quot;/dev/simple_char&amp;quot;)&lt;/code&gt; → 驱动 &lt;code&gt;dev_open()&lt;/code&gt;）：&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 4：写一个字符设备驱动</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-4-%E5%AD%97%E7%AC%A6%E9%A9%B1%E5%8A%A8/</link>
      <pubDate>Tue, 09 Jun 2026 15:00:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-4-%E5%AD%97%E7%AC%A6%E9%A9%B1%E5%8A%A8/</guid>
      <description>&lt;h1 id=&#34;level-4写一个字符设备驱动&#34;&gt;Level 4：写一个字符设备驱动&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;在内核里加一个最小内核模块，用户态 &lt;code&gt;echo &amp;quot;hi&amp;quot; &amp;gt; /dev/simple_char&lt;/code&gt; 能写进去，&lt;code&gt;cat /dev/simple_char&lt;/code&gt; 能读出来。&lt;/p&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内核驱动和用户态程序的根本区别是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;驱动运行在内核态，可以访问所有硬件资源和内存&lt;/li&gt;
&lt;li&gt;用户态程序通过系统调用（open/read/write/ioctl）请求内核代为操作&lt;/li&gt;
&lt;li&gt;内核态出错 → 整个系统崩溃（kernel panic）；用户态出错 → 只崩那个进程&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Linux 设备驱动分哪几类？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;字符设备&lt;/strong&gt;──像文件一样 open/read/write/close，顺序访问。例子：串口（&lt;code&gt;/dev/ttyAML0&lt;/code&gt;）、GPIO、I2C、SPI、按键。你的板子上 &lt;code&gt;ls -l /dev/&lt;/code&gt; 看到前面是 &lt;code&gt;c&lt;/code&gt; 的都是字符设备&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;块设备&lt;/strong&gt;──按块随机读写，有缓存层。例子：eMMC（&lt;code&gt;/dev/block/mmcblk0&lt;/code&gt;）、U 盘、SD 卡。前面是 &lt;code&gt;b&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网络设备&lt;/strong&gt;──通过 socket 接口访问，不通过文件系统。例子：以太网（eth0）、WiFi（wlan0）。&lt;code&gt;ip link show&lt;/code&gt; 看到的就是&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你的板子上跑 &lt;code&gt;adb shell ls -l /dev/ | head -20&lt;/code&gt;，看看哪些是字符设备（c）、哪些是块设备（b）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;什么是 file_operations？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它是一个结构体，里面全是函数指针&lt;/li&gt;
&lt;li&gt;每个字符驱动需要告诉内核：&amp;ldquo;当用户调用 open() 时，执行我这个函数；调用 read() 时，执行我那个函数&amp;rdquo;&lt;/li&gt;
&lt;li&gt;这是一个多态机制——不同的驱动实现相同的接口，用户态不用关心底层实现&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;需要懂的知识&#34;&gt;需要懂的知识&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;驱动模块的骨架&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每个内核模块都有两个必经的函数：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;module_init&lt;/span&gt;(mod_init);   &lt;span style=&#34;color:#75715e&#34;&gt;// insmod 时调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;module_exit&lt;/span&gt;(mod_exit);   &lt;span style=&#34;color:#75715e&#34;&gt;// rmmod 时调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;__init&lt;/code&gt; 和 &lt;code&gt;__exit&lt;/code&gt; 标记：这些函数在运行完后可以释放内存。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 9：修复一个 SELinux 权限问题</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-9-selinux/</link>
      <pubDate>Tue, 09 Jun 2026 14:03:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-9-selinux/</guid>
      <description>&lt;h1 id=&#34;level-9修复一个-selinux-权限问题&#34;&gt;Level 9：修复一个 SELinux 权限问题&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;当一个服务因为 SELinux 权限被拒绝而启动失败时，能独立定位并修复。这是 Android 嵌入式开发中最常见的调试场景。&lt;/p&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SELinux 在 Android 上到底保护什么？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有 SELinux：一个进程拿到 root 就可以做任何事（读所有文件、杀其他进程、控制硬件）&lt;/li&gt;
&lt;li&gt;有 SELinux：每个进程被限制在最小的权限域中（principle of least privilege）&lt;/li&gt;
&lt;li&gt;即使进程是 root 用户，SELinux 仍然会拒绝未经授权的操作&lt;/li&gt;
&lt;li&gt;avc: denied = SELinux 告诉你&amp;quot;这个操作不在你的权限范围内&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;domain 和 type 是什么关系？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;domain 是进程的标签（你是什么）&lt;/li&gt;
&lt;li&gt;type 是文件/资源的标签（这是什么）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;allow domain type:class { permission }&lt;/code&gt; = &amp;ldquo;谁 对什么 做什么&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;audit2allow 的原理？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从 &lt;code&gt;dmesg&lt;/code&gt; 或 &lt;code&gt;/proc/avc&lt;/code&gt; 中读取 avc denied 日志&lt;/li&gt;
&lt;li&gt;自动解析出需要的 &lt;code&gt;allow&lt;/code&gt; 语句&lt;/li&gt;
&lt;li&gt;但注意：&lt;code&gt;audit2allow&lt;/code&gt; 只是工具，直接套用可能给过多权限，要人工审查&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;需要懂的知识&#34;&gt;需要懂的知识&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;avc denied 日志解读&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 8：App 点一下控制板子上的 LED</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-8-%E5%85%A8%E9%93%BE%E8%B7%AF/</link>
      <pubDate>Tue, 09 Jun 2026 14:02:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-8-%E5%85%A8%E9%93%BE%E8%B7%AF/</guid>
      <description>&lt;h1 id=&#34;level-8app-点一下控制板子上的-led&#34;&gt;Level 8：App 点一下控制板子上的 LED&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;在手机上装一个自己写的 App，点一下按钮，板子上的物理 LED 亮或灭。打通从 App 到 GPIO 寄存器的完整链路。&lt;/p&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;App 是怎么跟硬件通信的？&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;App (Java)
  ↓ Binder IPC
Native Service (C++)
  ↓ hw_get_module()
HAL (xxx_module_t)
  ↓ open(&amp;#34;/dev/xxx&amp;#34;)
Kernel Driver
  ↓ writel()
GPIO 寄存器
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;每一层都是独立的模块，层与层之间有标准接口。替换其中任何一层不影响其他层。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;HAL 解决了什么问题？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有 HAL 之前：App 直接 open/ioctl 设备节点&lt;/li&gt;
&lt;li&gt;问题：驱动接口变了，所有 App 都得改&lt;/li&gt;
&lt;li&gt;HAL 的解决：给上层提供稳定的抽象接口，驱动变化只改 HAL 实现，不涉及 Framework 和 App&lt;/li&gt;
&lt;li&gt;在 Treble 架构中，HAL 更是 vendor 和 system 的契约边界&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Binder 是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android 特有的 IPC（进程间通信）机制&lt;/li&gt;
&lt;li&gt;App 和 Native Service 是不同进程，不能直接函数调用&lt;/li&gt;
&lt;li&gt;Binder 让它们像调用本地函数一样跨进程通信&lt;/li&gt;
&lt;li&gt;Binder 还负责权限校验——ServiceManager 检查调用方有没有权限访问某个服务&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;需要懂的知识&#34;&gt;需要懂的知识&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ioctl 驱动的写法（在 Level 4 驱动基础上扩展）&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 7：追踪完整启动流程</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-7-%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B/</link>
      <pubDate>Tue, 09 Jun 2026 14:01:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-7-%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B/</guid>
      <description>&lt;h1 id=&#34;level-7追踪完整启动流程&#34;&gt;Level 7：追踪完整启动流程&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;从上电到 Launcher，完整追踪一次 S905X5M 的启动过程，每个阶段都能在代码中找到对应位置。&lt;/p&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Amlogic 的启动链和通用 Linux 有什么不同？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通用嵌入式：ROM Code → Bootloader → Kernel → init&lt;/li&gt;
&lt;li&gt;Amlogic：ROM Code → BL2（DDR 初始化） → BL30/SPL → U-Boot → Kernel → init&lt;/li&gt;
&lt;li&gt;多出来的 BL2 和 BL30 是 Amlogic 私有的二进制固件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ROM Code 怎么找到下一阶段的代码？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;芯片上电后，内部 ROM 中的固化代码执行&lt;/li&gt;
&lt;li&gt;根据 boot mode 引脚的电平（eMMC/SD 卡/USB burning），去对应介质读取 bootloader&lt;/li&gt;
&lt;li&gt;这是芯片设计时固定的，不能修改&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内核解压后，第一个用户态进程是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PID 1 → init 进程&lt;/li&gt;
&lt;li&gt;init 解析 &lt;code&gt;init.rc&lt;/code&gt; → 启动核心服务（servicemanager、surfaceflinger 等）&lt;/li&gt;
&lt;li&gt;zygote（Android Java 虚拟机） → 启动 system_server → 启动 Launcher&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;需要懂的知识&#34;&gt;需要懂的知识&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;启动级联图&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Level 6：GPIO 按键 — 从设备树到 input 子系统</title>
      <link>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-6-%E6%8C%89%E9%94%AE/</link>
      <pubDate>Tue, 09 Jun 2026 14:00:00 +0800</pubDate>
      <guid>https://luojmarkdown.pages.dev/posts/%E7%BB%83%E4%B9%A0%E5%AE%9E%E6%93%8D/level-6-%E6%8C%89%E9%94%AE/</guid>
      <description>&lt;h1 id=&#34;level-6gpio-按键--从设备树到-input-子系统&#34;&gt;Level 6：GPIO 按键 — 从设备树到 input 子系统&lt;/h1&gt;
&lt;h2 id=&#34;我想做&#34;&gt;我想做&lt;/h2&gt;
&lt;p&gt;板子上有一个丝印 &lt;strong&gt;USER_KEY&lt;/strong&gt; 的物理按键（接在 &lt;strong&gt;GPIOD_2&lt;/strong&gt;），按下它能被 Linux input 子系统识别到事件，并理解从 DTS → 驱动 → sysfs → /dev/input/eventX 的完整链路。&lt;/p&gt;
&lt;h2 id=&#34;先回答三个问题&#34;&gt;先回答三个问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Linux 怎么知道一个 GPIO 是按键而不是 LED？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DTS 中的 &lt;code&gt;compatible&lt;/code&gt; 决定匹配哪个驱动。LED 用 &lt;code&gt;&amp;quot;gpio-leds&amp;quot;&lt;/code&gt;，按键用 &lt;code&gt;&amp;quot;amlogic, gpio_keypad&amp;quot;&lt;/code&gt;（或主线 &lt;code&gt;&amp;quot;gpio-keys&amp;quot;&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;驱动根据 compatible 字符串被内核匹配并 probe，在 probe 中注册 input 设备&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;按键事件是怎么从硬件传到 App 的？&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;手指按下 → GPIO 电平变化 → 驱动检测（polling/irq）
  → input_report_key() → input_sync()
    → /dev/input/eventX → App 通过 getevent / InputReader 读取
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;每一层都是标准接口，App 不关心 GPIO 编号，只读 keycode。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
