Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7beebcb0 authored by Linus Walleij's avatar Linus Walleij Committed by Dmitry Torokhov
Browse files

Input: tc3589x-keypad - support probing from device tree



Implement device tree probing for the tc3589x keypad driver.
This is modeled on the STMPE keypad driver and tested on the
Ux500 TVK1281618 UIB.

Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent e5e0937c
Loading
Loading
Loading
Loading
+64 −2
Original line number Diff line number Diff line
@@ -296,6 +296,65 @@ static void tc3589x_keypad_close(struct input_dev *input)
	tc3589x_keypad_disable(keypad);
}

#ifdef CONFIG_OF
static const struct tc3589x_keypad_platform_data *
tc3589x_keypad_of_probe(struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct tc3589x_keypad_platform_data *plat;
	u32 cols, rows;
	u32 debounce_ms;
	int proplen;

	if (!np)
		return ERR_PTR(-ENODEV);

	plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL);
	if (!plat)
		return ERR_PTR(-ENOMEM);

	of_property_read_u32(np, "keypad,num-columns", &cols);
	of_property_read_u32(np, "keypad,num-rows", &rows);
	plat->kcol = (u8) cols;
	plat->krow = (u8) rows;
	if (!plat->krow || !plat->kcol ||
	     plat->krow > TC_KPD_ROWS || plat->kcol > TC_KPD_COLUMNS) {
		dev_err(dev,
			"keypad columns/rows not properly specified (%ux%u)\n",
			plat->kcol, plat->krow);
		return ERR_PTR(-EINVAL);
	}

	if (!of_get_property(np, "linux,keymap", &proplen)) {
		dev_err(dev, "property linux,keymap not found\n");
		return ERR_PTR(-ENOENT);
	}

	plat->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat");
	plat->enable_wakeup = of_property_read_bool(np, "linux,wakeup");

	/* The custom delay format is ms/16 */
	of_property_read_u32(np, "debounce-delay-ms", &debounce_ms);
	if (debounce_ms)
		plat->debounce_period = debounce_ms * 16;
	else
		plat->debounce_period = TC_KPD_DEBOUNCE_PERIOD;

	plat->settle_time = TC_KPD_SETTLE_TIME;
	/* FIXME: should be property of the IRQ resource? */
	plat->irqtype = IRQF_TRIGGER_FALLING;

	return plat;
}
#else
static inline const struct tc3589x_keypad_platform_data *
tc3589x_keypad_of_probe(struct device *dev)
{
	return ERR_PTR(-ENODEV);
}
#endif


static int tc3589x_keypad_probe(struct platform_device *pdev)
{
	struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
@@ -306,8 +365,11 @@ static int tc3589x_keypad_probe(struct platform_device *pdev)

	plat = tc3589x->pdata->keypad;
	if (!plat) {
		plat = tc3589x_keypad_of_probe(&pdev->dev);
		if (IS_ERR(plat)) {
			dev_err(&pdev->dev, "invalid keypad platform data\n");
		return -EINVAL;
			return PTR_ERR(plat);
		}
	}

	irq = platform_get_irq(pdev, 0);