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/init.h> 21 #include <linux/slab.h> 22 #include <linux/errno.h> 23 #include <linux/input.h> 24 #include <linux/kernel.h> 25 #include <linux/module.h> 26 #include <linux/mfd/retu.h> 27 #include <linux/interrupt.h> 28 #include <linux/platform_device.h> 29 30 #define RETU_STATUS_PWRONX (1 << 5) 31 32 static irqreturn_t retu_pwrbutton_irq(int irq, void *_pwr) 33 { 34 struct input_dev *idev = _pwr; 35 struct retu_dev *rdev = input_get_drvdata(idev); 36 bool state; 37 38 state = !(retu_read(rdev, RETU_REG_STATUS) & RETU_STATUS_PWRONX); 39 input_report_key(idev, KEY_POWER, state); 40 input_sync(idev); 41 42 return IRQ_HANDLED; 43 } 44 45 static int retu_pwrbutton_probe(struct platform_device *pdev) 46 { 47 struct retu_dev *rdev = dev_get_drvdata(pdev->dev.parent); 48 struct input_dev *idev; 49 int irq; 50 int error; 51 52 irq = platform_get_irq(pdev, 0); 53 if (irq < 0) 54 return irq; 55 56 idev = devm_input_allocate_device(&pdev->dev); 57 if (!idev) 58 return -ENOMEM; 59 60 idev->name = "retu-pwrbutton"; 61 idev->dev.parent = &pdev->dev; 62 63 input_set_capability(idev, EV_KEY, KEY_POWER); 64 input_set_drvdata(idev, rdev); 65 66 error = devm_request_threaded_irq(&pdev->dev, irq, 67 NULL, retu_pwrbutton_irq, 0, 68 "retu-pwrbutton", idev); 69 if (error) 70 return error; 71 72 error = input_register_device(idev); 73 if (error) 74 return error; 75 76 return 0; 77 } 78 79 static int retu_pwrbutton_remove(struct platform_device *pdev) 80 { 81 return 0; 82 } 83 84 static struct platform_driver retu_pwrbutton_driver = { 85 .probe = retu_pwrbutton_probe, 86 .remove = retu_pwrbutton_remove, 87 .driver = { 88 .name = "retu-pwrbutton", 89 .owner = THIS_MODULE, 90 }, 91 }; 92 module_platform_driver(retu_pwrbutton_driver); 93 94 MODULE_ALIAS("platform:retu-pwrbutton"); 95 MODULE_DESCRIPTION("Retu Power Button"); 96 MODULE_AUTHOR("Ari Saastamoinen"); 97 MODULE_AUTHOR("Felipe Balbi"); 98 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>"); 99 MODULE_LICENSE("GPL"); 100