From patchwork Tue Dec 6 12:44:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Edmund Berenson X-Patchwork-Id: 30268 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2801156wrr; Tue, 6 Dec 2022 04:53:25 -0800 (PST) X-Google-Smtp-Source: AA0mqf7B0o5doJwleAag5a9SrEZKAulaZvQZCV9d/RBw75cE1XGEihqiFnn6Zsjy26Nthg4wNixs X-Received: by 2002:a17:906:78b:b0:7c0:e813:e07e with SMTP id l11-20020a170906078b00b007c0e813e07emr8896502ejc.156.1670331205193; Tue, 06 Dec 2022 04:53:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670331205; cv=none; d=google.com; s=arc-20160816; b=YBgnzzQYtqYfUgDqQOwXJAl8rE8Xu+Xdq2pjAyZSnoptcyNjPaduATPiSN2gTQb3s6 B5Gfs4qmnb8eIAKZGbcA38GccMMIxaCIFSvlPGtLKk33r/zIr6yUk5R+etBeBcKOYjgE B9ZUhI95Ldy+GdncYx1CmwPblsaiJS6C/X0qsWl/9+835FW0pnlpAPNst+2eMpp/Z31Z nvqjhrtsU376rjdeYiVwkpxjWoWSyAbACrw6/UI7DFHlZmnQkeJPQoeTINLNxpMIO01g oPrcSG4fj6izmdg4tUNBMgWYP4vxUifG2pLEVnu7Rg5C13QyqAZexGGr50jTk7zkfMGQ j7Tw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:content-transfer-encoding:mime-version :message-id:date:subject:cc:from; bh=r7PYxuObWMqBZ8zea/C7QJJGYh59QmnbXobbHsZyHyE=; b=t3mfugK9Op5mkU2hBhzRsuqMQClKhhP7rDTKYUidUrj7TJKu+Zn9//VSvi260hUyDQ 5qIpNC+8HzV8IftV+usZmbsnHGpgRb4H1LiUPOZCinJhGQRdpiFjfBqq0O9XS8VKAHqn mlFnzX4ZjrlikduBNNA3AHYS+E7m38D7obmgXNATAWlTyJN8x8NOhKqrGbtBXC2McSYl bHb1XFqTHRNIr8TMkB4NXr9wD4Ys5EPgcd1SAk16ICdTOJ7YAgzziBL4AKZbgxtlISLO AFxKMwgrBeQHyw6as0Pv0+4nbU1Vtx1PCXBx349NakYeupn7t66PVLBRYk0NwYiSKyVr kyNw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d29-20020a50f69d000000b00453688643fasi1770944edn.260.2022.12.06.04.53.01; Tue, 06 Dec 2022 04:53:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234261AbiLFMwO (ORCPT + 99 others); Tue, 6 Dec 2022 07:52:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233978AbiLFMwJ (ORCPT ); Tue, 6 Dec 2022 07:52:09 -0500 X-Greylist: delayed 405 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Tue, 06 Dec 2022 04:52:07 PST Received: from mx1.emlix.com (mx1.emlix.com [136.243.223.33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A8EAE00D; Tue, 6 Dec 2022 04:52:07 -0800 (PST) Received: from mailer.emlix.com (p5098be52.dip0.t-ipconnect.de [80.152.190.82]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.emlix.com (Postfix) with ESMTPS id 9689D60725; Tue, 6 Dec 2022 13:45:18 +0100 (CET) From: Edmund Berenson Cc: Edmund Berenson , Lukasz Zemla , Linus Walleij , Bartosz Golaszewski , Rob Herring , Krzysztof Kozlowski , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] dt-bindings: gpio: max7317: add gpio driver bindings Date: Tue, 6 Dec 2022 13:44:55 +0100 Message-Id: <20221206124456.4159-1-edmund.berenson@emlix.com> X-Mailer: git-send-email 2.37.4 MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net To: unlisted-recipients:; (no To-header on input) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1751469214130190449?= X-GMAIL-MSGID: =?utf-8?q?1751469214130190449?= Add driver bindings for the maxim max7317 spi gpio expander. Co-developed-by: Lukasz Zemla Signed-off-by: Lukasz Zemla Signed-off-by: Edmund Berenson --- .../bindings/gpio/gpio-max7317.yaml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-max7317.yaml diff --git a/Documentation/devicetree/bindings/gpio/gpio-max7317.yaml b/Documentation/devicetree/bindings/gpio/gpio-max7317.yaml new file mode 100644 index 000000000000..88f1fe02a627 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-max7317.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/gpio-max7317.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX7317 SPI-Interfaced I/O Expander + +description: | + Bindings for 10-Port Maxim MAX7317 SPI GPIO expanders. + +properties: + compatible: + const: maxim,max7317 + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + + gpio-line-names: + minItems: 1 + maxItems: 10 + +required: + - compatible + - reg + - gpio-controller + - "#gpio-cells" + +additionalProperties: false + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + gpio5: gpio5@0 { + compatible = "maxim,max7317"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + spi-max-frequency = <100000>; + }; + }; From patchwork Tue Dec 6 12:45:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Edmund Berenson X-Patchwork-Id: 30269 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2801216wrr; Tue, 6 Dec 2022 04:53:35 -0800 (PST) X-Google-Smtp-Source: AA0mqf4ilFbXksM2xQ9dA6kiacpOJSQ51PRllaqqNMt6e6jk+YCP4EMdIB5fmlo1aofGXtcHyxyZ X-Received: by 2002:a17:906:a983:b0:7b8:31b1:b23f with SMTP id jr3-20020a170906a98300b007b831b1b23fmr56272318ejb.591.1670331215183; Tue, 06 Dec 2022 04:53:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670331215; cv=none; d=google.com; s=arc-20160816; b=YKZiNoHmYGvi0mviKD8JfqgkZhPd/gHv/YGGEMe13B4oq/QwNRhihhu+4g6kkSV48a sM/g65CVAaI327HgcaIB474QoMYY0vjm+UWaaf3nsISK9y8dhbhnNRKDgwhQpIDwS3fl euGuHtN3Aw0dCJ0T/yfGa9iNGTsKnP3w/vZ7GGOmApEeY6erSprid/gS0Dpp/ViRsnN2 GRdNuo+M9SSzvtv4C28LzKfpH1w51tG+6tUwvnu7ddbbaZXPHTUHb+MA+JpdoaiFpx2J LB28E19z94lTS8jiBvFDdAGLS1x6Ed0qqN+BX1aSrX/loCMmbWvqKximLZwWDNoCpt5D Kbow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:content-transfer-encoding:mime-version :message-id:date:subject:cc:from; bh=81boVyoOQ6fo2301HPdn+zc+iBKKxHM9qHhJax+aNxg=; b=NGbQBSQ47o5R3sAtsK76aAI2C4P6ydkoAyMTAVRR8RqEzR1qIL/oGLa1Nb4nIiJnxA nwEYakX2SYlT78b8oY5Zb0eXMvxxf+348jzRGiJV/lS2MumUBGvtzsvuSX7NNKMY1mI6 j6+L2O2psFj85tUTaMUmU/Suaavl5AKAadh3IOMqoq/BPPqj+Tq0EjZeQCqdHMnJge5C 45UlpMmOYN0IQlRk+lbNuZ7rPMao0ALVqbq/WCZMpBotlkSm/F+v/hHq/b24YGWHxylD 8iHaCKt0locvrz/+bI2d7wdhNPEXGnGngjTPhenyYxS5CPhGDeVMvHA43aDS1gzoglMP FvHA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i16-20020a1709064fd000b007b29ccd79c0si2576320ejw.590.2022.12.06.04.53.10; Tue, 06 Dec 2022 04:53:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233978AbiLFMwa (ORCPT + 99 others); Tue, 6 Dec 2022 07:52:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234131AbiLFMw1 (ORCPT ); Tue, 6 Dec 2022 07:52:27 -0500 Received: from mx1.emlix.com (mx1.emlix.com [136.243.223.33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9FCC215A29; Tue, 6 Dec 2022 04:52:21 -0800 (PST) Received: from mailer.emlix.com (p5098be52.dip0.t-ipconnect.de [80.152.190.82]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.emlix.com (Postfix) with ESMTPS id 78B0A60730; Tue, 6 Dec 2022 13:45:37 +0100 (CET) From: Edmund Berenson Cc: Edmund Berenson , Lukasz Zemla , Linus Walleij , Bartosz Golaszewski , linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH 2/2] gpio: max7317: Add gpio expander driver Date: Tue, 6 Dec 2022 13:45:28 +0100 Message-Id: <20221206124530.5431-1-edmund.berenson@emlix.com> X-Mailer: git-send-email 2.37.4 MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net To: unlisted-recipients:; (no To-header on input) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1751469224225252131?= X-GMAIL-MSGID: =?utf-8?q?1751469224225252131?= Add driver for maxim MAX7317 SPI-Interfaced 10 Port GPIO Expander. Co-developed-by: Lukasz Zemla Signed-off-by: Lukasz Zemla Signed-off-by: Edmund Berenson --- drivers/gpio/Kconfig | 8 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-max7317.c | 221 ++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 drivers/gpio/gpio-max7317.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index a01af1180616..24ed968a2b7f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1622,6 +1622,14 @@ config GPIO_MAX7301 help GPIO driver for Maxim MAX7301 SPI-based GPIO expander. +config GPIO_MAX7317 + tristate "Maxim MAX7317 GPIO expander" + depends on SPI + help + GPIO driver for Maxim MAX7317 SPI-based GPIO expander. + The MAX7317 is a serial-interfaced gpio extender, with + 10 ports. + config GPIO_MC33880 tristate "Freescale MC33880 high-side/low-side switch" help diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 29e3beb6548c..edbfb3d918ce 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -89,6 +89,7 @@ obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o +obj-$(CONFIG_GPIO_MAX7317) += gpio-max7317.o obj-$(CONFIG_GPIO_MAX77620) += gpio-max77620.o obj-$(CONFIG_GPIO_MAX77650) += gpio-max77650.o obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o diff --git a/drivers/gpio/gpio-max7317.c b/drivers/gpio/gpio-max7317.c new file mode 100644 index 000000000000..58b66f763beb --- /dev/null +++ b/drivers/gpio/gpio-max7317.c @@ -0,0 +1,221 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021, Lukasz Zemla, Woodward Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* MAX7317 has 10 pins, controlled by 10 internal registers, + * addressed as 0x00 - 0x09. + */ +#define PIN_NUMBER 10 + +/* Register code to read inputs from 7 to 0 */ +#define REG_CODE_READ_PORTS_7_TO_0 ((u8)0x0E) +/* Register code to read inputs from 9 to 8 */ +#define REG_CODE_READ_PORTS_9_TO_8 ((u8)0x0F) + +struct max7317 { + struct mutex lock; + struct gpio_chip chip; + struct device *dev; +}; + +struct max7317_platform_data { + /* number assigned to the first GPIO */ + unsigned int gpio_base; +}; + +/* A write to the MAX7317 means one message with one transfer */ +static int max7317_spi_write(struct device *dev, unsigned int reg, + unsigned int val) +{ + struct spi_device *spi = to_spi_device(dev); + u16 word = ((reg & 0x7F) << 8) | (val & 0xFF); + + return spi_write_then_read(spi, &word, sizeof(word), NULL, 0); +} + +/* A read from the MAX7317 means two transfers, with chip select going high between them. */ +static int max7317_spi_read(struct device *dev, unsigned int reg) +{ + int ret; + u16 word; + struct spi_device *spi = to_spi_device(dev); + + word = 0x8000 | (reg << 8); + + /* First transfer: ask to read register */ + ret = spi_write(spi, &word, sizeof(word)); + if (ret) + return ret; + + /* Second transfer: read register value */ + ret = spi_read(spi, &word, sizeof(word)); + if (ret) + return ret; + + return word & 0xff; +} + +static void max7317_set(struct gpio_chip *chip, unsigned int offset, int value) +{ + struct max7317 *ts = gpiochip_get_data(chip); + + mutex_lock(&ts->lock); + max7317_spi_write(ts->dev, offset, value); + mutex_unlock(&ts->lock); +} + +static int max7317_get(struct gpio_chip *chip, unsigned int offset) +{ + struct max7317 *ts = gpiochip_get_data(chip); + unsigned int reg, val, mask, shift; + int inputs; + + if (offset < 8) { + reg = REG_CODE_READ_PORTS_7_TO_0; + mask = 1u << offset; + shift = offset; + } else { + reg = REG_CODE_READ_PORTS_9_TO_8; + mask = 1u << (offset - 8); + shift = offset - 8; + } + + mutex_lock(&ts->lock); + inputs = max7317_spi_read(ts->dev, reg); + mutex_unlock(&ts->lock); + + val = ((unsigned int)inputs & mask) >> shift; + + return (int)val; +} + +static int max7317_direction_input(struct gpio_chip *chip, unsigned int offset) +{ + /* Per documentation: + * 'Configure a port as an input by setting its output register to 0x01, + * which sets the port output high impedance (Table 4). + */ + max7317_set(chip, offset, 1); + return 0; +} + +static int max7301_direction_output(struct gpio_chip *chip, unsigned int offset, + int value) +{ + max7317_set(chip, offset, value); + return 0; +} + +static int max7317_probe(struct spi_device *spi) +{ + struct max7317 *ts; + struct device *dev; + struct max7317_platform_data *pdata; + int ret; + + /* bits_per_word cannot be configured in platform data */ + spi->bits_per_word = 16; + ret = spi_setup(spi); + if (ret < 0) + return ret; + + ts = devm_kzalloc(&spi->dev, sizeof(struct max7317), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + ts->dev = &spi->dev; + + dev = ts->dev; + + pdata = dev_get_platdata(dev); + + mutex_init(&ts->lock); + dev_set_drvdata(dev, ts); + + if (pdata) + ts->chip.base = pdata->gpio_base; + else + ts->chip.base = -1; + + ts->chip.label = dev->driver->name; + + ts->chip.direction_input = max7317_direction_input; + ts->chip.get = max7317_get; + ts->chip.direction_output = max7301_direction_output; + ts->chip.set = max7317_set; + + ts->chip.ngpio = PIN_NUMBER; + ts->chip.can_sleep = true; + ts->chip.parent = dev; + ts->chip.owner = THIS_MODULE; + + ret = gpiochip_add_data(&ts->chip, ts); + if (!ret) + return ret; + + mutex_destroy(&ts->lock); + return ret; +} + +static void max7317_remove(struct spi_device *spi) +{ + struct max7317 *ts = dev_get_drvdata(&spi->dev); + + if (!ts) + return; + + gpiochip_remove(&ts->chip); + mutex_destroy(&ts->lock); +} + +static const struct spi_device_id max7317_id[] = { + { "max7317", 0 }, + { } +}; +MODULE_DEVICE_TABLE(spi, max7317_id); + +static const struct of_device_id max7317_of_table[] = { + { .compatible = "maxim,max7317" }, + { } +}; +MODULE_DEVICE_TABLE(of, max7317_of_table); + +static struct spi_driver max7317_driver = { + .driver = { + .name = "max7317", + .of_match_table = of_match_ptr(max7317_of_table), + }, + .probe = max7317_probe, + .remove = max7317_remove, + .id_table = max7317_id, +}; + +static int __init max7317_init(void) +{ + return spi_register_driver(&max7317_driver); +} +/* register after spi postcore initcall and before + * subsys initcalls that may rely on these GPIOs + */ +subsys_initcall(max7317_init); + +static void __exit max7317_exit(void) +{ + spi_unregister_driver(&max7317_driver); +} +module_exit(max7317_exit); + +MODULE_AUTHOR("Lukasz Zemla"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MAX7317 GPIO-Expander");