From patchwork Fri Apr 12 05:02:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Packham X-Patchwork-Id: 10897257 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 412D617E0 for ; Fri, 12 Apr 2019 05:02:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D06E928E6F for ; Fri, 12 Apr 2019 05:02:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C4B1128E66; Fri, 12 Apr 2019 05:02:47 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 762A628E5F for ; Fri, 12 Apr 2019 05:02:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726808AbfDLFCm (ORCPT ); Fri, 12 Apr 2019 01:02:42 -0400 Received: from gate2.alliedtelesis.co.nz ([202.36.163.20]:40510 "EHLO gate2.alliedtelesis.co.nz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726616AbfDLFCg (ORCPT ); Fri, 12 Apr 2019 01:02:36 -0400 Received: from mmarshal3.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id 84092891A9; Fri, 12 Apr 2019 17:02:31 +1200 (NZST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1555045351; bh=QRINkbBDwCGpQne78Rboej0Vlek3WXEGOBoch9bHle8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=mNaYYAhNyU0wJZcu0eE/VSARHJKL0qpygbs5JGzbwMRsDz5A6gkw+T4p1Z0gjrGzx RX+oU/cFsT7yG6GAWtXpKbZZp0pK7WYA/P7f1XyyXKmSkyZvPJCcCd6/yyZWwmWJy0 7ESyb/HIhkpKh92hA9ZckGAhPq+J+S0DMN99CxrH/Q5yPHudw0e3ADVKh9HuxPOkGJ Iu9LQzDHntxml1o0ljeNAYFSOWIGxUT7JTg0Poq/eQl0wmUO5O7NoZpsErbeQrHV86 Y7Cj4stvACiveVtk6Dlr/ttuxiJjxjdN5oC8Euz7KxflgYV0/2eJ2TbMUt2et7dGCf fafFJTi1P1ANg== Received: from smtp (Not Verified[10.32.16.33]) by mmarshal3.atlnz.lc with Trustwave SEG (v7,5,8,10121) id ; Fri, 12 Apr 2019 17:02:31 +1200 Received: from chrisp-dl.ws.atlnz.lc (chrisp-dl.ws.atlnz.lc [10.33.22.30]) by smtp (Postfix) with ESMTP id 980F313EEED; Fri, 12 Apr 2019 17:02:26 +1200 (NZST) Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id 5DC551E1D9C; Fri, 12 Apr 2019 17:02:26 +1200 (NZST) From: Chris Packham To: broonie@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com Cc: Hamish Martin , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chris Packham Subject: [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio Date: Fri, 12 Apr 2019 17:02:11 +1200 Message-Id: <20190412050213.17698-2-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190412050213.17698-1-chris.packham@alliedtelesis.co.nz> References: <20190412050213.17698-1-chris.packham@alliedtelesis.co.nz> MIME-Version: 1.0 x-atlnz-ls: pat Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add binding documentation for spi-mux-gpio which is a slightly more complicated hardware implementation of using gpios to steer SPI chip selects. Signed-off-by: Chris Packham --- .../devicetree/bindings/spi/spi-mux-gpio.txt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/spi-mux-gpio.txt diff --git a/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt b/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt new file mode 100644 index 000000000000..a32f25321d37 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt @@ -0,0 +1,45 @@ +SPI bus gpio multiplexer + +The SPI bus gpio multiplexer can be used to implement more complicated access +logic than can be supported with the cs-gpios property of a SPI bus. + +In the example below we have a SoC with a single SPI CS that is gated by the +state of a gpio to select the desired SPI device. + + +----------+ CS +-----+ CS0 +----+ + | |--------| |------| | + | | | \ / | +----+ + | SoC | | + | + | | GPIO | / \ | CS1 +----+ + | |--------| |------| | + +----------+ +-----+ +----+ + +Required properties: +- compatible - must be "spi-mux-gpio" +- gpios - gpios used to implement the multiplexing logic +- spi-parent-bus - parent spi bus to use + +Optional properties: +- spi-parent-cs - chip select on parent bus to use. Defaults to 0 if not + specified. + +Example for a multiplexer with a single gpio: + + spi-mux { + compatible = "spi-mux-gpio"; + #address-cells = <1>; + #size-cells = <0>; + gpios = <&gpio0 1 0>; + spi-parent-bus = <&spi0>; + spi-parent-cs = <0>; + + spi-dev@0 { + compatible = "..."; + reg = <0>; + } + + spi-dev@1 { + compatible = "..."; + reg = <1>; + } + }; From patchwork Fri Apr 12 05:02:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Packham X-Patchwork-Id: 10897259 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E0D2F1708 for ; Fri, 12 Apr 2019 05:02:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BA15F28E30 for ; Fri, 12 Apr 2019 05:02:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AE5C728E6F; Fri, 12 Apr 2019 05:02:58 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 5E65528E30 for ; Fri, 12 Apr 2019 05:02:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726217AbfDLFCs (ORCPT ); Fri, 12 Apr 2019 01:02:48 -0400 Received: from gate2.alliedtelesis.co.nz ([202.36.163.20]:40518 "EHLO gate2.alliedtelesis.co.nz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725788AbfDLFCg (ORCPT ); Fri, 12 Apr 2019 01:02:36 -0400 Received: from mmarshal3.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id A0FFE891AA; Fri, 12 Apr 2019 17:02:31 +1200 (NZST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1555045351; bh=yxYq12tQ+1PP1TKykeYy3zcJNJhG05iavGcQg6WDqvA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=idTs7woZA8gaO6GdWYLx+UWLBJkrq/+1wF7hUh56ub5ZA2ILTbthLdHiN9+0xG8Ez 8eznrZBKl7nsR53+pOXi7Pkh6H0kTJS/r4GcRvfcNOycuNZN2ddqwp8qrXy8G/kF3T ofh3fDHBNlP9Hz3zIxZHfJ7YUW649VTl96f+xs9Nfg16X0MVJiOMdcGRwu2+v6oqrU diFAYlsOz9LnIUAaPfPtWaGmOZCzYfzLiBE6ydEPfKVKolMEPS1o7/I7QGxMGVhoGZ 3MGLgxBcgVVzfGKmZxlaanXV5VTDk05gLU3Vf51fl7wRKtvB8v/YxUywlXhEen2zxS 4taIVqDA+OuuQ== Received: from smtp (Not Verified[10.32.16.33]) by mmarshal3.atlnz.lc with Trustwave SEG (v7,5,8,10121) id ; Fri, 12 Apr 2019 17:02:31 +1200 Received: from chrisp-dl.ws.atlnz.lc (chrisp-dl.ws.atlnz.lc [10.33.22.30]) by smtp (Postfix) with ESMTP id BBBD913EF07; Fri, 12 Apr 2019 17:02:26 +1200 (NZST) Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id 813441E1D9C; Fri, 12 Apr 2019 17:02:26 +1200 (NZST) From: Chris Packham To: broonie@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com Cc: Hamish Martin , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chris Packham Subject: [PATCH 2/3] spi: Make of_find_spi_controller_by_node visible Date: Fri, 12 Apr 2019 17:02:12 +1200 Message-Id: <20190412050213.17698-3-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190412050213.17698-1-chris.packham@alliedtelesis.co.nz> References: <20190412050213.17698-1-chris.packham@alliedtelesis.co.nz> MIME-Version: 1.0 x-atlnz-ls: pat Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Drop the static and add of_find_spi_controller_by_node() to spi.h. Also move it outside of the CONFIG_OF_DYNAMIC so it is available with just CONFIG_OF. Signed-off-by: Chris Packham --- drivers/spi/spi.c | 7 ++++--- include/linux/spi/spi.h | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 93986f879b09..19929163a45b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3531,16 +3531,14 @@ struct spi_device *of_find_spi_device_by_node(struct device_node *node) return dev ? to_spi_device(dev) : NULL; } EXPORT_SYMBOL_GPL(of_find_spi_device_by_node); -#endif /* IS_ENABLED(CONFIG_OF) */ -#if IS_ENABLED(CONFIG_OF_DYNAMIC) static int __spi_of_controller_match(struct device *dev, const void *data) { return dev->of_node == data; } /* the spi controllers are not using spi_bus, so we find it with another way */ -static struct spi_controller *of_find_spi_controller_by_node(struct device_node *node) +struct spi_controller *of_find_spi_controller_by_node(struct device_node *node) { struct device *dev; @@ -3555,7 +3553,10 @@ static struct spi_controller *of_find_spi_controller_by_node(struct device_node /* reference got in class_find_device */ return container_of(dev, struct spi_controller, dev); } +EXPORT_SYMBOL_GPL(of_find_spi_controller_by_node); +#endif /* IS_ENABLED(CONFIG_OF) */ +#if IS_ENABLED(CONFIG_OF_DYNAMIC) static int of_spi_notify(struct notifier_block *nb, unsigned long action, void *arg) { diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 662b336aa2e4..e763290767ea 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1334,6 +1334,8 @@ spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer) extern struct spi_device * of_find_spi_device_by_node(struct device_node *node); +extern struct spi_controller * +of_find_spi_controller_by_node(struct device_node *node); #else static inline struct spi_device * @@ -1342,6 +1344,11 @@ of_find_spi_device_by_node(struct device_node *node) return NULL; } +static inline struct spi_controller * +of_find_spi_controller_by_node(struct device_node *node) +{ + return NULL; +} #endif /* IS_ENABLED(CONFIG_OF) */ /* Compatibility layer */ From patchwork Fri Apr 12 05:02:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Packham X-Patchwork-Id: 10897255 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4AE9717EF for ; Fri, 12 Apr 2019 05:02:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0052B28E66 for ; Fri, 12 Apr 2019 05:02:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F255128E71; Fri, 12 Apr 2019 05:02:47 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 973B628E6C for ; Fri, 12 Apr 2019 05:02:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726872AbfDLFCm (ORCPT ); Fri, 12 Apr 2019 01:02:42 -0400 Received: from gate2.alliedtelesis.co.nz ([202.36.163.20]:40525 "EHLO gate2.alliedtelesis.co.nz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726864AbfDLFCm (ORCPT ); Fri, 12 Apr 2019 01:02:42 -0400 Received: from mmarshal3.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id 2B616806AC; Fri, 12 Apr 2019 17:02:40 +1200 (NZST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1555045360; bh=Yj4l5iuapC5k0UM5N1OpYfHCl3S6iRN277AqHe6RClw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bo4a9rzrS5yv/AvMBfPWyjQgUsp/MuWa5fKVg+BBgEM281BSvqwAh2ZNBXr/HAezV SBUU7LXdXBc5T/ru6X1bAwtS0qR3sC0YJ2m5Rk9k1KrEVpvvm5rCqGqbAkU5/xW00V CaqcTwr51lgLCjI58+nor4cdK+SUii5xTXHo4vdt80tjrd0Jmm+CFNSF6wCVfi/EA5 RVlFRwUxQcIMNDDvhQFeGI/PTUeZL982GQxNn3qNaxDoovEUYc1ZQcunCSKIiaWd8/ 9Y+TB8VGiLoDgo0bVa1EKD46phrZLb09tbAu2RrRcSpTqyTX70OTpXVT5fx+DHBI3R +X9uxzzGMVHyA== Received: from smtp (Not Verified[10.32.16.33]) by mmarshal3.atlnz.lc with Trustwave SEG (v7,5,8,10121) id ; Fri, 12 Apr 2019 17:02:31 +1200 Received: from chrisp-dl.ws.atlnz.lc (chrisp-dl.ws.atlnz.lc [10.33.22.30]) by smtp (Postfix) with ESMTP id F0F3A13EF97; Fri, 12 Apr 2019 17:02:26 +1200 (NZST) Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id B67A21E1D9C; Fri, 12 Apr 2019 17:02:26 +1200 (NZST) From: Chris Packham To: broonie@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com Cc: Hamish Martin , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chris Packham Subject: [PATCH 3/3] spi: Add SPI bus gpio multiplexer Date: Fri, 12 Apr 2019 17:02:13 +1200 Message-Id: <20190412050213.17698-4-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190412050213.17698-1-chris.packham@alliedtelesis.co.nz> References: <20190412050213.17698-1-chris.packham@alliedtelesis.co.nz> MIME-Version: 1.0 x-atlnz-ls: pat Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This add support for a gpio based multiplexer for SPI buses. This can be used in situations where the cs-gpios property does not work with the hardware design. In particular this support situations where a single gpio is used to select between two possible devices. Signed-off-by: Chris Packham --- drivers/spi/Kconfig | 7 ++ drivers/spi/Makefile | 1 + drivers/spi/spi-mux-gpio.c | 169 +++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 drivers/spi/spi-mux-gpio.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f761655e2a36..bfb4bd5bc2f3 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -426,6 +426,13 @@ config SPI_MT65XX say Y or M here.If you are not sure, say N. SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs. +config SPI_MUX_GPIO + tristate "SPI bus gpio multiplexer" + help + This selects the SPI bus gpio multiplexer. + If you have a hardware design that requires multiplexing + on the SPI bus say Y or M here. If you are not sure, say N. + config SPI_NPCM_PSPI tristate "Nuvoton NPCM PSPI Controller" depends on ARCH_NPCM || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index d8fc03c9faa2..32d831374e1f 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o obj-$(CONFIG_SPI_MXIC) += spi-mxic.o obj-$(CONFIG_SPI_MXS) += spi-mxs.o +obj-$(CONFIG_SPI_MUX_GPIO) += spi-mux-gpio.o obj-$(CONFIG_SPI_NPCM_PSPI) += spi-npcm-pspi.o obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o obj-$(CONFIG_SPI_NXP_FLEXSPI) += spi-nxp-fspi.o diff --git a/drivers/spi/spi-mux-gpio.c b/drivers/spi/spi-mux-gpio.c new file mode 100644 index 000000000000..3666863a4e3f --- /dev/null +++ b/drivers/spi/spi-mux-gpio.c @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Allied Telesis + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct spi_mux_gpio { + struct gpio_descs *gpios; + struct spi_controller *ctlr; + struct spi_controller *parent_ctlr; + int chip_select; +}; + +static void spi_mux_set_cs(struct spi_device *spi, bool enable) +{ + DECLARE_BITMAP(values, BITS_PER_TYPE(spi->chip_select)); + struct spi_mux_gpio *mux = spi_master_get_devdata(spi->controller); + struct spi_device spidev = *spi; + + values[0] = spi->chip_select; + + gpiod_set_array_value_cansleep(mux->gpios->ndescs, + mux->gpios->desc, + mux->gpios->info, values); + + spidev.controller = mux->parent_ctlr; + spidev.master = mux->parent_ctlr; + spidev.chip_select = mux->chip_select; + + mux->parent_ctlr->set_cs(&spidev, enable); +} + +static int spi_mux_transfer_one(struct spi_controller *ctlr, + struct spi_device *spi, + struct spi_transfer *transfer) +{ + struct spi_mux_gpio *mux = spi_master_get_devdata(ctlr); + struct spi_device spidev = *spi; + + spidev.controller = mux->parent_ctlr; + spidev.master = mux->parent_ctlr; + spidev.chip_select = mux->chip_select; + + return mux->parent_ctlr->transfer_one(mux->parent_ctlr, &spidev, transfer); + +} + +static int spi_mux_setup(struct spi_device *spi) +{ + struct spi_mux_gpio *mux = spi_master_get_devdata(spi->controller); + struct spi_device spidev = *spi; + + spidev.controller = mux->parent_ctlr; + spidev.master = mux->parent_ctlr; + spidev.chip_select = mux->chip_select; + + return mux->parent_ctlr->setup(&spidev); +} + +static int spi_mux_gpio_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device_node *parent; + struct spi_controller *parent_ctlr; + struct spi_controller *ctlr; + struct spi_mux_gpio *mux; + struct gpio_descs *gpios; + int ret; + + gpios = devm_gpiod_get_array(&pdev->dev, NULL, GPIOD_OUT_LOW); + if (IS_ERR(gpios)) + return PTR_ERR(gpios); + + parent = of_parse_phandle(np, "spi-parent-bus", 0); + if (!parent) + return -ENODEV; + + parent_ctlr = of_find_spi_controller_by_node(parent); + if (!parent_ctlr) { + ret = -EPROBE_DEFER; + goto err_put_node; + } + + ctlr = spi_alloc_master(&pdev->dev, sizeof(*mux)); + if (!ctlr) { + ret = -ENOMEM; + goto err_put_device; + } + mux = spi_master_get_devdata(ctlr); + platform_set_drvdata(pdev, mux); + + ctlr->mode_bits = parent_ctlr->mode_bits; + ctlr->bits_per_word_mask = parent_ctlr->bits_per_word_mask; + ctlr->auto_runtime_pm = parent_ctlr->auto_runtime_pm; + ctlr->flags = parent_ctlr->flags; + ctlr->set_cs = spi_mux_set_cs; + ctlr->transfer_one = spi_mux_transfer_one; + ctlr->setup = spi_mux_setup; + ctlr->num_chipselect = of_get_available_child_count(np); + ctlr->bus_num = -1; + + mux->gpios = gpios; + mux->ctlr = ctlr; + mux->parent_ctlr = parent_ctlr; + ret = of_property_read_u32(np, "spi-parent-cs", + &mux->chip_select); + if (ret) + mux->chip_select = 0; + + ctlr->dev.of_node = np; + ret = devm_spi_register_controller(&pdev->dev, ctlr); + if (ret) { + dev_err(&pdev->dev, "Error: failed to register SPI bus %pOF %d\n", + np, ret); + goto err_put_ctlr; + } + + return 0; + +err_put_ctlr: + spi_controller_put(ctlr); +err_put_device: + put_device(&parent_ctlr->dev); +err_put_node: + of_node_put(parent); + + return ret; +} + +static int spi_mux_gpio_remove(struct platform_device *pdev) +{ + struct spi_mux_gpio *mux = platform_get_drvdata(pdev); + + spi_controller_put(mux->ctlr); + put_device(&mux->parent_ctlr->dev); + + return 0; +} + +static const struct of_device_id spi_mux_gpio_of_match[] = { + { .compatible = "spi-mux-gpio", }, + {}, +}; +MODULE_DEVICE_TABLE(of, spi_mux_gpio_of_match); + +static struct platform_driver spi_mux_gpio_driver = { + .probe = spi_mux_gpio_probe, + .remove = spi_mux_gpio_remove, + .driver = { + .name = "spi-mux-gpio", + .of_match_table = spi_mux_gpio_of_match, + }, +}; + +module_platform_driver(spi_mux_gpio_driver); + +MODULE_DESCRIPTION("SPI bus mutliplexer driver"); +MODULE_AUTHOR("Allied Telesis"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:spi-mux-gpio");