Merge branch 'torvalds/master'
[firefly-linux-kernel-4.4.55.git] / drivers / input / keyboard / pxa27x_keypad.c
index 5330d8fbf6c05a4d4c9e67d0a970beca8c3a076e..fcef5d1365e2a3034e3a9544f7e403a0680a5058 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/io.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/keypad-pxa27x.h>
 /*
  * Keypad Controller registers
 #define MAX_KEYPAD_KEYS                (MAX_MATRIX_KEY_NUM + MAX_DIRECT_KEY_NUM)
 
 struct pxa27x_keypad {
-       struct pxa27x_keypad_platform_data *pdata;
+       const struct pxa27x_keypad_platform_data *pdata;
 
        struct clk *clk;
        struct input_dev *input_dev;
@@ -111,6 +108,8 @@ struct pxa27x_keypad {
        unsigned short keycodes[MAX_KEYPAD_KEYS];
        int rotary_rel_code[2];
 
+       unsigned int row_shift;
+
        /* state row bits of each column scan */
        uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS];
        uint32_t direct_key_state;
@@ -118,25 +117,252 @@ struct pxa27x_keypad {
        unsigned int direct_key_mask;
 };
 
-static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
+#ifdef CONFIG_OF
+static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad,
+                               struct pxa27x_keypad_platform_data *pdata)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        struct input_dev *input_dev = keypad->input_dev;
-       unsigned short keycode;
+       struct device *dev = input_dev->dev.parent;
+       u32 rows, cols;
+       int error;
+
+       error = matrix_keypad_parse_of_params(dev, &rows, &cols);
+       if (error)
+               return error;
+
+       if (rows > MAX_MATRIX_KEY_ROWS || cols > MAX_MATRIX_KEY_COLS) {
+               dev_err(dev, "rows or cols exceeds maximum value\n");
+               return -EINVAL;
+       }
+
+       pdata->matrix_key_rows = rows;
+       pdata->matrix_key_cols = cols;
+
+       error = matrix_keypad_build_keymap(NULL, NULL,
+                                          pdata->matrix_key_rows,
+                                          pdata->matrix_key_cols,
+                                          keypad->keycodes, input_dev);
+       if (error)
+               return error;
+
+       return 0;
+}
+
+static int pxa27x_keypad_direct_key_parse_dt(struct pxa27x_keypad *keypad,
+                               struct pxa27x_keypad_platform_data *pdata)
+{
+       struct input_dev *input_dev = keypad->input_dev;
+       struct device *dev = input_dev->dev.parent;
+       struct device_node *np = dev->of_node;
+       const __be16 *prop;
+       unsigned short code;
+       unsigned int proplen, size;
        int i;
+       int error;
+
+       error = of_property_read_u32(np, "marvell,direct-key-count",
+                                    &pdata->direct_key_num);
+       if (error) {
+               /*
+                * If do not have marvel,direct-key-count defined,
+                * it means direct key is not supported.
+                */
+               return error == -EINVAL ? 0 : error;
+       }
 
-       for (i = 0; i < pdata->matrix_key_map_size; i++) {
-               unsigned int key = pdata->matrix_key_map[i];
-               unsigned int row = KEY_ROW(key);
-               unsigned int col = KEY_COL(key);
-               unsigned int scancode = MATRIX_SCAN_CODE(row, col,
-                                                        MATRIX_ROW_SHIFT);
+       error = of_property_read_u32(np, "marvell,direct-key-mask",
+                                    &pdata->direct_key_mask);
+       if (error) {
+               if (error != -EINVAL)
+                       return error;
+
+               /*
+                * If marvell,direct-key-mask is not defined, driver will use
+                * default value. Default value is set when configure the keypad.
+                */
+               pdata->direct_key_mask = 0;
+       }
 
-               keycode = KEY_VAL(key);
-               keypad->keycodes[scancode] = keycode;
-               __set_bit(keycode, input_dev->keybit);
+       pdata->direct_key_low_active = of_property_read_bool(np,
+                                       "marvell,direct-key-low-active");
+
+       prop = of_get_property(np, "marvell,direct-key-map", &proplen);
+       if (!prop)
+               return -EINVAL;
+
+       if (proplen % sizeof(u16))
+               return -EINVAL;
+
+       size = proplen / sizeof(u16);
+
+       /* Only MAX_DIRECT_KEY_NUM is accepted.*/
+       if (size > MAX_DIRECT_KEY_NUM)
+               return -EINVAL;
+
+       for (i = 0; i < size; i++) {
+               code = be16_to_cpup(prop + i);
+               keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = code;
+               __set_bit(code, input_dev->keybit);
+       }
+
+       return 0;
+}
+
+static int pxa27x_keypad_rotary_parse_dt(struct pxa27x_keypad *keypad,
+                               struct pxa27x_keypad_platform_data *pdata)
+{
+       const __be32 *prop;
+       int i, relkey_ret;
+       unsigned int code, proplen;
+       const char *rotaryname[2] = {
+                       "marvell,rotary0", "marvell,rotary1"};
+       const char relkeyname[] = {"marvell,rotary-rel-key"};
+       struct input_dev *input_dev = keypad->input_dev;
+       struct device *dev = input_dev->dev.parent;
+       struct device_node *np = dev->of_node;
+
+       relkey_ret = of_property_read_u32(np, relkeyname, &code);
+       /* if can read correct rotary key-code, we do not need this. */
+       if (relkey_ret == 0) {
+               unsigned short relcode;
+
+               /* rotary0 taks lower half, rotary1 taks upper half. */
+               relcode = code & 0xffff;
+               pdata->rotary0_rel_code = (code & 0xffff);
+               __set_bit(relcode, input_dev->relbit);
+
+               relcode = code >> 16;
+               pdata->rotary1_rel_code = relcode;
+               __set_bit(relcode, input_dev->relbit);
+       }
+
+       for (i = 0; i < 2; i++) {
+               prop = of_get_property(np, rotaryname[i], &proplen);
+               /*
+                * If the prop is not set, it means keypad does not need
+                * initialize the rotaryX.
+                */
+               if (!prop)
+                       continue;
+
+               code = be32_to_cpup(prop);
+               /*
+                * Not all up/down key code are valid.
+                * Now we depends on direct-rel-code.
+                */
+               if ((!(code & 0xffff) || !(code >> 16)) && relkey_ret) {
+                       return relkey_ret;
+               } else {
+                       unsigned int n = MAX_MATRIX_KEY_NUM + (i << 1);
+                       unsigned short keycode;
+
+                       keycode = code & 0xffff;
+                       keypad->keycodes[n] = keycode;
+                       __set_bit(keycode, input_dev->keybit);
+
+                       keycode = code >> 16;
+                       keypad->keycodes[n + 1] = keycode;
+                       __set_bit(keycode, input_dev->keybit);
+
+                       if (i == 0)
+                               pdata->rotary0_rel_code = -1;
+                       else
+                               pdata->rotary1_rel_code = -1;
+               }
+               if (i == 0)
+                       pdata->enable_rotary0 = 1;
+               else
+                       pdata->enable_rotary1 = 1;
+       }
+
+       keypad->rotary_rel_code[0] = pdata->rotary0_rel_code;
+       keypad->rotary_rel_code[1] = pdata->rotary1_rel_code;
+
+       return 0;
+}
+
+static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad)
+{
+       struct input_dev *input_dev = keypad->input_dev;
+       struct device *dev = input_dev->dev.parent;
+       struct device_node *np = dev->of_node;
+       struct pxa27x_keypad_platform_data *pdata;
+       int error;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata) {
+               dev_err(dev, "failed to allocate memory for pdata\n");
+               return -ENOMEM;
+       }
+
+       error = pxa27x_keypad_matrix_key_parse_dt(keypad, pdata);
+       if (error) {
+               dev_err(dev, "failed to parse matrix key\n");
+               return error;
+       }
+
+       error = pxa27x_keypad_direct_key_parse_dt(keypad, pdata);
+       if (error) {
+               dev_err(dev, "failed to parse direct key\n");
+               return error;
+       }
+
+       error = pxa27x_keypad_rotary_parse_dt(keypad, pdata);
+       if (error) {
+               dev_err(dev, "failed to parse rotary key\n");
+               return error;
        }
 
+       error = of_property_read_u32(np, "marvell,debounce-interval",
+                                    &pdata->debounce_interval);
+       if (error) {
+               dev_err(dev, "failed to parse debpunce-interval\n");
+               return error;
+       }
+
+       /*
+        * The keycodes may not only includes matrix key but also the direct
+        * key or rotary key.
+        */
+       input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
+       keypad->pdata = pdata;
+       return 0;
+}
+
+#else
+
+static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad)
+{
+       dev_info(keypad->input_dev->dev.parent, "missing platform data\n");
+
+       return -EINVAL;
+}
+
+#endif
+
+static int pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
+{
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       struct input_dev *input_dev = keypad->input_dev;
+       unsigned short keycode;
+       int i;
+       int error;
+
+       error = matrix_keypad_build_keymap(pdata->matrix_keymap_data, NULL,
+                                          pdata->matrix_key_rows,
+                                          pdata->matrix_key_cols,
+                                          keypad->keycodes, input_dev);
+       if (error)
+               return error;
+
+       /*
+        * The keycodes may not only include matrix keys but also the direct
+        * or rotary keys.
+        */
+       input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
+       /* For direct keys. */
        for (i = 0; i < pdata->direct_key_num; i++) {
                keycode = pdata->direct_key_map[i];
                keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = keycode;
@@ -178,11 +404,13 @@ static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
        }
 
        __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+       return 0;
 }
 
 static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        struct input_dev *input_dev = keypad->input_dev;
        int row, col, num_keys_pressed = 0;
        uint32_t new_state[MAX_MATRIX_KEY_COLS];
@@ -236,7 +464,8 @@ scan:
                        if ((bits_changed & (1 << row)) == 0)
                                continue;
 
-                       code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
+                       code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
+
                        input_event(input_dev, EV_MSC, MSC_SCAN, code);
                        input_report_key(input_dev, keypad->keycodes[code],
                                         new_state[col] & (1 << row));
@@ -284,7 +513,7 @@ static void report_rotary_event(struct pxa27x_keypad *keypad, int r, int delta)
 
 static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        uint32_t kprec;
 
        /* read and reset to default count value */
@@ -300,7 +529,7 @@ static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad)
 
 static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        struct input_dev *input_dev = keypad->input_dev;
        unsigned int new_state;
        uint32_t kpdk, bits_changed;
@@ -340,7 +569,7 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
 
 static void clear_wakeup_event(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 
        if (pdata->clear_wakeup_event)
                (pdata->clear_wakeup_event)();
@@ -364,7 +593,7 @@ static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
 
 static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        unsigned int mask = 0, direct_key_num = 0;
        unsigned long kpc = 0;
 
@@ -431,7 +660,7 @@ static void pxa27x_keypad_close(struct input_dev *dev)
        clk_disable_unprepare(keypad->clk);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int pxa27x_keypad_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
@@ -475,25 +704,25 @@ static int pxa27x_keypad_resume(struct device *dev)
 
        return 0;
 }
-
-static const struct dev_pm_ops pxa27x_keypad_pm_ops = {
-       .suspend        = pxa27x_keypad_suspend,
-       .resume         = pxa27x_keypad_resume,
-};
 #endif
 
+static SIMPLE_DEV_PM_OPS(pxa27x_keypad_pm_ops,
+                        pxa27x_keypad_suspend, pxa27x_keypad_resume);
+
+
 static int pxa27x_keypad_probe(struct platform_device *pdev)
 {
-       struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data;
+       const struct pxa27x_keypad_platform_data *pdata =
+                                       dev_get_platdata(&pdev->dev);
+       struct device_node *np = pdev->dev.of_node;
        struct pxa27x_keypad *keypad;
        struct input_dev *input_dev;
        struct resource *res;
        int irq, error;
 
-       if (pdata == NULL) {
-               dev_err(&pdev->dev, "no platform data defined\n");
+       /* Driver need build keycode from device tree or pdata */
+       if (!np && !pdata)
                return -EINVAL;
-       }
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -507,37 +736,27 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
-       input_dev = input_allocate_device();
-       if (!keypad || !input_dev) {
-               dev_err(&pdev->dev, "failed to allocate memory\n");
-               error = -ENOMEM;
-               goto failed_free;
-       }
+       keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad),
+                             GFP_KERNEL);
+       if (!keypad)
+               return -ENOMEM;
+
+       input_dev = devm_input_allocate_device(&pdev->dev);
+       if (!input_dev)
+               return -ENOMEM;
 
        keypad->pdata = pdata;
        keypad->input_dev = input_dev;
        keypad->irq = irq;
 
-       res = request_mem_region(res->start, resource_size(res), pdev->name);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "failed to request I/O memory\n");
-               error = -EBUSY;
-               goto failed_free;
-       }
-
-       keypad->mmio_base = ioremap(res->start, resource_size(res));
-       if (keypad->mmio_base == NULL) {
-               dev_err(&pdev->dev, "failed to remap I/O memory\n");
-               error = -ENXIO;
-               goto failed_free_mem;
-       }
+       keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(keypad->mmio_base))
+               return PTR_ERR(keypad->mmio_base);
 
-       keypad->clk = clk_get(&pdev->dev, NULL);
+       keypad->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(keypad->clk)) {
                dev_err(&pdev->dev, "failed to get keypad clock\n");
-               error = PTR_ERR(keypad->clk);
-               goto failed_free_io;
+               return PTR_ERR(keypad->clk);
        }
 
        input_dev->name = pdev->name;
@@ -555,81 +774,68 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
-       pxa27x_keypad_build_keycode(keypad);
+       if (pdata) {
+               error = pxa27x_keypad_build_keycode(keypad);
+       } else {
+               error = pxa27x_keypad_build_keycode_from_dt(keypad);
+               /*
+                * Data that we get from DT resides in dynamically
+                * allocated memory so we need to update our pdata
+                * pointer.
+                */
+               pdata = keypad->pdata;
+       }
+       if (error) {
+               dev_err(&pdev->dev, "failed to build keycode\n");
+               return error;
+       }
+
+       keypad->row_shift = get_count_order(pdata->matrix_key_cols);
 
        if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) ||
            (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) {
                input_dev->evbit[0] |= BIT_MASK(EV_REL);
        }
 
-       error = request_irq(irq, pxa27x_keypad_irq_handler, 0,
-                           pdev->name, keypad);
+       error = devm_request_irq(&pdev->dev, irq, pxa27x_keypad_irq_handler,
+                                0, pdev->name, keypad);
        if (error) {
                dev_err(&pdev->dev, "failed to request IRQ\n");
-               goto failed_put_clk;
+               return error;
        }
 
        /* Register the input device */
        error = input_register_device(input_dev);
        if (error) {
                dev_err(&pdev->dev, "failed to register input device\n");
-               goto failed_free_irq;
+               return error;
        }
 
        platform_set_drvdata(pdev, keypad);
        device_init_wakeup(&pdev->dev, 1);
 
        return 0;
-
-failed_free_irq:
-       free_irq(irq, pdev);
-failed_put_clk:
-       clk_put(keypad->clk);
-failed_free_io:
-       iounmap(keypad->mmio_base);
-failed_free_mem:
-       release_mem_region(res->start, resource_size(res));
-failed_free:
-       input_free_device(input_dev);
-       kfree(keypad);
-       return error;
 }
 
-static int pxa27x_keypad_remove(struct platform_device *pdev)
-{
-       struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
-       struct resource *res;
-
-       free_irq(keypad->irq, pdev);
-       clk_put(keypad->clk);
-
-       input_unregister_device(keypad->input_dev);
-       iounmap(keypad->mmio_base);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, resource_size(res));
-
-       platform_set_drvdata(pdev, NULL);
-       kfree(keypad);
-
-       return 0;
-}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:pxa27x-keypad");
+#ifdef CONFIG_OF
+static const struct of_device_id pxa27x_keypad_dt_match[] = {
+       { .compatible = "marvell,pxa27x-keypad" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, pxa27x_keypad_dt_match);
+#endif
 
 static struct platform_driver pxa27x_keypad_driver = {
        .probe          = pxa27x_keypad_probe,
-       .remove         = pxa27x_keypad_remove,
        .driver         = {
                .name   = "pxa27x-keypad",
-               .owner  = THIS_MODULE,
-#ifdef CONFIG_PM
+               .of_match_table = of_match_ptr(pxa27x_keypad_dt_match),
                .pm     = &pxa27x_keypad_pm_ops,
-#endif
        },
 };
 module_platform_driver(pxa27x_keypad_driver);
 
 MODULE_DESCRIPTION("PXA27x Keypad Controller Driver");
 MODULE_LICENSE("GPL");
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:pxa27x-keypad");