diff mbox

[V2,3/6] power: mxs_power: add driver for mxs power subsystem

Message ID 1430346747-28728-4-git-send-email-stefan.wahren@i2se.com (mailing list archive)
State New, archived
Headers show

Commit Message

Stefan Wahren April 29, 2015, 10:32 p.m. UTC
This patch adds a minimal driver for the Freescale i.MX23, i.MX28
power subsystem. It's required to trigger the probing of the underlying
drivers like on-chip regulators.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/power/Kconfig     |    8 +++
 drivers/power/Makefile    |    1 +
 drivers/power/mxs_power.c |  136 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+)
 create mode 100644 drivers/power/mxs_power.c

Comments

Sebastian Reichel May 23, 2015, 5:41 p.m. UTC | #1
Hi,

On Wed, Apr 29, 2015 at 10:32:24PM +0000, Stefan Wahren wrote:
> This patch adds a minimal driver for the Freescale i.MX23, i.MX28
> power subsystem. It's required to trigger the probing of the underlying
> drivers like on-chip regulators.

I'm not sure what you need the power supply class for. I see only
one property (ac connected), which is constant. Maybe just drop
the power supply stuff?

This would leave an almost empty driver, which just sets a single
register at probe time and probes more drivers. That would probably
be more fitting for the MFD subsystem.

-- Sebastian
Stefan Wahren May 27, 2015, 7:12 a.m. UTC | #2
Hi Sebastian,

Am 23.05.2015 um 19:41 schrieb Sebastian Reichel:
> Hi,
>
> On Wed, Apr 29, 2015 at 10:32:24PM +0000, Stefan Wahren wrote:
>> This patch adds a minimal driver for the Freescale i.MX23, i.MX28
>> power subsystem. It's required to trigger the probing of the underlying
>> drivers like on-chip regulators.
> I'm not sure what you need the power supply class for. I see only
> one property (ac connected), which is constant. Maybe just drop
> the power supply stuff?

those SoCs could be powered by 3 different sources:
- 5V wall
- USB
- battery

I choose the first one as a base, because it's the simplest one.
Unfortunately i don't have the time to implement all of them.

The Freescale downstream kernel (based on 2.6.35) [1] has a driver to
handle all MXS power sources. But i think a clean implementation from
the scratch would be necessary for mainline.

> This would leave an almost empty driver, which just sets a single
> register at probe time and probes more drivers. That would probably
> be more fitting for the MFD subsystem.

I don't have any problems with fitting the driver to MFD.

> -- Sebastian

[1] -
http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/power/mxs/linux.c?h=imx_2.6.35_maintain
Sebastian Reichel May 27, 2015, 1:51 p.m. UTC | #3
Hi Stefan,

On Wed, May 27, 2015 at 09:12:48AM +0200, Stefan Wahren wrote:
> Am 23.05.2015 um 19:41 schrieb Sebastian Reichel:
> > On Wed, Apr 29, 2015 at 10:32:24PM +0000, Stefan Wahren wrote:
> >> This patch adds a minimal driver for the Freescale i.MX23, i.MX28
> >> power subsystem. It's required to trigger the probing of the underlying
> >> drivers like on-chip regulators.
> > I'm not sure what you need the power supply class for. I see only
> > one property (ac connected), which is constant. Maybe just drop
> > the power supply stuff?
> 
> those SoCs could be powered by 3 different sources:
> - 5V wall
> - USB
> - battery
> 
> I choose the first one as a base, because it's the simplest one.
> Unfortunately i don't have the time to implement all of them.

From what I can see the driver does not implement the 5V wall
charger handling. It simply assumes, that the 5V wall charger
is there.

While you can skip implementation of battery connection check
you should make sure, that AC is actually connected.

> The Freescale downstream kernel (based on 2.6.35) [1] has a driver to
> handle all MXS power sources. But i think a clean implementation from
> the scratch would be necessary for mainline.
>
> > This would leave an almost empty driver, which just sets a single
> > register at probe time and probes more drivers. That would probably
> > be more fitting for the MFD subsystem.
> 
> I don't have any problems with fitting the driver to MFD.

You can keep in in drivers/power. From your code I assumed there
would simply be a fixed AC connection and nothing else.

> > -- Sebastian
> 
> [1] -
> http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/power/mxs/linux.c?h=imx_2.6.35_maintain

-- Sebastian
Stefan Wahren May 27, 2015, 4:34 p.m. UTC | #4
Hi Sebastian,

Am 27.05.2015 um 15:51 schrieb Sebastian Reichel:
> Hi Stefan,
>
> On Wed, May 27, 2015 at 09:12:48AM +0200, Stefan Wahren wrote:
>> Am 23.05.2015 um 19:41 schrieb Sebastian Reichel:
>>> On Wed, Apr 29, 2015 at 10:32:24PM +0000, Stefan Wahren wrote:
>>>> This patch adds a minimal driver for the Freescale i.MX23, i.MX28
>>>> power subsystem. It's required to trigger the probing of the underlying
>>>> drivers like on-chip regulators.
>>> I'm not sure what you need the power supply class for. I see only
>>> one property (ac connected), which is constant. Maybe just drop
>>> the power supply stuff?
>> those SoCs could be powered by 3 different sources:
>> - 5V wall
>> - USB
>> - battery
>>
>> I choose the first one as a base, because it's the simplest one.
>> Unfortunately i don't have the time to implement all of them.
> From what I can see the driver does not implement the 5V wall
> charger handling. It simply assumes, that the 5V wall charger
> is there.

the driver consists of multiple files in the mxs sub directory.
I linked to the main file to reduce search effort. The battery
handling incl. charging should be implemented in ddi_power_battery.c

From my understanding it's not possible to determine where the 5V
exactly come from (either 5V wall plug or USB). The driver simply uses
the USB PHY state.

>
> While you can skip implementation of battery connection check
> you should make sure, that AC is actually connected.

Do you refer to the right state of property POWER_SUPPLY_PROP_ONLINE or
driver probing?

Stefan
Sebastian Reichel May 28, 2015, 5:38 p.m. UTC | #5
Hi,

On Wed, May 27, 2015 at 06:34:01PM +0200, Stefan Wahren wrote:
> the driver consists of multiple files in the mxs sub directory.
> I linked to the main file to reduce search effort. The battery
> handling incl. charging should be implemented in ddi_power_battery.c
>
> From my understanding it's not possible to determine where the 5V
> exactly come from (either 5V wall plug or USB). The driver simply uses
> the USB PHY state.

Yes, but your driver does not even check, that there is 5V. It even
reports AC online if neither USB nor wall charger is connected.

> > While you can skip implementation of battery connection check
> > you should make sure, that AC is actually connected.
> 
> Do you refer to the right state of property
> POWER_SUPPLY_PROP_ONLINE or driver probing?

I'm referring to the right state.

-- Sebastian
diff mbox

Patch

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 4091fb0..0fcc158 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -43,6 +43,14 @@  config MAX8925_POWER
 	  Say Y here to enable support for the battery charger in the Maxim
 	  MAX8925 PMIC.
 
+config MXS_POWER
+	tristate "Freescale MXS power subsystem support"
+	depends on ARCH_MXS || COMPILE_TEST
+	help
+	  Say Y here to enable support for the Freescale i.MX23/i.MX28
+	  power subsystem. This is a requirement to get access to on-chip
+	  regulators, battery charger and many more.
+
 config WM831X_BACKUP
 	tristate "WM831X backup battery charger support"
 	depends on MFD_WM831X
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b7b0181..8edcad7 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -10,6 +10,7 @@  obj-$(CONFIG_GENERIC_ADC_BATTERY)	+= generic-adc-battery.o
 obj-$(CONFIG_PDA_POWER)		+= pda_power.o
 obj-$(CONFIG_APM_POWER)		+= apm_power.o
 obj-$(CONFIG_MAX8925_POWER)	+= max8925_power.o
+obj-$(CONFIG_MXS_POWER)		+= mxs_power.o
 obj-$(CONFIG_WM831X_BACKUP)	+= wm831x_backup.o
 obj-$(CONFIG_WM831X_POWER)	+= wm831x_power.o
 obj-$(CONFIG_WM8350_POWER)	+= wm8350_power.o
diff --git a/drivers/power/mxs_power.c b/drivers/power/mxs_power.c
new file mode 100644
index 0000000..669bfb1
--- /dev/null
+++ b/drivers/power/mxs_power.c
@@ -0,0 +1,136 @@ 
+/*
+ * Freescale MXS power subsystem
+ *
+ * Copyright (C) 2014 Stefan Wahren
+ *
+ * Inspired by imx-bootlets
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/stmp_device.h>
+#include <linux/types.h>
+
+#define BM_POWER_CTRL_POLARITY_VBUSVALID	BIT(5)
+#define BM_POWER_CTRL_VBUSVALID_IRQ		BIT(4)
+#define BM_POWER_CTRL_ENIRQ_VBUS_VALID		BIT(3)
+
+#define HW_POWER_5VCTRL_OFFSET	0x10
+
+#define BM_POWER_5VCTRL_VBUSVALID_THRESH	(7 << 8)
+#define BM_POWER_5VCTRL_PWDN_5VBRNOUT		BIT(7)
+#define BM_POWER_5VCTRL_ENABLE_LINREG_ILIMIT	BIT(6)
+#define BM_POWER_5VCTRL_VBUSVALID_5VDETECT	BIT(4)
+
+#define HW_POWER_5VCTRL_VBUSVALID_THRESH_4_40V	(5 << 8)
+
+struct mxs_power_data {
+	void __iomem *base_addr;
+	struct power_supply *ac;
+};
+
+static enum power_supply_property mxs_power_ac_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+};
+
+static int mxs_power_ac_get_property(struct power_supply *psy,
+				     enum power_supply_property psp,
+				     union power_supply_propval *val)
+{
+	int ret = 0;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = 1;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static const struct of_device_id of_mxs_power_match[] = {
+	{ .compatible = "fsl,imx23-power" },
+	{ .compatible = "fsl,imx28-power" },
+	{ /* end */ }
+};
+MODULE_DEVICE_TABLE(of, of_mxs_power_match);
+
+static const struct power_supply_desc ac_desc = {
+	.properties	= mxs_power_ac_props,
+	.num_properties	= ARRAY_SIZE(mxs_power_ac_props),
+	.get_property	= mxs_power_ac_get_property,
+	.name		= "ac",
+	.type		= POWER_SUPPLY_TYPE_MAINS,
+};
+
+static int mxs_power_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct resource *res;
+	struct mxs_power_data *data;
+	struct power_supply_config psy_cfg = {};
+	void __iomem *v5ctrl_addr;
+
+	if (!np) {
+		dev_err(dev, "missing device tree\n");
+		return -EINVAL;
+	}
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	data->base_addr = devm_ioremap_resource(dev, res);
+	if (IS_ERR(data->base_addr))
+		return PTR_ERR(data->base_addr);
+
+	psy_cfg.drv_data = data;
+
+	data->ac = devm_power_supply_register(dev, &ac_desc, &psy_cfg);
+	if (IS_ERR(data->ac))
+		return PTR_ERR(data->ac);
+
+	platform_set_drvdata(pdev, data);
+
+	v5ctrl_addr = data->base_addr + HW_POWER_5VCTRL_OFFSET;
+
+	/* Make sure the current limit of the linregs are disabled. */
+	writel(BM_POWER_5VCTRL_ENABLE_LINREG_ILIMIT,
+	       v5ctrl_addr + STMP_OFFSET_REG_CLR);
+
+	return of_platform_populate(np, NULL, NULL, dev);
+}
+
+static struct platform_driver mxs_power_driver = {
+	.driver = {
+		.name	= "mxs_power",
+		.of_match_table = of_mxs_power_match,
+	},
+	.probe	= mxs_power_probe,
+};
+
+module_platform_driver(mxs_power_driver);
+
+MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
+MODULE_DESCRIPTION("Freescale MXS power subsystem");
+MODULE_LICENSE("GPL v2");