]> git.dujemihanovic.xyz Git - linux.git/commitdiff
Input: adp5588-keys - add support for pure gpio
authorUtsav Agarwal <utsav.agarwal@analog.com>
Mon, 26 Aug 2024 17:22:02 +0000 (18:22 +0100)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 29 Aug 2024 01:50:45 +0000 (18:50 -0700)
Keypad specific setup is relaxed if no keypad rows/columns are specified,
enabling a purely gpio operation.

Reviewed-by: Nuno Sa <nuno.sa@analog.com>
Signed-off-by: Utsav Agarwal <utsav.agarwal@analog.com>
Link: https://lore.kernel.org/r/20240826-adp5588_gpio_support-v11-2-3e5ac2bd31b7@analog.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/keyboard/adp5588-keys.c

index 09bcfc6b9408a51fba8f38b0b0b45d93c1fd2b13..b5f4becf5cb6f3ac8f3076793be849c30416b496 100644 (file)
@@ -188,6 +188,7 @@ struct adp5588_kpad {
        u32 cols;
        u32 unlock_keys[2];
        int nkeys_unlock;
+       bool gpio_only;
        unsigned short keycode[ADP5588_KEYMAPSIZE];
        unsigned char gpiomap[ADP5588_MAXGPIO];
        struct gpio_chip gc;
@@ -431,10 +432,17 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
        kpad->gc.label = kpad->client->name;
        kpad->gc.owner = THIS_MODULE;
 
-       girq = &kpad->gc.irq;
-       gpio_irq_chip_set_chip(girq, &adp5588_irq_chip);
-       girq->handler = handle_bad_irq;
-       girq->threaded = true;
+       if (device_property_present(dev, "interrupt-controller")) {
+               if (!kpad->client->irq) {
+                       dev_err(dev, "Unable to serve as interrupt controller without interrupt");
+                       return -EINVAL;
+               }
+
+               girq = &kpad->gc.irq;
+               gpio_irq_chip_set_chip(girq, &adp5588_irq_chip);
+               girq->handler = handle_bad_irq;
+               girq->threaded = true;
+       }
 
        mutex_init(&kpad->gpio_lock);
 
@@ -632,6 +640,18 @@ static int adp5588_fw_parse(struct adp5588_kpad *kpad)
        struct i2c_client *client = kpad->client;
        int ret, i;
 
+       /*
+        * Check if the device is to be operated purely in GPIO mode. To do
+        * so, check that no keypad rows or columns have been specified,
+        * since all GPINS should be configured as GPIO.
+        */
+       if (!device_property_present(&client->dev, "keypad,num-rows") &&
+           !device_property_present(&client->dev, "keypad,num-columns")) {
+               /* If purely GPIO, skip keypad setup */
+               kpad->gpio_only = true;
+               return 0;
+       }
+
        ret = matrix_keypad_parse_properties(&client->dev, &kpad->rows,
                                             &kpad->cols);
        if (ret)
@@ -775,17 +795,19 @@ static int adp5588_probe(struct i2c_client *client)
        if (error)
                return error;
 
-       error = devm_request_threaded_irq(&client->dev, client->irq,
-                                         adp5588_hard_irq, adp5588_thread_irq,
-                                         IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                         client->dev.driver->name, kpad);
-       if (error) {
-               dev_err(&client->dev, "failed to request irq %d: %d\n",
-                       client->irq, error);
-               return error;
+       if (client->irq) {
+               error = devm_request_threaded_irq(&client->dev, client->irq,
+                                                 adp5588_hard_irq, adp5588_thread_irq,
+                                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                                 client->dev.driver->name, kpad);
+               if (error) {
+                       dev_err(&client->dev, "failed to request irq %d: %d\n",
+                               client->irq, error);
+                       return error;
+               }
        }
 
-       dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
+       dev_info(&client->dev, "Rev.%d controller\n", revid);
        return 0;
 }