lkml.org 
[lkml]   [2020]   [Sep]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCHv2 4/4] Input: rotary-encoder - Add gpio as push button
On Mon, Sep 07, 2020 at 10:40:45PM +0200, Sebastian Reichel wrote:
> From: Mylène Josserand <mylene.josserand@collabora.com>
>
> 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).

But it is not...

> Signed-off-by: Mylène Josserand <mylene.josserand@collabora.com>
> [code cleanup to current standards and renamed some properties]
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> .../bindings/input/rotary-encoder.yaml | 21 +++++++++

Bindings should be a separate patch.

> drivers/input/misc/rotary_encoder.c | 43 +++++++++++++++++++
> 2 files changed, 64 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/input/rotary-encoder.yaml b/Documentation/devicetree/bindings/input/rotary-encoder.yaml
> index 5b60ea86bd62..682fee104004 100644
> --- a/Documentation/devicetree/bindings/input/rotary-encoder.yaml
> +++ b/Documentation/devicetree/bindings/input/rotary-encoder.yaml
> @@ -74,6 +74,24 @@ properties:
> need to be passed.
> type: boolean
>
> + push-gpios:
> + description: GPIO used as a detection of a push from the rotary-encoder.
> + maxItems: 1
> +
> + linux,push-code:
> + description:
> + keycode to emit with the push-gpio of this rotary encoder.
> + If not specified defaults to <28> == KEY_ENTER.
> + $ref: /schemas/types.yaml#/definitions/uint32
> + default: 28
> +
> + linux,push-type:
> + description:
> + Specify event type this button/key generates.
> + If not specified defaults to <1> == EV_KEY.
> + $ref: /schemas/types.yaml#definitions/uint32
> + default: 1

Can we just use 'linux,code' and 'linux,input-type' here. That's
problematic if there's ever more than 1, but so is the current solution
having to make up new property names every time.

Why can't the gpio-keys binding just be used here? Is it important to
have the events on the same device? Is there some coordination needed
between the functions?

> +
> required:
> - compatible
> - gpios
> @@ -97,4 +115,7 @@ examples:
> linux,axis = <ABS_Y>;
> rotary-encoder,encoding = "binary";
> rotary-encoder,rollover;
> + push-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
> + linux,push-code = <KEY_ENTER>;
> + linux,push-type = <EV_KEY>;
> };
> diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
> index 16ad86fad7cb..484042a5afa0 100644
> --- a/drivers/input/misc/rotary_encoder.c
> +++ b/drivers/input/misc/rotary_encoder.c
> @@ -47,12 +47,33 @@ struct rotary_encoder {
>
> unsigned int *irq;
>
> + struct gpio_desc *push_gpio;
> + unsigned int push_code;
> + unsigned int push_type;
> +
> bool armed;
> signed char dir; /* 1 - clockwise, -1 - CCW */
>
> 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->push_gpio);
> +
> + input_report_key(encoder->input, encoder->push_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;
> @@ -248,6 +269,16 @@ static int rotary_encoder_probe(struct platform_device *pdev)
> return -EINVAL;
> }
>
> + encoder->push_gpio = devm_gpiod_get_optional(dev, "push", GPIOD_IN);
> + if (IS_ERR(encoder->push_gpio))
> + return dev_err_probe(dev, PTR_ERR(encoder->push_gpio), "failed to get push-gpio\n");
> +
> + encoder->push_code = KEY_ENTER;
> + device_property_read_u32(dev, "linux,push-code", &encoder->push_code);
> +
> + encoder->push_type = EV_KEY;
> + device_property_read_u32(dev, "linux,push-type", &encoder->push_type);
> +
> input = devm_input_allocate_device(dev);
> if (!input)
> return -ENOMEM;
> @@ -304,6 +335,18 @@ static int rotary_encoder_probe(struct platform_device *pdev)
> }
> }
>
> + if (encoder->push_gpio) {
> + input_set_capability(encoder->input, encoder->push_type, encoder->push_code);
> + err = devm_request_threaded_irq(dev, gpiod_to_irq(encoder->push_gpio),
> + NULL, rotary_push_irq,
> + IRQF_TRIGGER_RISING |
> + IRQF_TRIGGER_FALLING |
> + IRQF_ONESHOT,
> + DRV_NAME, encoder);
> + if (err)
> + return dev_err_probe(dev, err, "unable to request push IRQ\n");
> + }
> +
> err = input_register_device(input);
> if (err) {
> dev_err(dev, "failed to register input device\n");
> --
> 2.28.0
>

\
 
 \ /
  Last update: 2020-09-16 00:19    [W:0.091 / U:7.540 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site