From nobody Thu May 1 17:42:38 2025 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2C9121421A for <linux-kernel@vger.kernel.org>; Wed, 9 Apr 2025 20:37:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744231061; cv=none; b=TC+loxvSNHEasyuxwq0JVDBGN0PKP4hdqR6NR+gnSRgorE+/a4TYv88CB7A8cqGSlpIhBc2/W93oqdd54sH1TLMbscOOjmezovVw4j5I1n8UnC5GCmD4C3OJgts3SkEaOiG9K+0FlqJAhnRfx8h0kg530bpuOqCvPEx1YrZmt+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744231061; c=relaxed/simple; bh=LbHBF4TKWm+hdTLnEofbBcbPOlVj2NdAt9E7/ghwK00=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RAYqyqtu/lPoELI8+VRGqUuG2+WYEOzBc6SBFtqWQpUYRK23M/CL1YT0C84RetUurUDEaD4tbZ6pwSDmEbs6xTnKlTRSdZwPvKuEU7V1WVyGrbrTCN/46YWtkSGPPb28oHLR+5H3qN8iWvf+R0VFBFMyLB9pQrAP+5pGJPHD6Kc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=ld05X2wV; arc=none smtp.client-ip=209.85.218.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="ld05X2wV" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-ac298c8fa50so18980866b.1 for <linux-kernel@vger.kernel.org>; Wed, 09 Apr 2025 13:37:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1744231054; x=1744835854; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=w6ULFspg/CGx1bRJYjAsIrxdZCgjn7lM1Rjdh9Ft3ak=; b=ld05X2wV21FEsszR4Xo4jDv5m5f4eCeqRLPezGDOdiWsuhrpn/JUsbQIKsSPmxI0fD OEXlSJt0FNbuJoGVcf7nej6rQf53yCDYSHhXnwl1AXD5WzQnkE0Gxl+ig0VK9BLvNCxD 82z0HE1Yzc13bSv2ul7Y8+ack8rXPUYVyg/MvjGw2VdDGDuhDkFSX534NsFysZ6V2q6s V2r+hAo/X5SydxfADjd61g8UEj8RCiZsDMxs4QKnLPHqA5W1AQhEii0L3yHVK/9YfvGy kJLbdkx5xcO9hBLzQJOuNmURRf0ahmb/gmYOQfzKwMatrRQmUFbVfZeE2dWmMeiDh7OU YUYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744231054; x=1744835854; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=w6ULFspg/CGx1bRJYjAsIrxdZCgjn7lM1Rjdh9Ft3ak=; b=AbBVQPKwdTkCmcQHNWO5MMUnhBSbYEMH+izImhKGgs6ryxh6Xz1J/ICKCfEVUygCJl tG4HHv5TcC58ei9nImi4hz5IwrrvXuR5YCNh4As+1rr8ioLnree4govaOUx3l48APU7R 9F8VVCD0U54CPkDiF49VC6T/w8ZF9zi8W9tmvEv/1sRRXV3Hp6PfFfMJ5Gu3g99TPKWD a+iLKEWkpf/tED+FoCuwqjO9yOH2QtZyAqh/2TmUWB7ru2vPsrK4h2XX9Jy1EcNhGpEI Uxw9hgME8yHOveB+sUxd/mYwh4h8SxhRHncEHNzas+Rl5E9RivrC4JsizgaNxzRY1KzF j0FQ== X-Forwarded-Encrypted: i=1; AJvYcCWP6LH9yWSgfbAph/ymMWbVg081VWJ8/RbOvTI+ZjFD1SnES8XlTGSyF/M30W73YAps9pMG7YxQONBgKOs=@vger.kernel.org X-Gm-Message-State: AOJu0YzBcoVxPY4z1P9cplf5Ioit2bOy0+JNnixIqDm61PSWEyMxbwW3 sRTZJVqozum7c2wRZaJ2DY4dsggvkdNkOqEVLPYul6oVaN9bWnfhboVmKCMO1Cc= X-Gm-Gg: ASbGncuYwd2KiBYk2PSpV16Xh57QWaOZW36CSac7j1IUf0Vajq1oP1lGXtz13usPjH0 9kMequm1XEC093z+rtUubmCGDvnyLCENScc3BXz2X26MQveevBKMMR64jBloApRZvqUBL9tgaJq u+4lCFmtHcuv6MJ71xsLegFAt7cx8R2BbFxB/7NtpNKxzySjMZUDg3MIi5We7wBNHFwJMekdOIM oidLVH2eo779EmAA9c9l9ZeA6ckEECGyUevfOPqLo85KVA+6/ciMY3qiYA9VxiteZIs7htV73rS jK844kejrqaDYJeaa/dGhYx/ZYQhUmvUze5M/0nsM9jKlGRLjmAxzuLZQyZbgxSSqQVzQaeYQZg QDdDenJJujPj5xWOV0xIVR6EcdIQ= X-Google-Smtp-Source: AGHT+IFgA//GqlMMtxP6zq80GkYMJkQOvivm+CoiEHZTZ3tD28P40x9A2ESKEVfJI0wc+SZlWIBudA== X-Received: by 2002:a17:907:3f28:b0:ac7:ecfc:e5fa with SMTP id a640c23a62f3a-acabd4db30cmr8323166b.54.1744231053600; Wed, 09 Apr 2025 13:37:33 -0700 (PDT) Received: from puffmais.c.googlers.com (40.162.204.35.bc.googleusercontent.com. [35.204.162.40]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-acaa1ccc001sm145850366b.126.2025.04.09.13.37.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Apr 2025 13:37:33 -0700 (PDT) From: =?utf-8?q?Andr=C3=A9_Draszik?= <andre.draszik@linaro.org> Date: Wed, 09 Apr 2025 21:37:29 +0100 Subject: [PATCH v4 08/32] mfd: sec: Split into core and transport (i2c) drivers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250409-s2mpg10-v4-8-d66d5f39b6bf@linaro.org> References: <20250409-s2mpg10-v4-0-d66d5f39b6bf@linaro.org> In-Reply-To: <20250409-s2mpg10-v4-0-d66d5f39b6bf@linaro.org> To: Krzysztof Kozlowski <krzk@kernel.org>, Lee Jones <lee@kernel.org>, Rob Herring <robh@kernel.org>, Conor Dooley <conor+dt@kernel.org>, Sylwester Nawrocki <s.nawrocki@samsung.com>, Chanwoo Choi <cw00.choi@samsung.com>, Alim Akhtar <alim.akhtar@samsung.com>, Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@kernel.org>, Russell King <linux@armlinux.org.uk>, Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will@kernel.org>, Alexandre Belloni <alexandre.belloni@bootlin.com> Cc: Peter Griffin <peter.griffin@linaro.org>, Tudor Ambarus <tudor.ambarus@linaro.org>, Will McVicker <willmcvicker@google.com>, kernel-team@android.com, linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rtc@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Draszik?= <andre.draszik@linaro.org>, Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> X-Mailer: b4 0.14.2 As a preparation for adding support for Samsung's S2MPG10, which is connected via SPEEDY / ACPM rather than I2C, split out (move) all I2C-specific driver code into its own kernel module, sec-i2c, and make the existing sec-core module be just the transport-agnostic core driver kernel module. At the same time, update all defconfigs that reference the old kconfig symbol name. While at it, also update file header comments and module description(s) to drop references to 'mfd', and update comments to be C-style, not C++. Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Signed-off-by: Andr=C3=A9 Draszik <andre.draszik@linaro.org> --- Note: checkpatch complains about missing help for MFD_SEC_I2C here, but that's a false-positive due to patch context. It also suggests to update MAINTAINERS, but the new file is covered already due to using a wildcard. v2: * split MODULE_AUTHOR update out of this patch (Krzysztof) * keep DT parsing in core, not in transport driver (sec_pmic_i2c_parse_dt_pdata / sec_pmic_parse_dt_pdata) * merge defconfig updates into this patch (Krzysztof) --- arch/arm/configs/exynos_defconfig | 2 +- arch/arm/configs/multi_v7_defconfig | 2 +- arch/arm/configs/pxa_defconfig | 2 +- arch/arm64/configs/defconfig | 2 +- drivers/mfd/Kconfig | 18 ++- drivers/mfd/Makefile | 1 + drivers/mfd/sec-core.c | 247 +++++---------------------------= ---- drivers/mfd/sec-core.h | 9 ++ drivers/mfd/sec-i2c.c | 231 +++++++++++++++++++++++++++++++++ 9 files changed, 287 insertions(+), 227 deletions(-) diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_de= fconfig index 7ad48fdda1dac69a4a9612eabb573729bed7b3a6..251f45be6c14af59263373f21b2= 7b15f42ec7f61 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -167,7 +167,7 @@ CONFIG_MFD_MAX77686=3Dy CONFIG_MFD_MAX77693=3Dy CONFIG_MFD_MAX8997=3Dy CONFIG_MFD_MAX8998=3Dy -CONFIG_MFD_SEC_CORE=3Dy +CONFIG_MFD_SEC_I2C=3Dy CONFIG_MFD_STMPE=3Dy CONFIG_STMPE_I2C=3Dy CONFIG_MFD_TPS65090=3Dy diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v= 7_defconfig index ad037c175fdb0ec8601c9b3607aca0c0e5f3c145..7d06ac5369b1a2f325462f2cf5b= 54fe22061ca77 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -612,7 +612,7 @@ CONFIG_MFD_QCOM_RPM=3Dy CONFIG_MFD_SPMI_PMIC=3Dy CONFIG_MFD_RK8XX_I2C=3Dy CONFIG_MFD_RN5T618=3Dy -CONFIG_MFD_SEC_CORE=3Dy +CONFIG_MFD_SEC_I2C=3Dy CONFIG_MFD_STMPE=3Dy CONFIG_MFD_PALMAS=3Dy CONFIG_MFD_TPS65090=3Dy diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index de0ac8f521d7612704ce327e9ac16ab9e999f3d3..064e79baf20da809c9ab1f1fa18= 282aaba11a41f 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -335,7 +335,7 @@ CONFIG_MFD_MAX77693=3Dy CONFIG_MFD_MAX8907=3Dm CONFIG_EZX_PCAP=3Dy CONFIG_UCB1400_CORE=3Dm -CONFIG_MFD_SEC_CORE=3Dy +CONFIG_MFD_SEC_I2C=3Dy CONFIG_MFD_PALMAS=3Dy CONFIG_MFD_TPS65090=3Dy CONFIG_MFD_TPS6586X=3Dy diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 5bb8f09422a22116781169611482179b10798c14..f021fb29683be1a10720d7e6415= daea771647879 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -769,7 +769,7 @@ CONFIG_MFD_MT6397=3Dy CONFIG_MFD_SPMI_PMIC=3Dy CONFIG_MFD_RK8XX_I2C=3Dy CONFIG_MFD_RK8XX_SPI=3Dy -CONFIG_MFD_SEC_CORE=3Dy +CONFIG_MFD_SEC_I2C=3Dy CONFIG_MFD_SL28CPLD=3Dy CONFIG_RZ_MTU3=3Dy CONFIG_MFD_TI_AM335X_TSCADC=3Dm diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 22b93631003943c393d9fe704748bc23f1905397..62565dc89ec6d58611bbc1f31c6= 5f757343b6453 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1292,21 +1292,25 @@ config MFD_RN5T618 functionality of the device. =20 config MFD_SEC_CORE - tristate "Samsung Electronics PMIC Series Support" + tristate + select MFD_CORE + select REGMAP_IRQ + +config MFD_SEC_I2C + tristate "Samsung Electronics S2MPA/S2MPS1X/S2MPU/S5M series PMICs" depends on I2C=3Dy depends on OF - select MFD_CORE + select MFD_SEC_CORE select REGMAP_I2C - select REGMAP_IRQ help - Support for the Samsung Electronics PMIC devices coming - usually along with Samsung Exynos SoC chipset. + Support for the Samsung Electronics PMIC devices with I2C interface + coming usually along with Samsung Exynos SoC chipset. This driver provides common support for accessing the device, additional drivers must be enabled in order to use the functionality - of the device + of the device. =20 To compile this driver as a module, choose M here: the - module will be called sec-core. + module will be called sec-i2c. Have in mind that important core drivers (like regulators) depend on this driver so building this as a module might require proper initial ramdisk or might not boot up as well in certain scenarios. diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 948cbdf42a18b22a826f0b17fb8d5796a7ec8ba6..ab6c4b17a391946d4c88f52ccbf= ee5424b4fb2d2 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -229,6 +229,7 @@ obj-$(CONFIG_MFD_RK8XX_I2C) +=3D rk8xx-i2c.o obj-$(CONFIG_MFD_RK8XX_SPI) +=3D rk8xx-spi.o obj-$(CONFIG_MFD_RN5T618) +=3D rn5t618.o obj-$(CONFIG_MFD_SEC_CORE) +=3D sec-core.o sec-irq.o +obj-$(CONFIG_MFD_SEC_I2C) +=3D sec-i2c.o obj-$(CONFIG_MFD_SYSCON) +=3D syscon.o obj-$(CONFIG_MFD_LM3533) +=3D lm3533-core.o lm3533-ctrlbank.o obj-$(CONFIG_MFD_VEXPRESS_SYSREG) +=3D vexpress-sysreg.o diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 83693686567df61b5e09f7129dc6b01d69156ff3..bb664e052bf5198f2fc83a86bd6= e1e72364fb8df 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -1,23 +1,21 @@ // SPDX-License-Identifier: GPL-2.0+ -// -// Copyright (c) 2012 Samsung Electronics Co., Ltd -// http://www.samsung.com +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * http://www.samsung.com + * Copyright 2025 Linaro Ltd. + * + * Samsung SxM core driver + */ =20 #include <linux/device.h> #include <linux/err.h> -#include <linux/i2c.h> +#include <linux/export.h> #include <linux/interrupt.h> #include <linux/mfd/core.h> #include <linux/mfd/samsung/core.h> #include <linux/mfd/samsung/irq.h> -#include <linux/mfd/samsung/s2mpa01.h> #include <linux/mfd/samsung/s2mps11.h> #include <linux/mfd/samsung/s2mps13.h> -#include <linux/mfd/samsung/s2mps14.h> -#include <linux/mfd/samsung/s2mps15.h> -#include <linux/mfd/samsung/s2mpu02.h> -#include <linux/mfd/samsung/s5m8767.h> -#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/of.h> #include <linux/pm.h> @@ -88,144 +86,6 @@ static const struct mfd_cell s2mpu05_devs[] =3D { { .name =3D "s2mps15-rtc", }, }; =20 -static const struct of_device_id sec_dt_match[] =3D { - { - .compatible =3D "samsung,s5m8767-pmic", - .data =3D (void *)S5M8767X, - }, { - .compatible =3D "samsung,s2dos05", - .data =3D (void *)S2DOS05, - }, { - .compatible =3D "samsung,s2mps11-pmic", - .data =3D (void *)S2MPS11X, - }, { - .compatible =3D "samsung,s2mps13-pmic", - .data =3D (void *)S2MPS13X, - }, { - .compatible =3D "samsung,s2mps14-pmic", - .data =3D (void *)S2MPS14X, - }, { - .compatible =3D "samsung,s2mps15-pmic", - .data =3D (void *)S2MPS15X, - }, { - .compatible =3D "samsung,s2mpa01-pmic", - .data =3D (void *)S2MPA01, - }, { - .compatible =3D "samsung,s2mpu02-pmic", - .data =3D (void *)S2MPU02, - }, { - .compatible =3D "samsung,s2mpu05-pmic", - .data =3D (void *)S2MPU05, - }, { - /* Sentinel */ - }, -}; -MODULE_DEVICE_TABLE(of, sec_dt_match); - -static bool s2mpa01_volatile(struct device *dev, unsigned int reg) -{ - switch (reg) { - case S2MPA01_REG_INT1M: - case S2MPA01_REG_INT2M: - case S2MPA01_REG_INT3M: - return false; - default: - return true; - } -} - -static bool s2mps11_volatile(struct device *dev, unsigned int reg) -{ - switch (reg) { - case S2MPS11_REG_INT1M: - case S2MPS11_REG_INT2M: - case S2MPS11_REG_INT3M: - return false; - default: - return true; - } -} - -static bool s2mpu02_volatile(struct device *dev, unsigned int reg) -{ - switch (reg) { - case S2MPU02_REG_INT1M: - case S2MPU02_REG_INT2M: - case S2MPU02_REG_INT3M: - return false; - default: - return true; - } -} - -static const struct regmap_config sec_regmap_config =3D { - .reg_bits =3D 8, - .val_bits =3D 8, -}; - -static const struct regmap_config s2mpa01_regmap_config =3D { - .reg_bits =3D 8, - .val_bits =3D 8, - - .max_register =3D S2MPA01_REG_LDO_OVCB4, - .volatile_reg =3D s2mpa01_volatile, - .cache_type =3D REGCACHE_FLAT, -}; - -static const struct regmap_config s2mps11_regmap_config =3D { - .reg_bits =3D 8, - .val_bits =3D 8, - - .max_register =3D S2MPS11_REG_L38CTRL, - .volatile_reg =3D s2mps11_volatile, - .cache_type =3D REGCACHE_FLAT, -}; - -static const struct regmap_config s2mps13_regmap_config =3D { - .reg_bits =3D 8, - .val_bits =3D 8, - - .max_register =3D S2MPS13_REG_LDODSCH5, - .volatile_reg =3D s2mps11_volatile, - .cache_type =3D REGCACHE_FLAT, -}; - -static const struct regmap_config s2mps14_regmap_config =3D { - .reg_bits =3D 8, - .val_bits =3D 8, - - .max_register =3D S2MPS14_REG_LDODSCH3, - .volatile_reg =3D s2mps11_volatile, - .cache_type =3D REGCACHE_FLAT, -}; - -static const struct regmap_config s2mps15_regmap_config =3D { - .reg_bits =3D 8, - .val_bits =3D 8, - - .max_register =3D S2MPS15_REG_LDODSCH4, - .volatile_reg =3D s2mps11_volatile, - .cache_type =3D REGCACHE_FLAT, -}; - -static const struct regmap_config s2mpu02_regmap_config =3D { - .reg_bits =3D 8, - .val_bits =3D 8, - - .max_register =3D S2MPU02_REG_DVSDATA, - .volatile_reg =3D s2mpu02_volatile, - .cache_type =3D REGCACHE_FLAT, -}; - -static const struct regmap_config s5m8767_regmap_config =3D { - .reg_bits =3D 8, - .val_bits =3D 8, - - .max_register =3D S5M8767_REG_LDO28CTRL, - .volatile_reg =3D s2mps11_volatile, - .cache_type =3D REGCACHE_FLAT, -}; - static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic) { unsigned int val; @@ -268,7 +128,7 @@ static void sec_pmic_configure(struct sec_pmic_dev *sec= _pmic) * platform data. */ static struct sec_platform_data * -sec_pmic_i2c_parse_dt_pdata(struct device *dev) +sec_pmic_parse_dt_pdata(struct device *dev) { struct sec_platform_data *pd; =20 @@ -283,68 +143,34 @@ sec_pmic_i2c_parse_dt_pdata(struct device *dev) return pd; } =20 -static int sec_pmic_probe(struct i2c_client *i2c) +int sec_pmic_probe(struct device *dev, unsigned long device_type, + unsigned int irq, struct regmap *regmap, + struct i2c_client *client) { - const struct regmap_config *regmap; struct sec_platform_data *pdata; const struct mfd_cell *sec_devs; struct sec_pmic_dev *sec_pmic; int ret, num_sec_devs; =20 - sec_pmic =3D devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev), - GFP_KERNEL); + sec_pmic =3D devm_kzalloc(dev, sizeof(struct sec_pmic_dev), GFP_KERNEL); if (sec_pmic =3D=3D NULL) return -ENOMEM; =20 - i2c_set_clientdata(i2c, sec_pmic); - sec_pmic->dev =3D &i2c->dev; - sec_pmic->i2c =3D i2c; - sec_pmic->irq =3D i2c->irq; + dev_set_drvdata(dev, sec_pmic); + sec_pmic->dev =3D dev; + sec_pmic->device_type =3D device_type; + sec_pmic->i2c =3D client; + sec_pmic->irq =3D irq; + sec_pmic->regmap_pmic =3D regmap; =20 - pdata =3D sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev); + pdata =3D sec_pmic_parse_dt_pdata(sec_pmic->dev); if (IS_ERR(pdata)) { ret =3D PTR_ERR(pdata); return ret; } =20 - sec_pmic->device_type =3D (unsigned long)of_device_get_match_data(sec_pmi= c->dev); sec_pmic->pdata =3D pdata; =20 - switch (sec_pmic->device_type) { - case S2MPA01: - regmap =3D &s2mpa01_regmap_config; - break; - case S2MPS11X: - regmap =3D &s2mps11_regmap_config; - break; - case S2MPS13X: - regmap =3D &s2mps13_regmap_config; - break; - case S2MPS14X: - regmap =3D &s2mps14_regmap_config; - break; - case S2MPS15X: - regmap =3D &s2mps15_regmap_config; - break; - case S5M8767X: - regmap =3D &s5m8767_regmap_config; - break; - case S2MPU02: - regmap =3D &s2mpu02_regmap_config; - break; - default: - regmap =3D &sec_regmap_config; - break; - } - - sec_pmic->regmap_pmic =3D devm_regmap_init_i2c(i2c, regmap); - if (IS_ERR(sec_pmic->regmap_pmic)) { - ret =3D PTR_ERR(sec_pmic->regmap_pmic); - dev_err(&i2c->dev, "Failed to allocate register map: %d\n", - ret); - return ret; - } - sec_irq_init(sec_pmic); =20 pm_runtime_set_active(sec_pmic->dev); @@ -387,9 +213,9 @@ static int sec_pmic_probe(struct i2c_client *i2c) num_sec_devs =3D ARRAY_SIZE(s2mpu05_devs); break; default: - dev_err(&i2c->dev, "Unsupported device type (%lu)\n", + dev_err(sec_pmic->dev, "Unsupported device type %lu\n", sec_pmic->device_type); - return -ENODEV; + return -EINVAL; } ret =3D devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, NULL, 0, NULL); @@ -401,10 +227,11 @@ static int sec_pmic_probe(struct i2c_client *i2c) =20 return ret; } +EXPORT_SYMBOL_GPL(sec_pmic_probe); =20 -static void sec_pmic_shutdown(struct i2c_client *i2c) +void sec_pmic_shutdown(struct device *dev) { - struct sec_pmic_dev *sec_pmic =3D i2c_get_clientdata(i2c); + struct sec_pmic_dev *sec_pmic =3D dev_get_drvdata(dev); unsigned int reg, mask; =20 if (!sec_pmic->pdata->manual_poweroff) @@ -428,11 +255,11 @@ static void sec_pmic_shutdown(struct i2c_client *i2c) =20 regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0); } +EXPORT_SYMBOL_GPL(sec_pmic_shutdown); =20 static int sec_pmic_suspend(struct device *dev) { - struct i2c_client *i2c =3D to_i2c_client(dev); - struct sec_pmic_dev *sec_pmic =3D i2c_get_clientdata(i2c); + struct sec_pmic_dev *sec_pmic =3D dev_get_drvdata(dev); =20 if (device_may_wakeup(dev)) enable_irq_wake(sec_pmic->irq); @@ -452,8 +279,7 @@ static int sec_pmic_suspend(struct device *dev) =20 static int sec_pmic_resume(struct device *dev) { - struct i2c_client *i2c =3D to_i2c_client(dev); - struct sec_pmic_dev *sec_pmic =3D i2c_get_clientdata(i2c); + struct sec_pmic_dev *sec_pmic =3D dev_get_drvdata(dev); =20 if (device_may_wakeup(dev)) disable_irq_wake(sec_pmic->irq); @@ -462,20 +288,9 @@ static int sec_pmic_resume(struct device *dev) return 0; } =20 -static DEFINE_SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, - sec_pmic_suspend, sec_pmic_resume); - -static struct i2c_driver sec_pmic_driver =3D { - .driver =3D { - .name =3D "sec_pmic", - .pm =3D pm_sleep_ptr(&sec_pmic_pm_ops), - .of_match_table =3D sec_dt_match, - }, - .probe =3D sec_pmic_probe, - .shutdown =3D sec_pmic_shutdown, -}; -module_i2c_driver(sec_pmic_driver); +DEFINE_SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resum= e); +EXPORT_SYMBOL_GPL(sec_pmic_pm_ops); =20 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); -MODULE_DESCRIPTION("Core support for the S5M MFD"); +MODULE_DESCRIPTION("Core driver for the Samsung S5M"); MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/sec-core.h b/drivers/mfd/sec-core.h index b3fded5f02a0ddc09a9508fd49a5d335f7ad0ee7..a0a3488924d96f69373e7569079= cfefd0544ca26 100644 --- a/drivers/mfd/sec-core.h +++ b/drivers/mfd/sec-core.h @@ -10,6 +10,15 @@ #ifndef __SEC_CORE_INT_H #define __SEC_CORE_INT_H =20 +struct i2c_client; + +extern const struct dev_pm_ops sec_pmic_pm_ops; + +int sec_pmic_probe(struct device *dev, unsigned long device_type, + unsigned int irq, struct regmap *regmap, + struct i2c_client *client); +void sec_pmic_shutdown(struct device *dev); + int sec_irq_init(struct sec_pmic_dev *sec_pmic); =20 #endif /* __SEC_CORE_INT_H */ diff --git a/drivers/mfd/sec-i2c.c b/drivers/mfd/sec-i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..8e3a365ff3e5533e27d94fa8a15= dbfa639518a5f --- /dev/null +++ b/drivers/mfd/sec-i2c.c @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * http://www.samsung.com + * Copyright 2025 Linaro Ltd. + * + * Samsung SxM I2C driver + */ + +#include <linux/dev_printk.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/mfd/samsung/core.h> +#include <linux/mfd/samsung/s2mpa01.h> +#include <linux/mfd/samsung/s2mps11.h> +#include <linux/mfd/samsung/s2mps13.h> +#include <linux/mfd/samsung/s2mps14.h> +#include <linux/mfd/samsung/s2mps15.h> +#include <linux/mfd/samsung/s2mpu02.h> +#include <linux/mfd/samsung/s5m8767.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/pm.h> +#include <linux/regmap.h> +#include "sec-core.h" + +static bool s2mpa01_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case S2MPA01_REG_INT1M: + case S2MPA01_REG_INT2M: + case S2MPA01_REG_INT3M: + return false; + default: + return true; + } +} + +static bool s2mps11_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case S2MPS11_REG_INT1M: + case S2MPS11_REG_INT2M: + case S2MPS11_REG_INT3M: + return false; + default: + return true; + } +} + +static bool s2mpu02_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case S2MPU02_REG_INT1M: + case S2MPU02_REG_INT2M: + case S2MPU02_REG_INT3M: + return false; + default: + return true; + } +} + +static const struct regmap_config sec_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, +}; + +static const struct regmap_config s2mpa01_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + + .max_register =3D S2MPA01_REG_LDO_OVCB4, + .volatile_reg =3D s2mpa01_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + +static const struct regmap_config s2mps11_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + + .max_register =3D S2MPS11_REG_L38CTRL, + .volatile_reg =3D s2mps11_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + +static const struct regmap_config s2mps13_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + + .max_register =3D S2MPS13_REG_LDODSCH5, + .volatile_reg =3D s2mps11_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + +static const struct regmap_config s2mps14_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + + .max_register =3D S2MPS14_REG_LDODSCH3, + .volatile_reg =3D s2mps11_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + +static const struct regmap_config s2mps15_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + + .max_register =3D S2MPS15_REG_LDODSCH4, + .volatile_reg =3D s2mps11_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + +static const struct regmap_config s2mpu02_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + + .max_register =3D S2MPU02_REG_DVSDATA, + .volatile_reg =3D s2mpu02_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + +static const struct regmap_config s5m8767_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + + .max_register =3D S5M8767_REG_LDO28CTRL, + .volatile_reg =3D s2mps11_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + +static int sec_pmic_i2c_probe(struct i2c_client *client) +{ + const struct regmap_config *regmap; + unsigned long device_type; + struct regmap *regmap_pmic; + int ret; + + device_type =3D (unsigned long)of_device_get_match_data(&client->dev); + + switch (device_type) { + case S2MPA01: + regmap =3D &s2mpa01_regmap_config; + break; + case S2MPS11X: + regmap =3D &s2mps11_regmap_config; + break; + case S2MPS13X: + regmap =3D &s2mps13_regmap_config; + break; + case S2MPS14X: + regmap =3D &s2mps14_regmap_config; + break; + case S2MPS15X: + regmap =3D &s2mps15_regmap_config; + break; + case S5M8767X: + regmap =3D &s5m8767_regmap_config; + break; + case S2MPU02: + regmap =3D &s2mpu02_regmap_config; + break; + default: + regmap =3D &sec_regmap_config; + break; + } + + regmap_pmic =3D devm_regmap_init_i2c(client, regmap); + if (IS_ERR(regmap_pmic)) { + ret =3D PTR_ERR(regmap_pmic); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + return sec_pmic_probe(&client->dev, device_type, client->irq, + regmap_pmic, client); +} + +static void sec_pmic_i2c_shutdown(struct i2c_client *i2c) +{ + sec_pmic_shutdown(&i2c->dev); +} + +static const struct of_device_id sec_pmic_i2c_of_match[] =3D { + { + .compatible =3D "samsung,s5m8767-pmic", + .data =3D (void *)S5M8767X, + }, { + .compatible =3D "samsung,s2dos05", + .data =3D (void *)S2DOS05, + }, { + .compatible =3D "samsung,s2mps11-pmic", + .data =3D (void *)S2MPS11X, + }, { + .compatible =3D "samsung,s2mps13-pmic", + .data =3D (void *)S2MPS13X, + }, { + .compatible =3D "samsung,s2mps14-pmic", + .data =3D (void *)S2MPS14X, + }, { + .compatible =3D "samsung,s2mps15-pmic", + .data =3D (void *)S2MPS15X, + }, { + .compatible =3D "samsung,s2mpa01-pmic", + .data =3D (void *)S2MPA01, + }, { + .compatible =3D "samsung,s2mpu02-pmic", + .data =3D (void *)S2MPU02, + }, { + .compatible =3D "samsung,s2mpu05-pmic", + .data =3D (void *)S2MPU05, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, sec_pmic_i2c_of_match); + +static struct i2c_driver sec_pmic_i2c_driver =3D { + .driver =3D { + .name =3D "sec-pmic-i2c", + .pm =3D pm_sleep_ptr(&sec_pmic_pm_ops), + .of_match_table =3D sec_pmic_i2c_of_match, + }, + .probe =3D sec_pmic_i2c_probe, + .shutdown =3D sec_pmic_i2c_shutdown, +}; +module_i2c_driver(sec_pmic_i2c_driver); + +MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); +MODULE_DESCRIPTION("I2C driver for the Samsung S5M"); +MODULE_LICENSE("GPL"); --=20 2.49.0.604.gff1f9ca942-goog