Skip to content

Commit

Permalink
input: PCF50633 input driver
Browse files Browse the repository at this point in the history
Signed-off-by: Balaji Rao <balajirrao@openmoko.org>
Cc: Andy Green <andy@openmoko.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
  • Loading branch information
Balaji Rao authored and Samuel Ortiz committed Jan 11, 2009
1 parent f5714dc commit 1851b06
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
7 changes: 7 additions & 0 deletions drivers/input/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,11 @@ config HP_SDC_RTC
Say Y here if you want to support the built-in real time clock
of the HP SDC controller.

config INPUT_PCF50633_PMU
tristate "PCF50633 PMU events"
depends on MFD_PCF50633
help
Say Y to include support for delivering PMU events via input
layer on NXP PCF50633.

endif
1 change: 1 addition & 0 deletions drivers/input/misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_APANEL) += apanel.o
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
132 changes: 132 additions & 0 deletions drivers/input/misc/pcf50633-input.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/* NXP PCF50633 Input Driver
*
* (C) 2006-2008 by Openmoko, Inc.
* Author: Balaji Rao <balajirrao@openmoko.org>
* All rights reserved.
*
* Broken down from monstrous PCF50633 driver mainly by
* Harald Welte, Andy Green and Werner Almesberger
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/input.h>

#include <linux/mfd/pcf50633/core.h>

#define PCF50633_OOCSTAT_ONKEY 0x01
#define PCF50633_REG_OOCSTAT 0x12
#define PCF50633_REG_OOCMODE 0x10

struct pcf50633_input {
struct pcf50633 *pcf;
struct input_dev *input_dev;
};

static void
pcf50633_input_irq(int irq, void *data)
{
struct pcf50633_input *input;
int onkey_released;

input = data;

/* We report only one event depending on the key press status */
onkey_released = pcf50633_reg_read(input->pcf, PCF50633_REG_OOCSTAT)
& PCF50633_OOCSTAT_ONKEY;

if (irq == PCF50633_IRQ_ONKEYF && !onkey_released)
input_report_key(input->input_dev, KEY_POWER, 1);
else if (irq == PCF50633_IRQ_ONKEYR && onkey_released)
input_report_key(input->input_dev, KEY_POWER, 0);

input_sync(input->input_dev);
}

static int __devinit pcf50633_input_probe(struct platform_device *pdev)
{
struct pcf50633_input *input;
struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
struct input_dev *input_dev;
int ret;


input = kzalloc(sizeof(*input), GFP_KERNEL);
if (!input)
return -ENOMEM;

input_dev = input_allocate_device();
if (!input_dev) {
kfree(input);
return -ENOMEM;
}

platform_set_drvdata(pdev, input);
input->pcf = pdata->pcf;
input->input_dev = input_dev;

input_dev->name = "PCF50633 PMU events";
input_dev->id.bustype = BUS_I2C;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);
set_bit(KEY_POWER, input_dev->keybit);

ret = input_register_device(input_dev);
if (ret) {
input_free_device(input_dev);
kfree(input);
return ret;
}
pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR,
pcf50633_input_irq, input);
pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF,
pcf50633_input_irq, input);

return 0;
}

static int __devexit pcf50633_input_remove(struct platform_device *pdev)
{
struct pcf50633_input *input = platform_get_drvdata(pdev);

pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYR);
pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYF);

input_unregister_device(input->input_dev);
kfree(input);

return 0;
}

static struct platform_driver pcf50633_input_driver = {
.driver = {
.name = "pcf50633-input",
},
.probe = pcf50633_input_probe,
.remove = __devexit_p(pcf50633_input_remove),
};

static int __init pcf50633_input_init(void)
{
return platform_driver_register(&pcf50633_input_driver);
}
module_init(pcf50633_input_init);

static void __exit pcf50633_input_exit(void)
{
platform_driver_unregister(&pcf50633_input_driver);
}
module_exit(pcf50633_input_exit);

MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
MODULE_DESCRIPTION("PCF50633 input driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pcf50633-input");

0 comments on commit 1851b06

Please sign in to comment.