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>