From patchwork Tue May 4 19:20:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yassine Oudjana X-Patchwork-Id: 12238519 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D897C433B4 for ; Tue, 4 May 2021 19:20:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5A588613C7 for ; Tue, 4 May 2021 19:20:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232521AbhEDTVa (ORCPT ); Tue, 4 May 2021 15:21:30 -0400 Received: from mail-0301.mail-europe.com ([188.165.51.139]:42669 "EHLO mail-03.mail-europe.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S232483AbhEDTV3 (ORCPT ); Tue, 4 May 2021 15:21:29 -0400 X-Greylist: delayed 37923 seconds by postgrey-1.27 at vger.kernel.org; Tue, 04 May 2021 15:21:29 EDT Date: Tue, 04 May 2021 19:20:27 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail; t=1620156031; bh=RO5HKcBneRb2Yah0nMoSXvmeMB/hkyZ7H63li9LjO04=; h=Date:To:From:Cc:Reply-To:Subject:From; b=FbcjPDj2lmRlA/jWEcEQ9G6+AKaO5zp6y48vPZ7XiVicw79E2ttCPou0BQNCvJsTb wrZXb7zAZAe9e6t4hXylb7lXJW15qyhl+XL1cly0++7jfGrYFIgd7QvZ0PNKw9ZMag pqs5V/bGDD5lJS6mxgkfql5oQaZLVqMpc/F0+h/c= To: "linux-input@vger.kernel.org" , "devicetree@vger.kernel.org" , "dmitry.torokhov@gmail.com" , "robh+dt@kernel.org" From: Yassine Oudjana Cc: Yassine Oudjana , "linux-kernel@vger.kernel.org" , "phone-devel@vger.kernel.org" , "~postmarketos/upstreaming@lists.sr.ht" <~postmarketos/upstreaming@lists.sr.ht> Reply-To: Yassine Oudjana Subject: [PATCH v2 1/2] Input: cypress-sf - Add Cypress StreetFighter touchkey driver Message-ID: <7PLVBAKRbtNysjS13InqsN59dLZarOcTPCpRg8HH4@cp3-web-029.plabs.ch> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This adds support for Cypress StreetFighter touchkey controllers such as sf3155. This driver supports enabling regulators and generating input events. Signed-off-by: Yassine Oudjana --- drivers/input/keyboard/Kconfig | 10 ++ drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/cypress-sf.c | 219 ++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 drivers/input/keyboard/cypress-sf.c diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 32d15809ae58..9348cd604843 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -791,4 +791,14 @@ config KEYBOARD_MTK_PMIC To compile this driver as a module, choose M here: the module will be called pmic-keys. +config KEYBOARD_CYPRESS_SF + tristate "Cypress StreetFighter touchkey support" + depends on I2C + help + Say Y here if you want to enable support for Cypress StreetFighter + touchkeys. + + To compile this driver as a module, choose M here: the + module will be called cypress-sf. + endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 1d689fdd5c00..e3c8648f834e 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_BCM) += bcm-keypad.o obj-$(CONFIG_KEYBOARD_CAP11XX) += cap11xx.o obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o +obj-$(CONFIG_KEYBOARD_CYPRESS_SF) += cypress-sf.o obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o obj-$(CONFIG_KEYBOARD_DLINK_DIR685) += dlink-dir685-touchkeys.o obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o diff --git a/drivers/input/keyboard/cypress-sf.c b/drivers/input/keyboard/cypress-sf.c new file mode 100644 index 000000000000..49594d983c44 --- /dev/null +++ b/drivers/input/keyboard/cypress-sf.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CYPRESS_SF_DEV_NAME "cypress-sf" + +#define CYPRESS_SF_REG_FW_VERSION 0x46 +#define CYPRESS_SF_REG_HW_VERSION 0x48 +#define CYPRESS_SF_REG_BUTTON_STATUS 0x4a + +struct cypress_sf_data { + struct i2c_client *client; + struct input_dev *input_dev; + struct regulator_bulk_data regulators[2]; + u32 *keycodes; + unsigned long keystates; + int num_keys; +}; + +static irqreturn_t cypress_sf_irq_handler(int irq, void *devid) +{ + struct cypress_sf_data *touchkey = devid; + unsigned long keystates; + bool curr_state, new_state; + int key; + + keystates = i2c_smbus_read_byte_data(touchkey->client, + CYPRESS_SF_REG_BUTTON_STATUS); + if (keystates < 0) { + dev_err(&touchkey->client->dev, "Failed to read button status"); + return IRQ_NONE; + } + + for(key = 0; key < touchkey->num_keys; ++key) { + curr_state = test_bit(key, &touchkey->keystates); + new_state = test_bit(key, &keystates); + + if(curr_state ^ new_state) { + dev_dbg(&touchkey->client->dev,\ + "Key %d changed to %d", key, new_state); + input_report_key(touchkey->input_dev, + touchkey->keycodes[key], + new_state); + } + } + input_sync(touchkey->input_dev); + touchkey->keystates = keystates; + + return IRQ_HANDLED; +} + +static int cypress_sf_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cypress_sf_data *touchkey; + int hw_version, fw_version; + int ret; + int i; + + touchkey = devm_kzalloc(&client->dev, sizeof(*touchkey), GFP_KERNEL); + if(!touchkey) + return -ENOMEM; + + touchkey->client = client; + i2c_set_clientdata(client, touchkey); + + touchkey->regulators[0].supply = "vdd"; + touchkey->regulators[1].supply = "avdd"; + + ret = devm_regulator_bulk_get(&client->dev, + ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); + if(ret) { + dev_err(&client->dev, "Failed to get regulators: %d\n", ret); + return ret; + } + + touchkey->num_keys = of_property_count_elems_of_size(client->dev.of_node, + "linux,keycodes", + sizeof(u32)); + if(touchkey->num_keys < 0) + /* Default key count */ + touchkey->num_keys = 2; + + touchkey->keycodes = devm_kzalloc(&client->dev, + sizeof(u32) * touchkey->num_keys, GFP_KERNEL); + if(!touchkey->keycodes) + return -ENOMEM; + + ret = of_property_read_u32_array(client->dev.of_node, "linux,keycodes", + touchkey->keycodes, touchkey->num_keys); + + if(touchkey->num_keys < 0) { + /* Default keycodes */ + touchkey->keycodes[0] = KEY_BACK; + touchkey->keycodes[1] = KEY_MENU; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); + if(ret) { + dev_err(&client->dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + + touchkey->input_dev = devm_input_allocate_device(&client->dev); + if(!touchkey->input_dev) { + dev_err(&client->dev, "Failed to allocate input device\n"); + return -ENOMEM; + } + + touchkey->input_dev->name = CYPRESS_SF_DEV_NAME; + touchkey->input_dev->id.bustype = BUS_I2C; + + hw_version = i2c_smbus_read_byte_data(touchkey->client, + CYPRESS_SF_REG_HW_VERSION); + fw_version = i2c_smbus_read_word_data(touchkey->client, + CYPRESS_SF_REG_FW_VERSION); + if(hw_version < 0 || fw_version < 0) + dev_warn(&client->dev, "Failed to read versions\n"); + else + dev_info(&client->dev, "HW version %d, FW version %d\n", + hw_version, fw_version); + + for(i = 0; i < touchkey->num_keys; ++i) + input_set_capability(touchkey->input_dev, EV_KEY, + touchkey->keycodes[i]); + + ret = input_register_device(touchkey->input_dev); + if(ret) { + dev_err(&client->dev, + "Failed to register input device: %d\n", ret); + return ret; + } + + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, cypress_sf_irq_handler, + IRQF_ONESHOT, + CYPRESS_SF_DEV_NAME, touchkey); + if(ret) { + dev_err(&client->dev, + "Failed to register threaded irq: %d", ret); + return ret; + } + + return 0; +}; + +static int __maybe_unused cypress_sf_suspend(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); + struct cypress_sf_data *touchkey = i2c_get_clientdata(client); + int ret; + + disable_irq(client->irq); + ret = regulator_bulk_disable(ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); + if(ret) { + dev_err(dev, "Failed to disable regulators: %d", ret); + enable_irq(client->irq); + return ret; + } + dev_dbg(dev, "Suspended device"); + + return 0; +} + +static int __maybe_unused cypress_sf_resume(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); + struct cypress_sf_data *touchkey = i2c_get_clientdata(client); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); + if(ret) { + dev_err(dev, "Failed to enable regulators: %d", ret); + return ret; + } + enable_irq(client->irq); + dev_dbg(dev, "Resumed device"); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(cypress_sf_pm_ops, + cypress_sf_suspend, cypress_sf_resume); + +static struct i2c_device_id cypress_sf_id_table[] = { + { CYPRESS_SF_DEV_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cypress_sf_id_table); + +static const struct of_device_id cypress_sf_of_match[] = { + { .compatible = "cypress,sf3155", }, + { }, +}; +MODULE_DEVICE_TABLE(of, cypress_sf_of_match); + +static struct i2c_driver cypress_sf_driver = { + .driver = { + .name = CYPRESS_SF_DEV_NAME, + .pm = &cypress_sf_pm_ops, + .of_match_table = of_match_ptr(cypress_sf_of_match), + }, + .id_table = cypress_sf_id_table, + .probe = cypress_sf_probe, +}; +module_i2c_driver(cypress_sf_driver); + +MODULE_AUTHOR("Yassine Oudjana "); +MODULE_DESCRIPTION("Cypress StreetFighter Touchkey Driver"); +MODULE_LICENSE("GPL v2"); \ No newline at end of file From patchwork Tue May 4 19:20:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yassine Oudjana X-Patchwork-Id: 12238521 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C444C433B4 for ; Tue, 4 May 2021 19:21:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 25E59610E9 for ; Tue, 4 May 2021 19:21:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232455AbhEDTV4 (ORCPT ); Tue, 4 May 2021 15:21:56 -0400 Received: from mail4.protonmail.ch ([185.70.40.27]:33111 "EHLO mail4.protonmail.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232483AbhEDTV4 (ORCPT ); Tue, 4 May 2021 15:21:56 -0400 X-Greylist: delayed 38008 seconds by postgrey-1.27 at vger.kernel.org; Tue, 04 May 2021 15:21:56 EDT Date: Tue, 04 May 2021 19:20:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail; t=1620156059; bh=hPN9j0nF1AQgM6cAsZDixp19IElNYSJ0wg7fViCdyB0=; h=Date:To:From:Cc:Reply-To:Subject:From; b=A9qhvxX2TE6AkNYqZY73Rg0aM45HJH6nqpWLhbwtPjN3zEmA+EQDKQiZNOKhY6rh2 MaEvSH3naAkrtk8sgTaD4WnauKugRPywXxjfQR/zGShdgp7G4FFv8GJYYcZTdw/JK2 OiFZuz3QuJjR7H8c4D1t1jJZvPMAgu1b9aBAwu6A= To: "linux-input@vger.kernel.org" , "devicetree@vger.kernel.org" , "dmitry.torokhov@gmail.com" , "robh+dt@kernel.org" From: Yassine Oudjana Cc: Yassine Oudjana , "linux-kernel@vger.kernel.org" , "phone-devel@vger.kernel.org" , "~postmarketos/upstreaming@lists.sr.ht" <~postmarketos/upstreaming@lists.sr.ht> Reply-To: Yassine Oudjana Subject: [PATCH v2 2/2] dt-bindings: input: Add binding for cypress-sf Message-ID: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Add a device tree binding for Cypress StreetFighter. Signed-off-by: Yassine Oudjana Reviewed-by: Rob Herring --- .../devicetree/bindings/input/cypress-sf.yaml | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/cypress-sf.yaml diff --git a/Documentation/devicetree/bindings/input/cypress-sf.yaml b/Documentation/devicetree/bindings/input/cypress-sf.yaml new file mode 100644 index 000000000000..14689daf6567 --- /dev/null +++ b/Documentation/devicetree/bindings/input/cypress-sf.yaml @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/cypress-sf.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cypress StreetFighter touchkey controller + +maintainers: + - Yassine Oudjana + +allOf: + - $ref: input.yaml# + +properties: + compatible: + const: cypress,sf3155 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + avdd-supply: + description: Regulator for AVDD analog voltage + + vdd-supply: + description: Regulator for VDD digital voltage + + linux,keycodes: + minItems: 1 + maxItems: 8 + +required: + - compatible + - reg + - interrupts + - avdd-supply + - vdd-supply + +additionalProperties: false + +examples: + - | + #include + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchkey@28 { + compatible = "cypress,sf3155"; + reg = <0x28>; + interrupt-parent = <&msmgpio>; + interrupts = <77 IRQ_TYPE_EDGE_FALLING>; + avdd-supply = <&vreg_l6a_1p8>; + vdd-supply = <&vdd_3v2_tp>; + linux,keycodes = ; + }; + };