Path: blob/master/drivers/input/misc/pcf50633-input.c
15109 views
/* NXP PCF50633 Input Driver1*2* (C) 2006-2008 by Openmoko, Inc.3* Author: Balaji Rao <[email protected]>4* All rights reserved.5*6* Broken down from monstrous PCF50633 driver mainly by7* Harald Welte, Andy Green and Werner Almesberger8*9* This program is free software; you can redistribute it and/or modify it10* under the terms of the GNU General Public License as published by the11* Free Software Foundation; either version 2 of the License, or (at your12* option) any later version.13*14*/1516#include <linux/kernel.h>17#include <linux/module.h>18#include <linux/init.h>19#include <linux/device.h>20#include <linux/platform_device.h>21#include <linux/input.h>22#include <linux/slab.h>2324#include <linux/mfd/pcf50633/core.h>2526#define PCF50633_OOCSTAT_ONKEY 0x0127#define PCF50633_REG_OOCSTAT 0x1228#define PCF50633_REG_OOCMODE 0x102930struct pcf50633_input {31struct pcf50633 *pcf;32struct input_dev *input_dev;33};3435static void36pcf50633_input_irq(int irq, void *data)37{38struct pcf50633_input *input;39int onkey_released;4041input = data;4243/* We report only one event depending on the key press status */44onkey_released = pcf50633_reg_read(input->pcf, PCF50633_REG_OOCSTAT)45& PCF50633_OOCSTAT_ONKEY;4647if (irq == PCF50633_IRQ_ONKEYF && !onkey_released)48input_report_key(input->input_dev, KEY_POWER, 1);49else if (irq == PCF50633_IRQ_ONKEYR && onkey_released)50input_report_key(input->input_dev, KEY_POWER, 0);5152input_sync(input->input_dev);53}5455static int __devinit pcf50633_input_probe(struct platform_device *pdev)56{57struct pcf50633_input *input;58struct input_dev *input_dev;59int ret;606162input = kzalloc(sizeof(*input), GFP_KERNEL);63if (!input)64return -ENOMEM;6566input_dev = input_allocate_device();67if (!input_dev) {68kfree(input);69return -ENOMEM;70}7172platform_set_drvdata(pdev, input);73input->pcf = dev_to_pcf50633(pdev->dev.parent);74input->input_dev = input_dev;7576input_dev->name = "PCF50633 PMU events";77input_dev->id.bustype = BUS_I2C;78input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);79set_bit(KEY_POWER, input_dev->keybit);8081ret = input_register_device(input_dev);82if (ret) {83input_free_device(input_dev);84kfree(input);85return ret;86}87pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYR,88pcf50633_input_irq, input);89pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYF,90pcf50633_input_irq, input);9192return 0;93}9495static int __devexit pcf50633_input_remove(struct platform_device *pdev)96{97struct pcf50633_input *input = platform_get_drvdata(pdev);9899pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYR);100pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYF);101102input_unregister_device(input->input_dev);103kfree(input);104105return 0;106}107108static struct platform_driver pcf50633_input_driver = {109.driver = {110.name = "pcf50633-input",111},112.probe = pcf50633_input_probe,113.remove = __devexit_p(pcf50633_input_remove),114};115116static int __init pcf50633_input_init(void)117{118return platform_driver_register(&pcf50633_input_driver);119}120module_init(pcf50633_input_init);121122static void __exit pcf50633_input_exit(void)123{124platform_driver_unregister(&pcf50633_input_driver);125}126module_exit(pcf50633_input_exit);127128MODULE_AUTHOR("Balaji Rao <[email protected]>");129MODULE_DESCRIPTION("PCF50633 input driver");130MODULE_LICENSE("GPL");131MODULE_ALIAS("platform:pcf50633-input");132133134