From patchwork Wed Dec 18 23:36:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien Parent X-Patchwork-Id: 851769 Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (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 EFBEA1FD78C; Wed, 18 Dec 2024 23:37:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565042; cv=none; b=XfXKVEzYpfAmiXuSxVnBojUd0OOi0gYhCjfhME0i3zdVtfJ01NxqDvG85BFIWEJEzioQK3BzSh/U1vJ7rTsKBvdPOcf0aYPPWSsDdG7yUbpZDpNQojGl9pWw4aMC5ILQj2JOx5wMShUXqwiMQKK/oY0sR8eQV0StVqc8qwavlHM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565042; c=relaxed/simple; bh=4SE9setPSSrH0hJjJY1xCu9tx2HYa/TBhF8z5FVIs4g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=q8sC7ocsogEHQ0o7Jz9kSi0vjPb6XeKj+aNKDkhlCBUEC3tAzJgflGeTdLst18oez23Nl0zByt+5R+Ct59Xi1T3iqhPGRZrs6Cuxs6ua+AMCVk6KfSaHXz9VhC3pzs9j1LoS9101o9c0FHPi8kE4zXup83rkuQ6EawKZYPZpGSg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=b4es2Ivx; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="b4es2Ivx" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-21654fdd5daso1958805ad.1; Wed, 18 Dec 2024 15:37:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734565039; x=1735169839; 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=UhAzgwSjNox/FIb+hLHlHMNNI9yeP1VLZ/ht4Xnzx9w=; b=b4es2Ivx440lTh6viRB9LN5BYyxzNn55qYZowsx6aFWnjagV4qKvrwqBh9UkKIH7Sy LI3NG61EhxWMxbzPeBKEGqOyy0jhUT2dZmxlQrZhxv3YtkDlFUjDDEJU2WDk6fLosDMV tmzO7njsMRSUwbLQ7yiyuy3AdZXl3HK/mRHpr1ihMDIEyuyWfA6khYXJ6jb57F8g8ROE l8wMzYnq7hKdAgPL3rPcuOxUy4G6o2Y2wi1zvsvFyKLfYr/9ZwDEyEXGZrqtih9o796W 93/6o9MC2tAFW8opb8klHeLuq14oteCmRNzDcgQDBToJbAprKtIRBuPqUuRLtM6l+Jzx 7R2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734565039; x=1735169839; 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=UhAzgwSjNox/FIb+hLHlHMNNI9yeP1VLZ/ht4Xnzx9w=; b=K4H0pzWnvI/aGwSASqsn5TC+IwJ8GTjJ+FD6TGk0fZRMROelEdx0Bu6fcTihavjRuV V64OxIDEzvsck+xmTUkeA00NA5acAVA0zwgJ7apAeqjzvN2gZqk+HAMjgthCMkdXC/eg fIQJpUiXNzbpIXWGlSTtnV6409U0vKuopTao45WSLQwaUmCBbS4R5DCS5Z8TYD2QKdEs xZUNQlc0S0KclK83p2Nbac5wPoOODtxjEKehk+WDUWj+XqATRmQNManMWm7zq4ThNpqz sJsH7nS1539sKhqlo/v4ApDOp5yAwi4RND6HoOKwJYeBK4DmyABdkzZc/np1ArvzMyyp g8ww== X-Forwarded-Encrypted: i=1; AJvYcCUFlKmqjaToa95W6uLYp2mD1cgENnVZOCDjRufS+VRrgm7fRC8nidX8vabYjlVbG64hHuS3qODB9BGk@vger.kernel.org, AJvYcCWVwhcqW7QwmgtQST7GT8rcQ+wkGV6vy+F9buB17XkZqzRB0shc8R6VzwDp8e6zYIA6RZLMk479sbur57le@vger.kernel.org, AJvYcCWnrtplwpG8FZiNZ/WTuziE+Brd3O7W6/KVe44a1yGZ36Auy4lFQM6Qqy5EHGhEP7rTaIg2yZ9QSamviEgl@vger.kernel.org, AJvYcCXHUAm7KmTsM5H7Gvh12Jr/0KJk3XxJxwhlM1ZM/CG1+Dh86sTu9HrUWZe3HbHkuhqfVinBhymULPMi+KdLWAo=@vger.kernel.org X-Gm-Message-State: AOJu0YyVnUYUmb/nwrLtfrAj76ZR8f9WSnjWu2SCY/XRr8bFo2/crtHf DV6LdIfYE6xQO+Eu50i/BBOkNEfxCQVAM3R0i5UUrJgsPoj3yy+a X-Gm-Gg: ASbGncvwhtRtHg/zmbj3HOhOLbf7m9PkrRhPv+Kt4MMbE9v4873uRcAsfjf7SwECm10 3gPVKC4JZY6bPSk+nG48yTrLt/lEasI6CiDf9B51vgO5V+GNLEdBuHRI6dWM5M3NYf7IUe0nPSa a0Hya5ywlVGHtklFti11UqnwYCLJHVpxu6p49RFCVTahJxOcW8+9hVZYJjlp5OdchmWm2w4pdmO bdsn2NqPaMRDa4IWNeoltS+99oxBJjEl1Nc/YeG0wV3ANbhF/lqExkL X-Google-Smtp-Source: AGHT+IG25MGGi4G1Umt/pBxrQoT0UKWAYNG0VN2GMrkgQXxU0hwxukqEiX52e1fIsrdjr9zWG8xfmg== X-Received: by 2002:a17:902:ec81:b0:216:5568:38c9 with SMTP id d9443c01a7336-218d72349edmr71021735ad.31.1734565039076; Wed, 18 Dec 2024 15:37:19 -0800 (PST) Received: from [127.0.1.1] ([2001:569:fcea:600:2e06:283e:5daa:4d0f]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-219dc9f6967sm802335ad.214.2024.12.18.15.37.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2024 15:37:18 -0800 (PST) From: Fabien Parent Date: Wed, 18 Dec 2024 15:36:31 -0800 Subject: [PATCH 1/9] rust: i2c: add basic I2C client abstraction Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241218-ncv6336-v1-1-b8d973747f7a@gmail.com> References: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> In-Reply-To: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> To: Rob Herring , Saravana Kannan , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Greg Kroah-Hartman , "Rafael J. Wysocki" , Wolfram Sang , Mark Brown , Liam Girdwood , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Fabien Parent Cc: devicetree@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org, linux-arm-msm@vger.kernel.org, vinod.koul@linaro.org, Fabien Parent , Fiona Behrens X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=13005; i=parent.f@gmail.com; h=from:subject:message-id; bh=kd7a0C90uxuWTBjnlJWT2Q5dPINXmEd9sR6MvOUkVYg=; b=LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgpvd0o0bkFGdEFwTDlrQTBEQUFvQmlKc2d4Q kw5cktRQnl5WmlBR2RqWEtMNE1RVFdRTFpsRGxBdVl0WHJwNFVPCjFvc1d6OTYvZUZFOVByUXNZ Z1NYWjRrQ013UUFBUW9BSFJZaEJONk0wZElMeXpzd3JmRnNxWWliSU1RUy9heWsKQlFKblkxeWl BQW9KRUlpYklNUVMvYXlrOFNZUC9SQzVQZGIvdktiZ2RaOXBoY2pvQWMzWElFemFzTm1SMHVmMA orRE5FQlQ2YmhISzFyQVM2NStoTU5ET1g4VlZVTFBBejNjQTVjWGJmSm1uVGtoelgzaEt6Z1pUS TNocjdrUXgwCmxXU3JpU1J1QnUzYVZCN2pJS3FlanhKU3JCNytUZStWeC9NbDNaYWNsWHJkZzFD NnNRc3lWSWRkbjNPd3hTVEEKenZERmxxZDN5d3FaR25ocXZkLy9iL3ZXdzlYcEJ3cXF3ZnJLL0R MdDRDQnZxeTB6eDhsYk9SYUNCa3pxVHUrMAp1cGkzRmUvQ2FIbXBUNXpjOFpMN3pZalNtRzU5WH p2c2g2RndRcklVT0N6eTcvUVZqMDhaNXpEMVZRdzhsYWRZCmw0YStacENWR3V2Smtld1hMVkJOa EV3U0MvbDFuOW9SUFhyVFVYUmlNWlNPcDZyV01hZ3NXdmhyem1aUk1GakcKU2NySkNUdEhZWTNL OFhnZmt3WlhZS1preVFkS2ZRUjV1Z3lxcjVDbnhNRWwzbisvZVlIMTFPQWhGU1BhY2lDNgpjNVJ RQWI2MGNUeHcvTCtKUjM4ckE4UnZiM2JHY25JTnRMRkZyUHZWYy9PN2ZJYnNoSS8rZHdFMGt0Nj ZoMCsvCmk3YjVMR01BM3ZIcGR0VUNmRDJyZDZxd0VOelJoODdMdERRWDNDcXpkeHJ5SG1FYnhhZ E52OTZaVVBhTWtuZnMKMEhjZzZmRERtYU9ycU5ZWnVhcDBxcWJ0VWlaM00vQ29OOGRqd0VPemho NDhBRjBUcUJjbUc5UU4ybUhRUE1TLwpVaW94UWEvbUZscDM0N1lKUWRqRzZNTVB6YUV5TGZrUFJ NbTJjN0o1bUUrZDNhbmxacllyQXdTNFl4QUFrMVNJCk5meVpWaHUvT0NBMytnPT0KPWpHVUMKLS 0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo= X-Developer-Key: i=parent.f@gmail.com; a=openpgp; fpr=07BB034F9E8E3AF0DF4CF7607AE864A1E16FA383 From: Fiona Behrens Implement an abstraction to write I2C device drivers. The abstraction is pretty basic and provides just the infrastructure to probe a device from I2C/OF device_id and abstract `i2c_client`. The client will be used by the Regmap abstraction to perform I/O on the I2C bus. Signed-off-by: Fiona Behrens Co-developed-by: Fabien Parent Signed-off-by: Fabien Parent --- MAINTAINERS | 1 + rust/bindings/bindings_helper.h | 1 + rust/helpers/helpers.c | 1 + rust/helpers/i2c.c | 13 ++ rust/kernel/i2c.rs | 288 ++++++++++++++++++++++++++++++++++++++++ rust/kernel/lib.rs | 2 + 6 files changed, 306 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6b9e10551392c185b9314c9f94edeaf6e85af58f..961fe4ed39605bf489d1d9e473f47bccb692ff14 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10796,6 +10796,7 @@ F: include/linux/i2c-smbus.h F: include/linux/i2c.h F: include/uapi/linux/i2c-*.h F: include/uapi/linux/i2c.h +F: rust/kernel/i2c.rs I2C SUBSYSTEM HOST DRIVERS M: Andi Shyti diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index e9fdceb568b8f94e602ee498323e5768a40a6cba..a882efb90bfc27960ef1fd5f2dc8cc40533a1c27 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 0640b7e115be1553549312dcfdf842bcae3bde1b..630e903f516ee14a51f46ff0bcc68e8f9a64021a 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -15,6 +15,7 @@ #include "device.c" #include "err.c" #include "fs.c" +#include "i2c.c" #include "io.c" #include "jump_label.c" #include "kunit.c" diff --git a/rust/helpers/i2c.c b/rust/helpers/i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..8ffdc454e7597cc61909da5b3597057aeb5f7299 --- /dev/null +++ b/rust/helpers/i2c.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +void *rust_helper_i2c_get_clientdata(const struct i2c_client *client) +{ + return i2c_get_clientdata(client); +} + +void rust_helper_i2c_set_clientdata(struct i2c_client *client, void *data) +{ + i2c_set_clientdata(client, data); +} diff --git a/rust/kernel/i2c.rs b/rust/kernel/i2c.rs new file mode 100644 index 0000000000000000000000000000000000000000..efa03335e5b59e72738380e94213976b2464c25b --- /dev/null +++ b/rust/kernel/i2c.rs @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Abstractions for the I2C bus. +//! +//! C header: [`include/linux/i2c.h`](srctree/include/linux/i2c.h) + +use crate::{ + bindings, container_of, + device::Device, + device_id::{self, RawDeviceId}, + driver, + error::{to_result, Result}, + of, + prelude::*, + str::CStr, + types::{ARef, ForeignOwnable, Opaque}, + ThisModule, +}; + +/// Abstraction for `bindings::i2c_device_id`. +#[repr(transparent)] +#[derive(Clone, Copy)] +pub struct DeviceId(bindings::i2c_device_id); + +impl DeviceId { + /// Create a new device id from an I2C name. + pub const fn new(name: &CStr) -> Self { + let src = name.as_bytes_with_nul(); + // TODO: Replace with `bindings::i2c_device_id::default()` once stabilized for `const`. + // SAFETY: FFI type is valid to be zero-initialized. + let mut i2c: bindings::i2c_device_id = unsafe { core::mem::zeroed() }; + + let mut i = 0; + while i < src.len() { + i2c.name[i] = src[i] as _; + i += 1; + } + + Self(i2c) + } +} + +// SAFETY: +// * `DeviceId` is a `#[repr(transparent)` wrapper of `i2c_device_id` and does not add +// additional invariants, so it's safe to transmute to `RawType`. +// * `DRIVER_DATA_OFFSET` is the offset to the `data` field. +unsafe impl RawDeviceId for DeviceId { + type RawType = bindings::i2c_device_id; + + const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::i2c_device_id, driver_data); + + fn index(&self) -> usize { + self.0.driver_data as _ + } +} + +/// I2C [`DeviceId`] table. +pub type IdTable = &'static dyn device_id::IdTable; + +/// An adapter for the registration of I2C drivers. +#[doc(hidden)] +pub struct Adapter(T); + +impl driver::RegistrationOps for Adapter { + type RegType = bindings::i2c_driver; + + fn register( + i2cdrv: &Opaque, + name: &'static CStr, + module: &'static ThisModule, + ) -> Result { + // SAFETY: It's safe to set the fields of `struct i2c_driver` on initialization. + unsafe { + (*i2cdrv.get()).driver.name = name.as_char_ptr(); + (*i2cdrv.get()).probe = Some(Self::probe_callback); + (*i2cdrv.get()).remove = Some(Self::remove_callback); + if let Some(t) = T::I2C_ID_TABLE { + (*i2cdrv.get()).id_table = t.as_ptr(); + } + if let Some(t) = T::OF_ID_TABLE { + (*i2cdrv.get()).driver.of_match_table = t.as_ptr(); + } + } + + // SAFETY: `i2cdrv` is guaranteed to be a valid `RegType`. + to_result(unsafe { bindings::i2c_register_driver(module.0, i2cdrv.get()) }) + } + + fn unregister(i2cdrv: &Opaque) { + // SAFETY: `i2cdrv` is guaranteed to be a valid `RegType`. + unsafe { bindings::i2c_del_driver(i2cdrv.get()) }; + } +} + +impl Adapter { + /// Get the [`Self::IdInfo`] that matched during probe. + fn id_info(client: &mut Client) -> Option<&'static T::IdInfo> { + let id = ::id_info(client.as_ref()); + if id.is_some() { + return id; + } + + // SAFETY: `client` and `client.as_raw()` are guaranteed to be valid. + let id = unsafe { bindings::i2c_client_get_device_id(client.as_raw()) }; + if !id.is_null() { + // SAFETY: `DeviceId` is a `#[repr(transparent)` wrapper of `struct i2c_device_id` and + // does not add additional invariants, so it's safe to transmute. + let id = unsafe { &*id.cast::() }; + return Some(T::I2C_ID_TABLE?.info(id.index())); + } + + None + } + + extern "C" fn probe_callback(client: *mut bindings::i2c_client) -> core::ffi::c_int { + // SAFETY: The i2c bus only ever calls the probe callback with a valid `client`. + let dev = unsafe { Device::get_device(core::ptr::addr_of_mut!((*client).dev)) }; + // SAFETY: `dev` is guaranteed to be embedded in a valid `struct i2c_client` by the + // call above. + let mut client = unsafe { Client::from_dev(dev) }; + + let info = Self::id_info(&mut client); + match T::probe(&mut client, info) { + Ok(data) => { + // Let the `struct i2c_client` own a reference of the driver's private data. + // SAFETY: By the type invariant `client.as_raw` returns a valid pointer to a + // `struct i2c_client`. + unsafe { bindings::i2c_set_clientdata(client.as_raw(), data.into_foreign() as _) }; + } + Err(err) => return Error::to_errno(err), + } + + 0 + } + + extern "C" fn remove_callback(client: *mut bindings::i2c_client) { + // SAFETY: `client` is a valid pointer to a `struct i2c_client`. + let ptr = unsafe { bindings::i2c_get_clientdata(client) }; + + // SAFETY: `remove_callback` is only ever called after a successful call to + // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized + // `KBox` pointer created through `KBox::into_foreign`. + let _ = unsafe { KBox::::from_foreign(ptr) }; + } +} + +impl driver::Adapter for Adapter { + type IdInfo = T::IdInfo; + + fn of_id_table() -> Option> { + T::OF_ID_TABLE + } +} + +/// The I2C driver trait. +/// +/// Drivers must implement this trait in order to get a i2c driver registered. +/// +/// # Example +/// +///``` +/// # use kernel::{bindings, c_str, i2c, of}; +/// # +/// kernel::of_device_table!( +/// OF_ID_TABLE, +/// MODULE_OF_ID_TABLE, +/// ::IdInfo, +/// [(of::DeviceId::new(c_str!("onnn,ncv6336")), ()),] +/// ); +/// +/// kernel::i2c_device_table!( +/// I2C_ID_TABLE, +/// MODULE_I2C_ID_TABLE, +/// ::IdInfo, +/// [(i2c::DeviceId::new(c_str!("ncv6336")), ()),] +/// ); +/// +/// struct MyDriver; +/// +/// impl i2c::Driver for MyDriver { +/// type IdInfo = (); +/// const OF_ID_TABLE: Option> = Some(&OF_ID_TABLE); +/// const I2C_ID_TABLE: Option> = Some(&I2C_ID_TABLE); +/// +/// fn probe(_client: &mut i2c::Client, +/// id_info: Option<&Self::IdInfo>) -> Result>> { +/// Ok(KBox::new(Self, GFP_KERNEL)?.into()) +/// } +/// } +///``` +pub trait Driver { + /// The type holding information about each device id supported by the driver. + // TODO: Use associated_type_defaults once stabilized: + // type IdInfo: 'static = (); + type IdInfo: 'static; + + /// An optional table of I2C device ids supported by the driver. + const I2C_ID_TABLE: Option>; + + /// An optional table of OF device ids supported by the driver. + const OF_ID_TABLE: Option>; + + /// I2C driver probe. + /// + /// Called when a new I2C client is added or discovered. + fn probe(client: &mut Client, id_info: Option<&Self::IdInfo>) -> Result>>; +} + +/// An I2C Client. +/// +/// # Invariants +/// +/// `Client` holds a valid reference of `ARef` whose underlying `struct device` is a +/// member of a `struct i2c_client`. +#[derive(Clone)] +pub struct Client(ARef); + +impl Client { + /// Convert a raw kernel device into a `Client` + /// + /// # Safety + /// + /// `dev` must be an `Aref` whose underlying `bindings::device` is a member of a + /// `bindings::i2c_client`. + unsafe fn from_dev(dev: ARef) -> Self { + Self(dev) + } + + /// Returns the raw `struct i2c_client`. + pub fn as_raw(&self) -> *mut bindings::i2c_client { + // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` + // embedded in `struct i2c_client`. + unsafe { container_of!(self.0.as_raw(), bindings::i2c_client, dev) }.cast_mut() + } +} + +impl AsRef for Client { + fn as_ref(&self) -> &Device { + &self.0 + } +} + +/// Declares a kernel module that exposes a single I2C driver. +/// +/// # Examples +/// +/// ```ignore +/// kernel::module_i2c_driver! { +/// type: MyDriver, +/// name: "Module name", +/// author: "Author name", +/// description: "Description", +/// license: "GPL v2", +/// } +/// ``` +#[macro_export] +macro_rules! module_i2c_driver { + ($($f:tt)*) => { + $crate::module_driver!(, $crate::i2c::Adapter, { $($f)* }); + }; +} + +/// Create an I2C `IdTable` with an "alias" for modpost. +/// +/// # Examples +/// +/// ``` +/// use kernel::{c_str, i2c}; +/// +/// kernel::i2c_device_table!( +/// I2C_ID_TABLE, +/// MODULE_I2C_ID_TABLE, +/// u32, +/// [(i2c::DeviceId::new(c_str!("ncv6336")), 0x6336),] +/// ); +/// ``` +#[macro_export] +macro_rules! i2c_device_table { + ($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => { + const $table_name: $crate::device_id::IdArray< + $crate::i2c::DeviceId, + $id_info_type, + { $table_data.len() }, + > = $crate::device_id::IdArray::new($table_data); + + $crate::module_device_table!("i2c", $module_table_name, $table_name); + }; +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 7fb9858966e8457611d5868783000844ba640db9..71ef7df94302b689be665676a36bd5c2e6effff3 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -48,6 +48,8 @@ #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)] pub mod firmware; pub mod fs; +#[cfg(CONFIG_I2C)] +pub mod i2c; pub mod init; pub mod ioctl; pub mod jump_label; From patchwork Wed Dec 18 23:36:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien Parent X-Patchwork-Id: 851768 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (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 815C41FDE2F; Wed, 18 Dec 2024 23:37:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565046; cv=none; b=tWB73yeTtWMdiYZU+mqCiJ15C0/RwUfkkv5K8M26pV0RAYVbUpZCRIBHD8d8rVI8Uv4Rzlz/BqQi7flwjYy6rtXrwnsxdufGdNXEbCu2cVm7WxHiZ0L7dPgMj2u0dppuP0QW31CQvG11LtFxI8iJXCe7SvIgGz/GBm593IqplOQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565046; c=relaxed/simple; bh=NsdvfP9WuPfbdehzdnnHkfOaZjm7jFfiAr29jiutkkM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CmXAhy2pZX71lBRaAWbu989qeg+JQ7Ys5DaGf8NABfUtkom5jOVXpCi29rRf3IrPvmi4IhV3OxUjRvSr7Pj92tAL2X3LlYtQY8HTOUjALYrO/IdZGRviwf362dmS+JTiAmw/fCdaRDzG6XjIyAhdb1ki9X1/Q2sNax03lAfE5kQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VkHhOFvt; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VkHhOFvt" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-2163b0c09afso2234055ad.0; Wed, 18 Dec 2024 15:37:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734565044; x=1735169844; 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=9P/lUP2PRS4x/+lQSUCJv9QrZZ4hdzqovCNaqVm/erI=; b=VkHhOFvtsIASR5tR5256MvEWgPNb9V4/hNsKZikl7Y4xXm8VXzrk5haEB3NTWgJseI EXDNe1C9xnAGY5KMKj2PJpyPLXhKNHFKVYukC8Hk7snxnLKoEkA6o+1RJK8cOmEkUWm/ l+Pd80iUs1UR69aAeVXEDtywoqlEcjT1JW9xEnIU803FxhG3UY+5xKODQ+NZi47Nf8hQ DNnazpPpnyIx3MWS4Mim2//ZwZlqGojDBqLmweC+uX1FSvq88z/QYQlbqG/sIvuiOkqF 6EImdTcik7KxzJW+/G0LO+tX9fB9Y6Szho8BMV3+6B9ZbMpjZwBmFAcNjF70Yv9TmFsm nEeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734565044; x=1735169844; 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=9P/lUP2PRS4x/+lQSUCJv9QrZZ4hdzqovCNaqVm/erI=; b=NltHkA+c/lDL4+gqlPnwfPSi7LLQZAvVbMk32ZcnCaxFCTb4rKS7uTZFJVMYdaFZQq hK4JwXY70aTkRgZpx3CMWSMAgY1yQGxi6fYZfGljbUvdiqGsIzmJb64sBhhCVPUPhbNh Guib2TaA76WKt4CtNsmcWWz0XxoPSDTF72v+JIcBllJGbY6itZsk9/z/llmMoFZ6ODmB J5jMz5RmaQEFOUpDxeWPMZQPo91jjIzJlSwHUP0aRV/71oes+cxoXYTFF9wFfrfS8JtD vqoEEkWAaofCkCv2rO3udlB3R9mC/uhyODZ8qTPYSQYVh3KUrPkB6FX9Z2pIoqLdEma+ FJUQ== X-Forwarded-Encrypted: i=1; AJvYcCU1uFziu4TbN72kuGtqT2Cgoh0jQykB5Mx2+sSKRvfF9EEJDWHLfTL1VgSJhDkt0jEOTO9SvcHW4t8hNbSN@vger.kernel.org, AJvYcCVCndBonKs6/xq/vH5b5GsML+ycF1Dc2p0ngXt3pAvxCUh9ZXPxlGAQbziBsCgxeIGKmSk0b5Dw7kyj@vger.kernel.org, AJvYcCWhorU7mzRNSRciUe1hEwu2gOMmubYGURHZ69/atJk+0KoogIcgl1Q4ZviPdwjnXuXUfhDPdgphQrQzXwFH@vger.kernel.org, AJvYcCXDlYVmjR12BkKszTCE7ngsxWy/k/uF1mrZ2bWRV7cE9tVIZ0ySpYRF+V+Uh9j6rpwpaDXWQslB6dxOKmobrqg=@vger.kernel.org X-Gm-Message-State: AOJu0Ywdc3UuCXPHxjUdHIGJppsAsvivC0iOVk6LCXoSEiw3lkM/lt5y a2FlRlqx/cLwx+RJHxFepJK+IxlCCip5MFX4qX/+BILAgDw1b5lp X-Gm-Gg: ASbGncs5xnAoUB/TvAQdf7srPB5ky3kVJ6KCRxRPDcwoLQIX1sapoHUWaZY7R9iNpIR 7hClrDsd7oMGZVMmCQBujiaXfq2G/E5sO10aypDfZWq5Tk7V9/zE3S66kwRkiemfxgVCGQxkyEG wB1vNzHcSEWLBTnVplrCFIsvKgRHmc5wu7ijyPmT2+WquVs0eN4QIv2Oqoge//CPDTAxe86ayGv PaQ+Xp0TkvEcOKgs93NdmCitJRgdKP3h8+Fr29b/xRO7apUc7sZkQwq X-Google-Smtp-Source: AGHT+IGfZAqlhj0audMtxGa1Hunn/puU2OflMnZRL01UUIPkYNN49aM+qmpVt7uyRf0pK9RvPlUfGg== X-Received: by 2002:a17:902:cec7:b0:215:781a:9183 with SMTP id d9443c01a7336-218d7269af1mr77074055ad.38.1734565043733; Wed, 18 Dec 2024 15:37:23 -0800 (PST) Received: from [127.0.1.1] ([2001:569:fcea:600:2e06:283e:5daa:4d0f]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-219dc9f6967sm802335ad.214.2024.12.18.15.37.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2024 15:37:22 -0800 (PST) From: Fabien Parent Date: Wed, 18 Dec 2024 15:36:33 -0800 Subject: [PATCH 3/9] rust: error: add declaration for ENOTRECOVERABLE error Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241218-ncv6336-v1-3-b8d973747f7a@gmail.com> References: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> In-Reply-To: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> To: Rob Herring , Saravana Kannan , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Greg Kroah-Hartman , "Rafael J. Wysocki" , Wolfram Sang , Mark Brown , Liam Girdwood , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Fabien Parent Cc: devicetree@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org, linux-arm-msm@vger.kernel.org, vinod.koul@linaro.org, Fabien Parent X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=907; i=parent.f@gmail.com; h=from:subject:message-id; bh=vynuSFjbYPtMJhL+ID8YRu8L0WeE0IXWsYbO1p8vUJg=; b=LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgpvd0o0bkFGdEFwTDlrQTBEQUFvQmlKc2d4Q kw5cktRQnl5WmlBR2RqWEtUaDR0bFM0bm9HUVFtSTFkR0YvZE5UCk1HR0h0bmZoVXFHQ0N2SkQw VmhDdW9rQ013UUFBUW9BSFJZaEJONk0wZElMeXpzd3JmRnNxWWliSU1RUy9heWsKQlFKblkxeWt BQW9KRUlpYklNUVMvYXlrNjdnUUFNWGw5R2xzR2lJRjc0Wm9jbzdldTdsN0hIT0hWbG9ibVpXMg phQ2ZqT2NoYUZLUFo3dHlUSCs2dko4L1NzZnpDRlljZW5wUlBMQzdsNDZhcHdiT24yVFRlbGFwb kE2ZDQvc0hXCm8yK0lvQ01Db0xOa1pzVXFzWndCVlpaS3pwMGpGeGc5aVU1cHQ2N29jL0RzcXpr MDZGR0ErSzQyU3BTNUQ3SlEKbXR4aHlpcCtQc2l5TGJtZ0x5eWw2UUpyYUhxTmxvMGdGUG5tUHB YUmdPVHNub2JtOWlUZ0ZVWU03aE5qYWJocwpjOFV2MVE3RGZHNGU1eGpvaitaQVdrVUdUT0FUdU 1INEloWjVJKzNHeUFIeWh0SDNjYWxZOTU3aG5yN1lva1dDCjJpWTcrMjQzcHhodGttd3M1SGVmV zg5dVNuSkVzNGxFRkc5WDdrWFZMc1dhd3RqeTdxbnNRN0FheUJ3Rm1nWmgKSmU4UitRQkEwaFpX eVREdTZDSmZDYytuVlF1TVpHdE1OdytMZVhlekVLbzRPckRETTA3OTUyOGEwVEFPb0FUTgoycjQ 1cGtOdXpuV3h5RTNpdjNGNnkzWi9IZitqdlJzMVZkMWtuR0pIbEszZHEwZEZUQ3JHb2JOK00xTk FmWHIrCjVySWR2L0xOc2xWbERsQ0dFb3FBeE52QUptZ05DVGQ4SHhmeUkzMFVsbHEzazdJbzZMV 2VHZFA2OGNxbGRQTkUKb3E4UDU4TnNwdjBtWHZSMGlWcUQzdEZ2L1RvclR3Yk1mZTFyN2gxamlX aGNvMFI3OUQ2eEl6WCtsOWtKMHBraQp4WEtkb2R6UmNOL2dFTVFEMkVNR3VUWWNxdkxoMUVqa2V yVkFYY0RkeG9sZjdSZDhxTVNtODdidFIvZS83V1hsCkJJcG5yTks5RWkwNU93PT0KPXFZYnUKLS 0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo= X-Developer-Key: i=parent.f@gmail.com; a=openpgp; fpr=07BB034F9E8E3AF0DF4CF7607AE864A1E16FA383 From: Fabien Parent Add a missing errno for ENOTRECOVERABLE. ENOTRECOVERABLE is returned by get_voltage{_sel} from the Regulator driver API when a voltage cannot be read at bootup and hasn't been set yet. Signed-off-by: Fabien Parent --- rust/kernel/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs index 52c5024324474fc1306047f3fd7516f0023d0313..19c8287032631ee8c4afd3c9c3f1e0709591ba3d 100644 --- a/rust/kernel/error.rs +++ b/rust/kernel/error.rs @@ -82,6 +82,7 @@ macro_rules! declare_err { declare_err!(EIOCBQUEUED, "iocb queued, will get completion event."); declare_err!(ERECALLCONFLICT, "Conflict with recalled state."); declare_err!(ENOGRACE, "NFS file lock reclaim refused."); + declare_err!(ENOTRECOVERABLE, "State not recoverable."); } /// Generic integer kernel error. From patchwork Wed Dec 18 23:36:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien Parent X-Patchwork-Id: 851767 Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (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 0745E1FF1C8; Wed, 18 Dec 2024 23:37:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565051; cv=none; b=mYBgcWVANxgl01Z0EBxH0kGx3XuhuxXK1Ota9HHBwOa4qdO+bTqfqBi7ZarTh8blPBHJch7yUtGSoi1UC7849wJs0uKY1bwbRwTGhuUkKFEMxiP2VZ8q9v7x8e94NTADh1daPTbWFN7rYMsnwRKeCigquuH/Uc78YAl4YViLowQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565051; c=relaxed/simple; bh=JAfbjxBIY8Nq4rIVbaojRV+WEdf2qBL4PSC8ODV2X0Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iyWDTkVxZLR1qm6gxcE8rz0/0JwXlsGCfiTiqxw6Pemp/tTVQpuLZTAEVYWSQjzTyo3ZHqIuKwsqba4Jd/1rzHKz+wdZWU5GJH8JkpIxbSJQq62IVoc5RKWymZ6caD3YPOTAsgFzsmn8Mn7sddhhhox67cA9kFjRV8FW3EWzju8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BO61Cmln; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BO61Cmln" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-216728b1836so2060805ad.0; Wed, 18 Dec 2024 15:37:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734565048; x=1735169848; 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=tl+g5tdx7rxmvzKspLWFkF4LAJ0SjMm1pdSmLUZ7lgI=; b=BO61CmlnCVrdFf00dNyhfET2EfvBXBkwONq3/HPTOAX9fhdaz9L/7xvegtfY/YDDJM nMgtnxnx/4MuOy7talh85Gd42HSsEIkRL8tbuw36pxEX9Lv9J6pQSDm2yeviJo46pQvw aLlVcCuIh2tpLORsjlClRJRc1KxPTyYY5ZIpxrBkJTWPr/23NkBe1ZEbVHOQx1IhxoAZ 9lzjQhtpllWF3RL7xwLF5MjJ7dd5hsE0pGSpf5WxhOWvOurYaRh57+ixH2/EHF6axP65 uy18gq5/C04KbOo4ZkSv1zq5UO9PsqMInbupBDTMe53rsLD2z2DvO8BmxDsVZCnXWGon LzEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734565048; x=1735169848; 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=tl+g5tdx7rxmvzKspLWFkF4LAJ0SjMm1pdSmLUZ7lgI=; b=Y+vcTiNCGrL2ImypUS4z3FKTnPW1asLs9dOBpbP54/aksAADuKi5dLWuh4/aK8VH44 cCNU7Vy/vCkl0vxemEkBds+qmfjCZvAPH7ATCR2isBazPZJX6e8PkVsleKdIsMaPHNOo CYxcENgPhd/Xj8SmOk5USXl79M4akDFdzB5GB5mi4UYhxFh2t/oodYNRA1OcMcyMjMFs EBLI/xrQQd4RkKfJqvoSCXXtzMVkiB0X2AR17mLltafnfEuQHo0vBqGEks/MQMDzWBLu j21ULsu+A9iVaqFP9WC+JtbttZZQmIPq8wlh8WAM2j3g2G7Yr/HYnGm5x+7yNJk0RvWe lh+Q== X-Forwarded-Encrypted: i=1; AJvYcCUvzZg9CD8ATzPNRT0db9cG4IIaxeGpMsDS6zPt48mWmgPvnHMvCKamtrnf12gGSKfPWAu/Hen4PwFi5LAf@vger.kernel.org, AJvYcCVt4nsTetxepY70NqDaUoWFlbwo5ykwhmU8u+RerYYfu6ZhT6LoCeNFA5pK/WZMSCTEomP0dSGHcpVQ@vger.kernel.org, AJvYcCWtveDQ+1+ZDoIy0BLJQ0Qdkr1fRPO1OyZ/pGlUE9U4/tZ6FtusZpsPjd5Q6ClZhgLVQty4TmpyJqP/67MA1rY=@vger.kernel.org, AJvYcCX+UU2m1rtEwhVo5dgrmM0mu7jlPmney6Tb3UE1Y1VBh5NIqM2yg3AscNeR9RIj73jM4Npwx6wc481D0znY@vger.kernel.org X-Gm-Message-State: AOJu0YxULn3sDuG3LSMoK6PsSdaKI2ZtVVSJEFVXOhPleXo/wfXcpJNR N6J7a8m6WfqHIFfpprh6yiNuZmobBC/doPT0czP0TUluExVtqQkZ X-Gm-Gg: ASbGncuBmcZLTsS/KDGgSuhxtvQSH2P4JPmWie6xRiA8CuKGmKxsfE0JOoX6pEaYZ8Y 031KgBZVcL5XUHL8BrLuy1/DVw2TkBH33rwN7bRGBs0BqMgpzyMfiQoGDdjRsL8m3xubE7d8ZB+ 61628eeDVk0shYrA3sr9Pk34A6pRSgnyEGjZhitmQ1b6DdjcOMVI1Wivy1omqQWQhPXiyN2LSnd lo21gMctbfqPjAK35M8OeN8IlsrBPsaSiALCclJzU459jOmzWOxVUi+ X-Google-Smtp-Source: AGHT+IGsgZowloX2sSekJiZwr5HUa7XJGyd9XeMnodxAPqgzxE3diRw7PiA2qjjYWejh/G7dEWQHhw== X-Received: by 2002:a17:902:ce8b:b0:216:6f1a:1c81 with SMTP id d9443c01a7336-218d6fc3a38mr64676395ad.2.1734565047899; Wed, 18 Dec 2024 15:37:27 -0800 (PST) Received: from [127.0.1.1] ([2001:569:fcea:600:2e06:283e:5daa:4d0f]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-219dc9f6967sm802335ad.214.2024.12.18.15.37.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2024 15:37:26 -0800 (PST) From: Fabien Parent Date: Wed, 18 Dec 2024 15:36:35 -0800 Subject: [PATCH 5/9] rust: regulator: add Regulator Driver abstraction Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241218-ncv6336-v1-5-b8d973747f7a@gmail.com> References: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> In-Reply-To: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> To: Rob Herring , Saravana Kannan , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Greg Kroah-Hartman , "Rafael J. Wysocki" , Wolfram Sang , Mark Brown , Liam Girdwood , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Fabien Parent Cc: devicetree@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org, linux-arm-msm@vger.kernel.org, vinod.koul@linaro.org, Fabien Parent X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=31897; i=parent.f@gmail.com; h=from:subject:message-id; bh=OsmHu/e69v+xfLx7ce6mgWFJpVCdUWuT+k1hKoJNLVg=; b=LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgpvd0o0bkFGdEFwTDlrQTBEQUFvQmlKc2d4Q kw5cktRQnl5WmlBR2RqWEtiVEFyUFF4SFdUYkNlTTBPNkVyTG9KCjBtejJLMXV0WXkxWlpuNzlG V09rellrQ013UUFBUW9BSFJZaEJONk0wZElMeXpzd3JmRnNxWWliSU1RUy9heWsKQlFKblkxeW1 BQW9KRUlpYklNUVMvYXlrZGRnUC8zb0lsalZwdEs3TzBwdnRLcEhFd0F2Z2NISXhwd29DeDFYNw pnSzBwbm9MRnQ0RXdhc2lOeHZqa0FoYlgra2x5ZmVQT2VSR095YWdVd3BLMEZHelZVWXBGUXplM HBkL2tGOXF1CmpFeEYxQUxqMFJ1TllLMmtaaXVHbDhTQ240TnlZTGlvYitUM1B4cFRQS1JXWWx3 VlBPMTg1cVJrM29HdDJwTHoKQzNsVU8vcU0ySlU1MVYvT1d4TFN2bTVKUDRIVjcvTUhxeVhwcjl xU3BpZHJDcjVXRjViOXVyZUZyVDZRSlhneAorajRMSVZEWWJBVHlCT0dHR1o5TUpKKzlSNXhrVX ZCVk5leGp4ZThRWUQxR0pqWndCZVFhUklNOXJYUElub25GClcxTDBDc2xrVGR0MlNHOStYL1F6V 1JKeWQ2bEtRWVR1cnBDNFpxWTZURTg4U1R5NHFTOW5QY25Va0oyWW5GaXoKRTNGRVA3aFVsTnVU ZHNzbS9jMEVwUkJRUS9yako2MGZqa1pvMjV4bkp0dHQxSjZWc1JQaDdYK0V4SVlXemVuNwo2elB ZUTFGWDRzM3JIZnZHenJzWlgySkRsVGl2d3lqYm1CSmdDUmZzWS9SWWs5cTk0VTd2NjFPaEwzY2 dzbjZyCnFpRDZTZEd4dFlPTzV5ZkhCL3ZCbUxyaGMyUm9wbTFXL0t3K2tuMnZEdEJ4YUF1VnBoc 09TanpBYzRPNEZxclcKMlNjbFdWOVdpRkQ4bWlGQlh6WUNHMlVQZDhtbFp3Y3pmY3RaUzBvZTFY Njh6Z29UMTY0UEV2bWVtODFTN2h3cwo1NW9WdnFlbFFndlRlMFIxdS9jd3cyZEo5ZGYrRmd3YXB 1UHZ1RXpiRW1mOS9UbTltdVJHVllhdjhScExhQk11CmZzTldQSDFLYjk0dzl3PT0KPW9qWEoKLS 0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo= X-Developer-Key: i=parent.f@gmail.com; a=openpgp; fpr=07BB034F9E8E3AF0DF4CF7607AE864A1E16FA383 From: Fabien Parent This commit adds a Rust abstraction to write Regulator drivers. Only the features used by the NCV6336 driver were added to this abstraction. Signed-off-by: Fabien Parent --- MAINTAINERS | 1 + rust/bindings/bindings_helper.h | 1 + rust/kernel/regulator.rs | 4 +- rust/kernel/regulator/driver.rs | 850 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 855 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 90c231f0aa7381aa8d206fb94c5d1f013dfcae41..87da43251bf0f20d2b5831345778ead592c407dc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25160,6 +25160,7 @@ F: drivers/regulator/ F: include/dt-bindings/regulator/ F: include/linux/regulator/ F: rust/kernel/regulator.rs +F: rust/kernel/regulator/ K: regulator_get_optional VOLTAGE AND CURRENT REGULATOR IRQ HELPERS diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index b18d772bc3a0e78d749cc9e5ae81a4237a57f8c5..124129daea73c143c919d05814fc02bb4460ddfd 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/kernel/regulator.rs b/rust/kernel/regulator.rs index d695ac955193efcfda62770784a92d70d606b93d..bd8202fe5702b944201e76553b9496e1d42cb429 100644 --- a/rust/kernel/regulator.rs +++ b/rust/kernel/regulator.rs @@ -2,12 +2,14 @@ //! SoC Regulators +pub mod driver; + use crate::{ bindings, error::{code::*, Error, Result}, }; -/// Regulators operating modes +/// [`driver::Device`] operating modes #[derive(Copy, Clone)] #[repr(u32)] pub enum Mode { diff --git a/rust/kernel/regulator/driver.rs b/rust/kernel/regulator/driver.rs new file mode 100644 index 0000000000000000000000000000000000000000..8079ea28fd5bf7b6871a0b1d2cea7a6fffcb43ca --- /dev/null +++ b/rust/kernel/regulator/driver.rs @@ -0,0 +1,850 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! SoC Device Driver Interface +//! +//! C header: [`include/linux/regulator/driver.h`](srctree/include/linux/regulator/driver.h) +//! +//! # Examples +//! +//! ``` +//! use kernel::regulator::driver::{Config, Desc, Device, Driver, Type}; +//! +//! static DESC: Desc = +//! Desc::new::(kernel::c_str!("my-regulator-driver"), Type::Voltage); +//! +//! struct MyDeviceDriver; +//! +//! #[vtable] +//! impl Driver for MyDeviceDriver { +//! type Data = (); +//! +//! // Implement supported `Driver`'s operations here. +//! +//! // Example: +//! fn is_enabled(reg: &mut Device) -> Result { +//! Ok(true) +//! } +//! } +//! +//! impl MyDeviceDriver { +//! fn probe(dev: &mut kernel::device::Device) { +//! let _ = Device::register(dev, &DESC, Config::<::Data>::new(dev, ())); +//! } +//! } +//! ``` + +use crate::{ + device, + error::{code::*, from_err_ptr, from_result, Error, Result}, + macros::vtable, + regulator::Mode, + str::CStr, + types::ForeignOwnable, + ThisModule, +}; +use core::{marker::PhantomData, mem::ManuallyDrop, ptr::NonNull}; + +/// [`Device`]'s status +#[derive(Eq, PartialEq)] +pub enum Status { + /// Device is off + Off, + /// Device is on + On, + /// Device is in an error state + Error, + /// Device is on and in Fast mode + Fast, + /// Device is on and in Normal mode + Normal, + /// Device is on and in Idle mode + Idle, + /// Device is on and in Standby mode + Standby, + /// Device is enabled but not regulating + Bypass, + /// Device is any other status + Undefined, +} + +impl TryFrom for Status { + type Error = Error; + + fn try_from(status: core::ffi::c_uint) -> Result { + match status { + bindings::regulator_status_REGULATOR_STATUS_OFF => Ok(Self::Off), + bindings::regulator_status_REGULATOR_STATUS_ON => Ok(Self::On), + bindings::regulator_status_REGULATOR_STATUS_ERROR => Ok(Self::Error), + bindings::regulator_status_REGULATOR_STATUS_FAST => Ok(Self::Fast), + bindings::regulator_status_REGULATOR_STATUS_NORMAL => Ok(Self::Normal), + bindings::regulator_status_REGULATOR_STATUS_IDLE => Ok(Self::Idle), + bindings::regulator_status_REGULATOR_STATUS_STANDBY => Ok(Self::Standby), + bindings::regulator_status_REGULATOR_STATUS_BYPASS => Ok(Self::Bypass), + bindings::regulator_status_REGULATOR_STATUS_UNDEFINED => Ok(Self::Undefined), + _ => Err(EINVAL), + } + } +} + +impl From for Status { + fn from(mode: Mode) -> Self { + // SAFETY: `regulator_mode_to_status` is a `pure function` that is only doing integer + // to integer conversion, hence this function call is safe. + let status = unsafe { bindings::regulator_mode_to_status(mode as _) }; + + if status < 0 { + Self::Undefined + } else { + Self::try_from(status as core::ffi::c_uint).unwrap_or(Self::Undefined) + } + } +} + +/// [`Device`]'s operations +#[vtable] +pub trait Driver { + /// User data that will be accessible to all operations + type Data: ForeignOwnable + Send + Sync; + + /// Return one of the supported voltages, in microvolt; zero if the selector indicates a + /// voltage that is unusable by the system; or negative errno. Selectors range from zero to one + /// less than the number of voltages supported by the system. + fn list_voltage(_rdev: &mut Device, _selector: u32) -> Result { + Err(ENOTSUPP) + } + + /// Set the voltage for the regulator within the range specified. The driver should select the + /// voltage closest to `min_uv`. + fn set_voltage(_rdev: &mut Device, _min_uv: i32, _max_uv: i32) -> Result { + Err(ENOTSUPP) + } + + /// Set the voltage for the regulator using the specified selector. + fn set_voltage_sel(_rdev: &mut Device, _selector: u32) -> Result { + Err(ENOTSUPP) + } + + /// Convert a voltage into a selector. + fn map_voltage(_rdev: &mut Device, _min_uv: i32, _max_uv: i32) -> Result { + Err(ENOTSUPP) + } + + /// Get the currently configured voltage for the regulator; Returns + /// [`ENOTRECOVERABLE`] if the regulator can't be read at bootup and hasn't been + /// set yet. + fn get_voltage(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Get the currently configured voltage selector for the regulator; Returns + /// [`ENOTRECOVERABLE`] if the regulator can't be read at bootup and hasn't been + /// set yet. + fn get_voltage_sel(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Configure a limit for a current-limited regulator. + /// + /// The driver should select the current closest to `max_ua`. + fn set_current_limit(_rdev: &mut Device, _min_ua: i32, _max_ua: i32) -> Result { + Err(ENOTSUPP) + } + + /// Get the configured limit for a current-limited regulator. + fn get_current_limit(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Enable or disable the active discharge of the regulator. + fn set_active_discharge(_rdev: &mut Device, _enable: bool) -> Result { + Err(ENOTSUPP) + } + + /// Configure the regulator as enabled. + fn enable(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Configure the regulator as disabled. + fn disable(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Returns enablement state of the regulator. + fn is_enabled(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Set the configured operating [`Mode`] for the regulator. + fn set_mode(_rdev: &mut Device, _mode: Mode) -> Result { + Err(ENOTSUPP) + } + + /// Get the configured operating [`Mode`] for the regulator. + fn get_mode(_rdev: &mut Device) -> Mode { + Mode::Invalid + } + + /// Report the regulator [`Status`]. + fn get_status(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Set the voltage for the regaultor when the system is suspended. + fn set_suspend_voltage(_rdev: &mut Device, _uv: i32) -> Result { + Err(ENOTSUPP) + } + + /// Mark the regulator as enabled when the system is suspended. + fn set_suspend_enable(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Mark the regulator as disabled when the system is suspended. + fn set_suspend_disable(_rdev: &mut Device) -> Result { + Err(ENOTSUPP) + } + + /// Set the operating mode for the regulator when the system is suspended. + fn set_suspend_mode(_rdev: &mut Device, _mode: Mode) -> Result { + Err(ENOTSUPP) + } +} + +/// [`Device`]'s descriptor +/// +/// # Examples +/// +/// ``` +/// use kernel::{ +/// c_str, +/// device, +/// regulator::driver::{Config, Desc, Device, Driver, Type}, +/// types::ForeignOwnable, +/// }; +/// +/// struct MyDeviceDriver; +/// +/// #[vtable] +/// impl Driver for MyDeviceDriver { +/// type Data = (); +/// } +/// +/// static BUCK_DESC: Desc = Desc::new::(c_str!("my_driver"), Type::Voltage) +/// .with_of_match(c_str!("buck")) +/// .with_enable(0x24, 0x1, 0x1, 0); +/// +/// fn example(dev: &mut device::Device, mut config: Config<::Data>) { +/// let _ = Device::register(dev, &BUCK_DESC, config); +/// } +/// ``` +/// +/// # Invariants +/// +/// `self.0` has always valid data. +pub struct Desc(bindings::regulator_desc); +impl Desc { + /// Create a new [`Device`] descriptor + pub const fn new(name: &'static CStr, reg_type: Type) -> Self { + // SAFETY: `bindings::regulator_desc" is safe to initialize with 0s. + let mut desc: bindings::regulator_desc = unsafe { core::mem::zeroed() }; + desc.name = name.as_char_ptr(); + desc.type_ = match reg_type { + Type::Voltage => bindings::regulator_type_REGULATOR_VOLTAGE, + Type::Current => bindings::regulator_type_REGULATOR_CURRENT, + }; + desc.ops = Adapter::::build(); + Self(desc) + } + + /// Setup the register address, mask, and {en,dis}able values + pub const fn with_enable(mut self, reg: u32, mask: u32, en_val: u32, dis_val: u32) -> Self { + self.0.enable_reg = reg; + self.0.enable_mask = mask; + self.0.enable_val = en_val; + self.0.disable_val = dis_val; + self + } + + /// Setup the register address, mask, and {en,dis}able values. {En,Dis}able values are + /// inverted, i.e. `dis_val` will be use to enable the regulator while `en_val` will be used + /// to disable the regulator. + pub const fn with_inverted_enable( + mut self, + reg: u32, + mask: u32, + en_val: u32, + dis_val: u32, + ) -> Self { + self.0.enable_is_inverted = true; + self.with_enable(reg, mask, en_val, dis_val) + } + + /// Setup the active discharge regiter address, mask, on/off values. + pub const fn with_active_discharge(mut self, reg: u32, mask: u32, on: u32, off: u32) -> Self { + self.0.active_discharge_on = on; + self.0.active_discharge_off = off; + self.0.active_discharge_reg = reg; + self.0.active_discharge_mask = mask; + self + } + + /// Setup the current selection register address, mask, and current table + pub const fn with_csel(mut self, reg: u32, mask: u32, table: &'static [u32]) -> Self { + self.0.csel_reg = reg; + self.0.csel_mask = mask; + self.0.curr_table = table.as_ptr(); + self + } + + /// Voltages are a linear mapping + pub const fn with_linear_mapping( + mut self, + reg: u32, + mask: u32, + min_uv: u32, + uv_step: u32, + n_voltages: u32, + linear_min_sel: u32, + ) -> Self { + self.0.vsel_reg = reg; + self.0.vsel_mask = mask; + self.0.n_voltages = n_voltages; + self.0.min_uV = min_uv; + self.0.uV_step = uv_step; + self.0.linear_min_sel = linear_min_sel; + self + } + + /// Set the regulator owner + pub const fn with_owner(mut self, owner: &'static ThisModule) -> Self { + self.0.owner = owner.as_ptr(); + self + } + + /// Set the name used to identify the regulator in the DT. + pub const fn with_of_match(mut self, of_match: &'static CStr) -> Self { + self.0.of_match = of_match.as_char_ptr(); + self + } +} + +// SAFETY: `Desc` cannot be modified after its declaration and owns its data, hence it is safe +// to share references between threads. +unsafe impl Sync for Desc {} + +/// [`Device`]'s Config +/// +/// # Examples +/// +/// ``` +/// use kernel::regulator::driver::Config; +/// # use kernel::regulator::driver::{Desc, Device}; +/// # use kernel::{device, sync::Arc}; +/// +/// struct DriverData(u32); +/// +/// # fn probe(dev: &device::Device, desc: &'static Desc) -> Result { +/// let config = Config::>::new(dev, Arc::new(DriverData(128), GFP_KERNEL)?); +/// let reg = Device::register(dev, desc, config)?; +/// # Ok(()) +/// # } +/// ``` +/// +/// # Invariants +/// +/// `self.cfg` always hold valid data. +pub struct Config { + cfg: bindings::regulator_config, + data: T, +} + +impl Config { + /// Create a [`Device`] config. + pub fn new(dev: &device::Device, data: T) -> Self { + Self { + cfg: bindings::regulator_config { + dev: dev.as_raw(), + ..Default::default() + }, + data, + } + } +} + +/// Regulator device +/// +/// Abstraction for `struct regulator_dev`. +/// +/// # Invariants +/// +/// * `self.rdev` is valid and non-null. +/// * [`Self`] has owns `self.rdev` memory allocation. +/// * [`Self`] has owns memory of type `T` that can be retrieved through `rdev_get_drvdata`. +pub struct Device { + rdev: NonNull, + _data_type: PhantomData, +} + +impl Device { + /// # Safety + /// + /// `rdev` must be valid and non-null. + unsafe fn from_raw(rdev: *mut bindings::regulator_dev) -> ManuallyDrop { + ManuallyDrop::new(Self { + // SAFETY: The caller of `Self::from_raw` must garantee that `rdev` is non-null and + // valid.. + rdev: unsafe { NonNull::new_unchecked(rdev) }, + _data_type: PhantomData::, + }) + } + + /// register a Regulator driver + pub fn register( + dev: &device::Device, + desc: &'static Desc, + mut config: Config, + ) -> Result { + config.cfg.driver_data = config.data.into_foreign() as _; + + // SAFETY: By the type invariants, we know that `dev.as_ref().as_raw()` is always + // valid and non-null, and the descriptor and config are guaranteed to be valid values, + // hence it is safe to perform the FFI call. + let rdev = from_err_ptr(unsafe { + bindings::regulator_register(dev.as_raw(), &desc.0, &config.cfg) + })?; + + Ok(Self { + rdev: NonNull::new(rdev).ok_or(EINVAL)?, + _data_type: PhantomData::, + }) + } + + /// List voltages when the regulator is using linear mapping + pub fn list_voltage_linear(&self, selector: u32) -> Result { + // SAFETY: By the type invariants, we know that `self.rdev` is always valid and non-null. + // The C function is safe to call with any selector values. + let ret = unsafe { bindings::regulator_list_voltage_linear(self.rdev.as_ptr(), selector) }; + if ret < 0 { + return Err(Error::from_errno(ret)); + } + Ok(ret) + } + + /// Get regulator's name + pub fn get_name(&self) -> &'static CStr { + // SAFETY: By the type invariants, we know that `self.rdev` is always valid and non-null. + // The C function is guaranteed to return a valid string. + unsafe { CStr::from_char_ptr(bindings::rdev_get_name(self.rdev.as_ptr())) } + } + + /// Get regulator's ID + pub fn get_id(&self) -> i32 { + // SAFETY: By the type invariants, we know that `self.rdev` is always valid and non-null. + unsafe { bindings::rdev_get_id(self.rdev.as_ptr()) } + } + + /// Retrieve driver data associated to `self` + pub fn data(&self) -> T::Borrowed<'_> { + // SAFETY: By the type invariants, we know that `self.rdev` is always valid and non-null. + unsafe { T::borrow(bindings::rdev_get_drvdata(self.rdev.as_ptr())) } + } +} + +impl Drop for Device { + fn drop(&mut self) { + // SAFETY: The type invariants guarantee that `self.rdev` is valid and non-null, + // so it is safe to perform the FFI call. + unsafe { bindings::regulator_unregister(self.rdev.as_ptr()) }; + + // SAFETY: The type invariants garuantee that `self.rdev` is valid and non-null, and + // that `rdev_get_drvdata` is valid memory of type `T` stored there by calling + // `T::into_foreign`. + unsafe { T::from_foreign(bindings::rdev_get_drvdata(self.rdev.as_ptr())) }; + } +} + +// SAFETY: `Device` has sole ownership of `self.rdev` and is never read outside of the C +// implementation. It is safe to use it from any thread. +unsafe impl Send for Device {} + +// SAFETY: It is OK to access `Device` through shared references from other threads because +// the C code is insuring proper synchronization of `self.rdev`. +unsafe impl Sync for Device {} + +/// [`Device`] type +pub enum Type { + /// Voltage regulator + Voltage, + /// Current regulator + Current, +} + +pub(crate) struct Adapter(PhantomData); + +impl Adapter { + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn list_voltage_callback( + rdev: *mut bindings::regulator_dev, + selector: core::ffi::c_uint, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| T::list_voltage(&mut rdev, selector)) + } + + /// # Safety + /// + /// `rdev` and `selector` must be non-null and valid. + unsafe extern "C" fn set_voltage_callback( + rdev: *mut bindings::regulator_dev, + min_uv: core::ffi::c_int, + max_uv: core::ffi::c_int, + selector: *mut core::ffi::c_uint, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + match T::set_voltage(&mut rdev, min_uv, max_uv) { + Ok(v) => { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + unsafe { *selector = v as _ }; + 0 + } + Err(e) => e.to_errno(), + } + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn map_voltage_callback( + rdev: *mut bindings::regulator_dev, + min_uv: core::ffi::c_int, + max_uv: core::ffi::c_int, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| T::map_voltage(&mut rdev, min_uv, max_uv)) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn set_voltage_sel_callback( + rdev: *mut bindings::regulator_dev, + selector: core::ffi::c_uint, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::set_voltage_sel(&mut rdev, selector)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn get_voltage_callback( + rdev: *mut bindings::regulator_dev, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| T::get_voltage(&mut rdev)) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn get_voltage_sel_callback( + rdev: *mut bindings::regulator_dev, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| T::get_voltage_sel(&mut rdev)) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn set_current_limit_callback( + rdev: *mut bindings::regulator_dev, + min_ua: core::ffi::c_int, + max_ua: core::ffi::c_int, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::set_current_limit(&mut rdev, min_ua, max_ua)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn get_current_limit_callback( + rdev: *mut bindings::regulator_dev, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| T::get_current_limit(&mut rdev)) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn set_active_discharge_callback( + rdev: *mut bindings::regulator_dev, + enable: bool, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::set_active_discharge(&mut rdev, enable)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn enable_callback(rdev: *mut bindings::regulator_dev) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::enable(&mut rdev)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn disable_callback(rdev: *mut bindings::regulator_dev) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::disable(&mut rdev)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn is_enabled_callback( + rdev: *mut bindings::regulator_dev, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::is_enabled(&mut rdev)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn set_mode_callback( + rdev: *mut bindings::regulator_dev, + mode: core::ffi::c_uint, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + let mode = Mode::try_from(mode).unwrap_or(Mode::Invalid); + T::set_mode(&mut rdev, mode)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn get_mode_callback( + rdev: *mut bindings::regulator_dev, + ) -> core::ffi::c_uint { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + T::get_mode(&mut rdev) as _ + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn get_status_callback( + rdev: *mut bindings::regulator_dev, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| Ok(T::get_status(&mut rdev)? as _)) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn set_suspend_voltage_callback( + rdev: *mut bindings::regulator_dev, + uv: core::ffi::c_int, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::set_suspend_voltage(&mut rdev, uv)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn set_suspend_enable_callback( + rdev: *mut bindings::regulator_dev, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::set_suspend_enable(&mut rdev)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn set_suspend_disable_callback( + rdev: *mut bindings::regulator_dev, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + T::set_suspend_disable(&mut rdev)?; + Ok(0) + }) + } + + /// # Safety + /// + /// `rdev` must be non-null and valid. + unsafe extern "C" fn set_suspend_mode_callback( + rdev: *mut bindings::regulator_dev, + mode: core::ffi::c_uint, + ) -> core::ffi::c_int { + // SAFETY: Per this function safety requirements, `rdev` is non-null and valid. + let mut rdev = unsafe { Device::from_raw(rdev) }; + from_result(|| { + let mode = Mode::try_from(mode).unwrap_or(Mode::Invalid); + T::set_suspend_mode(&mut rdev, mode)?; + Ok(0) + }) + } + + const VTABLE: bindings::regulator_ops = bindings::regulator_ops { + list_voltage: if T::HAS_LIST_VOLTAGE { + Some(Adapter::::list_voltage_callback) + } else { + None + }, + set_voltage: if T::HAS_SET_VOLTAGE { + Some(Adapter::::set_voltage_callback) + } else { + None + }, + map_voltage: if T::HAS_MAP_VOLTAGE { + Some(Adapter::::map_voltage_callback) + } else { + None + }, + set_voltage_sel: if T::HAS_SET_VOLTAGE_SEL { + Some(Adapter::::set_voltage_sel_callback) + } else { + None + }, + get_voltage: if T::HAS_GET_VOLTAGE { + Some(Adapter::::get_voltage_callback) + } else { + None + }, + get_voltage_sel: if T::HAS_GET_VOLTAGE_SEL { + Some(Adapter::::get_voltage_sel_callback) + } else { + None + }, + set_current_limit: if T::HAS_SET_CURRENT_LIMIT { + Some(Adapter::::set_current_limit_callback) + } else { + None + }, + get_current_limit: if T::HAS_GET_CURRENT_LIMIT { + Some(Adapter::::get_current_limit_callback) + } else { + None + }, + set_active_discharge: if T::HAS_SET_ACTIVE_DISCHARGE { + Some(Adapter::::set_active_discharge_callback) + } else { + None + }, + enable: if T::HAS_ENABLE { + Some(Adapter::::enable_callback) + } else { + None + }, + disable: if T::HAS_DISABLE { + Some(Adapter::::disable_callback) + } else { + None + }, + is_enabled: if T::HAS_IS_ENABLED { + Some(Adapter::::is_enabled_callback) + } else { + None + }, + set_mode: if T::HAS_SET_MODE { + Some(Adapter::::set_mode_callback) + } else { + None + }, + get_mode: if T::HAS_GET_MODE { + Some(Adapter::::get_mode_callback) + } else { + None + }, + get_status: if T::HAS_GET_STATUS { + Some(Adapter::::get_status_callback) + } else { + None + }, + set_suspend_voltage: if T::HAS_SET_SUSPEND_VOLTAGE { + Some(Adapter::::set_suspend_voltage_callback) + } else { + None + }, + set_suspend_enable: if T::HAS_SET_SUSPEND_ENABLE { + Some(Adapter::::set_suspend_enable_callback) + } else { + None + }, + set_suspend_disable: if T::HAS_SET_SUSPEND_DISABLE { + Some(Adapter::::set_suspend_disable_callback) + } else { + None + }, + set_suspend_mode: if T::HAS_SET_SUSPEND_MODE { + Some(Adapter::::set_suspend_mode_callback) + } else { + None + }, + // SAFETY: The rest is zeroed out to initialize `struct regulator_ops`, + // sets `Option<&F>` to be `None`. + ..unsafe { core::mem::zeroed() } + }; + + const fn build() -> &'static bindings::regulator_ops { + &Self::VTABLE + } +} From patchwork Wed Dec 18 23:36:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien Parent X-Patchwork-Id: 851766 Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (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 B474C1FDE29; Wed, 18 Dec 2024 23:37:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565054; cv=none; b=uBW6pbswzo1AALANqC5HaEpi6AnIskflevuCoEYWk5/YWtEAcJuYdMXdebgVLRY8Wapl8l5Ml2kMboH//VUMPHWu05SsCUQEO5ULBDhhjcYCGniMLm/ZPe8Zp/I+NksmqIvk8oD0p9s+KRHk1zpKW2N+B25LvWl48OcC4Xejdbg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565054; c=relaxed/simple; bh=t2TsMiP3ilVlrTWn1B/PYvmpFe1OKGm02kYl5hvd16o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Vh7ennABYqjEp/B8pJJIPoMF35y5oovMQQVET3GN+g4huCqVdsHXaBW3p5eTLwPB/KfLj/YARt0iRMLFlXw9YzqFFA9bKeThA/d5uFRCYN8oUjsZVmiCp4PXwBlz7YCy59jWfKP6tvtfHdO1NNgKIPZu8L3YaztsNya8rdrqaDY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XSo6p10t; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XSo6p10t" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-21670dce0a7so2627735ad.1; Wed, 18 Dec 2024 15:37:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734565052; x=1735169852; 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=MwKgzZr86c7oRTHczyCJoBnZeP8Mi7cizIcfC7/y0QE=; b=XSo6p10t91g5ySCuLaj+Ufz6kt6gR8ovg6xb6d0qtYtRYptc8gRGuHLU4qA8CoLTxD fHa0i8BmzNm7gsPUV5MCTXaqNrsf7YebL8LvWaCP3oephDp5zJTg4IceTd02ieqGU7TD 6Tj/f+o3Z9N2dL6p94sAXiVaP3CrhsejzfwkPD0ODMNWGZTx1+N1rZ0wMviEfErUQytZ oOnKeNeJykMM0Wq6MBsPx7NZShgRQD3nh3b163bho0rY29N5xwMdZ0RahXm+bsmsv38a xO0xicOfrjReUGsYqv4wmt0I32nJ+/Drafc1Eg1Mv+JPICqwQmzlMMGGRHE+5oo6qtwM Jl8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734565052; x=1735169852; 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=MwKgzZr86c7oRTHczyCJoBnZeP8Mi7cizIcfC7/y0QE=; b=nqlH/2mbsk2Yl0tC+zplMopHhCOENHXNVsIRVYsEi/TUEmZD9272j1F+95DC+WEjK2 OQJCisUbzVWyohG5yv9BHmGK8gm9c83jvBn3yMeMHZ1ynIqRnYroQN5vaUyDxEr/8cCf uoDcPSszNOJuxziLUx8t5YCJfCX6ZUmQjbBh8mRvyvGBOzOh0wJVOGrWmHpOgAKYTiPj uWnk5BIDEfdsnMA1MYmRgPaVJMnLUgSbf4zJyVdI86whHj7yOkGyONIQmGpgS+xv8evY Z1cflYF2SRg6Nj+cEd3uK72tW2Uh/q9F/i8qEi69cTkT7uYKUGgpQbO9GcTiWoaOSk1h pD7w== X-Forwarded-Encrypted: i=1; AJvYcCVx1hld+HvzBFVpIkZ4dqRBumOV5iWdkQWyk/JZbi8TVmOQmS9mytByc2XiipIovkfJgl6yx8HYpSjr@vger.kernel.org, AJvYcCW2iQglCqozzDAJGLANp9sqPX50USp0w+Na/LbwGLNQ5nkexSYcvKDt2H7kcV6UID811gk5bg3mTXYEwLnp@vger.kernel.org, AJvYcCWkAH3Qa4kt97Ue/iBixerkQntGr+FgEFIzQhlK4Mxv2z7VTz8EBDPjGm4dgQGRzNPD8jIliL63+rWxg9NxRuo=@vger.kernel.org, AJvYcCXjetXlse6oMYDK/huyceNX8dGAb/ezrLZywC4wqEzt73WFv16cVYYqFOXk4CQqKC1ytZzRU1lFHRzE6D55@vger.kernel.org X-Gm-Message-State: AOJu0YzOLrnvLqak+sS0GH0UBxMX3nX6pPnb2r1akbdYAvzarYCwITix CG2hZmphsodL7c3YDhmY6Nm6Jbsv4wrNR3QEGjb39YgXap2mBN1p X-Gm-Gg: ASbGncsuoUnzuIcA9jAClC2y413tysJ+7mmOt1z8vo2QtRyaprXhKi2GUdvWWLjpA1P bhnmzGt6EAePUYD2cILUVvZDKBF+KL+jTEiyes7GpgjrEbb4A1U15BVhuTrEwWmoV0EnYQbP4fI aIS+lKtmllcKwZqp0d/p8081RXZjPR9sOaAUXVEWnwuW7l8K+38CM2gYnQ7/Fz7PsteyEEITKIt kLZX045Ha8sh/ZNv/kPkd8Mo1EtgvyxgFGGZnLmYl0pRoRr6aznHuSn X-Google-Smtp-Source: AGHT+IEXFMesvXJhtouY2pEYJ1RzXyDqbP8BeiasyhxSyJNIN4LRKtgRxxtfBkdvFwD8b4B4U9eHUw== X-Received: by 2002:a17:902:d2ca:b0:215:8695:ef91 with SMTP id d9443c01a7336-219d965c6c8mr18160005ad.6.1734565051971; Wed, 18 Dec 2024 15:37:31 -0800 (PST) Received: from [127.0.1.1] ([2001:569:fcea:600:2e06:283e:5daa:4d0f]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-219dc9f6967sm802335ad.214.2024.12.18.15.37.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2024 15:37:31 -0800 (PST) From: Fabien Parent Date: Wed, 18 Dec 2024 15:36:37 -0800 Subject: [PATCH 7/9] dt-bindings: regulator: add binding for ncv6336 regulator Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241218-ncv6336-v1-7-b8d973747f7a@gmail.com> References: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> In-Reply-To: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> To: Rob Herring , Saravana Kannan , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Greg Kroah-Hartman , "Rafael J. Wysocki" , Wolfram Sang , Mark Brown , Liam Girdwood , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Fabien Parent Cc: devicetree@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org, linux-arm-msm@vger.kernel.org, vinod.koul@linaro.org, Fabien Parent X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1743; i=parent.f@gmail.com; h=from:subject:message-id; bh=ggkzqiAnE/aO71fqKd9R2qFTZ9vozMA5CH3AStZDGIU=; b=LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgpvd0o0bkFGdEFwTDlrQTBEQUFvQmlKc2d4Q kw5cktRQnl5WmlBR2RqWEtoQkhva1UrTDJTS1ZBakR6ckswbXYwCjZ0Nnh1QWhmeER3ZWZnTmdP WFYvRklrQ013UUFBUW9BSFJZaEJONk0wZElMeXpzd3JmRnNxWWliSU1RUy9heWsKQlFKblkxeW9 BQW9KRUlpYklNUVMvYXlrM05VUC9qaWhsTjBZOHlEeEZqaUozTHNMS3ZsMk94R3NCSkxYOHFORw o0SzhMaWJ1RTQyT1FZemY0aEowcS90MTZSK0dlU1ZJNXI3YTlFWkR4ZGF4Sk50cVNDakthWFJyS jNyL21nL0wxCkJNb1JDZ25IZDlzWDFuamMxZmZvbERXR21uaGdlRDg4bEcwNjNFUnRpMDBiSUlO aUxSL0YrZ0cwQTJ5ZDFWRmQKcEl0VDlMQXNDbGlGeGtyT0tXZWpKQzFUVklUK0Frd2hQZmMwUnR 2ZCs5eWRENHMrZzE4c3JMdTNyYUZVTUs1QwpVcXBxMnNFc041a29yNXNvSkVKTkVzMDRZN2IzSk xxK1JPeWdrYUV2SzhGSlVOS3ByVXduZXA4UnA5VGRzNXJDCmRGZW5vdVpkRXM3cXBFaXQ4OHlYV W04czk0MmhnSlo5TTVHcFdSNjJodVo1S050MWUwYlE4T3NPUW0xT1NYc3AKb2NZem9tMkZUL05V eUYwVEtCdDYzbTFVa3NkdEZnT2taQ2ZpeUgrS0daQ3dZWVJYbDVqTlhZcmJsR3pVRU9nLwpBNFd 3TU5pUGY3aXZ5MWs2VVc5d2MrQ0w4Tk9mSUdGVDVkQXFVRDFLdVhRNnJSSitwNFR6Q0lkMENqZF NDQSs5CnY5WFZNRGNkdzFWVHNNaTYyTk9GS0R1R0Ura0FJYThnVEdITmYveVVsYysrV09SalJCa UIvbHNnWW9TMWhQZ2oKRGxrMTBDOGxheTdoL2RrcUd1c2lpWFo5L3l0ODZwRkNnWm1tSlBaZlUv dnhnVjhmN0tWZzBmR2tLWjd3K3o2aAp5byt1eU1mbTA4TFM5Z3MxTVFzQ3RqMm9HWG9FU3drcnJ ZcFBaWmRmVTdOZCs2MUJ5M3QzdHVSVTRSK0N5NjJYClE1SXEvS2VvWExZc2JRPT0KPXdKdGUKLS 0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo= X-Developer-Key: i=parent.f@gmail.com; a=openpgp; fpr=07BB034F9E8E3AF0DF4CF7607AE864A1E16FA383 From: Fabien Parent Add binding documentation for the Onsemi NCV6336 regulator. Signed-off-by: Fabien Parent --- .../bindings/regulator/onnn,ncv6336.yaml | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/onnn,ncv6336.yaml b/Documentation/devicetree/bindings/regulator/onnn,ncv6336.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c69d126cab33668febe18e77bb34bd4bef52c993 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/onnn,ncv6336.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/onnn,ncv6336.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Onsemi NCV6336 Buck converter + +maintainers: + - Fabien Parent + +description: | + The NCV6336 is an I2C programmable BUCK (step-down) converter. + It is designed for mobile power applications. + +properties: + $nodename: + pattern: "regulator@[0-9a-f]{2}" + + compatible: + const: onnn,ncv6336 + + reg: + maxItems: 1 + + buck: + description: buck regulator description + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + +required: + - compatible + - reg + - buck + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + regulator@1c { + compatible = "onnn,ncv6336"; + reg = <0x1c>; + + buck { + regulator-name = "ncv6336,buck"; + }; + }; + }; +... From patchwork Wed Dec 18 23:36:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien Parent X-Patchwork-Id: 851765 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (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 47FA7204F66; Wed, 18 Dec 2024 23:37:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565058; cv=none; b=ZWa72RSFlEdiEhe140nQl4v2e1LyOk72wSIA4q6JFaqJZ21udtWmUK20Ad4XV6znfjcvqeZ4sLKYL/uSSdAmTfiip/23hhBEohnj1H66PgAYqegQFosSfYjO+Beumh//oki5wjpxGthew4qzFlMc2jJ3vHa68Xq1H/dLsZN3JS8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734565058; c=relaxed/simple; bh=eZUgIXh4Dafp5SjQXe3JmOhBWmOQQGNy2uNWoRlXbQc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rU/wkFqQtKl75dIr+9FhGMeRqfhYayfBEgozfNFHl59qVxvdO0A748aCjiar9eXjya9y3iZJTIhDoixzwmgZ9csZ//ZTTyzqctneQ6kgJfLxlMX9Tbzlqr9g75e4Y8kfvNOOipxKBErjQn04r9TwUgJyeKGSfe+hHmtpchk4rho= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ILJ/EcO2; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ILJ/EcO2" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-216426b0865so2170875ad.0; Wed, 18 Dec 2024 15:37:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734565056; x=1735169856; 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=h2p+Bn+O63LERCuE6dGd6gVg3sXhL98osLDUQM697Sg=; b=ILJ/EcO2Y5BLl/RoAUabqnW76Ct7JSvRn2V3/vehQG4PjmkgQTWdf6DdJF6XxzfmR9 qT7RPXeNgzWQkYiLpJ9pYruUWaY0geFTeM7lSgCNzM/r8HAnrJcdVUHQ7cvFFch6mBZa xezxNvDVrrfrQhhht1rRtkxrky40Vb1dmoc5g6Bzl0zOru20sl/oJnHFPyMEbGXbEg+K gwarLydx7iQcjKtzgVqK8TVPF71D5eOSXRi8SwGPIkoJ+s4ZCRPi3ukdW0Ogtc2a0j1x NaXUoiqDNGVkWs2hUPCQEd3pUTValJTfdVqxmksXiSzlbXJEf7deBGAIa4OuoRY7Vs7+ SsMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734565056; x=1735169856; 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=h2p+Bn+O63LERCuE6dGd6gVg3sXhL98osLDUQM697Sg=; b=fdAuEvP1arumZpBLatz42WK+HTadRAE9nIIoZ2gx34pUTwZV11Ndg+Fib9ieDq+0G0 1gUySxSDaEwNiBy5BPJZW2AybXSpPFqaN9pkoxKKr74Dot5WfozlGDzptiM21SkGY8ho +S3bfHcN2x7mE4l6PtOHdpKM3KGa4N8SevNXHW3S0IlyJ11SYFpd99jo6Dm7RjQ3hJfR jziy8sxT5PmBrXaC2mTZXb4DwdQQ4RtT+HCpfsmA1q2z5C+wwFKqz0ItWthUl1ssWZo+ blxwwCGT03IDElSnWUlgf3JfPrZ41WgNVoqMWG7BoDxqMHyTWx3hoF3PrJnaA9H1N+3A 5iQw== X-Forwarded-Encrypted: i=1; AJvYcCVGHVLolDKSD5NdC/OpM9sRmxiVXom6Zrsju9N9b9aWtA2ckm9DKK0Tvx6ckJAwzx/W23RI+gARevKu@vger.kernel.org, AJvYcCVjB50JSG8sMbrb9/IEGHOczSIsoOG4iZwuEQrwg97mnt3Ig9l64wT+GvHKT3UkP5vqVaFkWZsJLobheCiA@vger.kernel.org, AJvYcCVsF12TcgniougzEi4j78W6NhPf9hlpl7q29+6+VDfvSThrH/sMSTI8fdzFPCupeerTy3JV6sZDPBXbafEbxBU=@vger.kernel.org, AJvYcCXDDwqF0XJBKHxqzMi8TI3AzO9yKPr/fgzVR/LCv0ECgwFPqBS1TPBI9R3qZ2AoNXXBlkm5fgLxvtng4yer@vger.kernel.org X-Gm-Message-State: AOJu0YwpGY5P92PqDCxiOeWTeyMHMMTmSwvLnXU5PYpzhgZK+oeec66J zBHtKorh/rRXuC/ncY7rNfZ0tI9eeEJPCjEQbabuxq8fT+MdWRaA X-Gm-Gg: ASbGncvr0mLow9apz2RJDUx6efyMEsfIFLERdNfhdZkvf46nBUCCfErUYxge70NZJFn vggZJ+QQMPQc2AzP9xcPxJFqKV+4xvqpOTQs2NDKSYRJ/IpRp+tgEfr0ysw73hlfCje0jv4JVOm tW6QAOpcr7H6zFfreXyJynvrK10S3czeUjcjRonO1iPJm/B9BbjmTVbZdO1E9pm9Q9Y9pEEKbba dyPErxyfb+pmsvljk9OT0Wge4xb8PRzoDNUqymc00E2sMzhcG50d9Lb X-Google-Smtp-Source: AGHT+IHSZdbhBBo2sF8tqN4LT+Oi0B4GGcc3Vh9M1Y2KXAp+XnvVO/Rtbaui7owIt/uIhqw2619amg== X-Received: by 2002:a17:902:ea11:b0:216:2f7f:ff69 with SMTP id d9443c01a7336-219d966ea2bmr21730945ad.5.1734565056516; Wed, 18 Dec 2024 15:37:36 -0800 (PST) Received: from [127.0.1.1] ([2001:569:fcea:600:2e06:283e:5daa:4d0f]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-219dc9f6967sm802335ad.214.2024.12.18.15.37.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2024 15:37:35 -0800 (PST) From: Fabien Parent Date: Wed, 18 Dec 2024 15:36:39 -0800 Subject: [PATCH 9/9] arm64: dts: qcom: apq8039-t2: add node for ncv6336 regulator Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241218-ncv6336-v1-9-b8d973747f7a@gmail.com> References: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> In-Reply-To: <20241218-ncv6336-v1-0-b8d973747f7a@gmail.com> To: Rob Herring , Saravana Kannan , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Greg Kroah-Hartman , "Rafael J. Wysocki" , Wolfram Sang , Mark Brown , Liam Girdwood , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Fabien Parent Cc: devicetree@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org, linux-arm-msm@vger.kernel.org, vinod.koul@linaro.org, Fabien Parent X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1251; i=parent.f@gmail.com; h=from:subject:message-id; bh=HWjtZtg1pmveHn6OiavIms18l8HI9Sa8dLce2gBDllY=; b=LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgpvd0o0bkFGdEFwTDlrQTBEQUFvQmlKc2d4Q kw5cktRQnl5WmlBR2RqWEtwQTJvQ0gvSmYydG1KWGZDWGx2SGo2CkY1VnJSNWNRbG56NFV0NGJw TU5PWTRrQ013UUFBUW9BSFJZaEJONk0wZElMeXpzd3JmRnNxWWliSU1RUy9heWsKQlFKblkxeXF BQW9KRUlpYklNUVMvYXlrdHQwUC9SWG1lTHU1L29wcHNxWHR1blJXUFVQeVpFZlBYVnlmbDRNaw paQnRFRzBDcU1RZTdqMk5qVVAxS25hWHFtQTgvVS9mMzRKSGNwSjBKTVhxV2ZxY3Z6dmxNRXh0c jZIK3BKM045CnFuUmt5KzBpUFNiL0lNUUZQVktWMVUwSHN6VWl3MVVtbTNNWlVTenBWQjBPSm9U OC9MODlEdHNzUVFCenZxaWsKanJLc2ZSV1MwNzlpL1NJdm9uc1JqOFZFY2lpY3FrbW5maERLYWo 2a1d0MFE2aTcvY0daQ2QvWVZndWFyYlNKOQpFcm8zbndrVEI0SVkrSWpGWWtQbkFhUGJUaVJpV1 lSYlQ4TjhIaDRjdEFKa2hSM1pzOFNkZ05jRUtwWEFjN1ZlCmFjelNXSC80VXNCby9mQ0U5d0szV mgvclZSTDlxdndBbWRCY2ZYMWVNZ2tMZWYrQWt6ZXNiWFpVUVR1L21aanoKZThNTk1IS0JYYytl d3pzYnlDd2UrWVJEcE8reEt0SVRpcFFvRFpPS1pQbEptaURJZ2RSRkMzeHJDaHROdy9mdwphNnB ReUFBS0RLWVl1QktrMjk3M1JmOFRQM0xPS1FJZ0NLRU1haXRQV2NzWWFKdjgrSkRhVU5aOWEzSj A3VDVnCjc2eXRvOS9qYW02dVNreWlqckpSYW11YUVRRjYwUTNvUzlQSTd5NnVWREFEdXEwZFZTe GZkb2ZBM0NCN1pyOTMKSDY3REVZWHErNG9CY2kwdlVmUTV5Mm5WVG10bDZuN080UHRJRTltNFk1 RHRXT2lOTXhCS05jdFVPSjlvRG1mNQo1bTRXUHJVWkEyQjI5TUZpVDU0dEhKb05yR1ZKUHBBVWh HZWNHcVBPQ0tFeXJvL2FWZm41UHhQS3ZZdXBPN3pkCmoySWIzSjMvZU9BbHRnPT0KPWNkTDkKLS 0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo= X-Developer-Key: i=parent.f@gmail.com; a=openpgp; fpr=07BB034F9E8E3AF0DF4CF7607AE864A1E16FA383 From: Fabien Parent CPR is using the power rail provided by the ncv6336 buck regulator on the apq8039 t2 board. This commit adds the required regulator. Signed-off-by: Fabien Parent --- arch/arm64/boot/dts/qcom/apq8039-t2.dts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8039-t2.dts b/arch/arm64/boot/dts/qcom/apq8039-t2.dts index 4f82bb668616f942d65f59a6f418cf38f404df32..2da5b7d01521520a6814b76c02329be3bdedb4fd 100644 --- a/arch/arm64/boot/dts/qcom/apq8039-t2.dts +++ b/arch/arm64/boot/dts/qcom/apq8039-t2.dts @@ -111,6 +111,23 @@ typec_ep: endpoint { }; }; +&blsp_i2c4 { + status = "okay"; + + regulator@1c { + compatible = "onnn,ncv6336"; + reg = <0x1c>; + pinctrl-0 = <&ncv6336_vsel>; + pinctrl-names = "default"; + + buck { + regulator-name = "ncv6336,buck"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1393750>; + }; + }; +}; + &blsp_i2c5 { status = "okay"; }; @@ -371,6 +388,12 @@ typec_irq: typec-irq-state { pins = "gpio107"; bias-pull-up; }; + + ncv6336_vsel: ncv6336-state { + function = "gpio"; + pins = "gpio111"; + output-low; + }; }; &usb {