Skip to contentSkip to conversation

mfd: AXP20x: Add support for AXP202 and AXP209

PATCH New Carlo Caione 4 participants 34 messages Mar 1, 2014 – Mar 12, 2014

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

cover mfd: AXP20x: Add support for AXP202 and AXP209

AXP209 and AXP202 are the PMUs (Power Management Unit) used by A10, A13 and A20 SoCs and developed by X-Powers, a sister company of Allwinner. AXP20x comprises an adaptive USB-Compatible PWM charger, 2 BUCK DC-DC converters, 5 LDOs, multiple 12-bit ADCs of voltage, current and temperature as well as 4 configurable GPIOs.

This set of patches introduces the core driver and support for two different subsystems:
- Regulators
- PEK (Power Enable Key)

Support for AXP209 in Cubieboard2 is also added.

Carlo Caione (7):
mfd: AXP20x: Add mfd driver for AXP20x PMIC
mfd: AXP20x: Add bindings documentation
ARM: dts: cubieboard2: Add AXP209 support
input: misc: Add driver for AXP20x Power Enable Key
input: misc: Add ABI docs for AXP20x PEK
regulator: AXP20x: Add support for regulators subsystem
ARM: dts: Cubieboard2: Add support for AXP209 regulators

 .../ABI/testing/sysfs-driver-input-axp-pek         |  11 +
 Documentation/devicetree/bindings/mfd/axp20x.txt   |  93 ++++++
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts        |  58 ++++
 arch/arm/configs/sunxi_defconfig                   |   4 +
 drivers/input/misc/Kconfig                         |  11 +
 drivers/input/misc/Makefile                        |   1 +
 drivers/input/misc/axp20x-pek.c                    | 265 ++++++++++++++++
 drivers/mfd/Kconfig                                |  12 +
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/axp20x.c                               | 250 +++++++++++++++
 drivers/regulator/Kconfig                          |   7 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/axp20x-regulator.c               | 349 +++++++++++++++++++++
 include/linux/mfd/axp20x.h                         | 180 +++++++++++
 14 files changed, 1243 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-input-axp-pek
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt
 create mode 100644 drivers/input/misc/axp20x-pek.c
 create mode 100644 drivers/mfd/axp20x.c
 create mode 100644 drivers/regulator/axp20x-regulator.c
 create mode 100644 include/linux/mfd/axp20x.h
Signature · 1 line
1.8.3.2
#1 lore raw

PATCH 1/7 mfd: AXP20x: Add mfd driver for AXP20x PMIC

This patch introduces the preliminary support for PMICs X-Powers AXP202 and AXP209. The AXP209 and AXP202 are the PMUs (Power Management Unit) used by A10, A13 and A20 SoCs and developed by X-Powers, a sister company of Allwinner.

The core enables support for two subsystems:
- PEK (Power Enable Key)
- Regulators

---
 arch/arm/configs/sunxi_defconfig |   1 +
 drivers/mfd/Kconfig              |  12 ++
 drivers/mfd/Makefile             |   1 +
 drivers/mfd/axp20x.c             | 250 +++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/axp20x.h       | 180 ++++++++++++++++++++++++++++
 5 files changed, 444 insertions(+)
 create mode 100644 drivers/mfd/axp20x.c
 create mode 100644 include/linux/mfd/axp20x.h
arch/arm/configs/sunxi_defconfig +1 -0
index 3e2259b..f8aa7e6 100644
@@ -52,6 +52,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
+CONFIG_MFD_AXP20X=y
 # CONFIG_USB_SUPPORT is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
drivers/mfd/Kconfig +12 -0
index dd67158..33d38c4 100644
@@ -59,6 +59,18 @@ config MFD_AAT2870_CORE
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 
+config MFD_AXP20X
+	bool "X-Powers AXP20X"
+	select MFD_CORE
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	depends on I2C=y
+	help
+	  If you say Y here you get support for the AXP20X.
+	  This driver provides common support for accessing the device,
+	  additional drivers must be enabled in order to use the
+	  functionality of the device.
+
 config MFD_CROS_EC
 	tristate "ChromeOS Embedded Controller"
 	select MFD_CORE
drivers/mfd/Makefile +1 -0
index 8a28dc9..371020e 100644
@@ -101,6 +101,7 @@ obj-$(CONFIG_PMIC_DA9052)	+= da9052-irq.o
 obj-$(CONFIG_PMIC_DA9052)	+= da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)	+= da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)	+= da9052-i2c.o
+obj-$(CONFIG_MFD_AXP20X)	+= axp20x.o
 
 obj-$(CONFIG_MFD_LP8788)	+= lp8788.o lp8788-irq.o
 
drivers/mfd/axp20x.c new file +250 -0

250 lines not on this page · raw message

include/linux/mfd/axp20x.h new file +180 -0

180 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#2 lore raw

PATCH 1/7 mfd: AXP20x: Add mfd driver for AXP20x PMIC

Hi,

Quoted 25 lines · Carlo Caione

This patch introduces the preliminary support for PMICs X-Powers AXP202 and AXP209. The AXP209 and AXP202 are the PMUs (Power Management Unit) used by A10, A13 and A20 SoCs and developed by X-Powers, a sister company of Allwinner.

The core enables support for two subsystems:
- PEK (Power Enable Key)
- Regulators

---
 arch/arm/configs/sunxi_defconfig |   1 +
 drivers/mfd/Kconfig              |  12 ++
 drivers/mfd/Makefile             |   1 +
 drivers/mfd/axp20x.c             | 250 +++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/axp20x.h       | 180 ++++++++++++++++++++++++++++
 5 files changed, 444 insertions(+)
 create mode 100644 drivers/mfd/axp20x.c
 create mode 100644 include/linux/mfd/axp20x.h
arch/arm/configs/sunxi_defconfig +0 -0
index 3e2259b..f8aa7e6 100644

arch/arm/configs/sunxi_defconfig CONFIG_GPIO_SYSFS=y · line 58

Quoted 7 lines
arch/arm/configs/sunxi_defconfig +1 -0
@@ -52,6 +52,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
+CONFIG_MFD_AXP20X=y
 # CONFIG_USB_SUPPORT is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y

Please provide a separate patch for both sunxi_defconfig and multi_v7_defconfig.

Quoted 159 lines
drivers/mfd/Kconfig +12 -0
index dd67158..33d38c4 100644
@@ -59,6 +59,18 @@ config MFD_AAT2870_CORE
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 
+config MFD_AXP20X
+	bool "X-Powers AXP20X"
+	select MFD_CORE
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	depends on I2C=y
+	help
+	  If you say Y here you get support for the AXP20X.
+	  This driver provides common support for accessing the device,
+	  additional drivers must be enabled in order to use the
+	  functionality of the device.
+
 config MFD_CROS_EC
 	tristate "ChromeOS Embedded Controller"
 	select MFD_CORE
drivers/mfd/Makefile +1 -0
index 8a28dc9..371020e 100644
@@ -101,6 +101,7 @@ obj-$(CONFIG_PMIC_DA9052)	+= da9052-irq.o
 obj-$(CONFIG_PMIC_DA9052)	+= da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)	+= da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)	+= da9052-i2c.o
+obj-$(CONFIG_MFD_AXP20X)	+= axp20x.o
 
 obj-$(CONFIG_MFD_LP8788)	+= lp8788.o lp8788-irq.o
 
drivers/mfd/axp20x.c new file +118 -0
new file mode 100644
index 0000000..92e5b0f
@@ -0,0 +1,250 @@
+/*
+ * axp20x.c - mfd core driver for the X-Powers AXP202 and AXP209
+ *
+ * Author: Carlo Caione <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/mfd/core.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+
+#define AXP20X_OFF	0x80
+
+static const struct regmap_range axp20x_writeable_ranges[] = {
+	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
+	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
+};
+
+static const struct regmap_range axp20x_volatile_ranges[] = {
+	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
+};
+
+static const struct regmap_access_table axp20x_writeable_table = {
+	.yes_ranges	= axp20x_writeable_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(axp20x_writeable_ranges),
+};
+
+static const struct regmap_access_table axp20x_volatile_table = {
+	.yes_ranges	= axp20x_volatile_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(axp20x_volatile_ranges),
+};
+
+static struct resource axp20x_pek_resources[] = {
+	{
+		.name	= "PEK_DBR",
+		.start	= AXP20X_IRQ_PEK_RIS_EDGE,
+		.end	= AXP20X_IRQ_PEK_RIS_EDGE,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "PEK_DBF",
+		.start	= AXP20X_IRQ_PEK_FAL_EDGE,
+		.end	= AXP20X_IRQ_PEK_FAL_EDGE,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static const struct regmap_config axp20x_regmap_config = {
+	.reg_bits	= 8,
+	.val_bits	= 8,
+	.wr_table	= &axp20x_writeable_table,
+	.volatile_table	= &axp20x_volatile_table,
+	.max_register	= AXP20X_FG_RES,
+	.cache_type	= REGCACHE_RBTREE,
+};
+
+#define AXP20X_IRQ(_irq, _off, _mask) \
+	[AXP20X_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
+
+static const struct regmap_irq axp20x_regmap_irqs[] = {
+	AXP20X_IRQ(ACIN_OVER_V,		0, 7),
+	AXP20X_IRQ(ACIN_PLUGIN,		0, 6),
+	AXP20X_IRQ(ACIN_REMOVAL,	0, 5),
+	AXP20X_IRQ(VBUS_OVER_V,		0, 4),
+	AXP20X_IRQ(VBUS_PLUGIN,		0, 3),
+	AXP20X_IRQ(VBUS_REMOVAL,	0, 2),
+	AXP20X_IRQ(VBUS_V_LOW,		0, 1),
+	AXP20X_IRQ(BATT_PLUGIN,		1, 7),
+	AXP20X_IRQ(BATT_REMOVAL,	1, 6),
+	AXP20X_IRQ(BATT_ENT_ACT_MODE,	1, 5),
+	AXP20X_IRQ(BATT_EXIT_ACT_MODE,	1, 4),
+	AXP20X_IRQ(CHARG,		1, 3),
+	AXP20X_IRQ(CHARG_DONE,		1, 2),
+	AXP20X_IRQ(BATT_TEMP_HIGH,	1, 1),
+	AXP20X_IRQ(BATT_TEMP_LOW,	1, 0),
+	AXP20X_IRQ(DIE_TEMP_HIGH,	2, 7),
+	AXP20X_IRQ(CHARG_I_LOW,		2, 6),
+	AXP20X_IRQ(DCDC1_V_LONG,	2, 5),
+	AXP20X_IRQ(DCDC2_V_LONG,	2, 4),
+	AXP20X_IRQ(DCDC3_V_LONG,	2, 3),
+	AXP20X_IRQ(PEK_SHORT,		2, 1),
+	AXP20X_IRQ(PEK_LONG,		2, 0),
+	AXP20X_IRQ(N_OE_PWR_ON,		3, 7),
+	AXP20X_IRQ(N_OE_PWR_OFF,	3, 6),
+	AXP20X_IRQ(VBUS_VALID,		3, 5),
+	AXP20X_IRQ(VBUS_NOT_VALID,	3, 4),
+	AXP20X_IRQ(VBUS_SESS_VALID,	3, 3),
+	AXP20X_IRQ(VBUS_SESS_END,	3, 2),
+	AXP20X_IRQ(LOW_PWR_LVL1,	3, 1),
+	AXP20X_IRQ(LOW_PWR_LVL2,	3, 0),
+	AXP20X_IRQ(TIMER,		4, 7),
+	AXP20X_IRQ(PEK_RIS_EDGE,	4, 6),
+	AXP20X_IRQ(PEK_FAL_EDGE,	4, 5),
+	AXP20X_IRQ(GPIO3_INPUT,		4, 3),
+	AXP20X_IRQ(GPIO2_INPUT,		4, 2),
+	AXP20X_IRQ(GPIO1_INPUT,		4, 1),
+	AXP20X_IRQ(GPIO0_INPUT,		4, 0),
+};
+
+static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
+	.name			= "axp20x_irq_chip",
+	.status_base		= AXP20X_IRQ1_STATE,
+	.ack_base		= AXP20X_IRQ1_STATE,
+	.mask_base		= AXP20X_IRQ1_EN,
+	.num_regs		= 5,

drivers/mfd/axp20x.c line 128

Quoted 10 lines
drivers/mfd/axp20x.c new file +10 -0
+	.irqs			= axp20x_regmap_irqs,
+	.num_irqs		= ARRAY_SIZE(axp20x_regmap_irqs),
+	.mask_invert		= true,
+	.init_ack_masked	= true,
+};
+
+static struct mfd_cell axp20x_cells[] = {
+	{
+		.name		= "axp20x-pek",
+		.of_compatible	= "x-powers,axp20x-pek",

You need to add the x-powers prefix to Documentation/devicetree/bindings/vendor-prefixes.txt, preferably in a separate patch.

Quoted 63 lines
drivers/mfd/axp20x.c new file +63 -0
+		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
+		.resources	= axp20x_pek_resources,
+	}, {
+		.name		= "axp20x-regulator",
+	},
+};
+
+const struct of_device_id axp20x_of_match[] = {
+	{ .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
+	{ .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
+	{ },
+};
+
+static struct axp20x_dev *axp20x_pm_power_off;
+static void axp20x_power_off(void)
+{
+	regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
+		     AXP20X_OFF);
+}
+
+static int axp20x_i2c_probe(struct i2c_client *i2c,
+			 const struct i2c_device_id *id)
+{
+	struct axp20x_dev *axp20x;
+	const struct of_device_id *of_id;
+	struct device_node *node = i2c->dev.of_node;
+	int ret;
+
+	axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL);
+	if (!axp20x)
+		return -ENOMEM;
+
+	of_id = of_match_device(axp20x_of_match, &i2c->dev);
+	if (!of_id) {
+		dev_err(&i2c->dev, "Unable to setup AXP20X data\n");
+		return -ENODEV;
+	}
+	axp20x->variant = (int) of_id->data;
+
+	axp20x->i2c_client = i2c;
+	axp20x->dev = &i2c->dev;
+	dev_set_drvdata(axp20x->dev, axp20x);
+
+	axp20x->regmap = devm_regmap_init_i2c(i2c, &axp20x_regmap_config);
+	if (IS_ERR(axp20x->regmap)) {
+		ret = PTR_ERR(axp20x->regmap);
+		dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
+		return ret;
+	}
+
+	axp20x->irq = i2c->irq;
+	ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
+				  IRQF_ONESHOT | IRQF_SHARED, -1,
+				  &axp20x_regmap_irq_chip,
+				  &axp20x->regmap_irqc);
+	if (ret) {
+		dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret);
+		return ret;
+	}
+
+	ret = mfd_add_devices(axp20x->dev, -1, axp20x_cells,
+			      ARRAY_SIZE(axp20x_cells), NULL, 0, NULL);
+	if (ret) {

drivers/mfd/axp20x.c line 201

Quoted 10 lines
drivers/mfd/axp20x.c new file +10 -0
+		dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
+		goto mfd_err;
+	}
+
+	axp20x->pm_off = of_property_read_bool(node, "axp,system-power-controller");
+
+	if (axp20x->pm_off && !pm_power_off) {
+		axp20x_pm_power_off = axp20x;
+		pm_power_off = axp20x_power_off;
+	}

I don't think we have any other way to actually power down the board.

Is there any reason why we would not need this property?

Quoted 237 lines
drivers/mfd/axp20x.c new file +48 -0
+	dev_info(&i2c->dev, "AXP20X driver loaded\n");
+
+	return 0;
+
+mfd_err:
+	regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
+
+	return ret;
+}
+
+static int axp20x_i2c_remove(struct i2c_client *i2c)
+{
+	struct axp20x_dev *axp20x = i2c_get_clientdata(i2c);
+
+	if (axp20x == axp20x_pm_power_off) {
+		axp20x_pm_power_off = NULL;
+		pm_power_off = NULL;
+	}
+
+	mfd_remove_devices(axp20x->dev);
+	regmap_del_irq_chip(axp20x->i2c_client->irq, axp20x->regmap_irqc);
+
+	return 0;
+}
+
+static const struct i2c_device_id axp20x_i2c_id[] = {
+	{ "axp202", AXP202_ID },
+	{ "axp209", AXP209_ID },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
+
+static struct i2c_driver axp20x_i2c_driver = {
+	.driver = {
+		.name	= "axp20x",
+		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(axp20x_of_match),
+	},
+	.probe		= axp20x_i2c_probe,
+	.remove		= axp20x_i2c_remove,
+	.id_table	= axp20x_i2c_id,
+};
+
+module_i2c_driver(axp20x_i2c_driver);
+
+MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
+MODULE_AUTHOR("Carlo Caione <[email protected]>");
+MODULE_LICENSE("GPL");
include/linux/mfd/axp20x.h new file +180 -0
new file mode 100644
index 0000000..fcef32c
@@ -0,0 +1,180 @@
+/*
+ * Functions to access AXP20X power management chip.
+ *
+ * Copyright (C) 2013, Carlo Caione <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_MFD_AXP20X_H
+#define __LINUX_MFD_AXP20X_H
+
+#define AXP202_ID			0
+#define AXP209_ID			1
+
+#define AXP20X_DATACACHE(m)		(0x04 + (m))
+
+/* Power supply */
+#define AXP20X_PWR_INPUT_STATUS		0x00
+#define AXP20X_PWR_OP_MODE		0x01
+#define AXP20X_USB_OTG_STATUS		0x02
+#define AXP20X_PWR_OUT_CTRL		0x12
+#define AXP20X_DCDC2_V_OUT		0x23
+#define AXP20X_DCDC2_LDO3_V_SCAL	0x25
+#define AXP20X_DCDC3_V_OUT		0x27
+#define AXP20X_LDO24_V_OUT		0x28
+#define AXP20X_LDO3_V_OUT		0x29
+#define AXP20X_VBUS_IPSOUT_MGMT		0x30
+#define AXP20X_V_OFF			0x31
+#define AXP20X_OFF_CTRL			0x32
+#define AXP20X_CHRG_CTRL1		0x33
+#define AXP20X_CHRG_CTRL2		0x34
+#define AXP20X_CHRG_BAK_CTRL		0x35
+#define AXP20X_PEK_KEY			0x36
+#define AXP20X_DCDC_FREQ		0x37
+#define AXP20X_V_LTF_CHRG		0x38
+#define AXP20X_V_HTF_CHRG		0x39
+#define AXP20X_APS_WARN_L1		0x3a
+#define AXP20X_APS_WARN_L2		0x3b
+#define AXP20X_V_LTF_DISCHRG		0x3c
+#define AXP20X_V_HTF_DISCHRG		0x3d
+
+/* Interrupt */
+#define AXP20X_IRQ1_EN			0x40
+#define AXP20X_IRQ2_EN			0x41
+#define AXP20X_IRQ3_EN			0x42
+#define AXP20X_IRQ4_EN			0x43
+#define AXP20X_IRQ5_EN			0x44
+#define AXP20X_IRQ1_STATE		0x48
+#define AXP20X_IRQ2_STATE		0x49
+#define AXP20X_IRQ3_STATE		0x4a
+#define AXP20X_IRQ4_STATE		0x4b
+#define AXP20X_IRQ5_STATE		0x4c
+
+/* ADC */
+#define AXP20X_ACIN_V_ADC_H		0x56
+#define AXP20X_ACIN_V_ADC_L		0x57
+#define AXP20X_ACIN_I_ADC_H		0x58
+#define AXP20X_ACIN_I_ADC_L		0x59
+#define AXP20X_VBUS_V_ADC_H		0x5a
+#define AXP20X_VBUS_V_ADC_L		0x5b
+#define AXP20X_VBUS_I_ADC_H		0x5c
+#define AXP20X_VBUS_I_ADC_L		0x5d
+#define AXP20X_TEMP_ADC_H		0x5e
+#define AXP20X_TEMP_ADC_L		0x5f
+#define AXP20X_TS_IN_H			0x62
+#define AXP20X_TS_IN_L			0x63
+#define AXP20X_GPIO0_V_ADC_H		0x64
+#define AXP20X_GPIO0_V_ADC_L		0x65
+#define AXP20X_GPIO1_V_ADC_H		0x66
+#define AXP20X_GPIO1_V_ADC_L		0x67
+#define AXP20X_PWR_BATT_H		0x70
+#define AXP20X_PWR_BATT_M		0x71
+#define AXP20X_PWR_BATT_L		0x72
+#define AXP20X_BATT_V_H			0x78
+#define AXP20X_BATT_V_L			0x79
+#define AXP20X_BATT_CHRG_I_H		0x7a
+#define AXP20X_BATT_CHRG_I_L		0x7b
+#define AXP20X_BATT_DISCHRG_I_H		0x7c
+#define AXP20X_BATT_DISCHRG_I_L		0x7d
+#define AXP20X_IPSOUT_V_HIGH_H		0x7e
+#define AXP20X_IPSOUT_V_HIGH_L		0x7f
+
+/* Power supply */
+#define AXP20X_DCDC_MODE		0x80
+#define AXP20X_ADC_EN1			0x82
+#define AXP20X_ADC_EN2			0x83
+#define AXP20X_ADC_RATE			0x84
+#define AXP20X_GPIO10_IN_RANGE		0x85
+#define AXP20X_GPIO1_ADC_IRQ_RIS	0x86
+#define AXP20X_GPIO1_ADC_IRQ_FAL	0x87
+#define AXP20X_TIMER_CTRL		0x8a
+#define AXP20X_VBUS_MON			0x8b
+#define AXP20X_OVER_TMP			0x8f
+
+/* GPIO */
+#define AXP20X_GPIO0_CTRL		0x90
+#define AXP20X_LDO5_V_OUT		0x91
+#define AXP20X_GPIO1_CTRL		0x92
+#define AXP20X_GPIO2_CTRL		0x93
+#define AXP20X_GPIO20_SS		0x94
+#define AXP20X_GPIO3_CTRL		0x95
+
+/* Battery */
+#define AXP20X_CHRG_CC_31_24		0xb0
+#define AXP20X_CHRG_CC_23_16		0xb1
+#define AXP20X_CHRG_CC_15_8		0xb2
+#define AXP20X_CHRG_CC_7_0		0xb3
+#define AXP20X_DISCHRG_CC_31_24		0xb4
+#define AXP20X_DISCHRG_CC_23_16		0xb5
+#define AXP20X_DISCHRG_CC_15_8		0xb6
+#define AXP20X_DISCHRG_CC_7_0		0xb7
+#define AXP20X_CC_CTRL			0xb8
+#define AXP20X_FG_RES			0xb9
+
+/* Regulators IDs */
+enum {
+	AXP20X_LDO1 = 0,
+	AXP20X_LDO2,
+	AXP20X_LDO3,
+	AXP20X_LDO4,
+	AXP20X_LDO5,
+	AXP20X_DCDC2,
+	AXP20X_DCDC3,
+	AXP20X_REG_ID_MAX,
+};
+
+/* IRQs */
+enum {
+	AXP20X_IRQ_ACIN_OVER_V = 1,
+	AXP20X_IRQ_ACIN_PLUGIN,
+	AXP20X_IRQ_ACIN_REMOVAL,
+	AXP20X_IRQ_VBUS_OVER_V,
+	AXP20X_IRQ_VBUS_PLUGIN,
+	AXP20X_IRQ_VBUS_REMOVAL,
+	AXP20X_IRQ_VBUS_V_LOW,
+	AXP20X_IRQ_BATT_PLUGIN,
+	AXP20X_IRQ_BATT_REMOVAL,
+	AXP20X_IRQ_BATT_ENT_ACT_MODE,
+	AXP20X_IRQ_BATT_EXIT_ACT_MODE,
+	AXP20X_IRQ_CHARG,
+	AXP20X_IRQ_CHARG_DONE,
+	AXP20X_IRQ_BATT_TEMP_HIGH,
+	AXP20X_IRQ_BATT_TEMP_LOW,
+	AXP20X_IRQ_DIE_TEMP_HIGH,
+	AXP20X_IRQ_CHARG_I_LOW,
+	AXP20X_IRQ_DCDC1_V_LONG,
+	AXP20X_IRQ_DCDC2_V_LONG,
+	AXP20X_IRQ_DCDC3_V_LONG,
+	AXP20X_IRQ_PEK_SHORT = 22,
+	AXP20X_IRQ_PEK_LONG,
+	AXP20X_IRQ_N_OE_PWR_ON,
+	AXP20X_IRQ_N_OE_PWR_OFF,
+	AXP20X_IRQ_VBUS_VALID,
+	AXP20X_IRQ_VBUS_NOT_VALID,
+	AXP20X_IRQ_VBUS_SESS_VALID,
+	AXP20X_IRQ_VBUS_SESS_END,
+	AXP20X_IRQ_LOW_PWR_LVL1,
+	AXP20X_IRQ_LOW_PWR_LVL2,
+	AXP20X_IRQ_TIMER,
+	AXP20X_IRQ_PEK_RIS_EDGE,
+	AXP20X_IRQ_PEK_FAL_EDGE,
+	AXP20X_IRQ_GPIO3_INPUT,
+	AXP20X_IRQ_GPIO2_INPUT,
+	AXP20X_IRQ_GPIO1_INPUT,
+	AXP20X_IRQ_GPIO0_INPUT,
+};
+
+struct axp20x_dev {
+	struct device			*dev;
+	struct i2c_client		*i2c_client;
+	struct regmap			*regmap;
+	struct regmap_irq_chip_data	*regmap_irqc;
+	int				variant;
+	int				irq;
+	bool				pm_off;
+};
+
+#endif /* __LINUX_MFD_AXP20X_H */
Signature · 1 line
1.8.3.2

Thanks!
Maxime

Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140307/ca4b0fb4/attachment.sig>
#3 lore raw

PATCH 1/7 mfd: AXP20x: Add mfd driver for AXP20x PMIC

Quoted 23 lines · Maxime Ripard

Hi,

Quoted 20 lines · Carlo Caione

This patch introduces the preliminary support for PMICs X-Powers AXP202 and AXP209. The AXP209 and AXP202 are the PMUs (Power Management Unit) used by A10, A13 and A20 SoCs and developed by X-Powers, a sister company of Allwinner.

The core enables support for two subsystems:
- PEK (Power Enable Key)
- Regulators

---
 arch/arm/configs/sunxi_defconfig |   1 +
 drivers/mfd/Kconfig              |  12 ++
 drivers/mfd/Makefile             |   1 +
 drivers/mfd/axp20x.c             | 250 +++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/axp20x.h       | 180 ++++++++++++++++++++++++++++
 5 files changed, 444 insertions(+)
 create mode 100644 drivers/mfd/axp20x.c
 create mode 100644 include/linux/mfd/axp20x.h
Quoted 15 lines

arch/arm/configs/sunxi_defconfig CONFIG_GPIO_SYSFS=y · line 58

Quoted 12 lines
arch/arm/configs/sunxi_defconfig +1 -0
index 3e2259b..f8aa7e6 100644
@@ -52,6 +52,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
+CONFIG_MFD_AXP20X=y
 # CONFIG_USB_SUPPORT is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y

Please provide a separate patch for both sunxi_defconfig and multi_v7_defconfig.

Ok

Quoted 165 lines
Quoted 165 lines
drivers/mfd/Kconfig +12 -0
index dd67158..33d38c4 100644
@@ -59,6 +59,18 @@ config MFD_AAT2870_CORE
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 
+config MFD_AXP20X
+	bool "X-Powers AXP20X"
+	select MFD_CORE
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	depends on I2C=y
+	help
+	  If you say Y here you get support for the AXP20X.
+	  This driver provides common support for accessing the device,
+	  additional drivers must be enabled in order to use the
+	  functionality of the device.
+
 config MFD_CROS_EC
 	tristate "ChromeOS Embedded Controller"
 	select MFD_CORE
drivers/mfd/Makefile +1 -0
index 8a28dc9..371020e 100644
@@ -101,6 +101,7 @@ obj-$(CONFIG_PMIC_DA9052)	+= da9052-irq.o
 obj-$(CONFIG_PMIC_DA9052)	+= da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)	+= da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)	+= da9052-i2c.o
+obj-$(CONFIG_MFD_AXP20X)	+= axp20x.o
 
 obj-$(CONFIG_MFD_LP8788)	+= lp8788.o lp8788-irq.o
 
drivers/mfd/axp20x.c new file +124 -0
new file mode 100644
index 0000000..92e5b0f
@@ -0,0 +1,250 @@
+/*
+ * axp20x.c - mfd core driver for the X-Powers AXP202 and AXP209
+ *
+ * Author: Carlo Caione <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/mfd/core.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+
+#define AXP20X_OFF	0x80
+
+static const struct regmap_range axp20x_writeable_ranges[] = {
+	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
+	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
+};
+
+static const struct regmap_range axp20x_volatile_ranges[] = {
+	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
+};
+
+static const struct regmap_access_table axp20x_writeable_table = {
+	.yes_ranges	= axp20x_writeable_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(axp20x_writeable_ranges),
+};
+
+static const struct regmap_access_table axp20x_volatile_table = {
+	.yes_ranges	= axp20x_volatile_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(axp20x_volatile_ranges),
+};
+
+static struct resource axp20x_pek_resources[] = {
+	{
+		.name	= "PEK_DBR",
+		.start	= AXP20X_IRQ_PEK_RIS_EDGE,
+		.end	= AXP20X_IRQ_PEK_RIS_EDGE,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "PEK_DBF",
+		.start	= AXP20X_IRQ_PEK_FAL_EDGE,
+		.end	= AXP20X_IRQ_PEK_FAL_EDGE,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static const struct regmap_config axp20x_regmap_config = {
+	.reg_bits	= 8,
+	.val_bits	= 8,
+	.wr_table	= &axp20x_writeable_table,
+	.volatile_table	= &axp20x_volatile_table,
+	.max_register	= AXP20X_FG_RES,
+	.cache_type	= REGCACHE_RBTREE,
+};
+
+#define AXP20X_IRQ(_irq, _off, _mask) \
+	[AXP20X_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
+
+static const struct regmap_irq axp20x_regmap_irqs[] = {
+	AXP20X_IRQ(ACIN_OVER_V,		0, 7),
+	AXP20X_IRQ(ACIN_PLUGIN,		0, 6),
+	AXP20X_IRQ(ACIN_REMOVAL,	0, 5),
+	AXP20X_IRQ(VBUS_OVER_V,		0, 4),
+	AXP20X_IRQ(VBUS_PLUGIN,		0, 3),
+	AXP20X_IRQ(VBUS_REMOVAL,	0, 2),
+	AXP20X_IRQ(VBUS_V_LOW,		0, 1),
+	AXP20X_IRQ(BATT_PLUGIN,		1, 7),
+	AXP20X_IRQ(BATT_REMOVAL,	1, 6),
+	AXP20X_IRQ(BATT_ENT_ACT_MODE,	1, 5),
+	AXP20X_IRQ(BATT_EXIT_ACT_MODE,	1, 4),
+	AXP20X_IRQ(CHARG,		1, 3),
+	AXP20X_IRQ(CHARG_DONE,		1, 2),
+	AXP20X_IRQ(BATT_TEMP_HIGH,	1, 1),
+	AXP20X_IRQ(BATT_TEMP_LOW,	1, 0),
+	AXP20X_IRQ(DIE_TEMP_HIGH,	2, 7),
+	AXP20X_IRQ(CHARG_I_LOW,		2, 6),
+	AXP20X_IRQ(DCDC1_V_LONG,	2, 5),
+	AXP20X_IRQ(DCDC2_V_LONG,	2, 4),
+	AXP20X_IRQ(DCDC3_V_LONG,	2, 3),
+	AXP20X_IRQ(PEK_SHORT,		2, 1),
+	AXP20X_IRQ(PEK_LONG,		2, 0),
+	AXP20X_IRQ(N_OE_PWR_ON,		3, 7),
+	AXP20X_IRQ(N_OE_PWR_OFF,	3, 6),
+	AXP20X_IRQ(VBUS_VALID,		3, 5),
+	AXP20X_IRQ(VBUS_NOT_VALID,	3, 4),
+	AXP20X_IRQ(VBUS_SESS_VALID,	3, 3),
+	AXP20X_IRQ(VBUS_SESS_END,	3, 2),
+	AXP20X_IRQ(LOW_PWR_LVL1,	3, 1),
+	AXP20X_IRQ(LOW_PWR_LVL2,	3, 0),
+	AXP20X_IRQ(TIMER,		4, 7),
+	AXP20X_IRQ(PEK_RIS_EDGE,	4, 6),
+	AXP20X_IRQ(PEK_FAL_EDGE,	4, 5),
+	AXP20X_IRQ(GPIO3_INPUT,		4, 3),
+	AXP20X_IRQ(GPIO2_INPUT,		4, 2),
+	AXP20X_IRQ(GPIO1_INPUT,		4, 1),
+	AXP20X_IRQ(GPIO0_INPUT,		4, 0),
+};
+
+static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
+	.name			= "axp20x_irq_chip",
+	.status_base		= AXP20X_IRQ1_STATE,
+	.ack_base		= AXP20X_IRQ1_STATE,
+	.mask_base		= AXP20X_IRQ1_EN,
+	.num_regs		= 5,
+	.irqs			= axp20x_regmap_irqs,
+	.num_irqs		= ARRAY_SIZE(axp20x_regmap_irqs),
+	.mask_invert		= true,
+	.init_ack_masked	= true,
+};
+
Quoted 8 lines

drivers/mfd/axp20x.c line 128

Quoted 4 lines
drivers/mfd/axp20x.c new file +4 -0
+static struct mfd_cell axp20x_cells[] = {
+	{
+		.name		= "axp20x-pek",
+		.of_compatible	= "x-powers,axp20x-pek",

You need to add the x-powers prefix to Documentation/devicetree/bindings/vendor-prefixes.txt, preferably in a separate patch.

Right, thanks

Quoted 76 lines
Quoted 63 lines
drivers/mfd/axp20x.c new file +63 -0
+		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
+		.resources	= axp20x_pek_resources,
+	}, {
+		.name		= "axp20x-regulator",
+	},
+};
+
+const struct of_device_id axp20x_of_match[] = {
+	{ .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
+	{ .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
+	{ },
+};
+
+static struct axp20x_dev *axp20x_pm_power_off;
+static void axp20x_power_off(void)
+{
+	regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
+		     AXP20X_OFF);
+}
+
+static int axp20x_i2c_probe(struct i2c_client *i2c,
+			 const struct i2c_device_id *id)
+{
+	struct axp20x_dev *axp20x;
+	const struct of_device_id *of_id;
+	struct device_node *node = i2c->dev.of_node;
+	int ret;
+
+	axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL);
+	if (!axp20x)
+		return -ENOMEM;
+
+	of_id = of_match_device(axp20x_of_match, &i2c->dev);
+	if (!of_id) {
+		dev_err(&i2c->dev, "Unable to setup AXP20X data\n");
+		return -ENODEV;
+	}
+	axp20x->variant = (int) of_id->data;
+
+	axp20x->i2c_client = i2c;
+	axp20x->dev = &i2c->dev;
+	dev_set_drvdata(axp20x->dev, axp20x);
+
+	axp20x->regmap = devm_regmap_init_i2c(i2c, &axp20x_regmap_config);
+	if (IS_ERR(axp20x->regmap)) {
+		ret = PTR_ERR(axp20x->regmap);
+		dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
+		return ret;
+	}
+
+	axp20x->irq = i2c->irq;
+	ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
+				  IRQF_ONESHOT | IRQF_SHARED, -1,
+				  &axp20x_regmap_irq_chip,
+				  &axp20x->regmap_irqc);
+	if (ret) {
+		dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret);
+		return ret;
+	}
+
+	ret = mfd_add_devices(axp20x->dev, -1, axp20x_cells,
+			      ARRAY_SIZE(axp20x_cells), NULL, 0, NULL);
+	if (ret) {

drivers/mfd/axp20x.c line 201

Quoted 10 lines
drivers/mfd/axp20x.c new file +10 -0
+		dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
+		goto mfd_err;
+	}
+
+	axp20x->pm_off = of_property_read_bool(node, "axp,system-power-controller");
+
+	if (axp20x->pm_off && !pm_power_off) {
+		axp20x_pm_power_off = axp20x;
+		pm_power_off = axp20x_power_off;
+	}

I don't think we have any other way to actually power down the board.

Quoted 1 line

Is there any reason why we would not need this property?

In case you have multiple PMIC on the board in this way you con define which is the one apt to power off.

Quoted 232 lines
Quoted 232 lines
drivers/mfd/axp20x.c new file +48 -0
+	dev_info(&i2c->dev, "AXP20X driver loaded\n");
+
+	return 0;
+
+mfd_err:
+	regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
+
+	return ret;
+}
+
+static int axp20x_i2c_remove(struct i2c_client *i2c)
+{
+	struct axp20x_dev *axp20x = i2c_get_clientdata(i2c);
+
+	if (axp20x == axp20x_pm_power_off) {
+		axp20x_pm_power_off = NULL;
+		pm_power_off = NULL;
+	}
+
+	mfd_remove_devices(axp20x->dev);
+	regmap_del_irq_chip(axp20x->i2c_client->irq, axp20x->regmap_irqc);
+
+	return 0;
+}
+
+static const struct i2c_device_id axp20x_i2c_id[] = {
+	{ "axp202", AXP202_ID },
+	{ "axp209", AXP209_ID },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
+
+static struct i2c_driver axp20x_i2c_driver = {
+	.driver = {
+		.name	= "axp20x",
+		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(axp20x_of_match),
+	},
+	.probe		= axp20x_i2c_probe,
+	.remove		= axp20x_i2c_remove,
+	.id_table	= axp20x_i2c_id,
+};
+
+module_i2c_driver(axp20x_i2c_driver);
+
+MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
+MODULE_AUTHOR("Carlo Caione <[email protected]>");
+MODULE_LICENSE("GPL");
include/linux/mfd/axp20x.h new file +178 -0
new file mode 100644
index 0000000..fcef32c
@@ -0,0 +1,180 @@
+/*
+ * Functions to access AXP20X power management chip.
+ *
+ * Copyright (C) 2013, Carlo Caione <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_MFD_AXP20X_H
+#define __LINUX_MFD_AXP20X_H
+
+#define AXP202_ID			0
+#define AXP209_ID			1
+
+#define AXP20X_DATACACHE(m)		(0x04 + (m))
+
+/* Power supply */
+#define AXP20X_PWR_INPUT_STATUS		0x00
+#define AXP20X_PWR_OP_MODE		0x01
+#define AXP20X_USB_OTG_STATUS		0x02
+#define AXP20X_PWR_OUT_CTRL		0x12
+#define AXP20X_DCDC2_V_OUT		0x23
+#define AXP20X_DCDC2_LDO3_V_SCAL	0x25
+#define AXP20X_DCDC3_V_OUT		0x27
+#define AXP20X_LDO24_V_OUT		0x28
+#define AXP20X_LDO3_V_OUT		0x29
+#define AXP20X_VBUS_IPSOUT_MGMT		0x30
+#define AXP20X_V_OFF			0x31
+#define AXP20X_OFF_CTRL			0x32
+#define AXP20X_CHRG_CTRL1		0x33
+#define AXP20X_CHRG_CTRL2		0x34
+#define AXP20X_CHRG_BAK_CTRL		0x35
+#define AXP20X_PEK_KEY			0x36
+#define AXP20X_DCDC_FREQ		0x37
+#define AXP20X_V_LTF_CHRG		0x38
+#define AXP20X_V_HTF_CHRG		0x39
+#define AXP20X_APS_WARN_L1		0x3a
+#define AXP20X_APS_WARN_L2		0x3b
+#define AXP20X_V_LTF_DISCHRG		0x3c
+#define AXP20X_V_HTF_DISCHRG		0x3d
+
+/* Interrupt */
+#define AXP20X_IRQ1_EN			0x40
+#define AXP20X_IRQ2_EN			0x41
+#define AXP20X_IRQ3_EN			0x42
+#define AXP20X_IRQ4_EN			0x43
+#define AXP20X_IRQ5_EN			0x44
+#define AXP20X_IRQ1_STATE		0x48
+#define AXP20X_IRQ2_STATE		0x49
+#define AXP20X_IRQ3_STATE		0x4a
+#define AXP20X_IRQ4_STATE		0x4b
+#define AXP20X_IRQ5_STATE		0x4c
+
+/* ADC */
+#define AXP20X_ACIN_V_ADC_H		0x56
+#define AXP20X_ACIN_V_ADC_L		0x57
+#define AXP20X_ACIN_I_ADC_H		0x58
+#define AXP20X_ACIN_I_ADC_L		0x59
+#define AXP20X_VBUS_V_ADC_H		0x5a
+#define AXP20X_VBUS_V_ADC_L		0x5b
+#define AXP20X_VBUS_I_ADC_H		0x5c
+#define AXP20X_VBUS_I_ADC_L		0x5d
+#define AXP20X_TEMP_ADC_H		0x5e
+#define AXP20X_TEMP_ADC_L		0x5f
+#define AXP20X_TS_IN_H			0x62
+#define AXP20X_TS_IN_L			0x63
+#define AXP20X_GPIO0_V_ADC_H		0x64
+#define AXP20X_GPIO0_V_ADC_L		0x65
+#define AXP20X_GPIO1_V_ADC_H		0x66
+#define AXP20X_GPIO1_V_ADC_L		0x67
+#define AXP20X_PWR_BATT_H		0x70
+#define AXP20X_PWR_BATT_M		0x71
+#define AXP20X_PWR_BATT_L		0x72
+#define AXP20X_BATT_V_H			0x78
+#define AXP20X_BATT_V_L			0x79
+#define AXP20X_BATT_CHRG_I_H		0x7a
+#define AXP20X_BATT_CHRG_I_L		0x7b
+#define AXP20X_BATT_DISCHRG_I_H		0x7c
+#define AXP20X_BATT_DISCHRG_I_L		0x7d
+#define AXP20X_IPSOUT_V_HIGH_H		0x7e
+#define AXP20X_IPSOUT_V_HIGH_L		0x7f
+
+/* Power supply */
+#define AXP20X_DCDC_MODE		0x80
+#define AXP20X_ADC_EN1			0x82
+#define AXP20X_ADC_EN2			0x83
+#define AXP20X_ADC_RATE			0x84
+#define AXP20X_GPIO10_IN_RANGE		0x85
+#define AXP20X_GPIO1_ADC_IRQ_RIS	0x86
+#define AXP20X_GPIO1_ADC_IRQ_FAL	0x87
+#define AXP20X_TIMER_CTRL		0x8a
+#define AXP20X_VBUS_MON			0x8b
+#define AXP20X_OVER_TMP			0x8f
+
+/* GPIO */
+#define AXP20X_GPIO0_CTRL		0x90
+#define AXP20X_LDO5_V_OUT		0x91
+#define AXP20X_GPIO1_CTRL		0x92
+#define AXP20X_GPIO2_CTRL		0x93
+#define AXP20X_GPIO20_SS		0x94
+#define AXP20X_GPIO3_CTRL		0x95
+
+/* Battery */
+#define AXP20X_CHRG_CC_31_24		0xb0
+#define AXP20X_CHRG_CC_23_16		0xb1
+#define AXP20X_CHRG_CC_15_8		0xb2
+#define AXP20X_CHRG_CC_7_0		0xb3
+#define AXP20X_DISCHRG_CC_31_24		0xb4
+#define AXP20X_DISCHRG_CC_23_16		0xb5
+#define AXP20X_DISCHRG_CC_15_8		0xb6
+#define AXP20X_DISCHRG_CC_7_0		0xb7
+#define AXP20X_CC_CTRL			0xb8
+#define AXP20X_FG_RES			0xb9
+
+/* Regulators IDs */
+enum {
+	AXP20X_LDO1 = 0,
+	AXP20X_LDO2,
+	AXP20X_LDO3,
+	AXP20X_LDO4,
+	AXP20X_LDO5,
+	AXP20X_DCDC2,
+	AXP20X_DCDC3,
+	AXP20X_REG_ID_MAX,
+};
+
+/* IRQs */
+enum {
+	AXP20X_IRQ_ACIN_OVER_V = 1,
+	AXP20X_IRQ_ACIN_PLUGIN,
+	AXP20X_IRQ_ACIN_REMOVAL,
+	AXP20X_IRQ_VBUS_OVER_V,
+	AXP20X_IRQ_VBUS_PLUGIN,
+	AXP20X_IRQ_VBUS_REMOVAL,
+	AXP20X_IRQ_VBUS_V_LOW,
+	AXP20X_IRQ_BATT_PLUGIN,
+	AXP20X_IRQ_BATT_REMOVAL,
+	AXP20X_IRQ_BATT_ENT_ACT_MODE,
+	AXP20X_IRQ_BATT_EXIT_ACT_MODE,
+	AXP20X_IRQ_CHARG,
+	AXP20X_IRQ_CHARG_DONE,
+	AXP20X_IRQ_BATT_TEMP_HIGH,
+	AXP20X_IRQ_BATT_TEMP_LOW,
+	AXP20X_IRQ_DIE_TEMP_HIGH,
+	AXP20X_IRQ_CHARG_I_LOW,
+	AXP20X_IRQ_DCDC1_V_LONG,
+	AXP20X_IRQ_DCDC2_V_LONG,
+	AXP20X_IRQ_DCDC3_V_LONG,
+	AXP20X_IRQ_PEK_SHORT = 22,
+	AXP20X_IRQ_PEK_LONG,
+	AXP20X_IRQ_N_OE_PWR_ON,
+	AXP20X_IRQ_N_OE_PWR_OFF,
+	AXP20X_IRQ_VBUS_VALID,
+	AXP20X_IRQ_VBUS_NOT_VALID,
+	AXP20X_IRQ_VBUS_SESS_VALID,
+	AXP20X_IRQ_VBUS_SESS_END,
+	AXP20X_IRQ_LOW_PWR_LVL1,
+	AXP20X_IRQ_LOW_PWR_LVL2,
+	AXP20X_IRQ_TIMER,
+	AXP20X_IRQ_PEK_RIS_EDGE,
+	AXP20X_IRQ_PEK_FAL_EDGE,
+	AXP20X_IRQ_GPIO3_INPUT,
+	AXP20X_IRQ_GPIO2_INPUT,
+	AXP20X_IRQ_GPIO1_INPUT,
+	AXP20X_IRQ_GPIO0_INPUT,
+};
+
+struct axp20x_dev {
+	struct device			*dev;
+	struct i2c_client		*i2c_client;
+	struct regmap			*regmap;
+	struct regmap_irq_chip_data	*regmap_irqc;
+	int				variant;
+	int				irq;
+	bool				pm_off;
+};
Quoted 8 lines
Quoted 5 lines
include/linux/mfd/axp20x.h new file +2 -0
+
+#endif /* __LINUX_MFD_AXP20X_H */
Signature · 1 line
1.8.3.2

Thanks!
Maxime

Thank you,

--
Carlo Caione

#4 lore raw

PATCH 1/7 mfd: AXP20x: Add mfd driver for AXP20x PMIC

Hi Carlo,

Quoted 9 lines · Carlo Caione
Quoted 9 lines

drivers/mfd/axp20x.c line 201

Quoted 6 lines
drivers/mfd/axp20x.c new file +6 -0
+	axp20x->pm_off = of_property_read_bool(node, "axp,system-power-controller");
+
+	if (axp20x->pm_off && !pm_power_off) {
+		axp20x_pm_power_off = axp20x;
+		pm_power_off = axp20x_power_off;
+	}

I don't think we have any other way to actually power down the board.

Quoted 4 lines
Quoted 1 line

Is there any reason why we would not need this property?

In case you have multiple PMIC on the board in this way you con define which is the one apt to power off.

Do we even have such a board?

Let's leave this out, we can always add it later if needs be.

Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140309/1ba2880f/attachment.sig>
#5 lore raw

PATCH 2/7 mfd: AXP20x: Add bindings documentation

In reply to Carlo Caione

Bindings documentation for the AXP20x driver. In this file also two sub-nodes (PEK and regulators) are documented.

---
 Documentation/devicetree/bindings/mfd/axp20x.txt | 93 ++++++++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt
Documentation/devicetree/bindings/mfd/axp20x.txt new file +93 -0
new file mode 100644
index 0000000..ae3e3c4
@@ -0,0 +1,93 @@
+* axp20x device tree bindings
+
+The axp20x family current members :-
+axp202 (X-Powers)
+axp209 (X-Powers)
+
+Required properties:
+- compatible 			: Should be "x-powers,axp202" or "x-powers,axp209"
+- interrupt-controller 		: axp20x has its own internal IRQs
+- #interrupt-cells 		: Should be set to 1
+- interrupt-parent 		: The parent interrupt controller
+- interrupts 			: Interrupt specifiers for interrupt sources
+- reg 				: The I2C slave address for the AXP chip
+- axp,system-power-controller	: Telling whether or not this pmic is
+				  controlling the system power
+
+Sub-nodes:
+* regulators : Contain the regulator nodes. The regulators are bound using
+	       their name as listed here: dcdc2, dcdc3, ldo1, ldo2, ldo3,
+	       ldo4, ldo5.
+	       The bindings details of individual regulator device can be found in:
+	       Documentation/devicetree/bindings/regulator/regulator.txt with the
+	       exception of:
+
+	- dcdc-freq		: defines the work frequency of DC-DC in KHz
+				  (range: 750-1875)
+	- dcdc-workmode		: 1 for PWM mode, 0 for AUTO mode
+
+* axp20x-pek : Power Enable Key
+	- compatible		: should be "x-powers,axp20x-pek"
+
+Example:
+
+axp: axp20x at 34 {
+	reg = <0x34>;
+	interrupt-parent = <&nmi_intc>;
+	interrupts = <0 8>;
+
+	axp,system-power-controller;
+
+	compatible = "x-powers,axp209";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	axp20x-pek {
+		compatible = "x-powers,axp20x-pek";
+	};
+
+	regulators {
+		dcdc-freq = "8";
+
+		axp_dcdc2: dcdc2 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <2275000>;
+			dcdc-workmode = <0>;
+			regulator-always-on;
+		};
+
+		axp_dcdc3: dcdc3 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <3500000>;
+			dcdc-workmode = <0>;
+			regulator-always-on;
+		};
+
+		axp_ldo1: ldo1 {
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+		};
+
+		axp_ldo2: ldo2 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		axp_ldo3: ldo3 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <3500000>;
+		};
+
+		axp_ldo4: ldo4 {
+			regulator-min-microvolt = <1250000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+		axp_ldo5: ldo5 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+		};
+	};
+};
+
Signature · 1 line
1.8.3.2
#6 lore raw

PATCH 2/7 mfd: AXP20x: Add bindings documentation

Quoted 32 lines · Carlo Caione

Bindings documentation for the AXP20x driver. In this file also two sub-nodes (PEK and regulators) are documented.

---
 Documentation/devicetree/bindings/mfd/axp20x.txt | 93 ++++++++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt
Documentation/devicetree/bindings/mfd/axp20x.txt new file +17 -0
new file mode 100644
index 0000000..ae3e3c4
@@ -0,0 +1,93 @@
+* axp20x device tree bindings
+
+The axp20x family current members :-
+axp202 (X-Powers)
+axp209 (X-Powers)
+
+Required properties:
+- compatible 			: Should be "x-powers,axp202" or "x-powers,axp209"
+- interrupt-controller 		: axp20x has its own internal IRQs
+- #interrupt-cells 		: Should be set to 1
+- interrupt-parent 		: The parent interrupt controller
+- interrupts 			: Interrupt specifiers for interrupt sources
+- reg 				: The I2C slave address for the AXP chip
+- axp,system-power-controller	: Telling whether or not this pmic is
+				  controlling the system power
+
+Sub-nodes:

Documentation/devicetree/bindings/mfd/axp20x.txt line 27

Quoted 10 lines
Documentation/devicetree/bindings/mfd/axp20x.txt new file +10 -0
+* regulators : Contain the regulator nodes. The regulators are bound using
+	       their name as listed here: dcdc2, dcdc3, ldo1, ldo2, ldo3,
+	       ldo4, ldo5.
+	       The bindings details of individual regulator device can be found in:
+	       Documentation/devicetree/bindings/regulator/regulator.txt with the
+	       exception of:
+
+	- dcdc-freq		: defines the work frequency of DC-DC in KHz
+				  (range: 750-1875)
+	- dcdc-workmode		: 1 for PWM mode, 0 for AUTO mode

You don't seem to always set this. You should mention that it is optional, and which default value it has.

Documentation/devicetree/bindings/mfd/axp20x.txt line 30

Quoted 3 lines
Documentation/devicetree/bindings/mfd/axp20x.txt new file +3 -0
+
+* axp20x-pek : Power Enable Key
+	- compatible		: should be "x-powers,axp20x-pek"

Why is this needed for?

Plus, please don't use any generic, or pattern matching compatibles, but rather precise ones, so that if it is needed, we can add any quirk we want.

Quoted 65 lines
Documentation/devicetree/bindings/mfd/axp20x.txt new file +62 -0
+Example:
+
+axp: axp20x at 34 {
+	reg = <0x34>;
+	interrupt-parent = <&nmi_intc>;
+	interrupts = <0 8>;
+
+	axp,system-power-controller;
+
+	compatible = "x-powers,axp209";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	axp20x-pek {
+		compatible = "x-powers,axp20x-pek";
+	};
+
+	regulators {
+		dcdc-freq = "8";
+
+		axp_dcdc2: dcdc2 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <2275000>;
+			dcdc-workmode = <0>;
+			regulator-always-on;
+		};
+
+		axp_dcdc3: dcdc3 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <3500000>;
+			dcdc-workmode = <0>;
+			regulator-always-on;
+		};
+
+		axp_ldo1: ldo1 {
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+		};
+
+		axp_ldo2: ldo2 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		axp_ldo3: ldo3 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <3500000>;
+		};
+
+		axp_ldo4: ldo4 {
+			regulator-min-microvolt = <1250000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+		axp_ldo5: ldo5 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+		};
+	};
+};
+
Signature · 1 line
1.8.3.2
Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140307/52e645ac/attachment-0001.sig>
#7 lore raw

[linux-sunxi] Re: [PATCH 2/7] mfd: AXP20x: Add bindings documentation

Quoted 38 lines · Maxime Ripard
Quoted 37 lines · Carlo Caione

Bindings documentation for the AXP20x driver. In this file also two sub-nodes (PEK and regulators) are documented.

---
 Documentation/devicetree/bindings/mfd/axp20x.txt | 93 ++++++++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt
Documentation/devicetree/bindings/mfd/axp20x.txt new file +22 -0
new file mode 100644
index 0000000..ae3e3c4
@@ -0,0 +1,93 @@
+* axp20x device tree bindings
+
+The axp20x family current members :-
+axp202 (X-Powers)
+axp209 (X-Powers)
+
+Required properties:
+- compatible 			: Should be "x-powers,axp202" or "x-powers,axp209"
+- interrupt-controller 		: axp20x has its own internal IRQs
+- #interrupt-cells 		: Should be set to 1
+- interrupt-parent 		: The parent interrupt controller
+- interrupts 			: Interrupt specifiers for interrupt sources
+- reg 				: The I2C slave address for the AXP chip
+- axp,system-power-controller	: Telling whether or not this pmic is
+				  controlling the system power
+
+Sub-nodes:
+* regulators : Contain the regulator nodes. The regulators are bound using
+	       their name as listed here: dcdc2, dcdc3, ldo1, ldo2, ldo3,
+	       ldo4, ldo5.
+	       The bindings details of individual regulator device can be found in:
+	       Documentation/devicetree/bindings/regulator/regulator.txt with the
Quoted 8 lines

Documentation/devicetree/bindings/mfd/axp20x.txt line 27

Quoted 5 lines
Documentation/devicetree/bindings/mfd/axp20x.txt new file +5 -0
+	       exception of:
+
+	- dcdc-freq		: defines the work frequency of DC-DC in KHz
+				  (range: 750-1875)
+	- dcdc-workmode		: 1 for PWM mode, 0 for AUTO mode

You don't seem to always set this. You should mention that it is optional, and which default value it has.

Fix in v2.

Quoted 9 lines

Documentation/devicetree/bindings/mfd/axp20x.txt line 30

Quoted 3 lines
Documentation/devicetree/bindings/mfd/axp20x.txt new file +3 -0
+
+* axp20x-pek : Power Enable Key
+	- compatible		: should be "x-powers,axp20x-pek"

Why is this needed for?

Plus, please don't use any generic, or pattern matching compatibles, but rather precise ones, so that if it is needed, we can add any quirk we want.

It is not needed, in fact I deleted it from dts. It is a refuse from the previous submission. I'll fix it.

Quoted 65 lines
Quoted 65 lines
Documentation/devicetree/bindings/mfd/axp20x.txt new file +62 -0
+Example:
+
+axp: axp20x at 34 {
+	reg = <0x34>;
+	interrupt-parent = <&nmi_intc>;
+	interrupts = <0 8>;
+
+	axp,system-power-controller;
+
+	compatible = "x-powers,axp209";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	axp20x-pek {
+		compatible = "x-powers,axp20x-pek";
+	};
+
+	regulators {
+		dcdc-freq = "8";
+
+		axp_dcdc2: dcdc2 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <2275000>;
+			dcdc-workmode = <0>;
+			regulator-always-on;
+		};
+
+		axp_dcdc3: dcdc3 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <3500000>;
+			dcdc-workmode = <0>;
+			regulator-always-on;
+		};
+
+		axp_ldo1: ldo1 {
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+		};
+
+		axp_ldo2: ldo2 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		axp_ldo3: ldo3 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <3500000>;
+		};
+
+		axp_ldo4: ldo4 {
+			regulator-min-microvolt = <1250000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+		axp_ldo5: ldo5 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+		};
+	};
+};
+
Signature · 1 line
1.8.3.2
Signature · 1 line
Carlo Caione
#8 lore raw

PATCH 3/7 ARM: dts: cubieboard2: Add AXP209 support

In reply to Carlo Caione

AXP209 is the PMU used by Cubieboard2. This patch enable the core support in the dts file.
This patch requires: "ARM: sun7i/sun6i: irqchip: Add irqchip driver for NMI controller"

---
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts +14 -0
index 5c51cb8..234b14b 100644
@@ -53,6 +53,20 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupt-parent = <&nmi_intc>;
+				interrupts = <0 8>;
+
+				axp,system-power-controller;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+			};
 		};
 
 		i2c1: i2c at 01c2b000 {
Signature · 1 line
1.8.3.2
#9 lore raw

PATCH 3/7 ARM: dts: cubieboard2: Add AXP209 support

Quoted 4 lines · Carlo Caione

AXP209 is the PMU used by Cubieboard2. This patch enable the core support in the dts file.
This patch requires: "ARM: sun7i/sun6i: irqchip: Add irqchip driver for NMI controller"

That shouldn't be in the commit log itself.

Quoted 34 lines
---
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts +14 -0
index 5c51cb8..234b14b 100644
@@ -53,6 +53,20 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupt-parent = <&nmi_intc>;
+				interrupts = <0 8>;
+
+				axp,system-power-controller;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+			};
 		};
 
 		i2c1: i2c at 01c2b000 {
Signature · 1 line
1.8.3.2
Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140307/744ae631/attachment-0001.sig>
#10 lore raw

PATCH 4/7 input: misc: Add driver for AXP20x Power Enable Key

In reply to Carlo Caione

This patch add support for the Power Enable Key found on MFD AXP202 and AXP209. Besides the basic support for the button, the driver adds two entries in sysfs to configure the time delay for power on/off.

---
 arch/arm/configs/sunxi_defconfig |   2 +
 drivers/input/misc/Kconfig       |  11 ++
 drivers/input/misc/Makefile      |   1 +
 drivers/input/misc/axp20x-pek.c  | 265 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 279 insertions(+)
 create mode 100644 drivers/input/misc/axp20x-pek.c
arch/arm/configs/sunxi_defconfig +2 -0
index f8aa7e6..d59c826 100644
@@ -39,6 +39,8 @@ CONFIG_SUN4I_EMAC=y
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 # CONFIG_WLAN is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AXP20X_PEK=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=8
drivers/input/misc/Kconfig +11 -0
index 5f4967d..c9438ac 100644
@@ -384,6 +384,17 @@ config INPUT_RETU_PWRBUTTON
 	  To compile this driver as a module, choose M here. The module will
 	  be called retu-pwrbutton.
 
+config INPUT_AXP20X_PEK
+	tristate "X-Powers AXP20X power button driver"
+	depends on MFD_AXP20X
+	help
+	  Say Y here if you want to enable power key reporting via the
+	  AXP20X PMIC.
+
+	  To compile this driver as a module, choose M here. The module will
+	  be called axp20x-pek.
+
+
 config INPUT_TWL4030_PWRBUTTON
 	tristate "TWL4030 Power button Driver"
 	depends on TWL4030_CORE
drivers/input/misc/Makefile +1 -0
index 0ebfb6d..41d5403 100644
@@ -49,6 +49,7 @@ obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
 obj-$(CONFIG_INPUT_PWM_BEEPER)		+= pwm-beeper.o
 obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
 obj-$(CONFIG_INPUT_RETU_PWRBUTTON)	+= retu-pwrbutton.o
+obj-$(CONFIG_INPUT_AXP20X_PEK)		+= axp20x-pek.o
 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
 obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)	+= sirfsoc-onkey.o
drivers/input/misc/axp20x-pek.c new file +265 -0

265 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#11 lore raw

PATCH 4/7 input: misc: Add driver for AXP20x Power Enable Key

Quoted 7 lines · Carlo Caione

This patch add support for the Power Enable Key found on MFD AXP202 and AXP209. Besides the basic support for the button, the driver adds two entries in sysfs to configure the time delay for power on/off.

---
 arch/arm/configs/sunxi_defconfig |   2 +

Again, please provide a separate patch for both sunxi_defconfig and multi_v7_defconfig.

(This can be the same patches than the one enabling the MFD though)

Quoted 81 lines
 drivers/input/misc/Kconfig       |  11 ++
 drivers/input/misc/Makefile      |   1 +
 drivers/input/misc/axp20x-pek.c  | 265 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 279 insertions(+)
 create mode 100644 drivers/input/misc/axp20x-pek.c
arch/arm/configs/sunxi_defconfig +2 -0
index f8aa7e6..d59c826 100644
@@ -39,6 +39,8 @@ CONFIG_SUN4I_EMAC=y
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 # CONFIG_WLAN is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AXP20X_PEK=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=8
drivers/input/misc/Kconfig +11 -0
index 5f4967d..c9438ac 100644
@@ -384,6 +384,17 @@ config INPUT_RETU_PWRBUTTON
 	  To compile this driver as a module, choose M here. The module will
 	  be called retu-pwrbutton.
 
+config INPUT_AXP20X_PEK
+	tristate "X-Powers AXP20X power button driver"
+	depends on MFD_AXP20X
+	help
+	  Say Y here if you want to enable power key reporting via the
+	  AXP20X PMIC.
+
+	  To compile this driver as a module, choose M here. The module will
+	  be called axp20x-pek.
+
+
 config INPUT_TWL4030_PWRBUTTON
 	tristate "TWL4030 Power button Driver"
 	depends on TWL4030_CORE
drivers/input/misc/Makefile +1 -0
index 0ebfb6d..41d5403 100644
@@ -49,6 +49,7 @@ obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
 obj-$(CONFIG_INPUT_PWM_BEEPER)		+= pwm-beeper.o
 obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
 obj-$(CONFIG_INPUT_RETU_PWRBUTTON)	+= retu-pwrbutton.o
+obj-$(CONFIG_INPUT_AXP20X_PEK)		+= axp20x-pek.o
 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
 obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)	+= sirfsoc-onkey.o
drivers/input/misc/axp20x-pek.c new file +22 -0
new file mode 100644
index 0000000..799275d
@@ -0,0 +1,265 @@
+/*
+ * axp20x power button driver.
+ *
+ * Copyright (C) 2013 Carlo Caione <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/axp20x.h>

drivers/input/misc/axp20x-pek.c line 32

Quoted 10 lines
drivers/input/misc/axp20x-pek.c new file +10 -0
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define AXP20X_PEK_STARTUP_MASK		(0xc0)
+#define AXP20X_PEK_SHUTDOWN_MASK	(0x03)
+
+static const char const *startup_time[] = { "128mS", "3S" , "1S", "2S" };
+static const char const *shutdown_time[] = { "4S", "6S" , "8S", "10S" };

I guess these are seconds. If so, a lowercase s in needed.

Quoted 236 lines
drivers/input/misc/axp20x-pek.c new file +233 -0
+
+struct axp20x_pek {
+	struct axp20x_dev *axp20x;
+	struct input_dev *input;
+	int irq_dbr;
+	int irq_dbf;
+};
+
+struct axp20x_pek_ext_attr {
+	const char const **str;
+	unsigned int mask;
+};
+
+static struct axp20x_pek_ext_attr axp20x_pek_startup_ext_attr = {
+	.str	= startup_time,
+	.mask	= AXP20X_PEK_STARTUP_MASK,
+};
+
+static struct axp20x_pek_ext_attr axp20x_pek_shutdown_ext_attr = {
+	.str	= shutdown_time,
+	.mask	= AXP20X_PEK_SHUTDOWN_MASK,
+};
+
+static struct axp20x_pek_ext_attr *get_axp_ext_attr(struct device_attribute *attr)
+{
+	return container_of(attr, struct dev_ext_attribute, attr)->var;
+}
+
+ssize_t axp20x_show_ext_attr(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
+	struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
+	unsigned int val;
+	int ret, i;
+	int cnt = 0;
+
+	ret = regmap_read(axp20x_pek->axp20x->regmap, AXP20X_PEK_KEY, &val);
+	if (ret != 0)
+		return ret;
+
+	val &= axp20x_ea->mask;
+	val >>= ffs(axp20x_ea->mask) - 1;
+
+	for (i = 0; i < 4; i++) {
+		if (val == i)
+			cnt += sprintf(buf + cnt, "[%s] ", axp20x_ea->str[i]);
+		else
+			cnt += sprintf(buf + cnt, "%s ", axp20x_ea->str[i]);
+	}
+
+	cnt += sprintf(buf + cnt, "\n");
+
+	return cnt;
+}
+
+ssize_t axp20x_store_ext_attr(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
+	struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
+	char val_str[20];
+	int ret, i;
+	size_t len;
+
+	val_str[sizeof(val_str) - 1] = '\0';
+	strncpy(val_str, buf, sizeof(val_str) - 1);
+	len = strlen(val_str);
+
+	if (len && val_str[len - 1] == '\n')
+		val_str[len - 1] = '\0';
+
+	for (i = 0; i < 4; i++) {
+		if (!strcmp(val_str, axp20x_ea->str[i])) {
+			ret = regmap_update_bits(axp20x_pek->axp20x->regmap,
+						 AXP20X_PEK_KEY,
+						 axp20x_ea->mask, i);
+			if (ret != 0)
+				return -EINVAL;
+			return count;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static struct dev_ext_attribute axp20x_dev_attr_startup = {
+	.attr	= __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
+	.var	= &axp20x_pek_startup_ext_attr
+};
+
+static struct dev_ext_attribute axp20x_dev_attr_shutdown = {
+	__ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
+	&axp20x_pek_shutdown_ext_attr
+};
+
+static struct attribute *dev_attrs[] = {
+	&axp20x_dev_attr_startup.attr.attr,
+	&axp20x_dev_attr_shutdown.attr.attr,
+	NULL,
+};
+
+static struct attribute_group dev_attr_group = {
+	.attrs	= dev_attrs,
+};
+
+static const struct attribute_group *dev_attr_groups[] = {
+	&dev_attr_group,
+	NULL,
+};
+
+static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
+{
+	struct input_dev *idev = pwr;
+	struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);
+
+	if (irq == axp20x_pek->irq_dbr)
+		input_report_key(idev, KEY_POWER, true);
+	else if (irq == axp20x_pek->irq_dbf)
+		input_report_key(idev, KEY_POWER, false);
+
+	input_sync(idev);
+
+	return IRQ_HANDLED;
+}
+
+static int axp20x_pek_probe(struct platform_device *pdev)
+{
+	struct axp20x_pek *axp20x_pek;
+	struct axp20x_dev *axp20x;
+	struct input_dev *idev;
+	int error;
+
+	axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
+				  GFP_KERNEL);
+	if (!axp20x_pek)
+		return -ENOMEM;
+
+	axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
+	axp20x = axp20x_pek->axp20x;
+
+	axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
+	if (axp20x_pek->irq_dbr < 0) {
+		dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n",
+				axp20x_pek->irq_dbr);
+		return axp20x_pek->irq_dbr;
+	}
+	axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
+						  axp20x_pek->irq_dbr);
+
+	axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
+	if (axp20x_pek->irq_dbf < 0) {
+		dev_err(&pdev->dev, "No IRQ for PEK_DBF, error=%d\n",
+				axp20x_pek->irq_dbf);
+		return axp20x_pek->irq_dbf;
+	}
+	axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
+						  axp20x_pek->irq_dbf);
+
+	axp20x_pek->input = devm_input_allocate_device(&pdev->dev);
+	if (!axp20x_pek->input)
+		return -ENOMEM;
+
+	idev = axp20x_pek->input;
+
+	idev->name = "axp20x-pek";
+	idev->phys = "m1kbd/input2";
+	idev->dev.parent = &pdev->dev;
+
+	input_set_capability(idev, EV_KEY, KEY_POWER);
+
+	input_set_drvdata(idev, axp20x_pek);
+
+	error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbr,
+					  NULL, axp20x_pek_irq, 0,
+					  "axp20x-pek-dbr", idev);
+	if (error) {
+		dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n",
+			axp20x_pek->irq_dbr, error);
+
+		return error;
+	}
+
+	error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbf,
+					  NULL, axp20x_pek_irq, 0,
+					  "axp20x-pek-dbf", idev);
+	if (error) {
+		dev_err(axp20x->dev, "Failed to request dbf IRQ#%d: %d\n",
+			axp20x_pek->irq_dbf, error);
+		return error;
+	}
+
+	idev->dev.groups = dev_attr_groups;
+	error = input_register_device(idev);
+	if (error) {
+		dev_err(axp20x->dev, "Can't register input device: %d\n", error);
+		return error;
+	}
+
+	platform_set_drvdata(pdev, axp20x_pek);
+
+	return 0;
+}
+
+static int axp20x_pek_remove(struct platform_device *pdev)
+{
+	struct axp20x_pek *axp20x_pek = platform_get_drvdata(pdev);
+
+	input_unregister_device(axp20x_pek->input);
+
+	return 0;
+}
+
+static const struct of_device_id axp20x_pek_match[] = {
+	{ .compatible = "x-powers,axp20x-pek", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, axp20x_pek_match);
+
+static struct platform_driver axp20x_pek_driver = {
+	.probe		= axp20x_pek_probe,
+	.remove		= axp20x_pek_remove,
+	.driver		= {
+		.name		= "axp20x-pek",
+		.owner		= THIS_MODULE,
+		.of_match_table	= axp20x_pek_match,
+	},
+};
+module_platform_driver(axp20x_pek_driver);
+
+MODULE_DESCRIPTION("axp20x Power Button");
+MODULE_AUTHOR("Carlo Caione <[email protected]>");
+MODULE_LICENSE("GPL");
Signature · 1 line
1.8.3.2
Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140307/eacc6a62/attachment.sig>
#12 lore raw

PATCH 5/7 input: misc: Add ABI docs for AXP20x PEK

In reply to Carlo Caione

Add ABI entries for the PEK found on PMU X-Powers AXP202 and AXP209.

---
 Documentation/ABI/testing/sysfs-driver-input-axp-pek | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-input-axp-pek
Documentation/ABI/testing/sysfs-driver-input-axp-pek new file +11 -0
new file mode 100644
index 0000000..f8cdad2
@@ -0,0 +1,11 @@
+What:		/sys/class/input/input(x)/startup
+Date:		March 2014
+Contact:	Carlo Caione <[email protected]>
+Description:	Startup time. Board is powered on if the button is pressed
+		for more than <startup_time>
+
+What:		/sys/class/input/input(x)/shutdown
+Date:		March 2014
+Contact:	Carlo Caione <[email protected]>
+Description:	Shutdown time. Board is powered off if the button is pressed
+		for more than <shutdown_time>
Signature · 1 line
1.8.3.2
#13 lore raw

PATCH 6/7 regulator: AXP20x: Add support for regulators subsystem

In reply to Carlo Caione

AXP202 and AXP209 come with two synchronous step-down DC-DCs and five LDOs. This patch introduces basic support for those regulators.

---
 arch/arm/configs/sunxi_defconfig     |   1 +
 drivers/regulator/Kconfig            |   7 +
 drivers/regulator/Makefile           |   1 +
 drivers/regulator/axp20x-regulator.c | 349 +++++++++++++++++++++++++++++++++++
 4 files changed, 358 insertions(+)
 create mode 100644 drivers/regulator/axp20x-regulator.c
arch/arm/configs/sunxi_defconfig +1 -0
index d59c826..0cef101 100644
@@ -69,3 +69,4 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS=y
 CONFIG_PRINTK_TIME=y
+CONFIG_REGULATOR_AXP20X=y
drivers/regulator/Kconfig +7 -0
index ce785f4..4cf9e32 100644
@@ -131,6 +131,13 @@ config REGULATOR_AS3722
 	  AS3722 PMIC. This will enable support for all the software
 	  controllable DCDC/LDO regulators.
 
+config REGULATOR_AXP20X
+	tristate "X-POWERS AXP20X PMIC Regulators"
+	depends on MFD_AXP20X
+	help
+	  This driver provides support for the voltage regulators on the
+	  AXP20X PMIC.
+
 config REGULATOR_DA903X
 	tristate "Dialog Semiconductor DA9030/DA9034 regulators"
 	depends on PMIC_DA903X
drivers/regulator/Makefile +1 -0
index 01c597e..2cf4646 100644
@@ -19,6 +19,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
 obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
 obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
 obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
+obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
 obj-$(CONFIG_REGULATOR_DA9052)	+= da9052-regulator.o
 obj-$(CONFIG_REGULATOR_DA9055)	+= da9055-regulator.o
drivers/regulator/axp20x-regulator.c new file +349 -0

349 lines not on this page · raw message

Signature · 1 line
1.8.3.2
maintainer
#14 lore raw

PATCH 6/7 regulator: AXP20x: Add support for regulators subsystem

arch/arm/configs/sunxi_defconfig CONFIG_NFS_FS=y · line 72

Quoted 8 lines · Carlo Caione

index d59c826..0cef101 100644

arch/arm/configs/sunxi_defconfig +1 -0
@@ -69,3 +69,4 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS=y
 CONFIG_PRINTK_TIME=y
+CONFIG_REGULATOR_AXP20X=y

If you want to update the defconfig do it in a separate patch.

arch/arm/configs/sunxi_defconfig

Quoted 4 lines
arch/arm/configs/sunxi_defconfig +4 -0
+static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV)
+{
+	return regulator_set_voltage_sel_regmap(rdev, 0);
+}

I'm not entirely clear what this is supposed to do but it's broken - it both ignores the voltage that is passed in and immediately writes to the normal voltage select register which will presumably distrupt the system.

arch/arm/configs/sunxi_defconfig

Quoted 5 lines
arch/arm/configs/sunxi_defconfig +5 -0
+static int axp20x_io_enable_regmap(struct regulator_dev *rdev)
+{
+	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+				  rdev->desc->enable_mask, AXP20X_IO_ENABLED);
+}

Please make some helpers for this (or extend the existing ones to cope with more than a single bit control) - there's several other devices which have similar multi-bit controls so we should factor this out rather than open coding.

arch/arm/configs/sunxi_defconfig

Quoted 9 lines
arch/arm/configs/sunxi_defconfig +9 -0
+	np = of_node_get(pdev->dev.parent->of_node);
+	if (!np)
+		return 0;
+
+	regulators = of_find_node_by_name(np, "regulators");
+	if (!regulators) {
+		dev_err(&pdev->dev, "regulators node not found\n");
+		return -EINVAL;
+	}

The driver should be able to start up with no configuration provided at all except for the device being registered - the user won't be able to change anything but they will be able to read the current state of the hardware which can be useful for diagnostics.

arch/arm/configs/sunxi_defconfig

Quoted 12 lines
arch/arm/configs/sunxi_defconfig +12 -0
+static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
+{
+	unsigned int mask = AXP20X_WORKMODE_DCDC2_MASK;
+
+	if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
+		return -EINVAL;
+
+	if (id == AXP20X_DCDC3)
+		mask = AXP20X_WORKMODE_DCDC3_MASK;
+
+	return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
+}

What is a workmode?

arch/arm/configs/sunxi_defconfig

Quoted 2 lines
arch/arm/configs/sunxi_defconfig +2 -0
+		pmic->rdev[i] = regulator_register(&pmic->rdesc[i], &config);
+		if (IS_ERR(pmic->rdev[i])) {

Use devm_regulator_register() and then you don't need to clean up the regulators either.

arch/arm/configs/sunxi_defconfig

Quoted 6 lines
arch/arm/configs/sunxi_defconfig +6 -0
+static int __init axp20x_regulator_init(void)
+{
+	return platform_driver_register(&axp20x_regulator_driver);
+}
+
+subsys_initcall(axp20x_regulator_init);

module_platform_driver().
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140303/19ba4f02/attachment.sig>

#15 lore raw

[linux-sunxi] Re: [PATCH 6/7] regulator: AXP20x: Add support for regulators subsystem

Quoted 12 lines · Mark Brown

arch/arm/configs/sunxi_defconfig CONFIG_NFS_FS=y · line 72

Quoted 8 lines · Carlo Caione

index d59c826..0cef101 100644

arch/arm/configs/sunxi_defconfig +1 -0
@@ -69,3 +69,4 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS=y
 CONFIG_PRINTK_TIME=y
+CONFIG_REGULATOR_AXP20X=y

If you want to update the defconfig do it in a separate patch.

Ok, I'll split the patch.

Quoted 4 lines

arch/arm/configs/sunxi_defconfig

Quoted 4 lines
arch/arm/configs/sunxi_defconfig +4 -0
+static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV)
+{
+     return regulator_set_voltage_sel_regmap(rdev, 0);
+}

Right. I'll fix it in v2.

Quoted 4 lines

I'm not entirely clear what this is supposed to do but it's broken - it both ignores the voltage that is passed in and immediately writes to the normal voltage select register which will presumably distrupt the system.

Quoted 10 lines

arch/arm/configs/sunxi_defconfig

Quoted 5 lines
arch/arm/configs/sunxi_defconfig +5 -0
+static int axp20x_io_enable_regmap(struct regulator_dev *rdev)
+{
+     return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+                               rdev->desc->enable_mask, AXP20X_IO_ENABLED);
+}

Please make some helpers for this (or extend the existing ones to cope with more than a single bit control) - there's several other devices which have similar multi-bit controls so we should factor this out rather than open coding.

No prob, I'll submit a patch for the helpers before submitting the v2 of this patchset

Quoted 10 lines

arch/arm/configs/sunxi_defconfig

Quoted 9 lines
arch/arm/configs/sunxi_defconfig +9 -0
+     np = of_node_get(pdev->dev.parent->of_node);
+     if (!np)
+             return 0;
+
+     regulators = of_find_node_by_name(np, "regulators");
+     if (!regulators) {
+             dev_err(&pdev->dev, "regulators node not found\n");
+             return -EINVAL;
+     }
Quoted 4 lines

The driver should be able to start up with no configuration provided at all except for the device being registered - the user won't be able to change anything but they will be able to read the current state of the hardware which can be useful for diagnostics.

seems reasonable

Quoted 6 lines
Quoted 6 lines
arch/arm/configs/sunxi_defconfig +6 -0
+static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
+{
+     unsigned int mask = AXP20X_WORKMODE_DCDC2_MASK;
+
+     if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
+             return -EINVAL;
Quoted 8 lines

arch/arm/configs/sunxi_defconfig

Quoted 6 lines
arch/arm/configs/sunxi_defconfig +6 -0
+
+     if (id == AXP20X_DCDC3)
+             mask = AXP20X_WORKMODE_DCDC3_MASK;
+
+     return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
+}

What is a workmode?

It defines if the output from DCDC2 or DCDC3 (that can be used as PWM chargers). I'll document it better in the bindings documentation.

Quoted 6 lines

arch/arm/configs/sunxi_defconfig

Quoted 2 lines
arch/arm/configs/sunxi_defconfig +2 -0
+             pmic->rdev[i] = regulator_register(&pmic->rdesc[i], &config);
+             if (IS_ERR(pmic->rdev[i])) {

Use devm_regulator_register() and then you don't need to clean up the regulators either.

Quoted 8 lines

arch/arm/configs/sunxi_defconfig

Quoted 6 lines
arch/arm/configs/sunxi_defconfig +6 -0
+static int __init axp20x_regulator_init(void)
+{
+     return platform_driver_register(&axp20x_regulator_driver);
+}
+
+subsys_initcall(axp20x_regulator_init);

module_platform_driver().

I'll fix both in v2.

Thank you,

Signature · 1 line
Carlo Caione
#16 lore raw

[linux-sunxi] Re: [PATCH 6/7] regulator: AXP20x: Add support for regulators subsystem

In reply to Mark Brown

On Mon, Mar 03, 2014 at 10:56:16AM +0900, Mark Brown wrote:

<snip>

Quoted 6 lines
Quoted 6 lines
drivers/regulator/axp20x-regulator.c new file +6 -0
+	np = of_node_get(pdev->dev.parent->of_node);
+	if (!np)
+		return 0;
+
+	regulators = of_find_node_by_name(np, "regulators");
+	if (!regulators) {
Quoted 8 lines

drivers/regulator/axp20x-regulator.c line 225

Quoted 3 lines
drivers/regulator/axp20x-regulator.c new file +3 -0
+		dev_err(&pdev->dev, "regulators node not found\n");
+		return -EINVAL;
+	}

The driver should be able to start up with no configuration provided at all except for the device being registered - the user won't be able to change anything but they will be able to read the current state of the hardware which can be useful for diagnostics.

If the device is DT enabled and no configuration is provided for regulators, these are disabled according to:

http://lxr.linux.no/linux+v3.13.5/drivers/regulator/core.c#L3797

Am I missing something or do you have any pointer?

Thanks,

Signature · 1 line
Carlo Caione
maintainer
#17 lore raw

[linux-sunxi] Re: [PATCH 6/7] regulator: AXP20x: Add support for regulators subsystem

Quoted 13 lines · Carlo Caione
Quoted 10 lines · Mark Brown

drivers/regulator/axp20x-regulator.c line 225

Quoted 5 lines
drivers/regulator/axp20x-regulator.c new file +5 -0
+	regulators = of_find_node_by_name(np, "regulators");
+	if (!regulators) {
+		dev_err(&pdev->dev, "regulators node not found\n");
+		return -EINVAL;
+	}

The driver should be able to start up with no configuration provided at all except for the device being registered - the user won't be able to change anything but they will be able to read the current state of the hardware which can be useful for diagnostics.

Quoted 6 lines

If the device is DT enabled and no configuration is provided for regulators, these are disabled according to:

http://lxr.linux.no/linux+v3.13.5/drivers/regulator/core.c#L3797

Am I missing something or do you have any pointer?

With the above code the driver will return an error and never get as far
as registering the regulator.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140311/fdccf963/attachment-0001.sig>

#18 lore raw

[linux-sunxi] Re: [PATCH 6/7] regulator: AXP20x: Add support for regulators subsystem

Quoted 17 lines · Mark Brown
Quoted 15 lines · Carlo Caione
Quoted 10 lines · Mark Brown

drivers/regulator/axp20x-regulator.c line 225

Quoted 5 lines
drivers/regulator/axp20x-regulator.c new file +5 -0
+	regulators = of_find_node_by_name(np, "regulators");
+	if (!regulators) {
+		dev_err(&pdev->dev, "regulators node not found\n");
+		return -EINVAL;
+	}

The driver should be able to start up with no configuration provided at all except for the device being registered - the user won't be able to change anything but they will be able to read the current state of the hardware which can be useful for diagnostics.

If the device is DT enabled and no configuration is provided for regulators, these are disabled according to:

Quoted 6 lines
Quoted 3 lines

http://lxr.linux.no/linux+v3.13.5/drivers/regulator/core.c#L3797

Am I missing something or do you have any pointer?

With the above code the driver will return an error and never get as far as registering the regulator.

I agree, but if I register the regulators without having the constrains defined in the DT, when regulator_init_complete() is
called, the regulators are disabled powering off the SoC (at least for DCDC2 and DCDC3).

Thanks,

Signature · 1 line
Carlo Caione
maintainer
#19 lore raw

[linux-sunxi] Re: [PATCH 6/7] regulator: AXP20x: Add support for regulators subsystem

Quoted 9 lines · Carlo Caione
Quoted 2 lines · Mark Brown

With the above code the driver will return an error and never get as far as registering the regulator.

I agree, but if I register the regulators without having the constrains defined in the DT, when regulator_init_complete() is
called, the regulators are disabled powering off the SoC (at least for DCDC2 and DCDC3).

Right, but the kernel will say what it's doing before it does so and
then the user can provide the appropriate setup in DT to force things
on.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140312/816efa6f/attachment.sig>

#20 lore raw

PATCH 6/7 regulator: AXP20x: Add support for regulators subsystem

In reply to Carlo Caione
Quoted 5 lines · Carlo Caione
drivers/regulator/axp20x-regulator.c new file +5 -0
+static struct platform_driver axp20x_regulator_driver = {
+	.probe	= axp20x_regulator_probe,
+	.remove	= axp20x_regulator_remove,
+	.driver	= {
+		.name		= "axp20x-regulator",

drivers/regulator/axp20x-regulator.c line 345

Quoted 10 lines
drivers/regulator/axp20x-regulator.c new file +10 -0
+		.owner		= THIS_MODULE,
+	},
+};
+
+static int __init axp20x_regulator_init(void)
+{
+	return platform_driver_register(&axp20x_regulator_driver);
+}
+
+subsys_initcall(axp20x_regulator_init);

Hmmm, really?

I thought the AXP was only connected through I2C? How is that a platform device then?

Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140307/f0704cd2/attachment.sig>
#21 lore raw

[linux-sunxi] Re: [PATCH 6/7] regulator: AXP20x: Add support for regulators subsystem

Quoted 19 lines · Maxime Ripard
Quoted 5 lines · Carlo Caione
drivers/regulator/axp20x-regulator.c new file +5 -0
+static struct platform_driver axp20x_regulator_driver = {
+     .probe  = axp20x_regulator_probe,
+     .remove = axp20x_regulator_remove,
+     .driver = {
+             .name           = "axp20x-regulator",

drivers/regulator/axp20x-regulator.c line 345

Quoted 10 lines
drivers/regulator/axp20x-regulator.c new file +10 -0
+             .owner          = THIS_MODULE,
+     },
+};
+
+static int __init axp20x_regulator_init(void)
+{
+     return platform_driver_register(&axp20x_regulator_driver);
+}
+
+subsys_initcall(axp20x_regulator_init);

Hmmm, really?

Quoted 2 lines

I thought the AXP was only connected through I2C? How is that a platform device then?

Not really. It is plain wrong.
I'll fix it in v2.

Thanks,

Signature · 1 line
Carlo Caione
maintainer
#22 lore raw

[linux-sunxi] Re: [PATCH 6/7] regulator: AXP20x: Add support for regulators subsystem

Quoted 10 lines · Carlo Caione

On Fri, Mar 7, 2014 at 7:22 PM, Maxime Ripard

Quoted 6 lines · Carlo Caione
Quoted 2 lines

+ return platform_driver_register(&axp20x_regulator_driver);

I thought the AXP was only connected through I2C? How is that a platform device then?

Not really. It is plain wrong.
I'll fix it in v2.

Are you sure this is wrong? For MFDs the core MFD is a driver of
whatever bus type is in use but the function drivers are platform
devices which talk to the hardware via the core device.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140309/6dc1f954/attachment-0001.sig>

#23 lore raw

[linux-sunxi] Re: [PATCH 6/7] regulator: AXP20x: Add support for regulators subsystem

Quoted 9 lines · Mark Brown
Quoted 7 lines · Carlo Caione

On Fri, Mar 7, 2014 at 7:22 PM, Maxime Ripard

Quoted 6 lines · Carlo Caione
Quoted 2 lines

+ return platform_driver_register(&axp20x_regulator_driver);

I thought the AXP was only connected through I2C? How is that a platform device then?

Quoted 6 lines
Quoted 2 lines

Not really. It is plain wrong.
I'll fix it in v2.

Are you sure this is wrong? For MFDs the core MFD is a driver of whatever bus type is in use but the function drivers are platform devices which talk to the hardware via the core device.

ok, I spoke too soon. Sorry for the noise.

Signature · 1 line
Carlo Caione
#24 lore raw

PATCH 7/7 ARM: dts: Cubieboard2: Add support for AXP209 regulators

In reply to Carlo Caione

This patch enables basic support for regulators found in AXP209 on Cubieboard2.

---
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 44 +++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts +44 -0
index 234b14b..2a0185a 100644
@@ -66,6 +66,50 @@
 				compatible = "x-powers,axp209";
 				interrupt-controller;
 				#interrupt-cells = <1>;
+
+				regulators {
+					dcdc-freq = "8";
+
+					axp_dcdc2: dcdc2 {
+						regulator-min-microvolt = <700000>;
+						regulator-max-microvolt = <2275000>;
+						dcdc-workmode = <0>;
+						regulator-always-on;
+					};
+
+					axp_dcdc3: dcdc3 {
+						regulator-min-microvolt = <700000>;
+						regulator-max-microvolt = <3500000>;
+						dcdc-workmode = <0>;
+						regulator-always-on;
+					};
+
+					axp_ldo1: ldo1 {
+						regulator-min-microvolt = <1300000>;
+						regulator-max-microvolt = <1300000>;
+					};
+
+					axp_ldo2: ldo2 {
+						regulator-min-microvolt = <1800000>;
+						regulator-max-microvolt = <3300000>;
+						regulator-always-on;
+					};
+
+					axp_ldo3: ldo3 {
+						regulator-min-microvolt = <700000>;
+						regulator-max-microvolt = <3500000>;
+					};
+
+					axp_ldo4: ldo4 {
+						regulator-min-microvolt = <1250000>;
+						regulator-max-microvolt = <3300000>;
+					};
+
+					axp_ldo5: ldo5 {
+						regulator-min-microvolt = <1800000>;
+						regulator-max-microvolt = <3300000>;
+					};
+				};
 			};
 		};
 
Signature · 1 line
1.8.3.2
#25 lore raw

cover mfd: AXP20x: Add support for AXP202 and AXP209

In reply to Carlo Caione

Hi Carlo,

Great work, thanks for all the time you're putting into this!

I've 2 questions:

1) What dependencies does this patch-set have? Obviously it needs the NMI irq patches for A20, anything else ? I no longer see any use of a special flag for ack on unmask, is that no longer needed ?

2) No poweroff functionality ? That would be really great to have.

Regards,

Hans

Quoted 44 lines · Carlo Caione

AXP209 and AXP202 are the PMUs (Power Management Unit) used by A10, A13 and A20 SoCs and developed by X-Powers, a sister company of Allwinner. AXP20x comprises an adaptive USB-Compatible PWM charger, 2 BUCK DC-DC converters, 5 LDOs, multiple 12-bit ADCs of voltage, current and temperature as well as 4 configurable GPIOs.

This set of patches introduces the core driver and support for two different subsystems:
- Regulators
- PEK (Power Enable Key)

Support for AXP209 in Cubieboard2 is also added.

Carlo Caione (7):
mfd: AXP20x: Add mfd driver for AXP20x PMIC
mfd: AXP20x: Add bindings documentation
ARM: dts: cubieboard2: Add AXP209 support
input: misc: Add driver for AXP20x Power Enable Key
input: misc: Add ABI docs for AXP20x PEK
regulator: AXP20x: Add support for regulators subsystem
ARM: dts: Cubieboard2: Add support for AXP209 regulators

 .../ABI/testing/sysfs-driver-input-axp-pek         |  11 +
 Documentation/devicetree/bindings/mfd/axp20x.txt   |  93 ++++++
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts        |  58 ++++
 arch/arm/configs/sunxi_defconfig                   |   4 +
 drivers/input/misc/Kconfig                         |  11 +
 drivers/input/misc/Makefile                        |   1 +
 drivers/input/misc/axp20x-pek.c                    | 265 ++++++++++++++++
 drivers/mfd/Kconfig                                |  12 +
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/axp20x.c                               | 250 +++++++++++++++
 drivers/regulator/Kconfig                          |   7 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/axp20x-regulator.c               | 349 +++++++++++++++++++++
 include/linux/mfd/axp20x.h                         | 180 +++++++++++
 14 files changed, 1243 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-input-axp-pek
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt
 create mode 100644 drivers/input/misc/axp20x-pek.c
 create mode 100644 drivers/mfd/axp20x.c
 create mode 100644 drivers/regulator/axp20x-regulator.c
 create mode 100644 include/linux/mfd/axp20x.h
#26 lore raw

cover mfd: AXP20x: Add support for AXP202 and AXP209

Quoted 3 lines · Hans de Goede

Hi Carlo,

Great work, thanks for all the time you're putting into this!

Hi Hans :)

Quoted 5 lines

I've 2 questions:

1) What dependencies does this patch-set have? Obviously it needs the NMI irq patches for A20, anything else ? I no longer see any use of a special flag for ack on unmask, is that no longer needed ?

Yes, the only dependency is on the NMI controller patch. After a discussion with Maxime and Thomas I decided to not push for including the special flag for ack on unmask in the irqchip core but to use the unmask callback as in the v3 version of the NMI controller driver (so no flag needed)

Quoted 1 line

2) No poweroff functionality ? That would be really great to have.

Actually in [PATCH 1/7] I support the poweroff using the pm_power_off hook.

Best,

Signature · 1 line
Carlo Caione
#27 lore raw

Hi,

Quoted 19 lines · Carlo Caione
Quoted 3 lines · Hans de Goede

Hi Carlo,

Great work, thanks for all the time you're putting into this!

Hi Hans :)

Quoted 5 lines

I've 2 questions:

1) What dependencies does this patch-set have? Obviously it needs the NMI irq patches for A20, anything else ? I no longer see any use of a special flag for ack on unmask, is that no longer needed ?

Yes, the only dependency is on the NMI controller patch. After a discussion with Maxime and Thomas I decided to not push for including the special flag for ack on unmask in the irqchip core but to use the unmask callback as in the v3 version of the NMI controller driver (so no flag needed)

Quoted 3 lines
Quoted 1 line

2) No poweroff functionality ? That would be really great to have.

Actually in [PATCH 1/7] I support the poweroff using the pm_power_off hook.

Ah I missed that, cool.

I'm doing with sunxi hacking for today, but I'll add these to sunxi-devel and them give them a test run tomorrow.

Regards,

Hans

#28 lore raw

Hi,

Quoted 22 lines · Hans de Goede

Hi,

Quoted 19 lines · Carlo Caione
Quoted 3 lines · Hans de Goede

Hi Carlo,

Great work, thanks for all the time you're putting into this!

Hi Hans :)

Quoted 5 lines

I've 2 questions:

1) What dependencies does this patch-set have? Obviously it needs the NMI irq patches for A20, anything else ? I no longer see any use of a special flag for ack on unmask, is that no longer needed ?

Yes, the only dependency is on the NMI controller patch. After a discussion with Maxime and Thomas I decided to not push for including the special flag for ack on unmask in the irqchip core but to use the unmask callback as in the v3 version of the NMI controller driver (so no flag needed)

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

2) No poweroff functionality ? That would be really great to have.

Actually in [PATCH 1/7] I support the poweroff using the pm_power_off hook.

Ah I missed that, cool.

I'm doing with sunxi hacking for today, but I'll add these to sunxi-devel and them give them a test run tomorrow.

So I've added your patches to my sunxi-devel tree and they work as advertised :)

I've also added dt support for the axp209 to the cubietruck dts file, to avoid things becoming a copy and paste fest I've introduced a new axp209.dtsi file, as well as did some fixes to the existing sun?i-a*.dtsi files, see my tree here:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-devel

If you agree this is a good idea feel free to steal it all for the next revision of your patch-set :)

Note that I've still left some copy-paste parts inside the per board dts files, specifically things which may differ per board, ie we know already that A10 boards will have a different interrupt parent for the interrupt.

Thanks for your work on this!

Regards,

Hans

#29 lore raw
Quoted 2 lines · Hans de Goede

So I've added your patches to my sunxi-devel tree and they work as advertised :)

Thank you for keeping the tree updated :)

Quoted 4 lines

I've also added dt support for the axp209 to the cubietruck dts file, to avoid things becoming a copy and paste fest I've introduced a new axp209.dtsi file, as well as did some fixes to the existing sun?i-a*.dtsi files, see my tree here:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-devel

That was also my idea (creating a new axp20x.dtsi) but it has been turned down by Maxime and Lee

Quoted 2 lines

If you agree this is a good idea feel free to steal it all for the next revision of your patch-set :)

I will do for sure, thanks

Quoted 3 lines

Note that I've still left some copy-paste parts inside the per board dts files, specifically things which may differ per board, ie we know already that A10 boards will have a different interrupt parent for the interrupt.

Yep, no prob.

Quoted 1 line

Thanks for your work on this!

Thank you!

Signature · 1 line
Carlo Caione
#30 lore raw

Hi,

Quoted 6 lines · Carlo Caione
Quoted 2 lines · Hans de Goede

So I've added your patches to my sunxi-devel tree and they work as advertised :)

Thank you for keeping the tree updated :)

Quoted 7 lines
Quoted 4 lines

I've also added dt support for the axp209 to the cubietruck dts file, to avoid things becoming a copy and paste fest I've introduced a new axp209.dtsi file, as well as did some fixes to the existing sun?i-a*.dtsi files, see my tree here:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-devel

That was also my idea (creating a new axp20x.dtsi) but it has been turned down by Maxime and Lee

Hmm, do you have a pointer to the mailinglist discussion about this ?

Regards,

Hans

#31 lore raw
Quoted 14 lines · Hans de Goede

Hi,

Quoted 11 lines · Carlo Caione
Quoted 2 lines · Hans de Goede

So I've added your patches to my sunxi-devel tree and they work as advertised :)

Thank you for keeping the tree updated :)

Quoted 4 lines

I've also added dt support for the axp209 to the cubietruck dts file, to avoid things becoming a copy and paste fest I've introduced a new axp209.dtsi file, as well as did some fixes to the existing sun?i-a*.dtsi files, see my tree here:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-devel

Quoted 4 lines
Quoted 2 lines

That was also my idea (creating a new axp20x.dtsi) but it has been turned down by Maxime and Lee

Hmm, do you have a pointer to the mailinglist discussion about this ?

Sure, http://www.spinics.net/lists/arm-kernel/msg306497.html

Best,

Signature · 1 line
Carlo Caione
#32 lore raw

Hi,

Quoted 15 lines · Carlo Caione
Quoted 14 lines · Hans de Goede

Hi,

Quoted 11 lines · Carlo Caione
Quoted 2 lines · Hans de Goede

So I've added your patches to my sunxi-devel tree and they work as advertised :)

Thank you for keeping the tree updated :)

Quoted 4 lines

I've also added dt support for the axp209 to the cubietruck dts file, to avoid things becoming a copy and paste fest I've introduced a new axp209.dtsi file, as well as did some fixes to the existing sun?i-a*.dtsi files, see my tree here:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-devel

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

That was also my idea (creating a new axp20x.dtsi) but it has been turned down by Maxime and Lee

Hmm, do you have a pointer to the mailinglist discussion about this ?

Sure, http://www.spinics.net/lists/arm-kernel/msg306497.html

Ah, yes but that is before you added all the regulators, which are a fixed part of the chip. Once you get long dts bits like that having a dtsi file makes a lot of sense IMHO. Note that the part of the dts this was discussing is actually the part I did not put in the dtis, since it can vary per board :)

Regards,

Hans

#33 lore raw
Quoted 5 lines · Hans de Goede

Ah, yes but that is before you added all the regulators, which are a fixed part of the chip. Once you get long dts bits like that having a dtsi file makes a lot of sense IMHO. Note that the part of the dts this was discussing is actually the part I did not put in the dtis, since it can vary per board :)

Oook, now it makes sense. The idea was to integrate axp20x.dtsi at a later time, but probably I was misunderstood. Thank you for clarifying it.
I'll put axp20x.dtsi back in v2.

Thanks,

Signature · 1 line
Carlo Caione