From patchwork Sat Jun 18 16:57:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Holland X-Patchwork-Id: 12886438 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 110A4CCA481 for ; Sat, 18 Jun 2022 17:00:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=gIqU0NdG0XWOHBkJwZ6iYgwMewNkjjLXN7brfNA/aeI=; b=tnWGlqKCDsA4E0 dHaqP8Wmba98gL5x3me2yD4A9H54w3NTE7rBH4V5fNN+n1E4pz0VhneJEV23jGKXoac5qdPYtcQf7 xBxQAC7EoRk55fR831Ee1R9bp4gOagDbgrLzc09CIHsr5/X6qkVIYrK5L5a86E+WJF4jdxh8crAyz x1UNZCs+LAfeEF/0vn/3+4/FBeeOg0RAL2L7zPSWp9izdV61uzYmVRT5RxtbWDSjcKJTuKKNHiLKh XXV9TzMC60gGn8SFhc3ytOdowDq5Cs13DRYUg1TZyELPnivWrig6NP0e2c35wdybBgdBIIX6WSs/r WkB823iQaD9njAUdFWCg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1o2bmF-00BtT6-FT; Sat, 18 Jun 2022 16:58:27 +0000 Received: from wnew2-smtp.messagingengine.com ([64.147.123.27]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1o2blu-00BtQm-P3 for linux-arm-kernel@lists.infradead.org; Sat, 18 Jun 2022 16:58:09 +0000 Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailnew.west.internal (Postfix) with ESMTP id 60C7D2B04FE0; Sat, 18 Jun 2022 12:58:04 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Sat, 18 Jun 2022 12:58:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sholland.org; h= cc:cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1655571483; x=1655578683; bh=f4 9f/XjlWb6yUqj3Q/Hp+u61iLGTlIGKm84rPezAGeA=; b=F7ZvoNWp5VZB1R7my1 1nyQrPuqRi13i/gcWPOfO3fPchclhyvS1jTDZLiL0d9HlifU35iUk+QV7qq2GqdT 6xAa1nxLFFbYj66WQnNH6FEPpyFN1kz24p+jRAY0SeNztWSPvtwbKuiFomvLDWFQ 0WgsC0aYK731Tc5zazhmLGpdpGpCknn4zqP/THGu7oqMpEqKZuKoIfgkoF+TDRk6 aGqMmpsdCGrw8h54iUCZ0h3ACfyUd9+nTnGqEyPuznKkQC3XyxSl5D3KRLD4Uw4w fcdLWwLpA9YugSu5iml1ON53nt7IRYLg/5EtzORQbFzO6b3h1H+Bqsja84PJXqmZ Fetw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm2; t=1655571483; x=1655578683; bh=f49f/XjlWb6yU qj3Q/Hp+u61iLGTlIGKm84rPezAGeA=; b=r5/+ceDIvzxb7kt+WgJGFjyx4x5vU nCD7muVNhvQuNuCQYGuBAiTwQ1iOcqiBiW9G4DEfcNhJZXIhV46DDzOqksUPDJzg J2VIy7yQLmRZHprvGziWGlbGk/TjUqMl03hXAcIWHs9pj/PdHbJVDPjxehHU6e8c wqY2oZUuE0giFtVH1//hcULzDIbxjKVmJSV7/Js4g/9TtyAL8k2OrCMKdJvOvfAC IdAmR0nMDjnbj/1nQ8f/M6w6NtRV0v6emgYAUby6cHLAtlTaFZMRLQMkTAge1+oL aOmJdM+VCgb6Gxn8Arg+HxzLJ5jhcCNtbaHG/dlrAwv1bglEWI5v91Isg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddvjedguddutdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefurghm uhgvlhcujfholhhlrghnugcuoehsrghmuhgvlhesshhhohhllhgrnhgurdhorhhgqeenuc ggtffrrghtthgvrhhnpedukeetueduhedtleetvefguddvvdejhfefudelgfduveeggeeh gfdufeeitdevteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfh hrohhmpehsrghmuhgvlhesshhhohhllhgrnhgurdhorhhg X-ME-Proxy: Feedback-ID: i0ad843c9:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 18 Jun 2022 12:58:02 -0400 (EDT) From: Samuel Holland To: Dmitry Torokhov , linux-input@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Rob Herring , Ondrej Jirman , Krzysztof Kozlowski , devicetree@vger.kernel.org, Samuel Holland , Andy Shevchenko , Chen-Yu Tsai , Colin Ian King , David Gow , Jernej Skrabec , Krzysztof Kozlowski , Marco Felsch , Mattijs Korpershoek , Stephen Boyd , Yassine Oudjana , "fengping.yu" , linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v4 3/4] Input: pinephone-keyboard - Support the proxied I2C bus Date: Sat, 18 Jun 2022 11:57:46 -0500 Message-Id: <20220618165747.55709-4-samuel@sholland.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220618165747.55709-1-samuel@sholland.org> References: <20220618165747.55709-1-samuel@sholland.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220618_095806_883940_AA77A556 X-CRM114-Status: GOOD ( 16.63 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The PinePhone keyboard case contains a battery managed by an integrated power bank IC. The power bank IC communicates over I2C, and the keyboard MCU firmware provides an interface to read and write its registers. Let's use this interface to implement a SMBus adapter, so we can reuse the driver for the power bank IC. Signed-off-by: Samuel Holland --- (no changes since v3) Changes in v3: - Rename i2c-bus to i2c drivers/input/keyboard/pinephone-keyboard.c | 73 +++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/input/keyboard/pinephone-keyboard.c b/drivers/input/keyboard/pinephone-keyboard.c index a021c9deee19..c22a1e306a71 100644 --- a/drivers/input/keyboard/pinephone-keyboard.c +++ b/drivers/input/keyboard/pinephone-keyboard.c @@ -3,6 +3,7 @@ // Copyright (C) 2021-2022 Samuel Holland #include +#include #include #include #include @@ -24,6 +25,11 @@ #define PPKB_SCAN_DATA 0x08 #define PPKB_SYS_CONFIG 0x20 #define PPKB_SYS_CONFIG_DISABLE_SCAN BIT(0) +#define PPKB_SYS_SMBUS_COMMAND 0x21 +#define PPKB_SYS_SMBUS_DATA 0x22 +#define PPKB_SYS_COMMAND 0x23 +#define PPKB_SYS_COMMAND_SMBUS_READ 0x91 +#define PPKB_SYS_COMMAND_SMBUS_WRITE 0xa1 #define PPKB_ROWS 6 #define PPKB_COLS 12 @@ -132,6 +138,7 @@ static const struct matrix_keymap_data ppkb_keymap_data = { }; struct pinephone_keyboard { + struct i2c_adapter adapter; struct input_dev *input; u8 buf[2][PPKB_BUF_LEN]; u8 crc_table[CRC8_TABLE_SIZE]; @@ -140,6 +147,57 @@ struct pinephone_keyboard { bool fn_pressed; }; +static int ppkb_adap_smbus_xfer(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data) +{ + struct i2c_client *client = adap->algo_data; + u8 buf[3]; + int ret; + + buf[0] = command; + buf[1] = data->byte; + buf[2] = read_write == I2C_SMBUS_READ ? PPKB_SYS_COMMAND_SMBUS_READ + : PPKB_SYS_COMMAND_SMBUS_WRITE; + + ret = i2c_smbus_write_i2c_block_data(client, PPKB_SYS_SMBUS_COMMAND, + sizeof(buf), buf); + if (ret) + return ret; + + /* Read back the command status until it passes or fails. */ + do { + usleep_range(300, 500); + ret = i2c_smbus_read_byte_data(client, PPKB_SYS_COMMAND); + } while (ret == buf[2]); + if (ret < 0) + return ret; + /* Commands return 0x00 on success and 0xff on failure. */ + if (ret) + return -EIO; + + if (read_write == I2C_SMBUS_READ) { + ret = i2c_smbus_read_byte_data(client, PPKB_SYS_SMBUS_DATA); + if (ret < 0) + return ret; + + data->byte = ret; + } + + return 0; +} + +static u32 ppkg_adap_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_SMBUS_BYTE_DATA; +} + +static const struct i2c_algorithm ppkb_adap_algo = { + .smbus_xfer = ppkb_adap_smbus_xfer, + .functionality = ppkg_adap_functionality, +}; + static void ppkb_update(struct i2c_client *client) { struct pinephone_keyboard *ppkb = i2c_get_clientdata(client); @@ -266,6 +324,7 @@ static int ppkb_probe(struct i2c_client *client) struct pinephone_keyboard *ppkb; struct regulator *vbat_supply; u8 info[PPKB_MATRIX_SIZE + 1]; + struct device_node *i2c_bus; int ret; vbat_supply = devm_regulator_get(dev, "vbat"); @@ -311,6 +370,20 @@ static int ppkb_probe(struct i2c_client *client) i2c_set_clientdata(client, ppkb); + i2c_bus = of_get_child_by_name(dev->of_node, "i2c"); + if (i2c_bus) { + ppkb->adapter.owner = THIS_MODULE; + ppkb->adapter.algo = &ppkb_adap_algo; + ppkb->adapter.algo_data = client; + ppkb->adapter.dev.parent = dev; + ppkb->adapter.dev.of_node = i2c_bus; + strscpy(ppkb->adapter.name, DRV_NAME, sizeof(ppkb->adapter.name)); + + ret = devm_i2c_add_adapter(dev, &ppkb->adapter); + if (ret) + return dev_err_probe(dev, ret, "Failed to add I2C adapter\n"); + } + crc8_populate_msb(ppkb->crc_table, PPKB_CRC8_POLYNOMIAL); ppkb->input = devm_input_allocate_device(dev);