mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
input: keyboard: rk_keys: fix CodingStyle issues only
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Driver for keys on GPIO lines capable of generating interrupts.
|
||||
*
|
||||
* Copyright (C) 2015, Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Copyright 2005 Phil Blundell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,71 +35,69 @@
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#define EMPTY_ADVALUE 950
|
||||
#define DRIFT_ADVALUE 70
|
||||
#define INVALID_ADVALUE -1
|
||||
#define EMPTY_ADVALUE 950
|
||||
#define DRIFT_ADVALUE 70
|
||||
#define INVALID_ADVALUE -1
|
||||
#define EV_ENCALL KEY_F4
|
||||
#define EV_MENU KEY_F1
|
||||
|
||||
|
||||
#if 0
|
||||
#define key_dbg(bdata, format, arg...) \
|
||||
dev_printk(KERN_INFO , &bdata->input->dev , format , ## arg)
|
||||
dev_info(&bdata->input->dev, format, ##arg)
|
||||
#else
|
||||
#define key_dbg(bdata, format, arg...)
|
||||
#define key_dbg(bdata, format, arg...)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_DEBOUNCE_INTERVAL 10 //10ms
|
||||
#define ADC_SAMPLE_TIME 100
|
||||
#define DEFAULT_DEBOUNCE_INTERVAL 10 /* 10ms */
|
||||
#define ADC_SAMPLE_TIME 100
|
||||
|
||||
enum rk_key_type{
|
||||
TYPE_GPIO = 1,
|
||||
TYPE_ADC
|
||||
enum rk_key_type {
|
||||
TYPE_GPIO = 1,
|
||||
TYPE_ADC
|
||||
};
|
||||
|
||||
struct rk_keys_button {
|
||||
u32 type; //TYPE_GPIO, TYPE_ADC
|
||||
u32 code; // key code
|
||||
const char *desc;//key label
|
||||
u32 state; //key up & down state
|
||||
int gpio; //gpio only
|
||||
int adc_value; //adc only
|
||||
int adc_state; //adc only
|
||||
int active_low;//gpio only
|
||||
int wakeup; //gpio only
|
||||
u32 type; /* TYPE_GPIO, TYPE_ADC */
|
||||
u32 code; /* key code */
|
||||
const char *desc; /* key label */
|
||||
u32 state; /* key up & down state */
|
||||
int gpio; /* gpio only */
|
||||
int adc_value; /* adc only */
|
||||
int adc_state; /* adc only */
|
||||
int active_low; /* gpio only */
|
||||
int wakeup; /* gpio only */
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
struct rk_keys_drvdata {
|
||||
int nbuttons;
|
||||
bool in_suspend; /* Flag to indicate if we're suspending/resuming */
|
||||
/* flag to indicate if we're suspending/resuming */
|
||||
bool in_suspend;
|
||||
int result;
|
||||
int rep;
|
||||
int rep;
|
||||
struct input_dev *input;
|
||||
struct delayed_work adc_poll_work;
|
||||
struct iio_channel *chan;
|
||||
struct iio_channel *chan;
|
||||
struct rk_keys_button button[0];
|
||||
};
|
||||
|
||||
static struct input_dev *sinput_dev = NULL;
|
||||
static struct rk_keys_drvdata *spdata = NULL;
|
||||
static void * rk_key_get_drvdata(void)
|
||||
static struct input_dev *sinput_dev;
|
||||
static struct rk_keys_drvdata *spdata;
|
||||
|
||||
static void *rk_key_get_drvdata(void)
|
||||
{
|
||||
BUG_ON(!spdata);
|
||||
return spdata;
|
||||
BUG_ON(!spdata);
|
||||
return spdata;
|
||||
}
|
||||
|
||||
void rk_send_power_key(int state)
|
||||
{
|
||||
if (!sinput_dev)
|
||||
return;
|
||||
if(state)
|
||||
{
|
||||
if (state) {
|
||||
input_report_key(sinput_dev, KEY_POWER, 1);
|
||||
input_sync(sinput_dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
input_report_key(sinput_dev, KEY_POWER, 0);
|
||||
input_sync(sinput_dev);
|
||||
}
|
||||
@@ -119,58 +118,63 @@ EXPORT_SYMBOL(rk_send_wakeup_key);
|
||||
|
||||
static void keys_timer(unsigned long _data)
|
||||
{
|
||||
struct rk_keys_drvdata *pdata = rk_key_get_drvdata();
|
||||
struct rk_keys_drvdata *pdata = rk_key_get_drvdata();
|
||||
struct rk_keys_button *button = (struct rk_keys_button *)_data;
|
||||
struct input_dev *input = pdata->input;
|
||||
int state;
|
||||
|
||||
if(button->type == TYPE_GPIO)
|
||||
state = !!((gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low);
|
||||
|
||||
if (button->type == TYPE_GPIO)
|
||||
state = !!((gpio_get_value(button->gpio) ? 1 : 0) ^
|
||||
button->active_low);
|
||||
else
|
||||
state = !!button->adc_state;
|
||||
|
||||
if(button->state != state) {
|
||||
button->state = state;
|
||||
|
||||
if (button->state != state) {
|
||||
button->state = state;
|
||||
input_event(input, EV_KEY, button->code, button->state);
|
||||
key_dbg(pdata, "%skey[%s]: report event[%d] state[%d]\n",
|
||||
(button->type == TYPE_ADC)?"adc":"gpio", button->desc, button->code, button->state);
|
||||
key_dbg(pdata, "%skey[%s]: report event[%d] state[%d]\n",
|
||||
button->type == TYPE_ADC ? "adc" : "gpio",
|
||||
button->desc, button->code, button->state);
|
||||
input_event(input, EV_KEY, button->code, button->state);
|
||||
input_sync(input);
|
||||
}
|
||||
|
||||
if(state)
|
||||
mod_timer(&button->timer,
|
||||
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
|
||||
|
||||
|
||||
if (state)
|
||||
mod_timer(&button->timer, jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
|
||||
}
|
||||
|
||||
static irqreturn_t keys_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct rk_keys_drvdata *pdata = rk_key_get_drvdata();
|
||||
struct rk_keys_drvdata *pdata = rk_key_get_drvdata();
|
||||
struct rk_keys_button *button = (struct rk_keys_button *)dev_id;
|
||||
struct input_dev *input = pdata->input;
|
||||
|
||||
BUG_ON(irq != gpio_to_irq(button->gpio));
|
||||
|
||||
if(button->wakeup == 1 && pdata->in_suspend == true){
|
||||
if (button->wakeup == 1 && pdata->in_suspend == true) {
|
||||
button->state = 1;
|
||||
key_dbg(pdata, "wakeup: %skey[%s]: report event[%d] state[%d]\n",
|
||||
(button->type == TYPE_ADC)?"adc":"gpio", button->desc, button->code, button->state);
|
||||
key_dbg(pdata,
|
||||
"wakeup: %skey[%s]: report event[%d] state[%d]\n",
|
||||
(button->type == TYPE_ADC) ? "adc" : "gpio",
|
||||
button->desc, button->code, button->state);
|
||||
input_event(input, EV_KEY, button->code, button->state);
|
||||
input_sync(input);
|
||||
}
|
||||
mod_timer(&button->timer,
|
||||
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
|
||||
}
|
||||
mod_timer(&button->timer, jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static ssize_t adc_value_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
/*
|
||||
static ssize_t adc_value_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct rk_keys_drvdata *ddata = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "adc_value: %d\n", ddata->result);
|
||||
}
|
||||
static DEVICE_ATTR(get_adc_value, S_IRUGO | S_IWUSR, adc_value_show, NULL);
|
||||
#endif
|
||||
*/
|
||||
|
||||
static const struct of_device_id rk_key_match[] = {
|
||||
{ .compatible = "rockchip,key", .data = NULL},
|
||||
@@ -180,129 +184,136 @@ MODULE_DEVICE_TABLE(of, rk_key_match);
|
||||
|
||||
static int rk_key_adc_iio_read(struct rk_keys_drvdata *data)
|
||||
{
|
||||
struct iio_channel *channel = data->chan;
|
||||
int val, ret;
|
||||
struct iio_channel *channel = data->chan;
|
||||
int val, ret;
|
||||
|
||||
if (!channel)
|
||||
return INVALID_ADVALUE;
|
||||
ret = iio_read_channel_raw(channel, &val);
|
||||
if (ret < 0) {
|
||||
pr_err("read channel() error: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return val;
|
||||
ret = iio_read_channel_raw(channel, &val);
|
||||
if (ret < 0) {
|
||||
pr_err("read channel() error: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static void adc_key_poll(struct work_struct *work)
|
||||
{
|
||||
struct rk_keys_drvdata *ddata;
|
||||
int i, result = -1;
|
||||
struct rk_keys_drvdata *ddata;
|
||||
int i, result = -1;
|
||||
|
||||
ddata = container_of(work, struct rk_keys_drvdata, adc_poll_work.work);
|
||||
if (!ddata->in_suspend)
|
||||
{
|
||||
result = rk_key_adc_iio_read(ddata);
|
||||
if(result > INVALID_ADVALUE && result < EMPTY_ADVALUE)
|
||||
ddata->result = result;
|
||||
for (i = 0; i < ddata->nbuttons; i++)
|
||||
{
|
||||
struct rk_keys_button *button = &ddata->button[i];
|
||||
if(!button->adc_value)
|
||||
continue;
|
||||
if(result < button->adc_value + DRIFT_ADVALUE &&
|
||||
result > button->adc_value - DRIFT_ADVALUE)
|
||||
button->adc_state = 1;
|
||||
else
|
||||
button->adc_state = 0;
|
||||
if(button->state != button->adc_state)
|
||||
mod_timer(&button->timer,
|
||||
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
|
||||
}
|
||||
}
|
||||
ddata = container_of(work, struct rk_keys_drvdata, adc_poll_work.work);
|
||||
if (!ddata->in_suspend) {
|
||||
result = rk_key_adc_iio_read(ddata);
|
||||
if (result > INVALID_ADVALUE && result < EMPTY_ADVALUE)
|
||||
ddata->result = result;
|
||||
for (i = 0; i < ddata->nbuttons; i++) {
|
||||
struct rk_keys_button *button = &ddata->button[i];
|
||||
|
||||
schedule_delayed_work(&ddata->adc_poll_work,
|
||||
msecs_to_jiffies(ADC_SAMPLE_TIME));
|
||||
if (!button->adc_value)
|
||||
continue;
|
||||
if (result < button->adc_value + DRIFT_ADVALUE &&
|
||||
result > button->adc_value - DRIFT_ADVALUE)
|
||||
button->adc_state = 1;
|
||||
else
|
||||
button->adc_state = 0;
|
||||
if (button->state != button->adc_state)
|
||||
mod_timer(&button->timer,
|
||||
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
schedule_delayed_work(&ddata->adc_poll_work, msecs_to_jiffies(ADC_SAMPLE_TIME));
|
||||
}
|
||||
|
||||
static int rk_key_type_get(struct device_node *node, struct rk_keys_button *button)
|
||||
static int rk_key_type_get(struct device_node *node,
|
||||
struct rk_keys_button *button)
|
||||
{
|
||||
u32 adc_value;
|
||||
|
||||
if (!of_property_read_u32(node, "rockchip,adc_value", &adc_value))
|
||||
return TYPE_ADC;
|
||||
else if(of_get_gpio(node, 0) >= 0)
|
||||
return TYPE_GPIO;
|
||||
return TYPE_ADC;
|
||||
else if (of_get_gpio(node, 0) >= 0)
|
||||
return TYPE_GPIO;
|
||||
else
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int rk_keys_parse_dt(struct rk_keys_drvdata *pdata,
|
||||
struct platform_device *pdev)
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct device_node *child_node;
|
||||
struct iio_channel *chan;
|
||||
int ret, gpio, i =0;
|
||||
u32 code, adc_value, flags;;
|
||||
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct device_node *child_node;
|
||||
struct iio_channel *chan;
|
||||
int ret, gpio, i = 0;
|
||||
u32 code, adc_value, flags;
|
||||
|
||||
chan = iio_channel_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(chan)) {
|
||||
dev_info(&pdev->dev, "no io-channels defined\n");
|
||||
chan = NULL;
|
||||
}
|
||||
pdata->chan = chan;
|
||||
|
||||
pdata->chan = chan;
|
||||
|
||||
for_each_child_of_node(node, child_node) {
|
||||
if(of_property_read_u32(child_node, "linux,code", &code)) {
|
||||
dev_err(&pdev->dev, "Missing linux,code property in the DT.\n");
|
||||
if (of_property_read_u32(child_node, "linux,code", &code)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Missing linux,code property in the DT.\n");
|
||||
ret = -EINVAL;
|
||||
goto error_ret;
|
||||
}
|
||||
pdata->button[i].code = code;
|
||||
pdata->button[i].desc = of_get_property(child_node, "label", NULL);
|
||||
pdata->button[i].type = rk_key_type_get(child_node, &pdata->button[i]);
|
||||
switch(pdata->button[i].type)
|
||||
{
|
||||
case TYPE_GPIO:
|
||||
gpio = of_get_gpio_flags(child_node, 0, &flags);
|
||||
if (gpio < 0) {
|
||||
ret = gpio;
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev,"Failed to get gpio flags, error: %d\n",
|
||||
ret);
|
||||
goto error_ret;
|
||||
}
|
||||
pdata->button[i].code = code;
|
||||
pdata->button[i].desc =
|
||||
of_get_property(child_node, "label", NULL);
|
||||
pdata->button[i].type =
|
||||
rk_key_type_get(child_node, &pdata->button[i]);
|
||||
switch (pdata->button[i].type) {
|
||||
case TYPE_GPIO:
|
||||
gpio = of_get_gpio_flags(child_node, 0, &flags);
|
||||
if (gpio < 0) {
|
||||
ret = gpio;
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to get gpio flags, error: %d\n",
|
||||
ret);
|
||||
goto error_ret;
|
||||
}
|
||||
|
||||
pdata->button[i].gpio = gpio;
|
||||
pdata->button[i].active_low = flags & OF_GPIO_ACTIVE_LOW;
|
||||
pdata->button[i].wakeup = !!of_get_property(child_node, "gpio-key,wakeup", NULL);
|
||||
break;
|
||||
pdata->button[i].gpio = gpio;
|
||||
pdata->button[i].active_low =
|
||||
flags & OF_GPIO_ACTIVE_LOW;
|
||||
pdata->button[i].wakeup =
|
||||
!!of_get_property(child_node, "gpio-key,wakeup",
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case TYPE_ADC:
|
||||
if (of_property_read_u32(child_node, "rockchip,adc_value", &adc_value)) {
|
||||
dev_err(&pdev->dev, "Missing rockchip,adc_value property in the DT.\n");
|
||||
ret = -EINVAL;
|
||||
goto error_ret;
|
||||
}
|
||||
pdata->button[i].adc_value = adc_value;
|
||||
break;
|
||||
case TYPE_ADC:
|
||||
if (of_property_read_u32
|
||||
(child_node, "rockchip,adc_value", &adc_value)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Missing rockchip,adc_value property in the DT.\n");
|
||||
ret = -EINVAL;
|
||||
goto error_ret;
|
||||
}
|
||||
pdata->button[i].adc_value = adc_value;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&pdev->dev, "Error rockchip,type property in the DT.\n");
|
||||
ret = -EINVAL;
|
||||
goto error_ret;
|
||||
default:
|
||||
dev_err(&pdev->dev,
|
||||
"Error rockchip,type property in the DT.\n");
|
||||
ret = -EINVAL;
|
||||
goto error_ret;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_ret:
|
||||
return ret;
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_ret:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int keys_probe(struct platform_device *pdev)
|
||||
static int keys_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
@@ -315,10 +326,10 @@ static int keys_probe(struct platform_device *pdev)
|
||||
if (key_num == 0)
|
||||
dev_info(&pdev->dev, "no key defined\n");
|
||||
|
||||
ddata = devm_kzalloc(dev, sizeof(struct rk_keys_drvdata) +
|
||||
key_num * sizeof(struct rk_keys_button),
|
||||
GFP_KERNEL);
|
||||
|
||||
ddata = devm_kzalloc(dev, sizeof(struct rk_keys_drvdata) +
|
||||
key_num * sizeof(struct rk_keys_button),
|
||||
GFP_KERNEL);
|
||||
|
||||
input = devm_input_allocate_device(dev);
|
||||
if (!ddata || !input) {
|
||||
error = -ENOMEM;
|
||||
@@ -326,7 +337,7 @@ static int keys_probe(struct platform_device *pdev)
|
||||
}
|
||||
platform_set_drvdata(pdev, ddata);
|
||||
|
||||
input->name = "rk29-keypad";//pdev->name;
|
||||
input->name = "rk29-keypad"; /* pdev->name; */
|
||||
input->phys = "gpio-keys/input0";
|
||||
input->dev.parent = dev;
|
||||
|
||||
@@ -336,11 +347,11 @@ static int keys_probe(struct platform_device *pdev)
|
||||
input->id.version = 0x0100;
|
||||
ddata->input = input;
|
||||
|
||||
//parse info from dt
|
||||
/* parse info from dt */
|
||||
ddata->nbuttons = key_num;
|
||||
error = rk_keys_parse_dt(ddata, pdev);
|
||||
if(error)
|
||||
goto fail0;
|
||||
if (error)
|
||||
goto fail0;
|
||||
|
||||
/* Enable auto repeat feature of Linux input subsystem */
|
||||
if (ddata->rep)
|
||||
@@ -349,34 +360,36 @@ static int keys_probe(struct platform_device *pdev)
|
||||
for (i = 0; i < ddata->nbuttons; i++) {
|
||||
struct rk_keys_button *button = &ddata->button[i];
|
||||
|
||||
if (button->code){
|
||||
if (button->code) {
|
||||
setup_timer(&button->timer,
|
||||
keys_timer, (unsigned long)button);}
|
||||
keys_timer, (unsigned long)button);
|
||||
}
|
||||
|
||||
if (button->wakeup)
|
||||
wakeup = 1;
|
||||
|
||||
|
||||
input_set_capability(input, EV_KEY, button->code);
|
||||
}
|
||||
|
||||
for (i = 0; i < ddata->nbuttons; i++) {
|
||||
struct rk_keys_button *button = &ddata->button[i];
|
||||
|
||||
if(button->type == TYPE_GPIO) {
|
||||
if (button->type == TYPE_GPIO) {
|
||||
int irq;
|
||||
|
||||
error = devm_gpio_request(dev, button->gpio, button->desc ?: "keys");
|
||||
error =
|
||||
devm_gpio_request(dev, button->gpio,
|
||||
button->desc ? : "keys");
|
||||
if (error < 0) {
|
||||
pr_err("gpio-keys: failed to request GPIO %d,"
|
||||
" error %d\n", button->gpio, error);
|
||||
pr_err("gpio-keys: failed to request GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
error = gpio_direction_input(button->gpio);
|
||||
if (error < 0) {
|
||||
pr_err("gpio-keys: failed to configure input"
|
||||
" direction for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
pr_err("gpio-keys: failed to configure input direction for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
gpio_free(button->gpio);
|
||||
goto fail1;
|
||||
}
|
||||
@@ -384,20 +397,22 @@ static int keys_probe(struct platform_device *pdev)
|
||||
irq = gpio_to_irq(button->gpio);
|
||||
if (irq < 0) {
|
||||
error = irq;
|
||||
pr_err("gpio-keys: Unable to get irq number"
|
||||
" for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
pr_err("gpio-keys: Unable to get irq number for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
gpio_free(button->gpio);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
error = devm_request_irq(dev, irq, keys_isr,
|
||||
(button->active_low)?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING,
|
||||
button->desc ? button->desc : "keys",
|
||||
button);
|
||||
button->active_low ?
|
||||
IRQF_TRIGGER_FALLING :
|
||||
IRQF_TRIGGER_RISING,
|
||||
button->desc ?
|
||||
button->desc : "keys",
|
||||
button);
|
||||
if (error) {
|
||||
pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
|
||||
irq, error);
|
||||
irq, error);
|
||||
gpio_free(button->gpio);
|
||||
goto fail1;
|
||||
}
|
||||
@@ -409,30 +424,29 @@ static int keys_probe(struct platform_device *pdev)
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
pr_err("gpio-keys: Unable to register input device, "
|
||||
"error: %d\n", error);
|
||||
pr_err("gpio-keys: Unable to register input device, error: %d\n",
|
||||
error);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
//adc polling work
|
||||
/* adc polling work */
|
||||
if (ddata->chan) {
|
||||
INIT_DELAYED_WORK(&ddata->adc_poll_work, adc_key_poll);
|
||||
schedule_delayed_work(&ddata->adc_poll_work,
|
||||
msecs_to_jiffies(ADC_SAMPLE_TIME));
|
||||
}
|
||||
|
||||
spdata = ddata;
|
||||
spdata = ddata;
|
||||
sinput_dev = input;
|
||||
return error;
|
||||
|
||||
fail2:
|
||||
fail2:
|
||||
device_init_wakeup(dev, 0);
|
||||
fail1:
|
||||
while (--i >= 0) {
|
||||
fail1:
|
||||
while (--i >= 0)
|
||||
del_timer_sync(&ddata->button[i].timer);
|
||||
}
|
||||
fail0:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
fail0:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -445,20 +459,18 @@ static int keys_remove(struct platform_device *pdev)
|
||||
int i;
|
||||
|
||||
device_init_wakeup(dev, 0);
|
||||
for (i = 0; i < ddata->nbuttons; i++) {
|
||||
for (i = 0; i < ddata->nbuttons; i++)
|
||||
del_timer_sync(&ddata->button[i].timer);
|
||||
}
|
||||
if (ddata->chan)
|
||||
cancel_delayed_work_sync(&ddata->adc_poll_work);
|
||||
input_unregister_device(input);
|
||||
|
||||
|
||||
sinput_dev = NULL;
|
||||
spdata = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int keys_suspend(struct device *dev)
|
||||
{
|
||||
@@ -469,10 +481,9 @@ static int keys_suspend(struct device *dev)
|
||||
if (device_may_wakeup(dev)) {
|
||||
for (i = 0; i < ddata->nbuttons; i++) {
|
||||
struct rk_keys_button *button = ddata->button + i;
|
||||
if (button->wakeup) {
|
||||
int irq = gpio_to_irq(button->gpio);
|
||||
enable_irq_wake(irq);
|
||||
}
|
||||
|
||||
if (button->wakeup)
|
||||
enable_irq_wake(gpio_to_irq(button->gpio));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,14 +498,14 @@ static int keys_resume(struct device *dev)
|
||||
if (device_may_wakeup(dev)) {
|
||||
for (i = 0; i < ddata->nbuttons; i++) {
|
||||
struct rk_keys_button *button = ddata->button + i;
|
||||
if (button->wakeup) {
|
||||
int irq = gpio_to_irq(button->gpio);
|
||||
disable_irq_wake(irq);
|
||||
}
|
||||
|
||||
if (button->wakeup)
|
||||
disable_irq_wake(gpio_to_irq(button->gpio));
|
||||
}
|
||||
preempt_disable();
|
||||
/* for call resend_irqs, which may call keys_isr */
|
||||
if (local_softirq_pending())
|
||||
do_softirq(); // for call resend_irqs, which may call keys_isr
|
||||
do_softirq();
|
||||
preempt_enable_no_resched();
|
||||
}
|
||||
|
||||
@@ -523,4 +534,3 @@ static struct platform_driver keys_device_driver = {
|
||||
};
|
||||
|
||||
module_platform_driver(keys_device_driver);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user