All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dirk Behme <dirk.behme@gmail.com>
To: "Fabien Parent" <parent.f@gmail.com>,
	"Rob Herring" <robh@kernel.org>,
	"Saravana Kannan" <saravanak@google.com>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	"Wolfram Sang" <wsa+renesas@sang-engineering.com>,
	"Mark Brown" <broonie@kernel.org>,
	"Liam Girdwood" <lgirdwood@gmail.com>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Bjorn Andersson" <andersson@kernel.org>,
	"Konrad Dybcio" <konradybcio@kernel.org>
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 <fabien.parent@linaro.org>
Subject: Re: [PATCH 8/9] regulator: add driver for ncv6336 regulator
Date: Thu, 19 Dec 2024 11:19:46 +0100	[thread overview]
Message-ID: <907b470c-3b24-41ba-9b6d-c07caa30ee00@gmail.com> (raw)
In-Reply-To: <20241218-ncv6336-v1-8-b8d973747f7a@gmail.com>

Hi Fabien,

you might have noticed that I'm using your development branches of
this since some time. So sending these patches for review is a big
step! Many thanks!

Just one topic to check below:

On 19.12.24 00:36, Fabien Parent wrote:
> From: Fabien Parent <fabien.parent@linaro.org>
> 
> This commit adds support for the Onsemi NCV6336 buck down converter.
> 
> Signed-off-by: Fabien Parent <fabien.parent@linaro.org>
> ---
>  drivers/regulator/Kconfig              |   7 +
>  drivers/regulator/Makefile             |   1 +
>  drivers/regulator/ncv6336_regulator.rs | 241 +++++++++++++++++++++++++++++++++
>  3 files changed, 249 insertions(+)
> 
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index 39297f7d8177193e51c99bc2b360c6d9936e62fe..7254a6e1d7539b147b7ba00ebcb6fd92eb6b2616 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -952,6 +952,13 @@ config REGULATOR_MTK_DVFSRC
>  	  of Mediatek. It allows for voting on regulator state
>  	  between multiple users.
>  
> +config REGULATOR_NCV6336
> +	tristate "Onsemi NCV6336 regulator driver"
> +	depends on RUST && OF && I2C=y
> +	select REGMAP_I2C
> +	help
> +	  Say y here to support the Onsemi NCV6336 buck converter.
> +
>  config REGULATOR_PALMAS
>  	tristate "TI Palmas PMIC Regulators"
>  	depends on MFD_PALMAS
> diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
> index 3d5a803dce8a0556ba9557fa069c6e37593b3c69..0309a78b820cc85883c0c129801ab713e08e4391 100644
> --- a/drivers/regulator/Makefile
> +++ b/drivers/regulator/Makefile
> @@ -113,6 +113,7 @@ obj-$(CONFIG_REGULATOR_MT6370) += mt6370-regulator.o
>  obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
>  obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
>  obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
> +obj-$(CONFIG_REGULATOR_NCV6336) += ncv6336_regulator.o
>  obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
>  obj-$(CONFIG_REGULATOR_QCOM_PM8008) += qcom-pm8008-regulator.o
>  obj-$(CONFIG_REGULATOR_QCOM_REFGEN) += qcom-refgen-regulator.o
> diff --git a/drivers/regulator/ncv6336_regulator.rs b/drivers/regulator/ncv6336_regulator.rs
> new file mode 100644
> index 0000000000000000000000000000000000000000..7efd7630792b68fb353ed1b1634980def9e326a1
> --- /dev/null
> +++ b/drivers/regulator/ncv6336_regulator.rs
> @@ -0,0 +1,241 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Driver for the Onsemi Buck Converter NCV6336
> +//!
> +//! Datasheet: https://www.onsemi.com/pdf/datasheet/ncv6336bm-d.pdf
> +
> +use kernel::{
> +    c_str, i2c, of,
> +    prelude::*,
> +    regmap::{self, BitFieldReadOps, BitFieldWriteOps, RawFieldWriteOps},
> +    regulator::{
> +        driver::{Config, Desc, Device, Driver, RegmapHelpers, Status, Type},
> +        Mode,
> +    },
> +    sync::{new_mutex, Arc, Mutex},
> +};
> +use register::*;
> +
> +kernel::module_i2c_driver! {
> +    type: Ncv6336,
> +    name: "ncv6336",
> +    author: "Fabien Parent <fabien.parent@linaro.org>",
> +    license: "GPL",
> +}
> +
> +kernel::i2c_device_table!(
> +    I2C_ID_TABLE,
> +    MODULE_I2C_ID_TABLE,
> +    <Ncv6336 as i2c::Driver>::IdInfo,
> +    [(i2c::DeviceId::new(c_str!("ncv6336")), ()),]
> +);
> +
> +kernel::of_device_table!(
> +    OF_ID_TABLE,
> +    MODULE_OF_ID_TABLE,
> +    <Ncv6336 as i2c::Driver>::IdInfo,
> +    [(of::DeviceId::new(c_str!("onnn,ncv6336")), ()),]
> +);
> +
> +regmap::define_regmap_field_descs!(FIELD_DESCS, {
> +    (pid, 0x3, READ, { value => raw([7:0], ro) }),
> +    (rid, 0x4, READ, { value => raw([7:0], ro) }),
> +    (fid, 0x5, READ, { value => raw([7:0], ro) }),
> +    (progvsel1, 0x10, RW, {
> +        voutvsel1 => raw([6:0], rw),
> +        envsel1   => bit(7, rw),
> +    }),
> +    (progvsel0, 0x11, RW, {
> +        voutvsel0 => raw([6:0], rw),
> +        envsel0   => bit(7, rw),
> +    }),
> +    (pgood, 0x12, RW, { dischg => bit(4, rw) }),
> +    (command, 0x14, RW, {
> +        vselgt   => bit(0, rw),
> +        pwmvsel1 => bit(6, rw),
> +        pwmvsel0 => bit(7, rw),
> +    }),
> +    (limconf, 0x16, RW, {
> +        rearm     => bit(0, rw),
> +        rststatus => bit(1, rw),
> +        tpwth     => enum([5:4], rw, {
> +            Temp83C  = 0x0,
> +            Temp94C  = 0x1,
> +            Temp105C = 0x2,
> +            Temp116C = 0x3,
> +        }),
> +        ipeak     => enum([7:6], rw, {
> +            Peak3p5A = 0x0,
> +            Peak4p0A = 0x1,
> +            Peak4p5A = 0x2,
> +            Peak5p0A = 0x3,

Could you check to read from or write to the tpwth or ipeak (enum)
above? I've been under the impression that for that Desc & enum need
to Copy & Clone [1]?

[1]

diff --git a/rust/kernel/regmap.rs b/rust/kernel/regmap.rs
index 232fe93df769..d1baf182f53c 100644
--- a/rust/kernel/regmap.rs
+++ b/rust/kernel/regmap.rs
@@ -623,6 +623,7 @@ macro_rules! regmap_field_enum {
         kernel::macros::paste! {
             #[repr(u32)]
             #[allow(non_camel_case_types)]
+            #[derive(Copy, Clone)]
             pub(crate) enum [<$field_name _enum>] {
                 $($k = $v,)+
             }
diff --git a/rust/kernel/regulator/driver.rs
b/rust/kernel/regulator/driver.rs
index e79e93122b09..0b6819e46686 100644
--- a/rust/kernel/regulator/driver.rs
+++ b/rust/kernel/regulator/driver.rs
@@ -256,6 +256,7 @@ fn set_suspend_mode(_rdev: &mut
Device<Self::Data>, _mode: Mode) -> Result {
 /// # Invariants
 ///
 /// `self.0` has always valid data.
+#[derive(Copy, Clone)]
 pub struct Desc(bindings::regulator_desc);
 impl Desc {
     /// Create a new [`Device`] descriptor

> +static NCV6336_DESC: Desc = Desc::new::<Ncv6336>(c_str!("ncv6336"), Type::Voltage)
> +    .with_owner(&THIS_MODULE)
> +    .with_of_match(c_str!("buck"))
> +    .with_active_discharge(
> +        pgood::addr(),
> +        pgood::dischg::mask(),
> +        pgood::dischg::mask(),
> +        0,
> +    )
> +    .with_csel(
> +        limconf::addr(),
> +        limconf::ipeak::mask(),
> +        &[3_500_000, 4_000_000, 4_500_000, 5_000_000],
> +    )
> +    .with_enable(
> +        progvsel0::addr(),
> +        progvsel0::envsel0::mask(),
> +        progvsel0::envsel0::mask(),
> +        0,
> +    )
> +    .with_linear_mapping(
> +        progvsel0::addr(),
> +        progvsel0::voutvsel0::mask(),
> +        600_000,
> +        6250,
> +        128,
> +        0,
> +    );
> +
> +struct Ncv6336RegulatorData {
> +    fields: regmap::Fields<{ FIELD_DESCS.len() }>,
> +}
> +
> +struct Ncv6336(#[expect(dead_code)] Device<<Self as Driver>::Data>);
> +
> +impl i2c::Driver for Ncv6336 {
> +    type IdInfo = ();
> +
> +    const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_ID_TABLE);
> +    const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_ID_TABLE);
> +
> +    fn probe(client: &mut i2c::Client, _id_info: Option<&Self::IdInfo>) -> Result<Pin<KBox<Self>>> {
> +        let config = regmap::Config::<AccessOps>::new(8, 8)
> +            .with_max_register(0x16)
> +            .with_cache_type(regmap::CacheType::RbTree);
> +        let regmap = Arc::new(regmap::Regmap::init_i2c(client, &config)?, GFP_KERNEL)?;
> +        let fields = regmap::Fields::new(&regmap, &FIELD_DESCS)?;
> +
> +        let data = Arc::pin_init(new_mutex!(Ncv6336RegulatorData { fields }), GFP_KERNEL)?;
> +        let config = Config::new(client.as_ref(), data.clone()).with_regmap(regmap.clone());
> +        let regulator = Device::register(client.as_ref(), &NCV6336_DESC, config)?;
> +
> +        let drvdata = KBox::new(Self(regulator), GFP_KERNEL)?;
> +
> +        Ok(drvdata.into())
> +    }
> +}
> +
> +#[vtable]
> +impl Driver for Ncv6336 {
> +    type Data = Arc<Mutex<Ncv6336RegulatorData>>;
> +
> +    fn list_voltage(reg: &mut Device<Self::Data>, selector: u32) -> Result<i32> {
> +        reg.list_voltage_linear(selector)
> +    }
> +
> +    fn enable(reg: &mut Device<Self::Data>) -> Result {
> +        reg.enable_regmap()
> +    }
> +
> +    fn disable(reg: &mut Device<Self::Data>) -> Result {
> +        reg.disable_regmap()
> +    }
> +
> +    fn is_enabled(reg: &mut Device<Self::Data>) -> Result<bool> {
> +        reg.is_enabled_regmap()
> +    }
> +
> +    fn set_active_discharge(reg: &mut Device<Self::Data>, enable: bool) -> Result {
> +        reg.set_active_discharge_regmap(enable)
> +    }
> +
> +    fn set_current_limit(reg: &mut Device<Self::Data>, min_ua: i32, max_ua: i32) -> Result {
> +        reg.set_current_limit_regmap(min_ua, max_ua)
> +    }
> +
> +    fn get_current_limit(reg: &mut Device<Self::Data>) -> Result<i32> {
> +        reg.get_current_limit_regmap()
> +    }
> +
> +    fn set_voltage_sel(reg: &mut Device<Self::Data>, selector: u32) -> Result {
> +        reg.set_voltage_sel_regmap(selector)
> +    }
> +
> +    fn get_voltage_sel(reg: &mut Device<Self::Data>) -> Result<i32> {
> +        reg.get_voltage_sel_regmap()
> +    }
> +
> +    fn set_mode(reg: &mut Device<Self::Data>, mode: Mode) -> Result {
> +        let data = reg.data();
> +        let fields = &mut data.lock().fields;
> +
> +        match mode {
> +            Mode::Normal => command::pwmvsel0::clear(fields),
> +            Mode::Fast => command::pwmvsel0::set(fields),
> +            _ => Err(ENOTSUPP),
> +        }
> +    }
> +
> +    fn get_mode(reg: &mut Device<Self::Data>) -> Mode {
> +        let data = reg.data();
> +        let fields = &mut data.lock().fields;
> +
> +        match command::pwmvsel0::is_set(fields) {
> +            Ok(true) => Mode::Fast,
> +            Ok(false) => Mode::Normal,
> +            Err(_) => Mode::Invalid,
> +        }
> +    }
> +
> +    fn get_status(reg: &mut Device<Self::Data>) -> Result<Status> {
> +        if !Self::is_enabled(reg)? {
> +            return Ok(Status::Off);
> +        }
> +
> +        Ok(Self::get_mode(reg).into())
> +    }
> +
> +    fn set_suspend_voltage(reg: &mut Device<Self::Data>, uv: i32) -> Result {
> +        let data = reg.data();
> +        let fields = &mut data.lock().fields;
> +
> +        let quot = (uv - 600000) / 6250;
> +        let rem = (uv - 600000) % 6250;
> +        let selector = if rem > 0 { quot + 1 } else { quot };
> +
> +        progvsel1::voutvsel1::write(fields, selector as _)
> +    }
> +
> +    fn set_suspend_enable(reg: &mut Device<Self::Data>) -> Result {
> +        let data = reg.data();
> +        let fields = &mut data.lock().fields;
> +
> +        progvsel1::envsel1::set(fields)?;
> +        command::vselgt::clear(fields)
> +    }
> +
> +    fn set_suspend_disable(reg: &mut Device<Self::Data>) -> Result {
> +        let data = reg.data();
> +        let fields = &mut data.lock().fields;
> +
> +        progvsel1::envsel1::clear(fields)?;
> +        command::vselgt::set(fields)
> +    }
> +
> +    fn set_suspend_mode(reg: &mut Device<Self::Data>, mode: Mode) -> Result {
> +        let data = reg.data();
> +        let fields = &mut data.lock().fields;
> +
> +        match mode {
> +            Mode::Normal => command::pwmvsel1::clear(fields),
> +            Mode::Fast => command::pwmvsel1::set(fields),
> +            _ => Err(ENOTSUPP),
> +        }
> +    }
> +}
> 


  reply	other threads:[~2024-12-19 10:19 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-18 23:36 [PATCH 0/9] Regulator driver with I2C/Regmap Rust abstractions Fabien Parent
2024-12-18 23:36 ` [PATCH 1/9] rust: i2c: add basic I2C client abstraction Fabien Parent
2024-12-19 13:03   ` Rob Herring
2024-12-19 15:33     ` Fabien Parent
2024-12-18 23:36 ` [PATCH 2/9] rust: add abstraction for regmap Fabien Parent
2024-12-20 13:16   ` Mark Brown
2024-12-18 23:36 ` [PATCH 3/9] rust: error: add declaration for ENOTRECOVERABLE error Fabien Parent
2024-12-18 23:36 ` [PATCH 4/9] rust: regulator: add abstraction for Regulator's modes Fabien Parent
2024-12-18 23:36 ` [PATCH 5/9] rust: regulator: add Regulator Driver abstraction Fabien Parent
2024-12-19 10:26   ` Danilo Krummrich
2024-12-19 16:00     ` Fabien Parent
2024-12-19 18:58       ` Mark Brown
2024-12-18 23:36 ` [PATCH 6/9] rust: regulator: add support for regmap Fabien Parent
2024-12-18 23:36 ` [PATCH 7/9] dt-bindings: regulator: add binding for ncv6336 regulator Fabien Parent
2024-12-19  9:28   ` Krzysztof Kozlowski
2024-12-19 16:13     ` Fabien Parent
2024-12-21 20:20       ` Krzysztof Kozlowski
2024-12-18 23:36 ` [PATCH 8/9] regulator: add driver " Fabien Parent
2024-12-19 10:19   ` Dirk Behme [this message]
2024-12-20 14:50   ` Mark Brown
2024-12-18 23:36 ` [PATCH 9/9] arm64: dts: qcom: apq8039-t2: add node " Fabien Parent

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=907b470c-3b24-41ba-9b6d-c07caa30ee00@gmail.com \
    --to=dirk.behme@gmail.com \
    --cc=a.hindborg@kernel.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=andersson@kernel.org \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=broonie@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=fabien.parent@linaro.org \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=konradybcio@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=parent.f@gmail.com \
    --cc=rafael@kernel.org \
    --cc=robh@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=saravanak@google.com \
    --cc=tmgross@umich.edu \
    --cc=vinod.koul@linaro.org \
    --cc=wsa+renesas@sang-engineering.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.