Re: [PATCH] Input: add switch event(SW_EXT_PEN_ATTACHED)

2020-10-30 Thread gre...@linuxfoundation.org
On Fri, Oct 30, 2020 at 03:27:40PM +0900, HyungJae Im wrote:
> We need support to various accessories on the device,
> some requiring switch does not exist in switch list.
> So added switch for the following purpose.
> 
> SW_EXT_PEN_ATTACHED is for the checking the external pen
> attached or not on the device. We also added driver
> that uses such event.
> 
> Signed-off-by: Hyungjae Im 
> ---
>  drivers/input/Kconfig  |  12 ++
>  drivers/input/Makefile |   1 +
>  drivers/input/ext_pen_detect.c | 237 +
>  include/linux/mod_devicetable.h|   2 +-
>  include/uapi/linux/input-event-codes.h |   3 +-
>  5 files changed, 253 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/input/ext_pen_detect.c
> 
> diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
> index ba5e7444c547..5d6d15c8f7e7 100644
> --- a/drivers/input/Kconfig
> +++ b/drivers/input/Kconfig
> @@ -197,6 +197,18 @@ config INPUT_COVER_DETECT
> To compile this driver as a module, choose M here: the
> module will be called cover_detect.
>  
> +config INPUT_EXT_PEN_DETECT
> + tristate "Enable external pen attach detection"
> + help
> +   Say Y here to enable external pen detection
> +   and send a event when external pen is attached/detached.
> +   Active gpio state is low and active event value is 0.
> +
> +   If unsure, say N.
> +
> +   To compile this driver as a module, choose M here: the
> +   module will be called ext_pen_detect.
> +
>  comment "Input Device Drivers"
>  
>  source "drivers/input/keyboard/Kconfig"
> diff --git a/drivers/input/Makefile b/drivers/input/Makefile
> index fc8dd9091821..0ccf02e34557 100644
> --- a/drivers/input/Makefile
> +++ b/drivers/input/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_INPUT_APMPOWER)+= apm-power.o
>  obj-$(CONFIG_RMI4_CORE)  += rmi4/
>  
>  obj-$(CONFIG_INPUT_COVER_DETECT)+= cover_detect.o
> +obj-$(CONFIG_INPUT_EXT_PEN_DETECT)+= ext_pen_detect.o
> diff --git a/drivers/input/ext_pen_detect.c b/drivers/input/ext_pen_detect.c
> new file mode 100644
> index ..9a0d106e49f8
> --- /dev/null
> +++ b/drivers/input/ext_pen_detect.c
> @@ -0,0 +1,237 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Support detection pen attachment externally on device
> + *
> + * Copyright (C) 2020 Samsung Electronics Co. Ltd. All Rights Reserved.
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct ext_pen_detect_drvdata {
> + struct input_dev *input;
> + struct delayed_work ext_pen_detect_dwork;
> + struct wakeup_source *ws;
> + int gpio_ext_pen_detect;
> + int irq_ext_pen_detect;
> +};
> +
> +static void ext_pen_detect_work(struct work_struct *work)
> +{
> + struct ext_pen_detect_drvdata *ddata =
> + container_of(work, struct ext_pen_detect_drvdata,
> + ext_pen_detect_dwork.work);
> + bool ext_pen_status;
> +
> + ext_pen_status = gpio_get_value(ddata->gpio_ext_pen_detect);
> +
> + input_report_switch(ddata->input,
> + SW_EXT_PEN_ATTACHED, ext_pen_status);

As this is just a gpio device, again, why is this needed and you can't
just use the gpio_keys driver instead?

Why does this have to be a new driver?

thanks,

greg k-h


[PATCH] Input: add switch event(SW_EXT_PEN_ATTACHED)

2020-10-30 Thread HyungJae Im
We need support to various accessories on the device,
some requiring switch does not exist in switch list.
So added switch for the following purpose.

SW_EXT_PEN_ATTACHED is for the checking the external pen
attached or not on the device. We also added driver
that uses such event.

Signed-off-by: Hyungjae Im 
---
 drivers/input/Kconfig  |  12 ++
 drivers/input/Makefile |   1 +
 drivers/input/ext_pen_detect.c | 237 +
 include/linux/mod_devicetable.h|   2 +-
 include/uapi/linux/input-event-codes.h |   3 +-
 5 files changed, 253 insertions(+), 2 deletions(-)
 create mode 100644 drivers/input/ext_pen_detect.c

diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index ba5e7444c547..5d6d15c8f7e7 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -197,6 +197,18 @@ config INPUT_COVER_DETECT
  To compile this driver as a module, choose M here: the
  module will be called cover_detect.
 
+config INPUT_EXT_PEN_DETECT
+   tristate "Enable external pen attach detection"
+   help
+ Say Y here to enable external pen detection
+ and send a event when external pen is attached/detached.
+ Active gpio state is low and active event value is 0.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ext_pen_detect.
+
 comment "Input Device Drivers"
 
 source "drivers/input/keyboard/Kconfig"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index fc8dd9091821..0ccf02e34557 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_INPUT_APMPOWER)  += apm-power.o
 obj-$(CONFIG_RMI4_CORE)+= rmi4/
 
 obj-$(CONFIG_INPUT_COVER_DETECT)+= cover_detect.o
+obj-$(CONFIG_INPUT_EXT_PEN_DETECT)+= ext_pen_detect.o
diff --git a/drivers/input/ext_pen_detect.c b/drivers/input/ext_pen_detect.c
new file mode 100644
index ..9a0d106e49f8
--- /dev/null
+++ b/drivers/input/ext_pen_detect.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Support detection pen attachment externally on device
+ *
+ * Copyright (C) 2020 Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct ext_pen_detect_drvdata {
+   struct input_dev *input;
+   struct delayed_work ext_pen_detect_dwork;
+   struct wakeup_source *ws;
+   int gpio_ext_pen_detect;
+   int irq_ext_pen_detect;
+};
+
+static void ext_pen_detect_work(struct work_struct *work)
+{
+   struct ext_pen_detect_drvdata *ddata =
+   container_of(work, struct ext_pen_detect_drvdata,
+   ext_pen_detect_dwork.work);
+   bool ext_pen_status;
+
+   ext_pen_status = gpio_get_value(ddata->gpio_ext_pen_detect);
+
+   input_report_switch(ddata->input,
+   SW_EXT_PEN_ATTACHED, ext_pen_status);
+   input_sync(ddata->input);
+}
+
+static void __ext_pen_detect(struct ext_pen_detect_drvdata *ddata,
+   bool ext_pen_status)
+{
+   cancel_delayed_work_sync(>ext_pen_detect_dwork);
+   if (ext_pen_status) {
+   __pm_wakeup_event(ddata->ws, jiffies_to_msecs(HZ / 20));
+   schedule_delayed_work(>ext_pen_detect_dwork,
+   HZ * 1 / 100);
+   } else {
+   __pm_relax(ddata->ws);
+   schedule_delayed_work(>ext_pen_detect_dwork, 0);
+   }
+}
+
+static irqreturn_t ext_pen_detect_irq(int irq, void *dev_id)
+{
+   bool ext_pen_status;
+   struct ext_pen_detect_drvdata *ddata = dev_id;
+
+   ext_pen_status = gpio_get_value(ddata->gpio_ext_pen_detect);
+
+   __ext_pen_detect(ddata, ext_pen_status);
+
+   return IRQ_HANDLED;
+}
+
+static int ext_pen_detect_open(struct input_dev *input)
+{
+   struct ext_pen_detect_drvdata *ddata = input_get_drvdata(input);
+   /* update the current status */
+   schedule_delayed_work(>ext_pen_detect_dwork, HZ / 2);
+   /* Report current state of buttons that are connected to GPIOs */
+   input_sync(input);
+
+   return 0;
+}
+
+static void ext_pen_detect_close(struct input_dev *input)
+{
+}
+
+static void init_ext_pen_detect_irq(struct input_dev *input)
+{
+   struct ext_pen_detect_drvdata *ddata = input_get_drvdata(input);
+
+   int ret = 0;
+   int irq = ddata->irq_ext_pen_detect;
+
+   ret =   request_threaded_irq(
+   irq, NULL,
+   ext_pen_detect_irq,
+   IRQF_TRIGGER_RISING |
+   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+   "ext_pen_detect", ddata);
+   if (ret < 0)
+   pr_err("keys: failed to request ext_pen detect irq %d gpio 
%d\n",
+   irq, ddata->gpio_ext_pen_detect);
+}
+
+#ifdef CONFIG_OF
+static