Hi All,<br><br>Gentle Ping on this... <br><br>~Sourav<br><br><div class="gmail_quote">On Fri, Jun 8, 2012 at 4:22 PM, Sourav Poddar <span dir="ltr"><<a href="mailto:sourav.poddar@ti.com" target="_blank">sourav.poddar@ti.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Update the Documentation with omap4 keypad device tree<br>
binding information.<br>
Add device tree support for omap4 keypad driver.<br>
<br>
Tested on omap4430 sdp.<br>
<br>
Cc: Andrew Morton <<a href="mailto:akpm@linux-foundation.org">akpm@linux-foundation.org</a>><br>
Cc: Benoit Cousson <<a href="mailto:b-cousson@ti.com">b-cousson@ti.com</a>><br>
Cc: Rob Herring <<a href="mailto:rob.herring@calxeda.com">rob.herring@calxeda.com</a>><br>
Cc: Grant Likely <<a href="mailto:grant.likely@secretlab.ca">grant.likely@secretlab.ca</a>><br>
Cc: Felipe Balbi <<a href="mailto:balbi@ti.com">balbi@ti.com</a>><br>
Cc: Dmitry Torokhov <<a href="mailto:dtor@mail.ru">dtor@mail.ru</a>><br>
Cc: Randy Dunlap <<a href="mailto:rdunlap@xenotime.net">rdunlap@xenotime.net</a>><br>
Signed-off-by: Sourav Poddar <<a href="mailto:sourav.poddar@ti.com">sourav.poddar@ti.com</a>><br>
---<br>
changes since v4:<br>
- Developed it on top of dmitry's 'next' branch due to<br>
dependency on generic "matrix_keypad_build_keymap" api<br>
patches queued in that branch<br>
- Adapted the driver to fill "keymap" in device tree<br>
using "matrix_keypad_build_keymap" api defined in<br>
drivers/input/matrix-keymap.c<br>
 .../devicetree/bindings/input/omap-keypad.txt      |   31 ++++++<br>
 drivers/input/keyboard/omap4-keypad.c              |  108 +++++++++++++++-----<br>
 2 files changed, 111 insertions(+), 28 deletions(-)<br>
 create mode 100644 Documentation/devicetree/bindings/input/omap-keypad.txt<br>
<br>
diff --git a/Documentation/devicetree/bindings/input/omap-keypad.txt b/Documentation/devicetree/bindings/input/omap-keypad.txt<br>
new file mode 100644<br>
index 0000000..722425b<br>
--- /dev/null<br>
+++ b/Documentation/devicetree/bindings/input/omap-keypad.txt<br>
@@ -0,0 +1,31 @@<br>
+* TI's Keypad Controller device tree bindings<br>
+<br>
+TI's Keypad controller is used to interface a SoC with a matrix-type<br>
+keypad device. The keypad controller supports multiple row and column lines.<br>
+A key can be placed at each intersection of a unique row and a unique column.<br>
+The keypad controller can sense a key-press and key-release and report the<br>
+event using a interrupt to the cpu.<br>
+<br>
+Required SoC Specific Properties:<br>
+- compatible: should be one of the following<br>
+   - "ti,omap4-keypad": For controllers compatible with omap4 keypad<br>
+      controller.<br>
+<br>
+Required Board Specific Properties, in addition to those specified by<br>
+the shared matrix-keyboard bindings:<br>
+- keypad,num-rows: Number of row lines connected to the keypad<br>
+  controller.<br>
+<br>
+- keypad,num-columns: Number of column lines connected to the<br>
+  keypad controller.<br>
+<br>
+Optional Properties specific to linux:<br>
+- linux,keypad-no-autorepeat: do no enable autorepeat feature.<br>
+<br>
+Example:<br>
+        keypad@4ae1c000{<br>
+                compatible = "ti,omap4-keypad";<br>
+                keypad,num-rows = <2>;<br>
+                keypad,num-columns = <8>;<br>
+               linux,keypad-no-autorepeat;<br>
+       };<br>
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c<br>
index aed5f69..d5a2d1a 100644<br>
--- a/drivers/input/keyboard/omap4-keypad.c<br>
+++ b/drivers/input/keyboard/omap4-keypad.c<br>
@@ -27,6 +27,7 @@<br>
 #include <linux/platform_device.h><br>
 #include <linux/errno.h><br>
 #include <linux/io.h><br>
+#include <linux/of.h><br>
 #include <linux/input.h><br>
 #include <linux/slab.h><br>
 #include <linux/pm_runtime.h><br>
@@ -75,6 +76,7 @@ enum {<br>
<br>
 struct omap4_keypad {<br>
        struct input_dev *input;<br>
+       struct matrix_keymap_data *keymap_data;<br>
<br>
        void __iomem *base;<br>
        unsigned int irq;<br>
@@ -84,6 +86,7 @@ struct omap4_keypad {<br>
        u32 reg_offset;<br>
        u32 irqreg_offset;<br>
        unsigned int row_shift;<br>
+       bool no_autorepeat;<br>
        unsigned char key_state[8];<br>
        unsigned short keymap[];<br>
 };<br>
@@ -208,25 +211,74 @@ static void omap4_keypad_close(struct input_dev *input)<br>
        pm_runtime_put_sync(input->dev.parent);<br>
 }<br>
<br>
+static struct omap4_keypad *omap_keypad_parse_dt(struct device *dev,<br>
+                               uint32_t rows, uint32_t cols,<br>
+                               struct input_dev *input_dev)<br>
+{<br>
+       struct device_node *np = dev->of_node;<br>
+       struct platform_device *pdev = to_platform_device(dev);<br>
+       struct omap4_keypad *keypad_data = platform_get_drvdata(pdev);<br>
+       int error;<br>
+<br>
+       error = matrix_keypad_build_keymap(NULL, "linux,keymap",<br>
+                               rows, cols, keypad_data->keymap, input_dev);<br>
+       if (error) {<br>
+               dev_err(&pdev->dev, "failed to build keymap\n");<br>
+               input_free_device(input_dev);<br>
+       }<br>
+<br>
+       if (of_get_property(np, "linux,input-no-autorepeat", NULL))<br>
+               keypad_data->no_autorepeat = true;<br>
+<br>
+       return keypad_data;<br>
+}<br>
+<br>
 static int __devinit omap4_keypad_probe(struct platform_device *pdev)<br>
 {<br>
+       struct device *dev = &pdev->dev;<br>
+       struct device_node *np = dev->of_node;<br>
        const struct omap4_keypad_platform_data *pdata;<br>
        struct omap4_keypad *keypad_data;<br>
        struct input_dev *input_dev;<br>
        struct resource *res;<br>
        resource_size_t size;<br>
-       unsigned int row_shift, max_keys;<br>
+       unsigned int row_shift = 0, max_keys = 0;<br>
+       uint32_t num_rows = 0, num_cols = 0;<br>
        int rev;<br>
        int irq;<br>
        int error;<br>
<br>
        /* platform data */<br>
        pdata = pdev->dev.platform_data;<br>
-       if (!pdata) {<br>
+       if (np) {<br>
+               of_property_read_u32(np, "keypad,num-rows", &num_rows);<br>
+               of_property_read_u32(np, "keypad,num-columns", &num_cols);<br>
+               if (!num_rows || !num_cols) {<br>
+                       dev_err(&pdev->dev, "number of keypad rows/columns not specified\n");<br>
+                       return -EINVAL;<br>
+               }<br>
+       } else if (pdata) {<br>
+               num_rows = pdata->rows;<br>
+               num_cols = pdata->cols;<br>
+       } else {<br>
                dev_err(&pdev->dev, "no platform data defined\n");<br>
                return -EINVAL;<br>
        }<br>
<br>
+       row_shift = get_count_order(num_cols);<br>
+       max_keys = num_rows << row_shift;<br>
+<br>
+       keypad_data = devm_kzalloc(dev, sizeof(struct omap4_keypad) +<br>
+                       max_keys * sizeof(keypad_data->keymap[0]),<br>
+                               GFP_KERNEL);<br>
+<br>
+       if (!keypad_data) {<br>
+               dev_err(&pdev->dev, "keypad_data memory allocation failed\n");<br>
+               return -ENOMEM;<br>
+       }<br>
+<br>
+       platform_set_drvdata(pdev, keypad_data);<br>
+<br>
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);<br>
        if (!res) {<br>
                dev_err(&pdev->dev, "no base address specified\n");<br>
@@ -239,22 +291,6 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)<br>
                return -EINVAL;<br>
        }<br>
<br>
-       if (!pdata->keymap_data) {<br>
-               dev_err(&pdev->dev, "no keymap data defined\n");<br>
-               return -EINVAL;<br>
-       }<br>
-<br>
-       row_shift = get_count_order(pdata->cols);<br>
-       max_keys = pdata->rows << row_shift;<br>
-<br>
-       keypad_data = kzalloc(sizeof(struct omap4_keypad) +<br>
-                               max_keys * sizeof(keypad_data->keymap[0]),<br>
-                             GFP_KERNEL);<br>
-       if (!keypad_data) {<br>
-               dev_err(&pdev->dev, "keypad_data memory allocation failed\n");<br>
-               return -ENOMEM;<br>
-       }<br>
-<br>
        size = resource_size(res);<br>
<br>
        res = request_mem_region(res->start, size, pdev->name);<br>
@@ -271,10 +307,10 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)<br>
                goto err_release_mem;<br>
        }<br>
<br>
+       keypad_data->rows = num_rows;<br>
+       keypad_data->cols = num_cols;<br>
        keypad_data->irq = irq;<br>
        keypad_data->row_shift = row_shift;<br>
-       keypad_data->rows = pdata->rows;<br>
-       keypad_data->cols = pdata->cols;<br>
<br>
        /*<br>
        * Enable clocks for the keypad module so that we can read<br>
@@ -322,15 +358,25 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)<br>
        input_dev->open = omap4_keypad_open;<br>
        input_dev->close = omap4_keypad_close;<br>
<br>
-       error = matrix_keypad_build_keymap(pdata->keymap_data, NULL,<br>
-                                          pdata->rows, pdata->cols,<br>
-                                          keypad_data->keymap, input_dev);<br>
-       if (error) {<br>
-               dev_err(&pdev->dev, "failed to build keymap\n");<br>
-               goto err_free_input;<br>
+       if (np) {<br>
+               keypad_data = omap_keypad_parse_dt(&pdev->dev,<br>
+                               keypad_data->rows, keypad_data->cols,<br>
+                               input_dev);<br>
+       } else {<br>
+               keypad_data->keymap_data =<br>
+                       (struct matrix_keymap_data *)pdata->keymap_data;<br>
+               error = matrix_keypad_build_keymap(keypad_data->keymap_data,<br>
+                               NULL, keypad_data->rows, keypad_data->cols,<br>
+                               keypad_data->keymap, input_dev);<br>
+               if (error) {<br>
+                       dev_err(&pdev->dev, "failed to build keymap\n");<br>
+                       goto err_free_input;<br>
+               }<br>
        }<br>
<br>
-       __set_bit(EV_REP, input_dev->evbit);<br>
+       if (!keypad_data->no_autorepeat)<br>
+               __set_bit(EV_REP, input_dev->evbit);<br>
+<br>
        input_set_capability(input_dev, EV_MSC, MSC_SCAN);<br>
<br>
        input_set_drvdata(input_dev, keypad_data);<br>
@@ -351,7 +397,6 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)<br>
                goto err_pm_disable;<br>
        }<br>
<br>
-       platform_set_drvdata(pdev, keypad_data);<br>
        return 0;<br>
<br>
 err_pm_disable:<br>
@@ -392,12 +437,19 @@ static int __devexit omap4_keypad_remove(struct platform_device *pdev)<br>
        return 0;<br>
 }<br>
<br>
+static const struct of_device_id omap_keypad_dt_match[] = {<br>
+       { .compatible = "ti,omap4-keypad" },<br>
+       {},<br>
+};<br>
+MODULE_DEVICE_TABLE(of, omap_keypad_dt_match);<br>
+<br>
 static struct platform_driver omap4_keypad_driver = {<br>
        .probe          = omap4_keypad_probe,<br>
        .remove         = __devexit_p(omap4_keypad_remove),<br>
        .driver         = {<br>
                .name   = "omap4-keypad",<br>
                .owner  = THIS_MODULE,<br>
+               .of_match_table = of_match_ptr(omap_keypad_dt_match),<br>
        },<br>
 };<br>
 module_platform_driver(omap4_keypad_driver);<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.1<br>
<br>
</font></span></blockquote></div><br>