Input: stmpe-keypad - add support for Device Tree bindings
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 14 Nov 2012 16:55:21 +0000 (08:55 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 24 Nov 2012 08:21:49 +0000 (00:21 -0800)
This patch allows the STMPE driver to be successfully probed and
initialised when Device Tree support is enabled. Besides the usual
platform data changes, we also separate the process of filling in
the 'in use' pin bitmap, as we have to extract the information from
Device Tree in the DT boot case.

Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Documentation/devicetree/bindings/input/stmpe-keypad.txt [new file with mode: 0644]
drivers/input/keyboard/stmpe-keypad.c
drivers/mfd/stmpe.c

diff --git a/Documentation/devicetree/bindings/input/stmpe-keypad.txt b/Documentation/devicetree/bindings/input/stmpe-keypad.txt
new file mode 100644 (file)
index 0000000..1b97222
--- /dev/null
@@ -0,0 +1,39 @@
+* STMPE Keypad
+
+Required properties:
+ - compatible               : "st,stmpe-keypad"
+ - linux,keymap             : See ./matrix-keymap.txt
+
+Optional properties:
+ - debounce-interval        : Debouncing interval time in milliseconds
+ - st,scan-count            : Scanning cycles elapsed before key data is updated
+ - st,no-autorepeat         : If specified device will not autorepeat
+
+Example:
+
+       stmpe_keypad {
+               compatible = "st,stmpe-keypad";
+
+               debounce-interval = <64>;
+               st,scan-count = <8>;
+               st,no-autorepeat;
+
+               linux,keymap = <0x205006b
+                               0x4010074
+                               0x3050072
+                               0x1030004
+                               0x502006a
+                               0x500000a
+                               0x5008b
+                               0x706001c
+                               0x405000b
+                               0x6070003
+                               0x3040067
+                               0x303006c
+                               0x60400e7
+                               0x602009e
+                               0x4020073
+                               0x5050002
+                               0x4030069
+                               0x3020008>;
+       };
index 7bac0524900a4e0a475fce2c962e2785bae89a15..5cbec56f772000f2b10836ef6585c65472f96b2d 100644 (file)
@@ -257,6 +257,51 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
                              (plat->debounce_ms << 1));
 }
 
+static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad)
+{
+       int row, col;
+
+       for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) {
+               for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) {
+                       int code = MATRIX_SCAN_CODE(row, col,
+                                               STMPE_KEYPAD_ROW_SHIFT);
+                       if (keypad->keymap[code] != KEY_RESERVED) {
+                               keypad->rows |= 1 << row;
+                               keypad->cols |= 1 << col;
+                       }
+               }
+       }
+}
+
+#ifdef CONFIG_OF
+static const struct stmpe_keypad_platform_data *
+stmpe_keypad_of_probe(struct device *dev)
+{
+       struct device_node *np = dev->of_node;
+       struct stmpe_keypad_platform_data *plat;
+
+       if (!np)
+               return ERR_PTR(-ENODEV);
+
+       plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL);
+       if (!plat)
+               return ERR_PTR(-ENOMEM);
+
+       of_property_read_u32(np, "debounce-interval", &plat->debounce_ms);
+       of_property_read_u32(np, "st,scan-count", &plat->scan_count);
+
+       plat->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat");
+
+       return plat;
+}
+#else
+static inline const struct stmpe_keypad_platform_data *
+stmpe_keypad_of_probe(struct device *dev)
+{
+       return ERR_PTR(-EINVAL);
+}
+#endif
+
 static int stmpe_keypad_probe(struct platform_device *pdev)
 {
        struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
@@ -265,11 +310,13 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
        struct input_dev *input;
        int error;
        int irq;
-       int i;
 
        plat = stmpe->pdata->keypad;
-       if (!plat)
-               return -ENODEV;
+       if (!plat) {
+               plat = stmpe_keypad_of_probe(&pdev->dev);
+               if (IS_ERR(plat))
+                       return PTR_ERR(plat);
+       }
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
@@ -299,12 +346,7 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
        if (!plat->no_autorepeat)
                __set_bit(EV_REP, input->evbit);
 
-       for (i = 0; i < plat->keymap_data->keymap_size; i++) {
-               unsigned int key = plat->keymap_data->keymap[i];
-
-               keypad->cols |= 1 << KEY_COL(key);
-               keypad->rows |= 1 << KEY_ROW(key);
-       }
+       stmpe_keypad_fill_used_pins(keypad);
 
        keypad->stmpe = stmpe;
        keypad->plat = plat;
index 55c7b9531ad4de717649440e76e797d08ddc1745..bf1ba93f43a05c78924d213caf03ea05303232ba 100644 (file)
@@ -324,6 +324,7 @@ static struct resource stmpe_keypad_resources[] = {
 
 static struct mfd_cell stmpe_keypad_cell = {
        .name           = "stmpe-keypad",
+       .of_compatible  = "st,stmpe-keypad",
        .resources      = stmpe_keypad_resources,
        .num_resources  = ARRAY_SIZE(stmpe_keypad_resources),
 };