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