From patchwork Thu Feb 25 16:42:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387905 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 BBEC9C433E9 for ; Thu, 25 Feb 2021 16:43:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8213264F21 for ; Thu, 25 Feb 2021 16:43:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232203AbhBYQnK (ORCPT ); Thu, 25 Feb 2021 11:43:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232608AbhBYQnD (ORCPT ); Thu, 25 Feb 2021 11:43:03 -0500 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA990C061756; Thu, 25 Feb 2021 08:42:22 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id w11so5881849wrr.10; Thu, 25 Feb 2021 08:42:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=6hkW7suAFaiZeM1Sy2O+nOrhjHJ//Jazavsp18uR06g=; b=bTQ8tD9pyBtMGdRKw1hpKtPzxgymaWzL+Qa39SWbrBdBQLpsGE7auUAW8dq/keKv0w psKKoRmdOPK8KQan5GB6UEktHOUZ9B4DElyNTEMMWzXoe0HAWI16TGdmG6zuA6Zr8Ljc 3gdkwTPZTdVfnIq8zlEKsJxOKJytZd0aolrjl8FrYSePi3C+6wyawq7758jyaCpvSn/9 FkalpJlFIPYYolSr/AWdJGWT9tib52bNfH/0GNMBe3gXrTiaZtHyhD9gUMCNqOeED2Aa gDjkef8NmMumLwe5VzqMUWUXK9tjjrwNK1ogEUrCgAlMh6Vqf9deZfq0oykY6d2nFWtv i8xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6hkW7suAFaiZeM1Sy2O+nOrhjHJ//Jazavsp18uR06g=; b=LEq+OZY4HDy0FYwAlcMetTuenxpSWPllbOYgi3unDPLyKjA9jC812iV7tw5Va5AHzy Cu23Yb+bbHwPEO/7D3Lnsi8S1RPPV23E57T6UPVqZ5yrxqk56MVLwv6vNUc59jX6olCI IykTgA06mizpzGP6DjLZ+J0UAC0RGwwZ4lcZ1StN+buJehdmh1MB/4K98FjBUeAhXwuX 5qzRRodGvGw8Gr6vEzfS3rCIsms0pXRYcS9z/9N5Yxc+YfVjaviGusxQO5BXIdkQq9QK Rg6uHkemFy8DPter2Mv3IFKz6bw4N5xZGvwVYXz0JT8g9R+8ljpTbJxOBQILEJYqbE8b TLZw== X-Gm-Message-State: AOAM530/T9XMtfFMQ1IgOPdXViJsNPF3w2k1Bi6LTOn/a2Z6OslHLiSl 2xbJVKmA2/zQrVBKu7FTNEE= X-Google-Smtp-Source: ABdhPJzwrc01FSwP8z5Pq6c2DBJ4qWy2VGrbpKITZXCi3BLT5ysP8NLOU0P/irwKtAnnGv+00ZHGkQ== X-Received: by 2002:a05:6000:186f:: with SMTP id d15mr4477392wri.237.1614271340512; Thu, 25 Feb 2021 08:42:20 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:20 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 01/12] Documentation: add BCM6328 pincontroller binding documentation Date: Thu, 25 Feb 2021 17:42:05 +0100 Message-Id: <20210225164216.21124-2-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add binding documentation for the pincontrol core found in BCM6328 SoCs. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- .../pinctrl/brcm,bcm6328-pinctrl.yaml | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml new file mode 100644 index 000000000000..2012cb1dbf5c --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml @@ -0,0 +1,161 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6328 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: |+ + The pin controller node should be the child of a syscon node. + + Refer to the bindings described in + Documentation/devicetree/bindings/mfd/syscon.yaml + +properties: + compatible: + const: brcm,bcm6328-pinctrl + + gpio-controller: true + + '#gpio-cells': + description: + Specifies the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + interrupts-extended: + description: + One interrupt per each of the 4 GPIO ports supported by the controller, + sorted by port number ascending order. + minItems: 4 + maxItems: 4 + +patternProperties: + '^.*$': + if: + type: object + then: + properties: + function: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq, + led, ephy0_act_led, ephy1_act_led, ephy2_act_led, + ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ] + + pins: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19, + gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1, + usb_port1 ] + +required: + - compatible + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +examples: + - | + gpio@10000080 { + compatible = "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + + pinctrl: pinctrl { + compatible = "brcm,bcm6328-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc 3 0>, + <&ext_intc 2 0>, + <&ext_intc 1 0>, + <&ext_intc 0 0>; + interrupt-names = "gpio12", + "gpio15", + "gpio23", + "gpio24"; + + pinctrl_serial_led: serial_led { + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led { + function = "inet_act_led"; + pins = "gpio11"; + }; + + pinctrl_pcie_clkreq: pcie_clkreq { + function = "pcie_clkreq"; + pins = "gpio16"; + }; + + pinctrl_ephy0_spd_led: ephy0_spd_led { + function = "led"; + pins = "gpio17"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led { + function = "led"; + pins = "gpio18"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led { + function = "led"; + pins = "gpio19"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led { + function = "led"; + pins = "gpio20"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led { + function = "ephy0_act_led"; + pins = "gpio25"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led { + function = "ephy1_act_led"; + pins = "gpio26"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led { + function = "ephy2_act_led"; + pins = "gpio27"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led { + function = "ephy3_act_led"; + pins = "gpio28"; + }; + + pinctrl_hsspi_cs1: hsspi_cs1 { + function = "hsspi_cs1"; + pins = "hsspi_cs1"; + }; + + pinctrl_usb_port1_device: usb_port1_device { + function = "usb_device_port"; + pins = "usb_port1"; + }; + + pinctrl_usb_port1_host: usb_port1_host { + function = "usb_host_port"; + pins = "usb_port1"; + }; + }; + }; From patchwork Thu Feb 25 16:42:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387430 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 4E34FC433E6 for ; Thu, 25 Feb 2021 16:43:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0AC1164F03 for ; Thu, 25 Feb 2021 16:43:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233077AbhBYQnJ (ORCPT ); Thu, 25 Feb 2021 11:43:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232588AbhBYQnD (ORCPT ); Thu, 25 Feb 2021 11:43:03 -0500 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8EB8FC06174A; Thu, 25 Feb 2021 08:42:22 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id i9so4867773wml.0; Thu, 25 Feb 2021 08:42:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=+3P3GdthYLepHoOKDe71ONHgmsqcMTg0LEDKKo0meIo=; b=sY+PMmDrM47fDUq6Bn86SlcJcMV5oBsARNqwDYlGHq9OnANXdmlu0Xy/ZPUyxjHHXr l/m9mFKubpWsrB2OHagTLFipq2n3vJ4NxJOPy5O6OGbcSEvxaetMSkm+wpNU63GIMhDx qyGWwcpZRA9aZwvjZREtfGiRI0TBlzSD7EThildWnyPGsxpUSu/vVNqm5UmNgiBhztV8 7wd8L0QaHnDqS3g0aiGN9zY6mVQmv87n0xqkw2le1L1+/VKhbrilXa08ryipJhda43NN 2C4PGHekxCu6rmJcTBlCs4rPKg/zvqoAACbnp8FMwATbMJ1zDkcPDbHgvTfboBbfqUFj GI3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+3P3GdthYLepHoOKDe71ONHgmsqcMTg0LEDKKo0meIo=; b=Gea7ziZRFM9jhu3MAgYST5N4Qj1frna5omnTOp98XKXh/UTzbY/4bcsSfUL97DrhPe n6so00uuza+JPOEPmJpDtJ6YcI9LcmO8vvr5KYovQa2KYDkQFucNLd5YiMm7I/iI8F/p 8PKusrVQxqpo2mea19xFaWEiPUmILoqQ6kTh+fleIjVavyGDmw/BySFPopBS5/c9Ipze JQeyZ5v0+h5/PmoknpJM8kClusxAaMYccpjx0bAzGdn5Cl5R+FokT5aV0Y5SCs0OlAZs GpJVShkxyn/unbbB5w6LN6YUSbipNlhtdqB3Iv2gKUTxATRGHjc5kqa4UZ4W8tv394qI NAzg== X-Gm-Message-State: AOAM5339mWTJ8PNw7ovnuX2TKSVl11ce0EMCWSUFecXfEvIDw/XF24i5 ki2ACG94cTVXXYCIjUyBZQ4= X-Google-Smtp-Source: ABdhPJyVb9zY5I6apgQVI2/e3nQ5H4Vx6ZpytVbgSCEGMQfpQNS/qLS4RQmKzKBOTFOc8K6tAYAOiQ== X-Received: by 2002:a7b:cc0c:: with SMTP id f12mr3086841wmh.137.1614271341237; Thu, 25 Feb 2021 08:42:21 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:21 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 02/12] pinctrl: add a pincontrol driver for BCM6328 Date: Thu, 25 Feb 2021 17:42:06 +0100 Message-Id: <20210225164216.21124-3-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as GPIOs, as LEDs for the integrated LED controller, or various other functions. Its pincontrol mux registers also control other aspects, like switching the second USB port between host and device mode. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- drivers/pinctrl/bcm/Kconfig | 11 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6328.c | 581 ++++++++++++++++++++++++++ 3 files changed, 593 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 0ed14de0134c..4c6e41cf7a32 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -29,6 +29,17 @@ config PINCTRL_BCM2835 help Say Y here to enable the Broadcom BCM2835 GPIO driver. +config PINCTRL_BCM6328 + bool "Broadcom BCM6328 GPIO driver" + depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) + select PINMUX + select PINCONF + select GENERIC_PINCONF + select MFD_SYSCON + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6328 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 79d5e49fdd9a..7e7c6e25b26d 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o +obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6328.c b/drivers/pinctrl/bcm/pinctrl-bcm6328.c new file mode 100644 index 000000000000..0b1e45145fdd --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c @@ -0,0 +1,581 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6328 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define MODULE_NAME "bcm6328-pinctrl" +#define BCM6328_NUM_GPIOS 32 + +#define BANK_SIZE sizeof(uint32_t) +#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) + +#define BCM6328_DIROUT_REG 0x04 +#define BCM6328_DATA_REG 0x0c +#define BCM6328_MODE_REG 0x18 +#define BCM6328_MUX_HI_REG 0x1c +#define BCM6328_MUX_LO_REG 0x20 +#define BCM6328_MUX_OTHER_REG 0x24 + +struct bcm6328_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6328_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned mode_val:1; + unsigned mux_val:2; +}; + +struct bcm6328_pinctrl { + struct device *dev; + struct regmap *regs; + + struct pinctrl_dev *pctl_dev; + struct gpio_chip gpio_chip; + struct pinctrl_desc pctl_desc; + struct pinctrl_gpio_range gpio_range; +}; + +static const struct pinctrl_pin_desc bcm6328_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + + /* + * No idea where they really are; so let's put them according + * to their mux offsets. + */ + PINCTRL_PIN(36, "hsspi_cs1"), + PINCTRL_PIN(38, "usb_p2"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; + +static unsigned hsspi_cs1_pins[] = { 36 }; +static unsigned usb_port1_pins[] = { 38 }; + +#define BCM6328_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6328_pingroup bcm6328_groups[] = { + BCM6328_GROUP(gpio0), + BCM6328_GROUP(gpio1), + BCM6328_GROUP(gpio2), + BCM6328_GROUP(gpio3), + BCM6328_GROUP(gpio4), + BCM6328_GROUP(gpio5), + BCM6328_GROUP(gpio6), + BCM6328_GROUP(gpio7), + BCM6328_GROUP(gpio8), + BCM6328_GROUP(gpio9), + BCM6328_GROUP(gpio10), + BCM6328_GROUP(gpio11), + BCM6328_GROUP(gpio12), + BCM6328_GROUP(gpio13), + BCM6328_GROUP(gpio14), + BCM6328_GROUP(gpio15), + BCM6328_GROUP(gpio16), + BCM6328_GROUP(gpio17), + BCM6328_GROUP(gpio18), + BCM6328_GROUP(gpio19), + BCM6328_GROUP(gpio20), + BCM6328_GROUP(gpio21), + BCM6328_GROUP(gpio22), + BCM6328_GROUP(gpio23), + BCM6328_GROUP(gpio24), + BCM6328_GROUP(gpio25), + BCM6328_GROUP(gpio26), + BCM6328_GROUP(gpio27), + BCM6328_GROUP(gpio28), + BCM6328_GROUP(gpio29), + BCM6328_GROUP(gpio30), + BCM6328_GROUP(gpio31), + + BCM6328_GROUP(hsspi_cs1), + BCM6328_GROUP(usb_port1), +}; + +/* GPIO_MODE */ +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +/* PINMUX_SEL */ +static const char * const serial_led_data_groups[] = { + "gpio6", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio7", +}; + +static const char * const inet_act_led_groups[] = { + "gpio11", +}; + +static const char * const pcie_clkreq_groups[] = { + "gpio16", +}; + +static const char * const ephy0_act_led_groups[] = { + "gpio25", +}; + +static const char * const ephy1_act_led_groups[] = { + "gpio26", +}; + +static const char * const ephy2_act_led_groups[] = { + "gpio27", +}; + +static const char * const ephy3_act_led_groups[] = { + "gpio28", +}; + +static const char * const hsspi_cs1_groups[] = { + "hsspi_cs1" +}; + +static const char * const usb_host_port_groups[] = { + "usb_port1", +}; + +static const char * const usb_device_port_groups[] = { + "usb_port1", +}; + +#define BCM6328_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mode_val = 1, \ + } + +#define BCM6328_MUX_FUN(n, mux) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mux_val = mux, \ + } + +static const struct bcm6328_function bcm6328_funcs[] = { + BCM6328_MODE_FUN(led), + BCM6328_MUX_FUN(serial_led_data, 2), + BCM6328_MUX_FUN(serial_led_clk, 2), + BCM6328_MUX_FUN(inet_act_led, 1), + BCM6328_MUX_FUN(pcie_clkreq, 2), + BCM6328_MUX_FUN(ephy0_act_led, 1), + BCM6328_MUX_FUN(ephy1_act_led, 1), + BCM6328_MUX_FUN(ephy2_act_led, 1), + BCM6328_MUX_FUN(ephy3_act_led, 1), + BCM6328_MUX_FUN(hsspi_cs1, 2), + BCM6328_MUX_FUN(usb_host_port, 1), + BCM6328_MUX_FUN(usb_device_port, 2), +}; + +static inline unsigned int bcm6328_bank_pin(unsigned int pin) +{ + return pin % PINS_PER_BANK; +} + +static inline unsigned int bcm6318_mux_off(unsigned int pin) +{ + static const unsigned int bcm6328_mux[] = { + BCM6328_MUX_LO_REG, + BCM6328_MUX_HI_REG, + BCM6328_MUX_OTHER_REG + }; + + return bcm6328_mux[pin / 16]; +} + +static inline unsigned int bcm6328_reg_off(unsigned int reg, unsigned int pin) +{ + return reg - (pin / PINS_PER_BANK) * BANK_SIZE; +} + +static int bcm6328_gpio_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin); + unsigned int bank_pin = bcm6328_bank_pin(pin); + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an input GPIO + */ + ret = pinctrl_gpio_direction_input(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); + + return 0; +} + +static int bcm6328_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin); + unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin); + unsigned int bank_pin = bcm6328_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an output GPIO + */ + ret = pinctrl_gpio_direction_output(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); + + return 0; +} + +static int bcm6328_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin); + unsigned int bank_pin = bcm6328_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, data, &val); + + return !!(val & BIT(bank_pin)); +} + +static int bcm6328_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin); + unsigned int bank_pin = bcm6328_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, dirout, &val); + + if (val & BIT(bank_pin)) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static void bcm6328_gpio_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin); + unsigned int bank_pin = bcm6328_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); +} + +static int bcm6328_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +{ + char irq_name[7]; + + sprintf(irq_name, "gpio%d", gpio); + + return of_irq_get_byname(chip->of_node, irq_name); +} + +static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6328_groups); +} + +static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6328_groups[group].name; +} + +static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6328_groups[group].pins; + *num_pins = bcm6328_groups[group].num_pins; + + return 0; +} + +static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6328_funcs); +} + +static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6328_funcs[selector].name; +} + +static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6328_funcs[selector].groups; + *num_groups = bcm6328_funcs[selector].num_groups; + + return 0; +} + +static void bcm6328_rmw_mux(struct bcm6328_pinctrl *pc, unsigned pin, + unsigned int mode, unsigned int mux) +{ + if (pin < BCM6328_NUM_GPIOS) + regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin), + mode ? BIT(pin) : 0); + + regmap_update_bits(pc->regs, bcm6318_mux_off(pin), + 3UL << ((pin % 16) * 2), + mux << ((pin % 16) * 2)); +} + +static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm6328_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6328_pingroup *pg = &bcm6328_groups[group]; + const struct bcm6328_function *f = &bcm6328_funcs[selector]; + + bcm6328_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); + + return 0; +} + +static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm6328_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm6328_rmw_mux(pc, offset, 0, 0); + + return 0; +} + +static struct pinctrl_ops bcm6328_pctl_ops = { + .get_groups_count = bcm6328_pinctrl_get_group_count, + .get_group_name = bcm6328_pinctrl_get_group_name, + .get_group_pins = bcm6328_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static struct pinmux_ops bcm6328_pmx_ops = { + .get_functions_count = bcm6328_pinctrl_get_func_count, + .get_function_name = bcm6328_pinctrl_get_func_name, + .get_function_groups = bcm6328_pinctrl_get_groups, + .set_mux = bcm6328_pinctrl_set_mux, + .gpio_request_enable = bcm6328_gpio_request_enable, + .strict = true, +}; + +static int bcm6328_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm6328_pinctrl *pc; + int err; + + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + platform_set_drvdata(pdev, pc); + pc->dev = dev; + + pc->regs = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(pc->regs)) + return PTR_ERR(pc->regs); + + pc->gpio_chip.label = MODULE_NAME; + pc->gpio_chip.owner = THIS_MODULE; + pc->gpio_chip.request = gpiochip_generic_request; + pc->gpio_chip.free = gpiochip_generic_free; + pc->gpio_chip.direction_input = bcm6328_gpio_direction_input; + pc->gpio_chip.direction_output = bcm6328_gpio_direction_output; + pc->gpio_chip.get_direction = bcm6328_gpio_get_direction; + pc->gpio_chip.get = bcm6328_gpio_get; + pc->gpio_chip.set = bcm6328_gpio_set; + pc->gpio_chip.set_config = gpiochip_generic_config; + pc->gpio_chip.base = -1; + pc->gpio_chip.ngpio = BCM6328_NUM_GPIOS; + pc->gpio_chip.can_sleep = false; + pc->gpio_chip.parent = dev; + pc->gpio_chip.of_node = np; + + if (of_get_property(np, "interrupt-names", NULL)) + pc->gpio_chip.to_irq = bcm6328_gpio_to_irq; + + err = gpiochip_add_data(&pc->gpio_chip, pc); + if (err) { + dev_err(dev, "could not add GPIO chip\n"); + return err; + } + + pc->pctl_desc.name = MODULE_NAME, + pc->pctl_desc.pins = bcm6328_pins, + pc->pctl_desc.npins = ARRAY_SIZE(bcm6328_pins), + pc->pctl_desc.pctlops = &bcm6328_pctl_ops, + pc->pctl_desc.pmxops = &bcm6328_pmx_ops, + pc->pctl_desc.owner = THIS_MODULE, + + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) { + gpiochip_remove(&pc->gpio_chip); + return PTR_ERR(pc->pctl_dev); + } + + pc->gpio_range.name = MODULE_NAME; + pc->gpio_range.npins = BCM6328_NUM_GPIOS; + pc->gpio_range.base = pc->gpio_chip.base; + pc->gpio_range.gc = &pc->gpio_chip; + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); + + dev_info(dev, "registered\n"); + + return 0; +} + +static const struct of_device_id bcm6328_pinctrl_match[] = { + { .compatible = "brcm,bcm6328-pinctrl", }, + { }, +}; + +static struct platform_driver bcm6328_pinctrl_driver = { + .probe = bcm6328_pinctrl_probe, + .driver = { + .name = MODULE_NAME, + .of_match_table = bcm6328_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6328_pinctrl_driver); From patchwork Thu Feb 25 16:42:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387904 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 59448C4332D for ; Thu, 25 Feb 2021 16:43:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2DD0064F03 for ; Thu, 25 Feb 2021 16:43:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233161AbhBYQnM (ORCPT ); Thu, 25 Feb 2021 11:43:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232787AbhBYQnE (ORCPT ); Thu, 25 Feb 2021 11:43:04 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 49A94C061786; Thu, 25 Feb 2021 08:42:23 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id g11so1441995wmh.1; Thu, 25 Feb 2021 08:42:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=dLlC1LtxEBko7Y+crRoY9/o8oPZpGvVfWGDAZ24Hitc=; b=RGe706ONP5Y8FsEhFRx0hL73moEePVthbZ+M9ZbH25yLiS5dRQXr0yc5AGSGGhsxoa +FB/dWT+jksz0VYOto9kRz1pz31DIPTGR0xT8v25s7zfxCKLFueAajSgeQ/PIPNg57wi 62bcImqFIQuuV/79kn05w0Qtdr/rYqgmK3KbNdiFYuSUnMYoLhQ6eAgr5mbzXOEbhC1V mTxolTq+UYOBmB6TrnQHCohjj7jBrLwULD3DscpaJXOvi9Xr3+POUVv8PWtB7CSN1cIy dOtdVLJ5z97ClV6k7qL+Sgr/YAxMMHRrwCFLQA7ALTgl864EpY3yzoSh3G0lK6Fk0gE4 CRhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dLlC1LtxEBko7Y+crRoY9/o8oPZpGvVfWGDAZ24Hitc=; b=kQ1ZOU17duzvoTczGW+AUB8S5tdeI8triFFVU8JSjRgCBFJFIt2NRUFYEB0qAv/3i4 Qri4sMHJJ2rVdh8hs1fvXi8P2z6xqhIChVdjKBou32lwURTnKTccP739MQoMHEZg+1W9 MuBelUxdMGyj4Axs9ecmzVMNNwga+05fgNON5stcBF/rRQTce/sK5ZusmHdW67d6kaPa TazhMPL6DxNVKu8Z1bFequMcOd3/PLUoJmsyiY8b7Uh5zcMrxRpKB820clIOUcLd4POA 9cnIgHJtMLkCVojmOurFQm8vO9F890O/MFCjXHKmpxhv/pbLnkljhWT0LJLiowdPv7fn d9zQ== X-Gm-Message-State: AOAM531SDXqr3M2cHWmRYPpb1yc4qDF6OD8jsvcx8BZlOo1N0DXm2kIe fSyV5c4TkOztATiEOmJz/QZ45gdHg1NuSw== X-Google-Smtp-Source: ABdhPJw+f7wulOXUpQN6ThVGbmdLP/cTHe5x0lHXWIMIfZ8xvlg3cg5X2u0aSikH7NFsG1EvDHsB3Q== X-Received: by 2002:a05:600c:c3:: with SMTP id u3mr4194685wmm.64.1614271341968; Thu, 25 Feb 2021 08:42:21 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:21 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 03/12] Documentation: add BCM6358 pincontroller binding documentation Date: Thu, 25 Feb 2021 17:42:07 +0100 Message-Id: <20210225164216.21124-4-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add binding documentation for the pincontrol core found in BCM6358 SoCs. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- .../pinctrl/brcm,bcm6358-pinctrl.yaml | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml new file mode 100644 index 000000000000..d86608173498 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6358-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6358 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: |+ + The pin controller node should be the child of a syscon node. + + Refer to the bindings described in + Documentation/devicetree/bindings/mfd/syscon.yaml + +properties: + compatible: + const: brcm,bcm6358-pinctrl + + gpio-controller: true + + '#gpio-cells': + description: + Specifies the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + interrupts-extended: + description: + One interrupt per each of the 4 GPIO ports supported by the controller, + sorted by port number ascending order. + minItems: 6 + maxItems: 6 + +patternProperties: + '^.*$': + if: + type: object + then: + properties: + function: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ ebi_cs, uart1, serial_led, legacy_led, led, spi_cs, utopia, + pwm_syn_clk, sys_irq ] + + pins: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ ebi_cs_grp, uart1_grp, serial_led_grp, legacy_led_grp, + led_grp, spi_cs_grp, utopia_grp, pwm_syn_clk, sys_irq_grp ] + +required: + - compatible + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +examples: + - | + gpio@fffe0080 { + compatible = "syscon", "simple-mfd"; + reg = <0xfffe0080 0x80>; + + pinctrl: pinctrl { + compatible = "brcm,bcm6358-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc1 0 0>, + <&ext_intc1 1 0>, + <&ext_intc0 0 0>, + <&ext_intc0 1 0>, + <&ext_intc0 2 0>, + <&ext_intc0 3 0>; + interrupt-names = "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37"; + + pinctrl_ebi_cs: ebi_cs { + function = "ebi_cs"; + groups = "ebi_cs_grp"; + }; + + pinctrl_uart1: uart1 { + function = "uart1"; + groups = "uart1_grp"; + }; + + pinctrl_serial_led: serial_led { + function = "serial_led"; + groups = "serial_led_grp"; + }; + + pinctrl_legacy_led: legacy_led { + function = "legacy_led"; + groups = "legacy_led_grp"; + }; + + pinctrl_led: led { + function = "led"; + groups = "led_grp"; + }; + + pinctrl_spi_cs_23: spi_cs { + function = "spi_cs"; + groups = "spi_cs_grp"; + }; + + pinctrl_utopia: utopia { + function = "utopia"; + groups = "utopia_grp"; + }; + + pinctrl_pwm_syn_clk: pwm_syn_clk { + function = "pwm_syn_clk"; + groups = "pwm_syn_clk_grp"; + }; + + pinctrl_sys_irq: sys_irq { + function = "sys_irq"; + groups = "sys_irq_grp"; + }; + }; + }; From patchwork Thu Feb 25 16:42:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387429 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 0C15FC433E6 for ; Thu, 25 Feb 2021 16:43:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CD73264F0D for ; Thu, 25 Feb 2021 16:43:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233207AbhBYQnQ (ORCPT ); Thu, 25 Feb 2021 11:43:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232923AbhBYQnF (ORCPT ); Thu, 25 Feb 2021 11:43:05 -0500 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D1D5C061788; Thu, 25 Feb 2021 08:42:24 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id w7so5170352wmb.5; Thu, 25 Feb 2021 08:42:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=T2y6jieZmKn5aMiF03FXjpMSZg3L/1KWOk3ftcjGWnw=; b=rOoIyXR9EaQHCY/JGdW0lUtCm4EDVowxzglw773lpK4fxJUnjeadd9+T7vt6BIJIzs BxgbdqaTqXm4w010O3KSL0vmuMh7CvihY+pqs3dh7RMxeNXKu0kMIOEHxW9TJZh9Eta3 8meaCfzVCfsEK7+WyktQC7zJR1I+Twz3cT7TxRY5iqCXk0GBNXAHCP41lnYiCppq7bqX KlDprCa1BuRev9PDDNGYLJLIY9DaVoFbjYU4ZAAdwpbJ/2HS8PSiFS1tqvlWitaTXcxy h9rWc7s/rt/7SgfI61s65GSbVWQ/zUqcYTHgjT5b/LSMbP6+QPpjCn3ikPhMvVSEEVSa h/iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=T2y6jieZmKn5aMiF03FXjpMSZg3L/1KWOk3ftcjGWnw=; b=mdnAt82DT8HJhFDwCcT/N4tPOKGbztBfOe+3Xc1Lzy14iJ59f6ctuXP35Edhm4v/wR RzGxT1riPF1Eal4iIRDeIYl0SztU1fNdImKRMxsgk5ql0OBKEFG2SdEHTFsScivxFSGs Vd3jIIXDHg9ar4Ngg4JRbp8jxpM+KYYFPr8l/Znk4GPkLerRed1NV9lGFhBaubPIPT5b 8uUVs8IaWET3dQyi+m5n8lwWSJVPcbeSEnWcPP3O634M+mx7phw2cL63TSVNBfMwUuve EZFcOjPQh5E5zO6qOBshA32xEvYMgdPccA3R7ihj5flxQiYOyuw7z79Rw7NfrO5NNVWW hJYg== X-Gm-Message-State: AOAM531m7M3LGkviZhrif41v/R1zC11zGdng6Z9i9iLYVpBt7RHeM0/b xZr+jIQ9jfLMTXHOC4hbm9o= X-Google-Smtp-Source: ABdhPJyFd1gLxVn5wDbYh451fTvadsCzTApfoRicBMjG9QOE3WFQgpJd9TvYSBD7dBNbi2YQ61usPw== X-Received: by 2002:a7b:c5c7:: with SMTP id n7mr4070555wmk.63.1614271342733; Thu, 25 Feb 2021 08:42:22 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:22 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 04/12] pinctrl: add a pincontrol driver for BCM6358 Date: Thu, 25 Feb 2021 17:42:08 +0100 Message-Id: <20210225164216.21124-5-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different functions onto the GPIO pins. It does not support configuring individual pins but only whole groups. These groups may overlap, and still require the directions to be set correctly in the GPIO register. In addition the functions register controls other, not directly mux related functions. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- drivers/pinctrl/bcm/Kconfig | 11 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6358.c | 526 ++++++++++++++++++++++++++ 3 files changed, 538 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 4c6e41cf7a32..dd82a34125ed 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -40,6 +40,17 @@ config PINCTRL_BCM6328 help Say Y here to enable the Broadcom BCM6328 GPIO driver. +config PINCTRL_BCM6358 + bool "Broadcom BCM6358 GPIO driver" + depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) + select PINMUX + select PINCONF + select GENERIC_PINCONF + select MFD_SYSCON + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6358 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 7e7c6e25b26d..794d07d97754 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o +obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6358.c b/drivers/pinctrl/bcm/pinctrl-bcm6358.c new file mode 100644 index 000000000000..4948d668d186 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6358.c @@ -0,0 +1,526 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6358 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define MODULE_NAME "bcm6358-pinctrl" +#define BCM6358_NUM_GPIOS 40 + +#define BANK_SIZE sizeof(uint32_t) +#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) + +#define BCM6358_DIROUT_REG 0x04 +#define BCM6358_DATA_REG 0x0c +#define BCM6358_MODE_REG 0x18 + +#define BCM6358_MODE_MUX_NONE 0 +#define BCM6358_MODE_MUX_EBI_CS BIT(5) +#define BCM6358_MODE_MUX_UART1 BIT(6) +#define BCM6358_MODE_MUX_SPI_CS BIT(7) +#define BCM6358_MODE_MUX_ASYNC_MODEM BIT(8) +#define BCM6358_MODE_MUX_LEGACY_LED BIT(9) +#define BCM6358_MODE_MUX_SERIAL_LED BIT(10) +#define BCM6358_MODE_MUX_LED BIT(11) +#define BCM6358_MODE_MUX_UTOPIA BIT(12) +#define BCM6358_MODE_MUX_CLKRST BIT(13) +#define BCM6358_MODE_MUX_PWM_SYN_CLK BIT(14) +#define BCM6358_MODE_MUX_SYS_IRQ BIT(15) + +struct bcm6358_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; + + const uint16_t mode_val; + + /* non-GPIO function muxes require the gpio direction to be set */ + const uint16_t direction; +}; + +struct bcm6358_function { + const char *name; + const char * const *groups; + const unsigned num_groups; +}; + +struct bcm6358_pinctrl { + struct device *dev; + struct regmap *regs; + struct regmap_field *overlays; + + struct pinctrl_dev *pctl_dev; + struct gpio_chip gpio_chip; + struct pinctrl_desc pctl_desc; + struct pinctrl_gpio_range gpio_range; +}; + +#define BCM6358_GPIO_PIN(a, b, bit1, bit2, bit3) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(BCM6358_MODE_MUX_##bit1 | \ + BCM6358_MODE_MUX_##bit2 | \ + BCM6358_MODE_MUX_##bit3), \ + } + +static const struct pinctrl_pin_desc bcm6358_pins[] = { + BCM6358_GPIO_PIN(0, "gpio0", LED, NONE, NONE), + BCM6358_GPIO_PIN(1, "gpio1", LED, NONE, NONE), + BCM6358_GPIO_PIN(2, "gpio2", LED, NONE, NONE), + BCM6358_GPIO_PIN(3, "gpio3", LED, NONE, NONE), + PINCTRL_PIN(4, "gpio4"), + BCM6358_GPIO_PIN(5, "gpio5", SYS_IRQ, NONE, NONE), + BCM6358_GPIO_PIN(6, "gpio6", SERIAL_LED, NONE, NONE), + BCM6358_GPIO_PIN(7, "gpio7", SERIAL_LED, NONE, NONE), + BCM6358_GPIO_PIN(8, "gpio8", PWM_SYN_CLK, NONE, NONE), + BCM6358_GPIO_PIN(9, "gpio09", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(10, "gpio10", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(11, "gpio11", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(12, "gpio12", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(13, "gpio13", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(14, "gpio14", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(15, "gpio15", LEGACY_LED, ASYNC_MODEM, UTOPIA), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + BCM6358_GPIO_PIN(22, "gpio22", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(23, "gpio23", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(24, "gpio24", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(25, "gpio25", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(26, "gpio26", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(27, "gpio27", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(28, "gpio28", UTOPIA, UART1, NONE), + BCM6358_GPIO_PIN(29, "gpio29", UTOPIA, UART1, NONE), + BCM6358_GPIO_PIN(30, "gpio30", UTOPIA, UART1, EBI_CS), + BCM6358_GPIO_PIN(31, "gpio31", UTOPIA, UART1, EBI_CS), + BCM6358_GPIO_PIN(32, "gpio32", SPI_CS, NONE, NONE), + BCM6358_GPIO_PIN(33, "gpio33", SPI_CS, NONE, NONE), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), +}; + +static unsigned ebi_cs_grp_pins[] = { 30, 31 }; + +static unsigned uart1_grp_pins[] = { 28, 29, 30, 31 }; + +static unsigned spi_cs_grp_pins[] = { 32, 33 }; + +static unsigned async_modem_grp_pins[] = { 12, 13, 14, 15 }; + +static unsigned serial_led_grp_pins[] = { 6, 7 }; + +static unsigned legacy_led_grp_pins[] = { 9, 10, 11, 12, 13, 14, 15 }; + +static unsigned led_grp_pins[] = { 0, 1, 2, 3 }; + +static unsigned utopia_grp_pins[] = { + 12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, +}; + +static unsigned pwm_syn_clk_grp_pins[] = { 8 }; + +static unsigned sys_irq_grp_pins[] = { 5 }; + +#define BCM6358_GPIO_MUX_GROUP(n, bit, dir) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + .mode_val = BCM6358_MODE_MUX_##bit, \ + .direction = dir, \ + } + +static const struct bcm6358_pingroup bcm6358_groups[] = { + BCM6358_GPIO_MUX_GROUP(ebi_cs_grp, EBI_CS, 0x3), + BCM6358_GPIO_MUX_GROUP(uart1_grp, UART1, 0x2), + BCM6358_GPIO_MUX_GROUP(spi_cs_grp, SPI_CS, 0x6), + BCM6358_GPIO_MUX_GROUP(async_modem_grp, ASYNC_MODEM, 0x6), + BCM6358_GPIO_MUX_GROUP(legacy_led_grp, LEGACY_LED, 0x7f), + BCM6358_GPIO_MUX_GROUP(serial_led_grp, SERIAL_LED, 0x3), + BCM6358_GPIO_MUX_GROUP(led_grp, LED, 0xf), + BCM6358_GPIO_MUX_GROUP(utopia_grp, UTOPIA, 0x000f), + BCM6358_GPIO_MUX_GROUP(pwm_syn_clk_grp, PWM_SYN_CLK, 0x1), + BCM6358_GPIO_MUX_GROUP(sys_irq_grp, SYS_IRQ, 0x1), +}; + +static const char * const ebi_cs_groups[] = { + "ebi_cs_grp" +}; + +static const char * const uart1_groups[] = { + "uart1_grp" +}; + +static const char * const spi_cs_2_3_groups[] = { + "spi_cs_2_3_grp" +}; + +static const char * const async_modem_groups[] = { + "async_modem_grp" +}; + +static const char * const legacy_led_groups[] = { + "legacy_led_grp", +}; + +static const char * const serial_led_groups[] = { + "serial_led_grp", +}; + +static const char * const led_groups[] = { + "led_grp", +}; + +static const char * const clkrst_groups[] = { + "clkrst_grp", +}; + +static const char * const pwm_syn_clk_groups[] = { + "pwm_syn_clk_grp", +}; + +static const char * const sys_irq_groups[] = { + "sys_irq_grp", +}; + +#define BCM6358_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + } + +static const struct bcm6358_function bcm6358_funcs[] = { + BCM6358_FUN(ebi_cs), + BCM6358_FUN(uart1), + BCM6358_FUN(spi_cs_2_3), + BCM6358_FUN(async_modem), + BCM6358_FUN(legacy_led), + BCM6358_FUN(serial_led), + BCM6358_FUN(led), + BCM6358_FUN(clkrst), + BCM6358_FUN(pwm_syn_clk), + BCM6358_FUN(sys_irq), +}; + +static inline unsigned int bcm6358_bank_pin(unsigned int pin) +{ + return pin % PINS_PER_BANK; +} + +static inline unsigned int bcm6358_reg_off(unsigned int reg, unsigned int pin) +{ + return reg - (pin / PINS_PER_BANK) * BANK_SIZE; +} + +static int bcm6358_gpio_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin); + unsigned int bank_pin = bcm6358_bank_pin(pin); + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an input GPIO + */ + ret = pinctrl_gpio_direction_input(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); + + return 0; +} + +static int bcm6358_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin); + unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin); + unsigned int bank_pin = bcm6358_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an output GPIO + */ + ret = pinctrl_gpio_direction_output(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); + + return 0; +} + +static int bcm6358_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin); + unsigned int bank_pin = bcm6358_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, data, &val); + + return !!(val & BIT(bank_pin)); +} + +static int bcm6358_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin); + unsigned int bank_pin = bcm6358_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, dirout, &val); + + if (val & BIT(bank_pin)) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static void bcm6358_gpio_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin); + unsigned int bank_pin = bcm6358_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); +} + +static int bcm6358_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +{ + char irq_name[7]; + + sprintf(irq_name, "gpio%d", gpio); + + return of_irq_get_byname(chip->of_node, irq_name); +} + +static int bcm6358_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6358_groups); +} + +static const char *bcm6358_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6358_groups[group].name; +} + +static int bcm6358_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6358_groups[group].pins; + *num_pins = bcm6358_groups[group].num_pins; + + return 0; +} + +static int bcm6358_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6358_funcs); +} + +static const char *bcm6358_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6358_funcs[selector].name; +} + +static int bcm6358_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6358_funcs[selector].groups; + *num_groups = bcm6358_funcs[selector].num_groups; + + return 0; +} + +static int bcm6358_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm6358_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6358_pingroup *pg = &bcm6358_groups[group]; + unsigned int val = pg->mode_val; + unsigned int mask = val; + unsigned pin; + + for (pin = 0; pin < pg->num_pins; pin++) + mask |= (unsigned long)bcm6358_pins[pin].drv_data; + + regmap_field_update_bits(pc->overlays, mask, val); + + for (pin = 0; pin < pg->num_pins; pin++) { + int hw_gpio = bcm6358_pins[pin].number; + struct gpio_chip *gc = &pc->gpio_chip; + + if (pg->direction & BIT(pin)) + gc->direction_output(gc, hw_gpio, 0); + else + gc->direction_input(gc, hw_gpio); + } + + return 0; +} + +static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm6358_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + unsigned int mask; + + mask = (unsigned long) bcm6358_pins[offset].drv_data; + if (!mask) + return 0; + + /* disable all functions using this pin */ + return regmap_field_update_bits(pc->overlays, mask, 0); +} + +static struct pinctrl_ops bcm6358_pctl_ops = { + .get_groups_count = bcm6358_pinctrl_get_group_count, + .get_group_name = bcm6358_pinctrl_get_group_name, + .get_group_pins = bcm6358_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static struct pinmux_ops bcm6358_pmx_ops = { + .get_functions_count = bcm6358_pinctrl_get_func_count, + .get_function_name = bcm6358_pinctrl_get_func_name, + .get_function_groups = bcm6358_pinctrl_get_groups, + .set_mux = bcm6358_pinctrl_set_mux, + .gpio_request_enable = bcm6358_gpio_request_enable, + .strict = true, +}; + +static int bcm6358_pinctrl_probe(struct platform_device *pdev) +{ + struct reg_field overlays = REG_FIELD(BCM6358_MODE_REG, 0, 15); + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm6358_pinctrl *pc; + int err; + + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + platform_set_drvdata(pdev, pc); + pc->dev = dev; + + pc->regs = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(pc->regs)) + return PTR_ERR(pc->regs); + + pc->overlays = devm_regmap_field_alloc(&pdev->dev, pc->regs, overlays); + if (IS_ERR(pc->overlays)) + return PTR_ERR(pc->overlays); + + /* disable all muxes by default */ + regmap_field_write(pc->overlays, 0); + + pc->gpio_chip.label = MODULE_NAME; + pc->gpio_chip.owner = THIS_MODULE; + pc->gpio_chip.request = gpiochip_generic_request; + pc->gpio_chip.free = gpiochip_generic_free; + pc->gpio_chip.direction_input = bcm6358_gpio_direction_input; + pc->gpio_chip.direction_output = bcm6358_gpio_direction_output; + pc->gpio_chip.get_direction = bcm6358_gpio_get_direction; + pc->gpio_chip.get = bcm6358_gpio_get; + pc->gpio_chip.set = bcm6358_gpio_set; + pc->gpio_chip.set_config = gpiochip_generic_config; + pc->gpio_chip.base = -1; + pc->gpio_chip.ngpio = BCM6358_NUM_GPIOS; + pc->gpio_chip.can_sleep = false; + pc->gpio_chip.parent = dev; + pc->gpio_chip.of_node = np; + + if (of_get_property(np, "interrupt-names", NULL)) + pc->gpio_chip.to_irq = bcm6358_gpio_to_irq; + + err = gpiochip_add_data(&pc->gpio_chip, pc); + if (err) { + dev_err(dev, "could not add GPIO chip\n"); + return err; + } + + pc->pctl_desc.name = MODULE_NAME, + pc->pctl_desc.pins = bcm6358_pins, + pc->pctl_desc.npins = ARRAY_SIZE(bcm6358_pins), + pc->pctl_desc.pctlops = &bcm6358_pctl_ops, + pc->pctl_desc.pmxops = &bcm6358_pmx_ops, + pc->pctl_desc.owner = THIS_MODULE, + + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) { + gpiochip_remove(&pc->gpio_chip); + return PTR_ERR(pc->pctl_dev); + } + + pc->gpio_range.name = MODULE_NAME; + pc->gpio_range.npins = BCM6358_NUM_GPIOS; + pc->gpio_range.base = pc->gpio_chip.base; + pc->gpio_range.gc = &pc->gpio_chip; + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); + + dev_info(dev, "registered\n"); + + return 0; +} + +static const struct of_device_id bcm6358_pinctrl_match[] = { + { .compatible = "brcm,bcm6358-pinctrl", }, + { }, +}; + +static struct platform_driver bcm6358_pinctrl_driver = { + .probe = bcm6358_pinctrl_probe, + .driver = { + .name = MODULE_NAME, + .of_match_table = bcm6358_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6358_pinctrl_driver); From patchwork Thu Feb 25 16:42:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387428 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 F08EFC433DB for ; Thu, 25 Feb 2021 16:44:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B605964F0D for ; Thu, 25 Feb 2021 16:44:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231160AbhBYQoT (ORCPT ); Thu, 25 Feb 2021 11:44:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233383AbhBYQnn (ORCPT ); Thu, 25 Feb 2021 11:43:43 -0500 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 042ABC06178A; Thu, 25 Feb 2021 08:42:25 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id w7so5170387wmb.5; Thu, 25 Feb 2021 08:42:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=ALvGgK20hY4hg2uRVpw0C+Cu820uWjonTHwM40KRiOM=; b=CUdJHyWP8T32dkSPb0BTFKoJn/Al59JEl/gxv76QZfINclI5E+M2snFOJ3zbuLm0gJ y6nlt7VSLY7Yo/I+BW9VIB47JNPjp2jU6sk7r5+M2RH1FkT6HV9wa6Vrc1D9ELiZ1rbm +OTrZ+fqnm/+5Gv3BPCfE2l1wu4psrYnBIRKmrRkY8d2J+8FxenPOHDF4zlYjX4mKm0x /bex0zYY4uecNU+5kkBhFhNUd6x4Xdt1YOwVPbF4bSLOx5S1wUmHly1z5jLNd7UDgPXJ 4vNynHSgC8jI4QLZSGzYgwgFEFUvHtPOVVnFcZkMrsWkDI64XiGerQaVkHQiGgaW2vKJ h5gQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ALvGgK20hY4hg2uRVpw0C+Cu820uWjonTHwM40KRiOM=; b=U32jJKlEGyaIPJF9HpSS3Y/s/e+nlvv7qk7dphpIelHMvp5EEWnesjseJyxUsRBoB2 tWmKuIjBby6II5O+/U9dwYf6v7QeO8wC0IXi4uC5JHdio8P5gb2zzf/YMuxHD7YX+GZv jqnxzsZZTbcwjAkXn8YZtz4379o9ANDjBgfCmwY1nJmp8OpZinMVIxO40JZ1q1YFYBU8 rPclKoesZL6rK4yHDDvueNj5iCdvsyDGjhoquHlnRrhqC6d1EXxKPArvf96x8AEunCNJ CES3joxuTsQsoVxr5BEIKoRMbDSW6o1CKzECR0IXP/pe/P2sFOA/xlnjyi8V6sxvw4nL WIbQ== X-Gm-Message-State: AOAM533yU6E8PaeTRjEiI8Z/Z/rgqyDJeT8DnXYxoJHZfd901dKcLi8F pM64EwygabstICKvblrdBsg= X-Google-Smtp-Source: ABdhPJxr9n+ZM55pRwe4mlRQ+uYcdggF3q3DMUkBFcm3zQW5Lo6Cn5Wm0BooGi6Jo1YMDuVp81bNeA== X-Received: by 2002:a1c:f603:: with SMTP id w3mr4026320wmc.122.1614271343731; Thu, 25 Feb 2021 08:42:23 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:23 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 05/12] Documentation: add BCM6362 pincontroller binding documentation Date: Thu, 25 Feb 2021 17:42:09 +0100 Message-Id: <20210225164216.21124-6-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add binding documentation for the pincontrol core found in BCM6362 SoCs. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- .../pinctrl/brcm,bcm6362-pinctrl.yaml | 240 ++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml new file mode 100644 index 000000000000..57a1718b179a --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml @@ -0,0 +1,240 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6362-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6362 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: |+ + The pin controller node should be the child of a syscon node. + + Refer to the bindings described in + Documentation/devicetree/bindings/mfd/syscon.yaml + +properties: + compatible: + const: brcm,bcm6362-pinctrl + + gpio-controller: true + + '#gpio-cells': + description: + Specifies the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + interrupts-extended: + description: + One interrupt per each of the 4 GPIO ports supported by the controller, + sorted by port number ascending order. + minItems: 4 + maxItems: 4 + +patternProperties: + '^.*$': + if: + type: object + then: + properties: + function: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ usb_device_led, sys_irq, serial_led_clk, serial_led_data, + robosw_led_data, robosw_led_clk, robosw_led0, robosw_led1, + inet_led, spi_cs2, spi_cs3, ntr_pulse, uart1_scts, + uart1_srts, uart1_sdin, uart1_sdout, adsl_spi_miso, + adsl_spi_mosi, adsl_spi_clk, adsl_spi_cs, ephy0_led, + ephy1_led, ephy2_led, ephy3_led, ext_irq0, ext_irq1, + ext_irq2, ext_irq3, nand ] + + pins: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14, + gpio15, gpio16, gpio17, gpio18, gpio19, gpio20, gpio21, + gpio22, gpio23, gpio24, gpio25, gpio26, gpio27, nand_grp ] + +required: + - compatible + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +examples: + - | + gpio@10000080 { + compatible = "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + + pinctrl: pinctrl { + compatible = "brcm,bcm6362-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc 0 0>, + <&ext_intc 1 0>, + <&ext_intc 2 0>, + <&ext_intc 3 0>; + interrupt-names = "gpio24", + "gpio25", + "gpio26", + "gpio27"; + + pinctrl_usb_device_led: usb_device_led { + function = "usb_device_led"; + pins = "gpio0"; + }; + + pinctrl_sys_irq: sys_irq { + function = "sys_irq"; + pins = "gpio1"; + }; + + pinctrl_serial_led: serial_led { + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio2"; + }; + + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio3"; + }; + }; + + pinctrl_robosw_led_data: robosw_led_data { + function = "robosw_led_data"; + pins = "gpio4"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk { + function = "robosw_led_clk"; + pins = "gpio5"; + }; + + pinctrl_robosw_led0: robosw_led0 { + function = "robosw_led0"; + pins = "gpio6"; + }; + + pinctrl_robosw_led1: robosw_led1 { + function = "robosw_led1"; + pins = "gpio7"; + }; + + pinctrl_inet_led: inet_led { + function = "inet_led"; + pins = "gpio8"; + }; + + pinctrl_spi_cs2: spi_cs2 { + function = "spi_cs2"; + pins = "gpio9"; + }; + + pinctrl_spi_cs3: spi_cs3 { + function = "spi_cs3"; + pins = "gpio10"; + }; + + pinctrl_ntr_pulse: ntr_pulse { + function = "ntr_pulse"; + pins = "gpio11"; + }; + + pinctrl_uart1_scts: uart1_scts { + function = "uart1_scts"; + pins = "gpio12"; + }; + + pinctrl_uart1_srts: uart1_srts { + function = "uart1_srts"; + pins = "gpio13"; + }; + + pinctrl_uart1: uart1 { + pinctrl_uart1_sdin: uart1_sdin { + function = "uart1_sdin"; + pins = "gpio14"; + }; + + pinctrl_uart1_sdout: uart1_sdout { + function = "uart1_sdout"; + pins = "gpio15"; + }; + }; + + pinctrl_adsl_spi: adsl_spi { + pinctrl_adsl_spi_miso: adsl_spi_miso { + function = "adsl_spi_miso"; + pins = "gpio16"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi { + function = "adsl_spi_mosi"; + pins = "gpio17"; + }; + + pinctrl_adsl_spi_clk: adsl_spi_clk { + function = "adsl_spi_clk"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_cs: adsl_spi_cs { + function = "adsl_spi_cs"; + pins = "gpio19"; + }; + }; + + pinctrl_ephy0_led: ephy0_led { + function = "ephy0_led"; + pins = "gpio20"; + }; + + pinctrl_ephy1_led: ephy1_led { + function = "ephy1_led"; + pins = "gpio21"; + }; + + pinctrl_ephy2_led: ephy2_led { + function = "ephy2_led"; + pins = "gpio22"; + }; + + pinctrl_ephy3_led: ephy3_led { + function = "ephy3_led"; + pins = "gpio23"; + }; + + pinctrl_ext_irq0: ext_irq0 { + function = "ext_irq0"; + pins = "gpio24"; + }; + + pinctrl_ext_irq1: ext_irq1 { + function = "ext_irq1"; + pins = "gpio25"; + }; + + pinctrl_ext_irq2: ext_irq2 { + function = "ext_irq2"; + pins = "gpio26"; + }; + + pinctrl_ext_irq3: ext_irq3 { + function = "ext_irq3"; + pins = "gpio27"; + }; + + pinctrl_nand: nand { + function = "nand"; + group = "nand_grp"; + }; + }; + }; From patchwork Thu Feb 25 16:42:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387903 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 5E035C433E0 for ; Thu, 25 Feb 2021 16:44:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2A97964E83 for ; Thu, 25 Feb 2021 16:44:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230019AbhBYQoL (ORCPT ); Thu, 25 Feb 2021 11:44:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54120 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233387AbhBYQnn (ORCPT ); Thu, 25 Feb 2021 11:43:43 -0500 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D63F7C06178B; Thu, 25 Feb 2021 08:42:25 -0800 (PST) Received: by mail-wm1-x330.google.com with SMTP id g11so1442087wmh.1; Thu, 25 Feb 2021 08:42:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=p3etVA4sTuJ3ARxwbMgB9mJU+LSE6+0VAGujoTLmmlk=; b=l6/kbEzBM1zO1fiDRCI4TEiXRrdbb/ITG8dlnV2dPlGFdS+1hyILZJdn5upCFS+E3W nLhVRt2U9pKigqgvFXRK8mKY6Lz6Z1QtLvubLgoon+8ldbHm7j9AyJuinp76J5TWZM1g 78l+0WUDkoOyZRDKz9FUmlAuzfhE6urnVm+GSqCMCeAyKMB+wLZlyUDvgAymT0CbKUxX JtDtAC2X+xqmY8NU/8uXRLrfIm9PjtC9kSeYNJ5DrY+Du7oQll08TcK/int3nLeRv56O IaRaVw5yjKClEKCcYuPBMoU4BtwwTy0v5yMT8hSvUnwe8+rbqMxIyGB3mQfzi73RrOOT wSGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=p3etVA4sTuJ3ARxwbMgB9mJU+LSE6+0VAGujoTLmmlk=; b=Hg6m8vV+w3/VTzPDrTW/NxddOmNIgs73V0UQnZWf13dEmaz6jBqd2m/a1tNiPOi6qJ dX/jNlsRogfjHRlwA+YtpvUMEQogSAYnMr7mqzB1xs8aGRNYSFm/dEpURvkwBWQbUFLJ RIuXCD/+sEmQ56U5jW5/iPG0dPZCVSxTfLI2FQFHN+coiGON2fMv4+Zy+XV+DVgo6CbG yGCACSUrzhE1qZnTE4LOvO3dqWrhtmW8IjOIe3jczF2SHO5sGLJjNtFoI14IHL5t//Lx vewAFK/NKIgKxqBlhp2LX1ws0+XTQXKMRpEI+Dhm77SNAt6lz6+iHhoo3akYf5Aw7IUD gNkQ== X-Gm-Message-State: AOAM530sJM2OKKXbCiKK9TAnULAdKfGHBj3iY6sH3jarJSNBW7Q1mu7b TGf03oal6HjnrmSxJufrDp8= X-Google-Smtp-Source: ABdhPJz8xJ/HWTvx0ILRsBJecWAaxTw1Fn/Vm4iMT3Ew+NOcwweocL92LOP/aAvt62qYqY+jONpuUg== X-Received: by 2002:a7b:c18b:: with SMTP id y11mr4023375wmi.132.1614271344478; Thu, 25 Feb 2021 08:42:24 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:24 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 06/12] pinctrl: add a pincontrol driver for BCM6362 Date: Thu, 25 Feb 2021 17:42:10 +0100 Message-Id: <20210225164216.21124-7-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add a pincotrol driver for BCM6362. BCM6362 allows muxing individual GPIO pins to the LED controller, to be available by the integrated wifi, or other functions. It also supports overlay groups, of which only NAND is documented. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- drivers/pinctrl/bcm/Kconfig | 11 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6362.c | 794 ++++++++++++++++++++++++++ 3 files changed, 806 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index dd82a34125ed..44517f6407cf 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -51,6 +51,17 @@ config PINCTRL_BCM6358 help Say Y here to enable the Broadcom BCM6358 GPIO driver. +config PINCTRL_BCM6362 + bool "Broadcom BCM6362 GPIO driver" + depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) + select PINMUX + select PINCONF + select GENERIC_PINCONF + select MFD_SYSCON + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6362 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 794d07d97754..0ade52a390cb 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o +obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6362.c b/drivers/pinctrl/bcm/pinctrl-bcm6362.c new file mode 100644 index 000000000000..4a34de17ed74 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c @@ -0,0 +1,794 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6362 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define MODULE_NAME "bcm6362-pinctrl" +#define BCM6362_NUM_GPIOS 48 +#define BCM6362_NUM_LEDS 24 + +#define BANK_SIZE sizeof(uint32_t) +#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) + +#define BCM6362_DIROUT_REG 0x04 +#define BCM6362_DATA_REG 0x0c +#define BCM6362_LED_REG 0x10 +#define BCM6362_MODE_REG 0x18 +#define BCM6362_CTRL_REG 0x1c +#define BCM6362_BASEMODE_REG 0x38 +#define BASEMODE_NAND BIT(2) + +enum bcm6362_pinctrl_reg { + BCM6362_LEDCTRL, + BCM6362_MODE, + BCM6362_CTRL, + BCM6362_BASEMODE, +}; + +struct bcm6362_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6362_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + enum bcm6362_pinctrl_reg reg; + uint32_t basemode_mask; +}; + +struct bcm6362_pinctrl { + struct device *dev; + struct regmap *regs; + + struct pinctrl_dev *pctl_dev; + struct gpio_chip gpio_chip; + struct pinctrl_desc pctl_desc; + struct pinctrl_gpio_range gpio_range; +}; + +#define BCM6362_PIN(a, b, mask) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(mask), \ + } + +static const struct pinctrl_pin_desc bcm6362_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + BCM6362_PIN(8, "gpio8", BASEMODE_NAND), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + BCM6362_PIN(12, "gpio12", BASEMODE_NAND), + BCM6362_PIN(13, "gpio13", BASEMODE_NAND), + BCM6362_PIN(14, "gpio14", BASEMODE_NAND), + BCM6362_PIN(15, "gpio15", BASEMODE_NAND), + BCM6362_PIN(16, "gpio16", BASEMODE_NAND), + BCM6362_PIN(17, "gpio17", BASEMODE_NAND), + BCM6362_PIN(18, "gpio18", BASEMODE_NAND), + BCM6362_PIN(19, "gpio19", BASEMODE_NAND), + BCM6362_PIN(20, "gpio20", BASEMODE_NAND), + BCM6362_PIN(21, "gpio21", BASEMODE_NAND), + BCM6362_PIN(22, "gpio22", BASEMODE_NAND), + BCM6362_PIN(23, "gpio23", BASEMODE_NAND), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + BCM6362_PIN(27, "gpio27", BASEMODE_NAND), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; + +static unsigned nand_grp_pins[] = { + 8, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 27, +}; + +#define BCM6362_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6362_pingroup bcm6362_groups[] = { + BCM6362_GROUP(gpio0), + BCM6362_GROUP(gpio1), + BCM6362_GROUP(gpio2), + BCM6362_GROUP(gpio3), + BCM6362_GROUP(gpio4), + BCM6362_GROUP(gpio5), + BCM6362_GROUP(gpio6), + BCM6362_GROUP(gpio7), + BCM6362_GROUP(gpio8), + BCM6362_GROUP(gpio9), + BCM6362_GROUP(gpio10), + BCM6362_GROUP(gpio11), + BCM6362_GROUP(gpio12), + BCM6362_GROUP(gpio13), + BCM6362_GROUP(gpio14), + BCM6362_GROUP(gpio15), + BCM6362_GROUP(gpio16), + BCM6362_GROUP(gpio17), + BCM6362_GROUP(gpio18), + BCM6362_GROUP(gpio19), + BCM6362_GROUP(gpio20), + BCM6362_GROUP(gpio21), + BCM6362_GROUP(gpio22), + BCM6362_GROUP(gpio23), + BCM6362_GROUP(gpio24), + BCM6362_GROUP(gpio25), + BCM6362_GROUP(gpio26), + BCM6362_GROUP(gpio27), + BCM6362_GROUP(gpio28), + BCM6362_GROUP(gpio29), + BCM6362_GROUP(gpio30), + BCM6362_GROUP(gpio31), + BCM6362_GROUP(gpio32), + BCM6362_GROUP(gpio33), + BCM6362_GROUP(gpio34), + BCM6362_GROUP(gpio35), + BCM6362_GROUP(gpio36), + BCM6362_GROUP(gpio37), + BCM6362_GROUP(gpio38), + BCM6362_GROUP(gpio39), + BCM6362_GROUP(gpio40), + BCM6362_GROUP(gpio41), + BCM6362_GROUP(gpio42), + BCM6362_GROUP(gpio43), + BCM6362_GROUP(gpio44), + BCM6362_GROUP(gpio45), + BCM6362_GROUP(gpio46), + BCM6362_GROUP(gpio47), + BCM6362_GROUP(nand_grp), +}; + +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +static const char * const usb_device_led_groups[] = { + "gpio0", +}; + +static const char * const sys_irq_groups[] = { + "gpio1", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio2", +}; + +static const char * const serial_led_data_groups[] = { + "gpio3", +}; + +static const char * const robosw_led_data_groups[] = { + "gpio4", +}; + +static const char * const robosw_led_clk_groups[] = { + "gpio5", +}; + +static const char * const robosw_led0_groups[] = { + "gpio6", +}; + +static const char * const robosw_led1_groups[] = { + "gpio7", +}; + +static const char * const inet_led_groups[] = { + "gpio8", +}; + +static const char * const spi_cs2_groups[] = { + "gpio9", +}; + +static const char * const spi_cs3_groups[] = { + "gpio10", +}; + +static const char * const ntr_pulse_groups[] = { + "gpio11", +}; + +static const char * const uart1_scts_groups[] = { + "gpio12", +}; + +static const char * const uart1_srts_groups[] = { + "gpio13", +}; + +static const char * const uart1_sdin_groups[] = { + "gpio14", +}; + +static const char * const uart1_sdout_groups[] = { + "gpio15", +}; + +static const char * const adsl_spi_miso_groups[] = { + "gpio16", +}; + +static const char * const adsl_spi_mosi_groups[] = { + "gpio17", +}; + +static const char * const adsl_spi_clk_groups[] = { + "gpio18", +}; + +static const char * const adsl_spi_cs_groups[] = { + "gpio19", +}; + +static const char * const ephy0_led_groups[] = { + "gpio20", +}; + +static const char * const ephy1_led_groups[] = { + "gpio21", +}; + +static const char * const ephy2_led_groups[] = { + "gpio22", +}; + +static const char * const ephy3_led_groups[] = { + "gpio23", +}; + +static const char * const ext_irq0_groups[] = { + "gpio24", +}; + +static const char * const ext_irq1_groups[] = { + "gpio25", +}; + +static const char * const ext_irq2_groups[] = { + "gpio26", +}; + +static const char * const ext_irq3_groups[] = { + "gpio27", +}; + +static const char * const wifi_groups[] = { + "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37", + "gpio38", + "gpio39", + "gpio40", + "gpio41", + "gpio42", + "gpio43", + "gpio44", + "gpio45", + "gpio46", + "gpio47", +}; + +static const char * const nand_groups[] = { + "nand_grp", +}; + +#define BCM6362_LED_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_LEDCTRL, \ + } + +#define BCM6362_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_MODE, \ + } + +#define BCM6362_CTRL_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_CTRL, \ + } + +#define BCM6362_BASEMODE_FUN(n, mask) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_BASEMODE, \ + .basemode_mask = (mask), \ + } + +static const struct bcm6362_function bcm6362_funcs[] = { + BCM6362_LED_FUN(led), + BCM6362_MODE_FUN(usb_device_led), + BCM6362_MODE_FUN(sys_irq), + BCM6362_MODE_FUN(serial_led_clk), + BCM6362_MODE_FUN(serial_led_data), + BCM6362_MODE_FUN(robosw_led_data), + BCM6362_MODE_FUN(robosw_led_clk), + BCM6362_MODE_FUN(robosw_led0), + BCM6362_MODE_FUN(robosw_led1), + BCM6362_MODE_FUN(inet_led), + BCM6362_MODE_FUN(spi_cs2), + BCM6362_MODE_FUN(spi_cs3), + BCM6362_MODE_FUN(ntr_pulse), + BCM6362_MODE_FUN(uart1_scts), + BCM6362_MODE_FUN(uart1_srts), + BCM6362_MODE_FUN(uart1_sdin), + BCM6362_MODE_FUN(uart1_sdout), + BCM6362_MODE_FUN(adsl_spi_miso), + BCM6362_MODE_FUN(adsl_spi_mosi), + BCM6362_MODE_FUN(adsl_spi_clk), + BCM6362_MODE_FUN(adsl_spi_cs), + BCM6362_MODE_FUN(ephy0_led), + BCM6362_MODE_FUN(ephy1_led), + BCM6362_MODE_FUN(ephy2_led), + BCM6362_MODE_FUN(ephy3_led), + BCM6362_MODE_FUN(ext_irq0), + BCM6362_MODE_FUN(ext_irq1), + BCM6362_MODE_FUN(ext_irq2), + BCM6362_MODE_FUN(ext_irq3), + BCM6362_CTRL_FUN(wifi), + BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND), +}; + +static inline unsigned int bcm6362_bank_pin(unsigned int pin) +{ + return pin % PINS_PER_BANK; +} + +static inline unsigned int bcm6362_reg_off(unsigned int reg, unsigned int pin) +{ + return reg - (pin / PINS_PER_BANK) * BANK_SIZE; +} + +static int bcm6362_gpio_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin); + unsigned int bank_pin = bcm6362_bank_pin(pin); + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an input GPIO + */ + ret = pinctrl_gpio_direction_input(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); + + return 0; +} + +static int bcm6362_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin); + unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin); + unsigned int bank_pin = bcm6362_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an output GPIO + */ + ret = pinctrl_gpio_direction_output(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); + + return 0; +} + +static int bcm6362_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin); + unsigned int bank_pin = bcm6362_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, data, &val); + + return !!(val & BIT(bank_pin)); +} + +static int bcm6362_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin); + unsigned int bank_pin = bcm6362_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, dirout, &val); + + if (val & BIT(bank_pin)) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static void bcm6362_gpio_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin); + unsigned int bank_pin = bcm6362_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); +} + +static int bcm6362_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +{ + char irq_name[7]; + + sprintf(irq_name, "gpio%d", gpio); + + return of_irq_get_byname(chip->of_node, irq_name); +} + +static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6362_groups); +} + +static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6362_groups[group].name; +} + +static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6362_groups[group].pins; + *num_pins = bcm6362_groups[group].num_pins; + + return 0; +} + +static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6362_funcs); +} + +static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6362_funcs[selector].name; +} + +static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6362_funcs[selector].groups; + *num_groups = bcm6362_funcs[selector].num_groups; + + return 0; +} + +static void bcm6362_set_gpio(struct bcm6362_pinctrl *pc, unsigned pin) +{ + const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin]; + unsigned int mask = bcm6362_bank_pin(pin); + + if (desc->drv_data) + regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, + (unsigned int) desc->drv_data, 0); + + if (pin < PINS_PER_BANK) { + /* base mode 0 => gpio 1 => mux function */ + regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0); + + /* pins 0-23 might be muxed to led */ + if (pin < BCM6362_NUM_LEDS) + regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0); + } else { + /* ctrl reg 0 => wifi function 1 => gpio */ + regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask); + } +} + +static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm6362_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6362_pingroup *pg = &bcm6362_groups[group]; + const struct bcm6362_function *f = &bcm6362_funcs[selector]; + unsigned i; + unsigned int reg; + unsigned int val, mask; + + for (i = 0; i < pg->num_pins; i++) + bcm6362_set_gpio(pc, pg->pins[i]); + + switch (f->reg) { + case BCM6362_LEDCTRL: + reg = BCM6362_LED_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM6362_MODE: + reg = BCM6362_MODE_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM6362_CTRL: + reg = BCM6362_CTRL_REG; + mask = BIT(pg->pins[0]); + val = 0; + break; + case BCM6362_BASEMODE: + reg = BCM6362_BASEMODE_REG; + mask = f->basemode_mask; + val = f->basemode_mask; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + regmap_update_bits(pc->regs, reg, mask, val); + + return 0; +} + +static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm6362_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm6362_set_gpio(pc, offset); + + return 0; +} + +static struct pinctrl_ops bcm6362_pctl_ops = { + .get_groups_count = bcm6362_pinctrl_get_group_count, + .get_group_name = bcm6362_pinctrl_get_group_name, + .get_group_pins = bcm6362_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static struct pinmux_ops bcm6362_pmx_ops = { + .get_functions_count = bcm6362_pinctrl_get_func_count, + .get_function_name = bcm6362_pinctrl_get_func_name, + .get_function_groups = bcm6362_pinctrl_get_groups, + .set_mux = bcm6362_pinctrl_set_mux, + .gpio_request_enable = bcm6362_gpio_request_enable, + .strict = true, +}; + +static int bcm6362_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm6362_pinctrl *pc; + int err; + + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + platform_set_drvdata(pdev, pc); + pc->dev = dev; + + pc->regs = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(pc->regs)) + return PTR_ERR(pc->regs); + + pc->gpio_chip.label = MODULE_NAME; + pc->gpio_chip.owner = THIS_MODULE; + pc->gpio_chip.request = gpiochip_generic_request; + pc->gpio_chip.free = gpiochip_generic_free; + pc->gpio_chip.direction_input = bcm6362_gpio_direction_input; + pc->gpio_chip.direction_output = bcm6362_gpio_direction_output; + pc->gpio_chip.get_direction = bcm6362_gpio_get_direction; + pc->gpio_chip.get = bcm6362_gpio_get; + pc->gpio_chip.set = bcm6362_gpio_set; + pc->gpio_chip.set_config = gpiochip_generic_config; + pc->gpio_chip.base = -1; + pc->gpio_chip.ngpio = BCM6362_NUM_GPIOS; + pc->gpio_chip.can_sleep = false; + pc->gpio_chip.parent = dev; + pc->gpio_chip.of_node = np; + + if (of_get_property(np, "interrupt-names", NULL)) + pc->gpio_chip.to_irq = bcm6362_gpio_to_irq; + + err = gpiochip_add_data(&pc->gpio_chip, pc); + if (err) { + dev_err(dev, "could not add GPIO chip\n"); + return err; + } + + pc->pctl_desc.name = MODULE_NAME, + pc->pctl_desc.pins = bcm6362_pins, + pc->pctl_desc.npins = ARRAY_SIZE(bcm6362_pins), + pc->pctl_desc.pctlops = &bcm6362_pctl_ops, + pc->pctl_desc.pmxops = &bcm6362_pmx_ops, + pc->pctl_desc.owner = THIS_MODULE, + + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) { + gpiochip_remove(&pc->gpio_chip); + return PTR_ERR(pc->pctl_dev); + } + + pc->gpio_range.name = MODULE_NAME; + pc->gpio_range.npins = BCM6362_NUM_GPIOS; + pc->gpio_range.base = pc->gpio_chip.base; + pc->gpio_range.gc = &pc->gpio_chip; + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); + + dev_info(dev, "registered\n"); + + return 0; +} + +static const struct of_device_id bcm6362_pinctrl_match[] = { + { .compatible = "brcm,bcm6362-pinctrl", }, + { }, +}; + +static struct platform_driver bcm6362_pinctrl_driver = { + .probe = bcm6362_pinctrl_probe, + .driver = { + .name = MODULE_NAME, + .of_match_table = bcm6362_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6362_pinctrl_driver); From patchwork Thu Feb 25 16:42:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387427 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 B74DBC4332D for ; Thu, 25 Feb 2021 16:44:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 961CC64F1D for ; Thu, 25 Feb 2021 16:44:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233582AbhBYQoj (ORCPT ); Thu, 25 Feb 2021 11:44:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54144 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233404AbhBYQn6 (ORCPT ); Thu, 25 Feb 2021 11:43:58 -0500 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 602A9C06178C; Thu, 25 Feb 2021 08:42:26 -0800 (PST) Received: by mail-wm1-x32e.google.com with SMTP id o16so5430630wmh.0; Thu, 25 Feb 2021 08:42:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Un6fINwvcp1AmGq52RBKA5ETcCYH1TeUxfrGm2elcIg=; b=RDZ1mk672ySOFSOl1HZLJOXlocXIPKf9hSiwHcK9mTV5uBppJXpCQlLfhAHELpEUSI NCmS8UzK04BynuuTvKyWv0wUj1ShsggJ8cMD3xF3P9R2lUAW4DN1BwoVziHWysoXLvH1 yZQZ9nVWRcc1V6Gj5paEGjiGq7vQ6Z5ZFgbNbz0O+zQh1mlYIE2qjtwZXhwevHFriLis gBY/eFjHGmtOUpEyYedG/12PUKapiKjoe2oO+X1SL6R7jawHSNZVjUgBrlnIBf/T6YOk nGnZ/GT90eZKK064K6jJq6EIZG657MyXNtWMDLsRxhixhGnAtSCWbOmVkHgKDmsk3J+s RoMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Un6fINwvcp1AmGq52RBKA5ETcCYH1TeUxfrGm2elcIg=; b=pu8ROwuD/jF/PpWswHY1WHujLW3ZSJSY5XMJtSyQf6EYl+w0Br3FwOYd6QNKU/3RuI dpncshoej85A91MRWF0IVgvZ33PEWESP3VHZL/stuWRcDB+zcJpldePQuS73GGVF/S5F p+WP6OESC8LngjqyGIK1bitN1wxy5xCbBajk1BdtWf9OZNt4NJ8kfxr+fACtYVN53Fst 7+52WtDzljHQG4CgDuKStFL0tnnTp64vQ99muthE8i8g+nwj/Pwc5acVgT9hI99fdVzp batPcenZoFDj6xRYOzOgaufGi43NQWxs5mGLTa6fji3oY9F5dcmXT0q+iEUe2sHpd+r3 Oglg== X-Gm-Message-State: AOAM533EYuJ5nqIfwbtXfK2MMfFF5YBiUjinIX86XO5uQjwszy5rjoG2 m5kyTjIuJPe9ZzA0u+zFZN0= X-Google-Smtp-Source: ABdhPJzYJJzk2mqSFT2TVwWzQVHm3kHqqTcZSkVW7iglT2Vxrhoe4+441XCikENlrfJ35s4J4c/6qw== X-Received: by 2002:a1c:4b16:: with SMTP id y22mr3999062wma.99.1614271345118; Thu, 25 Feb 2021 08:42:25 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:24 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 07/12] Documentation: add BCM6368 pincontroller binding documentation Date: Thu, 25 Feb 2021 17:42:11 +0100 Message-Id: <20210225164216.21124-8-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add binding documentation for the pincontrol core found in BCM6368 SoCs. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- .../pinctrl/brcm,bcm6368-pinctrl.yaml | 255 ++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml new file mode 100644 index 000000000000..1f69baef6e40 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml @@ -0,0 +1,255 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6368-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6368 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: |+ + The pin controller node should be the child of a syscon node. + + Refer to the bindings described in + Documentation/devicetree/bindings/mfd/syscon.yaml + +properties: + compatible: + const: brcm,bcm6368-pinctrl + + gpio-controller: true + + '#gpio-cells': + description: + Specifies the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + interrupts-extended: + description: + One interrupt per each of the 6 GPIO ports supported by the controller, + sorted by port number ascending order. + minItems: 6 + maxItems: 6 + +patternProperties: + '^.*$': + if: + type: object + then: + properties: + function: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ analog_afe_0, analog_afe_1, sys_irq, serial_led_data, + serial_led_clk, inet_led, ephy0_led, ephy1_led, ephy2_led, + ephy3_led, robosw_led_data, robosw_led_clk, robosw_led0, + robosw_led1, usb_device_led, pci_req1, pci_gnt1, pci_intb, + pci_req0, pci_gnt0, pcmcia_cd1, pcmcia_cd2, pcmcia_vs1, + pcmcia_vs2, ebi_cs2, ebi_cs3, spi_cs2, spi_cs3, spi_cs4, + spi_cs5, uart1 ] + + pins: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14, + gpio16, gpio17, gpio18, gpio19, gpio20, gpio22, gpio23, + gpio24, gpio25, gpio26, gpio27, gpio28, gpio29, gpio30, + gpio31, uart1_grp ] + +required: + - compatible + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +examples: + - | + gpio@10000080 { + compatible = "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + + pinctrl: pinctrl { + compatible = "brcm,bcm6368-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc1 0 0>, + <&ext_intc1 1 0>, + <&ext_intc0 0 0>, + <&ext_intc0 1 0>, + <&ext_intc0 2 0>, + <&ext_intc0 3 0>; + interrupt-names = "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37"; + + pinctrl_analog_afe_0: analog_afe_0 { + function = "analog_afe_0"; + pins = "gpio0"; + }; + + pinctrl_analog_afe_1: analog_afe_1 { + function = "analog_afe_1"; + pins = "gpio1"; + }; + + pinctrl_sys_irq: sys_irq { + function = "sys_irq"; + pins = "gpio2"; + }; + + pinctrl_serial_led: serial_led { + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio3"; + }; + + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio4"; + }; + }; + + pinctrl_inet_led: inet_led { + function = "inet_led"; + pins = "gpio5"; + }; + + pinctrl_ephy0_led: ephy0_led { + function = "ephy0_led"; + pins = "gpio6"; + }; + + pinctrl_ephy1_led: ephy1_led { + function = "ephy1_led"; + pins = "gpio7"; + }; + + pinctrl_ephy2_led: ephy2_led { + function = "ephy2_led"; + pins = "gpio8"; + }; + + pinctrl_ephy3_led: ephy3_led { + function = "ephy3_led"; + pins = "gpio9"; + }; + + pinctrl_robosw_led_data: robosw_led_data { + function = "robosw_led_data"; + pins = "gpio10"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk { + function = "robosw_led_clk"; + pins = "gpio11"; + }; + + pinctrl_robosw_led0: robosw_led0 { + function = "robosw_led0"; + pins = "gpio12"; + }; + + pinctrl_robosw_led1: robosw_led1 { + function = "robosw_led1"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led { + function = "usb_device_led"; + pins = "gpio14"; + }; + + pinctrl_pci: pci { + pinctrl_pci_req1: pci_req1 { + function = "pci_req1"; + pins = "gpio16"; + }; + + pinctrl_pci_gnt1: pci_gnt1 { + function = "pci_gnt1"; + pins = "gpio17"; + }; + + pinctrl_pci_intb: pci_intb { + function = "pci_intb"; + pins = "gpio18"; + }; + + pinctrl_pci_req0: pci_req0 { + function = "pci_req0"; + pins = "gpio19"; + }; + + pinctrl_pci_gnt0: pci_gnt0 { + function = "pci_gnt0"; + pins = "gpio20"; + }; + }; + + pinctrl_pcmcia: pcmcia { + pinctrl_pcmcia_cd1: pcmcia_cd1 { + function = "pcmcia_cd1"; + pins = "gpio22"; + }; + + pinctrl_pcmcia_cd2: pcmcia_cd2 { + function = "pcmcia_cd2"; + pins = "gpio23"; + }; + + pinctrl_pcmcia_vs1: pcmcia_vs1 { + function = "pcmcia_vs1"; + pins = "gpio24"; + }; + + pinctrl_pcmcia_vs2: pcmcia_vs2 { + function = "pcmcia_vs2"; + pins = "gpio25"; + }; + }; + + pinctrl_ebi_cs2: ebi_cs2 { + function = "ebi_cs2"; + pins = "gpio26"; + }; + + pinctrl_ebi_cs3: ebi_cs3 { + function = "ebi_cs3"; + pins = "gpio27"; + }; + + pinctrl_spi_cs2: spi_cs2 { + function = "spi_cs2"; + pins = "gpio28"; + }; + + pinctrl_spi_cs3: spi_cs3 { + function = "spi_cs3"; + pins = "gpio29"; + }; + + pinctrl_spi_cs4: spi_cs4 { + function = "spi_cs4"; + pins = "gpio30"; + }; + + pinctrl_spi_cs5: spi_cs5 { + function = "spi_cs5"; + pins = "gpio31"; + }; + + pinctrl_uart1: uart1 { + function = "uart1"; + group = "uart1_grp"; + }; + }; + }; From patchwork Thu Feb 25 16:42:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387426 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 03A72C43332 for ; Thu, 25 Feb 2021 16:44:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D179564F19 for ; Thu, 25 Feb 2021 16:44:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233591AbhBYQoo (ORCPT ); Thu, 25 Feb 2021 11:44:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233443AbhBYQn6 (ORCPT ); Thu, 25 Feb 2021 11:43:58 -0500 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 296CCC061793; Thu, 25 Feb 2021 08:42:27 -0800 (PST) Received: by mail-wr1-x42d.google.com with SMTP id n4so5913448wrx.1; Thu, 25 Feb 2021 08:42:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=m9+9LagDXM3WJ9Qz4CxaMbL7qAr9u+9D0teukKqZU3w=; b=CQla3/dO0xZkkojv0odO9TZi5VhMNxzUOmxOIasp/EiOLLp5CFzjRyqubmmhoJC7iD u2u0mEfaItLNOIub0eXAK3Kz93CxWjWLJSGEPTnEBiOCSDcO8bzddlNYzD46QFcBf4OI +uAZG/80cuucqwhvjCMoS1g+mvY4fToC2xeYanQ8HhHSOIwXWndwZSrgzL59X6fVqzug pfNrM0RwEEghY27Zpxk7UfM+PAAPLACad5OjElUzlluSb4GZd5STOCBZUCGz2pbEauvK w9GrrdXf9HYpnmZnlpSn11YRgUV0Y400RY+SMYuv9GEfcG0UhImsKdqerY4bL7vzkIIj UZCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=m9+9LagDXM3WJ9Qz4CxaMbL7qAr9u+9D0teukKqZU3w=; b=GTPQFqpCzv3nNcMJtFvxc+UzKgJyedEFm4hoLGN8SB+Zvk2apNOyCmIxokx3W8jgtz TGjMGwYuOK1FgEiIZN02zJFe1/E3re6ig2kcY+YhcVjQHwowdOo9x0keLJUyqdIHUqwy SHCN0yden43y8+PVF0aix0bTm0hoT5wEszUjPj4iJyw9W9uvIBrH3pSnJ6Dsn2PNjg0z 9wL4ewSCtsrDkZrJi/ZPnsSJ4cDEhPuaNO+FQCzb4jIT7858hWHD0F7isSfT6kq7lrFM XRTleVLygA1xLhjsd0rvp7yczAuGD/2tQbHmJJVOkYE+rLZ7rddGv6ed0xvGE4kajHNM UXzA== X-Gm-Message-State: AOAM533dMV7kiRat9rSOhLbDdPfv2dGp0rhTHOK+wvo7PPhM4qPjIP/5 /x8VCkf6oa3dDcyVMOr32SA= X-Google-Smtp-Source: ABdhPJwf2U/X5uEEQl+0lRMyIW7B1Cwvwbte0zOUKmtUCAeCRLjAReVqNShHJXIikaAOcTX+CHvkDw== X-Received: by 2002:a5d:6786:: with SMTP id v6mr4425551wru.19.1614271345829; Thu, 25 Feb 2021 08:42:25 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:25 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 08/12] pinctrl: add a pincontrol driver for BCM6368 Date: Thu, 25 Feb 2021 17:42:12 +0100 Message-Id: <20210225164216.21124-9-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32 GPIOs onto alternative functions. Not all are documented. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- drivers/pinctrl/bcm/Kconfig | 11 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6368.c | 679 ++++++++++++++++++++++++++ 3 files changed, 691 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 44517f6407cf..b8109f0a692c 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -62,6 +62,17 @@ config PINCTRL_BCM6362 help Say Y here to enable the Broadcom BCM6362 GPIO driver. +config PINCTRL_BCM6368 + bool "Broadcom BCM6368 GPIO driver" + depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) + select PINMUX + select PINCONF + select GENERIC_PINCONF + select MFD_SYSCON + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6368 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 0ade52a390cb..2d9c99a41c51 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o +obj-$(CONFIG_PINCTRL_BCM6368) += pinctrl-bcm6368.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6368.c b/drivers/pinctrl/bcm/pinctrl-bcm6368.c new file mode 100644 index 000000000000..3a268679132d --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6368.c @@ -0,0 +1,679 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6368 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define MODULE_NAME "bcm6368-pinctrl" +#define BCM6368_NUM_GPIOS 38 + +#define BANK_SIZE sizeof(uint32_t) +#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) + +#define BCM6368_DIROUT_REG 0x04 +#define BCM6368_DATA_REG 0x0c +#define BCM6368_MODE_REG 0x18 +#define BCM6368_BASEMODE_REG 0x38 +#define BCM6368_BASEMODE_MASK 0x7 +#define BCM6368_BASEMODE_GPIO 0x0 +#define BCM6368_BASEMODE_UART1 0x1 + +struct bcm6368_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6368_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned dir_out:16; + unsigned basemode:3; +}; + +struct bcm6368_pinctrl { + struct device *dev; + struct regmap *regs; + struct regmap_field *overlays; + + struct pinctrl_dev *pctl_dev; + struct gpio_chip gpio_chip; + struct pinctrl_desc pctl_desc; + struct pinctrl_gpio_range gpio_range; +}; + +#define BCM6368_BASEMODE_PIN(a, b) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)true \ + } + +static const struct pinctrl_pin_desc bcm6368_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + BCM6368_BASEMODE_PIN(30, "gpio30"), + BCM6368_BASEMODE_PIN(31, "gpio31"), + BCM6368_BASEMODE_PIN(32, "gpio32"), + BCM6368_BASEMODE_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned uart1_grp_pins[] = { 30, 31, 32, 33 }; + +#define BCM6368_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6368_pingroup bcm6368_groups[] = { + BCM6368_GROUP(gpio0), + BCM6368_GROUP(gpio1), + BCM6368_GROUP(gpio2), + BCM6368_GROUP(gpio3), + BCM6368_GROUP(gpio4), + BCM6368_GROUP(gpio5), + BCM6368_GROUP(gpio6), + BCM6368_GROUP(gpio7), + BCM6368_GROUP(gpio8), + BCM6368_GROUP(gpio9), + BCM6368_GROUP(gpio10), + BCM6368_GROUP(gpio11), + BCM6368_GROUP(gpio12), + BCM6368_GROUP(gpio13), + BCM6368_GROUP(gpio14), + BCM6368_GROUP(gpio15), + BCM6368_GROUP(gpio16), + BCM6368_GROUP(gpio17), + BCM6368_GROUP(gpio18), + BCM6368_GROUP(gpio19), + BCM6368_GROUP(gpio20), + BCM6368_GROUP(gpio21), + BCM6368_GROUP(gpio22), + BCM6368_GROUP(gpio23), + BCM6368_GROUP(gpio24), + BCM6368_GROUP(gpio25), + BCM6368_GROUP(gpio26), + BCM6368_GROUP(gpio27), + BCM6368_GROUP(gpio28), + BCM6368_GROUP(gpio29), + BCM6368_GROUP(gpio30), + BCM6368_GROUP(gpio31), + BCM6368_GROUP(uart1_grp), +}; + +static const char * const analog_afe_0_groups[] = { + "gpio0", +}; + +static const char * const analog_afe_1_groups[] = { + "gpio1", +}; + +static const char * const sys_irq_groups[] = { + "gpio2", +}; + +static const char * const serial_led_data_groups[] = { + "gpio3", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio4", +}; + +static const char * const inet_led_groups[] = { + "gpio5", +}; + +static const char * const ephy0_led_groups[] = { + "gpio6", +}; + +static const char * const ephy1_led_groups[] = { + "gpio7", +}; + +static const char * const ephy2_led_groups[] = { + "gpio8", +}; + +static const char * const ephy3_led_groups[] = { + "gpio9", +}; + +static const char * const robosw_led_data_groups[] = { + "gpio10", +}; + +static const char * const robosw_led_clk_groups[] = { + "gpio11", +}; + +static const char * const robosw_led0_groups[] = { + "gpio12", +}; + +static const char * const robosw_led1_groups[] = { + "gpio13", +}; + +static const char * const usb_device_led_groups[] = { + "gpio14", +}; + +static const char * const pci_req1_groups[] = { + "gpio16", +}; + +static const char * const pci_gnt1_groups[] = { + "gpio17", +}; + +static const char * const pci_intb_groups[] = { + "gpio18", +}; + +static const char * const pci_req0_groups[] = { + "gpio19", +}; + +static const char * const pci_gnt0_groups[] = { + "gpio20", +}; + +static const char * const pcmcia_cd1_groups[] = { + "gpio22", +}; + +static const char * const pcmcia_cd2_groups[] = { + "gpio23", +}; + +static const char * const pcmcia_vs1_groups[] = { + "gpio24", +}; + +static const char * const pcmcia_vs2_groups[] = { + "gpio25", +}; + +static const char * const ebi_cs2_groups[] = { + "gpio26", +}; + +static const char * const ebi_cs3_groups[] = { + "gpio27", +}; + +static const char * const spi_cs2_groups[] = { + "gpio28", +}; + +static const char * const spi_cs3_groups[] = { + "gpio29", +}; + +static const char * const spi_cs4_groups[] = { + "gpio30", +}; + +static const char * const spi_cs5_groups[] = { + "gpio31", +}; + +static const char * const uart1_groups[] = { + "uart1_grp", +}; + +#define BCM6368_FUN(n, out) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .dir_out = out, \ + } + +#define BCM6368_BASEMODE_FUN(n, val, out) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .basemode = BCM6368_BASEMODE_##val, \ + .dir_out = out, \ + } + +static const struct bcm6368_function bcm6368_funcs[] = { + BCM6368_FUN(analog_afe_0, 1), + BCM6368_FUN(analog_afe_1, 1), + BCM6368_FUN(sys_irq, 1), + BCM6368_FUN(serial_led_data, 1), + BCM6368_FUN(serial_led_clk, 1), + BCM6368_FUN(inet_led, 1), + BCM6368_FUN(ephy0_led, 1), + BCM6368_FUN(ephy1_led, 1), + BCM6368_FUN(ephy2_led, 1), + BCM6368_FUN(ephy3_led, 1), + BCM6368_FUN(robosw_led_data, 1), + BCM6368_FUN(robosw_led_clk, 1), + BCM6368_FUN(robosw_led0, 1), + BCM6368_FUN(robosw_led1, 1), + BCM6368_FUN(usb_device_led, 1), + BCM6368_FUN(pci_req1, 0), + BCM6368_FUN(pci_gnt1, 0), + BCM6368_FUN(pci_intb, 0), + BCM6368_FUN(pci_req0, 0), + BCM6368_FUN(pci_gnt0, 0), + BCM6368_FUN(pcmcia_cd1, 0), + BCM6368_FUN(pcmcia_cd2, 0), + BCM6368_FUN(pcmcia_vs1, 0), + BCM6368_FUN(pcmcia_vs2, 0), + BCM6368_FUN(ebi_cs2, 1), + BCM6368_FUN(ebi_cs3, 1), + BCM6368_FUN(spi_cs2, 1), + BCM6368_FUN(spi_cs3, 1), + BCM6368_FUN(spi_cs4, 1), + BCM6368_FUN(spi_cs5, 1), + BCM6368_BASEMODE_FUN(uart1, UART1, 0x6), +}; + +static inline unsigned int bcm6368_bank_pin(unsigned int pin) +{ + return pin % PINS_PER_BANK; +} + +static inline unsigned int bcm6368_reg_off(unsigned int reg, unsigned int pin) +{ + return reg - (pin / PINS_PER_BANK) * BANK_SIZE; +} + +static int bcm6368_gpio_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin); + unsigned int bank_pin = bcm6368_bank_pin(pin); + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an input GPIO + */ + ret = pinctrl_gpio_direction_input(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); + + return 0; +} + +static int bcm6368_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin); + unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin); + unsigned int bank_pin = bcm6368_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an output GPIO + */ + ret = pinctrl_gpio_direction_output(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); + + return 0; +} + +static int bcm6368_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin); + unsigned int bank_pin = bcm6368_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, data, &val); + + return !!(val & BIT(bank_pin)); +} + +static int bcm6368_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin); + unsigned int bank_pin = bcm6368_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, dirout, &val); + + if (val & BIT(bank_pin)) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static void bcm6368_gpio_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin); + unsigned int bank_pin = bcm6368_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); +} + +static int bcm6368_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +{ + char irq_name[7]; + + sprintf(irq_name, "gpio%d", gpio); + + return of_irq_get_byname(chip->of_node, irq_name); +} + +static int bcm6368_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6368_groups); +} + +static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6368_groups[group].name; +} + +static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6368_groups[group].pins; + *num_pins = bcm6368_groups[group].num_pins; + + return 0; +} + +static int bcm6368_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6368_funcs); +} + +static const char *bcm6368_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6368_funcs[selector].name; +} + +static int bcm6368_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6368_funcs[selector].groups; + *num_groups = bcm6368_funcs[selector].num_groups; + + return 0; +} + +static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm6368_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6368_pingroup *pg = &bcm6368_groups[group]; + const struct bcm6368_function *fun = &bcm6368_funcs[selector]; + int i, pin; + + if (fun->basemode) { + unsigned int mask = 0; + + for (i = 0; i < pg->num_pins; i++) { + pin = pg->pins[i]; + if (pin < PINS_PER_BANK) + mask |= BIT(pin); + } + + regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0); + regmap_field_write(pc->overlays, fun->basemode); + } else { + pin = pg->pins[0]; + + if (bcm6368_pins[pin].drv_data) + regmap_field_write(pc->overlays, + BCM6368_BASEMODE_GPIO); + + regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin), + BIT(pin)); + } + + for (pin = 0; pin < pg->num_pins; pin++) { + int hw_gpio = bcm6368_pins[pin].number; + struct gpio_chip *gc = &pc->gpio_chip; + + if (fun->dir_out & BIT(pin)) + gc->direction_output(gc, hw_gpio, 0); + else + gc->direction_input(gc, hw_gpio); + } + + return 0; +} + +static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm6368_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + if (offset >= PINS_PER_BANK && !bcm6368_pins[offset].drv_data) + return 0; + + /* disable all functions using this pin */ + if (offset < PINS_PER_BANK) + regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0); + + if (bcm6368_pins[offset].drv_data) + regmap_field_write(pc->overlays, BCM6368_BASEMODE_GPIO); + + return 0; +} + +static struct pinctrl_ops bcm6368_pctl_ops = { + .get_groups_count = bcm6368_pinctrl_get_group_count, + .get_group_name = bcm6368_pinctrl_get_group_name, + .get_group_pins = bcm6368_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static struct pinmux_ops bcm6368_pmx_ops = { + .get_functions_count = bcm6368_pinctrl_get_func_count, + .get_function_name = bcm6368_pinctrl_get_func_name, + .get_function_groups = bcm6368_pinctrl_get_groups, + .set_mux = bcm6368_pinctrl_set_mux, + .gpio_request_enable = bcm6368_gpio_request_enable, + .strict = true, +}; + +static int bcm6368_pinctrl_probe(struct platform_device *pdev) +{ + struct reg_field overlays = REG_FIELD(BCM6368_BASEMODE_REG, 0, 15); + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm6368_pinctrl *pc; + int err; + + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + platform_set_drvdata(pdev, pc); + pc->dev = dev; + + pc->regs = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(pc->regs)) + return PTR_ERR(pc->regs); + + pc->overlays = devm_regmap_field_alloc(&pdev->dev, pc->regs, overlays); + if (IS_ERR(pc->overlays)) + return PTR_ERR(pc->overlays); + + /* disable all muxes by default */ + regmap_field_write(pc->overlays, 0); + + pc->gpio_chip.label = MODULE_NAME; + pc->gpio_chip.owner = THIS_MODULE; + pc->gpio_chip.request = gpiochip_generic_request; + pc->gpio_chip.free = gpiochip_generic_free; + pc->gpio_chip.direction_input = bcm6368_gpio_direction_input; + pc->gpio_chip.direction_output = bcm6368_gpio_direction_output; + pc->gpio_chip.get_direction = bcm6368_gpio_get_direction; + pc->gpio_chip.get = bcm6368_gpio_get; + pc->gpio_chip.set = bcm6368_gpio_set; + pc->gpio_chip.set_config = gpiochip_generic_config; + pc->gpio_chip.base = -1; + pc->gpio_chip.ngpio = BCM6368_NUM_GPIOS; + pc->gpio_chip.can_sleep = false; + pc->gpio_chip.parent = dev; + pc->gpio_chip.of_node = np; + + if (of_get_property(np, "interrupt-names", NULL)) + pc->gpio_chip.to_irq = bcm6368_gpio_to_irq; + + err = gpiochip_add_data(&pc->gpio_chip, pc); + if (err) { + dev_err(dev, "could not add GPIO chip\n"); + return err; + } + + pc->pctl_desc.name = MODULE_NAME, + pc->pctl_desc.pins = bcm6368_pins, + pc->pctl_desc.npins = ARRAY_SIZE(bcm6368_pins), + pc->pctl_desc.pctlops = &bcm6368_pctl_ops, + pc->pctl_desc.pmxops = &bcm6368_pmx_ops, + pc->pctl_desc.owner = THIS_MODULE, + + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) { + gpiochip_remove(&pc->gpio_chip); + return PTR_ERR(pc->pctl_dev); + } + + pc->gpio_range.name = MODULE_NAME; + pc->gpio_range.npins = BCM6368_NUM_GPIOS; + pc->gpio_range.base = pc->gpio_chip.base; + pc->gpio_range.gc = &pc->gpio_chip; + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); + + dev_info(dev, "registered\n"); + + return 0; +} + +static const struct of_device_id bcm6368_pinctrl_match[] = { + { .compatible = "brcm,bcm6368-pinctrl", }, + { }, +}; + +static struct platform_driver bcm6368_pinctrl_driver = { + .probe = bcm6368_pinctrl_probe, + .driver = { + .name = MODULE_NAME, + .of_match_table = bcm6368_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6368_pinctrl_driver); From patchwork Thu Feb 25 16:42:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387902 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 6B385C43381 for ; Thu, 25 Feb 2021 16:44:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 41FD664F24 for ; Thu, 25 Feb 2021 16:44:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232923AbhBYQo1 (ORCPT ); Thu, 25 Feb 2021 11:44:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233452AbhBYQn6 (ORCPT ); Thu, 25 Feb 2021 11:43:58 -0500 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3DF0C061794; Thu, 25 Feb 2021 08:42:27 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id k66so5437397wmf.1; Thu, 25 Feb 2021 08:42:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=7fjB1e++hLR8ADNwUG9q+2gJ3lhPcwoGxct0PrcHySc=; b=ebwloGE/6e1DXLMiQg4+dsaXBVxWm2WTm0j/SKoFm8m9jDAiGrGC08F8XRU6hwRXbX vf+QL0ue/DowmHVeOD3kXUzLzWZjimJ4CJkNsQz9wXhF9ZWVd1T2hHGdxFx2zLA7VbcI XNoDOD2nCZYxvHR99GEh6XIbvOmIg7kXqN4KWCQRlehlDETcFB2HL+FvGJCqN/Wld625 MF/uNUKLzYthoLC7alXJZfJ7rL1/JksQBsrx6nmFnuotD7SZpgAagM5ZYfPpNfEtwj9W csl/rp1j40ukZ9PVUCGoU7z/aayEW4ljga8rjrfGqmxaY0mkD31GDjIP2ViIZYqkWYoB Tr4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7fjB1e++hLR8ADNwUG9q+2gJ3lhPcwoGxct0PrcHySc=; b=PMBjxslON8ZiNnPk9u2AcyvsK8xvJo7wkAPEUCu1Pze4nYsIEuCCiOJCmiLvtB/qHk nwuaqAeu9ecdj5jR7rVaqp/xvbLzzrBY8KN9cQujd4KInpE4jvGliVEbak2xR337ortN VK01C/537xtMhdQw7h1dAeLDn22qNMkzC6BFXVCTUI1A1bbWsm3IfMBnfDuQhfqmoo0B qbuxPxmbwq5OIBKwZvLryj7e26J7XLqgBHGjLa8u/xnwAwVB3ylTODwK9PtZD5r6Q/Q9 ocCfTf9+mLAYxPqh7FlkeYu36Pb8OovGQRl/0Yf3ou9bfH2RCBA8NbIAK1tMVQxHiTVL k7/Q== X-Gm-Message-State: AOAM5326/x44K7fml+e/gr55ac4e1WvCWI25o5fL2V6Iq859wL7Gzjps CzLuUO3aM4LZDaY6I/+zbFw= X-Google-Smtp-Source: ABdhPJxY3WPedcs0R1kilFOnbyH4pzdu6nx2ZKqZ0K84bgCv8yBEh00LshHAnm1uXVFEie750xO9Ag== X-Received: by 2002:a05:600c:4c17:: with SMTP id d23mr4052587wmp.116.1614271346539; Thu, 25 Feb 2021 08:42:26 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:26 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 09/12] Documentation: add BCM63268 pincontroller binding documentation Date: Thu, 25 Feb 2021 17:42:13 +0100 Message-Id: <20210225164216.21124-10-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add binding documentation for the pincontrol core found in the BCM63268 family SoCs. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- .../pinctrl/brcm,bcm63268-pinctrl.yaml | 198 ++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml new file mode 100644 index 000000000000..00a681772319 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml @@ -0,0 +1,198 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm63268-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM63268 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: |+ + The pin controller node should be the child of a syscon node. + + Refer to the bindings described in + Documentation/devicetree/bindings/mfd/syscon.yaml + +properties: + compatible: + const: brcm,bcm63268-pinctrl + + gpio-controller: true + + '#gpio-cells': + description: + Specifies the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + interrupts-extended: + description: + One interrupt per each of the 4 GPIO ports supported by the controller, + sorted by port number ascending order. + minItems: 4 + maxItems: 4 + +patternProperties: + '^.*$': + if: + type: object + then: + properties: + function: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ serial_led_clk, serial_led_data, hsspi_cs4, hsspi_cs5, + hsspi_cs6, hsspi_cs7, adsl_spi_miso, adsl_spi_mosi, + vreq_clk, pcie_clkreq_b, robosw_led_clk, robosw_led_data, + nand, gpio35_alt, dectpd, vdsl_phy_override_0, + vdsl_phy_override_1, vdsl_phy_override_2, + vdsl_phy_override_3, dsl_gpio8, dsl_gpio9 ] + + pins: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ gpio0, gpio1, gpio16, gpio17, gpio8, gpio9, gpio18, gpio19, + gpio22, gpio23, gpio30, gpio31, nand_grp, gpio35 + dectpd_grp, vdsl_phy_override_0_grp, + vdsl_phy_override_1_grp, vdsl_phy_override_2_grp, + vdsl_phy_override_3_grp, dsl_gpio8, dsl_gpio9 ] + +required: + - compatible + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +examples: + - | + gpio@100000c0 { + compatible = "syscon", "simple-mfd"; + reg = <0x100000c0 0x80>; + + pinctrl: pinctrl { + compatible = "brcm,bcm63268-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc 0 0>, + <&ext_intc 1 0>, + <&ext_intc 2 0>, + <&ext_intc 3 0>; + interrupt-names = "gpio32", + "gpio33", + "gpio34", + "gpio35"; + + pinctrl_serial_led: serial_led { + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio0"; + }; + + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio1"; + }; + }; + + pinctrl_hsspi_cs4: hsspi_cs4 { + function = "hsspi_cs4"; + pins = "gpio16"; + }; + + pinctrl_hsspi_cs5: hsspi_cs5 { + function = "hsspi_cs5"; + pins = "gpio17"; + }; + + pinctrl_hsspi_cs6: hsspi_cs6 { + function = "hsspi_cs6"; + pins = "gpio8"; + }; + + pinctrl_hsspi_cs7: hsspi_cs7 { + function = "hsspi_cs7"; + pins = "gpio9"; + }; + + pinctrl_adsl_spi: adsl_spi { + pinctrl_adsl_spi_miso: adsl_spi_miso { + function = "adsl_spi_miso"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi { + function = "adsl_spi_mosi"; + pins = "gpio19"; + }; + }; + + pinctrl_vreq_clk: vreq_clk { + function = "vreq_clk"; + pins = "gpio22"; + }; + + pinctrl_pcie_clkreq_b: pcie_clkreq_b { + function = "pcie_clkreq_b"; + pins = "gpio23"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk { + function = "robosw_led_clk"; + pins = "gpio30"; + }; + + pinctrl_robosw_led_data: robosw_led_data { + function = "robosw_led_data"; + pins = "gpio31"; + }; + + pinctrl_nand: nand { + function = "nand"; + group = "nand_grp"; + }; + + pinctrl_gpio35_alt: gpio35_alt { + function = "gpio35_alt"; + pin = "gpio35"; + }; + + pinctrl_dectpd: dectpd { + function = "dectpd"; + group = "dectpd_grp"; + }; + + pinctrl_vdsl_phy_override_0: vdsl_phy_override_0 { + function = "vdsl_phy_override_0"; + group = "vdsl_phy_override_0_grp"; + }; + + pinctrl_vdsl_phy_override_1: vdsl_phy_override_1 { + function = "vdsl_phy_override_1"; + group = "vdsl_phy_override_1_grp"; + }; + + pinctrl_vdsl_phy_override_2: vdsl_phy_override_2 { + function = "vdsl_phy_override_2"; + group = "vdsl_phy_override_2_grp"; + }; + + pinctrl_vdsl_phy_override_3: vdsl_phy_override_3 { + function = "vdsl_phy_override_3"; + group = "vdsl_phy_override_3_grp"; + }; + + pinctrl_dsl_gpio8: dsl_gpio8 { + function = "dsl_gpio8"; + group = "dsl_gpio8"; + }; + + pinctrl_dsl_gpio9: dsl_gpio9 { + function = "dsl_gpio9"; + group = "dsl_gpio9"; + }; + }; + }; From patchwork Thu Feb 25 16:42:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387901 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 91E80C4332B for ; Thu, 25 Feb 2021 16:44:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5A56C64F19 for ; Thu, 25 Feb 2021 16:44:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233541AbhBYQof (ORCPT ); Thu, 25 Feb 2021 11:44:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54152 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233451AbhBYQn6 (ORCPT ); Thu, 25 Feb 2021 11:43:58 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7E0BC061797; Thu, 25 Feb 2021 08:42:28 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id p3so5185099wmc.2; Thu, 25 Feb 2021 08:42:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=X5NgHc9FaWWZxT4P1Jqwe21zSmIseQRtugtLqJFJw7s=; b=DYobSuxsjaRNsfW4bCS4u4US+mkP0xFDjxorbq3GCgvbbFlA+e4QenZ0AYRk1+0gY3 +Wso8SQ3HJatAoj26/KIailwIk0ZqiklkHfzcbie11bKzZIdZ0JLYPVdhPq8aeYR3uIT F/LfReXShC412njIZZm8zS47zBxV1LROPsZfkCIRo0PAI16RIqjaRBw4cNkr+YtfZ1JI J0dgo/TYZIeFz2GicsgQ4DRpa93quWx/TdOiVzksW8g3drd1RS5OiFAlNWEWCldq3Ioc f5Oyq+FgrGLyTkA63ZVXkxNLxc+KgR7ouqrU7ZN6S/wqVf4V/YjJQDhgeSSxOLIuYb4o lVtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=X5NgHc9FaWWZxT4P1Jqwe21zSmIseQRtugtLqJFJw7s=; b=c3t4nI/9gcsoNunwixKc7QlwcakzsiHuYdTrzsTfhwquXtMKJ5h9zvAB/F56x28geK DSPojhihg99NgBl7wWX9nrx/TmaJYLOeO3Lz8o/QRnW1E1rnnzTy1x80LqMwTMfmEvWr OOmQe7SbdOiBQeGcYHzBdiOK+DEjtuCdQBGFmbMFyi5Pe4naDrquEfEYbZxUPg60fmqy Ixpgh0yPmnLWwLL6e/COxXnlVIRMmRKoVgie9nKRoBKGGxdZftUrenCTClrgZEVEyBHU aMUKd+1JBQhgSa2b8qOOhuYIFuuJopRd4+JwTCtfy2LpWfGyC5u02x5x89dHFd1T/wuQ dHVQ== X-Gm-Message-State: AOAM5331GS1c2khyHhusz29E+vE4dBefWh8I8daJGbcd4PPUSJdkHQJZ p9CNsAY2xueYh0OAYihgeHM= X-Google-Smtp-Source: ABdhPJz3S5axa1PQhwgZ4ey94uunBe/47RKj5Le3aHBT493JxVnIgUKQ+BdsyguWLv9gJjcUKrE17Q== X-Received: by 2002:a1c:7c17:: with SMTP id x23mr4062477wmc.95.1614271347284; Thu, 25 Feb 2021 08:42:27 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:27 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 10/12] pinctrl: add a pincontrol driver for BCM63268 Date: Thu, 25 Feb 2021 17:42:14 +0100 Message-Id: <20210225164216.21124-11-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs to different functions. Depending on the mux, these are either single pin configurations or whole pin groups. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- drivers/pinctrl/bcm/Kconfig | 11 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm63268.c | 821 +++++++++++++++++++++++++ 3 files changed, 833 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index b8109f0a692c..8918600466b4 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -73,6 +73,17 @@ config PINCTRL_BCM6368 help Say Y here to enable the Broadcom BCM6368 GPIO driver. +config PINCTRL_BCM63268 + bool "Broadcom BCM63268 GPIO driver" + depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) + select PINMUX + select PINCONF + select GENERIC_PINCONF + select MFD_SYSCON + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM63268 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 2d9c99a41c51..d5a8ee914fc6 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o obj-$(CONFIG_PINCTRL_BCM6368) += pinctrl-bcm6368.o +obj-$(CONFIG_PINCTRL_BCM63268) += pinctrl-bcm63268.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63268.c b/drivers/pinctrl/bcm/pinctrl-bcm63268.c new file mode 100644 index 000000000000..b58e24d2cd01 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c @@ -0,0 +1,821 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM63268 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define MODULE_NAME "bcm63268-pinctrl" +#define BCM63268_NUM_GPIOS 52 +#define BCM63268_NUM_LEDS 24 + +#define BANK_SIZE sizeof(uint32_t) +#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) + +#define BCM63268_DIROUT_REG 0x04 +#define BCM63268_DATA_REG 0x0c +#define BCM63268_LED_REG 0x10 +#define BCM63268_MODE_REG 0x18 +#define BCM63268_CTRL_REG 0x1c +#define BCM63268_BASEMODE_REG 0x38 +#define BCM63268_BASEMODE_NAND BIT(2) /* GPIOs 2-7, 24-31 */ +#define BCM63268_BASEMODE_GPIO35 BIT(4) /* GPIO 35 */ +#define BCM63268_BASEMODE_DECTPD BIT(5) /* GPIOs 8/9 */ +#define BCM63268_BASEMODE_VDSL_PHY_0 BIT(6) /* GPIOs 10/11 */ +#define BCM63268_BASEMODE_VDSL_PHY_1 BIT(7) /* GPIOs 12/13 */ +#define BCM63268_BASEMODE_VDSL_PHY_2 BIT(8) /* GPIOs 24/25 */ +#define BCM63268_BASEMODE_VDSL_PHY_3 BIT(9) /* GPIOs 26/27 */ + +enum bcm63268_pinctrl_reg { + BCM63268_LEDCTRL, + BCM63268_MODE, + BCM63268_CTRL, + BCM63268_BASEMODE, +}; + +struct bcm63268_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm63268_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + enum bcm63268_pinctrl_reg reg; + uint32_t mask; +}; + +struct bcm63268_pinctrl { + struct device *dev; + struct regmap *regs; + + struct pinctrl_dev *pctl_dev; + struct gpio_chip gpio_chip; + struct pinctrl_desc pctl_desc; + struct pinctrl_gpio_range gpio_range; +}; + +#define BCM63268_PIN(a, b, basemode) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(basemode) \ + } + +static const struct pinctrl_pin_desc bcm63268_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + BCM63268_PIN(2, "gpio2", BCM63268_BASEMODE_NAND), + BCM63268_PIN(3, "gpio3", BCM63268_BASEMODE_NAND), + BCM63268_PIN(4, "gpio4", BCM63268_BASEMODE_NAND), + BCM63268_PIN(5, "gpio5", BCM63268_BASEMODE_NAND), + BCM63268_PIN(6, "gpio6", BCM63268_BASEMODE_NAND), + BCM63268_PIN(7, "gpio7", BCM63268_BASEMODE_NAND), + BCM63268_PIN(8, "gpio8", BCM63268_BASEMODE_DECTPD), + BCM63268_PIN(9, "gpio9", BCM63268_BASEMODE_DECTPD), + BCM63268_PIN(10, "gpio10", BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_PIN(11, "gpio11", BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_PIN(12, "gpio12", BCM63268_BASEMODE_VDSL_PHY_1), + BCM63268_PIN(13, "gpio13", BCM63268_BASEMODE_VDSL_PHY_1), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + BCM63268_PIN(24, "gpio24", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_PIN(25, "gpio25", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_PIN(26, "gpio26", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3), + BCM63268_PIN(27, "gpio27", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3), + BCM63268_PIN(28, "gpio28", BCM63268_BASEMODE_NAND), + BCM63268_PIN(29, "gpio29", BCM63268_BASEMODE_NAND), + BCM63268_PIN(30, "gpio30", BCM63268_BASEMODE_NAND), + BCM63268_PIN(31, "gpio31", BCM63268_BASEMODE_NAND), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), + PINCTRL_PIN(48, "gpio48"), + PINCTRL_PIN(49, "gpio49"), + PINCTRL_PIN(50, "gpio50"), + PINCTRL_PIN(51, "gpio51"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; +static unsigned gpio48_pins[] = { 48 }; +static unsigned gpio49_pins[] = { 49 }; +static unsigned gpio50_pins[] = { 50 }; +static unsigned gpio51_pins[] = { 51 }; + +static unsigned nand_grp_pins[] = { + 2, 3, 4, 5, 6, 7, 24, + 25, 26, 27, 28, 29, 30, 31, +}; + +static unsigned dectpd_grp_pins[] = { 8, 9 }; +static unsigned vdsl_phy0_grp_pins[] = { 10, 11 }; +static unsigned vdsl_phy1_grp_pins[] = { 12, 13 }; +static unsigned vdsl_phy2_grp_pins[] = { 24, 25 }; +static unsigned vdsl_phy3_grp_pins[] = { 26, 27 }; + +#define BCM63268_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm63268_pingroup bcm63268_groups[] = { + BCM63268_GROUP(gpio0), + BCM63268_GROUP(gpio1), + BCM63268_GROUP(gpio2), + BCM63268_GROUP(gpio3), + BCM63268_GROUP(gpio4), + BCM63268_GROUP(gpio5), + BCM63268_GROUP(gpio6), + BCM63268_GROUP(gpio7), + BCM63268_GROUP(gpio8), + BCM63268_GROUP(gpio9), + BCM63268_GROUP(gpio10), + BCM63268_GROUP(gpio11), + BCM63268_GROUP(gpio12), + BCM63268_GROUP(gpio13), + BCM63268_GROUP(gpio14), + BCM63268_GROUP(gpio15), + BCM63268_GROUP(gpio16), + BCM63268_GROUP(gpio17), + BCM63268_GROUP(gpio18), + BCM63268_GROUP(gpio19), + BCM63268_GROUP(gpio20), + BCM63268_GROUP(gpio21), + BCM63268_GROUP(gpio22), + BCM63268_GROUP(gpio23), + BCM63268_GROUP(gpio24), + BCM63268_GROUP(gpio25), + BCM63268_GROUP(gpio26), + BCM63268_GROUP(gpio27), + BCM63268_GROUP(gpio28), + BCM63268_GROUP(gpio29), + BCM63268_GROUP(gpio30), + BCM63268_GROUP(gpio31), + BCM63268_GROUP(gpio32), + BCM63268_GROUP(gpio33), + BCM63268_GROUP(gpio34), + BCM63268_GROUP(gpio35), + BCM63268_GROUP(gpio36), + BCM63268_GROUP(gpio37), + BCM63268_GROUP(gpio38), + BCM63268_GROUP(gpio39), + BCM63268_GROUP(gpio40), + BCM63268_GROUP(gpio41), + BCM63268_GROUP(gpio42), + BCM63268_GROUP(gpio43), + BCM63268_GROUP(gpio44), + BCM63268_GROUP(gpio45), + BCM63268_GROUP(gpio46), + BCM63268_GROUP(gpio47), + BCM63268_GROUP(gpio48), + BCM63268_GROUP(gpio49), + BCM63268_GROUP(gpio50), + BCM63268_GROUP(gpio51), + + /* multi pin groups */ + BCM63268_GROUP(nand_grp), + BCM63268_GROUP(dectpd_grp), + BCM63268_GROUP(vdsl_phy0_grp), + BCM63268_GROUP(vdsl_phy1_grp), + BCM63268_GROUP(vdsl_phy2_grp), + BCM63268_GROUP(vdsl_phy3_grp), +}; + +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio0", +}; + +static const char * const serial_led_data_groups[] = { + "gpio1", +}; + +static const char * const hsspi_cs4_groups[] = { + "gpio16", +}; + +static const char * const hsspi_cs5_groups[] = { + "gpio17", +}; + +static const char * const hsspi_cs6_groups[] = { + "gpio8", +}; + +static const char * const hsspi_cs7_groups[] = { + "gpio9", +}; + +static const char * const uart1_scts_groups[] = { + "gpio10", + "gpio24", +}; + +static const char * const uart1_srts_groups[] = { + "gpio11", + "gpio25", +}; + +static const char * const uart1_sdin_groups[] = { + "gpio12", + "gpio26", +}; + +static const char * const uart1_sdout_groups[] = { + "gpio13", + "gpio27", +}; + +static const char * const ntr_pulse_in_groups[] = { + "gpio14", + "gpio28", +}; + +static const char * const dsl_ntr_pulse_out_groups[] = { + "gpio15", + "gpio29", +}; + +static const char * const adsl_spi_miso_groups[] = { + "gpio18", +}; + +static const char * const adsl_spi_mosi_groups[] = { + "gpio19", +}; + +static const char * const vreg_clk_groups[] = { + "gpio22", +}; + +static const char * const pcie_clkreq_b_groups[] = { + "gpio23", +}; + +static const char * const switch_led_clk_groups[] = { + "gpio30", +}; + +static const char * const switch_led_data_groups[] = { + "gpio31", +}; + +static const char * const wifi_groups[] = { + "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37", + "gpio38", + "gpio39", + "gpio40", + "gpio41", + "gpio42", + "gpio43", + "gpio44", + "gpio45", + "gpio46", + "gpio47", + "gpio48", + "gpio49", + "gpio50", + "gpio51", +}; + +static const char * const nand_groups[] = { + "nand_grp", +}; + +static const char * const dectpd_groups[] = { + "dectpd_grp", +}; + +static const char * const vdsl_phy_override_0_groups[] = { + "vdsl_phy_override_0_grp", +}; + +static const char * const vdsl_phy_override_1_groups[] = { + "vdsl_phy_override_1_grp", +}; + +static const char * const vdsl_phy_override_2_groups[] = { + "vdsl_phy_override_2_grp", +}; + +static const char * const vdsl_phy_override_3_groups[] = { + "vdsl_phy_override_3_grp", +}; + +#define BCM63268_LED_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_LEDCTRL, \ + } + +#define BCM63268_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_MODE, \ + } + +#define BCM63268_CTRL_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_CTRL, \ + } + +#define BCM63268_BASEMODE_FUN(n, val) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_BASEMODE, \ + .mask = val, \ + } + +static const struct bcm63268_function bcm63268_funcs[] = { + BCM63268_LED_FUN(led), + BCM63268_MODE_FUN(serial_led_clk), + BCM63268_MODE_FUN(serial_led_data), + BCM63268_MODE_FUN(hsspi_cs6), + BCM63268_MODE_FUN(hsspi_cs7), + BCM63268_MODE_FUN(uart1_scts), + BCM63268_MODE_FUN(uart1_srts), + BCM63268_MODE_FUN(uart1_sdin), + BCM63268_MODE_FUN(uart1_sdout), + BCM63268_MODE_FUN(ntr_pulse_in), + BCM63268_MODE_FUN(dsl_ntr_pulse_out), + BCM63268_MODE_FUN(hsspi_cs4), + BCM63268_MODE_FUN(hsspi_cs5), + BCM63268_MODE_FUN(adsl_spi_miso), + BCM63268_MODE_FUN(adsl_spi_mosi), + BCM63268_MODE_FUN(vreg_clk), + BCM63268_MODE_FUN(pcie_clkreq_b), + BCM63268_MODE_FUN(switch_led_clk), + BCM63268_MODE_FUN(switch_led_data), + BCM63268_CTRL_FUN(wifi), + BCM63268_BASEMODE_FUN(nand, BCM63268_BASEMODE_NAND), + BCM63268_BASEMODE_FUN(dectpd, BCM63268_BASEMODE_DECTPD), + BCM63268_BASEMODE_FUN(vdsl_phy_override_0, + BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_BASEMODE_FUN(vdsl_phy_override_1, + BCM63268_BASEMODE_VDSL_PHY_1), + BCM63268_BASEMODE_FUN(vdsl_phy_override_2, + BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_BASEMODE_FUN(vdsl_phy_override_3, + BCM63268_BASEMODE_VDSL_PHY_3), +}; + +static inline unsigned int bcm63268_bank_pin(unsigned int pin) +{ + return pin % PINS_PER_BANK; +} + +static inline unsigned int bcm63268_reg_off(unsigned int reg, unsigned int pin) +{ + return reg - (pin / PINS_PER_BANK) * BANK_SIZE; +} + +static int bcm63268_gpio_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin); + unsigned int bank_pin = bcm63268_bank_pin(pin); + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an input GPIO + */ + ret = pinctrl_gpio_direction_input(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); + + return 0; +} + +static int bcm63268_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin); + unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin); + unsigned int bank_pin = bcm63268_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an output GPIO + */ + ret = pinctrl_gpio_direction_output(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); + + return 0; +} + +static int bcm63268_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin); + unsigned int bank_pin = bcm63268_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, data, &val); + + return !!(val & BIT(bank_pin)); +} + +static int bcm63268_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin); + unsigned int bank_pin = bcm63268_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, dirout, &val); + + if (val & BIT(bank_pin)) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static void bcm63268_gpio_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin); + unsigned int bank_pin = bcm63268_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); +} + +static int bcm63268_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +{ + char irq_name[7]; + + sprintf(irq_name, "gpio%d", gpio); + + return of_irq_get_byname(chip->of_node, irq_name); +} + +static int bcm63268_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm63268_groups); +} + +static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm63268_groups[group].name; +} + +static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, + const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm63268_groups[group].pins; + *num_pins = bcm63268_groups[group].num_pins; + + return 0; +} + +static int bcm63268_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm63268_funcs); +} + +static const char *bcm63268_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm63268_funcs[selector].name; +} + +static int bcm63268_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm63268_funcs[selector].groups; + *num_groups = bcm63268_funcs[selector].num_groups; + + return 0; +} + +static void bcm63268_set_gpio(struct bcm63268_pinctrl *pc, unsigned pin) +{ + const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin]; + unsigned int basemode = (unsigned long) desc->drv_data; + unsigned int mask = BIT(bcm63268_bank_pin(pin)); + + if (basemode) + regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode, + 0); + + if (pin < PINS_PER_BANK) { + /* base mode: 0 => gpio, 1 => mux function */ + regmap_update_bits(pc->regs, BCM63268_MODE_REG, mask, 0); + + /* pins 0-23 might be muxed to led */ + if (pin < BCM63268_NUM_LEDS) + regmap_update_bits(pc->regs, BCM63268_LED_REG, mask, + 0); + } else if (pin < BCM63268_NUM_GPIOS) { + /* ctrl reg: 0 => wifi function, 1 => gpio */ + regmap_update_bits(pc->regs, BCM63268_CTRL_REG, mask, mask); + } +} + +static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63268_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm63268_pingroup *pg = &bcm63268_groups[group]; + const struct bcm63268_function *f = &bcm63268_funcs[selector]; + unsigned i; + unsigned int reg; + unsigned int val, mask; + + for (i = 0; i < pg->num_pins; i++) + bcm63268_set_gpio(pc, pg->pins[i]); + + switch (f->reg) { + case BCM63268_LEDCTRL: + reg = BCM63268_LED_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM63268_MODE: + reg = BCM63268_MODE_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM63268_CTRL: + reg = BCM63268_CTRL_REG; + mask = BIT(pg->pins[0]); + val = 0; + break; + case BCM63268_BASEMODE: + reg = BCM63268_BASEMODE_REG; + mask = f->mask; + val = f->mask; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + regmap_update_bits(pc->regs, reg, mask, val); + + return 0; +} + +static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63268_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm63268_set_gpio(pc, offset); + + return 0; +} + +static struct pinctrl_ops bcm63268_pctl_ops = { + .get_groups_count = bcm63268_pinctrl_get_group_count, + .get_group_name = bcm63268_pinctrl_get_group_name, + .get_group_pins = bcm63268_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static struct pinmux_ops bcm63268_pmx_ops = { + .get_functions_count = bcm63268_pinctrl_get_func_count, + .get_function_name = bcm63268_pinctrl_get_func_name, + .get_function_groups = bcm63268_pinctrl_get_groups, + .set_mux = bcm63268_pinctrl_set_mux, + .gpio_request_enable = bcm63268_gpio_request_enable, + .strict = true, +}; + +static int bcm63268_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm63268_pinctrl *pc; + int err; + + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + platform_set_drvdata(pdev, pc); + pc->dev = dev; + + pc->regs = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(pc->regs)) + return PTR_ERR(pc->regs); + + pc->gpio_chip.label = MODULE_NAME; + pc->gpio_chip.owner = THIS_MODULE; + pc->gpio_chip.request = gpiochip_generic_request; + pc->gpio_chip.free = gpiochip_generic_free; + pc->gpio_chip.direction_input = bcm63268_gpio_direction_input; + pc->gpio_chip.direction_output = bcm63268_gpio_direction_output; + pc->gpio_chip.get_direction = bcm63268_gpio_get_direction; + pc->gpio_chip.get = bcm63268_gpio_get; + pc->gpio_chip.set = bcm63268_gpio_set; + pc->gpio_chip.set_config = gpiochip_generic_config; + pc->gpio_chip.base = -1; + pc->gpio_chip.ngpio = BCM63268_NUM_GPIOS; + pc->gpio_chip.can_sleep = false; + pc->gpio_chip.parent = dev; + pc->gpio_chip.of_node = np; + + if (of_get_property(np, "interrupt-names", NULL)) + pc->gpio_chip.to_irq = bcm63268_gpio_to_irq; + + err = gpiochip_add_data(&pc->gpio_chip, pc); + if (err) { + dev_err(dev, "could not add GPIO chip\n"); + return err; + } + + pc->pctl_desc.name = MODULE_NAME, + pc->pctl_desc.pins = bcm63268_pins, + pc->pctl_desc.npins = ARRAY_SIZE(bcm63268_pins), + pc->pctl_desc.pctlops = &bcm63268_pctl_ops, + pc->pctl_desc.pmxops = &bcm63268_pmx_ops, + pc->pctl_desc.owner = THIS_MODULE, + + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) { + gpiochip_remove(&pc->gpio_chip); + return PTR_ERR(pc->pctl_dev); + } + + pc->gpio_range.name = MODULE_NAME; + pc->gpio_range.npins = BCM63268_NUM_GPIOS; + pc->gpio_range.base = pc->gpio_chip.base; + pc->gpio_range.gc = &pc->gpio_chip; + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); + + dev_info(dev, "registered\n"); + + return 0; +} + +static const struct of_device_id bcm63268_pinctrl_match[] = { + { .compatible = "brcm,bcm63268-pinctrl", }, + { }, +}; + +static struct platform_driver bcm63268_pinctrl_driver = { + .probe = bcm63268_pinctrl_probe, + .driver = { + .name = MODULE_NAME, + .of_match_table = bcm63268_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm63268_pinctrl_driver); From patchwork Thu Feb 25 16:42:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387900 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 87D5EC433E0 for ; Thu, 25 Feb 2021 16:45:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5E31D64F1F for ; Thu, 25 Feb 2021 16:45:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233621AbhBYQou (ORCPT ); Thu, 25 Feb 2021 11:44:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233454AbhBYQn6 (ORCPT ); Thu, 25 Feb 2021 11:43:58 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 56ACAC0617A7; Thu, 25 Feb 2021 08:42:29 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id g11so1442199wmh.1; Thu, 25 Feb 2021 08:42:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=a0t0Tsfv/PeLKbtINIkw/IwfI/GRBWgrP/QiNYEEsRU=; b=NQj4Q3lcY0TxqHsWVUrRPLaKGJ3MnRxcHCY5361qgbGzmhklKx7V2K72Oa6iphshcW 3IJfrGLdvk7zq63oiNkzxYQzrZ8UgNM9bBrAdcN2OrVKefPncuaQmK15je4sQjyiOrFB cbdrwJ7ZHrjEXfaDBajGxIhFx5FtR+JSXUKW5MahTTh9O0n3aF4jaSTpWfaWfdV9jHRv a77rMZfAHhswoGtNuNPw9J8NV0n6ozUwqqpvb0NNucItkwuzEINwqhgpDUIWETvh1bZM JQLJeDw+78KtPug86rP5fP4R+XMShftoRiI4LUyq7lEX35mPaqf1kb9FQozeccsHEw8q Hkxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=a0t0Tsfv/PeLKbtINIkw/IwfI/GRBWgrP/QiNYEEsRU=; b=lvUafs8oKFwb9rMx9NF9y/uSsRHoZenyeoi21jDyyTlh4gyk10t2bF5Sm6Yb2lJ3ll kARxzVnYkBQkJMTJ2LamIR2uHLs95pvqU0l2cGO2DS890BnkAtl8inEW6aDnTOQZ0z5N OEHdhQotHSI/fvYEuG0IWEIBh2aMyWE2+6aKz5gagl0ArcPy4hys+sh11y+MvjvYsu23 ko/cbmbVcOXsPdVyaoIq9/r98rTAbgLsLMKISNn7IeI4y2Ooengd0y0Nn/RpPcScPUc/ NVrNp/a1LOT/VhG7GJ8nTMPBDtpYEIF6z+yeGZLF/dA7uHlRDP7i+GPex13KTahDi8/m Baww== X-Gm-Message-State: AOAM530v0UTI0YkFdtD855xR7pk99zdouCeCB+024Vi6wzH6jM+Vk599 KS23YNKQ6M1fIVDTEy4rSLY= X-Google-Smtp-Source: ABdhPJzjM5gGoQTMAgxhMmGQC5OsSkyR0PQOm5yIINe6xl/XZezurWp6sOPqvJY6jRMxT/LAwSQneg== X-Received: by 2002:a05:600c:19c7:: with SMTP id u7mr3960956wmq.160.1614271348011; Thu, 25 Feb 2021 08:42:28 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:27 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 11/12] Documentation: add BCM6318 pincontroller binding documentation Date: Thu, 25 Feb 2021 17:42:15 +0100 Message-Id: <20210225164216.21124-12-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add binding documentation for the pincontrol core found in BCM6318 SoCs. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- .../pinctrl/brcm,bcm6318-pinctrl.yaml | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml new file mode 100644 index 000000000000..e2e6c06fa200 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml @@ -0,0 +1,173 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6318-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6318 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: |+ + The pin controller node should be the child of a syscon node. + + Refer to the bindings described in + Documentation/devicetree/bindings/mfd/syscon.yaml + +properties: + compatible: + const: brcm,bcm6318-pinctrl + + gpio-controller: true + + '#gpio-cells': + description: + Specifies the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + interrupts-extended: + description: + One interrupt per each of the 2 GPIO ports supported by the controller, + sorted by port number ascending order. + minItems: 2 + maxItems: 2 + +patternProperties: + '^.*$': + if: + type: object + then: + properties: + function: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ ephy0_spd_led, ephy1_spd_led, ephy2_spd_led, ephy3_spd_led, + ephy0_act_led, ephy1_act_led, ephy2_act_led, ephy3_act_led, + serial_led_data, serial_led_clk, inet_act_led, inet_fail_led, + dsl_led, post_fail_led, wlan_wps_led, usb_pwron, + usb_device_led, usb_active ] + + pins: + $ref: "/schemas/types.yaml#/definitions/string" + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio40 ] + +required: + - compatible + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +examples: + - | + gpio@10000080 { + compatible = "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + + pinctrl: pinctrl { + compatible = "brcm,bcm6318-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc 0 0>, + <&ext_intc 1 0>; + interrupt-names = "gpio33", + "gpio34"; + + pinctrl_ephy0_spd_led: ephy0_spd_led { + function = "ephy0_spd_led"; + pins = "gpio0"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led { + function = "ephy1_spd_led"; + pins = "gpio1"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led { + function = "ephy2_spd_led"; + pins = "gpio2"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led { + function = "ephy3_spd_led"; + pins = "gpio3"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led { + function = "ephy0_act_led"; + pins = "gpio4"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led { + function = "ephy1_act_led"; + pins = "gpio5"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led { + function = "ephy2_act_led"; + pins = "gpio6"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led { + function = "ephy3_act_led"; + pins = "gpio7"; + }; + + pinctrl_serial_led: serial_led { + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led { + function = "inet_act_led"; + pins = "gpio8"; + }; + + pinctrl_inet_fail_led: inet_fail_led { + function = "inet_fail_led"; + pins = "gpio9"; + }; + + pinctrl_dsl_led: dsl_led { + function = "dsl_led"; + pins = "gpio10"; + }; + + pinctrl_post_fail_led: post_fail_led { + function = "post_fail_led"; + pins = "gpio11"; + }; + + pinctrl_wlan_wps_led: wlan_wps_led { + function = "wlan_wps_led"; + pins = "gpio12"; + }; + + pinctrl_usb_pwron: usb_pwron { + function = "usb_pwron"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led { + function = "usb_device_led"; + pins = "gpio13"; + }; + + pinctrl_usb_active: usb_active { + function = "usb_active"; + pins = "gpio40"; + }; + }; + }; From patchwork Thu Feb 25 16:42:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= X-Patchwork-Id: 387425 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=-15.7 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, URIBL_BLOCKED, USER_AGENT_GIT 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 6978AC433DB for ; Thu, 25 Feb 2021 16:45:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3E65264F19 for ; Thu, 25 Feb 2021 16:45:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233387AbhBYQpZ (ORCPT ); Thu, 25 Feb 2021 11:45:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233455AbhBYQn7 (ORCPT ); Thu, 25 Feb 2021 11:43:59 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 192CDC0617A9; Thu, 25 Feb 2021 08:42:30 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id n4so5913610wrx.1; Thu, 25 Feb 2021 08:42:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=tsWOTMpDW4ycew/wVLfnu3e4LDCzLyPcfvvjh8TkG3M=; b=ieGYUzVdWuh7U0ua0QRT6+P41DH6MsulnzhezQrmr4kOqGmwwC+n9IydhLo4xkFg+w 2Oi8e6BtOawZPdkoQnb2dJXzOX1Ihk2G0BPHQMPjr55AZWWiaZ7GPAI5sDp/y1O1SIb6 J8ykkKNOBMzcEV9GLIUhNeDwmM9zu/RDYmk1OlBpR2vW1tK/n9ieiIS0biZFzy+styXT znbXjWPb0pJQsPxIVFrzvbrtyKivhXrEMnOK0ptYxSIaRY9oTn3QW6GAFMZGuyghR45F gJD8JcbVvMOwKxFTjWGgAhTPMBKPf8GrMTEmi6uGzRGexumytjIh89A32emYr9h58+8w zyiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tsWOTMpDW4ycew/wVLfnu3e4LDCzLyPcfvvjh8TkG3M=; b=eIEjpQw5tITkE7VoUNdKS5tyy3poN1EK5trYYCKoFfelauwqaudNAH9l73dCQG1L/E bBdrhIaUFbYD5BM0cYl9VA5H4tj5YJkINF3HgYposbq93icOhUtaw5MvDdJlvZUcu+eT QpRmqxzy+VcSEGposNtK4SZVfPXECK+tyQVPRk3ectPfQhMeJzOQcYOPxIPJOj4eSpX1 qt3hrIRlfnkf81kLlZr9LGMeZlU5IbgN0Uqef5MkGLH7iuZdfdjW3/ePm7WoF75WYomh z4xWLyilDqO/bM7ABErp3celPWU9h5AOvfX0DftpGlMd8TyuU64QoB2OglIFONRRuV2N uwgw== X-Gm-Message-State: AOAM533T83rGeXNStCFKWFh8tvy/AYNeghOG5J6Se65iJjZh5v9Fk8Pt 2kx56AfXz/kM9SnpYuRaXIg= X-Google-Smtp-Source: ABdhPJzN26q/2oO9hpS0BV9yH/lgN34weyHLaYOJuuX/J7niYxdLRkMOLjIi1+EVwkMdV28CHvN9XA== X-Received: by 2002:a5d:6643:: with SMTP id f3mr4384687wrw.182.1614271348779; Thu, 25 Feb 2021 08:42:28 -0800 (PST) Received: from skynet.lan (170.red-88-1-105.dynamicip.rima-tde.net. [88.1.105.170]) by smtp.gmail.com with ESMTPSA id u4sm372779wrm.24.2021.02.25.08.42.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Feb 2021 08:42:28 -0800 (PST) From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= To: f.fainelli@gmail.com, Linus Walleij , Rob Herring , =?utf-8?b?w4FsdmFybyBGZXJuw6FuZGV6IFJv?= =?utf-8?q?jas?= , Jonas Gorski , Necip Fazil Yildiran , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 12/12] pinctrl: add a pincontrol driver for BCM6318 Date: Thu, 25 Feb 2021 17:42:16 +0100 Message-Id: <20210225164216.21124-13-noltari@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210225164216.21124-1-noltari@gmail.com> References: <20210225164216.21124-1-noltari@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs to different functions. BCM6318 is similar to BCM6328 with the addition of a pad register, and the GPIO meaning of the mux register changes based on the GPIO number. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski --- drivers/pinctrl/bcm/Kconfig | 11 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6318.c | 674 ++++++++++++++++++++++++++ 3 files changed, 686 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 8918600466b4..1003a209a2cd 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -29,6 +29,17 @@ config PINCTRL_BCM2835 help Say Y here to enable the Broadcom BCM2835 GPIO driver. +config PINCTRL_BCM6318 + bool "Broadcom BCM6318 GPIO driver" + depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) + select PINMUX + select PINCONF + select GENERIC_PINCONF + select MFD_SYSCON + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6318 GPIO driver. + config PINCTRL_BCM6328 bool "Broadcom BCM6328 GPIO driver" depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index d5a8ee914fc6..50faf6b2a018 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o +obj-$(CONFIG_PINCTRL_BCM6318) += pinctrl-bcm6318.o obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6318.c b/drivers/pinctrl/bcm/pinctrl-bcm6318.c new file mode 100644 index 000000000000..017ec4ead884 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6318.c @@ -0,0 +1,674 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6318 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define MODULE_NAME "bcm6318-pinctrl" +#define BCM6318_NUM_GPIOS 50 +#define BCM6318_NUM_MUX 48 + +#define BANK_SIZE sizeof(uint32_t) +#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) + +#define BCM6318_DIROUT_REG 0x04 +#define BCM6318_DATA_REG 0x0c +#define BCM6318_MODE_REG 0x18 +#define BCM6318_MUX_REG 0x1c +#define BCM6318_PAD_REG 0x54 + +struct bcm6318_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6318_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned mode_val:1; + unsigned mux_val:2; +}; + +struct bcm6318_pinctrl { + struct device *dev; + struct regmap *regs; + + struct pinctrl_dev *pctl_dev; + struct gpio_chip gpio_chip; + struct pinctrl_desc pctl_desc; + struct pinctrl_gpio_range gpio_range; +}; + +static const struct pinctrl_pin_desc bcm6318_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), + PINCTRL_PIN(48, "gpio48"), + PINCTRL_PIN(49, "gpio49"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; +static unsigned gpio48_pins[] = { 48 }; +static unsigned gpio49_pins[] = { 49 }; + +#define BCM6318_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6318_pingroup bcm6318_groups[] = { + BCM6318_GROUP(gpio0), + BCM6318_GROUP(gpio1), + BCM6318_GROUP(gpio2), + BCM6318_GROUP(gpio3), + BCM6318_GROUP(gpio4), + BCM6318_GROUP(gpio5), + BCM6318_GROUP(gpio6), + BCM6318_GROUP(gpio7), + BCM6318_GROUP(gpio8), + BCM6318_GROUP(gpio9), + BCM6318_GROUP(gpio10), + BCM6318_GROUP(gpio11), + BCM6318_GROUP(gpio12), + BCM6318_GROUP(gpio13), + BCM6318_GROUP(gpio14), + BCM6318_GROUP(gpio15), + BCM6318_GROUP(gpio16), + BCM6318_GROUP(gpio17), + BCM6318_GROUP(gpio18), + BCM6318_GROUP(gpio19), + BCM6318_GROUP(gpio20), + BCM6318_GROUP(gpio21), + BCM6318_GROUP(gpio22), + BCM6318_GROUP(gpio23), + BCM6318_GROUP(gpio24), + BCM6318_GROUP(gpio25), + BCM6318_GROUP(gpio26), + BCM6318_GROUP(gpio27), + BCM6318_GROUP(gpio28), + BCM6318_GROUP(gpio29), + BCM6318_GROUP(gpio30), + BCM6318_GROUP(gpio31), + BCM6318_GROUP(gpio32), + BCM6318_GROUP(gpio33), + BCM6318_GROUP(gpio34), + BCM6318_GROUP(gpio35), + BCM6318_GROUP(gpio36), + BCM6318_GROUP(gpio37), + BCM6318_GROUP(gpio38), + BCM6318_GROUP(gpio39), + BCM6318_GROUP(gpio40), + BCM6318_GROUP(gpio41), + BCM6318_GROUP(gpio42), + BCM6318_GROUP(gpio43), + BCM6318_GROUP(gpio44), + BCM6318_GROUP(gpio45), + BCM6318_GROUP(gpio46), + BCM6318_GROUP(gpio47), + BCM6318_GROUP(gpio48), + BCM6318_GROUP(gpio49), +}; + +/* GPIO_MODE */ +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +/* PINMUX_SEL */ +static const char * const ephy0_spd_led_groups[] = { + "gpio0", +}; + +static const char * const ephy1_spd_led_groups[] = { + "gpio1", +}; + +static const char * const ephy2_spd_led_groups[] = { + "gpio2", +}; + +static const char * const ephy3_spd_led_groups[] = { + "gpio3", +}; + +static const char * const ephy0_act_led_groups[] = { + "gpio4", +}; + +static const char * const ephy1_act_led_groups[] = { + "gpio5", +}; + +static const char * const ephy2_act_led_groups[] = { + "gpio6", +}; + +static const char * const ephy3_act_led_groups[] = { + "gpio7", +}; + +static const char * const serial_led_data_groups[] = { + "gpio6", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio7", +}; + +static const char * const inet_act_led_groups[] = { + "gpio8", +}; + +static const char * const inet_fail_led_groups[] = { + "gpio9", +}; + +static const char * const dsl_led_groups[] = { + "gpio10", +}; + +static const char * const post_fail_led_groups[] = { + "gpio11", +}; + +static const char * const wlan_wps_led_groups[] = { + "gpio12", +}; + +static const char * const usb_pwron_groups[] = { + "gpio13", +}; + +static const char * const usb_device_led_groups[] = { + "gpio13", +}; + +static const char * const usb_active_groups[] = { + "gpio40", +}; + +#define BCM6318_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mode_val = 1, \ + } + +#define BCM6318_MUX_FUN(n, mux) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mux_val = mux, \ + } + +static const struct bcm6318_function bcm6318_funcs[] = { + BCM6318_MODE_FUN(led), + BCM6318_MUX_FUN(ephy0_spd_led, 1), + BCM6318_MUX_FUN(ephy1_spd_led, 1), + BCM6318_MUX_FUN(ephy2_spd_led, 1), + BCM6318_MUX_FUN(ephy3_spd_led, 1), + BCM6318_MUX_FUN(ephy0_act_led, 1), + BCM6318_MUX_FUN(ephy1_act_led, 1), + BCM6318_MUX_FUN(ephy2_act_led, 1), + BCM6318_MUX_FUN(ephy3_act_led, 1), + BCM6318_MUX_FUN(serial_led_data, 3), + BCM6318_MUX_FUN(serial_led_clk, 3), + BCM6318_MUX_FUN(inet_act_led, 1), + BCM6318_MUX_FUN(inet_fail_led, 1), + BCM6318_MUX_FUN(dsl_led, 1), + BCM6318_MUX_FUN(post_fail_led, 1), + BCM6318_MUX_FUN(wlan_wps_led, 1), + BCM6318_MUX_FUN(usb_pwron, 1), + BCM6318_MUX_FUN(usb_device_led, 2), + BCM6318_MUX_FUN(usb_active, 2), +}; + +static inline unsigned int bcm6318_bank_pin(unsigned int pin) +{ + return pin % PINS_PER_BANK; +} + +static inline unsigned int bcm6318_mux_off(unsigned int pin) +{ + return BCM6318_MUX_REG + (pin / 16) * BANK_SIZE; +} + +static inline unsigned int bcm6318_pad_off(unsigned int pin) +{ + return BCM6318_PAD_REG + (pin / 8) * BANK_SIZE; +} + +static inline unsigned int bcm6318_reg_off(unsigned int reg, unsigned int pin) +{ + return reg - (pin / PINS_PER_BANK) * BANK_SIZE; +} + +static int bcm6318_gpio_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin); + unsigned int bank_pin = bcm6318_bank_pin(pin); + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an input GPIO + */ + ret = pinctrl_gpio_direction_input(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); + + return 0; +} + +static int bcm6318_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin); + unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin); + unsigned int bank_pin = bcm6318_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + int ret; + + /* + * Check with the pinctrl driver whether this pin is usable as + * an output GPIO + */ + ret = pinctrl_gpio_direction_output(chip->base + pin); + if (ret) + return ret; + + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); + + return 0; +} + +static int bcm6318_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin); + unsigned int bank_pin = bcm6318_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, data, &val); + + return !!(val & BIT(bank_pin)); +} + +static int bcm6318_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) +{ + struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); + unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin); + unsigned int bank_pin = bcm6318_bank_pin(pin); + unsigned int val; + + regmap_read(pc->regs, dirout, &val); + + if (val & BIT(bank_pin)) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static void bcm6318_gpio_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); + unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin); + unsigned int bank_pin = bcm6318_bank_pin(pin); + unsigned int val = value ? BIT(bank_pin) : 0; + + regmap_update_bits(pc->regs, data, BIT(bank_pin), val); +} + +static int bcm6318_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +{ + char irq_name[7]; + + sprintf(irq_name, "gpio%d", gpio); + + return of_irq_get_byname(chip->of_node, irq_name); +} + +static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6318_groups); +} + +static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6318_groups[group].name; +} + +static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6318_groups[group].pins; + *num_pins = bcm6318_groups[group].num_pins; + + return 0; +} + +static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6318_funcs); +} + +static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6318_funcs[selector].name; +} + +static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6318_funcs[selector].groups; + *num_groups = bcm6318_funcs[selector].num_groups; + + return 0; +} + +static inline void bcm6318_rmw_mux(struct bcm6318_pinctrl *pc, unsigned pin, + unsigned int mode, unsigned int mux) +{ + if (pin < PINS_PER_BANK) + regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin), + mode ? BIT(pin) : 0); + + if (pin < BCM6318_NUM_MUX) + regmap_update_bits(pc->regs, + bcm6318_mux_off(pin), + 3UL << ((pin % 16) * 2), + mux << ((pin % 16) * 2)); +} + +static inline void bcm6318_set_pad(struct bcm6318_pinctrl *pc, unsigned pin, + uint8_t val) +{ + regmap_update_bits(pc->regs, bcm6318_pad_off(pin), + 0xfUL << ((pin % 8) * 4), + val << ((pin % 8) * 4)); +} + +static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm6318_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6318_pingroup *pg = &bcm6318_groups[group]; + const struct bcm6318_function *f = &bcm6318_funcs[selector]; + + bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); + + return 0; +} + +static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm6318_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + if (offset < 13) { + /* GPIOs 0-12 use mux 0 as GPIO function */ + bcm6318_rmw_mux(pc, offset, 0, 0); + } else if (offset < 42) { + /* GPIOs 13-41 use mux 3 as GPIO function */ + bcm6318_rmw_mux(pc, offset, 0, 3); + + bcm6318_set_pad(pc, offset, 0); + } + + return 0; +} + +static struct pinctrl_ops bcm6318_pctl_ops = { + .get_groups_count = bcm6318_pinctrl_get_group_count, + .get_group_name = bcm6318_pinctrl_get_group_name, + .get_group_pins = bcm6318_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static struct pinmux_ops bcm6318_pmx_ops = { + .get_functions_count = bcm6318_pinctrl_get_func_count, + .get_function_name = bcm6318_pinctrl_get_func_name, + .get_function_groups = bcm6318_pinctrl_get_groups, + .set_mux = bcm6318_pinctrl_set_mux, + .gpio_request_enable = bcm6318_gpio_request_enable, + .strict = true, +}; + +static int bcm6318_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm6318_pinctrl *pc; + int err; + + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + platform_set_drvdata(pdev, pc); + pc->dev = dev; + + pc->regs = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(pc->regs)) + return PTR_ERR(pc->regs); + + pc->gpio_chip.label = MODULE_NAME; + pc->gpio_chip.owner = THIS_MODULE; + pc->gpio_chip.request = gpiochip_generic_request; + pc->gpio_chip.free = gpiochip_generic_free; + pc->gpio_chip.direction_input = bcm6318_gpio_direction_input; + pc->gpio_chip.direction_output = bcm6318_gpio_direction_output; + pc->gpio_chip.get_direction = bcm6318_gpio_get_direction; + pc->gpio_chip.get = bcm6318_gpio_get; + pc->gpio_chip.set = bcm6318_gpio_set; + pc->gpio_chip.set_config = gpiochip_generic_config; + pc->gpio_chip.base = -1; + pc->gpio_chip.ngpio = BCM6318_NUM_GPIOS; + pc->gpio_chip.can_sleep = false; + pc->gpio_chip.parent = dev; + pc->gpio_chip.of_node = np; + + if (of_get_property(np, "interrupt-names", NULL)) + pc->gpio_chip.to_irq = bcm6318_gpio_to_irq; + + err = gpiochip_add_data(&pc->gpio_chip, pc); + if (err) { + dev_err(dev, "could not add GPIO chip\n"); + return err; + } + + pc->pctl_desc.name = MODULE_NAME, + pc->pctl_desc.pins = bcm6318_pins, + pc->pctl_desc.npins = ARRAY_SIZE(bcm6318_pins), + pc->pctl_desc.pctlops = &bcm6318_pctl_ops, + pc->pctl_desc.pmxops = &bcm6318_pmx_ops, + pc->pctl_desc.owner = THIS_MODULE, + + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) { + gpiochip_remove(&pc->gpio_chip); + return PTR_ERR(pc->pctl_dev); + } + + pc->gpio_range.name = MODULE_NAME; + pc->gpio_range.npins = BCM6318_NUM_GPIOS; + pc->gpio_range.base = pc->gpio_chip.base; + pc->gpio_range.gc = &pc->gpio_chip; + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); + + dev_info(dev, "registered\n"); + + return 0; +} + +static const struct of_device_id bcm6318_pinctrl_match[] = { + { .compatible = "brcm,bcm6318-pinctrl", }, + { }, +}; + +static struct platform_driver bcm6318_pinctrl_driver = { + .probe = bcm6318_pinctrl_probe, + .driver = { + .name = MODULE_NAME, + .of_match_table = bcm6318_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6318_pinctrl_driver);