From nobody Fri Oct 3 23:08:19 2025 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93A442D8DA3 for ; Sun, 24 Aug 2025 11:58:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756036684; cv=none; b=PK2DQlMj9MCJ/JIa2U7eLxIOWgFQLNAM0KzmLeBj+Ze2RrIfB5umrMvOdeaZu6aHqvbeqGW4zv431xdRMjsqTYBnEsVGUl+/Dn2xiw75mcbUXmPJhfpCLKbkFlONRLHhu1b3PO6WaIq8nQiBcYucw0KpENAkjPectpEVUE1S7EQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756036684; c=relaxed/simple; bh=qFg1KV9wUddnletBmw9Jh03TWXAMow0hfT6D3eV2KmI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MpSzh2rq1ihTSjT4gy1sAEGuB5rHMWpMg3UbAWiDqS1MLcJsG1dmATc9RWz9V5QTXS7Gwn8lpbtPIV4Ptl8y6iS8dpd6AMZ1ncYFeOfMjqEIjClwG5bBbYNoNvxLlkU524DrqEgPglUkoMuEUkzEkATowGuB+VEZTLlqbdWJENE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=HG15YKBC; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="HG15YKBC" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 096A04E40C35; Sun, 24 Aug 2025 11:58:01 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D7182605F1; Sun, 24 Aug 2025 11:58:00 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 51C371C22D33A; Sun, 24 Aug 2025 13:57:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1756036679; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=WOU+KrbiHQXXsg8GAcDkGetD9yZnlKPQ7YQWxgYZBT0=; b=HG15YKBChdNzsqR/vL3PA93jptz1PQDFGgQrr1hfcokkzihZBRc1gtkB5HIdTXuQuDLrd1 SG/dqgf5YooX2/Q9OhGZN0pWvOtPfpt9vxa5IGFGB0sgeO1z4e6w3Gayzfs06mo140NydQ cX3qdZS1gPdxt+IOZKnB4R5N1u067Muhdyj2b7t+ntsFPZgyG43Mrue61NJXcNGAjrQbC0 Ykea99MZfVTEoRtxL6FxHyaGLIRgO9z0FRbAONNpZFKdBBIRJbHKhGqU4bmr/cg4/FGh7k 2dWS0zxnYxU5L0DCBD3252uF9g4mBRLbpmrKKQv2FZ3CBmOzKyNECeOvPA2aFQ== From: Mathieu Dubois-Briand Date: Sun, 24 Aug 2025 13:57:22 +0200 Subject: [PATCH v14 03/10] pinctrl: Add MAX7360 pinctrl driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250824-mdb-max7360-support-v14-3-435cfda2b1ea@bootlin.com> References: <20250824-mdb-max7360-support-v14-0-435cfda2b1ea@bootlin.com> In-Reply-To: <20250824-mdb-max7360-support-v14-0-435cfda2b1ea@bootlin.com> To: Lee Jones , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Kamel Bouhara , Linus Walleij , Bartosz Golaszewski , Dmitry Torokhov , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Walle , Mark Brown , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, linux-input@vger.kernel.org, linux-pwm@vger.kernel.org, andriy.shevchenko@intel.com, =?utf-8?q?Gr=C3=A9gory_Clement?= , Thomas Petazzoni , Mathieu Dubois-Briand , Andy Shevchenko X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1756036647; l=9011; i=mathieu.dubois-briand@bootlin.com; s=20241219; h=from:subject:message-id; bh=qFg1KV9wUddnletBmw9Jh03TWXAMow0hfT6D3eV2KmI=; b=N3ybeHT5l0C8Ago/4QwKgPGg4w2NA3P9MtG9r3P/s0pCjLg0E7NhijxxGDWCsxLNQr+0v1jtr 6t/WH3RaX3XAEhDE7e8TWwsIX3F8+IcgKbi2l5LKvy0WCic0ZzeFD7J X-Developer-Key: i=mathieu.dubois-briand@bootlin.com; a=ed25519; pk=1PVTmzPXfKvDwcPUzG0aqdGoKZJA3b9s+3DqRlm0Lww= X-Last-TLS-Session-Version: TLSv1.3 Add driver for Maxim Integrated MAX7360 pinctrl on the PORT pins. Pins can be used either for GPIO, PWM or rotary encoder functionalities. Signed-off-by: Mathieu Dubois-Briand Reviewed-by: Linus Walleij Reviewed-by: Andy Shevchenko --- drivers/pinctrl/Kconfig | 11 ++ drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-max7360.c | 215 ++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 227 insertions(+) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index ddd11668457c..57e4bdc8011d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -358,6 +358,17 @@ config PINCTRL_LPC18XX help Pinctrl driver for NXP LPC18xx/43xx System Control Unit (SCU). =20 +config PINCTRL_MAX7360 + tristate "MAX7360 Pincontrol support" + depends on MFD_MAX7360 + select PINMUX + select GENERIC_PINCONF + help + Say Y here to enable pin control support for Maxim MAX7360 keypad + controller. + This keypad controller has 8 GPIO pins that may work as GPIO, or PWM, + or rotary encoder alternate modes. + config PINCTRL_MAX77620 tristate "MAX77620/MAX20024 Pincontrol support" depends on MFD_MAX77620 && OF diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 909ab89a56d2..65aa432fc97e 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PINCTRL_FALCON) +=3D pinctrl-falcon.o obj-$(CONFIG_PINCTRL_LOONGSON2) +=3D pinctrl-loongson2.o obj-$(CONFIG_PINCTRL_XWAY) +=3D pinctrl-xway.o obj-$(CONFIG_PINCTRL_LPC18XX) +=3D pinctrl-lpc18xx.o +obj-$(CONFIG_PINCTRL_MAX7360) +=3D pinctrl-max7360.o obj-$(CONFIG_PINCTRL_MAX77620) +=3D pinctrl-max77620.o obj-$(CONFIG_PINCTRL_MCP23S08_I2C) +=3D pinctrl-mcp23s08_i2c.o obj-$(CONFIG_PINCTRL_MCP23S08_SPI) +=3D pinctrl-mcp23s08_spi.o diff --git a/drivers/pinctrl/pinctrl-max7360.c b/drivers/pinctrl/pinctrl-ma= x7360.c new file mode 100644 index 000000000000..abfaff468bad --- /dev/null +++ b/drivers/pinctrl/pinctrl-max7360.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2025 Bootlin + * + * Author: Mathieu Dubois-Briand + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "core.h" +#include "pinmux.h" + +struct max7360_pinctrl { + struct pinctrl_dev *pctldev; + struct pinctrl_desc pinctrl_desc; +}; + +static const struct pinctrl_pin_desc max7360_pins[] =3D { + PINCTRL_PIN(0, "PORT0"), + PINCTRL_PIN(1, "PORT1"), + PINCTRL_PIN(2, "PORT2"), + PINCTRL_PIN(3, "PORT3"), + PINCTRL_PIN(4, "PORT4"), + PINCTRL_PIN(5, "PORT5"), + PINCTRL_PIN(6, "PORT6"), + PINCTRL_PIN(7, "PORT7"), +}; + +static const unsigned int port0_pins[] =3D {0}; +static const unsigned int port1_pins[] =3D {1}; +static const unsigned int port2_pins[] =3D {2}; +static const unsigned int port3_pins[] =3D {3}; +static const unsigned int port4_pins[] =3D {4}; +static const unsigned int port5_pins[] =3D {5}; +static const unsigned int port6_pins[] =3D {6}; +static const unsigned int port7_pins[] =3D {7}; +static const unsigned int rotary_pins[] =3D {6, 7}; + +static const struct pingroup max7360_groups[] =3D { + PINCTRL_PINGROUP("PORT0", port0_pins, ARRAY_SIZE(port0_pins)), + PINCTRL_PINGROUP("PORT1", port1_pins, ARRAY_SIZE(port1_pins)), + PINCTRL_PINGROUP("PORT2", port2_pins, ARRAY_SIZE(port2_pins)), + PINCTRL_PINGROUP("PORT3", port3_pins, ARRAY_SIZE(port3_pins)), + PINCTRL_PINGROUP("PORT4", port4_pins, ARRAY_SIZE(port4_pins)), + PINCTRL_PINGROUP("PORT5", port5_pins, ARRAY_SIZE(port5_pins)), + PINCTRL_PINGROUP("PORT6", port6_pins, ARRAY_SIZE(port6_pins)), + PINCTRL_PINGROUP("PORT7", port7_pins, ARRAY_SIZE(port7_pins)), + PINCTRL_PINGROUP("ROTARY", rotary_pins, ARRAY_SIZE(rotary_pins)), +}; + +static int max7360_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(max7360_groups); +} + +static const char *max7360_pinctrl_get_group_name(struct pinctrl_dev *pctl= dev, + unsigned int group) +{ + return max7360_groups[group].name; +} + +static int max7360_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int group, + const unsigned int **pins, + unsigned int *num_pins) +{ + *pins =3D max7360_groups[group].pins; + *num_pins =3D max7360_groups[group].npins; + return 0; +} + +static const struct pinctrl_ops max7360_pinctrl_ops =3D { + .get_groups_count =3D max7360_pinctrl_get_groups_count, + .get_group_name =3D max7360_pinctrl_get_group_name, + .get_group_pins =3D max7360_pinctrl_get_group_pins, +#ifdef CONFIG_OF + .dt_node_to_map =3D pinconf_generic_dt_node_to_map_pin, + .dt_free_map =3D pinconf_generic_dt_free_map, +#endif +}; + +static const char * const simple_groups[] =3D { + "PORT0", "PORT1", "PORT2", "PORT3", + "PORT4", "PORT5", "PORT6", "PORT7", +}; + +static const char * const rotary_groups[] =3D { "ROTARY" }; + +#define MAX7360_PINCTRL_FN_GPIO 0 +#define MAX7360_PINCTRL_FN_PWM 1 +#define MAX7360_PINCTRL_FN_ROTARY 2 +static const struct pinfunction max7360_functions[] =3D { + [MAX7360_PINCTRL_FN_GPIO] =3D PINCTRL_PINFUNCTION("gpio", simple_groups, + ARRAY_SIZE(simple_groups)), + [MAX7360_PINCTRL_FN_PWM] =3D PINCTRL_PINFUNCTION("pwm", simple_groups, + ARRAY_SIZE(simple_groups)), + [MAX7360_PINCTRL_FN_ROTARY] =3D PINCTRL_PINFUNCTION("rotary", rotary_grou= ps, + ARRAY_SIZE(rotary_groups)), +}; + +static int max7360_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(max7360_functions); +} + +static const char *max7360_get_function_name(struct pinctrl_dev *pctldev, = unsigned int selector) +{ + return max7360_functions[selector].name; +} + +static int max7360_get_function_groups(struct pinctrl_dev *pctldev, unsign= ed int selector, + const char * const **groups, + unsigned int * const num_groups) +{ + *groups =3D max7360_functions[selector].groups; + *num_groups =3D max7360_functions[selector].ngroups; + + return 0; +} + +static int max7360_set_mux(struct pinctrl_dev *pctldev, unsigned int selec= tor, + unsigned int group) +{ + struct regmap *regmap =3D dev_get_regmap(pctldev->dev->parent, NULL); + int val; + + /* + * GPIO and PWM functions are the same: we only need to handle the + * rotary encoder function, on pins 6 and 7. + */ + if (max7360_groups[group].pins[0] >=3D 6) { + if (selector =3D=3D MAX7360_PINCTRL_FN_ROTARY) + val =3D MAX7360_GPIO_CFG_RTR_EN; + else + val =3D 0; + + return regmap_write_bits(regmap, MAX7360_REG_GPIOCFG, MAX7360_GPIO_CFG_R= TR_EN, val); + } + + return 0; +} + +static const struct pinmux_ops max7360_pmxops =3D { + .get_functions_count =3D max7360_get_functions_count, + .get_function_name =3D max7360_get_function_name, + .get_function_groups =3D max7360_get_function_groups, + .set_mux =3D max7360_set_mux, + .strict =3D true, +}; + +static int max7360_pinctrl_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + struct pinctrl_desc *pd; + struct max7360_pinctrl *chip; + struct device *dev =3D &pdev->dev; + + regmap =3D dev_get_regmap(dev->parent, NULL); + if (!regmap) + return dev_err_probe(dev, -ENODEV, "Could not get parent regmap\n"); + + chip =3D devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + pd =3D &chip->pinctrl_desc; + + pd->pctlops =3D &max7360_pinctrl_ops; + pd->pmxops =3D &max7360_pmxops; + pd->name =3D dev_name(dev); + pd->pins =3D max7360_pins; + pd->npins =3D MAX7360_MAX_GPIO; + pd->owner =3D THIS_MODULE; + + /* + * This MFD sub-device does not have any associated device tree node: + * properties are stored in the device node of the parent (MFD) device + * and this same node is used in phandles of client devices. + * Reuse this device tree node here, as otherwise the pinctrl subsystem + * would be confused by this topology. + */ + device_set_of_node_from_dev(dev, dev->parent); + + chip->pctldev =3D devm_pinctrl_register(dev, pd, chip); + if (IS_ERR(chip->pctldev)) + return dev_err_probe(dev, PTR_ERR(chip->pctldev), "can't register contro= ller\n"); + + return 0; +} + +static struct platform_driver max7360_pinctrl_driver =3D { + .driver =3D { + .name =3D "max7360-pinctrl", + }, + .probe =3D max7360_pinctrl_probe, +}; +module_platform_driver(max7360_pinctrl_driver); + +MODULE_DESCRIPTION("MAX7360 pinctrl driver"); +MODULE_AUTHOR("Mathieu Dubois-Briand "); +MODULE_LICENSE("GPL"); --=20 2.39.5