1/* 2 * Retu power button driver. 3 * 4 * Copyright (C) 2004-2010 Nokia Corporation 5 * 6 * Original code written by Ari Saastamoinen, Juha Yrjölä and Felipe Balbi. 7 * Rewritten by Aaro Koskinen. 8 * 9 * This file is subject to the terms and conditions of the GNU General 10 * Public License. See the file "COPYING" in the main directory of this 11 * archive for more details. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19#include <linux/irq.h> 20#include <linux/slab.h> 21#include <linux/errno.h> 22#include <linux/input.h> 23#include <linux/kernel.h> 24#include <linux/module.h> 25#include <linux/mfd/retu.h> 26#include <linux/interrupt.h> 27#include <linux/platform_device.h> 28 29#define RETU_STATUS_PWRONX (1 << 5) 30 31static irqreturn_t retu_pwrbutton_irq(int irq, void *_pwr) 32{ 33 struct input_dev *idev = _pwr; 34 struct retu_dev *rdev = input_get_drvdata(idev); 35 bool state; 36 37 state = !(retu_read(rdev, RETU_REG_STATUS) & RETU_STATUS_PWRONX); 38 input_report_key(idev, KEY_POWER, state); 39 input_sync(idev); 40 41 return IRQ_HANDLED; 42} 43 44static int retu_pwrbutton_probe(struct platform_device *pdev) 45{ 46 struct retu_dev *rdev = dev_get_drvdata(pdev->dev.parent); 47 struct input_dev *idev; 48 int irq; 49 int error; 50 51 irq = platform_get_irq(pdev, 0); 52 if (irq < 0) 53 return irq; 54 55 idev = devm_input_allocate_device(&pdev->dev); 56 if (!idev) 57 return -ENOMEM; 58 59 idev->name = "retu-pwrbutton"; 60 idev->dev.parent = &pdev->dev; 61 62 input_set_capability(idev, EV_KEY, KEY_POWER); 63 input_set_drvdata(idev, rdev); 64 65 error = devm_request_threaded_irq(&pdev->dev, irq, 66 NULL, retu_pwrbutton_irq, 0, 67 "retu-pwrbutton", idev); 68 if (error) 69 return error; 70 71 error = input_register_device(idev); 72 if (error) 73 return error; 74 75 return 0; 76} 77 78static int retu_pwrbutton_remove(struct platform_device *pdev) 79{ 80 return 0; 81} 82 83static struct platform_driver retu_pwrbutton_driver = { 84 .probe = retu_pwrbutton_probe, 85 .remove = retu_pwrbutton_remove, 86 .driver = { 87 .name = "retu-pwrbutton", 88 .owner = THIS_MODULE, 89 }, 90}; 91module_platform_driver(retu_pwrbutton_driver); 92 93MODULE_ALIAS("platform:retu-pwrbutton"); 94MODULE_DESCRIPTION("Retu Power Button"); 95MODULE_AUTHOR("Ari Saastamoinen"); 96MODULE_AUTHOR("Felipe Balbi"); 97MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>"); 98MODULE_LICENSE("GPL"); 99