]> Pileus Git - ~andy/linux/blobdiff - drivers/input/keyboard/tegra-kbc.c
Input: spear-keyboard - add device tree bindings
[~andy/linux] / drivers / input / keyboard / tegra-kbc.c
index 21c42f852343e4fbfe2905d9dc5b75b96b9670db..4ffe64d53107f48336999d4753299a3cc03fa8ae 100644 (file)
@@ -619,8 +619,8 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata,
 }
 
 #ifdef CONFIG_OF
-static struct tegra_kbc_platform_data * __devinit
-tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
+static struct tegra_kbc_platform_data * __devinit tegra_kbc_dt_parse_pdata(
+       struct platform_device *pdev)
 {
        struct tegra_kbc_platform_data *pdata;
        struct device_node *np = pdev->dev.of_node;
@@ -630,6 +630,7 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
        if (!np)
                return NULL;
 
+       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                return NULL;
 
@@ -659,10 +660,6 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
                pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL;
        }
 
-       pdata->keymap_data = matrix_keyboard_of_fill_keymap(np, "linux,keymap");
-
-       /* FIXME: Add handling of linux,fn-keymap here */
-
        return pdata;
 }
 #else
@@ -673,10 +670,36 @@ static inline struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
 }
 #endif
 
+static int __devinit tegra_kbd_setup_keymap(struct tegra_kbc *kbc)
+{
+       const struct tegra_kbc_platform_data *pdata = kbc->pdata;
+       const struct matrix_keymap_data *keymap_data = pdata->keymap_data;
+       unsigned int keymap_rows = KBC_MAX_KEY;
+       int retval;
+
+       if (keymap_data && pdata->use_fn_map)
+               keymap_rows *= 2;
+
+       retval = matrix_keypad_build_keymap(keymap_data, NULL,
+                                           keymap_rows, KBC_MAX_COL,
+                                           kbc->keycode, kbc->idev);
+       if (retval == -ENOSYS || retval == -ENOENT) {
+               /*
+                * If there is no OF support in kernel or keymap
+                * property is missing, use default keymap.
+                */
+               retval = matrix_keypad_build_keymap(
+                                       &tegra_kbc_default_keymap_data, NULL,
+                                       keymap_rows, KBC_MAX_COL,
+                                       kbc->keycode, kbc->idev);
+       }
+
+       return retval;
+}
+
 static int __devinit tegra_kbc_probe(struct platform_device *pdev)
 {
        const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data;
-       const struct matrix_keymap_data *keymap_data;
        struct tegra_kbc *kbc;
        struct input_dev *input_dev;
        struct resource *res;
@@ -756,29 +779,26 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
        kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt;
        kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS);
 
+       kbc->wakeup_key = pdata->wakeup_key;
+       kbc->use_fn_map = pdata->use_fn_map;
+       kbc->use_ghost_filter = pdata->use_ghost_filter;
+
        input_dev->name = pdev->name;
        input_dev->id.bustype = BUS_HOST;
        input_dev->dev.parent = &pdev->dev;
        input_dev->open = tegra_kbc_open;
        input_dev->close = tegra_kbc_close;
 
-       input_set_drvdata(input_dev, kbc);
+       err = tegra_kbd_setup_keymap(kbc);
+       if (err) {
+               dev_err(&pdev->dev, "failed to setup keymap\n");
+               goto err_put_clk;
+       }
 
-       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       __set_bit(EV_REP, input_dev->evbit);
        input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
-       input_dev->keycode = kbc->keycode;
-       input_dev->keycodesize = sizeof(kbc->keycode[0]);
-       input_dev->keycodemax = KBC_MAX_KEY;
-       if (pdata->use_fn_map)
-               input_dev->keycodemax *= 2;
-
-       kbc->use_fn_map = pdata->use_fn_map;
-       kbc->use_ghost_filter = pdata->use_ghost_filter;
-       keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data;
-       matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT,
-                                  input_dev->keycode, input_dev->keybit);
-       kbc->wakeup_key = pdata->wakeup_key;
+       input_set_drvdata(input_dev, kbc);
 
        err = request_irq(kbc->irq, tegra_kbc_isr,
                          IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH, pdev->name, kbc);
@@ -798,9 +818,6 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, kbc);
        device_init_wakeup(&pdev->dev, pdata->wakeup);
 
-       if (!pdev->dev.platform_data)
-               matrix_keyboard_of_free_keymap(pdata->keymap_data);
-
        return 0;
 
 err_free_irq:
@@ -815,10 +832,8 @@ err_free_mem:
        input_free_device(input_dev);
        kfree(kbc);
 err_free_pdata:
-       if (!pdev->dev.platform_data) {
-               matrix_keyboard_of_free_keymap(pdata->keymap_data);
+       if (!pdev->dev.platform_data)
                kfree(pdata);
-       }
 
        return err;
 }