^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * twl4030-pwrbutton.c - TWL4030 Power Button Input Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2008-2009 Nokia Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Written by Peter De Schrijver <peter.de-schrijver@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Several fixes by Felipe Balbi <felipe.balbi@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This file is subject to the terms and conditions of the GNU General
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Public License. See the file "COPYING" in the main directory of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * archive for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/mfd/twl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PWR_PWRON_IRQ (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define STS_HW_CONDITIONS 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static irqreturn_t powerbutton_irq(int irq, void *_pwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct input_dev *pwr = _pwr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &value, STS_HW_CONDITIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) pm_wakeup_event(pwr->dev.parent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) input_sync(pwr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dev_err(pwr->dev.parent, "twl4030: i2c error %d while reading"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) " TWL4030 PM_MASTER STS_HW_CONDITIONS register\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int twl4030_pwrbutton_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct input_dev *pwr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) pwr = devm_input_allocate_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (!pwr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dev_err(&pdev->dev, "Can't allocate power button\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) input_set_capability(pwr, EV_KEY, KEY_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) pwr->name = "twl4030_pwrbutton";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) pwr->phys = "twl4030_pwrbutton/input0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) pwr->dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) err = devm_request_threaded_irq(&pdev->dev, irq, NULL, powerbutton_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) "twl4030_pwrbutton", pwr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) dev_err(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) err = input_register_device(pwr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) dev_err(&pdev->dev, "Can't register power button: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) device_init_wakeup(&pdev->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static const struct of_device_id twl4030_pwrbutton_dt_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) { .compatible = "ti,twl4030-pwrbutton" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MODULE_DEVICE_TABLE(of, twl4030_pwrbutton_dt_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static struct platform_driver twl4030_pwrbutton_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .probe = twl4030_pwrbutton_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .name = "twl4030_pwrbutton",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .of_match_table = of_match_ptr(twl4030_pwrbutton_dt_match_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) module_platform_driver(twl4030_pwrbutton_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) MODULE_ALIAS("platform:twl4030_pwrbutton");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) MODULE_DESCRIPTION("Triton2 Power Button");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) MODULE_AUTHOR("Peter De Schrijver <peter.de-schrijver@nokia.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)