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, 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 78 static int retu_pwrbutton_remove(struct platform_device *pdev) 79 { 80 return 0; 81 } 82 83 static struct platform_driver retu_pwrbutton_driver = { 84 .probe = retu_pwrbutton_probe, 85 .remove = retu_pwrbutton_remove, 86 .driver = { 87 .name = "retu-pwrbutton", 88 }, 89 }; 90 module_platform_driver(retu_pwrbutton_driver); 91 92 MODULE_ALIAS("platform:retu-pwrbutton"); 93 MODULE_DESCRIPTION("Retu Power Button"); 94 MODULE_AUTHOR("Ari Saastamoinen"); 95 MODULE_AUTHOR("Felipe Balbi"); 96 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>"); 97 MODULE_LICENSE("GPL"); 98