linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: ttynkkynen@nvidia.com (Tuomas Tynkkynen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 02/16] regulator: Add helpers for low-level register access
Date: Mon, 21 Jul 2014 18:38:48 +0300	[thread overview]
Message-ID: <1405957142-19416-3-git-send-email-ttynkkynen@nvidia.com> (raw)
In-Reply-To: <1405957142-19416-1-git-send-email-ttynkkynen@nvidia.com>

Add helper functions that allow regulator consumers to obtain low-level
details about the regulator hardware, like the voltage selector register
address and such. These details can be useful when configuring hardware
or firmware that want to do low-level access to regulators, with no
involvement from the kernel.

The use-case for Tegra is a voltage-controlled oscillator clocksource
which has control logic to change the supply voltage via I2C to achieve
a desired output clock rate.

Signed-off-by: Tuomas Tynkkynen <ttynkkynen@nvidia.com>
---
 Documentation/power/regulator/consumer.txt | 35 +++++++++++++++
 drivers/regulator/core.c                   | 71 ++++++++++++++++++++++++++++++
 include/linux/regulator/consumer.h         | 26 +++++++++++
 3 files changed, 132 insertions(+)

diff --git a/Documentation/power/regulator/consumer.txt b/Documentation/power/regulator/consumer.txt
index 55c4175..81c0e2b 100644
--- a/Documentation/power/regulator/consumer.txt
+++ b/Documentation/power/regulator/consumer.txt
@@ -180,3 +180,38 @@ int regulator_unregister_notifier(struct regulator *regulator,
 
 Regulators use the kernel notifier framework to send event to their interested
 consumers.
+
+7. Regulator Direct Register Access
+===================================
+Some kinds of power management hardware or firmware are designed such that
+they need to do low-level hardware access to regulators, with no involvement
+from the kernel. Examples of such devices are:
+
+- clocksource with a voltage-controlled oscillator and control logic to change
+  the supply voltage over I2C to achieve a desired output clock rate
+- thermal management firmware that can issue an arbitrary I2C transaction to
+  perform system poweroff during overtemperature conditions
+
+To set up such a device/firmware, various parameters like I2C address of the
+regulator, addresses of various regulator registers etc. need to be configured
+to it. The regulator framework provides the following helpers for querying
+these details.
+
+Bus-specific details, like I2C addresses or transfer rates are handled by the
+regmap framework. To get the regulator's regmap (if supported), use :-
+
+struct regmap *regulator_get_regmap(struct regulator *regulator);
+
+To obtain the hardware register offset and bitmask for the regulator's voltage
+selector register, use :-
+
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+					 unsigned *vsel_reg,
+					 unsigned *vsel_mask);
+
+To convert a regulator framework voltage selector code (used by
+regulator_list_voltage) to a hardware-specific voltage selector that can be
+directly written to the voltage selector register, use :-
+
+int regulator_list_hardware_vsel(struct regulator *regulator,
+				 unsigned selector);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c563d93..69c9c08 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2228,6 +2228,77 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
 EXPORT_SYMBOL_GPL(regulator_list_voltage);
 
 /**
+ * regulator_get_regmap - get the regulator's register map
+ * @regulator: regulator source
+ *
+ * Returns the register map for the given regulator, or an ERR_PTR value
+ * if the regulator doesn't use regmap.
+ */
+struct regmap *regulator_get_regmap(struct regulator *regulator)
+{
+	struct regmap *map = regulator->rdev->regmap;
+
+	return map ? map : ERR_PTR(-EOPNOTSUPP);
+}
+
+/**
+ * regulator_get_hardware_vsel_register - get the HW voltage selector register
+ * @regulator: regulator source
+ * @vsel_reg: voltage selector register, output parameter
+ * @vsel_mask: mask for voltage selector bitfield, output parameter
+ *
+ * Returns the hardware register offset and bitmask used for setting the
+ * regulator voltage. This might be useful when configuring voltage-scaling
+ * hardware or firmware that can make I2C requests behind the kernel's back,
+ * for example.
+ *
+ * On success, the output parameters @vsel_reg and @vsel_mask are filled in
+ * and 0 is returned, otherwise a negative errno is returned.
+ */
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+					 unsigned *vsel_reg,
+					 unsigned *vsel_mask)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+	struct regulator_ops	*ops = rdev->desc->ops;
+
+	if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+		return -EOPNOTSUPP;
+
+	 *vsel_reg = rdev->desc->vsel_reg;
+	 *vsel_mask = rdev->desc->vsel_mask;
+
+	 return 0;
+}
+EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register);
+
+/**
+ * regulator_list_hardware_vsel - get the HW-specific register value for a selector
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ *
+ * Converts the selector to a hardware-specific voltage selector that can be
+ * directly written to the regulator registers. The address of the voltage
+ * register can be determined by calling @regulator_get_hardware_vsel_register.
+ *
+ * On error a negative errno is returned.
+ */
+int regulator_list_hardware_vsel(struct regulator *regulator,
+				 unsigned selector)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+	struct regulator_ops	*ops = rdev->desc->ops;
+
+	if (selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+	if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+		return -EOPNOTSUPP;
+
+	return selector;
+}
+EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel);
+
+/**
  * regulator_get_linear_step - return the voltage step size between VSEL values
  * @regulator: regulator source
  *
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 14ec18d..6bb5002 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -37,6 +37,7 @@
 
 struct device;
 struct notifier_block;
+struct regmap;
 
 /*
  * Regulator operating modes.
@@ -215,6 +216,13 @@ int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
 
 int regulator_allow_bypass(struct regulator *regulator, bool allow);
 
+struct regmap *regulator_get_regmap(struct regulator *regulator);
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+					 unsigned *vsel_reg,
+					 unsigned *vsel_mask);
+int regulator_list_hardware_vsel(struct regulator *regulator,
+				 unsigned selector);
+
 /* regulator notifier block */
 int regulator_register_notifier(struct regulator *regulator,
 			      struct notifier_block *nb);
@@ -457,6 +465,24 @@ static inline int regulator_allow_bypass(struct regulator *regulator,
 	return 0;
 }
 
+struct regmap *regulator_get_regmap(struct regulator *regulator)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+					 unsigned *vsel_reg,
+					 unsigned *vsel_mask)
+{
+	return -EOPNOTSUPP;
+}
+
+int regulator_list_hardware_vsel(struct regulator *regulator,
+				 unsigned selector)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int regulator_register_notifier(struct regulator *regulator,
 			      struct notifier_block *nb)
 {
-- 
1.8.1.5

  parent reply	other threads:[~2014-07-21 15:38 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-21 15:38 [PATCH v2 00/16] Tegra124 CL-DVFS / DFLL clocksource, plus cpufreq Tuomas Tynkkynen
2014-07-21 15:38 ` [PATCH v2 01/16] regmap: Add regmap_get_device Tuomas Tynkkynen
2014-07-25 17:34   ` Mark Brown
2014-07-25 17:43   ` Mark Brown
2014-07-21 15:38 ` Tuomas Tynkkynen [this message]
2014-07-25 17:48   ` [PATCH v2 02/16] regulator: Add helpers for low-level register access Mark Brown
2014-07-21 15:38 ` [PATCH v2 03/16] clk: tegra: Add binding for the Tegra124 DFLL clocksource Tuomas Tynkkynen
2014-07-21 15:38 ` [PATCH v2 04/16] clk: tegra: Add library for the DFLL clock source (open-loop mode) Tuomas Tynkkynen
2014-08-18  6:05   ` Vince Hsu
2014-07-21 15:38 ` [PATCH v2 05/16] clk: tegra: Add closed loop support for the DFLL Tuomas Tynkkynen
2014-08-18  6:08   ` Vince Hsu
2014-07-21 15:38 ` [PATCH v2 06/16] clk: tegra: Add functions for parsing CVB tables Tuomas Tynkkynen
2014-07-21 15:38 ` [PATCH v2 07/16] clk: tegra: Add DFLL DVCO reset control for Tegra124 Tuomas Tynkkynen
2014-07-21 15:38 ` [PATCH v2 08/16] clk: tegra: Add Tegra124 DFLL clocksource platform driver Tuomas Tynkkynen
2014-08-12 10:37   ` Vince Hsu
2014-07-21 15:38 ` [PATCH v2 09/16] clk: tegra: Save/restore CCLKG_BURST_POLICY on suspend Tuomas Tynkkynen
2014-07-21 15:38 ` [PATCH v2 10/16] clk: tegra: Add the DFLL as a possible parent of the cclk_g clock Tuomas Tynkkynen
2014-07-21 15:38 ` [PATCH v2 11/16] ARM: tegra: Add the DFLL to Tegra124 device tree Tuomas Tynkkynen
2014-07-21 15:38 ` [PATCH v2 12/16] ARM: tegra: Enable the DFLL on the Jetson TK1 Tuomas Tynkkynen
2014-07-21 15:38 ` [PATCH v2 13/16] cpufreq: tegra124: Add device tree bindings Tuomas Tynkkynen
2014-07-21 15:39 ` [PATCH v2 14/16] cpufreq: Add cpufreq driver for Tegra124 Tuomas Tynkkynen
2014-07-22  0:49   ` Rafael J. Wysocki
2014-07-23  4:44   ` Viresh Kumar
2014-07-23  6:54     ` Thierry Reding
2014-07-23  6:58       ` Viresh Kumar
2014-07-23  7:24         ` Thierry Reding
2014-07-23  8:25           ` Viresh Kumar
2014-07-23 13:51             ` Thierry Reding
2014-07-23 11:57     ` Tuomas Tynkkynen
2014-07-23 16:50       ` Viresh Kumar
2014-07-23 19:17         ` Tuomas Tynkkynen
2014-07-24  0:13           ` Viresh Kumar
2014-07-24  9:10             ` Thierry Reding
2014-07-23  7:09   ` Thierry Reding
2014-07-23 12:35     ` Tuomas Tynkkynen
2014-07-23 13:59       ` Thierry Reding
2014-07-23  7:21   ` pramod gurav
2014-07-21 15:39 ` [PATCH v2 15/16] ARM: tegra: Add entries for cpufreq on Tegra124 Tuomas Tynkkynen
2014-07-21 15:39 ` [PATCH v2 16/16] ARM: tegra: Update defconfig for tegra124-cpufreq Tuomas Tynkkynen

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=1405957142-19416-3-git-send-email-ttynkkynen@nvidia.com \
    --to=ttynkkynen@nvidia.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).