From patchwork Tue Jul 16 19:28:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13734833 Received: from AM0PR83CU005.outbound.protection.outlook.com (mail-westeuropeazon11010069.outbound.protection.outlook.com [52.101.69.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 059121A2548 for ; Tue, 16 Jul 2024 19:29:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.69.69 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721158149; cv=fail; b=EXO4W2Q2OMz3DZ0fLNIe0EDhLOoJCJco06xbd7U4ODoYdFkCblzQdUHZJe03g57MFmAgcwaTWQVjq5FEJnbwQ+SifuJgVw4H4VlYs9Z92IP+1YsdGFJibmsvKcj7bz8E0W1OL8bWPbyQ8Adq9fyn1Gwao/QV8PwpMhnBVBGLEEE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721158149; c=relaxed/simple; bh=u6o5ZgVOhIDsk0rsR+s89WrDh8nd57MlF4eGf0tco7s=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=CkzJ1b5jkALX7UCNMDZoKML0Ayd9gVzXT/bnKgYgyTB3HuP5rNKbETjCQBvSR3jPWszft5wZc/ZQ6aPvAD1FPlak/0jcu9kapY/n0WZKrjsh6LOPwXenpJHYTVn5ce9Q2lh12gz96XtkACEaPwKydR9qiK922+uhz1qDBqKx1Wk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b=NEFevBNI; arc=fail smtp.client-ip=52.101.69.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b="NEFevBNI" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=R4+we141gKYNvczBCXFZbpTa39fGlRyy+3MzdbZCdLxD9CStPUfwdxEzp4pSXOdP5W4VFAW1DLucfaVExmP5AQ0cGVOotLuYdwghWixpEyLYtCWoIBQjjfx4XRN9D4Va3HdkYP2og4O7blr9h2voJ1mmpapEk0M6Jc8wvcY8sSJmGCdoIeJUK2s1rD5+tu5yskNd8QVHZB7balMhz+NV3eDxZ743TEzhEjX2Z4jrIvFB8TF4ZjTrL1qu1nC3VciuntIvHWUx37L80SIZBcHODRGtWoxH6mfZdjgv6GdLz1njErMZmX3gg42WfKjJcAqiJxK+W3E4J68YcjGcWhYK/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=+w2t/T6iFzLfIMCDVpUfoX1P4V02RfiRLH2a5fsRmGM=; b=QoyL873/PKqX5N/DTnWGapUYb7W6z9LB/4vO10g53ITtZDLuXLcRpitld3YJALMBmAhWIbd9GteYrtqlWHzBdO8U3p91mJddkUH//MjrSQn2+XIUOsui3WSOX77Nvx0UKh14D5B0O+wAhYMpiUaO34NUdl9sBqyrFA9rFdzS2p8Z6gspDHWLSxCUj9T+tPxAIFud1WKiUrIRqG43kbgxHB6sC8L3Ekd4+3Q6DDJ51M8KRq2bALmiSaVh213YF4zfJqQG0lcym2giX9savwIhd9+dhFkTlvhNGFyN8M7HNAqQfO+YPQIwq374EBlnktXbzTreb5ibrGSkGonwDCP5iw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+w2t/T6iFzLfIMCDVpUfoX1P4V02RfiRLH2a5fsRmGM=; b=NEFevBNI+zbhLgjopx5WkhLpEQaOQAI9uBS2LDZPmmweY4iYWAgMvHLSZf0glKkUy3F3gZVbHdtnROgRSvnN+/PiaZAnq1nSt04QpyFWgGGtTse7VkdMsy9Y1mIMo/Hx6WqaADLumQSRHPiTB6F7MaPSiVxMCLdfDtR5A3O9qUI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) by VE1PR04MB7325.eurprd04.prod.outlook.com (2603:10a6:800:1af::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.14; Tue, 16 Jul 2024 19:29:03 +0000 Received: from PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::9126:a61e:341d:4b06]) by PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::9126:a61e:341d:4b06%4]) with mapi id 15.20.7762.027; Tue, 16 Jul 2024 19:29:03 +0000 From: Frank Li Date: Tue, 16 Jul 2024 15:28:26 -0400 Subject: [PATCH 3/6] gpio: adp5585-gpio: add adp5585-gpio support Message-Id: <20240716-adi-v1-3-79c0122986e7@nxp.com> References: <20240716-adi-v1-0-79c0122986e7@nxp.com> In-Reply-To: <20240716-adi-v1-0-79c0122986e7@nxp.com> To: Lee Jones , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Linus Walleij , Bartosz Golaszewski , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, linux-pwm@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Frank Li , Haibo Chen , Jun Li X-Mailer: b4 0.13-dev-e586c X-Developer-Signature: v=1; a=ed25519-sha256; t=1721158123; l=6743; i=Frank.Li@nxp.com; s=20240130; h=from:subject:message-id; bh=DWKFapoE8P1FSqk1OvDAEQl8OhrCjAiJ3y8kQN6BUkw=; b=Gu4DsNZiq6XDAIm8e7HIsiPXLc8qNgVRLwW+bQewKukNoK23sU/6uI3X5HxUSjQJkR+OShj5X mEwMIZ+4B16AfephX1ZeWSxAqc30cgK6A4pFL2FUZ+nSbK8nWn1Z25J X-Developer-Key: i=Frank.Li@nxp.com; a=ed25519; pk=I0L1sDUfPxpAkRvPKy7MdauTuSENRq+DnA+G4qcS94Q= X-ClientProxiedBy: SJ0PR03CA0148.namprd03.prod.outlook.com (2603:10b6:a03:33c::33) To PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) Precedence: bulk X-Mailing-List: imx@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PAXPR04MB9642:EE_|VE1PR04MB7325:EE_ X-MS-Office365-Filtering-Correlation-Id: 0cd1a394-9e72-45d2-323e-08dca5cd8d36 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|366016|376014|52116014|7416014|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?utf-8?q?3CIEoUp0onmDzpUqeDvF7akVhhEp79g?= =?utf-8?q?G7BzWusUeKsvUBqmjSlKwLIlDFGnvLbAhhbFzhfWNiwtm0Pw+E4SDGzGJ+Qjud/U2?= =?utf-8?q?+TdCffj6nyIarKy/AetkFvsAMd8aN/ukdQhZE0Uiq4UmGV7zoNOxRCFUWDpBow3TR?= =?utf-8?q?jaWmxsupZrzUdGQ2q41w02yM/rwCB7YtrOJDSVhpvDZVUq4LAGCk/mUWAJI3bCP/8?= =?utf-8?q?h7std1seEDJBsW2KWPHL9DpMStoqVCgYwYweh6ycq926CzusBCT3d/5E5RQF7VjtK?= =?utf-8?q?yXkua1UBzi2JY0jBAe56YqogNjUJhYre2MPX3P4T0Fh6VNhD6DJmU34LcnWHwScUK?= =?utf-8?q?SxsJjJzJwft7x/+gJ0tDm9cQJ8uGCVWQk64hPpaceFY8m/YFIhrjCsH4levh5r0cl?= =?utf-8?q?QjyxPd3pwW29tT43vqGxnElylb9FUow3goaTFKpYqiJlWOzEqQY861r9kvof9U2bZ?= =?utf-8?q?YuxAbj6fMFpEs8oE45wNFcsTKaw+QZ+E6o4lUL6QvyDvqD78iEo9oTAf1XC2/1Jd6?= =?utf-8?q?/tCVpG8jVyYX7azS/btTzCIyJsxh8w8s9FhbqdHaigNOp9OvOSA2FjxTwWrdk9N/X?= =?utf-8?q?TUA2o1lm/JQaA9c7LOSSHop5uYB2J0gv5od0o39BnMOxxsc6kUfGTVrXdXdde5mUr?= =?utf-8?q?+8bKN3TGUr6VaFEzQKGpSirHWTt35HVwqTsvUugv+MSKYuH4rpr+WeFgkJ8+y+0F5?= =?utf-8?q?moXnD9Nhhuy5ot9OsxhbvyyciifiZ+xtwC8yFrTmGwmfFChzE0KW9HY7TLclsqBgV?= =?utf-8?q?DN2BXGAGFMdoXn6XmVXYeIixP9iGydU0TliyVA2DCACGkAbNk7GK78KLhUSe76/x8?= =?utf-8?q?PMJc4MtX/h6uFQNTEadgtN1DL4qPkoJ7fihPzN/+hmuHPNauQycUEV3n1MK1u1/Ta?= =?utf-8?q?nIjVGQBg/hdYdrOk73kN1S78GiCruPBZdqQf5IF8jDNmqL9VU17V65g5BGm2nkQZH?= =?utf-8?q?KWmZuSuNKW1A0srhzvK8V4bM+GCM/bpmfbaNhTxLj24vJwTS/HSCBRhTH374+UVrn?= =?utf-8?q?ixyY3KIuw3ci9m3r9hkZCKiN1j++QXLOAo/TjkLfQDoeuxOK4pqDXPGOcYPwQxQAi?= =?utf-8?q?r/B1NfWvKAEP2rqkDKqkjWmyruY9QZgcBQRdoOvqM53J7O3qOdUXDlSF0TuKBvz72?= =?utf-8?q?ql0730RY5WWzCmlmk3wy6KUcZRwhc2Ouqev2t26vkUYdwgpHaxzf1a/I01zATCgzf?= =?utf-8?q?wHkDuYXCnDP9U4uMdwXoQFIzzrCPRPmKVedSD0gaRtPH0+qVOMrC3s/RHN7fx2SuL?= =?utf-8?q?OJKu3SnSZiLNZTPeO1T/KUJ4e1V6ARFsiz0FSlkIeHZM8ONegMcULlPdtp32MP1fm?= =?utf-8?q?QD5WRPoTZFmLJg3nb2kEb9VeUbEikffA8Q=3D=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PAXPR04MB9642.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(366016)(376014)(52116014)(7416014)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?Il8ouWtJVaowqwAh8EHDo2BB0wK8?= =?utf-8?q?ThYv5cfuE+aU/m7UCwCfnwNN8IlH/aXeEg5HYh+OzpW8DmHJGMYdaGj63IrcbC/CH?= =?utf-8?q?sKW7U4HONEm2rsPqjczOLk79BbvdqIdyY88OvseXUDHf03le0J+RvOyonUqUX7AfO?= =?utf-8?q?9VK/FghxUxq/Sm6gOfdv9q0TwyIUQMxEMIdL9MHLzTlqyk+iiynsKZH3U6dKqrJlB?= =?utf-8?q?cxHGc2ke4ttrBb7Uz/pNiEwig5ABU8rl3lmpWtausK9nzxDHQl853nEyVnQG5Wdd9?= =?utf-8?q?4WrGWlvcsMmdFTLqhCu2dK/6BTVWTbZ5mhft8ciX80+tVi3AgZx84TxE0fpZU9Il9?= =?utf-8?q?Y0xal0ACLZMc4FwvtlaJtXWQcuxl3ZoTPExOWdiNlo+YoKrxy8K3U2WDpvu9Zvht3?= =?utf-8?q?l3HK34if5W9KLcJvGRQMYHqtUsrVTnnGfzI/u5FbxnnU258U0DPmDREXaf8wLfTuV?= =?utf-8?q?Vo52/ZEJkQXyoBEyL8D5GyOShJzyaMU43bRv7kHM41oHS5oSLDhcyz3y+2u1mnvFi?= =?utf-8?q?eyv2zvLPzJL6vIsrTAEVlExoz1fVtW6I0eSv/Czm3zgrf6n6Ta2Cfm5v5AiRhmTvg?= =?utf-8?q?ukTfwb52rtCjx528qWfcmLgzuSVj4qvcOo1h+3Lmqr1BaY40T6XEycL++Wde+LVy8?= =?utf-8?q?ETM4uGaUiRw3AdKutLA2JPMJyeUslONMsz/KaCcwgPAwSkn2j/kcrxgr41Wzl6xrv?= =?utf-8?q?dctf+t671OBBkplCCkfBM2fhcCSgm1n8YGSKdpDr3wn+l+fTcVmKCqGbTrpFvXoNk?= =?utf-8?q?9bM43N49/dkaPAecWi/rm5OUakzx/dxtg5pd0UWOkFzsVYayMk0BmN6JBtZWUnN10?= =?utf-8?q?Di+SfGdb6kFLb4MDmLRPMJA/tLo6EUQS6Dt7Bf26S47+dIRvaLMXdMbUqhmhWc6+q?= =?utf-8?q?U56FCiyZv4FGP744CJw0XaoBvoEmYaHxnEpW53Ml2QTHF6ammSu+kYFRapmg7s4/Y?= =?utf-8?q?Vr3J7zC6p2vVAXbmxmOUPbvMW55bOefbtbDreamcNatsPChT1O3NV+UWnK/Bj1DwN?= =?utf-8?q?rtXefbUv+O8UcNZhJ8J29w/Nmx7noRM19fC7/nbM0yXoBesCabBzDLQbSvgwrrppW?= =?utf-8?q?gswIi8IZd9k6PWb5xTfvtkoLxVu0VtXgZnY33CRgWUzzLqXPcLwewNJxiqO11i/6o?= =?utf-8?q?HEIn7lCo8EeaRgtrzmTHfnsjECLWYOIU1EvDm1+PUy7Mls57Pjek7V8NF3GeTVumB?= =?utf-8?q?N82rgqgSnRkJ8nA8gRYb+/0JUqu0V9/Rfkiyn3YfXsG3jPNDrgkDWS0EpX6WPMDV7?= =?utf-8?q?7crwE/jPHaUZ78tCKk6oSHM1XJykc5EIR01WZgig6WPghg2woEr0xLYMYjeOMNzZQ?= =?utf-8?q?YsOcCj75DqjXjujM5bm2YUNJ5VKsZR4RBExyONXm7QTIddDY7P6Og0xetl9CGYN5o?= =?utf-8?q?zIbUuh29Hco6q8H8OxojiUsrvEPbp+4mxJS+REdpHpVzJMHSx5eC2R/YloKnmaPwp?= =?utf-8?q?4jiShfA7v2MIyc+WqQWHEDYj9QUo7aXLwW2JD+saHyWtlYJgrU8xe/JM=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0cd1a394-9e72-45d2-323e-08dca5cd8d36 X-MS-Exchange-CrossTenant-AuthSource: PAXPR04MB9642.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Jul 2024 19:29:03.8596 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 3qB6OGAyCPX0NCdsT+lQ4mU3vLqI75Kau7+GIO9/YJtNZT4qXVv23ix9JCIdB2AKMkP1EsAlpJfrQL8z7EAEaw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1PR04MB7325 From: Haibo Chen Add gpio function support for MFD adp5585. Signed-off-by: Haibo Chen Reviewed-by: Jun Li Signed-off-by: Frank Li --- drivers/gpio/Kconfig | 7 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-adp5585.c | 184 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 58f43bcced7c1..20daa3d70abc7 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1233,6 +1233,13 @@ config GPIO_ADP5520 This option enables support for on-chip GPIO found on Analog Devices ADP5520 PMICs. +config GPIO_ADP5585 + tristate "GPIO Support for ADP5585" + depends on MFD_ADP5585 + help + This option enables support for on-chip GPIO found on Analog + devices ADP5585. + config GPIO_ALTERA_A10SR tristate "Altera Arria10 System Resource GPIO" depends on MFD_ALTERA_A10SR diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 64dd6d9d730d5..1429e8c0229b9 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o +obj-$(CONFIG_GPIO_ADP5585) += gpio-adp5585.o obj-$(CONFIG_GPIO_AGGREGATOR) += gpio-aggregator.o obj-$(CONFIG_GPIO_ALTERA_A10SR) += gpio-altera-a10sr.o obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o diff --git a/drivers/gpio/gpio-adp5585.c b/drivers/gpio/gpio-adp5585.c new file mode 100644 index 0000000000000..7c9edbc16975b --- /dev/null +++ b/drivers/gpio/gpio-adp5585.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * GPIO driver for Analog Devices ADP5585 MFD + * + * Copyright 2024 NXP + */ + +#include +#include +#include +#include +#include +#include +#include + +#define ADP5585_GPIO_MAX 10 + +struct adp5585_gpio_dev { + struct device *parent; + struct gpio_chip gpio_chip; + struct mutex lock; + u8 dat_out[2]; + u8 dir[2]; +}; + +static int adp5585_gpio_reg_read(struct adp5585_gpio_dev *adp5585_gpio, u8 reg, u8 *val) +{ + struct adp5585_dev *adp5585 = dev_get_drvdata(adp5585_gpio->parent); + + return adp5585->read_reg(adp5585, reg, val); +} + +static int adp5585_gpio_reg_write(struct adp5585_gpio_dev *adp5585_gpio, u8 reg, u8 val) +{ + struct adp5585_dev *adp5585 = dev_get_drvdata(adp5585_gpio->parent); + + return adp5585->write_reg(adp5585, reg, val); +} + +static int adp5585_gpio_get_value(struct gpio_chip *chip, unsigned int off) +{ + struct adp5585_gpio_dev *adp5585_gpio; + unsigned int bank, bit; + u8 val; + + adp5585_gpio = gpiochip_get_data(chip); + bank = ADP5585_BANK(off); + bit = ADP5585_BIT(off); + + guard(mutex)(&adp5585_gpio->lock); + + /* There are dedicated registers for GPIO IN/OUT. */ + if (adp5585_gpio->dir[bank] & bit) + val = adp5585_gpio->dat_out[bank]; + else + adp5585_gpio_reg_read(adp5585_gpio, ADP5585_GPI_STATUS_A + bank, &val); + + return !!(val & bit); +} + +static void adp5585_gpio_set_value(struct gpio_chip *chip, unsigned int off, int val) +{ + struct adp5585_gpio_dev *adp5585_gpio; + unsigned int bank, bit; + + adp5585_gpio = gpiochip_get_data(chip); + bank = ADP5585_BANK(off); + bit = ADP5585_BIT(off); + + guard(mutex)(&adp5585_gpio->lock); + + if (val) + adp5585_gpio->dat_out[bank] |= bit; + else + adp5585_gpio->dat_out[bank] &= ~bit; + + adp5585_gpio_reg_write(adp5585_gpio, ADP5585_GPO_DATA_OUT_A + bank, + adp5585_gpio->dat_out[bank]); +} + +static int adp5585_gpio_direction_input(struct gpio_chip *chip, unsigned int off) +{ + struct adp5585_gpio_dev *adp5585_gpio; + unsigned int bank, bit; + int ret; + + adp5585_gpio = gpiochip_get_data(chip); + bank = ADP5585_BANK(off); + bit = ADP5585_BIT(off); + + guard(mutex)(&adp5585_gpio->lock); + + adp5585_gpio->dir[bank] &= ~bit; + ret = adp5585_gpio_reg_write(adp5585_gpio, ADP5585_GPIO_DIRECTION_A + bank, + adp5585_gpio->dir[bank]); + return ret; +} + +static int adp5585_gpio_direction_output(struct gpio_chip *chip, unsigned int off, int val) +{ + struct adp5585_gpio_dev *adp5585_gpio; + unsigned int bank, bit; + int ret; + + adp5585_gpio = gpiochip_get_data(chip); + bank = ADP5585_BANK(off); + bit = ADP5585_BIT(off); + + guard(mutex)(&adp5585_gpio->lock); + + adp5585_gpio->dir[bank] |= bit; + + if (val) + adp5585_gpio->dat_out[bank] |= bit; + else + adp5585_gpio->dat_out[bank] &= ~bit; + + ret = adp5585_gpio_reg_write(adp5585_gpio, ADP5585_GPO_DATA_OUT_A + bank, + adp5585_gpio->dat_out[bank]); + ret |= adp5585_gpio_reg_write(adp5585_gpio, ADP5585_GPIO_DIRECTION_A + bank, + adp5585_gpio->dir[bank]); + + return ret; +} + +static int adp5585_gpio_probe(struct platform_device *pdev) +{ + struct adp5585_gpio_dev *adp5585_gpio; + struct device *dev = &pdev->dev; + struct gpio_chip *gc; + int i; + + adp5585_gpio = devm_kzalloc(&pdev->dev, sizeof(struct adp5585_gpio_dev), GFP_KERNEL); + if (!adp5585_gpio) + return -ENOMEM; + + adp5585_gpio->parent = pdev->dev.parent; + + gc = &adp5585_gpio->gpio_chip; + gc->parent = dev; + gc->direction_input = adp5585_gpio_direction_input; + gc->direction_output = adp5585_gpio_direction_output; + gc->get = adp5585_gpio_get_value; + gc->set = adp5585_gpio_set_value; + gc->can_sleep = true; + + gc->base = -1; + gc->ngpio = ADP5585_GPIO_MAX; + gc->label = pdev->name; + gc->owner = THIS_MODULE; + + mutex_init(&adp5585_gpio->lock); + + for (i = 0; i < 2; i++) { + u8 *dat_out, *dir; + + dat_out = adp5585_gpio->dat_out; + dir = adp5585_gpio->dir; + adp5585_gpio_reg_read(adp5585_gpio, ADP5585_GPO_DATA_OUT_A + i, dat_out + i); + adp5585_gpio_reg_read(adp5585_gpio, ADP5585_GPIO_DIRECTION_A + i, dir + i); + } + + return devm_gpiochip_add_data(&pdev->dev, &adp5585_gpio->gpio_chip, adp5585_gpio); +} + +static const struct of_device_id adp5585_of_match[] = { + {.compatible = "adp5585-gpio", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, adp5585_of_match); + +static struct platform_driver adp5585_gpio_driver = { + .driver = { + .name = "adp5585-gpio", + .of_match_table = adp5585_of_match, + }, + .probe = adp5585_gpio_probe, +}; + +module_platform_driver(adp5585_gpio_driver); + +MODULE_AUTHOR("Haibo Chen "); +MODULE_DESCRIPTION("GPIO ADP5585 Driver"); +MODULE_LICENSE("GPL");