From patchwork Sun Jan 15 13:15:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 9517407 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DFF86601DA for ; Sun, 15 Jan 2017 13:16:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D5E0D283FB for ; Sun, 15 Jan 2017 13:16:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CAF4D283FF; Sun, 15 Jan 2017 13:16:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1ED29283FB for ; Sun, 15 Jan 2017 13:16:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751111AbdAONQQ (ORCPT ); Sun, 15 Jan 2017 08:16:16 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:35095 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751077AbdAONQP (ORCPT ); Sun, 15 Jan 2017 08:16:15 -0500 Received: by mail-pf0-f195.google.com with SMTP id f144so12452960pfa.2; Sun, 15 Jan 2017 05:16:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=naj1wsmWVVExJ6WzKMgs4HYTqEh9m0VVYODTn/q93eo=; b=Jb1dZk2+TZyk0jyyRJvD4GT83yLj+k4zPFB0VrLajDBd23fdgbvrVfNHdro0GrM9FJ qi6iOKJcS4I+BvYZ7IikyyL9Bi6446nDiTLFMhm9+/2VP//CeIAQtKYz1ZHYsemUqoMB bGu+dw7KGGCWkuPAfE0APR9bmHYjAVgVnIoW2Gm34oSVsZ8pRQSs/IW19KHamA/6ixwB CBfWgNWXr+Y4CfIpTSqQP4quscVtCc6cYY9a0qCvPOdncH/F8MP2avKcZr6sT4k90ys+ tsP2ITq0nAE9Sn7rUkTcZWRNRkEZwihTdO/a/o8/QP8ecscG9sp8lf2OKCVRr2m5uKJv d5mQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=naj1wsmWVVExJ6WzKMgs4HYTqEh9m0VVYODTn/q93eo=; b=Go0YoL8B2j7bRrsa8Qha2ANcBuWOixcdGRH82KHiLfYcHqgt+/QJaUz6sat6lJPhbu NaBwTT9y7FdLaM4wyI4LXEt29tADaREDGttM9G4N+PHOAn0+MJqObEWWcdLicB7i4YFz ZRrml2fqNyFhurs4OjoiJuKt5LBasE9dEmmkxVGMPk7Tu860Fq4g2eudL3EIN7ie+L1h ntVHjSeCHP01SfgouOtx4+VuUX/PSBCTNrJtheJ8HwzVKHpFxrim9QOvq7TrAN1X77C0 A+yGUQ6Fr/Xx8OKzzru+k4w94OGXQaEE9gQhmQrXVD6Inmn74JcD6n2Gl85oLeR7Lm2l 1TPw== X-Gm-Message-State: AIkVDXIL6ai/+cCK2Tjyt12Dh1mmq1EIceydhOFBHykMbC4ayjWA7vafUohRR1ZSVYmG4A== X-Received: by 10.84.136.7 with SMTP id 7mr29974338plk.100.1484486174557; Sun, 15 Jan 2017 05:16:14 -0800 (PST) Received: from localhost.localdomain ([240f:4:c2bc:1:9509:afdd:5ccb:93b]) by smtp.gmail.com with ESMTPSA id n70sm10038237pfg.34.2017.01.15.05.16.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 15 Jan 2017 05:16:14 -0800 (PST) From: Akinobu Mita To: linux-input@vger.kernel.org, devicetree@vger.kernel.org Cc: Akinobu Mita , Dmitry Torokhov , Rob Herring Subject: [PATCH v2 5/5] Input: mpr121 - switch to device tree probe Date: Sun, 15 Jan 2017 22:15:44 +0900 Message-Id: <1484486144-27947-6-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1484486144-27947-1-git-send-email-akinobu.mita@gmail.com> References: <1484486144-27947-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This driver currently only supports legacy platform data probe. This change adds device tree support and gets rid of platform data probe code since no one is actually using mpr121 platform data in the mainline. The device tree property parsing code is based on the work of atmel_captouch driver. Cc: Dmitry Torokhov Cc: Rob Herring Signed-off-by: Akinobu Mita --- * Newly added patch from v2 .../devicetree/bindings/input/mpr121-touchkey.txt | 30 ++++++ drivers/input/keyboard/mpr121_touchkey.c | 110 +++++++++++++++------ include/linux/i2c/mpr121_touchkey.h | 20 ---- 3 files changed, 110 insertions(+), 50 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/mpr121-touchkey.txt delete mode 100644 include/linux/i2c/mpr121_touchkey.h diff --git a/Documentation/devicetree/bindings/input/mpr121-touchkey.txt b/Documentation/devicetree/bindings/input/mpr121-touchkey.txt new file mode 100644 index 0000000..b7c61ee --- /dev/null +++ b/Documentation/devicetree/bindings/input/mpr121-touchkey.txt @@ -0,0 +1,30 @@ +* Freescale MPR121 Controllor + +Required Properties: +- compatible: Should be "fsl,mpr121-touchkey" +- reg: The I2C slave address of the device. +- interrupts: The interrupt number to the cpu. +- vdd-supply: Phandle to the Vdd power supply. +- linux,keycodes: Specifies an array of numeric keycode values to + be used for reporting button presses. The array can + contain up to 12 entries. + +Optional Properties: +- wakeup-source: Use any event on keypad as wakeup event. +- autorepeat: Enable autorepeat feature. + +Example: + +#include "dt-bindings/input/input.h" + + touchkey: mpr121@5a { + compatible = "fsl,mpr121-touchkey"; + reg = <0x5a>; + interrupt-parent = <&gpio1>; + interrupts = <28 2>; + autorepeat; + vdd-supply = <&ldo4_reg>; + linux,keycodes = , , , , + , , , + , , , ; + }; diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index a0210ae..ebb401f 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include /* Register definitions */ #define ELE_TOUCH_STATUS_0_ADDR 0x0 @@ -61,7 +61,7 @@ struct mpr121_touchkey { struct input_dev *input_dev; unsigned int statusbits; unsigned int keycount; - u16 keycodes[MPR121_MAX_KEY_COUNT]; + u32 keycodes[MPR121_MAX_KEY_COUNT]; }; struct mpr121_init_register { @@ -81,6 +81,42 @@ static const struct mpr121_init_register init_reg_table[] = { { AUTO_CONFIG_CTRL_ADDR, 0x0b }, }; +static void mpr121_vdd_supply_disable(void *data) +{ + struct regulator *vdd_supply = data; + + regulator_disable(vdd_supply); +} + +static struct regulator *mpr121_vdd_supply_init(struct device *dev) +{ + struct regulator *vdd_supply; + int err; + + vdd_supply = devm_regulator_get(dev, "vdd"); + if (IS_ERR(vdd_supply)) { + dev_err(dev, "failed to get vdd regulator: %ld\n", + PTR_ERR(vdd_supply)); + return vdd_supply; + } + + err = regulator_enable(vdd_supply); + if (err) { + dev_err(dev, "failed to enable vdd regulator: %d\n", err); + return ERR_PTR(err); + } + + err = devm_add_action(dev, mpr121_vdd_supply_disable, vdd_supply); + if (err) { + regulator_disable(vdd_supply); + dev_err(dev, "failed to add disable regulator action: %d\n", + err); + return ERR_PTR(err); + } + + return vdd_supply; +} + static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) { struct mpr121_touchkey *mpr121 = dev_id; @@ -126,9 +162,8 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int mpr121_phys_init(const struct mpr121_platform_data *pdata, - struct mpr121_touchkey *mpr121, - struct i2c_client *client) +static int mpr121_phys_init(struct mpr121_touchkey *mpr121, + struct i2c_client *client, int vdd_uv) { const struct mpr121_init_register *reg; unsigned char usl, lsl, tl, eleconf; @@ -158,9 +193,9 @@ static int mpr121_phys_init(const struct mpr121_platform_data *pdata, /* * Capacitance on sensing input varies and needs to be compensated. * The internal MPR121-auto-configuration can do this if it's - * registers are set properly (based on pdata->vdd_uv). + * registers are set properly (based on vdd_uv). */ - vdd = pdata->vdd_uv / 1000; + vdd = vdd_uv / 1000; usl = ((vdd - 700) * 256) / vdd; lsl = (usl * 65) / 100; tl = (usl * 90) / 100; @@ -191,27 +226,19 @@ static int mpr121_phys_init(const struct mpr121_platform_data *pdata, static int mpr_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct mpr121_platform_data *pdata = - dev_get_platdata(&client->dev); + struct device *dev = &client->dev; + struct regulator *vdd_supply; + int vdd_uv; struct mpr121_touchkey *mpr121; struct input_dev *input_dev; int error; int i; - if (!pdata) { - dev_err(&client->dev, "no platform data defined\n"); - return -EINVAL; - } + vdd_supply = mpr121_vdd_supply_init(dev); + if (IS_ERR(vdd_supply)) + return PTR_ERR(vdd_supply); - if (!pdata->keymap || !pdata->keymap_size) { - dev_err(&client->dev, "missing keymap data\n"); - return -EINVAL; - } - - if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) { - dev_err(&client->dev, "too many keys defined\n"); - return -EINVAL; - } + vdd_uv = regulator_get_voltage(vdd_supply); if (!client->irq) { dev_err(&client->dev, "irq number should not be zero\n"); @@ -229,24 +256,37 @@ static int mpr_touchkey_probe(struct i2c_client *client, mpr121->client = client; mpr121->input_dev = input_dev; - mpr121->keycount = pdata->keymap_size; + mpr121->keycount = device_property_read_u32_array(dev, "linux,keycodes", + NULL, 0); + if (mpr121->keycount > MPR121_MAX_KEY_COUNT) { + dev_err(dev, "too many keys defined\n"); + return -EINVAL; + } + + error = device_property_read_u32_array(dev, "linux,keycodes", + mpr121->keycodes, + mpr121->keycount); + if (error) { + dev_err(dev, + "failed to read linux,keycode property: %d\n", error); + return error; + } input_dev->name = "Freescale MPR121 Touchkey"; input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + if (device_property_present(dev, "autorepeat")) + __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_dev->keycode = mpr121->keycodes; input_dev->keycodesize = sizeof(mpr121->keycodes[0]); input_dev->keycodemax = mpr121->keycount; - for (i = 0; i < pdata->keymap_size; i++) { - input_set_capability(input_dev, EV_KEY, pdata->keymap[i]); - mpr121->keycodes[i] = pdata->keymap[i]; - } + for (i = 0; i < mpr121->keycount; i++) + input_set_capability(input_dev, EV_KEY, mpr121->keycodes[i]); - error = mpr121_phys_init(pdata, mpr121, client); + error = mpr121_phys_init(mpr121, client, vdd_uv); if (error) { dev_err(&client->dev, "Failed to init register\n"); return error; @@ -266,7 +306,8 @@ static int mpr_touchkey_probe(struct i2c_client *client, return error; i2c_set_clientdata(client, mpr121); - device_init_wakeup(&client->dev, pdata->wakeup); + device_init_wakeup(dev, + device_property_read_bool(dev, "wakeup-source")); return 0; } @@ -305,10 +346,19 @@ static const struct i2c_device_id mpr121_id[] = { }; MODULE_DEVICE_TABLE(i2c, mpr121_id); +#ifdef CONFIG_OF +static const struct of_device_id mpr121_touchkey_dt_match_table[] = { + { .compatible = "fsl,mpr121-touchkey" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mpr121_touchkey_dt_match_table); +#endif + static struct i2c_driver mpr_touchkey_driver = { .driver = { .name = "mpr121", .pm = &mpr121_touchkey_pm_ops, + .of_match_table = of_match_ptr(mpr121_touchkey_dt_match_table), }, .id_table = mpr121_id, .probe = mpr_touchkey_probe, diff --git a/include/linux/i2c/mpr121_touchkey.h b/include/linux/i2c/mpr121_touchkey.h deleted file mode 100644 index f0bcc38..0000000 --- a/include/linux/i2c/mpr121_touchkey.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Header file for Freescale MPR121 Capacitive Touch Sensor */ - -#ifndef _MPR121_TOUCHKEY_H -#define _MPR121_TOUCHKEY_H - -/** - * struct mpr121_platform_data - platform data for mpr121 sensor - * @keymap: pointer to array of KEY_* values representing keymap - * @keymap_size: size of the keymap - * @wakeup: configure the button as a wake-up source - * @vdd_uv: VDD voltage in uV - */ -struct mpr121_platform_data { - const unsigned short *keymap; - unsigned int keymap_size; - bool wakeup; - int vdd_uv; -}; - -#endif /* _MPR121_TOUCHKEY_H */