From: maramaopercheseimorto@gmail.com (Alberto Panizzo)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] regulator: mc13783: consider Power Gates as digital regulators.
Date: Mon, 18 Jan 2010 17:02:03 +0100 [thread overview]
Message-ID: <1263830523.3632.22.camel@realization> (raw)
GPO regulators are digital outputs that can be enabled or disabled by a
dedicated bit in mc13783 POWERMISC register.
In this family can be count in also Power Gates (PWGT1 and 2): enabled by
a dedicated pin a Power Gate is an hardware driven supply where the output
(PWGTnDRV) follow this law:
Bit PWGTxSPIEN | Pin PWGTxEN | PWGTxDRV | Read Back
0 = default | | | PWGTxSPIEN
---------------+-------------+----------+------------
1 | x | Low | 0
0 | 0 | High | 1
0 | 1 | Low | 0
As read back value of control bit reflects the PWGTxDRV state and not the
control value previously written, a dedicated function to manage bits of
POWERMISC register is created and the state of PWGTxEN bits is stored in memory.
All POWERMISC users _must_ make use of the new function to not accidentally
disable Power Gates supplies.
Signed-off-by: Alberto Panizzo <maramaopercheseimorto@gmail.com>
---
drivers/regulator/mc13783-regulator.c | 97 ++++++++++++++++++++++++++++++++-
include/linux/mfd/mc13783.h | 2 +
2 files changed, 98 insertions(+), 1 deletions(-)
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index a40e35a..8570fce 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -82,6 +82,10 @@
#define MC13783_REG_POWERMISC_GPO2EN (1 << 8)
#define MC13783_REG_POWERMISC_GPO3EN (1 << 10)
#define MC13783_REG_POWERMISC_GPO4EN (1 << 12)
+#define MC13783_REG_POWERMISC_PWGTSPI_M (3 << 15)
+#define MC13783_REG_POWERMISC_PWGT1SPIEN (1 << 15)
+#define MC13783_REG_POWERMISC_PWGT2SPIEN (1 << 16)
+
struct mc13783_regulator {
struct regulator_desc desc;
@@ -163,6 +167,7 @@ static const int const mc13783_vrf_val[] = {
static struct regulator_ops mc13783_regulator_ops;
static struct regulator_ops mc13783_fixed_regulator_ops;
+static struct regulator_ops mc13783_regulator_ops_gpo;
#define MC13783_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages) \
[MC13783_ ## prefix ## _ ## _name] = { \
@@ -201,7 +206,7 @@ static struct regulator_ops mc13783_fixed_regulator_ops;
[MC13783_ ## prefix ## _ ## _name] = { \
.desc = { \
.name = #prefix "_" #_name, \
- .ops = &mc13783_regulator_ops, \
+ .ops = &mc13783_regulator_ops_gpo, \
.type = REGULATOR_VOLTAGE, \
.id = MC13783_ ## prefix ## _ ## _name, \
.owner = THIS_MODULE, \
@@ -253,6 +258,8 @@ static struct mc13783_regulator mc13783_regulators[] = {
MC13783_GPO_DEFINE(REGU, GPO2, POWERMISC),
MC13783_GPO_DEFINE(REGU, GPO3, POWERMISC),
MC13783_GPO_DEFINE(REGU, GPO4, POWERMISC),
+ MC13783_GPO_DEFINE(REGU, PWGT1SPI, POWERMISC),
+ MC13783_GPO_DEFINE(REGU, PWGT2SPI, POWERMISC),
};
struct mc13783_regulator_priv {
@@ -445,6 +452,94 @@ static struct regulator_ops mc13783_fixed_regulator_ops = {
.get_voltage = mc13783_fixed_regulator_get_voltage,
};
+int mc13783_state_powermisc_pwgt;
+int mc13783_reg_rmw_powermisc(struct mc13783 *mc13783, u32 mask, u32 val)
+{
+ int ret;
+ u32 valread;
+
+ BUG_ON(val & ~mask);
+
+ /* Update the stored state for Power Gates.
+ * As from specs the meaning is inverted (0: en, 1: dis) */
+ if (mask & MC13783_REG_POWERMISC_PWGTSPI_M)
+ mc13783_state_powermisc_pwgt =
+ (mc13783_state_powermisc_pwgt & ~mask) |
+ ((val ^ mask) & MC13783_REG_POWERMISC_PWGTSPI_M);
+
+ ret = mc13783_reg_read(mc13783, MC13783_REG_POWERMISC, &valread);
+ if (ret)
+ return ret;
+
+ valread = (valread & ~mask) | val;
+
+ /* Re propose the stored state for Power Gates */
+ valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
+ mc13783_state_powermisc_pwgt;
+
+ return mc13783_reg_write(mc13783, MC13783_REG_POWERMISC, valread);
+}
+
+static int mc13783_regulator_enable_gpo(struct regulator_dev *rdev)
+{
+ struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+ int ret;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+ mc13783_lock(priv->mc13783);
+ ret = mc13783_reg_rmw_powermisc(priv->mc13783,
+ mc13783_regulators[id].enable_bit,
+ mc13783_regulators[id].enable_bit);
+ mc13783_unlock(priv->mc13783);
+
+ return ret;
+}
+
+static int mc13783_regulator_disable_gpo(struct regulator_dev *rdev)
+{
+ struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+ int ret;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+ mc13783_lock(priv->mc13783);
+ ret = mc13783_reg_rmw_powermisc(priv->mc13783,
+ mc13783_regulators[id].enable_bit, 0);
+ mc13783_unlock(priv->mc13783);
+
+ return ret;
+}
+
+static int mc13783_regulator_is_enabled_gpo(struct regulator_dev *rdev)
+{
+ struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int ret, id = rdev_get_id(rdev);
+ unsigned int val;
+
+ mc13783_lock(priv->mc13783);
+ ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
+ mc13783_unlock(priv->mc13783);
+
+ /* Power Gates state is stored in mc13783_state_powermisc_pwgt
+ * where the meaning is inverted */
+ val = (val & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
+ (mc13783_state_powermisc_pwgt ^ MC13783_REG_POWERMISC_PWGTSPI_M);
+
+ if (ret)
+ return ret;
+
+ return (val & mc13783_regulators[id].enable_bit) != 0;
+}
+
+static struct regulator_ops mc13783_regulator_ops_gpo = {
+ .enable = mc13783_regulator_enable_gpo,
+ .disable = mc13783_regulator_disable_gpo,
+ .is_enabled = mc13783_regulator_is_enabled_gpo,
+};
+
static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
{
struct mc13783_regulator_priv *priv;
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
index 3568040..94cb51a 100644
--- a/include/linux/mfd/mc13783.h
+++ b/include/linux/mfd/mc13783.h
@@ -108,6 +108,8 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
#define MC13783_REGU_V2 28
#define MC13783_REGU_V3 29
#define MC13783_REGU_V4 30
+#define MC13783_REGU_PWGT1SPI 31
+#define MC13783_REGU_PWGT2SPI 32
#define MC13783_IRQ_ADCDONE 0
#define MC13783_IRQ_ADCBISDONE 1
--
1.6.3.3
WARNING: multiple messages have this Message-ID (diff)
From: Alberto Panizzo <maramaopercheseimorto@gmail.com>
To: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
"Samuel Ortiz" <sameo@linux.intel.com>,
"Liam Girdwood" <lrg@slimlogic.co.uk>,
"Sascha linux-arm" <s.hauer@pengutronix.de>,
linux-kernel <linux-kernel@vger.kernel.org>,
linux-arm-kernel-infradead <linux-arm-kernel@lists.infradead.org>
Subject: [PATCH] regulator: mc13783: consider Power Gates as digital regulators.
Date: Mon, 18 Jan 2010 17:02:03 +0100 [thread overview]
Message-ID: <1263830523.3632.22.camel@realization> (raw)
GPO regulators are digital outputs that can be enabled or disabled by a
dedicated bit in mc13783 POWERMISC register.
In this family can be count in also Power Gates (PWGT1 and 2): enabled by
a dedicated pin a Power Gate is an hardware driven supply where the output
(PWGTnDRV) follow this law:
Bit PWGTxSPIEN | Pin PWGTxEN | PWGTxDRV | Read Back
0 = default | | | PWGTxSPIEN
---------------+-------------+----------+------------
1 | x | Low | 0
0 | 0 | High | 1
0 | 1 | Low | 0
As read back value of control bit reflects the PWGTxDRV state and not the
control value previously written, a dedicated function to manage bits of
POWERMISC register is created and the state of PWGTxEN bits is stored in memory.
All POWERMISC users _must_ make use of the new function to not accidentally
disable Power Gates supplies.
Signed-off-by: Alberto Panizzo <maramaopercheseimorto@gmail.com>
---
drivers/regulator/mc13783-regulator.c | 97 ++++++++++++++++++++++++++++++++-
include/linux/mfd/mc13783.h | 2 +
2 files changed, 98 insertions(+), 1 deletions(-)
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index a40e35a..8570fce 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -82,6 +82,10 @@
#define MC13783_REG_POWERMISC_GPO2EN (1 << 8)
#define MC13783_REG_POWERMISC_GPO3EN (1 << 10)
#define MC13783_REG_POWERMISC_GPO4EN (1 << 12)
+#define MC13783_REG_POWERMISC_PWGTSPI_M (3 << 15)
+#define MC13783_REG_POWERMISC_PWGT1SPIEN (1 << 15)
+#define MC13783_REG_POWERMISC_PWGT2SPIEN (1 << 16)
+
struct mc13783_regulator {
struct regulator_desc desc;
@@ -163,6 +167,7 @@ static const int const mc13783_vrf_val[] = {
static struct regulator_ops mc13783_regulator_ops;
static struct regulator_ops mc13783_fixed_regulator_ops;
+static struct regulator_ops mc13783_regulator_ops_gpo;
#define MC13783_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages) \
[MC13783_ ## prefix ## _ ## _name] = { \
@@ -201,7 +206,7 @@ static struct regulator_ops mc13783_fixed_regulator_ops;
[MC13783_ ## prefix ## _ ## _name] = { \
.desc = { \
.name = #prefix "_" #_name, \
- .ops = &mc13783_regulator_ops, \
+ .ops = &mc13783_regulator_ops_gpo, \
.type = REGULATOR_VOLTAGE, \
.id = MC13783_ ## prefix ## _ ## _name, \
.owner = THIS_MODULE, \
@@ -253,6 +258,8 @@ static struct mc13783_regulator mc13783_regulators[] = {
MC13783_GPO_DEFINE(REGU, GPO2, POWERMISC),
MC13783_GPO_DEFINE(REGU, GPO3, POWERMISC),
MC13783_GPO_DEFINE(REGU, GPO4, POWERMISC),
+ MC13783_GPO_DEFINE(REGU, PWGT1SPI, POWERMISC),
+ MC13783_GPO_DEFINE(REGU, PWGT2SPI, POWERMISC),
};
struct mc13783_regulator_priv {
@@ -445,6 +452,94 @@ static struct regulator_ops mc13783_fixed_regulator_ops = {
.get_voltage = mc13783_fixed_regulator_get_voltage,
};
+int mc13783_state_powermisc_pwgt;
+int mc13783_reg_rmw_powermisc(struct mc13783 *mc13783, u32 mask, u32 val)
+{
+ int ret;
+ u32 valread;
+
+ BUG_ON(val & ~mask);
+
+ /* Update the stored state for Power Gates.
+ * As from specs the meaning is inverted (0: en, 1: dis) */
+ if (mask & MC13783_REG_POWERMISC_PWGTSPI_M)
+ mc13783_state_powermisc_pwgt =
+ (mc13783_state_powermisc_pwgt & ~mask) |
+ ((val ^ mask) & MC13783_REG_POWERMISC_PWGTSPI_M);
+
+ ret = mc13783_reg_read(mc13783, MC13783_REG_POWERMISC, &valread);
+ if (ret)
+ return ret;
+
+ valread = (valread & ~mask) | val;
+
+ /* Re propose the stored state for Power Gates */
+ valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
+ mc13783_state_powermisc_pwgt;
+
+ return mc13783_reg_write(mc13783, MC13783_REG_POWERMISC, valread);
+}
+
+static int mc13783_regulator_enable_gpo(struct regulator_dev *rdev)
+{
+ struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+ int ret;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+ mc13783_lock(priv->mc13783);
+ ret = mc13783_reg_rmw_powermisc(priv->mc13783,
+ mc13783_regulators[id].enable_bit,
+ mc13783_regulators[id].enable_bit);
+ mc13783_unlock(priv->mc13783);
+
+ return ret;
+}
+
+static int mc13783_regulator_disable_gpo(struct regulator_dev *rdev)
+{
+ struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+ int ret;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+ mc13783_lock(priv->mc13783);
+ ret = mc13783_reg_rmw_powermisc(priv->mc13783,
+ mc13783_regulators[id].enable_bit, 0);
+ mc13783_unlock(priv->mc13783);
+
+ return ret;
+}
+
+static int mc13783_regulator_is_enabled_gpo(struct regulator_dev *rdev)
+{
+ struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int ret, id = rdev_get_id(rdev);
+ unsigned int val;
+
+ mc13783_lock(priv->mc13783);
+ ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
+ mc13783_unlock(priv->mc13783);
+
+ /* Power Gates state is stored in mc13783_state_powermisc_pwgt
+ * where the meaning is inverted */
+ val = (val & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
+ (mc13783_state_powermisc_pwgt ^ MC13783_REG_POWERMISC_PWGTSPI_M);
+
+ if (ret)
+ return ret;
+
+ return (val & mc13783_regulators[id].enable_bit) != 0;
+}
+
+static struct regulator_ops mc13783_regulator_ops_gpo = {
+ .enable = mc13783_regulator_enable_gpo,
+ .disable = mc13783_regulator_disable_gpo,
+ .is_enabled = mc13783_regulator_is_enabled_gpo,
+};
+
static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
{
struct mc13783_regulator_priv *priv;
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
index 3568040..94cb51a 100644
--- a/include/linux/mfd/mc13783.h
+++ b/include/linux/mfd/mc13783.h
@@ -108,6 +108,8 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
#define MC13783_REGU_V2 28
#define MC13783_REGU_V3 29
#define MC13783_REGU_V4 30
+#define MC13783_REGU_PWGT1SPI 31
+#define MC13783_REGU_PWGT2SPI 32
#define MC13783_IRQ_ADCDONE 0
#define MC13783_IRQ_ADCBISDONE 1
--
1.6.3.3
next reply other threads:[~2010-01-18 16:02 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-18 16:02 Alberto Panizzo [this message]
2010-01-18 16:02 ` [PATCH] regulator: mc13783: consider Power Gates as digital regulators Alberto Panizzo
2010-01-18 16:32 ` Mark Brown
2010-01-18 16:32 ` Mark Brown
2010-01-18 17:26 ` Alberto Panizzo
2010-01-18 17:26 ` Alberto Panizzo
2010-01-18 17:37 ` Mark Brown
2010-01-18 17:37 ` Mark Brown
[not found] ` <1263834473.3632.31.camel@realization>
[not found] ` <20100118172002.GB6889@rakim.wolfsonmicro.main>
2010-01-18 17:50 ` Alberto Panizzo
2010-01-18 17:50 ` Alberto Panizzo
2010-01-18 17:56 ` Mark Brown
2010-01-18 17:56 ` Mark Brown
2010-01-18 19:04 ` Uwe Kleine-König
2010-01-18 19:04 ` Uwe Kleine-König
2010-01-18 21:01 ` Alberto Panizzo
2010-01-18 21:01 ` Alberto Panizzo
2010-01-19 10:26 ` Liam Girdwood
2010-01-19 10:26 ` Liam Girdwood
2010-01-19 11:12 ` Alberto Panizzo
2010-01-19 11:12 ` Alberto Panizzo
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=1263830523.3632.22.camel@realization \
--to=maramaopercheseimorto@gmail.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 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.