#define GPIO_EVENT_DEV_NAME "gpio-event"
1,定义
static struct gpio_keys_button gpio_keys_buttons[] = {
{
.code = SW_LID,
.gpio = LID_SENSOR_GPIO,
.desc = "Lid",
.active_low = 1,
.type= EV_SW,
.wakeup= 1
},
};
static struct gpio_keys_platform_data gpio_keys_data = {
.buttons = gpio_keys_buttons,
.nbuttons = ARRAY_SIZE(gpio_keys_buttons),
.rep= 0,
};
static struct platform_device msm_gpio_keys = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &gpio_keys_data,
},
};
2,
/* drivers/input/misc/gpio_event.c
*
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/earlysuspend.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/gpio_event.h>
#include <linux/hrtimer.h>
#include <linux/platform_device.h>
struct gpio_event {
struct gpio_event_input_devs *input_devs;
const struct gpio_event_platform_data *info;
struct early_suspend early_suspend;
void *state[0];
};
static int gpio_input_event(
struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
int i;
int devnr;
int ret = 0;
int tmp_ret;
struct gpio_event_info **ii;
struct gpio_event *ip = input_get_drvdata(dev);
for (devnr = 0; devnr < ip->input_devs->count; devnr++)
if (ip->input_devs->dev[devnr] == dev)
break;
if (devnr == ip->input_devs->count) {
pr_err("gpio_input_event: unknown device %p/n", dev);
return -EIO;
}
for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) {
if ((*ii)->event) {
tmp_ret = (*ii)->event(ip->input_devs, *ii,
&ip->state[i],
devnr, type, code, value);
if (tmp_ret)
ret = tmp_ret;
}
}
return ret;
}
static int gpio_event_call_all_func(struct gpio_event *ip, int func)
{
int i;
int ret;
struct gpio_event_info **ii;
if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) {
ii = ip->info->info;
for (i = 0; i < ip->info->info_count; i++, ii++) {
if ((*ii)->func == NULL) {
ret = -ENODEV;
pr_err("gpio_event_probe: Incomplete pdata, "
"no function/n");
goto err_no_func;
}
if (func == GPIO_EVENT_FUNC_RESUME && (*ii)->no_suspend)
continue;
ret = (*ii)->func(ip->input_devs, *ii, &ip->state[i],
func);
if (ret) {
pr_err("gpio_event_probe: function failed/n");
goto err_func_failed;
}
}
return 0;
}
ret = 0;
i = ip->info->info_count;
ii = ip->info->info + i;
while (i > 0) {
i--;
ii--;
if ((func & ~1) == GPIO_EVENT_FUNC_SUSPEND && (*ii)->no_suspend)
continue;
(*ii)->func(ip->input_devs, *ii, &ip->state[i], func & ~1);
err_func_failed:
err_no_func:
;
}
return ret;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
void gpio_event_suspend(struct early_suspend *h)
{
struct gpio_event *ip;
ip = container_of(h, struct gpio_event, early_suspend);
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND);
ip->info->power(ip->info, 0);
}
void gpio_event_resume(struct early_suspend *h)
{
struct gpio_event *ip;
ip = container_of(h, struct gpio_event, early_suspend);
ip->info->power(ip->info, 1);
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME);
}
#endif
static int __init gpio_event_probe(struct platform_device *pdev)
{
int err;
struct gpio_event *ip;
struct gpio_event_platform_data *event_info;
int dev_count = 1;
int i;
int registered = 0;
event_info = pdev->dev.platform_data;
if (event_info == NULL) {
pr_err("gpio_event_probe: No pdata/n");
return -ENODEV;
}
if ((!event_info->name && !event_info->names[0]) ||
!event_info->info || !event_info->info_count) {
pr_err("gpio_event_probe: Incomplete pdata/n");
return -ENODEV;
}
if (!event_info->name)
while (event_info->names[dev_count])
dev_count++;
ip = kzalloc(sizeof(*ip) +
sizeof(ip->state[0]) * event_info->info_count +
sizeof(*ip->input_devs) +
sizeof(ip->input_devs->dev[0]) * dev_count, GFP_KERNEL);
if (ip == NULL) {
err = -ENOMEM;
pr_err("gpio_event_probe: Failed to allocate private data/n");
goto err_kp_alloc_failed;
}
ip->input_devs = (void*)&ip->state[event_info->info_count];
platform_set_drvdata(pdev, ip);
for (i = 0; i < dev_count; i++) {
struct input_dev *input_dev = input_allocate_device();
if (input_dev == NULL) {
err = -ENOMEM;
pr_err("gpio_event_probe: "
"Failed to allocate input device/n");
goto err_input_dev_alloc_failed;
}
input_set_drvdata(input_dev, ip);
input_dev->name = event_info->name ?
event_info->name : event_info->names[i];
input_dev->event = gpio_input_event;
ip->input_devs->dev[i] = input_dev;
}
ip->input_devs->count = dev_count;
ip->info = event_info;
if (event_info->power) {
#ifdef CONFIG_HAS_EARLYSUSPEND
ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
ip->early_suspend.suspend = gpio_event_suspend;
ip->early_suspend.resume = gpio_event_resume;
register_early_suspend(&ip->early_suspend);
#endif
ip->info->power(ip->info, 1);
}
err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
if (err)
goto err_call_all_func_failed;
for (i = 0; i < dev_count; i++) {
err = input_register_device(ip->input_devs->dev[i]);
if (err) {
pr_err("gpio_event_probe: Unable to register %s "
"input device/n", ip->input_devs->dev[i]->name);
goto err_input_register_device_failed;
}
registered++;
}
return 0;
err_input_register_device_failed:
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
err_call_all_func_failed:
if (event_info->power) {
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&ip->early_suspend);
#endif
ip->info->power(ip->info, 0);
}
for (i = 0; i < registered; i++)
input_unregister_device(ip->input_devs->dev[i]);
for (i = dev_count - 1; i >= registered; i--) {
input_free_device(ip->input_devs->dev[i]);
err_input_dev_alloc_failed:
;
}
kfree(ip);
err_kp_alloc_failed:
return err;
}
static int gpio_event_remove(struct platform_device *pdev)
{
struct gpio_event *ip = platform_get_drvdata(pdev);
int i;
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
if (ip->info->power) {
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&ip->early_suspend);
#endif
ip->info->power(ip->info, 0);
}
for (i = 0; i < ip->input_devs->count; i++)
input_unregister_device(ip->input_devs->dev[i]);
kfree(ip);
return 0;
}
static struct platform_driver gpio_event_driver = {
.probe= gpio_event_probe,
.remove= gpio_event_remove,
.driver= {
.name= GPIO_EVENT_DEV_NAME,
},
};
static int __devinit gpio_event_init(void)
{
return platform_driver_register(&gpio_event_driver);
}
static void __exit gpio_event_exit(void)
{
platform_driver_unregister(&gpio_event_driver);
}
module_init(gpio_event_init);
module_exit(gpio_event_exit);
MODULE_DESCRIPTION("GPIO Event Driver");
MODULE_LICENSE("GPL");
注册gpio键盘,设置gpio为输入状态,注册gpio的中断回调函数,设置gpio的唤醒功能
分享到:
相关推荐
文中仿真源码和原理图尽可能的接近实物 实测两者差异性极小 从理论学习的角度来看,基于仿真完全可以达到学习目的 从实践的角度来看,通过简单移植和调试可将仿真转换成实物 功能概述 使用51单片机基础外设GPIO进行...
学习k60 GPIO ,了解掌握独立按键和矩阵键盘的使用方面及其原理
使用PCF8574 / PCF8574A I2C GPIO,仅使用2个Arduino引脚连接矩阵键盘-轻松快捷!
如图 8×8键盘扩展电路原理 此设计通过CPLD的GPIO扩展8×8键盘,与处理器接口仅需要7个GPIO。CPLD的6位编码输出可以代表64个按键,但是必须有一个状态表示空闲状态,因此图方案只可以实现63个按键编码。如果需要...
如图 8×8键盘扩展电路原理 此设计通过CPLD的GPIO扩展8×8键盘,与处理器接口仅需要7个GPIO。CPLD的6位编码输出可以代表64个按键,但是必须有一个状态表示空闲状态,因此图方案只可以实现63个按键编码。如果需要...
该驱动基于imx6硬件平台,linux内核版本为3.14,矩阵键盘驱动IC为...原理:max7349与cpu通过i2c通信,当有按键按下,max7349扫描到该事件,产生一个脉冲发往cpu,cpu通过GPIO中断来检测该事件。该通过i2c总线读取键值。
Driver Get Started 1 Preface 2 Declaration: 2 ...键盘原理 24 GPIO 29 触摸屏 32 显示设备 38 Camera模块 47 FMRDS模块 57 蓝牙模块 62 CMMB 67 双模双待 68 USB模块 68 GPS模块 70 红外(IrDA)模块 70
2.3.5 键盘接口基本原理与结构 2.3.6 显示接口基本原理与结构 2.3.7 触摸屏接口基本原理与结构 2.3.8 音频接口基本原理与结构 2.4 嵌入式系统总线接口 2.5 嵌入式系统网络接口 2.6 嵌入式系统电源 2.7电子电路设计...
这里通过按键改变引脚的输入电平高低,当引脚上接入高电平时,其输入数据寄存器对应的位将置1,而当引脚上接入低电平时,将清0;程序对引脚的输入数据进行判断,并控制LED的亮灭。 由于笔者蓝色的最小系统板没有设置...
17、 提供4个按键输入,用于GPIO键盘试验,其中一个兼顾外部中断试验 18、 提供4位拨码开关 19、 提供复位芯片MAX811,复位可靠,独立复位按钮可手工复位 20、 提供1 路RS-232 接口,可连接PC 进行通信 21、 提供1 ...
6~12章分别介绍GPIO的应用(键盘、LED及LCD)、定时器(含PWM)、串行外设接口SPI、Flash存储器在线编程、CAN总线、A/D转换及S12XS128其他模块等。附录给出相关资料。《嵌入式系统设计实战:基于飞思卡尔S12X微控制...
第5章介绍了嵌入式系统的GPIO、A/D转换器接口、D/A转换器接口、键盘与LE D数码管接口、LCD显示接口、触摸屏接口的基本原理、电路结构与编程方法。 第6章介绍了嵌入式系统的串行接口、I2C接口、USB接口、SPI接口、PCI...
MPOS机电源设计方案功能概述: 该手机移动MPOS机电源通过采用1S1P锂电池来缩小其体积...TCA8414集成了键盘扫描和GPIO扩展成一个单一的程序包,简化设计,降低BOM计数 MPOS机电源硬件设计框图: MPOS机电源电路部分截图:
8个轻触按键连接到了STM32的GPIO;MPU9250采用GY-91模块,通过I2C接口连接到STM32,MPU9250由应美盛(InvenSense)出品,是MPU6050的升级版,第二代9轴组合传感器将6轴惯性测量单元(三轴加速度计+三轴陀螺仪)和三...
23个GPIO总计 - 6个模拟输入,1个SPI端口,1个I2C端口,1个硬件串行端口和10个GPIO,其中4个具有PWM 可以驱动NeoPixels,连接传感器,伺服器等。 重置按钮,用于进入引导加载程序或重新启动程序。 对于5V版本: 5V...
5.4.1 键盘与LED数码管接口基本原理与结构 5.4.2 用I/O口实现键盘接口 5.4.3 采用专用芯片实现键盘及LED 接口 5.5 LCD显示接口 5.5.1 LCD显示接口原理与结构 5.5.2 S3C2410A的LCD控制器 5.5.3 LCD显示的编程实例 5.6...
5.1.6 timed gpio驱动程序 139 5.1.7 ram console驱动程序 139 5.2 wakelock和early_suspend 140 5.2.1 wakelock和early_suspend的原理 140 5.2.2 Android休眠 141 5.2.3 Android唤醒 ...
ItsyBitsy M4 Express只有1.4英寸长,0.7英寸宽,但有6个电源引脚,23个数字GPIO引脚(其中7个可以是模拟输入,2个1 MSPS模拟输出DAC和18个PWM输出)。它与Adafruit Metro M4相同,但真的很小。所以一旦你完成了...