input: max77650: Add onkey support
authorBartosz Golaszewski <bgolaszewski@baylibre.com>
Tue, 23 Apr 2019 09:04:50 +0000 (11:04 +0200)
committerLee Jones <lee.jones@linaro.org>
Wed, 8 May 2019 11:07:07 +0000 (12:07 +0100)
Add support for the push- and slide-button events for max77650.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/max77650-onkey.c [new file with mode: 0644]

index e15ed1bb8558c69e2eda42507953e2e079e759d7..85bc675eecd3c4b1e4e6741950aa4581240a8907 100644 (file)
@@ -190,6 +190,15 @@ config INPUT_M68K_BEEP
        tristate "M68k Beeper support"
        depends on M68K
 
+config INPUT_MAX77650_ONKEY
+       tristate "Maxim MAX77650 ONKEY support"
+       depends on MFD_MAX77650
+       help
+         Support the ONKEY of the MAX77650 PMIC as an input device.
+
+         To compile this driver as a module, choose M here: the module
+         will be called max77650-onkey.
+
 config INPUT_MAX77693_HAPTIC
        tristate "MAXIM MAX77693/MAX77843 haptic controller support"
        depends on (MFD_MAX77693 || MFD_MAX77843) && PWM
index b936c5b1d4ac6ac99f3f86614f886b2bd788637f..ffd72161c79bd67ff1dbfeb9e33c34593df3a1cb 100644 (file)
@@ -43,6 +43,7 @@ obj-$(CONFIG_INPUT_IXP4XX_BEEPER)     += ixp4xx-beeper.o
 obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)     += keyspan_remote.o
 obj-$(CONFIG_INPUT_KXTJ9)              += kxtj9.o
 obj-$(CONFIG_INPUT_M68K_BEEP)          += m68kspkr.o
+obj-$(CONFIG_INPUT_MAX77650_ONKEY)     += max77650-onkey.o
 obj-$(CONFIG_INPUT_MAX77693_HAPTIC)    += max77693-haptic.o
 obj-$(CONFIG_INPUT_MAX8925_ONKEY)      += max8925_onkey.o
 obj-$(CONFIG_INPUT_MAX8997_HAPTIC)     += max8997_haptic.o
diff --git a/drivers/input/misc/max77650-onkey.c b/drivers/input/misc/max77650-onkey.c
new file mode 100644 (file)
index 0000000..fbf6caa
--- /dev/null
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2018 BayLibre SAS
+// Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+//
+// ONKEY driver for MAXIM 77650/77651 charger/power-supply.
+
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/max77650.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define MAX77650_ONKEY_MODE_MASK       BIT(3)
+#define MAX77650_ONKEY_MODE_PUSH       0x00
+#define MAX77650_ONKEY_MODE_SLIDE      BIT(3)
+
+struct max77650_onkey {
+       struct input_dev *input;
+       unsigned int code;
+};
+
+static irqreturn_t max77650_onkey_falling(int irq, void *data)
+{
+       struct max77650_onkey *onkey = data;
+
+       input_report_key(onkey->input, onkey->code, 0);
+       input_sync(onkey->input);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t max77650_onkey_rising(int irq, void *data)
+{
+       struct max77650_onkey *onkey = data;
+
+       input_report_key(onkey->input, onkey->code, 1);
+       input_sync(onkey->input);
+
+       return IRQ_HANDLED;
+}
+
+static int max77650_onkey_probe(struct platform_device *pdev)
+{
+       int irq_r, irq_f, error, mode;
+       struct max77650_onkey *onkey;
+       struct device *dev, *parent;
+       struct regmap *map;
+       unsigned int type;
+
+       dev = &pdev->dev;
+       parent = dev->parent;
+
+       map = dev_get_regmap(parent, NULL);
+       if (!map)
+               return -ENODEV;
+
+       onkey = devm_kzalloc(dev, sizeof(*onkey), GFP_KERNEL);
+       if (!onkey)
+               return -ENOMEM;
+
+       error = device_property_read_u32(dev, "linux,code", &onkey->code);
+       if (error)
+               onkey->code = KEY_POWER;
+
+       if (device_property_read_bool(dev, "maxim,onkey-slide")) {
+               mode = MAX77650_ONKEY_MODE_SLIDE;
+               type = EV_SW;
+       } else {
+               mode = MAX77650_ONKEY_MODE_PUSH;
+               type = EV_KEY;
+       }
+
+       error = regmap_update_bits(map, MAX77650_REG_CNFG_GLBL,
+                                  MAX77650_ONKEY_MODE_MASK, mode);
+       if (error)
+               return error;
+
+       irq_f = platform_get_irq_byname(pdev, "nEN_F");
+       if (irq_f < 0)
+               return irq_f;
+
+       irq_r = platform_get_irq_byname(pdev, "nEN_R");
+       if (irq_r < 0)
+               return irq_r;
+
+       onkey->input = devm_input_allocate_device(dev);
+       if (!onkey->input)
+               return -ENOMEM;
+
+       onkey->input->name = "max77650_onkey";
+       onkey->input->phys = "max77650_onkey/input0";
+       onkey->input->id.bustype = BUS_I2C;
+       input_set_capability(onkey->input, type, onkey->code);
+
+       error = devm_request_any_context_irq(dev, irq_f, max77650_onkey_falling,
+                                            IRQF_ONESHOT, "onkey-down", onkey);
+       if (error < 0)
+               return error;
+
+       error = devm_request_any_context_irq(dev, irq_r, max77650_onkey_rising,
+                                            IRQF_ONESHOT, "onkey-up", onkey);
+       if (error < 0)
+               return error;
+
+       return input_register_device(onkey->input);
+}
+
+static struct platform_driver max77650_onkey_driver = {
+       .driver = {
+               .name = "max77650-onkey",
+       },
+       .probe = max77650_onkey_probe,
+};
+module_platform_driver(max77650_onkey_driver);
+
+MODULE_DESCRIPTION("MAXIM 77650/77651 ONKEY driver");
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_LICENSE("GPL v2");