Path: blob/master/drivers/input/misc/twl4030-pwrbutton.c
15109 views
/**1* twl4030-pwrbutton.c - TWL4030 Power Button Input Driver2*3* Copyright (C) 2008-2009 Nokia Corporation4*5* Written by Peter De Schrijver <[email protected]>6* Several fixes by Felipe Balbi <[email protected]>7*8* This file is subject to the terms and conditions of the GNU General9* Public License. See the file "COPYING" in the main directory of this10* archive for more details.11*12* This program is distributed in the hope that it will be useful,13* but WITHOUT ANY WARRANTY; without even the implied warranty of14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15* GNU General Public License for more details.16*17* You should have received a copy of the GNU General Public License18* along with this program; if not, write to the Free Software19* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA20*/2122#include <linux/module.h>23#include <linux/init.h>24#include <linux/kernel.h>25#include <linux/errno.h>26#include <linux/input.h>27#include <linux/interrupt.h>28#include <linux/platform_device.h>29#include <linux/i2c/twl.h>3031#define PWR_PWRON_IRQ (1 << 0)3233#define STS_HW_CONDITIONS 0xf3435static irqreturn_t powerbutton_irq(int irq, void *_pwr)36{37struct input_dev *pwr = _pwr;38int err;39u8 value;4041err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value,42STS_HW_CONDITIONS);43if (!err) {44input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ);45input_sync(pwr);46} else {47dev_err(pwr->dev.parent, "twl4030: i2c error %d while reading"48" TWL4030 PM_MASTER STS_HW_CONDITIONS register\n", err);49}5051return IRQ_HANDLED;52}5354static int __init twl4030_pwrbutton_probe(struct platform_device *pdev)55{56struct input_dev *pwr;57int irq = platform_get_irq(pdev, 0);58int err;5960pwr = input_allocate_device();61if (!pwr) {62dev_dbg(&pdev->dev, "Can't allocate power button\n");63return -ENOMEM;64}6566pwr->evbit[0] = BIT_MASK(EV_KEY);67pwr->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);68pwr->name = "twl4030_pwrbutton";69pwr->phys = "twl4030_pwrbutton/input0";70pwr->dev.parent = &pdev->dev;7172err = request_threaded_irq(irq, NULL, powerbutton_irq,73IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,74"twl4030_pwrbutton", pwr);75if (err < 0) {76dev_dbg(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err);77goto free_input_dev;78}7980err = input_register_device(pwr);81if (err) {82dev_dbg(&pdev->dev, "Can't register power button: %d\n", err);83goto free_irq;84}8586platform_set_drvdata(pdev, pwr);8788return 0;8990free_irq:91free_irq(irq, pwr);92free_input_dev:93input_free_device(pwr);94return err;95}9697static int __exit twl4030_pwrbutton_remove(struct platform_device *pdev)98{99struct input_dev *pwr = platform_get_drvdata(pdev);100int irq = platform_get_irq(pdev, 0);101102free_irq(irq, pwr);103input_unregister_device(pwr);104105return 0;106}107108static struct platform_driver twl4030_pwrbutton_driver = {109.remove = __exit_p(twl4030_pwrbutton_remove),110.driver = {111.name = "twl4030_pwrbutton",112.owner = THIS_MODULE,113},114};115116static int __init twl4030_pwrbutton_init(void)117{118return platform_driver_probe(&twl4030_pwrbutton_driver,119twl4030_pwrbutton_probe);120}121module_init(twl4030_pwrbutton_init);122123static void __exit twl4030_pwrbutton_exit(void)124{125platform_driver_unregister(&twl4030_pwrbutton_driver);126}127module_exit(twl4030_pwrbutton_exit);128129MODULE_ALIAS("platform:twl4030_pwrbutton");130MODULE_DESCRIPTION("Triton2 Power Button");131MODULE_LICENSE("GPL");132MODULE_AUTHOR("Peter De Schrijver <[email protected]>");133MODULE_AUTHOR("Felipe Balbi <[email protected]>");134135136137