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 31 static 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 44 static 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, 67 IRQF_ONESHOT, 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 }, 90 }; 91 module_platform_driver(retu_pwrbutton_driver); 92 93 MODULE_ALIAS("platform:retu-pwrbutton"); 94 MODULE_DESCRIPTION("Retu Power Button"); 95 MODULE_AUTHOR("Ari Saastamoinen"); 96 MODULE_AUTHOR("Felipe Balbi"); 97 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>"); 98 MODULE_LICENSE("GPL"); 99