2019-06-14 13:39:03

by Mylène Josserand

[permalink] [raw]
Subject: [PATCH v1] Input: rotary-encoder - Add gpio as push button

Add the support of a gpio that can be defined as a push button.
Thanks to that, it is possible to emit a keycode in case of a
"push" event, if the rotary supports that.

The keycode to emit is defined using "linux,code" property
(such as in gpio-keys).

Signed-off-by: Mylène Josserand <[email protected]>
---
.../devicetree/bindings/input/rotary-encoder.txt | 5 +++
drivers/input/misc/rotary_encoder.c | 50 ++++++++++++++++++++++
2 files changed, 55 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/rotary-encoder.txt b/Documentation/devicetree/bindings/input/rotary-encoder.txt
index a644408b33b8..1cfce5d0b5c4 100644
--- a/Documentation/devicetree/bindings/input/rotary-encoder.txt
+++ b/Documentation/devicetree/bindings/input/rotary-encoder.txt
@@ -22,6 +22,9 @@ Optional properties:
- wakeup-source: Boolean, rotary encoder can wake up the system.
- rotary-encoder,encoding: String, the method used to encode steps.
Supported are "gray" (the default and more common) and "binary".
+- push-gpio: a gpio to be used as a detection of a push from the rotary.
+- linux,code: keycode to emit with the push-gpio of this rotary encoder.
+ Required property in case "push-gpio"'s one is used.

Deprecated properties:
- rotary-encoder,half-period: Makes the driver work on half-period mode.
@@ -47,4 +50,6 @@ Example:
rotary-encoder,steps = <24>;
rotary-encoder,encoding = "binary";
rotary-encoder,rollover;
+ push-gpio = <&gpio 20 0>;
+ linux-code = <28> /* KEY_ENTER */
};
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index d748897bf5e9..556995fb7dde 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -47,8 +47,10 @@ struct rotary_encoder {
unsigned int pos;

struct gpio_descs *gpios;
+ struct gpio_desc *gpio_push;

unsigned int *irq;
+ unsigned int code;

bool armed;
signed char dir; /* 1 - clockwise, -1 - CCW */
@@ -56,6 +58,23 @@ struct rotary_encoder {
unsigned int last_stable;
};

+static irqreturn_t rotary_push_irq(int irq, void *dev_id)
+{
+ struct rotary_encoder *encoder = dev_id;
+ int val;
+
+ mutex_lock(&encoder->access_mutex);
+
+ val = gpiod_get_value_cansleep(encoder->gpio_push);
+
+ input_report_key(encoder->input, encoder->code, val);
+ input_sync(encoder->input);
+
+ mutex_unlock(&encoder->access_mutex);
+
+ return IRQ_HANDLED;
+}
+
static unsigned int rotary_encoder_get_state(struct rotary_encoder *encoder)
{
int i;
@@ -190,6 +209,7 @@ static int rotary_encoder_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct rotary_encoder *encoder;
struct input_dev *input;
+ unsigned int irq_push;
irq_handler_t handler;
u32 steps_per_period;
unsigned int i;
@@ -250,6 +270,20 @@ static int rotary_encoder_probe(struct platform_device *pdev)
return -EINVAL;
}

+ encoder->gpio_push = devm_gpiod_get_optional(dev, "push", GPIOD_IN);
+ if (IS_ERR(encoder->gpio_push)) {
+ dev_err(dev, "unable to get gpio-push\n");
+ return PTR_ERR(encoder->gpio_push);
+ }
+
+ if (encoder->gpio_push) {
+ if (device_property_read_u32(dev, "linux,code",
+ &encoder->code)) {
+ dev_err(dev, "gpio-push without keycode\n");
+ return -EINVAL;
+ }
+ }
+
input = devm_input_allocate_device(dev);
if (!input)
return -ENOMEM;
@@ -306,6 +340,22 @@ static int rotary_encoder_probe(struct platform_device *pdev)
}
}

+ if (encoder->gpio_push) {
+ input_set_capability(encoder->input, EV_KEY, encoder->code);
+
+ irq_push = gpiod_to_irq(encoder->gpio_push);
+ err = devm_request_threaded_irq(dev, irq_push,
+ NULL, rotary_push_irq,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ DRV_NAME, encoder);
+ if (err) {
+ dev_err(dev, "unable to request IRQ %d\n", irq_push);
+ return err;
+ }
+ }
+
err = input_register_device(input);
if (err) {
dev_err(dev, "failed to register input device\n");
--
2.11.0


2019-06-14 14:53:49

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1] Input: rotary-encoder - Add gpio as push button

Hi Mylene,

On Fri, Jun 14, 2019 at 03:36:51PM +0200, Myl?ne Josserand wrote:
> Add the support of a gpio that can be defined as a push button.
> Thanks to that, it is possible to emit a keycode in case of a
> "push" event, if the rotary supports that.
>
> The keycode to emit is defined using "linux,code" property
> (such as in gpio-keys).
>
> Signed-off-by: Myl?ne Josserand <[email protected]>
> ---
> .../devicetree/bindings/input/rotary-encoder.txt | 5 +++
> drivers/input/misc/rotary_encoder.c | 50 ++++++++++++++++++++++
> 2 files changed, 55 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/input/rotary-encoder.txt b/Documentation/devicetree/bindings/input/rotary-encoder.txt
> index a644408b33b8..1cfce5d0b5c4 100644
> --- a/Documentation/devicetree/bindings/input/rotary-encoder.txt
> +++ b/Documentation/devicetree/bindings/input/rotary-encoder.txt
> @@ -22,6 +22,9 @@ Optional properties:
> - wakeup-source: Boolean, rotary encoder can wake up the system.
> - rotary-encoder,encoding: String, the method used to encode steps.
> Supported are "gray" (the default and more common) and "binary".
> +- push-gpio: a gpio to be used as a detection of a push from the rotary.

According to Documentation/devicetree/bindings/gpio/gpio.txt, GPIO
properties with a -gpio suffix are now deprecated in favor of the
-gpios suffix.

> +- linux,code: keycode to emit with the push-gpio of this rotary encoder.
> + Required property in case "push-gpio"'s one is used.

I guess we should make it clear in the property name that it's the
keycode emitted at push. Otherwise, it will be ambiguous between the
rotary itself, or the button.

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


Attachments:
(No filename) (1.78 kB)
signature.asc (235.00 B)
Download all attachments

2019-06-23 07:06:23

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH v1] Input: rotary-encoder - Add gpio as push button

On Fri, Jun 14, 2019 at 04:51:58PM +0200, Maxime Ripard wrote:
> Hi Mylene,
>
> On Fri, Jun 14, 2019 at 03:36:51PM +0200, Myl?ne Josserand wrote:
> > Add the support of a gpio that can be defined as a push button.
> > Thanks to that, it is possible to emit a keycode in case of a
> > "push" event, if the rotary supports that.
> >
> > The keycode to emit is defined using "linux,code" property
> > (such as in gpio-keys).
> >
> > Signed-off-by: Myl?ne Josserand <[email protected]>
> > ---
> > .../devicetree/bindings/input/rotary-encoder.txt | 5 +++
> > drivers/input/misc/rotary_encoder.c | 50 ++++++++++++++++++++++
> > 2 files changed, 55 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/input/rotary-encoder.txt b/Documentation/devicetree/bindings/input/rotary-encoder.txt
> > index a644408b33b8..1cfce5d0b5c4 100644
> > --- a/Documentation/devicetree/bindings/input/rotary-encoder.txt
> > +++ b/Documentation/devicetree/bindings/input/rotary-encoder.txt
> > @@ -22,6 +22,9 @@ Optional properties:
> > - wakeup-source: Boolean, rotary encoder can wake up the system.
> > - rotary-encoder,encoding: String, the method used to encode steps.
> > Supported are "gray" (the default and more common) and "binary".
> > +- push-gpio: a gpio to be used as a detection of a push from the rotary.
>
> According to Documentation/devicetree/bindings/gpio/gpio.txt, GPIO
> properties with a -gpio suffix are now deprecated in favor of the
> -gpios suffix.
>
> > +- linux,code: keycode to emit with the push-gpio of this rotary encoder.
> > + Required property in case "push-gpio"'s one is used.
>
> I guess we should make it clear in the property name that it's the
> keycode emitted at push. Otherwise, it will be ambiguous between the
> rotary itself, or the button.

Also, I am pretty sure someone will come up with a switch instead of a
button shortly after ;) so I think we should have an event type there as
well.

Thanks.

--
Dmitry