From fe6b0dfaba689ad5481037bdfbf31531b3e4c074 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:48:16 -0700 Subject: Input: tegra-kbc - use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-by: Dmitry Torokhov Reviewed-by: Thierry Reding --- drivers/input/keyboard/tegra-kbc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 8508879f6faf..9757a58bc897 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #define KBC_MAX_KPENT 8 @@ -116,6 +116,7 @@ struct tegra_kbc { u32 wakeup_key; struct timer_list timer; struct clk *clk; + struct reset_control *rst; const struct tegra_kbc_hw_support *hw_support; int max_keys; int num_rows_and_columns; @@ -373,9 +374,9 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) clk_prepare_enable(kbc->clk); /* Reset the KBC controller to clear all previous status.*/ - tegra_periph_reset_assert(kbc->clk); + reset_control_assert(kbc->rst); udelay(100); - tegra_periph_reset_deassert(kbc->clk); + reset_control_assert(kbc->rst); udelay(100); tegra_kbc_config_pins(kbc); @@ -663,6 +664,12 @@ static int tegra_kbc_probe(struct platform_device *pdev) return PTR_ERR(kbc->clk); } + kbc->rst = devm_reset_control_get(&pdev->dev, "kbc"); + if (IS_ERR(kbc->rst)) { + dev_err(&pdev->dev, "failed to get keyboard reset\n"); + return PTR_ERR(kbc->rst); + } + /* * The time delay between two consecutive reads of the FIFO is * the sum of the repeat time and the time taken for scanning -- cgit v1.2.3 From 7fb45edba8b5206e645572a682c946f67375447e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 17 Feb 2014 11:31:36 -0800 Subject: Input: imx_keypad - Propagate the real error code on platform_get_irq() failure No need to return a 'fake' return value on platform_get_irq() failure. Just return the error code itself instead. Signed-off-by: Fabio Estevam Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/imx_keypad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index cbf4f8038cba..97ec33572e56 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -439,7 +439,7 @@ static int imx_keypad_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq defined in platform data\n"); - return -EINVAL; + return irq; } input_dev = devm_input_allocate_device(&pdev->dev); @@ -449,7 +449,7 @@ static int imx_keypad_probe(struct platform_device *pdev) } keypad = devm_kzalloc(&pdev->dev, sizeof(struct imx_keypad), - GFP_KERNEL); + GFP_KERNEL); if (!keypad) { dev_err(&pdev->dev, "not enough memory for driver data\n"); return -ENOMEM; -- cgit v1.2.3 From e545ef39e06e7b1df2ef9ddbbf665b74c4e1878a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 28 Mar 2014 00:52:36 -0700 Subject: Input: remove obsolete tnetv107x drivers The tnetv107x platform is getting removed, so the touchscreen and keypad drivers for this platform will no longer be needed either. Signed-off-by: Arnd Bergmann Acked-by: Sekhar Nori Acked-by: Kevin Hilman Cc: Dmitry Torokhov Cc: linux-input@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 10 - drivers/input/keyboard/Makefile | 1 - drivers/input/keyboard/tnetv107x-keypad.c | 329 ------------------------- drivers/input/touchscreen/Kconfig | 9 - drivers/input/touchscreen/Makefile | 1 - drivers/input/touchscreen/tnetv107x-ts.c | 384 ------------------------------ 6 files changed, 734 deletions(-) delete mode 100644 drivers/input/keyboard/tnetv107x-keypad.c delete mode 100644 drivers/input/touchscreen/tnetv107x-ts.c (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a673c9f3a0b9..935dcaf16646 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -595,16 +595,6 @@ config KEYBOARD_TC3589X To compile this driver as a module, choose M here: the module will be called tc3589x-keypad. -config KEYBOARD_TNETV107X - tristate "TI TNETV107X keypad support" - depends on ARCH_DAVINCI_TNETV107X - select INPUT_MATRIXKMAP - help - Say Y here if you want to use the TNETV107X keypad. - - To compile this driver as a module, choose M here: the - module will be called tnetv107x-keypad. - config KEYBOARD_TWL4030 tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" depends on TWL4030_CORE diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index a699b6172303..81014d94a0c1 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -53,7 +53,6 @@ obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o -obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c deleted file mode 100644 index 086511c2121b..000000000000 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Texas Instruments TNETV107X Keypad Driver - * - * Copyright (C) 2010 Texas Instruments - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BITS(x) (BIT(x) - 1) - -#define KEYPAD_ROWS 9 -#define KEYPAD_COLS 9 - -#define DEBOUNCE_MIN 0x400ul -#define DEBOUNCE_MAX 0x3ffffffful - -struct keypad_regs { - u32 rev; - u32 mode; - u32 mask; - u32 pol; - u32 dclock; - u32 rclock; - u32 stable_cnt; - u32 in_en; - u32 out; - u32 out_en; - u32 in; - u32 lock; - u32 pres[3]; -}; - -#define keypad_read(kp, reg) __raw_readl(&(kp)->regs->reg) -#define keypad_write(kp, reg, val) __raw_writel(val, &(kp)->regs->reg) - -struct keypad_data { - struct input_dev *input_dev; - struct resource *res; - struct keypad_regs __iomem *regs; - struct clk *clk; - struct device *dev; - spinlock_t lock; - int irq_press; - int irq_release; - int rows, cols, row_shift; - int debounce_ms, active_low; - u32 prev_keys[3]; - unsigned short keycodes[]; -}; - -static irqreturn_t keypad_irq(int irq, void *data) -{ - struct keypad_data *kp = data; - int i, bit, val, row, col, code; - unsigned long flags; - u32 curr_keys[3]; - u32 change; - - spin_lock_irqsave(&kp->lock, flags); - - memset(curr_keys, 0, sizeof(curr_keys)); - if (irq == kp->irq_press) - for (i = 0; i < 3; i++) - curr_keys[i] = keypad_read(kp, pres[i]); - - for (i = 0; i < 3; i++) { - change = curr_keys[i] ^ kp->prev_keys[i]; - - while (change) { - bit = fls(change) - 1; - change ^= BIT(bit); - val = curr_keys[i] & BIT(bit); - bit += i * 32; - row = bit / KEYPAD_COLS; - col = bit % KEYPAD_COLS; - - code = MATRIX_SCAN_CODE(row, col, kp->row_shift); - input_event(kp->input_dev, EV_MSC, MSC_SCAN, code); - input_report_key(kp->input_dev, kp->keycodes[code], - val); - } - } - input_sync(kp->input_dev); - memcpy(kp->prev_keys, curr_keys, sizeof(curr_keys)); - - if (irq == kp->irq_press) - keypad_write(kp, lock, 0); /* Allow hardware updates */ - - spin_unlock_irqrestore(&kp->lock, flags); - - return IRQ_HANDLED; -} - -static int keypad_start(struct input_dev *dev) -{ - struct keypad_data *kp = input_get_drvdata(dev); - unsigned long mask, debounce, clk_rate_khz; - unsigned long flags; - - clk_enable(kp->clk); - clk_rate_khz = clk_get_rate(kp->clk) / 1000; - - spin_lock_irqsave(&kp->lock, flags); - - /* Initialize device registers */ - keypad_write(kp, mode, 0); - - mask = BITS(kp->rows) << KEYPAD_COLS; - mask |= BITS(kp->cols); - keypad_write(kp, mask, ~mask); - - keypad_write(kp, pol, kp->active_low ? 0 : 0x3ffff); - keypad_write(kp, stable_cnt, 3); - - debounce = kp->debounce_ms * clk_rate_khz; - debounce = clamp(debounce, DEBOUNCE_MIN, DEBOUNCE_MAX); - keypad_write(kp, dclock, debounce); - keypad_write(kp, rclock, 4 * debounce); - - keypad_write(kp, in_en, 1); - - spin_unlock_irqrestore(&kp->lock, flags); - - return 0; -} - -static void keypad_stop(struct input_dev *dev) -{ - struct keypad_data *kp = input_get_drvdata(dev); - - synchronize_irq(kp->irq_press); - synchronize_irq(kp->irq_release); - clk_disable(kp->clk); -} - -static int keypad_probe(struct platform_device *pdev) -{ - const struct matrix_keypad_platform_data *pdata; - const struct matrix_keymap_data *keymap_data; - struct device *dev = &pdev->dev; - struct keypad_data *kp; - int error = 0, sz, row_shift; - u32 rev = 0; - - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(dev, "cannot find device data\n"); - return -EINVAL; - } - - keymap_data = pdata->keymap_data; - if (!keymap_data) { - dev_err(dev, "cannot find keymap data\n"); - return -EINVAL; - } - - row_shift = get_count_order(pdata->num_col_gpios); - sz = offsetof(struct keypad_data, keycodes); - sz += (pdata->num_row_gpios << row_shift) * sizeof(kp->keycodes[0]); - kp = kzalloc(sz, GFP_KERNEL); - if (!kp) { - dev_err(dev, "cannot allocate device info\n"); - return -ENOMEM; - } - - kp->dev = dev; - kp->rows = pdata->num_row_gpios; - kp->cols = pdata->num_col_gpios; - kp->row_shift = row_shift; - platform_set_drvdata(pdev, kp); - spin_lock_init(&kp->lock); - - kp->irq_press = platform_get_irq_byname(pdev, "press"); - kp->irq_release = platform_get_irq_byname(pdev, "release"); - if (kp->irq_press < 0 || kp->irq_release < 0) { - dev_err(dev, "cannot determine device interrupts\n"); - error = -ENODEV; - goto error_res; - } - - kp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!kp->res) { - dev_err(dev, "cannot determine register area\n"); - error = -ENODEV; - goto error_res; - } - - if (!request_mem_region(kp->res->start, resource_size(kp->res), - pdev->name)) { - dev_err(dev, "cannot claim register memory\n"); - kp->res = NULL; - error = -EINVAL; - goto error_res; - } - - kp->regs = ioremap(kp->res->start, resource_size(kp->res)); - if (!kp->regs) { - dev_err(dev, "cannot map register memory\n"); - error = -ENOMEM; - goto error_map; - } - - kp->clk = clk_get(dev, NULL); - if (IS_ERR(kp->clk)) { - dev_err(dev, "cannot claim device clock\n"); - error = PTR_ERR(kp->clk); - goto error_clk; - } - - error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, - IRQF_ONESHOT, dev_name(dev), kp); - if (error < 0) { - dev_err(kp->dev, "Could not allocate keypad press key irq\n"); - goto error_irq_press; - } - - error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, - IRQF_ONESHOT, dev_name(dev), kp); - if (error < 0) { - dev_err(kp->dev, "Could not allocate keypad release key irq\n"); - goto error_irq_release; - } - - kp->input_dev = input_allocate_device(); - if (!kp->input_dev) { - dev_err(dev, "cannot allocate input device\n"); - error = -ENOMEM; - goto error_input; - } - - kp->input_dev->name = pdev->name; - kp->input_dev->dev.parent = &pdev->dev; - kp->input_dev->open = keypad_start; - kp->input_dev->close = keypad_stop; - - clk_enable(kp->clk); - rev = keypad_read(kp, rev); - kp->input_dev->id.bustype = BUS_HOST; - kp->input_dev->id.product = ((rev >> 8) & 0x07); - kp->input_dev->id.version = ((rev >> 16) & 0xfff); - clk_disable(kp->clk); - - error = matrix_keypad_build_keymap(keymap_data, NULL, - kp->rows, kp->cols, - kp->keycodes, kp->input_dev); - if (error) { - dev_err(dev, "Failed to build keymap\n"); - goto error_reg; - } - - if (!pdata->no_autorepeat) - kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); - input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); - - input_set_drvdata(kp->input_dev, kp); - - error = input_register_device(kp->input_dev); - if (error < 0) { - dev_err(dev, "Could not register input device\n"); - goto error_reg; - } - - return 0; - - -error_reg: - input_free_device(kp->input_dev); -error_input: - free_irq(kp->irq_release, kp); -error_irq_release: - free_irq(kp->irq_press, kp); -error_irq_press: - clk_put(kp->clk); -error_clk: - iounmap(kp->regs); -error_map: - release_mem_region(kp->res->start, resource_size(kp->res)); -error_res: - kfree(kp); - return error; -} - -static int keypad_remove(struct platform_device *pdev) -{ - struct keypad_data *kp = platform_get_drvdata(pdev); - - free_irq(kp->irq_press, kp); - free_irq(kp->irq_release, kp); - input_unregister_device(kp->input_dev); - clk_put(kp->clk); - iounmap(kp->regs); - release_mem_region(kp->res->start, resource_size(kp->res)); - kfree(kp); - - return 0; -} - -static struct platform_driver keypad_driver = { - .probe = keypad_probe, - .remove = keypad_remove, - .driver.name = "tnetv107x-keypad", - .driver.owner = THIS_MODULE, -}; -module_platform_driver(keypad_driver); - -MODULE_AUTHOR("Cyril Chemparathy"); -MODULE_DESCRIPTION("TNETV107X Keypad Driver"); -MODULE_ALIAS("platform:tnetv107x-keypad"); -MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 07e9e82029d1..68edc9db2c64 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -514,15 +514,6 @@ config TOUCHSCREEN_MIGOR To compile this driver as a module, choose M here: the module will be called migor_ts. -config TOUCHSCREEN_TNETV107X - tristate "TI TNETV107X touchscreen support" - depends on ARCH_DAVINCI_TNETV107X - help - Say Y here if you want to use the TNETV107X touchscreen. - - To compile this driver as a module, choose M here: the - module will be called tnetv107x-ts. - config TOUCHSCREEN_TOUCHRIGHT tristate "Touchright serial touchscreen" select SERIO diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 62801f213346..4bc954b7c7c3 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -56,7 +56,6 @@ obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o -obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o diff --git a/drivers/input/touchscreen/tnetv107x-ts.c b/drivers/input/touchscreen/tnetv107x-ts.c deleted file mode 100644 index c47827a26e3c..000000000000 --- a/drivers/input/touchscreen/tnetv107x-ts.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Texas Instruments TNETV107X Touchscreen Driver - * - * Copyright (C) 2010 Texas Instruments - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define TSC_PENUP_POLL (HZ / 5) -#define IDLE_TIMEOUT 100 /* msec */ - -/* - * The first and last samples of a touch interval are usually garbage and need - * to be filtered out with these devices. The following definitions control - * the number of samples skipped. - */ -#define TSC_HEAD_SKIP 1 -#define TSC_TAIL_SKIP 1 -#define TSC_SKIP (TSC_HEAD_SKIP + TSC_TAIL_SKIP + 1) -#define TSC_SAMPLES (TSC_SKIP + 1) - -/* Register Offsets */ -struct tsc_regs { - u32 rev; - u32 tscm; - u32 bwcm; - u32 swc; - u32 adcchnl; - u32 adcdata; - u32 chval[4]; -}; - -/* TSC Mode Configuration Register (tscm) bits */ -#define WMODE BIT(0) -#define TSKIND BIT(1) -#define ZMEASURE_EN BIT(2) -#define IDLE BIT(3) -#define TSC_EN BIT(4) -#define STOP BIT(5) -#define ONE_SHOT BIT(6) -#define SINGLE BIT(7) -#define AVG BIT(8) -#define AVGNUM(x) (((x) & 0x03) << 9) -#define PVSTC(x) (((x) & 0x07) << 11) -#define PON BIT(14) -#define PONBG BIT(15) -#define AFERST BIT(16) - -/* ADC DATA Capture Register bits */ -#define DATA_VALID BIT(16) - -/* Register Access Macros */ -#define tsc_read(ts, reg) __raw_readl(&(ts)->regs->reg) -#define tsc_write(ts, reg, val) __raw_writel(val, &(ts)->regs->reg); -#define tsc_set_bits(ts, reg, val) \ - tsc_write(ts, reg, tsc_read(ts, reg) | (val)) -#define tsc_clr_bits(ts, reg, val) \ - tsc_write(ts, reg, tsc_read(ts, reg) & ~(val)) - -struct sample { - int x, y, p; -}; - -struct tsc_data { - struct input_dev *input_dev; - struct resource *res; - struct tsc_regs __iomem *regs; - struct timer_list timer; - spinlock_t lock; - struct clk *clk; - struct device *dev; - int sample_count; - struct sample samples[TSC_SAMPLES]; - int tsc_irq; -}; - -static int tsc_read_sample(struct tsc_data *ts, struct sample* sample) -{ - int x, y, z1, z2, t, p = 0; - u32 val; - - val = tsc_read(ts, chval[0]); - if (val & DATA_VALID) - x = val & 0xffff; - else - return -EINVAL; - - y = tsc_read(ts, chval[1]) & 0xffff; - z1 = tsc_read(ts, chval[2]) & 0xffff; - z2 = tsc_read(ts, chval[3]) & 0xffff; - - if (z1) { - t = ((600 * x) * (z2 - z1)); - p = t / (u32) (z1 << 12); - if (p < 0) - p = 0; - } - - sample->x = x; - sample->y = y; - sample->p = p; - - return 0; -} - -static void tsc_poll(unsigned long data) -{ - struct tsc_data *ts = (struct tsc_data *)data; - unsigned long flags; - int i, val, x, y, p; - - spin_lock_irqsave(&ts->lock, flags); - - if (ts->sample_count >= TSC_SKIP) { - input_report_abs(ts->input_dev, ABS_PRESSURE, 0); - input_report_key(ts->input_dev, BTN_TOUCH, 0); - input_sync(ts->input_dev); - } else if (ts->sample_count > 0) { - /* - * A touch event lasted less than our skip count. Salvage and - * report anyway. - */ - for (i = 0, val = 0; i < ts->sample_count; i++) - val += ts->samples[i].x; - x = val / ts->sample_count; - - for (i = 0, val = 0; i < ts->sample_count; i++) - val += ts->samples[i].y; - y = val / ts->sample_count; - - for (i = 0, val = 0; i < ts->sample_count; i++) - val += ts->samples[i].p; - p = val / ts->sample_count; - - input_report_abs(ts->input_dev, ABS_X, x); - input_report_abs(ts->input_dev, ABS_Y, y); - input_report_abs(ts->input_dev, ABS_PRESSURE, p); - input_report_key(ts->input_dev, BTN_TOUCH, 1); - input_sync(ts->input_dev); - } - - ts->sample_count = 0; - - spin_unlock_irqrestore(&ts->lock, flags); -} - -static irqreturn_t tsc_irq(int irq, void *dev_id) -{ - struct tsc_data *ts = (struct tsc_data *)dev_id; - struct sample *sample; - int index; - - spin_lock(&ts->lock); - - index = ts->sample_count % TSC_SAMPLES; - sample = &ts->samples[index]; - if (tsc_read_sample(ts, sample) < 0) - goto out; - - if (++ts->sample_count >= TSC_SKIP) { - index = (ts->sample_count - TSC_TAIL_SKIP - 1) % TSC_SAMPLES; - sample = &ts->samples[index]; - - input_report_abs(ts->input_dev, ABS_X, sample->x); - input_report_abs(ts->input_dev, ABS_Y, sample->y); - input_report_abs(ts->input_dev, ABS_PRESSURE, sample->p); - if (ts->sample_count == TSC_SKIP) - input_report_key(ts->input_dev, BTN_TOUCH, 1); - input_sync(ts->input_dev); - } - mod_timer(&ts->timer, jiffies + TSC_PENUP_POLL); -out: - spin_unlock(&ts->lock); - return IRQ_HANDLED; -} - -static int tsc_start(struct input_dev *dev) -{ - struct tsc_data *ts = input_get_drvdata(dev); - unsigned long timeout = jiffies + msecs_to_jiffies(IDLE_TIMEOUT); - u32 val; - - clk_enable(ts->clk); - - /* Go to idle mode, before any initialization */ - while (time_after(timeout, jiffies)) { - if (tsc_read(ts, tscm) & IDLE) - break; - } - - if (time_before(timeout, jiffies)) { - dev_warn(ts->dev, "timeout waiting for idle\n"); - clk_disable(ts->clk); - return -EIO; - } - - /* Configure TSC Control register*/ - val = (PONBG | PON | PVSTC(4) | ONE_SHOT | ZMEASURE_EN); - tsc_write(ts, tscm, val); - - /* Bring TSC out of reset: Clear AFE reset bit */ - val &= ~(AFERST); - tsc_write(ts, tscm, val); - - /* Configure all pins for hardware control*/ - tsc_write(ts, bwcm, 0); - - /* Finally enable the TSC */ - tsc_set_bits(ts, tscm, TSC_EN); - - return 0; -} - -static void tsc_stop(struct input_dev *dev) -{ - struct tsc_data *ts = input_get_drvdata(dev); - - tsc_clr_bits(ts, tscm, TSC_EN); - synchronize_irq(ts->tsc_irq); - del_timer_sync(&ts->timer); - clk_disable(ts->clk); -} - -static int tsc_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct tsc_data *ts; - int error = 0; - u32 rev = 0; - - ts = kzalloc(sizeof(struct tsc_data), GFP_KERNEL); - if (!ts) { - dev_err(dev, "cannot allocate device info\n"); - return -ENOMEM; - } - - ts->dev = dev; - spin_lock_init(&ts->lock); - setup_timer(&ts->timer, tsc_poll, (unsigned long)ts); - platform_set_drvdata(pdev, ts); - - ts->tsc_irq = platform_get_irq(pdev, 0); - if (ts->tsc_irq < 0) { - dev_err(dev, "cannot determine device interrupt\n"); - error = -ENODEV; - goto error_res; - } - - ts->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!ts->res) { - dev_err(dev, "cannot determine register area\n"); - error = -ENODEV; - goto error_res; - } - - if (!request_mem_region(ts->res->start, resource_size(ts->res), - pdev->name)) { - dev_err(dev, "cannot claim register memory\n"); - ts->res = NULL; - error = -EINVAL; - goto error_res; - } - - ts->regs = ioremap(ts->res->start, resource_size(ts->res)); - if (!ts->regs) { - dev_err(dev, "cannot map register memory\n"); - error = -ENOMEM; - goto error_map; - } - - ts->clk = clk_get(dev, NULL); - if (IS_ERR(ts->clk)) { - dev_err(dev, "cannot claim device clock\n"); - error = PTR_ERR(ts->clk); - goto error_clk; - } - - error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, IRQF_ONESHOT, - dev_name(dev), ts); - if (error < 0) { - dev_err(ts->dev, "Could not allocate ts irq\n"); - goto error_irq; - } - - ts->input_dev = input_allocate_device(); - if (!ts->input_dev) { - dev_err(dev, "cannot allocate input device\n"); - error = -ENOMEM; - goto error_input; - } - input_set_drvdata(ts->input_dev, ts); - - ts->input_dev->name = pdev->name; - ts->input_dev->id.bustype = BUS_HOST; - ts->input_dev->dev.parent = &pdev->dev; - ts->input_dev->open = tsc_start; - ts->input_dev->close = tsc_stop; - - clk_enable(ts->clk); - rev = tsc_read(ts, rev); - ts->input_dev->id.product = ((rev >> 8) & 0x07); - ts->input_dev->id.version = ((rev >> 16) & 0xfff); - clk_disable(ts->clk); - - __set_bit(EV_KEY, ts->input_dev->evbit); - __set_bit(EV_ABS, ts->input_dev->evbit); - __set_bit(BTN_TOUCH, ts->input_dev->keybit); - - input_set_abs_params(ts->input_dev, ABS_X, 0, 0xffff, 5, 0); - input_set_abs_params(ts->input_dev, ABS_Y, 0, 0xffff, 5, 0); - input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 4095, 128, 0); - - error = input_register_device(ts->input_dev); - if (error < 0) { - dev_err(dev, "failed input device registration\n"); - goto error_reg; - } - - return 0; - -error_reg: - input_free_device(ts->input_dev); -error_input: - free_irq(ts->tsc_irq, ts); -error_irq: - clk_put(ts->clk); -error_clk: - iounmap(ts->regs); -error_map: - release_mem_region(ts->res->start, resource_size(ts->res)); -error_res: - kfree(ts); - - return error; -} - -static int tsc_remove(struct platform_device *pdev) -{ - struct tsc_data *ts = platform_get_drvdata(pdev); - - input_unregister_device(ts->input_dev); - free_irq(ts->tsc_irq, ts); - clk_put(ts->clk); - iounmap(ts->regs); - release_mem_region(ts->res->start, resource_size(ts->res)); - kfree(ts); - - return 0; -} - -static struct platform_driver tsc_driver = { - .probe = tsc_probe, - .remove = tsc_remove, - .driver.name = "tnetv107x-ts", - .driver.owner = THIS_MODULE, -}; -module_platform_driver(tsc_driver); - -MODULE_AUTHOR("Cyril Chemparathy"); -MODULE_DESCRIPTION("TNETV107X Touchscreen Driver"); -MODULE_ALIAS("platform:tnetv107x-ts"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From e70f18e1c7868bebad16b21b4821b2adb8c1abf8 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Fri, 28 Mar 2014 09:37:14 -0700 Subject: Input: add new driver for ARM CLPS711X keypad This patch adds a new driver for keypad for Cirrus Logic CLPS711X CPUs. Target CPU contain keyboard interface which can scan 8 column lines, so we can read row GPIOs to read status and determine asserted state. Signed-off-by: Alexander Shiyan Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/clps711x-keypad.txt | 27 +++ drivers/input/keyboard/Kconfig | 12 ++ drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/clps711x-keypad.c | 207 +++++++++++++++++++++ 4 files changed, 247 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/clps711x-keypad.txt create mode 100644 drivers/input/keyboard/clps711x-keypad.c (limited to 'drivers/input/keyboard') diff --git a/Documentation/devicetree/bindings/input/clps711x-keypad.txt b/Documentation/devicetree/bindings/input/clps711x-keypad.txt new file mode 100644 index 000000000000..e68d2bbc6c07 --- /dev/null +++ b/Documentation/devicetree/bindings/input/clps711x-keypad.txt @@ -0,0 +1,27 @@ +* Cirrus Logic CLPS711X matrix keypad device tree bindings + +Required Properties: +- compatible: Shall contain "cirrus,clps711x-keypad". +- row-gpios: List of GPIOs used as row lines. +- poll-interval: Poll interval time in milliseconds. +- linux,keymap: The definition can be found at + bindings/input/matrix-keymap.txt. + +Optional Properties: +- autorepeat: Enable autorepeat feature. + +Example: + keypad { + compatible = "cirrus,ep7312-keypad", "cirrus,clps711x-keypad"; + autorepeat; + poll-interval = <120>; + row-gpios = <&porta 0 0>, + <&porta 1 0>; + + linux,keymap = < + MATRIX_KEY(0, 0, KEY_UP) + MATRIX_KEY(0, 1, KEY_DOWN) + MATRIX_KEY(1, 0, KEY_LEFT) + MATRIX_KEY(1, 1, KEY_RIGHT) + >; + }; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 935dcaf16646..76842d7dc2e3 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -151,6 +151,18 @@ config KEYBOARD_BFIN To compile this driver as a module, choose M here: the module will be called bf54x-keys. +config KEYBOARD_CLPS711X + tristate "CLPS711X Keypad support" + depends on OF_GPIO && (ARCH_CLPS711X || COMPILE_TEST) + select INPUT_MATRIXKMAP + select INPUT_POLLDEV + help + Say Y here to enable the matrix keypad on the Cirrus Logic + CLPS711X CPUs. + + To compile this driver as a module, choose M here: the + module will be called clps711x-keypad. + config KEYBOARD_LKKBD tristate "DECstation/VAXstation LK201/LK401 keyboard" select SERIO diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 81014d94a0c1..11cff7b84b47 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o +obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c new file mode 100644 index 000000000000..3955aecee44b --- /dev/null +++ b/drivers/input/keyboard/clps711x-keypad.c @@ -0,0 +1,207 @@ +/* + * Cirrus Logic CLPS711X Keypad driver + * + * Copyright (C) 2014 Alexander Shiyan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLPS711X_KEYPAD_COL_COUNT 8 + +struct clps711x_gpio_data { + struct gpio_desc *desc; + DECLARE_BITMAP(last_state, CLPS711X_KEYPAD_COL_COUNT); +}; + +struct clps711x_keypad_data { + struct regmap *syscon; + int row_count; + unsigned int row_shift; + struct clps711x_gpio_data *gpio_data; +}; + +static void clps711x_keypad_poll(struct input_polled_dev *dev) +{ + const unsigned short *keycodes = dev->input->keycode; + struct clps711x_keypad_data *priv = dev->private; + bool sync = false; + int col, row; + + for (col = 0; col < CLPS711X_KEYPAD_COL_COUNT; col++) { + /* Assert column */ + regmap_update_bits(priv->syscon, SYSCON_OFFSET, + SYSCON1_KBDSCAN_MASK, + SYSCON1_KBDSCAN(8 + col)); + + /* Scan rows */ + for (row = 0; row < priv->row_count; row++) { + struct clps711x_gpio_data *data = &priv->gpio_data[row]; + bool state, state1; + + /* Read twice for protection against fluctuations */ + do { + state = gpiod_get_value_cansleep(data->desc); + cond_resched(); + state1 = gpiod_get_value_cansleep(data->desc); + } while (state != state1); + + if (test_bit(col, data->last_state) != state) { + int code = MATRIX_SCAN_CODE(row, col, + priv->row_shift); + + if (state) { + set_bit(col, data->last_state); + input_event(dev->input, EV_MSC, + MSC_SCAN, code); + } else { + clear_bit(col, data->last_state); + } + + if (keycodes[code]) + input_report_key(dev->input, + keycodes[code], state); + sync = true; + } + } + + /* Set all columns to low */ + regmap_update_bits(priv->syscon, SYSCON_OFFSET, + SYSCON1_KBDSCAN_MASK, SYSCON1_KBDSCAN(1)); + } + + if (sync) + input_sync(dev->input); +} + +static int clps711x_keypad_probe(struct platform_device *pdev) +{ + struct clps711x_keypad_data *priv; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct input_polled_dev *poll_dev; + u32 poll_interval; + int i, err; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->syscon = + syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1"); + if (IS_ERR(priv->syscon)) + return PTR_ERR(priv->syscon); + + priv->row_count = of_gpio_named_count(np, "row-gpios"); + if (priv->row_count < 1) + return -EINVAL; + + priv->gpio_data = devm_kzalloc(dev, + sizeof(*priv->gpio_data) * priv->row_count, + GFP_KERNEL); + if (!priv->gpio_data) + return -ENOMEM; + + priv->row_shift = get_count_order(CLPS711X_KEYPAD_COL_COUNT); + + for (i = 0; i < priv->row_count; i++) { + struct clps711x_gpio_data *data = &priv->gpio_data[i]; + + data->desc = devm_gpiod_get_index(dev, "row", i); + if (!data->desc) + return -EINVAL; + + if (IS_ERR(data->desc)) + return PTR_ERR(data->desc); + + gpiod_direction_input(data->desc); + } + + err = of_property_read_u32(np, "poll-interval", &poll_interval); + if (err) + return err; + + poll_dev = input_allocate_polled_device(); + if (!poll_dev) + return -ENOMEM; + + poll_dev->private = priv; + poll_dev->poll = clps711x_keypad_poll; + poll_dev->poll_interval = poll_interval; + poll_dev->input->name = pdev->name; + poll_dev->input->dev.parent = dev; + poll_dev->input->id.bustype = BUS_HOST; + poll_dev->input->id.vendor = 0x0001; + poll_dev->input->id.product = 0x0001; + poll_dev->input->id.version = 0x0100; + + err = matrix_keypad_build_keymap(NULL, NULL, priv->row_count, + CLPS711X_KEYPAD_COL_COUNT, + NULL, poll_dev->input); + if (err) + goto out_err; + + input_set_capability(poll_dev->input, EV_MSC, MSC_SCAN); + if (of_property_read_bool(np, "autorepeat")) + __set_bit(EV_REP, poll_dev->input->evbit); + + platform_set_drvdata(pdev, poll_dev); + + /* Set all columns to low */ + regmap_update_bits(priv->syscon, SYSCON_OFFSET, SYSCON1_KBDSCAN_MASK, + SYSCON1_KBDSCAN(1)); + + err = input_register_polled_device(poll_dev); + if (err) + goto out_err; + + return 0; + +out_err: + input_free_polled_device(poll_dev); + return err; +} + +static int clps711x_keypad_remove(struct platform_device *pdev) +{ + struct input_polled_dev *poll_dev = platform_get_drvdata(pdev); + + input_unregister_polled_device(poll_dev); + input_free_polled_device(poll_dev); + + return 0; +} + +static struct of_device_id clps711x_keypad_of_match[] = { + { .compatible = "cirrus,clps711x-keypad", }, + { } +}; +MODULE_DEVICE_TABLE(of, clps711x_keypad_of_match); + +static struct platform_driver clps711x_keypad_driver = { + .driver = { + .name = "clps711x-keypad", + .owner = THIS_MODULE, + .of_match_table = clps711x_keypad_of_match, + }, + .probe = clps711x_keypad_probe, + .remove = clps711x_keypad_remove, +}; +module_platform_driver(clps711x_keypad_driver); + +MODULE_AUTHOR("Alexander Shiyan "); +MODULE_DESCRIPTION("Cirrus Logic CLPS711X Keypad driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From d3e6a67c7e502e8d21624c453f1d1f697e674548 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 29 Mar 2014 12:32:06 -0700 Subject: Input: pmic8xxx-keypad - fix build by removing gpio configuration The gpio configuration in this driver doesn't work because the gpio.h include doesn't exist. Remove the configuration as it isn't strictly necessary, allowing us to actually compile this driver. If it's needed in the future, it should be done via a pinctrl driver. Signed-off-by: Stephen Boyd Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/pmic8xxx-keypad.c | 58 -------------------------------- 1 file changed, 58 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 2c9f19ac35ea..c4aa882c8fb9 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -21,7 +21,6 @@ #include #include -#include #include #define PM8XXX_MAX_ROWS 18 @@ -447,27 +446,6 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) } -static int pmic8xxx_kp_config_gpio(int gpio_start, int num_gpios, - struct pmic8xxx_kp *kp, struct pm_gpio *gpio_config) -{ - int rc, i; - - if (gpio_start < 0 || num_gpios < 0) - return -EINVAL; - - for (i = 0; i < num_gpios; i++) { - rc = pm8xxx_gpio_config(gpio_start + i, gpio_config); - if (rc) { - dev_err(kp->dev, "%s: FAIL pm8xxx_gpio_config():" - "for PM GPIO [%d] rc=%d.\n", - __func__, gpio_start + i, rc); - return rc; - } - } - - return 0; -} - static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp) { int rc; @@ -527,27 +505,6 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) int rc; u8 ctrl_val; - struct pm_gpio kypd_drv = { - .direction = PM_GPIO_DIR_OUT, - .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, - .output_value = 0, - .pull = PM_GPIO_PULL_NO, - .vin_sel = PM_GPIO_VIN_S3, - .out_strength = PM_GPIO_STRENGTH_LOW, - .function = PM_GPIO_FUNC_1, - .inv_int_pol = 1, - }; - - struct pm_gpio kypd_sns = { - .direction = PM_GPIO_DIR_IN, - .pull = PM_GPIO_PULL_UP_31P5, - .vin_sel = PM_GPIO_VIN_S3, - .out_strength = PM_GPIO_STRENGTH_NO, - .function = PM_GPIO_FUNC_NORMAL, - .inv_int_pol = 1, - }; - - if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8XXX_MAX_COLS || pdata->num_rows > PM8XXX_MAX_ROWS || @@ -653,20 +610,6 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) goto err_get_irq; } - rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, - pdata->num_cols, kp, &kypd_sns); - if (rc < 0) { - dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); - goto err_gpio_config; - } - - rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, - pdata->num_rows, kp, &kypd_drv); - if (rc < 0) { - dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); - goto err_gpio_config; - } - rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { @@ -703,7 +646,6 @@ err_pmic_reg_read: free_irq(kp->key_stuck_irq, kp); err_req_stuck_irq: free_irq(kp->key_sense_irq, kp); -err_gpio_config: err_get_irq: input_free_device(kp->input); err_alloc_device: -- cgit v1.2.3 From c7f6ee264b511d8a35063e9821cf36ad18e4e4fd Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 29 Mar 2014 12:32:43 -0700 Subject: Input: pmic8xxx-keypad - migrate to devm_* APIs Simplify the error paths and reduce the lines of code in this driver by using the devm_* APIs. Signed-off-by: Stephen Boyd Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/pmic8xxx-keypad.c | 61 +++++++++----------------------- 1 file changed, 17 insertions(+), 44 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index c4aa882c8fb9..bec53ebde7b2 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -543,7 +543,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) return -EINVAL; } - kp = kzalloc(sizeof(*kp), GFP_KERNEL); + kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; @@ -552,32 +552,27 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) kp->pdata = pdata; kp->dev = &pdev->dev; - kp->input = input_allocate_device(); + kp->input = devm_input_allocate_device(&pdev->dev); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); - rc = -ENOMEM; - goto err_alloc_device; + return -ENOMEM; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); - rc = -ENXIO; - goto err_get_irq; + return kp->key_sense_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); - rc = -ENXIO; - goto err_get_irq; + return kp->key_stuck_irq; } kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; - kp->input->dev.parent = &pdev->dev; - kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; @@ -591,7 +586,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) kp->keycodes, kp->input); if (rc) { dev_err(&pdev->dev, "failed to build keymap\n"); - goto err_get_irq; + return rc; } if (pdata->rep) @@ -607,27 +602,29 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) rc = pmic8xxx_kpd_init(kp); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); - goto err_get_irq; + return rc; } - rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, - IRQF_TRIGGER_RISING, "pmic-keypad", kp); + rc = devm_request_any_context_irq(&pdev->dev, kp->key_sense_irq, + pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", + kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); - goto err_get_irq; + return rc; } - rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, - IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); + rc = devm_request_any_context_irq(&pdev->dev, kp->key_stuck_irq, + pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, + "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); - goto err_req_stuck_irq; + return rc; } rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); - goto err_pmic_reg_read; + return rc; } kp->ctrl_reg = ctrl_val; @@ -635,34 +632,11 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); - goto err_pmic_reg_read; + return rc; } device_init_wakeup(&pdev->dev, pdata->wakeup); - return 0; - -err_pmic_reg_read: - free_irq(kp->key_stuck_irq, kp); -err_req_stuck_irq: - free_irq(kp->key_sense_irq, kp); -err_get_irq: - input_free_device(kp->input); -err_alloc_device: - kfree(kp); - return rc; -} - -static int pmic8xxx_kp_remove(struct platform_device *pdev) -{ - struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); - - device_init_wakeup(&pdev->dev, 0); - free_irq(kp->key_stuck_irq, kp); - free_irq(kp->key_sense_irq, kp); - input_unregister_device(kp->input); - kfree(kp); - return 0; } @@ -713,7 +687,6 @@ static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, - .remove = pmic8xxx_kp_remove, .driver = { .name = PM8XXX_KEYPAD_DEV_NAME, .owner = THIS_MODULE, -- cgit v1.2.3 From a5dde0c72ccbb0f66b3491ee83f4c579aea0651d Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 29 Mar 2014 12:34:14 -0700 Subject: Input: pmic8xxx-keypad - migrate to regmap APIs Use the regmap APIs for this driver instead of custom pm8xxx APIs. This breaks this driver's dependency on the pm8xxx APIs and allows us to easily port it to other bus protocols in the future. Signed-off-by: Stephen Boyd Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/pmic8xxx-keypad.c | 81 ++++++++++++-------------------- 1 file changed, 29 insertions(+), 52 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index bec53ebde7b2..0efd11e16b7e 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -19,8 +19,8 @@ #include #include #include +#include -#include #include #define PM8XXX_MAX_ROWS 18 @@ -86,6 +86,7 @@ * struct pmic8xxx_kp - internal keypad data structure * @pdata - keypad platform data pointer * @input - input device pointer for keypad + * @regmap - regmap handle * @key_sense_irq - key press/release irq number * @key_stuck_irq - key stuck notification irq number * @keycodes - array to hold the key codes @@ -97,6 +98,7 @@ struct pmic8xxx_kp { const struct pm8xxx_keypad_platform_data *pdata; struct input_dev *input; + struct regmap *regmap; int key_sense_irq; int key_stuck_irq; @@ -109,33 +111,6 @@ struct pmic8xxx_kp { u8 ctrl_reg; }; -static int pmic8xxx_kp_write_u8(struct pmic8xxx_kp *kp, - u8 data, u16 reg) -{ - int rc; - - rc = pm8xxx_writeb(kp->dev->parent, reg, data); - return rc; -} - -static int pmic8xxx_kp_read(struct pmic8xxx_kp *kp, - u8 *data, u16 reg, unsigned num_bytes) -{ - int rc; - - rc = pm8xxx_read_buf(kp->dev->parent, reg, data, num_bytes); - return rc; -} - -static int pmic8xxx_kp_read_u8(struct pmic8xxx_kp *kp, - u8 *data, u16 reg) -{ - int rc; - - rc = pmic8xxx_kp_read(kp, data, reg, 1); - return rc; -} - static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) { /* all keys pressed on that particular row? */ @@ -160,9 +135,9 @@ static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) { int rc; - u8 scan_val; + unsigned int scan_val; - rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); + rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); return rc; @@ -170,7 +145,7 @@ static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) scan_val |= 0x1; - rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); + rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); if (rc < 0) { dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); return rc; @@ -186,26 +161,24 @@ static int pmic8xxx_kp_read_data(struct pmic8xxx_kp *kp, u16 *state, u16 data_reg, int read_rows) { int rc, row; - u8 new_data[PM8XXX_MAX_ROWS]; + unsigned int val; - rc = pmic8xxx_kp_read(kp, new_data, data_reg, read_rows); - if (rc) - return rc; - - for (row = 0; row < kp->pdata->num_rows; row++) { - dev_dbg(kp->dev, "new_data[%d] = %d\n", row, - new_data[row]); - state[row] = pmic8xxx_col_state(kp, new_data[row]); + for (row = 0; row < read_rows; row++) { + rc = regmap_read(kp->regmap, data_reg, &val); + if (rc) + return rc; + dev_dbg(kp->dev, "%d = %d\n", row, val); + state[row] = pmic8xxx_col_state(kp, val); } - return rc; + return 0; } static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int rc, read_rows; - u8 scan_val; + unsigned int scan_val; if (kp->pdata->num_rows < PM8XXX_MIN_ROWS) read_rows = PM8XXX_MIN_ROWS; @@ -235,14 +208,14 @@ static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, /* 4 * 32KHz clocks */ udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); - rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); + rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); return rc; } scan_val &= 0xFE; - rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); + rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); if (rc < 0) dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); @@ -378,10 +351,10 @@ static irqreturn_t pmic8xxx_kp_stuck_irq(int irq, void *data) static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) { struct pmic8xxx_kp *kp = data; - u8 ctrl_val, events; + unsigned int ctrl_val, events; int rc; - rc = pmic8xxx_kp_read(kp, &ctrl_val, KEYP_CTRL, 1); + rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val); if (rc < 0) { dev_err(kp->dev, "failed to read keyp_ctrl register\n"); return IRQ_HANDLED; @@ -420,7 +393,7 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT); - rc = pmic8xxx_kp_write_u8(kp, ctrl_val, KEYP_CTRL); + rc = regmap_write(kp->regmap, KEYP_CTRL, ctrl_val); if (rc < 0) { dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); return rc; @@ -438,7 +411,7 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT); - rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); + rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); if (rc) dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); @@ -452,7 +425,7 @@ static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp) kp->ctrl_reg |= KEYP_CTRL_KEYP_EN; - rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); + rc = regmap_write(kp->regmap, KEYP_CTRL, kp->ctrl_reg); if (rc < 0) dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); @@ -465,7 +438,7 @@ static int pmic8xxx_kp_disable(struct pmic8xxx_kp *kp) kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN; - rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); + rc = regmap_write(kp->regmap, KEYP_CTRL, kp->ctrl_reg); if (rc < 0) return rc; @@ -503,7 +476,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) const struct matrix_keymap_data *keymap_data; struct pmic8xxx_kp *kp; int rc; - u8 ctrl_val; + unsigned int ctrl_val; if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8XXX_MAX_COLS || @@ -547,6 +520,10 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) if (!kp) return -ENOMEM; + kp->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!kp->regmap) + return -ENODEV; + platform_set_drvdata(pdev, kp); kp->pdata = pdata; @@ -621,7 +598,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) return rc; } - rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); + rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); return rc; -- cgit v1.2.3 From 86ea5e6b793d45fa7d2aa504ac3aefc813f0fd55 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 29 Mar 2014 12:35:35 -0700 Subject: Input: pmic8xxx-keypad - migrate to DT The driver is only supported on DT enabled platforms. Convert the driver to DT so that it can probe properly. Signed-off-by: Stephen Boyd Signed-off-by: Dmitry Torokhov --- .../bindings/input/qcom,pm8xxx-keypad.txt | 89 ++++++++++++ drivers/input/keyboard/pmic8xxx-keypad.c | 150 ++++++++++++--------- include/linux/input/pmic8xxx-keypad.h | 52 ------- 3 files changed, 175 insertions(+), 116 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt delete mode 100644 include/linux/input/pmic8xxx-keypad.h (limited to 'drivers/input/keyboard') diff --git a/Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt b/Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt new file mode 100644 index 000000000000..7d8cb92831d7 --- /dev/null +++ b/Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt @@ -0,0 +1,89 @@ +Qualcomm PM8xxx PMIC Keypad + +PROPERTIES + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,pm8058-keypad" + "qcom,pm8921-keypad" + +- reg: + Usage: required + Value type: + Definition: address of keypad control register + +- interrupts: + Usage: required + Value type: + Definition: the first interrupt specifies the key sense interrupt + and the second interrupt specifies the key stuck interrupt. + The format of the specifier is defined by the binding + document describing the node's interrupt parent. + +- linux,keymap: + Usage: required + Value type: + Definition: the linux keymap. More information can be found in + input/matrix-keymap.txt. + +- linux,keypad-no-autorepeat: + Usage: optional + Value type: + Definition: don't enable autorepeat feature. + +- linux,keypad-wakeup: + Usage: optional + Value type: + Definition: use any event on keypad as wakeup event. + +- keypad,num-rows: + Usage: required + Value type: + Definition: number of rows in the keymap. More information can be found + in input/matrix-keymap.txt. + +- keypad,num-columns: + Usage: required + Value type: + Definition: number of columns in the keymap. More information can be + found in input/matrix-keymap.txt. + +- debounce: + Usage: optional + Value type: + Definition: time in microseconds that key must be pressed or release + for key sense interrupt to trigger. + +- scan-delay: + Usage: optional + Value type: + Definition: time in microseconds to pause between successive scans + of the matrix array. + +- row-hold: + Usage: optional + Value type: + Definition: time in nanoseconds to pause between scans of each row in + the matrix array. + +EXAMPLE + + keypad@148 { + compatible = "qcom,pm8921-keypad"; + reg = <0x148>; + interrupt-parent = <&pmicintc>; + interrupts = <74 1>, <75 1>; + linux,keymap = < + MATRIX_KEY(0, 0, KEY_VOLUMEUP) + MATRIX_KEY(0, 1, KEY_VOLUMEDOWN) + MATRIX_KEY(0, 2, KEY_CAMERA_FOCUS) + MATRIX_KEY(0, 3, KEY_CAMERA) + >; + keypad,num-rows = <1>; + keypad,num-columns = <5>; + debounce = <15>; + scan-delay = <32>; + row-hold = <91500>; + }; diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 0efd11e16b7e..80c6b0ef3fc8 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -20,8 +20,8 @@ #include #include #include - -#include +#include +#include #define PM8XXX_MAX_ROWS 18 #define PM8XXX_MAX_COLS 8 @@ -84,7 +84,8 @@ /** * struct pmic8xxx_kp - internal keypad data structure - * @pdata - keypad platform data pointer + * @num_cols - number of columns of keypad + * @num_rows - number of row of keypad * @input - input device pointer for keypad * @regmap - regmap handle * @key_sense_irq - key press/release irq number @@ -96,7 +97,8 @@ * @ctrl_reg - control register value */ struct pmic8xxx_kp { - const struct pm8xxx_keypad_platform_data *pdata; + unsigned int num_rows; + unsigned int num_cols; struct input_dev *input; struct regmap *regmap; int key_sense_irq; @@ -115,9 +117,9 @@ static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) { /* all keys pressed on that particular row? */ if (col == 0x00) - return 1 << kp->pdata->num_cols; + return 1 << kp->num_cols; else - return col & ((1 << kp->pdata->num_cols) - 1); + return col & ((1 << kp->num_cols) - 1); } /* @@ -180,10 +182,10 @@ static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, int rc, read_rows; unsigned int scan_val; - if (kp->pdata->num_rows < PM8XXX_MIN_ROWS) + if (kp->num_rows < PM8XXX_MIN_ROWS) read_rows = PM8XXX_MIN_ROWS; else - read_rows = kp->pdata->num_rows; + read_rows = kp->num_rows; pmic8xxx_chk_sync_read(kp); @@ -227,13 +229,13 @@ static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, { int row, col, code; - for (row = 0; row < kp->pdata->num_rows; row++) { + for (row = 0; row < kp->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; - for (col = 0; col < kp->pdata->num_cols; col++) { + for (col = 0; col < kp->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; @@ -259,9 +261,9 @@ static bool pmic8xxx_detect_ghost_keys(struct pmic8xxx_kp *kp, u16 *new_state) u16 check, row_state; check = 0; - for (row = 0; row < kp->pdata->num_rows; row++) { + for (row = 0; row < kp->num_rows; row++) { row_state = (~new_state[row]) & - ((1 << kp->pdata->num_cols) - 1); + ((1 << kp->num_cols) - 1); if (hweight16(row_state) > 1) { if (found_first == -1) @@ -369,8 +371,13 @@ static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) return IRQ_HANDLED; } -static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) +static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp, + struct platform_device *pdev) { + const struct device_node *of_node = pdev->dev.of_node; + unsigned int scan_delay_ms; + unsigned int row_hold_ns; + unsigned int debounce_ms; int bits, rc, cycles; u8 scan_val = 0, ctrl_val = 0; static const u8 row_bits[] = { @@ -378,18 +385,18 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) }; /* Find column bits */ - if (kp->pdata->num_cols < KEYP_CTRL_SCAN_COLS_MIN) + if (kp->num_cols < KEYP_CTRL_SCAN_COLS_MIN) bits = 0; else - bits = kp->pdata->num_cols - KEYP_CTRL_SCAN_COLS_MIN; + bits = kp->num_cols - KEYP_CTRL_SCAN_COLS_MIN; ctrl_val = (bits & KEYP_CTRL_SCAN_COLS_BITS) << KEYP_CTRL_SCAN_COLS_SHIFT; /* Find row bits */ - if (kp->pdata->num_rows < KEYP_CTRL_SCAN_ROWS_MIN) + if (kp->num_rows < KEYP_CTRL_SCAN_ROWS_MIN) bits = 0; else - bits = row_bits[kp->pdata->num_rows - KEYP_CTRL_SCAN_ROWS_MIN]; + bits = row_bits[kp->num_rows - KEYP_CTRL_SCAN_ROWS_MIN]; ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT); @@ -399,15 +406,44 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) return rc; } - bits = (kp->pdata->debounce_ms / 5) - 1; + if (of_property_read_u32(of_node, "scan-delay", &scan_delay_ms)) + scan_delay_ms = MIN_SCAN_DELAY; + + if (scan_delay_ms > MAX_SCAN_DELAY || scan_delay_ms < MIN_SCAN_DELAY || + !is_power_of_2(scan_delay_ms)) { + dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); + return -EINVAL; + } + + if (of_property_read_u32(of_node, "row-hold", &row_hold_ns)) + row_hold_ns = MIN_ROW_HOLD_DELAY; + + if (row_hold_ns > MAX_ROW_HOLD_DELAY || + row_hold_ns < MIN_ROW_HOLD_DELAY || + ((row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { + dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); + return -EINVAL; + } + + if (of_property_read_u32(of_node, "debounce", &debounce_ms)) + debounce_ms = MIN_DEBOUNCE_TIME; + + if (((debounce_ms % 5) != 0) || + debounce_ms > MAX_DEBOUNCE_TIME || + debounce_ms < MIN_DEBOUNCE_TIME) { + dev_err(&pdev->dev, "invalid debounce time supplied\n"); + return -EINVAL; + } + + bits = (debounce_ms / 5) - 1; scan_val |= (bits << KEYP_SCAN_DBOUNCE_SHIFT); - bits = fls(kp->pdata->scan_delay_ms) - 1; + bits = fls(scan_delay_ms) - 1; scan_val |= (bits << KEYP_SCAN_PAUSE_SHIFT); /* Row hold time is a multiple of 32KHz cycles. */ - cycles = (kp->pdata->row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC; + cycles = (row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC; scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT); @@ -471,50 +507,27 @@ static void pmic8xxx_kp_close(struct input_dev *dev) */ static int pmic8xxx_kp_probe(struct platform_device *pdev) { - const struct pm8xxx_keypad_platform_data *pdata = - dev_get_platdata(&pdev->dev); - const struct matrix_keymap_data *keymap_data; + unsigned int rows, cols; + bool repeat; + bool wakeup; struct pmic8xxx_kp *kp; int rc; unsigned int ctrl_val; - if (!pdata || !pdata->num_cols || !pdata->num_rows || - pdata->num_cols > PM8XXX_MAX_COLS || - pdata->num_rows > PM8XXX_MAX_ROWS || - pdata->num_cols < PM8XXX_MIN_COLS) { - dev_err(&pdev->dev, "invalid platform data\n"); - return -EINVAL; - } - - if (!pdata->scan_delay_ms || - pdata->scan_delay_ms > MAX_SCAN_DELAY || - pdata->scan_delay_ms < MIN_SCAN_DELAY || - !is_power_of_2(pdata->scan_delay_ms)) { - dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); - return -EINVAL; - } - - if (!pdata->row_hold_ns || - pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || - pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || - ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { - dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); - return -EINVAL; - } + rc = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); + if (rc) + return rc; - if (!pdata->debounce_ms || - ((pdata->debounce_ms % 5) != 0) || - pdata->debounce_ms > MAX_DEBOUNCE_TIME || - pdata->debounce_ms < MIN_DEBOUNCE_TIME) { - dev_err(&pdev->dev, "invalid debounce time supplied\n"); + if (cols > PM8XXX_MAX_COLS || rows > PM8XXX_MAX_ROWS || + cols < PM8XXX_MIN_COLS) { + dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } - keymap_data = pdata->keymap_data; - if (!keymap_data) { - dev_err(&pdev->dev, "no keymap data supplied\n"); - return -EINVAL; - } + repeat = !of_property_read_bool(pdev->dev.of_node, + "linux,input-no-autorepeat"); + wakeup = of_property_read_bool(pdev->dev.of_node, + "linux,keypad-wakeup"); kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); if (!kp) @@ -526,7 +539,8 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, kp); - kp->pdata = pdata; + kp->num_rows = rows; + kp->num_cols = cols; kp->dev = &pdev->dev; kp->input = devm_input_allocate_device(&pdev->dev); @@ -547,8 +561,8 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) return kp->key_stuck_irq; } - kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; - kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; + kp->input->name = "PMIC8XXX keypad"; + kp->input->phys = "pmic8xxx_keypad/input0"; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; @@ -558,7 +572,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; - rc = matrix_keypad_build_keymap(keymap_data, NULL, + rc = matrix_keypad_build_keymap(NULL, NULL, PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, kp->keycodes, kp->input); if (rc) { @@ -566,7 +580,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) return rc; } - if (pdata->rep) + if (repeat) __set_bit(EV_REP, kp->input->evbit); input_set_capability(kp->input, EV_MSC, MSC_SCAN); @@ -576,7 +590,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); - rc = pmic8xxx_kpd_init(kp); + rc = pmic8xxx_kpd_init(kp, pdev); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); return rc; @@ -612,7 +626,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) return rc; } - device_init_wakeup(&pdev->dev, pdata->wakeup); + device_init_wakeup(&pdev->dev, wakeup); return 0; } @@ -662,12 +676,20 @@ static int pmic8xxx_kp_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, pmic8xxx_kp_suspend, pmic8xxx_kp_resume); +static const struct of_device_id pm8xxx_match_table[] = { + { .compatible = "qcom,pm8058-keypad" }, + { .compatible = "qcom,pm8921-keypad" }, + { } +}; +MODULE_DEVICE_TABLE(of, pm8xxx_match_table); + static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .driver = { - .name = PM8XXX_KEYPAD_DEV_NAME, + .name = "pm8xxx-keypad", .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, + .of_match_table = pm8xxx_match_table, }, }; module_platform_driver(pmic8xxx_kp_driver); diff --git a/include/linux/input/pmic8xxx-keypad.h b/include/linux/input/pmic8xxx-keypad.h deleted file mode 100644 index 5f1e2f9ad959..000000000000 --- a/include/linux/input/pmic8xxx-keypad.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __PMIC8XXX_KEYPAD_H__ -#define __PMIC8XXX_KEYPAD_H__ - -#include - -#define PM8XXX_KEYPAD_DEV_NAME "pm8xxx-keypad" - -/** - * struct pm8xxx_keypad_platform_data - platform data for keypad - * @keymap_data - matrix keymap data - * @input_name - input device name - * @input_phys_device - input device name - * @num_cols - number of columns of keypad - * @num_rows - number of row of keypad - * @debounce_ms - debounce period in milliseconds - * @scan_delay_ms - scan delay in milliseconds - * @row_hold_ns - row hold period in nanoseconds - * @wakeup - configure keypad as wakeup - * @rep - enable or disable key repeat bit - */ -struct pm8xxx_keypad_platform_data { - const struct matrix_keymap_data *keymap_data; - - const char *input_name; - const char *input_phys_device; - - unsigned int num_cols; - unsigned int num_rows; - unsigned int rows_gpio_start; - unsigned int cols_gpio_start; - - unsigned int debounce_ms; - unsigned int scan_delay_ms; - unsigned int row_hold_ns; - - bool wakeup; - bool rep; -}; - -#endif /*__PMIC8XXX_KEYPAD_H__ */ -- cgit v1.2.3