From patchwork Fri Dec 29 07:45:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Liu X-Patchwork-Id: 1881011 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=ieJRKsGv; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=112.213.38.117; helo=lists.ozlabs.org; envelope-from=openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=patchwork.ozlabs.org) Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T1cs36pv0z1ySy for ; Fri, 29 Dec 2023 18:46:47 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=ieJRKsGv; dkim-atps=neutral Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4T1cs20tDfz3brC for ; Fri, 29 Dec 2023 18:46:46 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=ieJRKsGv; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::b29; helo=mail-yb1-xb29.google.com; envelope-from=jim.t90615@gmail.com; receiver=lists.ozlabs.org) Received: from mail-yb1-xb29.google.com (mail-yb1-xb29.google.com [IPv6:2607:f8b0:4864:20::b29]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4T1cqd4npnz2xdg for ; Fri, 29 Dec 2023 18:45:33 +1100 (AEDT) Received: by mail-yb1-xb29.google.com with SMTP id 3f1490d57ef6-dbd990ad852so4749612276.1 for ; Thu, 28 Dec 2023 23:45:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1703835930; x=1704440730; darn=lists.ozlabs.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GEGAxLf4IsKoqwzjcok3JRGPJ70voZ7ZjL8ngt195yA=; b=ieJRKsGvKxR4aR8IuoKYklnoZnglKJpwCY5+C9sSgd21IVbgm+4C32JvcIcA6Pl9T0 7ZyZKbQbXkNCKb/5PClTxN3BsGdgqJ9mpn0O2xXHFjZyJYYpRM+DlwkwCgCX31nsMpZH TJUumHQnyZ9ia3xqh5w3/5bFQlHUeCXSDVAUH1YOyhIJTVBnJavL5u03mCifstEevZk5 8Cv9QIdYdVyxJ9GYpvT0G3ZXmr7ayCDiv9VjU5ra66H8hK78G7lvlYbZBdNjCsb5kLzA yKbhlNf+uhxnshB1mu12j1RrHwILQjCl3Y8Ysl4OIZVACUcs8MXc6eI54xdDZvIzATfF 9i3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703835930; x=1704440730; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GEGAxLf4IsKoqwzjcok3JRGPJ70voZ7ZjL8ngt195yA=; b=DiiQ+II/kD2cvsLtKXpDJRDqVediOYpSpYatGJC5jP/aYslgJnGncZc6ZYZm5hqKWI UY5hpDgmL5CFuhILht1M9d2+Diyhi3DFl1LYxoehPe0w5OQamFFxODfFjUMMUyRMnjQZ t8E57CFsWwPmE7YNoSVnnL+RUPxDjtnAKgMhwm6Km+B8CoSa97R5tgfFjsV1+bBNPPQj 0Q1XA8hGDAzgZmjStjMq1imsQsH+Ybpl6YRFb+04D1jZ9HB+rIGlYnKfOppIrNPtP8Do SXTBoN/4OSMIKY+/DZnn2loMWD7mRJBac3olpItVjCEDPW+gVcyQmkKrBjGMMQk9VwPO sJuA== X-Gm-Message-State: AOJu0YyQy8HJIqezDwP9307QITIWPTLf6SGBlFWHSRHeZoxNLv5k7mMj 7Oal+Wn5xuwisGlj+GzgY9E= X-Google-Smtp-Source: AGHT+IGU6rlyzKFUXt2uV0qU7Ku9PkDDI4wAMUvhgBjSVCDz4vqA9CFCVZ1s108SqYFGYMxlr5tcRA== X-Received: by 2002:a25:69c5:0:b0:dbd:38c:e612 with SMTP id e188-20020a2569c5000000b00dbd038ce612mr6841255ybc.84.1703835930106; Thu, 28 Dec 2023 23:45:30 -0800 (PST) Received: from localhost.localdomain ([1.200.140.173]) by smtp.gmail.com with ESMTPSA id s188-20020a6377c5000000b005c683937cc5sm10305186pgc.44.2023.12.28.23.45.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Dec 2023 23:45:29 -0800 (PST) From: jim.t90615@gmail.com X-Google-Original-From: JJLIU0@nuvoton.com To: JJLIU0@nuvoton.com, KWLIU@nuvoton.com, jim.t90615@gmail.com, linus.walleij@linaro.org, brgl@bgdev.pl, andy@kernel.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org Subject: [PATCH v10 1/3] dt-bindings: gpio: add NPCM sgpio driver bindings Date: Fri, 29 Dec 2023 15:45:06 +0800 Message-Id: <20231229074508.2709093-2-JJLIU0@nuvoton.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231229074508.2709093-1-JJLIU0@nuvoton.com> References: <20231229074508.2709093-1-JJLIU0@nuvoton.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Paul Menzel , openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" From: Jim Liu Add dt-bindings document for the Nuvoton NPCM7xx sgpio driver Signed-off-by: Jim Liu Reviewed-by: Linus Walleij Reviewed-by: Rob Herring Reviewed-by: Paul Menzel --- Changes for v10: - modify error words Changes for v9: - no changed Changes for v8: - no changed --- .../bindings/gpio/nuvoton,sgpio.yaml | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/nuvoton,sgpio.yaml diff --git a/Documentation/devicetree/bindings/gpio/nuvoton,sgpio.yaml b/Documentation/devicetree/bindings/gpio/nuvoton,sgpio.yaml new file mode 100644 index 000000000000..9e32e54aeb24 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/nuvoton,sgpio.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/nuvoton,sgpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton SGPIO controller + +maintainers: + - Jim LIU + +description: | + This SGPIO controller is for NUVOTON NPCM7xx and NPCM8xx SoC and detailed + information is in the NPCM7XX/8XX SERIAL I/O EXPANSION INTERFACE section. + Nuvoton NPCM7xx SGPIO module is combines a serial to parallel IC (HC595) + and a parallel to serial IC (HC165). + Clock is a division of the APB3 clock. + This interface has 4 pins (D_out , D_in, S_CLK, LDSH). + NPCM7xx/NPCM8xx have two sgpio modules. Each module can support up + to 64 output pins, and up to 64 input pins, the pin is only for GPI or GPO. + GPIO pins can be programmed to support the following options + - Support interrupt option for each input port and various interrupt + sensitivity options (level-high, level-low, edge-high, edge-low) + - ngpios is number of nuvoton,input-ngpios GPIO lines and nuvoton,output-ngpios GPIO lines. + nuvoton,input-ngpios GPIO lines is only for GPI. + nuvoton,output-ngpios GPIO lines is only for GPO. + +properties: + compatible: + enum: + - nuvoton,npcm750-sgpio + - nuvoton,npcm845-sgpio + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + nuvoton,input-ngpios: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + The numbers of GPIO's exposed. GPIO lines are only for GPI. + minimum: 0 + maximum: 64 + + nuvoton,output-ngpios: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + The numbers of GPIO's exposed. GPIO lines are only for GPO. + minimum: 0 + maximum: 64 + +required: + - compatible + - reg + - gpio-controller + - '#gpio-cells' + - interrupts + - nuvoton,input-ngpios + - nuvoton,output-ngpios + - clocks + +additionalProperties: false + +examples: + - | + #include + #include + gpio8: gpio@101000 { + compatible = "nuvoton,npcm750-sgpio"; + reg = <0x101000 0x200>; + clocks = <&clk NPCM7XX_CLK_APB3>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + nuvoton,input-ngpios = <64>; + nuvoton,output-ngpios = <64>; + }; From patchwork Fri Dec 29 07:45:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Liu X-Patchwork-Id: 1881012 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=kYsDZ5J0; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=patchwork.ozlabs.org) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T1ct34z83z1ySy for ; Fri, 29 Dec 2023 18:47:39 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=kYsDZ5J0; dkim-atps=neutral Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4T1ct32vnPz3bdG for ; Fri, 29 Dec 2023 18:47:39 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=kYsDZ5J0; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::32b; helo=mail-ot1-x32b.google.com; envelope-from=jim.t90615@gmail.com; receiver=lists.ozlabs.org) Received: from mail-ot1-x32b.google.com (mail-ot1-x32b.google.com [IPv6:2607:f8b0:4864:20::32b]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4T1cqk0bJBz3bcJ for ; Fri, 29 Dec 2023 18:45:37 +1100 (AEDT) Received: by mail-ot1-x32b.google.com with SMTP id 46e09a7af769-6dbaf9b1674so3969158a34.2 for ; Thu, 28 Dec 2023 23:45:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1703835935; x=1704440735; darn=lists.ozlabs.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=raM42T0EIL2NcFESOuJEj10hSihrJvgpKQH+cdOXtTI=; b=kYsDZ5J05PqmE3eVu0JabMvjl4GHqSr7P4a0hC6znz3tNZcarZZyJvCPnBlXawG8vA E3oSMS+dK/ZGpP8r/v0nduC51PEF+HzbqDSSwL9K1o7NqW2/leXqDVL/Bvx7o7GZSS+H vXVpX0OA8X8Qo4K9bY/wM3UEEhJoyiaoZC5Uvn7y+Ga4Xd1rYot0oVecJGK0c3JT6v4G XVKcmMTN6VxZ6JLdf/j82w5niC96HwDJrRqbtVWXO6INmz/K15mtz9TUmZUADc1/pGhy Ky6w9J7XlLf7jU6TeZXfX3QlAt1h7tWhBjbiUwORE+uQopFbvoYKZpme8iMdE24ITiDJ CeHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703835935; x=1704440735; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=raM42T0EIL2NcFESOuJEj10hSihrJvgpKQH+cdOXtTI=; b=uYISGUrNN4zgd52DhaW5NIYI4OYMhD73cGfsK1p2OmNgWwXeXGmJn17B1n0OzQXiip 4rWHcRWc4Jp3EYo66km+iEmLj3Pf4iTxOtWUU0bJjizj5Us/PmgGY/B8QBs/ieEMaMm2 fWhRBq4khtiximejGuuGUv6DhZarMTgu8dxgd0hXeJmDfmZ110BRniaoiGKLPXqSuEXD c119SY9kRllShJIaAQw1qPMb4Z0lbfskQYCvD3Qy5XiT/wPUWxpUngkJoitm0qyb+CUA khhwjGnvHuznDV2aoZrq/ttie/R18PmWQfzSA3Za4RZgKMbsHZDUrC+wBEOWawiPXZVe rbSQ== X-Gm-Message-State: AOJu0YyvAeE5cd7j8GfIYSjovOWjIQO0YESz7xIK4NUp7YjT3vTf8d3D fkwXaZIRn9efl1luvvXAyh4zP3xTbDg= X-Google-Smtp-Source: AGHT+IHVacEjDYDHAf1Is5qnuiqwZwRsVxajivxiR3T1XLsZA5D4sijpp84TGkK8RWO6nbh5MDsz7w== X-Received: by 2002:a9d:6e8b:0:b0:6db:af74:dacb with SMTP id a11-20020a9d6e8b000000b006dbaf74dacbmr7602885otr.67.1703835935085; Thu, 28 Dec 2023 23:45:35 -0800 (PST) Received: from localhost.localdomain ([1.200.140.173]) by smtp.gmail.com with ESMTPSA id s188-20020a6377c5000000b005c683937cc5sm10305186pgc.44.2023.12.28.23.45.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Dec 2023 23:45:34 -0800 (PST) From: jim.t90615@gmail.com X-Google-Original-From: JJLIU0@nuvoton.com To: JJLIU0@nuvoton.com, KWLIU@nuvoton.com, jim.t90615@gmail.com, linus.walleij@linaro.org, brgl@bgdev.pl, andy@kernel.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org Subject: [PATCH v10 2/3] arm: dts: nuvoton: npcm: Add sgpio feature Date: Fri, 29 Dec 2023 15:45:07 +0800 Message-Id: <20231229074508.2709093-3-JJLIU0@nuvoton.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231229074508.2709093-1-JJLIU0@nuvoton.com> References: <20231229074508.2709093-1-JJLIU0@nuvoton.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-gpio@vger.kernel.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" From: Jim Liu Add the SGPIO controller to the NPCM7xx devicetree Signed-off-by: Jim Liu --- Changes for v10: - no changed Changes for v9: - no changed --- .../dts/nuvoton/nuvoton-common-npcm7xx.dtsi | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi index 868454ae6bde..df91517a4842 100644 --- a/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi +++ b/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi @@ -372,6 +372,30 @@ &fanin12_pins &fanin13_pins status = "disabled"; }; + gpio8: gpio@101000 { + compatible = "nuvoton,npcm750-sgpio"; + reg = <0x101000 0x200>; + clocks = <&clk NPCM7XX_CLK_APB3>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + nuvoton,input-ngpios = <64>; + nuvoton,output-ngpios = <64>; + status = "disabled"; + }; + + gpio9: gpio@102000 { + compatible = "nuvoton,npcm750-sgpio"; + reg = <0x102000 0x200>; + clocks = <&clk NPCM7XX_CLK_APB3>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + nuvoton,input-ngpios = <64>; + nuvoton,output-ngpios = <64>; + status = "disabled"; + }; + i2c0: i2c@80000 { reg = <0x80000 0x1000>; compatible = "nuvoton,npcm750-i2c"; From patchwork Fri Dec 29 07:45:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Liu X-Patchwork-Id: 1881013 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=Wq8Li3us; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=patchwork.ozlabs.org) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T1cv46wGgz1ySy for ; Fri, 29 Dec 2023 18:48:32 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=Wq8Li3us; dkim-atps=neutral Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4T1cv4580xz3cNt for ; Fri, 29 Dec 2023 18:48:32 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=Wq8Li3us; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::129; helo=mail-il1-x129.google.com; envelope-from=jim.t90615@gmail.com; receiver=lists.ozlabs.org) Received: from mail-il1-x129.google.com (mail-il1-x129.google.com [IPv6:2607:f8b0:4864:20::129]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4T1cqq3wfvz3bWy for ; Fri, 29 Dec 2023 18:45:43 +1100 (AEDT) Received: by mail-il1-x129.google.com with SMTP id e9e14a558f8ab-35fcea0ac1aso32694075ab.1 for ; Thu, 28 Dec 2023 23:45:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1703835940; x=1704440740; darn=lists.ozlabs.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fMIfoUSkLSoDGZ5tRbb3bXVs4hbdVpL1OH6EPKJqVS4=; b=Wq8Li3usZQUoESkhlqHoDCgNLZvI+t1uW2XiX7H8e/m78Pyda0WzN+OY/9CT42mFqn xjNOdObuw0s++9TI2ZsnpVFwmh+pxUb5Bo0Bc4cM16ti97CoShgHaswvPtAucgSUnE6X 3tFzeFTltlha1qfMMBzjp4TiuAqoWf3BFfnzjd/fcjdVvvhizVAoUQy3juz0/pOY6lKD lDU5+gyHwsF0Hnaif3SbsOYZnaC+ZipL0gBCyZmyRupAgZzr5gqTO5p1BdYFTsK8Es8H nqw/Y8Hh4sQzx9mwM7bXbkrX618VQr34myxiVQAun78kj2K/cupa22t3FOFXWEY6i7D8 YVkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703835940; x=1704440740; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fMIfoUSkLSoDGZ5tRbb3bXVs4hbdVpL1OH6EPKJqVS4=; b=IeWBX6UNEsKXNWjyU8aae11gBR4vFXxHXHTlSZG6zaGWOFegLsbssUS/pgJ5XtodzZ ZLXrdIxNALi/CvtLiWHRd3xc87qL54gBQz9wEEaJu9mo+aRXZMTLUPvcS/yFk7e1S1YJ OUNSCBg4XilNv9J3KOAY+uJSCfhJ/jWDTriARsI+d1kC4emZHz/M77ajGIflwVri0Ajl nb2VWz7GGsCB1nGi50HsSFOCrAYxWvFbSq4USdouonFOjMed4xW9RrBXQaR1L8XQQlMk k+WJKbSyClvBOd3JWNZhs4ZcGn6Y5FUz0dWhZd4tyyVQ/Wh3+lhVaf9j9+wzJFYzQswx bDCg== X-Gm-Message-State: AOJu0YyV7HKKSsj2ZzHwLHHhZcPGT2QMJsww+8KZBIcHiraFhFazr8pi 5o98lCb/wKFjJjuv4KbE8KM= X-Google-Smtp-Source: AGHT+IFOWQbvYCSYGznrRgGPUgj4LOiR0e9OWuMLARRpr5JAWfNEpz3eoJ/g1+Y2tv6KiAFp/xarzQ== X-Received: by 2002:a05:6e02:1c89:b0:35f:f67b:b004 with SMTP id w9-20020a056e021c8900b0035ff67bb004mr7762429ill.15.1703835940334; Thu, 28 Dec 2023 23:45:40 -0800 (PST) Received: from localhost.localdomain ([1.200.140.173]) by smtp.gmail.com with ESMTPSA id s188-20020a6377c5000000b005c683937cc5sm10305186pgc.44.2023.12.28.23.45.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Dec 2023 23:45:39 -0800 (PST) From: jim.t90615@gmail.com X-Google-Original-From: JJLIU0@nuvoton.com To: JJLIU0@nuvoton.com, KWLIU@nuvoton.com, jim.t90615@gmail.com, linus.walleij@linaro.org, brgl@bgdev.pl, andy@kernel.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org Subject: [PATCH v10 3/3] gpio: nuvoton: Add Nuvoton NPCM sgpio driver Date: Fri, 29 Dec 2023 15:45:08 +0800 Message-Id: <20231229074508.2709093-4-JJLIU0@nuvoton.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231229074508.2709093-1-JJLIU0@nuvoton.com> References: <20231229074508.2709093-1-JJLIU0@nuvoton.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-gpio@vger.kernel.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" From: Jim Liu Add Nuvoton BMC NPCM7xx/NPCM8xx sgpio driver support. Nuvoton NPCM SGPIO module is combine serial to parallel IC (HC595) and parallel to serial IC (HC165), and use APB3 clock to control it. This interface has 4 pins (D_out , D_in, S_CLK, LDSH). BMC can use this driver to increase 64 GPI pins and 64 GPO pins to use. Signed-off-by: Jim Liu --- Changes for v10: - use HZ_PER_MHZ - check blank line and spaces wrongs - use dev_err_probe - Instead of conditionals use arithmetics Changes for v9: - fix kernel rebot test warning Changes for v8: - Remove OF_GPIO/GPIO_GENERIC and redundant assignments - Use GENMASK() and BIT() - Use dev_WARN and dev_err_probe - Check indentation issue - Use raw_spinlock_t --- drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-npcm-sgpio.c | 612 +++++++++++++++++++++++++++++++++ 3 files changed, 620 insertions(+) create mode 100644 drivers/gpio/gpio-npcm-sgpio.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b3a133ed31ee..efbdc93819d4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -478,6 +478,13 @@ config GPIO_MXS select GPIO_GENERIC select GENERIC_IRQ_CHIP +config GPIO_NPCM_SGPIO + bool "Nuvoton SGPIO support" + depends on ARCH_NPCM || COMPILE_TEST + select GPIOLIB_IRQCHIP + help + Say Y here to support Nuvoton NPCM7XX/NPCM8XX SGPIO functionality. + config GPIO_OCTEON tristate "Cavium OCTEON GPIO" depends on CAVIUM_OCTEON_SOC diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index eb73b5d633eb..373aa2943de5 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -116,6 +116,7 @@ obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o +obj-$(CONFIG_GPIO_NPCM_SGPIO) += gpio-npcm-sgpio.o obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o diff --git a/drivers/gpio/gpio-npcm-sgpio.c b/drivers/gpio/gpio-npcm-sgpio.c new file mode 100644 index 000000000000..e9057c4a658d --- /dev/null +++ b/drivers/gpio/gpio-npcm-sgpio.c @@ -0,0 +1,612 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Nuvoton NPCM Serial GPIO Driver + * + * Copyright (C) 2021 Nuvoton Technologies + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_NR_HW_SGPIO 64 + +#define NPCM_IOXCFG1 0x2A +#define NPCM_IOXCFG1_SFT_CLK GENMASK(3, 0) +#define NPCM_IOXCFG1_SCLK_POL BIT(4) +#define NPCM_IOXCFG1_LDSH_POL BIT(5) + +#define NPCM_IOXCTS 0x28 +#define NPCM_IOXCTS_IOXIF_EN BIT(7) +#define NPCM_IOXCTS_RD_MODE GENMASK(2, 1) +#define NPCM_IOXCTS_RD_MODE_PERIODIC BIT(2) + +#define NPCM_IOXCFG2 0x2B +#define NPCM_IOXCFG2_PORT GENMASK(3, 0) + +#define NPCM_IXOEVCFG_MASK GENMASK(1, 0) +#define NPCM_IXOEVCFG_FALLING BIT(1) +#define NPCM_IXOEVCFG_RISING BIT(0) +#define NPCM_IXOEVCFG_BOTH (NPCM_IXOEVCFG_FALLING | NPCM_IXOEVCFG_RISING) + +#define NPCM_CLK_MHZ (8 * HZ_PER_MHZ) +#define NPCM_750_OPT 6 +#define NPCM_845_OPT 5 + +#define GPIO_BANK(x) ((x) / 8) +#define GPIO_BIT(x) ((x) % 8) + +/* + * Select the frequency of shift clock. + * The shift clock is a division of the APB clock. + */ +struct npcm_clk_cfg { + unsigned int *sft_clk; + unsigned int *clk_sel; + unsigned int cfg_opt; +}; + +struct npcm_sgpio { + struct gpio_chip chip; + struct clk *pclk; + struct irq_chip intc; + raw_spinlock_t lock; + + void __iomem *base; + int irq; + u8 nin_sgpio; + u8 nout_sgpio; + u8 in_port; + u8 out_port; + u8 int_type[MAX_NR_HW_SGPIO]; +}; + +struct npcm_sgpio_bank { + u8 rdata_reg; + u8 wdata_reg; + u8 event_config; + u8 event_status; +}; + +enum npcm_sgpio_reg { + READ_DATA, + WRITE_DATA, + EVENT_CFG, + EVENT_STS, +}; + +static const struct npcm_sgpio_bank npcm_sgpio_banks[] = { + { + .wdata_reg = 0x00, + .rdata_reg = 0x08, + .event_config = 0x10, + .event_status = 0x20, + }, + { + .wdata_reg = 0x01, + .rdata_reg = 0x09, + .event_config = 0x12, + .event_status = 0x21, + }, + { + .wdata_reg = 0x02, + .rdata_reg = 0x0a, + .event_config = 0x14, + .event_status = 0x22, + }, + { + .wdata_reg = 0x03, + .rdata_reg = 0x0b, + .event_config = 0x16, + .event_status = 0x23, + }, + { + .wdata_reg = 0x04, + .rdata_reg = 0x0c, + .event_config = 0x18, + .event_status = 0x24, + }, + { + .wdata_reg = 0x05, + .rdata_reg = 0x0d, + .event_config = 0x1a, + .event_status = 0x25, + }, + { + .wdata_reg = 0x06, + .rdata_reg = 0x0e, + .event_config = 0x1c, + .event_status = 0x26, + }, + { + .wdata_reg = 0x07, + .rdata_reg = 0x0f, + .event_config = 0x1e, + .event_status = 0x27, + }, +}; + +static void __iomem *bank_reg(struct npcm_sgpio *gpio, + const struct npcm_sgpio_bank *bank, + const enum npcm_sgpio_reg reg) +{ + switch (reg) { + case READ_DATA: + return gpio->base + bank->rdata_reg; + case WRITE_DATA: + return gpio->base + bank->wdata_reg; + case EVENT_CFG: + return gpio->base + bank->event_config; + case EVENT_STS: + return gpio->base + bank->event_status; + default: + /* actually if code runs to here, it's an error case */ + dev_WARN(gpio->chip.parent, "Getting here is an error condition"); + return NULL; + } +} + +static const struct npcm_sgpio_bank *offset_to_bank(unsigned int offset) +{ + unsigned int bank = GPIO_BANK(offset); + + return &npcm_sgpio_banks[bank]; +} + +static void npcm_sgpio_irqd_to_data(struct irq_data *d, + struct npcm_sgpio **gpio, + const struct npcm_sgpio_bank **bank, + u8 *bit, unsigned int *offset) +{ + struct npcm_sgpio *internal; + + *offset = irqd_to_hwirq(d); + internal = irq_data_get_irq_chip_data(d); + + *gpio = internal; + *offset -= internal->nout_sgpio; + *bank = offset_to_bank(*offset); + *bit = GPIO_BIT(*offset); +} + +static int npcm_sgpio_init_port(struct npcm_sgpio *gpio) +{ + u8 in_port, out_port, set_port, reg; + + in_port = GPIO_BANK(gpio->nin_sgpio); + if (GPIO_BIT(gpio->nin_sgpio) > 0) + in_port += 1; + + out_port = GPIO_BANK(gpio->nout_sgpio); + if (GPIO_BIT(gpio->nout_sgpio) > 0) + out_port += 1; + + gpio->in_port = in_port; + gpio->out_port = out_port; + set_port = (out_port & NPCM_IOXCFG2_PORT) << 4 | (in_port & NPCM_IOXCFG2_PORT); + iowrite8(set_port, gpio->base + NPCM_IOXCFG2); + + reg = ioread8(gpio->base + NPCM_IOXCFG2); + + return reg == set_port ? 0 : -EINVAL; + +} + +static int npcm_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + + return offset < gpio->nout_sgpio ? -EINVAL : 0; + +} + +static int npcm_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int val) +{ + gc->set(gc, offset, val); + + return 0; +} + +static int npcm_sgpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + + if (offset < gpio->nout_sgpio) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static void npcm_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + const struct npcm_sgpio_bank *bank = offset_to_bank(offset); + void __iomem *addr; + u8 reg = 0; + + addr = bank_reg(gpio, bank, WRITE_DATA); + reg = ioread8(addr); + + if (val) + reg |= BIT(GPIO_BIT(offset)); + else + reg &= ~BIT(GPIO_BIT(offset)); + + iowrite8(reg, addr); +} + +static int npcm_sgpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + const struct npcm_sgpio_bank *bank; + void __iomem *addr; + u8 reg; + + if (offset < gpio->nout_sgpio) { + bank = offset_to_bank(offset); + addr = bank_reg(gpio, bank, WRITE_DATA); + } else { + offset -= gpio->nout_sgpio; + bank = offset_to_bank(offset); + addr = bank_reg(gpio, bank, READ_DATA); + } + + reg = ioread8(addr); + + return !!(reg & BIT(GPIO_BIT(offset))); +} + +static void npcm_sgpio_setup_enable(struct npcm_sgpio *gpio, bool enable) +{ + u8 reg; + + reg = ioread8(gpio->base + NPCM_IOXCTS); + reg = (reg & ~NPCM_IOXCTS_RD_MODE) | NPCM_IOXCTS_RD_MODE_PERIODIC; + + if (enable) + reg |= NPCM_IOXCTS_IOXIF_EN; + else + reg &= ~NPCM_IOXCTS_IOXIF_EN; + + iowrite8(reg, gpio->base + NPCM_IOXCTS); +} + +static int npcm_sgpio_setup_clk(struct npcm_sgpio *gpio, + const struct npcm_clk_cfg *clk_cfg) +{ + unsigned long apb_freq; + u32 val; + u8 tmp; + int i; + + apb_freq = clk_get_rate(gpio->pclk); + tmp = ioread8(gpio->base + NPCM_IOXCFG1) & ~NPCM_IOXCFG1_SFT_CLK; + + for (i = clk_cfg->cfg_opt-1; i > 0; i--) { + val = apb_freq / clk_cfg->sft_clk[i]; + if (NPCM_CLK_MHZ > val) { + iowrite8(clk_cfg->clk_sel[i] | tmp, gpio->base + NPCM_IOXCFG1); + return 0; + } + } + + return -EINVAL; +} + +static void npcm_sgpio_irq_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, unsigned int ngpios) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + + /* input GPIOs in the high range */ + bitmap_set(valid_mask, gpio->nout_sgpio, gpio->nin_sgpio); + bitmap_clear(valid_mask, 0, gpio->nout_sgpio); +} + +static void npcm_sgpio_irq_set_mask(struct irq_data *d, bool set) +{ + const struct npcm_sgpio_bank *bank; + struct npcm_sgpio *gpio; + unsigned long flags; + void __iomem *addr; + unsigned int offset; + u16 reg, type; + u8 bit; + + npcm_sgpio_irqd_to_data(d, &gpio, &bank, &bit, &offset); + addr = bank_reg(gpio, bank, EVENT_CFG); + + reg = ioread16(addr); + if (set) { + reg &= ~(NPCM_IXOEVCFG_MASK << (bit * 2)); + } else { + type = gpio->int_type[offset]; + reg |= (type << (bit * 2)); + } + + raw_spin_lock_irqsave(&gpio->lock, flags); + + npcm_sgpio_setup_enable(gpio, false); + + iowrite16(reg, addr); + + npcm_sgpio_setup_enable(gpio, true); + + addr = bank_reg(gpio, bank, EVENT_STS); + reg = ioread8(addr); + reg |= BIT(bit); + iowrite8(reg, addr); + + raw_spin_unlock_irqrestore(&gpio->lock, flags); +} + +static void npcm_sgpio_irq_ack(struct irq_data *d) +{ + const struct npcm_sgpio_bank *bank; + struct npcm_sgpio *gpio; + unsigned long flags; + void __iomem *status_addr; + unsigned int offset; + u8 bit; + + npcm_sgpio_irqd_to_data(d, &gpio, &bank, &bit, &offset); + status_addr = bank_reg(gpio, bank, EVENT_STS); + raw_spin_lock_irqsave(&gpio->lock, flags); + iowrite8(BIT(bit), status_addr); + raw_spin_unlock_irqrestore(&gpio->lock, flags); +} + +static void npcm_sgpio_irq_mask(struct irq_data *d) +{ + npcm_sgpio_irq_set_mask(d, true); +} + +static void npcm_sgpio_irq_unmask(struct irq_data *d) +{ + npcm_sgpio_irq_set_mask(d, false); +} + +static int npcm_sgpio_set_type(struct irq_data *d, unsigned int type) +{ + const struct npcm_sgpio_bank *bank; + irq_flow_handler_t handler; + struct npcm_sgpio *gpio; + unsigned long flags; + void __iomem *addr; + unsigned int offset; + u16 reg, val; + u8 bit; + + npcm_sgpio_irqd_to_data(d, &gpio, &bank, &bit, &offset); + + switch (type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_BOTH: + val = NPCM_IXOEVCFG_BOTH; + break; + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_LEVEL_HIGH: + val = NPCM_IXOEVCFG_RISING; + break; + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_LEVEL_LOW: + val = NPCM_IXOEVCFG_FALLING; + break; + default: + return -EINVAL; + } + + if (type & IRQ_TYPE_LEVEL_MASK) + handler = handle_level_irq; + else + handler = handle_edge_irq; + + gpio->int_type[offset] = val; + + raw_spin_lock_irqsave(&gpio->lock, flags); + npcm_sgpio_setup_enable(gpio, false); + addr = bank_reg(gpio, bank, EVENT_CFG); + reg = ioread16(addr); + + reg |= (val << (bit * 2)); + + iowrite16(reg, addr); + npcm_sgpio_setup_enable(gpio, true); + raw_spin_unlock_irqrestore(&gpio->lock, flags); + + irq_set_handler_locked(d, handler); + + return 0; +} + +static void npcm_sgpio_irq_handler(struct irq_desc *desc) +{ + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct irq_chip *ic = irq_desc_get_chip(desc); + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + unsigned int i, j, girq; + unsigned long reg; + + chained_irq_enter(ic, desc); + + for (i = 0; i < ARRAY_SIZE(npcm_sgpio_banks); i++) { + const struct npcm_sgpio_bank *bank = &npcm_sgpio_banks[i]; + + reg = ioread8(bank_reg(gpio, bank, EVENT_STS)); + for_each_set_bit(j, ®, 8) { + girq = irq_find_mapping(gc->irq.domain, i * 8 + gpio->nout_sgpio + j); + generic_handle_domain_irq(gc->irq.domain, girq); + } + } + + chained_irq_exit(ic, desc); +} + +static const struct irq_chip sgpio_irq_chip = { + .name = "sgpio-irq", + .irq_ack = npcm_sgpio_irq_ack, + .irq_mask = npcm_sgpio_irq_mask, + .irq_unmask = npcm_sgpio_irq_unmask, + .irq_set_type = npcm_sgpio_set_type, + .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int npcm_sgpio_setup_irqs(struct npcm_sgpio *gpio, + struct platform_device *pdev) +{ + int rc, i; + struct gpio_irq_chip *irq; + + rc = platform_get_irq(pdev, 0); + if (rc < 0) + return rc; + + gpio->irq = rc; + + npcm_sgpio_setup_enable(gpio, false); + + /* Disable IRQ and clear Interrupt status registers for all SGPIO Pins. */ + for (i = 0; i < ARRAY_SIZE(npcm_sgpio_banks); i++) { + const struct npcm_sgpio_bank *bank = &npcm_sgpio_banks[i]; + + iowrite16(0, bank_reg(gpio, bank, EVENT_CFG)); + iowrite8(0xff, bank_reg(gpio, bank, EVENT_STS)); + } + + irq = &gpio->chip.irq; + gpio_irq_chip_set_chip(irq, &sgpio_irq_chip); + irq->init_valid_mask = npcm_sgpio_irq_init_valid_mask; + irq->handler = handle_bad_irq; + irq->default_type = IRQ_TYPE_NONE; + irq->parent_handler = npcm_sgpio_irq_handler; + irq->parent_handler_data = gpio; + irq->parents = &gpio->irq; + irq->num_parents = 1; + + return 0; +} + +static int npcm_sgpio_probe(struct platform_device *pdev) +{ + struct npcm_sgpio *gpio; + const struct npcm_clk_cfg *clk_cfg; + int rc; + u32 nin_gpios, nout_gpios; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + gpio->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(gpio->base)) + return PTR_ERR(gpio->base); + + clk_cfg = device_get_match_data(&pdev->dev); + if (!clk_cfg) + return -EINVAL; + + rc = device_property_read_u32(&pdev->dev, "nuvoton,input-ngpios", &nin_gpios); + if (rc < 0) + return dev_err_probe(&pdev->dev, rc, "Could not read ngpios property\n"); + + rc = device_property_read_u32(&pdev->dev, "nuvoton,output-ngpios", &nout_gpios); + if (rc < 0) + return dev_err_probe(&pdev->dev, rc, "Could not read ngpios property\n"); + + gpio->nin_sgpio = nin_gpios; + gpio->nout_sgpio = nout_gpios; + if (gpio->nin_sgpio > MAX_NR_HW_SGPIO || gpio->nout_sgpio > MAX_NR_HW_SGPIO) + return dev_err_probe(&pdev->dev, -EINVAL, "Number of GPIOs exceeds the maximum of %d: input: %d output: %d\n", MAX_NR_HW_SGPIO, nin_gpios, nout_gpios); + + gpio->pclk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(gpio->pclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(gpio->pclk), "Could not get pclk\n"); + + rc = npcm_sgpio_setup_clk(gpio, clk_cfg); + if (rc < 0) + return dev_err_probe(&pdev->dev, rc, "Failed to setup clock\n"); + + raw_spin_lock_init(&gpio->lock); + gpio->chip.parent = &pdev->dev; + gpio->chip.ngpio = gpio->nin_sgpio + gpio->nout_sgpio; + gpio->chip.direction_input = npcm_sgpio_dir_in; + gpio->chip.direction_output = npcm_sgpio_dir_out; + gpio->chip.get_direction = npcm_sgpio_get_direction; + gpio->chip.get = npcm_sgpio_get; + gpio->chip.set = npcm_sgpio_set; + gpio->chip.label = dev_name(&pdev->dev); + gpio->chip.base = -1; + + rc = npcm_sgpio_init_port(gpio); + if (rc < 0) + return rc; + + rc = npcm_sgpio_setup_irqs(gpio, pdev); + if (rc < 0) + return rc; + + rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); + if (rc) + return dev_err_probe(&pdev->dev, rc, "GPIO registering failed\n"); + + npcm_sgpio_setup_enable(gpio, true); + + return 0; +} + +static unsigned int npcm750_SFT_CLK[NPCM_750_OPT] = { + 1024, 32, 8, 4, 3, 2, +}; + +static unsigned int npcm750_CLK_SEL[NPCM_750_OPT] = { + 0x00, 0x05, 0x07, 0x0C, 0x0D, 0x0E, +}; + +static unsigned int npcm845_SFT_CLK[NPCM_845_OPT] = { + 1024, 32, 16, 8, 4, +}; + +static unsigned int npcm845_CLK_SEL[NPCM_845_OPT] = { + 0x00, 0x05, 0x06, 0x07, 0x0C, +}; + +static struct npcm_clk_cfg npcm750_sgpio_pdata = { + .sft_clk = npcm750_SFT_CLK, + .clk_sel = npcm750_CLK_SEL, + .cfg_opt = NPCM_750_OPT, +}; + +static const struct npcm_clk_cfg npcm845_sgpio_pdata = { + .sft_clk = npcm845_SFT_CLK, + .clk_sel = npcm845_CLK_SEL, + .cfg_opt = NPCM_845_OPT, +}; + +static const struct of_device_id npcm_sgpio_of_table[] = { + { .compatible = "nuvoton,npcm750-sgpio", .data = &npcm750_sgpio_pdata, }, + { .compatible = "nuvoton,npcm845-sgpio", .data = &npcm845_sgpio_pdata, }, + {} +}; +MODULE_DEVICE_TABLE(of, npcm_sgpio_of_table); + +static struct platform_driver npcm_sgpio_driver = { + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = npcm_sgpio_of_table, + }, + .probe = npcm_sgpio_probe, +}; +module_platform_driver(npcm_sgpio_driver); + +MODULE_AUTHOR("Jim Liu "); +MODULE_AUTHOR("Joseph Liu "); +MODULE_DESCRIPTION("Nuvoton NPCM Serial GPIO Driver"); +MODULE_LICENSE("GPL v2");