Signed-off-by: Robin van der Gracht <ro...@protonic.nl>
---
Changes in v2:
        - Removed the trailing dot in the patch subject

 .../devicetree/bindings/display/ht16k33.txt        |  15 ++-
 drivers/auxdisplay/ht16k33.c                       | 126 +++++++++++----------
 2 files changed, 73 insertions(+), 68 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/ht16k33.txt 
b/Documentation/devicetree/bindings/display/ht16k33.txt
index 8e5b30b..e2c9048 100644
--- a/Documentation/devicetree/bindings/display/ht16k33.txt
+++ b/Documentation/devicetree/bindings/display/ht16k33.txt
@@ -4,18 +4,21 @@ Holtek ht16k33 RAM mapping 16*8 LED controller driver with 
keyscan
 Required properties:
 - compatible:          "holtek,ht16k33"
 - reg:                 I2C slave address of the chip.
-- interrupt-parent:    A phandle pointing to the interrupt controller
-                       serving the interrupt for this chip.
-- interrupts:          Interrupt specification for the key pressed interrupt.
 - refresh-rate-hz:     Display update interval in HZ.
-- debounce-delay-ms:   Debouncing interval time in milliseconds.
-- linux,keymap:        The keymap for keys as described in the binding
-                       document (devicetree/bindings/input/matrix-keymap.txt).
 
 Optional properties:
 - linux,no-autorepeat: Disable keyrepeat.
 - default-brightness-level: Initial brightness level [0-15] (default: 15).
 
+- Keypad
+ Supply the 'interrupts' property to enable the keyscan feature.
+ - interrupts:         Interrupt specification for the key pressed interrupt.
+ - interrupt-parent:   A phandle pointing to the interrupt controller
+                       serving the interrupt for this chip.
+ - debounce-delay-ms:  Debouncing interval time in milliseconds.
+ - linux,keymap:       The keymap for keys as described in the binding
+                       document (devicetree/bindings/input/matrix-keymap.txt).
+
 Example:
 
 &i2c1 {
diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c
index 9c09bbc..5cf8fb4 100644
--- a/drivers/auxdisplay/ht16k33.c
+++ b/drivers/auxdisplay/ht16k33.c
@@ -334,15 +334,71 @@ static struct fb_ops ht16k33_fb_ops = {
        .fb_mmap = ht16k33_mmap,
 };
 
+static int ht16k33_register_keypad(struct ht16k33_priv *priv)
+{
+       int rows, cols, err;
+       struct ht16k33_keypad *keypad = &priv->keypad;
+       struct device *dev = &priv->client->dev;
+
+       keypad->dev = devm_input_allocate_device(dev);
+       if (!keypad->dev)
+               return -ENOMEM;
+
+       keypad->dev->name = dev_name(dev);
+       keypad->dev->id.bustype = BUS_I2C;
+       keypad->dev->open = ht16k33_keypad_start;
+       keypad->dev->close = ht16k33_keypad_stop;
+
+       if (!of_get_property(dev->of_node, "linux,no-autorepeat", NULL))
+               __set_bit(EV_REP, keypad->dev->evbit);
+
+       err = of_property_read_u32(dev->of_node, "debounce-delay-ms",
+                                  &keypad->debounce_ms);
+       if (err) {
+               dev_err(dev, "key debounce delay not specified\n");
+               return err;
+       }
+
+       err = devm_request_threaded_irq(dev, priv->client->irq, NULL,
+                                       ht16k33_irq_thread,
+                                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+                                       DRIVER_NAME, priv);
+       if (err) {
+               dev_err(dev, "Failed to request irq %i\n", priv->client->irq);
+               return err;
+       }
+
+       disable_irq_nosync(priv->client->irq);
+       rows = HT16K33_MATRIX_KEYPAD_MAX_ROWS;
+       cols = HT16K33_MATRIX_KEYPAD_MAX_COLS;
+       err = matrix_keypad_parse_of_params(dev, &rows, &cols);
+       if (err)
+               return err;
+
+       err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL,
+                                        keypad->dev);
+       if (err) {
+               dev_err(dev, "failed to build keymap\n");
+               return err;
+       }
+
+       input_set_drvdata(keypad->dev, priv);
+       keypad->rows = rows;
+       keypad->cols = cols;
+       keypad->row_shift = get_count_order(cols);
+       INIT_DELAYED_WORK(&keypad->work, ht16k33_keypad_scan);
+
+       return input_register_device(keypad->dev);
+}
+
 static int ht16k33_probe(struct i2c_client *client,
                                  const struct i2c_device_id *id)
 {
        int err;
-       uint32_t rows, cols, dft_brightness;
+       uint32_t dft_brightness;
        struct backlight_device *bl;
        struct backlight_properties bl_props;
        struct ht16k33_priv *priv;
-       struct ht16k33_keypad *keypad;
        struct ht16k33_fbdev *fbdev;
        struct device_node *node = client->dev.of_node;
        const char *dev_id = dev_name(&client->dev);
@@ -352,11 +408,6 @@ static int ht16k33_probe(struct i2c_client *client,
                return -EIO;
        }
 
-       if (client->irq <= 0) {
-               dev_err(&client->dev, "No IRQ specified\n");
-               return -EINVAL;
-       }
-
        priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
@@ -364,7 +415,6 @@ static int ht16k33_probe(struct i2c_client *client,
        priv->client = client;
        i2c_set_clientdata(client, priv);
        fbdev = &priv->fbdev;
-       keypad = &priv->keypad;
 
        priv->workqueue = create_singlethread_workqueue(dev_id);
        if (priv->workqueue == NULL)
@@ -417,61 +467,12 @@ static int ht16k33_probe(struct i2c_client *client,
                goto err_fbdev_info;
 
        /* Keypad */
-       keypad->dev = devm_input_allocate_device(&client->dev);
-       if (!keypad->dev) {
-               err = -ENOMEM;
-               goto err_fbdev_unregister;
-       }
-
-       keypad->dev->name = dev_id;
-       keypad->dev->id.bustype = BUS_I2C;
-       keypad->dev->open = ht16k33_keypad_start;
-       keypad->dev->close = ht16k33_keypad_stop;
-
-       if (!of_get_property(node, "linux,no-autorepeat", NULL))
-               __set_bit(EV_REP, keypad->dev->evbit);
-
-       err = of_property_read_u32(node, "debounce-delay-ms",
-                                  &keypad->debounce_ms);
-       if (err) {
-               dev_err(&client->dev, "key debounce delay not specified\n");
-               goto err_fbdev_unregister;
+       if (client->irq > 0) {
+               err = ht16k33_register_keypad(priv);
+               if (err)
+                       goto err_fbdev_unregister;
        }
 
-       err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
-                                       ht16k33_irq_thread,
-                                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-                                       DRIVER_NAME, priv);
-       if (err) {
-               dev_err(&client->dev, "irq request failed %d, error %d\n",
-                       client->irq, err);
-               goto err_fbdev_unregister;
-       }
-
-       disable_irq_nosync(client->irq);
-       rows = HT16K33_MATRIX_KEYPAD_MAX_ROWS;
-       cols = HT16K33_MATRIX_KEYPAD_MAX_COLS;
-       err = matrix_keypad_parse_of_params(&client->dev, &rows, &cols);
-       if (err)
-               goto err_fbdev_unregister;
-
-       err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL,
-                                        keypad->dev);
-       if (err) {
-               dev_err(&client->dev, "failed to build keymap\n");
-               goto err_fbdev_unregister;
-       }
-
-       input_set_drvdata(keypad->dev, priv);
-       keypad->rows = rows;
-       keypad->cols = cols;
-       keypad->row_shift = get_count_order(cols);
-       INIT_DELAYED_WORK(&keypad->work, ht16k33_keypad_scan);
-
-       err = input_register_device(keypad->dev);
-       if (err)
-               goto err_fbdev_unregister;
-
        /* Backlight */
        memset(&bl_props, 0, sizeof(struct backlight_properties));
        bl_props.type = BACKLIGHT_RAW;
@@ -504,7 +505,8 @@ static int ht16k33_probe(struct i2c_client *client,
        return 0;
 
 err_keypad_unregister:
-       input_unregister_device(keypad->dev);
+       if (priv->keypad.dev)
+               input_unregister_device(priv->keypad.dev);
 err_fbdev_unregister:
        unregister_framebuffer(fbdev->info);
 err_fbdev_info:
-- 
2.7.4

Reply via email to