From nobody Thu Oct 2 01:01:38 2025 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 CDD9A154423; Thu, 25 Sep 2025 12:37:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803878; cv=none; b=uZ77GsrPocjK2oQZE3vvnNm7Ky7dBekP2I1bofOQBJSuMPPPkttByDN01Fs4YuU4oyfwDRdoBB23URXoBiARQUjzwhvTxq+c+0i2++JRbYxyy5utow1kR64Gcqu4N5TE5RI8N3+/iVQOy+rk06QHuDcL5oyKdPBiUGgRuWQzAd8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803878; c=relaxed/simple; bh=ARaI6sAn1ScO5elgBBI9/4QuQ8iaswhaC7shsZDwj/8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Hqrzj85OL5MMxSlzrR3v3wguZAN924e64y0uyaEFmjeg1nFlaauzBwHlziYpjV6j8as6UpZ41PYIY7FbJY1VlFnsuyh2X2EQ0lsY5nVQzYNIctGMvHQwvQcusnsCe1z6P7G4foi7kSnsu6vWpJZI4yfp69ZIHSLAXVTL4fOv1iw= 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=cOJTMFFC; arc=none smtp.client-ip=185.171.202.116 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="cOJTMFFC" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id BDD93C011F6; Thu, 25 Sep 2025 12:37:36 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0DE2D6062C; Thu, 25 Sep 2025 12:37:54 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 077E8102F189D; Thu, 25 Sep 2025 14:37:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1758803873; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=ezJpNoVstQDrmQSBUVTTKViwRkcKwZkbTFCSfYyOfLo=; b=cOJTMFFCKWKEFQmNFlW3MfN9N5SRo2gPqNd2lCAGbQeabZgTxz1w+7IUHFksTHnoVn7Ryy 77bpakGtGVZS3mzxBlZnamf8eFsxVDDBUm+5dpnqeiGwk4UJMOTYDXLBGhxQot3npcPDrh ZdmWMBfxk8FaKHdKcwzjn8G/uJQt8Jm8pPMeqFxfcSvo6YlQgS087Tv2gD05MsNoOXt4LP 7QQRcWKd5w9uRuKonJxmCpL+lzXGSIWvkSEhk/SaNLPh8oMC+c+ISnCppsDE0uvLMksYja 61wpxgyQzci6SSjg2bCwlQbU1CXHGfFYCn9gJgGxAMNViCMPW872T9EAh8JM8g== From: Romain Gantois Date: Thu, 25 Sep 2025 14:37:33 +0200 Subject: [PATCH v2 1/5] regulator: dt-bindings: Add Linear Technology LTM8054 regulator 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: <20250925-ltm8054-driver-v2-1-bb61a401a0dc@bootlin.com> References: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> In-Reply-To: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko Cc: Hans de Goede , Thomas Petazzoni , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-iio@vger.kernel.org, Romain Gantois X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 The Linear Technology LTM8054 is a Buck-Boost voltage regulator with an input range of 5V to 36V and an output range of 1.2V to 36V. The LTM8054's output voltage level is typically set using a voltage divider between the Vout and FB pins, the FB pin being constantly regulated to 1.2V. The output current limit of the LTM8054 may be statically set by placing a sense resistor on a dedicated pin. This limit can then be lowered by controlling the voltage level on the CTL pin. Describe the LTM8054 voltage regulator. Signed-off-by: Romain Gantois --- .../devicetree/bindings/regulator/adi,ltm8054.yaml | 73 ++++++++++++++++++= ++++ MAINTAINERS | 5 ++ 2 files changed, 78 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml b= /Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8ca8fc4e80b5722f58b4cbe9de2= 2c16d4fd91670 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/adi,ltm8054.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices LTM8054 buck-boost regulator + +maintainers: + - Romain Gantois + +description: + This regulator operates over an input voltage range of 5V to 36V, and can + output from 1.2V to 36V. The output voltage level is typically set with a + voltage divider between the Vout pin and the FB pin which is internally + regulated to 1.2V. + + The output current of the LTM8054 can be limited by tying the Iout pin t= o a + current sense resistor. This limit can be further lowered by applying a + voltage below 1.2V to the CTL pin. + +allOf: + - $ref: /schemas/regulator/regulator.yaml# + +properties: + compatible: + const: adi,ltm8054 + + enable-gpios: + description: GPIO connected to the RUN pin. + maxItems: 1 + + lltc,fb-voltage-divider: + description: + An array of two integers containing the resistor values + R1 and R2 of the feedback voltage divider in Ohms. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 2 + + adi,iout-rsense-micro-ohms: + description: + Value of the output current sense resistor, in micro Ohms. + + io-channels: + items: + - description: DAC controlling the voltage level of the CTL pin. + + io-channel-names: + items: + - const: ctl + +required: + - compatible + - lltc,fb-voltage-divider + +additionalProperties: false + +examples: + - | + #include + regulator { + compatible =3D "adi,ltm8054"; + + enable-gpios =3D <&gpio0 1 GPIO_ACTIVE_HIGH>; + + lltc,fb-voltage-divider =3D <1000000 68000>; + + adi,iout-rsense-micro-ohms =3D <20000>; + + io-channels =3D <&dac 1>; + io-channel-names =3D "ctl"; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 3763f9fc9e4ed62bc8b273756a25f9c921570bee..69bcba82808bb815af436232fab= 50f70713fd533 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14534,6 +14534,11 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt F: drivers/i2c/muxes/i2c-mux-ltc4306.c =20 +LTM8054 REGULATOR DRIVER +M: Romain Gantois +S: Maintained +F: Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml + LTP (Linux Test Project) M: Andrea Cervesato M: Cyril Hrubis --=20 2.51.0 From nobody Thu Oct 2 01:01:38 2025 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (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 25FFB16F288 for ; Thu, 25 Sep 2025 12:37:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803879; cv=none; b=LE+E5HkGaMswFNE30rcJdRzTPbO9NvD5qD6ELUnfutydKCwEgyvsVZHBW0BN5apRcF7IKAYCh34ygVVIq4v/ryHHJPTaPX2X3ASEqNtdrcwbYcBCy1HqnRPUfQBF7lXMHzOAXcaLPBBcVqjCVSRUxawr7VG7kAaji/z+m8mElHs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803879; c=relaxed/simple; bh=nq8yvrCq4BHSVH81mDwXPtdNyjSh2WWWKD7668zP+PM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TC531ifUUE86atME0mKJgY8xAkzwYpuK8iDF5l/sv6xEt5Xu+oMe0qlk30GrDd06KOlRpD00OfGKFAXRoyQXSYSevdJ0AWSF/wVawjEzE9+kQxR9bkkuX92Kzh8j6iQlY8+3QKFn9E3jTG0B0YYDLYDlcHGTXkiLR0j298CizGY= 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=ki/0x7oT; arc=none smtp.client-ip=185.246.84.56 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="ki/0x7oT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id AC7F61A0FCD; Thu, 25 Sep 2025 12:37:55 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 823096062C; Thu, 25 Sep 2025 12:37:55 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 97A1C102F1895; Thu, 25 Sep 2025 14:37:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1758803874; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=30C/Rm/y1QtLYOy3aNA1T8D9WKuvuDfHijiy4zbDhrA=; b=ki/0x7oT+OUAv0qV4C8vI3Wa5SToC8StIAusWr/Wsd9DNtJ1yZ1xipi2wMbZFEq01Uus29 QjVFay6ujMqP8Z4SOoFdIMdixvei+n74bX3/eCU7B4r+j5wCOrZiGSI3oNHyXAu0U1ZE3X 8G01lP5WbDPZw93RSE3FgTAVUc2uZKXl8Hu+w79/hP5YKfYVpfZ2Cn/BxFIhrIQFisQzEG D8DuG/LdQQCPO5dnQZxjEKYEc54KkCz7CsXJHt/z10cAp4St4se88MXS6eKuj5ia+DfrDu h6e6YIdEGmnkEPMuq6O+u3YjVg3J+NevWJsIMpFj8kuaFW9SbWOnVj5v+KGxoA== From: Romain Gantois Date: Thu, 25 Sep 2025 14:37:34 +0200 Subject: [PATCH v2 2/5] iio: add processed write API 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: <20250925-ltm8054-driver-v2-2-bb61a401a0dc@bootlin.com> References: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> In-Reply-To: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko Cc: Hans de Goede , Thomas Petazzoni , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-iio@vger.kernel.org, Romain Gantois X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 Add a function to allow IIO consumers to write a processed value to a channel. Signed-off-by: Romain Gantois --- drivers/iio/inkern.c | 120 +++++++++++++++++++++++++++++++++++++++= ++++ include/linux/iio/consumer.h | 36 +++++++++++++ 2 files changed, 156 insertions(+) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 2a1ecef2b82007f5ee8e8d0f8b35846bc4d2f94a..a6ec724b7c1fb197e6261c1162f= 8315deda20fd7 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -631,6 +631,57 @@ int iio_multiply_value(int *result, s64 multiplier, } EXPORT_SYMBOL_GPL(iio_multiply_value); =20 +int iio_divide_by_value(int *result, s64 numerator, + unsigned int type, int val, int val2) +{ + s64 tmp_num, tmp_den; + + switch (type) { + case IIO_VAL_INT: + tmp_num =3D numerator; + tmp_den =3D val; + break; + case IIO_VAL_INT_PLUS_MICRO: + case IIO_VAL_INT_PLUS_NANO: + switch (type) { + case IIO_VAL_INT_PLUS_MICRO: + tmp_num =3D MICRO; + tmp_den =3D MICRO; + break; + + case IIO_VAL_INT_PLUS_NANO: + tmp_num =3D NANO; + tmp_den =3D NANO; + break; + } + + tmp_num *=3D (s64)numerator; + tmp_den =3D (s64)abs(val) * tmp_den + (s64)abs(val2); + + if (val < 0 || val2 < 0) + tmp_num *=3D -1; + + break; + case IIO_VAL_FRACTIONAL: + tmp_num =3D (s64)numerator * (s64)val2; + tmp_den =3D val; + break; + case IIO_VAL_FRACTIONAL_LOG2: + tmp_num =3D (s64)numerator << val2; + tmp_den =3D val; + break; + default: + return -EINVAL; + } + + if (!tmp_den) + return -ERANGE; + + *result =3D div64_s64(tmp_num, tmp_den); + + return IIO_VAL_INT; +} + static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, int raw, int *processed, unsigned int scale) @@ -699,6 +750,53 @@ int iio_convert_raw_to_processed(struct iio_channel *c= han, int raw, } EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed); =20 +static int iio_convert_processed_to_raw_unlocked(struct iio_channel *chan, + int processed, int *raw, + unsigned int scale) +{ + int scale_type, scale_val, scale_val2; + int offset_type, offset_val, offset_val2; + int ret; + + scale_type =3D iio_channel_read(chan, &scale_val, &scale_val2, + IIO_CHAN_INFO_SCALE); + if (scale_type >=3D 0) { + ret =3D iio_divide_by_value(raw, processed, scale_type, scale_val, scale= _val2); + if (ret < 0) + return ret; + } else { + *raw =3D processed; + } + + if (!scale) + return -ERANGE; + + *raw =3D div_s64(*raw, scale); + + offset_type =3D iio_channel_read(chan, &offset_val, &offset_val2, + IIO_CHAN_INFO_OFFSET); + if (offset_type >=3D 0) { + switch (offset_type) { + case IIO_VAL_INT: + case IIO_VAL_INT_PLUS_MICRO: + case IIO_VAL_INT_PLUS_NANO: + break; + case IIO_VAL_FRACTIONAL: + offset_val /=3D offset_val2; + break; + case IIO_VAL_FRACTIONAL_LOG2: + offset_val >>=3D offset_val2; + break; + default: + return -EINVAL; + } + + *raw -=3D offset_val; + } + + return 0; +} + int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *va= l2, enum iio_chan_info_enum attribute) { @@ -1035,3 +1133,25 @@ ssize_t iio_read_channel_label(struct iio_channel *c= han, char *buf) return do_iio_read_channel_label(chan->indio_dev, chan->channel, buf); } EXPORT_SYMBOL_GPL(iio_read_channel_label); + +int iio_write_channel_processed_scale(struct iio_channel *chan, int val, + unsigned int scale) +{ + struct iio_dev_opaque *iio_dev_opaque =3D to_iio_dev_opaque(chan->indio_d= ev); + int ret, processed; + + scoped_guard(mutex, &iio_dev_opaque->info_exist_lock) { + if (!chan->indio_dev->info) + return -ENODEV; + + ret =3D iio_convert_processed_to_raw_unlocked(chan, val, &processed, sca= le); + if (ret) + return ret; + + ret =3D iio_channel_write(chan, processed, 0, IIO_CHAN_INFO_RAW); + } + + return ret; +} +EXPORT_SYMBOL_GPL(iio_write_channel_processed_scale); + diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index c8c6261c81f934480e16854412e269207be60adc..dc84b8b4c61911d1a58427f1a9c= 798cae3954ac1 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -399,6 +399,24 @@ int iio_read_channel_scale(struct iio_channel *chan, i= nt *val, int iio_multiply_value(int *result, s64 multiplier, unsigned int type, int val, int val2); =20 +/** + * iio_divide_by_value() - Divide by an IIO value + * @result: Destination pointer for the division result + * @numerator: Numerator. + * @type: One of the IIO_VAL_* constants. This decides how the @val + * and @val2 parameters are interpreted. + * @val: Denominator. + * @val2: Denominator. @val2 use depends on type. + * + * Divide an s64 number by an IIO value, storing the result as + * IIO_VAL_INT. This is typically used for scaling. + * + * Returns: + * IIO_VAL_INT on success or a negative error-number on failure. + */ +int iio_divide_by_value(int *result, s64 numerator, + unsigned int type, int val, int val2); + /** * iio_convert_raw_to_processed() - Converts a raw value to a processed va= lue * @chan: The channel being queried @@ -469,4 +487,22 @@ ssize_t iio_write_channel_ext_info(struct iio_channel = *chan, const char *attr, */ ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf); =20 +/** + * iio_write_channel_processed_scale() - scale and write processed value t= o a given channel + * @chan: The channel being queried. + * @val: Value to write. + * @scale: Scale factor to apply during the conversion + * + * This function writes a processed value to a channel. A processed value = means + * that this value will have the correct unit and not some device internal + * representation. If the device does not support writing a processed valu= e, the + * function will query the channel's scale and offset and write an appropr= iately + * transformed raw value. + * + * Return: an error code or 0. + * + */ +int iio_write_channel_processed_scale(struct iio_channel *chan, int val, + unsigned int scale); + #endif --=20 2.51.0 From nobody Thu Oct 2 01:01:38 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 D89FF1C84D0 for ; Thu, 25 Sep 2025 12:37:58 +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=1758803880; cv=none; b=MkLvAWwZ2QbSYWvkSkzT8ZuAe26eO8vGo+lUHzQSmw/trxHAqy/YA2VKyWw3Orqv23hN6KYniK1J3yJiaIgbCKwW+v4zXZKkbwGU9gMvRzGMxeKkFr5c50eRhXE/3TN/T6mmSxX7qPtRCLqwu024to/Uky69wqq8jdjqH7kN0hA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803880; c=relaxed/simple; bh=AcCFw4xOZWaL2Vloup40NocEpyxl3c95QlY3hp+pNs8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jWk0THsuuFtzKNkxPrNLT8WEV9Qr0VUQrDXxx13lpJUnk//eMDQxAzVYZ0CS/mOv1fuN3ABysQl2+XK7x3d7vY07Z0haEgWYQc+e9fe/zcfWwb9URQR5jJezHK8Wv2Dy8hnKZ78037ehjHRIM0l8vT6K75BIHqMibSBHKQg3cbM= 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=vC9Ze1R9; 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="vC9Ze1R9" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 466D84E40DD7; Thu, 25 Sep 2025 12:37:57 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 1A8B16062C; Thu, 25 Sep 2025 12:37:57 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F2D41102F17E6; Thu, 25 Sep 2025 14:37:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1758803876; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=k7o/HfxDrKJe5p4M+ISv4mlYo5xYjk8Am9y+75H1iHk=; b=vC9Ze1R9g34l4uP2D5GiUidy255ekno2l8GpyvFwTuMOaRT91EAPmhn/ddt9NlcdKlC0cZ 17mpk31MrdrBgroVzwUr2oXgPC4MO7YRQy4z1nqdYwwD4h+z60v5RBhmqJNsvQ4cEOr3FY XfTZolyXqB1MnEHn9ercWjR3NNwg5GeqU/xuEVkKK+X1UP2demaO/Nu4G9JrdDVyYRUNcx 6k7mRF/odhAn8cQFPC9pPtwDXbUsjk/xC1dssvmNVuDoMp5wQ9qtQUU0B1r/pI42fmOe0M UzDBubfC2TynA2xinRd+l5VscGc7RC4QnT5EILJ5NkyoT1B8FPIEoCL8GKnAkA== From: Romain Gantois Date: Thu, 25 Sep 2025 14:37:35 +0200 Subject: [PATCH v2 3/5] Add kunit tests for iio_divide_by_value() 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: <20250925-ltm8054-driver-v2-3-bb61a401a0dc@bootlin.com> References: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> In-Reply-To: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko Cc: Hans de Goede , Thomas Petazzoni , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-iio@vger.kernel.org, Romain Gantois X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 Add kunit tests for iio_divide_by_value(), these are similar to the existing tests for iio_multiply_value(), but the operand values used differ slightly. Signed-off-by: Romain Gantois --- drivers/iio/test/Kconfig | 12 +++ drivers/iio/test/Makefile | 1 + drivers/iio/test/iio-test-divide.c | 212 +++++++++++++++++++++++++++++++++= ++++ 3 files changed, 225 insertions(+) diff --git a/drivers/iio/test/Kconfig b/drivers/iio/test/Kconfig index 6e65e929791ca247df9ac993fddbb4da557d5dfa..3aa1fc78966cf72554e069db75d= e1c6eff532850 100644 --- a/drivers/iio/test/Kconfig +++ b/drivers/iio/test/Kconfig @@ -4,6 +4,18 @@ # =20 # Keep in alphabetical order +config IIO_DIVIDE_KUNIT_TEST + tristate "Test IIO division functions" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + build unit tests for the IIO division functions. + + For more information on KUnit and unit tests in general, please refer + to the KUnit documentation in Documentation/dev-tools/kunit/. + + If unsure, say N. + config IIO_GTS_KUNIT_TEST tristate "Test IIO gain-time-scale helpers" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/drivers/iio/test/Makefile b/drivers/iio/test/Makefile index 0c846bc21acda5a487b3a6977a8e9feaef20159a..16344eedc46a5ebb4d57468b3e5= 49d8f65b85432 100644 --- a/drivers/iio/test/Makefile +++ b/drivers/iio/test/Makefile @@ -5,6 +5,7 @@ =20 # Keep in alphabetical order obj-$(CONFIG_IIO_RESCALE_KUNIT_TEST) +=3D iio-test-rescale.o +obj-$(CONFIG_IIO_DIVIDE_KUNIT_TEST) +=3D iio-test-divide.o obj-$(CONFIG_IIO_FORMAT_KUNIT_TEST) +=3D iio-test-format.o obj-$(CONFIG_IIO_GTS_KUNIT_TEST) +=3D iio-test-gts.o obj-$(CONFIG_IIO_MULTIPLY_KUNIT_TEST) +=3D iio-test-multiply.o diff --git a/drivers/iio/test/iio-test-divide.c b/drivers/iio/test/iio-test= -divide.c new file mode 100644 index 0000000000000000000000000000000000000000..dd4f53bf7223750e2ac583b6e23= 92abb42fb045b --- /dev/null +++ b/drivers/iio/test/iio-test-divide.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Unit tests for IIO division functions + * + * Copyright (c) 2025 Bootlin + * Based on iio-test-multiply.c which is: + * Copyright (c) 2025 Hans de Goede + * Based on iio-test-format.c which is: + * Copyright (c) 2020 Lars-Peter Clausen + */ + +#include +#include + +static void __iio_test_iio_divide_by_integer(struct kunit *test, s64 numer= ator) +{ + int ret, result, val; + + val =3D 42; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT, val, 0); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator, val)); + + val =3D -23; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT, val, 0); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator, val)); + + val =3D 0; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT, val, 0); + KUNIT_EXPECT_EQ(test, ret, -ERANGE); +} + +static void iio_test_iio_divide_by_integer(struct kunit *test) +{ + __iio_test_iio_divide_by_integer(test, 2000); + __iio_test_iio_divide_by_integer(test, -2000); +} + +static void __iio_test_iio_divide_by_fixedpoint(struct kunit *test, s64 nu= merator) +{ + int ret, result, val, val2; + + /* positive >=3D 1 (1.5) */ + val =3D 1; + val2 =3D 500000; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, v= al, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * 10, 15)); + + val =3D 1; + val2 =3D 500000000; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, va= l, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * 10, 15)); + + /* positive < 1 (0.5) */ + val =3D 0; + val2 =3D 500000; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, v= al, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * 10, 5)); + + val =3D 0; + val2 =3D 500000000; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, va= l, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * 10, 5)); + + /* negative <=3D -1 (-1.5) */ + val =3D -1; + val2 =3D 500000; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, v= al, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * -10, 15)); + + val =3D -1; + val2 =3D 500000000; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, va= l, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * -10, 15)); + + /* negative > -1 (-0.5) */ + val =3D 0; + val2 =3D -500000; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, v= al, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * -10, 5)); + + val =3D 0; + val2 =3D -500000000; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, va= l, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * -10, 5)); + + /* Zero */ + val =3D 0; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, = val, 0); + KUNIT_EXPECT_EQ(test, ret, -ERANGE); +} + +static void iio_test_iio_divide_by_fixedpoint(struct kunit *test) +{ + __iio_test_iio_divide_by_fixedpoint(test, 2000); + __iio_test_iio_divide_by_fixedpoint(test, -2000); +} + +static void __iio_test_iio_divide_by_fractional(struct kunit *test, s64 nu= merator) +{ + int ret, result, val, val2; + + /* positive < 1 (1/10)*/ + val =3D 1; + val2 =3D 10; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, = val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * val2, val)); + + /* positive >=3D 1 (100/3)*/ + val =3D 100; + val2 =3D 3; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, = val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * val2, val)); + + /* negative > -1 (-1/10) */ + val =3D -1; + val2 =3D 10; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, = val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * val2, val)); + + /* negative <=3D -1 (-200/3)*/ + val =3D -200; + val2 =3D 3; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, = val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64(numerator * val2, val)); + + /* Zero */ + val =3D 0; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, = 0); + KUNIT_EXPECT_EQ(test, ret, -ERANGE); +} + +static void iio_test_iio_divide_by_fractional(struct kunit *test) +{ + __iio_test_iio_divide_by_fractional(test, 2000); + __iio_test_iio_divide_by_fractional(test, -2000); +} + +static void __iio_test_iio_divide_by_fractional_log2(struct kunit *test, s= 64 numerator) +{ + int ret, result, val, val2; + + /* positive < 1 (123/1024) */ + val =3D 123; + val2 =3D 10; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, = val, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64((numerator << val2), val)); + + /* positive >=3D 1 (1234567/1024) */ + val =3D 1234567; + val2 =3D 10; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, = val, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64((numerator << val2), val)); + + /* negative > -1 (-123/1024) */ + val =3D -123; + val2 =3D 10; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, = val, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64((numerator << val2), val)); + + /* negative <=3D -1 (-1234567/1024) */ + val =3D -1234567; + val2 =3D 10; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, = val, val2); + KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); + KUNIT_EXPECT_EQ(test, result, div_s64((numerator << val2), val)); + + /* Zero */ + val =3D 0; + ret =3D iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, = val, 0); + KUNIT_EXPECT_EQ(test, ret, -ERANGE); +} + +static void iio_test_iio_divide_by_fractional_log2(struct kunit *test) +{ + __iio_test_iio_divide_by_fractional_log2(test, 2000); + __iio_test_iio_divide_by_fractional_log2(test, -2000); +} + +static struct kunit_case iio_divide_test_cases[] =3D { + KUNIT_CASE(iio_test_iio_divide_by_integer), + KUNIT_CASE(iio_test_iio_divide_by_fixedpoint), + KUNIT_CASE(iio_test_iio_divide_by_fractional), + KUNIT_CASE(iio_test_iio_divide_by_fractional_log2), + { } +}; + +static struct kunit_suite iio_divide_test_suite =3D { + .name =3D "iio-divide", + .test_cases =3D iio_divide_test_cases, +}; + +kunit_test_suite(iio_divide_test_suite); + +MODULE_AUTHOR("Romain Gantois "); +MODULE_DESCRIPTION("Test IIO division functions"); +MODULE_LICENSE("GPL"); --=20 2.51.0 From nobody Thu Oct 2 01:01:38 2025 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (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 95F5126058D; Thu, 25 Sep 2025 12:38:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803882; cv=none; b=MVjTljv6KAL4twJVHT6JAZsjz8+EHdMYSzCAvjIMUjoAwowzcb59quegtRwpLgA5iFuXHDKTXO5IXNJoaeoY/G6P5IaX6OCo2KYfRAj3Wv7xPZUAlUkk82hTI/y/5zP5pe3TIWGWXmmAFtQ6Dhy636PONs7kjPVm5yCfQgUi/Vo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803882; c=relaxed/simple; bh=ww5ZuNFiVaKq48nt0LtjEQM7n2gmuZ7VXoE0sIeFjJY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=umxYNCJnFezcyT+YRVLdzc7sS6HpfF8glB90g5XQ+CBdR+ez8aTx4FM4FLq/0OyqcjgybBFTVH9SezPp+rcnGuZrMXoAvGwmnaYAMuvqjdROWf0+vNsuRtsQ3MfducmSowCj3bSy0gT1RvrCnP9vLgC1/FNDm/NGp5QAyUj2BsM= 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=kk5xQ80b; arc=none smtp.client-ip=185.246.84.56 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="kk5xQ80b" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 0F2F81A0FCC; Thu, 25 Sep 2025 12:37:59 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D9F716062C; Thu, 25 Sep 2025 12:37:58 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 96311102F189D; Thu, 25 Sep 2025 14:37:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1758803877; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=zzaArUK40mxLPZyXfgdMYo6ReXlBpF/NnUC2885MlQY=; b=kk5xQ80b4hbjGDwHEzMDeS1rItinFDUJ9E0pbTOZmuWmwqaQI5rO8yNpGaQKRT6Fw1tRbN YtKoy4YUmaN6x2OSdRh2J+n3nsPK8s+5ZEZzuYGPEa21fijeK3OwF9UujvWPe2UAO+RxK6 68WjvE5/ONWQD0husG8XEWBnEYOCY/RukZLCKdj2wF9iJ4tXRDOyjyrzHk9BL7Exk71ScW 803+brgpA1uX3jvpQEU2z08HhvIHNc16VEvuEd6APWpKJme+rrogi9FM50l7n4DUo840mp MnWr14Q0tatcfqgqlRqEaYhYg8snihjdSjjykepx7EA+4/Daj4j5ZiCNuIDFGQ== From: Romain Gantois Date: Thu, 25 Sep 2025 14:37:36 +0200 Subject: [PATCH v2 4/5] regulator: Support the LTM8054 voltage regulator 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: <20250925-ltm8054-driver-v2-4-bb61a401a0dc@bootlin.com> References: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> In-Reply-To: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko Cc: Hans de Goede , Thomas Petazzoni , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-iio@vger.kernel.org, Romain Gantois X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 Add a stub driver for the Linear Technology LTM8054 Buck-Boost voltage regulator. This version only supports enabling/disabling the regulator via a GPIO, and reporting the output voltage level from the resistor divider values given in the device tree. Signed-off-by: Romain Gantois --- MAINTAINERS | 1 + drivers/regulator/Kconfig | 8 +++ drivers/regulator/Makefile | 1 + drivers/regulator/ltm8054-regulator.c | 126 ++++++++++++++++++++++++++++++= ++++ 4 files changed, 136 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 69bcba82808bb815af436232fab50f70713fd533..310dac4f60ab1e6e82e4dd66748= 2f46723964992 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14538,6 +14538,7 @@ LTM8054 REGULATOR DRIVER M: Romain Gantois S: Maintained F: Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml +F: drivers/regulator/ltm8054-regulator.c =20 LTP (Linux Test Project) M: Andrea Cervesato diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index e252bb11ae6615dc9154908bc237905b97e739e5..c48b2af350974b3715a1ecf05de= c656a92268294 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -577,6 +577,14 @@ config REGULATOR_LTC3676 This enables support for the LTC3676 8-output regulators controlled via I2C. =20 +config REGULATOR_LTM8054 + tristate "LTM8054 Buck-Boost voltage regulator" + help + This driver provides support for the Analog Devices LTM8054 + Buck-Boost micromodule regulator. The LTM8054 has an adjustable + output current limitation and a feedback pin for setting the + output voltage level. + config REGULATOR_MAX14577 tristate "Maxim 14577/77836 regulator" depends on MFD_MAX14577 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 76b02d12b758c607028d2c8879017afc6d1b244e..afcc9ffcc72f268a9e999a185e3= 024d67261249a 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_REGULATOR_LP8788) +=3D lp8788-ldo.o obj-$(CONFIG_REGULATOR_LP8755) +=3D lp8755.o obj-$(CONFIG_REGULATOR_LTC3589) +=3D ltc3589.o obj-$(CONFIG_REGULATOR_LTC3676) +=3D ltc3676.o +obj-$(CONFIG_REGULATOR_LTM8054) +=3D ltm8054-regulator.o obj-$(CONFIG_REGULATOR_MAX14577) +=3D max14577-regulator.o obj-$(CONFIG_REGULATOR_MAX1586) +=3D max1586.o obj-$(CONFIG_REGULATOR_MAX5970) +=3D max5970-regulator.o diff --git a/drivers/regulator/ltm8054-regulator.c b/drivers/regulator/ltm8= 054-regulator.c new file mode 100644 index 0000000000000000000000000000000000000000..bc8cf98b5a3b5663481d148330d= e70a8165e5981 --- /dev/null +++ b/drivers/regulator/ltm8054-regulator.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Analog Devices LTM8054 Buck-Boost regulator driver + * + * Copyright (C) 2025 Bootlin + */ + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* The LTM8054 regulates its FB pin to 1.2V */ +#define LTM8054_FB_uV 1200000 + +struct ltm8054_priv { + struct regulator_desc rdesc; +}; + +static int ltm8054_scale(unsigned int uV, u32 r1, u32 r2) +{ + u64 tmp; + + tmp =3D (u64)uV * r1; + do_div(tmp, r2); + + return uV + tmp; +} + +static const struct regulator_ops ltm8054_regulator_ops =3D { }; + +static int ltm8054_of_parse(struct device *dev, struct ltm8054_priv *priv, + struct regulator_config *config) +{ + struct device_node *np =3D dev->of_node; + u32 r[2]; + int ret; + + config->of_node =3D np; + + ret =3D device_property_read_u32_array(dev, "lltc,fb-voltage-divider", r,= ARRAY_SIZE(r)); + if (ret) + return ret; + + priv->rdesc.fixed_uV =3D ltm8054_scale(LTM8054_FB_uV, r[0], r[1]); + priv->rdesc.min_uV =3D priv->rdesc.fixed_uV; + priv->rdesc.n_voltages =3D 1; + + config->init_data =3D of_get_regulator_init_data(dev, + np, + &priv->rdesc); + if (!config->init_data) + return -EINVAL; + + config->ena_gpiod =3D devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LO= W); + if (IS_ERR(config->ena_gpiod)) + return PTR_ERR(config->ena_gpiod); + + return 0; +} + +static int ltm8054_probe(struct platform_device *pdev) +{ + struct regulator_config config =3D { }; + struct device *dev =3D &pdev->dev; + struct regulator_dev *rdev; + struct ltm8054_priv *priv; + int ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->rdesc.name =3D "ltm8054-regulator", + priv->rdesc.ops =3D <m8054_regulator_ops, + priv->rdesc.type =3D REGULATOR_VOLTAGE, + priv->rdesc.owner =3D THIS_MODULE, + + config.dev =3D dev; + config.driver_data =3D priv; + + ret =3D ltm8054_of_parse(dev, priv, &config); + if (ret) + return dev_err_probe(dev, ret, "failed to parse device tree\n"); + + rdev =3D devm_regulator_register(dev, &priv->rdesc, &config); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), "failed to register regulator\n= "); + + return 0; +} + +static const struct of_device_id ltm8054_of_match[] =3D { + { .compatible =3D "adi,ltm8054" }, + {} +}; +MODULE_DEVICE_TABLE(of, ltm8054_of_match); + +static struct platform_driver ltm8054_driver =3D { + .probe =3D ltm8054_probe, + .driver =3D { + .name =3D "ltm8054", + .of_match_table =3D ltm8054_of_match, + }, +}; +module_platform_driver(ltm8054_driver); + +MODULE_DESCRIPTION("LTM8054 regulator driver"); +MODULE_AUTHOR("Romain Gantois "); +MODULE_LICENSE("GPL"); --=20 2.51.0 From nobody Thu Oct 2 01:01:38 2025 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 AC44B26E6FE for ; Thu, 25 Sep 2025 12:38:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803883; cv=none; b=GKgw1TNZmULgMF2zD5ACINWbwkNRtqBY+H4yyeXXDaVOwvSp8vYqfB0FQeZmyzWpLNGq2uLwF6Zf33ycTbWdaPpdwhfKdtfBa2cXvL3XkxglElOlYBGbirSOgtqIJq2GP6T1dOmn34jxZPNx4QPQoDm+/OZG7g6fhhMXSYIkchk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758803883; c=relaxed/simple; bh=cE6dqP10Uu7Ap+7dTimu+BxM1SJYWWd/P7RXknWJ/Ao=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=m6TACExJWfReQk+uaeVyZjK6jKRmDlpyg7ei0K3wOL3K6eAEhgYy1Db99EJdSZlASV7y8lhWbNOoCX+Fti7lQCRsohfW9BdURiFMvS9UeyENcyTp4FDlH+Ey7vqVFE3+R0itkZWWH9kMUYpDsPB0bf3LnN2GhC0i4pH9hvhKPOo= 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=tajFAysD; arc=none smtp.client-ip=185.171.202.116 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="tajFAysD" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id F202DC011FA; Thu, 25 Sep 2025 12:37:42 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 40B526062C; Thu, 25 Sep 2025 12:38:00 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 46B97102F1895; Thu, 25 Sep 2025 14:37:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1758803879; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=DBmZYj9uOOiozLigWRqEkHlxIev9s38O1X01yQhnqPo=; b=tajFAysDfCgDA/mszBL8ZF2V0D7e+a1m4dYYsSJ1FVpFIiZbTMRPD9+VyCUyXTho5VrMem LumFryZdWz7lrpm2VFAG8tE55IjuHF8YyWtMEtyY8FAGmOOu9nzotDfu0bRTtQp59sVzTj /7aPegnI9Xel32kRu6XXtDIPRaj8tOL+H/eVk8sV75xzY/pBCpnn0yUmFF2aD1IwMffyKV 7pVhjSOcTbrINdxYLgs8jsW45ghqUHqLYD1fg8rvFo0+m1FmREtFfua1YGW6QWOpukaObw AEXBv0k5gUk76QV7cCh9t7aGBEZwo1ki6zj971hi4BzFVkjuDjiezK1qPTP2vQ== From: Romain Gantois Date: Thu, 25 Sep 2025 14:37:37 +0200 Subject: [PATCH v2 5/5] regulator: ltm8054: Support output current limit control 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: <20250925-ltm8054-driver-v2-5-bb61a401a0dc@bootlin.com> References: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> In-Reply-To: <20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko Cc: Hans de Goede , Thomas Petazzoni , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-iio@vger.kernel.org, Romain Gantois X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 The LTM8054 supports setting a fixed output current limit using a sense resistor connected to a dedicated pin. This limit can then be lowered dynamically by varying the voltage level of the CTL pin. Support controlling the LTM8054's output current limit. Signed-off-by: Romain Gantois --- drivers/regulator/Kconfig | 1 + drivers/regulator/ltm8054-regulator.c | 113 ++++++++++++++++++++++++++++++= +++- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c48b2af350974b3715a1ecf05dec656a92268294..e9ee6ed9fe3587c542223a6d6be= 78412e96797ee 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -579,6 +579,7 @@ config REGULATOR_LTC3676 =20 config REGULATOR_LTM8054 tristate "LTM8054 Buck-Boost voltage regulator" + depends on IIO help This driver provides support for the Analog Devices LTM8054 Buck-Boost micromodule regulator. The LTM8054 has an adjustable diff --git a/drivers/regulator/ltm8054-regulator.c b/drivers/regulator/ltm8= 054-regulator.c index bc8cf98b5a3b5663481d148330de70a8165e5981..172ec32c5a9517c6fb38ded8095= ffc8e1acf55f0 100644 --- a/drivers/regulator/ltm8054-regulator.c +++ b/drivers/regulator/ltm8054-regulator.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -26,10 +28,25 @@ #include #include =20 +#include + /* The LTM8054 regulates its FB pin to 1.2V */ #define LTM8054_FB_uV 1200000 =20 +/* Threshold voltage between the Vout and Iout pins which triggers current + * limiting. + */ +#define LTM8054_VOUT_IOUT_MAX_uV 58000 + +#define LTM8054_MAX_CTL_uV 1200000 +#define LTM8054_MIN_CTL_uV 50000 + struct ltm8054_priv { + struct iio_channel *ctl_dac; + + int min_uA; + int max_uA; + struct regulator_desc rdesc; }; =20 @@ -43,18 +60,103 @@ static int ltm8054_scale(unsigned int uV, u32 r1, u32 = r2) return uV + tmp; } =20 -static const struct regulator_ops ltm8054_regulator_ops =3D { }; +static int ltm8054_set_current_limit(struct regulator_dev *rdev, int min_u= A, int max_uA) +{ + struct ltm8054_priv *priv =3D rdev_get_drvdata(rdev); + u64 vdac_uV; + + min_uA =3D clamp_t(int, min_uA, priv->min_uA, priv->max_uA); + + /* adjusted current limit =3D Rsense current limit * CTL pin voltage / ma= x CTL pin voltage */ + vdac_uV =3D (u64)min_uA * LTM8054_MAX_CTL_uV; + do_div(vdac_uV, priv->max_uA); + + dev_dbg(&rdev->dev, + "Setting current limit to %duA, CTL pin to %duV\n", min_uA, (int)vdac_uV= ); + + /* Standard IIO voltage unit is mV, scale accordingly. */ + return iio_write_channel_processed_scale(priv->ctl_dac, vdac_uV, 1000); +} + +static int ltm8054_get_current_limit(struct regulator_dev *rdev) +{ + struct ltm8054_priv *priv =3D rdev_get_drvdata(rdev); + int ret, vdac_uv; + u64 uA; + + ret =3D iio_read_channel_processed_scale(priv->ctl_dac, &vdac_uv, 1000); + if (ret < 0) { + dev_err(&rdev->dev, "failed to read CTL DAC voltage, err %d\n", ret); + return ret; + } + + uA =3D (u64)vdac_uv * priv->max_uA; + do_div(uA, LTM8054_MAX_CTL_uV); + + return uA; +} + +static const struct regulator_ops ltm8054_regulator_ops =3D { + .set_current_limit =3D ltm8054_set_current_limit, + .get_current_limit =3D ltm8054_get_current_limit, +}; + +static int ltm8054_init_ctl_dac(struct platform_device *pdev, struct ltm80= 54_priv *priv) +{ + struct iio_channel *ctl_dac; + enum iio_chan_type type; + int ret; + + ctl_dac =3D devm_iio_channel_get(&pdev->dev, "ctl"); + if (IS_ERR(ctl_dac)) + return PTR_ERR(ctl_dac); + + ret =3D iio_get_channel_type(ctl_dac, &type); + if (ret) + return ret; + + if (type !=3D IIO_VOLTAGE) + return -EINVAL; + + priv->ctl_dac =3D ctl_dac; + + return 0; +} =20 static int ltm8054_of_parse(struct device *dev, struct ltm8054_priv *priv, struct regulator_config *config) { struct device_node *np =3D dev->of_node; + u32 rsense; u32 r[2]; + u64 tmp; int ret; =20 config->of_node =3D np; =20 - ret =3D device_property_read_u32_array(dev, "lltc,fb-voltage-divider", r,= ARRAY_SIZE(r)); + ret =3D device_property_read_u32(dev, "adi,iout-rsense-micro-ohms", &rsen= se); + if (ret) + return ret; + + if (rsense =3D=3D 0) + return -EINVAL; + + /* The maximum output current limit is the one set by the Rsense resistor= */ + tmp =3D (u64)LTM8054_VOUT_IOUT_MAX_uV * MICRO; + do_div(tmp, rsense); + priv->max_uA =3D tmp; + + /* + * Applying a voltage below LTM8054_MAX_CTL_uV on the CTL pin reduces + * the output current limit. If this level drops below + * LTM8054_MIN_CTL_uV the regulator stops switching. + */ + + tmp =3D (u64)priv->max_uA * LTM8054_MIN_CTL_uV; + do_div(tmp, LTM8054_MAX_CTL_uV); + priv->min_uA =3D tmp; + + ret =3D device_property_read_u32_array(dev, "lltc,fb-voltage-divider", r,= 2); if (ret) return ret; =20 @@ -62,6 +164,9 @@ static int ltm8054_of_parse(struct device *dev, struct l= tm8054_priv *priv, priv->rdesc.min_uV =3D priv->rdesc.fixed_uV; priv->rdesc.n_voltages =3D 1; =20 + dev_dbg(dev, "max_uA: %d min_uA: %d fixed_uV: %d\n", + priv->max_uA, priv->min_uA, priv->rdesc.fixed_uV); + config->init_data =3D of_get_regulator_init_data(dev, np, &priv->rdesc); @@ -99,6 +204,10 @@ static int ltm8054_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "failed to parse device tree\n"); =20 + ret =3D ltm8054_init_ctl_dac(pdev, priv); + if (ret) + return dev_err_probe(dev, ret, "failed to initialize CTL DAC\n"); + rdev =3D devm_regulator_register(dev, &priv->rdesc, &config); if (IS_ERR(rdev)) return dev_err_probe(dev, PTR_ERR(rdev), "failed to register regulator\n= "); --=20 2.51.0