All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/10] mfd: AXP20x: Add support for AXP202 and AXP209
@ 2014-03-27 21:29 ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
  Cc: 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)

This patchset depends on patchsets:
	irq: sun4i IRQ 0 / ENMI fixes (Hans de Goede)
	ARM: sun7i/sun6i: irqchip: Irqchip driver for NMI controller (Carlo Caione)
	regulator: helpers: Modify helpers enabling multi-bit control (Carlo Caione)

Changes since v1:

	- Added a new standalone patch for defconfig

	- MFD core:
	  * Removed axp,system-power-controller property

	- Bindings documentation:
	  * Corrected description for dcdc-workmode property
	  * Removed unused axp20x-pek compatible

	- Input misc PEK driver:
	  * Fixed seconds in lower case

	- Regulators subsystem:
	  * Fixed axp20x_set_suspend_voltage()
	  * Switched to using multi-bit control for regulators
	  * When "regulators" node is not found driver doesn't quit
	  * Driver is now using devm_regulator_register()
	  * Added module_platform_driver() instead of subsys_initcall()

	- DT:
	  * Added new DTSI for AXP209
	  * Added support for cubietruck and olinuxino-micro

Changes since v2:

	- Added a new patch for multi_v7_defconfig to enable MFD core
	  and subsystems

	- DT:
	  * Dropped axp,system-power-controller property from DTS
	  * Moved compatible and interrupt-related properties from the
	    DTSI file to the DTS board files

	- Regulators subsystem:
	  * Deleted useless struct axp20x_regulators
	  * Added a warning when out of specs values are used for the
	    dcdc frequency

	- MFD core:
	  * Fixed coding style
	  * Removed IDs from device table for i2c

	- Bindings documentation:
	  * Several corrections and fixes

Carlo Caione (10):
  mfd: AXP20x: Add mfd driver for AXP20x PMIC
  dt-bindings: add vendor-prefix for X-Powers
  mfd: AXP20x: Add bindings documentation
  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: sunxi: dt: Add x-powers-axp209.dtsi file
  ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  ARM: sunxi: Add AXP20x support in defconfig
  ARM: sunxi: Add AXP20x support multi_v7_defconfig

 .../ABI/testing/sysfs-driver-input-axp-pek         |  11 +
 Documentation/devicetree/bindings/mfd/axp20x.txt   |  83 ++++++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/arm/boot/dts/sun4i-a10-a1000.dts              |  13 +
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts         |  13 +
 arch/arm/boot/dts/sun4i-a10-hackberry.dts          |  19 ++
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts          |  13 +
 arch/arm/boot/dts/sun4i-a10-mini-xplus.dts         |  19 ++
 arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts     |  19 ++
 arch/arm/boot/dts/sun4i-a10-pcduino.dts            |  13 +
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts        |  14 ++
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |  15 ++
 arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts    |  14 ++
 arch/arm/boot/dts/x-powers-axp209.dtsi             |  54 ++++
 arch/arm/configs/multi_v7_defconfig                |   3 +
 arch/arm/configs/sunxi_defconfig                   |   4 +
 drivers/input/misc/Kconfig                         |  11 +
 drivers/input/misc/Makefile                        |   1 +
 drivers/input/misc/axp20x-pek.c                    | 260 +++++++++++++++++++
 drivers/mfd/Kconfig                                |  12 +
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/axp20x.c                               | 240 ++++++++++++++++++
 drivers/regulator/Kconfig                          |   7 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/axp20x-regulator.c               | 280 +++++++++++++++++++++
 include/linux/mfd/axp20x.h                         | 180 +++++++++++++
 26 files changed, 1301 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-input-axp-pek
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt
 create mode 100644 arch/arm/boot/dts/x-powers-axp209.dtsi
 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

-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 00/10] mfd: AXP20x: Add support for AXP202 and AXP209
@ 2014-03-27 21:29 ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

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)

This patchset depends on patchsets:
	irq: sun4i IRQ 0 / ENMI fixes (Hans de Goede)
	ARM: sun7i/sun6i: irqchip: Irqchip driver for NMI controller (Carlo Caione)
	regulator: helpers: Modify helpers enabling multi-bit control (Carlo Caione)

Changes since v1:

	- Added a new standalone patch for defconfig

	- MFD core:
	  * Removed axp,system-power-controller property

	- Bindings documentation:
	  * Corrected description for dcdc-workmode property
	  * Removed unused axp20x-pek compatible

	- Input misc PEK driver:
	  * Fixed seconds in lower case

	- Regulators subsystem:
	  * Fixed axp20x_set_suspend_voltage()
	  * Switched to using multi-bit control for regulators
	  * When "regulators" node is not found driver doesn't quit
	  * Driver is now using devm_regulator_register()
	  * Added module_platform_driver() instead of subsys_initcall()

	- DT:
	  * Added new DTSI for AXP209
	  * Added support for cubietruck and olinuxino-micro

Changes since v2:

	- Added a new patch for multi_v7_defconfig to enable MFD core
	  and subsystems

	- DT:
	  * Dropped axp,system-power-controller property from DTS
	  * Moved compatible and interrupt-related properties from the
	    DTSI file to the DTS board files

	- Regulators subsystem:
	  * Deleted useless struct axp20x_regulators
	  * Added a warning when out of specs values are used for the
	    dcdc frequency

	- MFD core:
	  * Fixed coding style
	  * Removed IDs from device table for i2c

	- Bindings documentation:
	  * Several corrections and fixes

Carlo Caione (10):
  mfd: AXP20x: Add mfd driver for AXP20x PMIC
  dt-bindings: add vendor-prefix for X-Powers
  mfd: AXP20x: Add bindings documentation
  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: sunxi: dt: Add x-powers-axp209.dtsi file
  ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  ARM: sunxi: Add AXP20x support in defconfig
  ARM: sunxi: Add AXP20x support multi_v7_defconfig

 .../ABI/testing/sysfs-driver-input-axp-pek         |  11 +
 Documentation/devicetree/bindings/mfd/axp20x.txt   |  83 ++++++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/arm/boot/dts/sun4i-a10-a1000.dts              |  13 +
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts         |  13 +
 arch/arm/boot/dts/sun4i-a10-hackberry.dts          |  19 ++
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts          |  13 +
 arch/arm/boot/dts/sun4i-a10-mini-xplus.dts         |  19 ++
 arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts     |  19 ++
 arch/arm/boot/dts/sun4i-a10-pcduino.dts            |  13 +
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts        |  14 ++
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |  15 ++
 arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts    |  14 ++
 arch/arm/boot/dts/x-powers-axp209.dtsi             |  54 ++++
 arch/arm/configs/multi_v7_defconfig                |   3 +
 arch/arm/configs/sunxi_defconfig                   |   4 +
 drivers/input/misc/Kconfig                         |  11 +
 drivers/input/misc/Makefile                        |   1 +
 drivers/input/misc/axp20x-pek.c                    | 260 +++++++++++++++++++
 drivers/mfd/Kconfig                                |  12 +
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/axp20x.c                               | 240 ++++++++++++++++++
 drivers/regulator/Kconfig                          |   7 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/axp20x-regulator.c               | 280 +++++++++++++++++++++
 include/linux/mfd/axp20x.h                         | 180 +++++++++++++
 26 files changed, 1301 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-input-axp-pek
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt
 create mode 100644 arch/arm/boot/dts/x-powers-axp209.dtsi
 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

-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29     ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
  Cc: 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

Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
---
 drivers/mfd/Kconfig        |  12 +++
 drivers/mfd/Makefile       |   1 +
 drivers/mfd/axp20x.c       | 240 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/axp20x.h | 180 ++++++++++++++++++++++++++++++++++
 4 files changed, 433 insertions(+)
 create mode 100644 drivers/mfd/axp20x.c
 create mode 100644 include/linux/mfd/axp20x.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 49bb445..24ba61a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -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
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 5aea5ef..fb773b5 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -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_LP3943)	+= lp3943.o
 obj-$(CONFIG_MFD_LP8788)	+= lp8788.o lp8788-irq.o
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
new file mode 100644
index 0000000..f77a663
--- /dev/null
+++ b/drivers/mfd/axp20x.c
@@ -0,0 +1,240 @@
+/*
+ * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209
+ *
+ * Author: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
+ *
+ * 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 of_device_id axp20x_of_match[] = {
+	{ .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
+	{ .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, axp20x_of_match);
+
+static const struct i2c_device_id axp20x_i2c_id[] = {
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
+
+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,
+};
+
+static struct mfd_cell axp20x_cells[] = {
+	{
+		.name		= "axp20x-pek",
+		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
+		.resources	= axp20x_pek_resources,
+	}, {
+		.name		= "axp20x-regulator",
+	},
+};
+
+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;
+	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;
+	}
+
+	ret = regmap_add_irq_chip(axp20x->regmap, i2c->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) {
+		dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
+		regmap_del_irq_chip(i2c->irq, axp20x->regmap_irqc);
+		return ret;
+	}
+
+	if (!pm_power_off) {
+		axp20x_pm_power_off = axp20x;
+		pm_power_off = axp20x_power_off;
+	}
+
+	dev_info(&i2c->dev, "AXP20X driver loaded\n");
+
+	return 0;
+}
+
+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 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 <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
new file mode 100644
index 0000000..c7b1658
--- /dev/null
+++ b/include/linux/mfd/axp20x.h
@@ -0,0 +1,180 @@
+/*
+ * Functions and registers to access AXP20X power management chip.
+ *
+ * Copyright (C) 2013, Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
+ *
+ * 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
+
+enum {
+	AXP202_ID = 0,
+	AXP209_ID,
+};
+
+#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;
+};
+
+#endif /* __LINUX_MFD_AXP20X_H */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC
@ 2014-03-27 21:29     ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 drivers/mfd/Kconfig        |  12 +++
 drivers/mfd/Makefile       |   1 +
 drivers/mfd/axp20x.c       | 240 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/axp20x.h | 180 ++++++++++++++++++++++++++++++++++
 4 files changed, 433 insertions(+)
 create mode 100644 drivers/mfd/axp20x.c
 create mode 100644 include/linux/mfd/axp20x.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 49bb445..24ba61a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -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
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 5aea5ef..fb773b5 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -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_LP3943)	+= lp3943.o
 obj-$(CONFIG_MFD_LP8788)	+= lp8788.o lp8788-irq.o
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
new file mode 100644
index 0000000..f77a663
--- /dev/null
+++ b/drivers/mfd/axp20x.c
@@ -0,0 +1,240 @@
+/*
+ * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209
+ *
+ * Author: Carlo Caione <carlo@caione.org>
+ *
+ * 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 of_device_id axp20x_of_match[] = {
+	{ .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
+	{ .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, axp20x_of_match);
+
+static const struct i2c_device_id axp20x_i2c_id[] = {
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
+
+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,
+};
+
+static struct mfd_cell axp20x_cells[] = {
+	{
+		.name		= "axp20x-pek",
+		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
+		.resources	= axp20x_pek_resources,
+	}, {
+		.name		= "axp20x-regulator",
+	},
+};
+
+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;
+	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;
+	}
+
+	ret = regmap_add_irq_chip(axp20x->regmap, i2c->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) {
+		dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
+		regmap_del_irq_chip(i2c->irq, axp20x->regmap_irqc);
+		return ret;
+	}
+
+	if (!pm_power_off) {
+		axp20x_pm_power_off = axp20x;
+		pm_power_off = axp20x_power_off;
+	}
+
+	dev_info(&i2c->dev, "AXP20X driver loaded\n");
+
+	return 0;
+}
+
+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 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 <carlo@caione.org>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
new file mode 100644
index 0000000..c7b1658
--- /dev/null
+++ b/include/linux/mfd/axp20x.h
@@ -0,0 +1,180 @@
+/*
+ * Functions and registers to access AXP20X power management chip.
+ *
+ * Copyright (C) 2013, Carlo Caione <carlo@caione.org>
+ *
+ * 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
+
+enum {
+	AXP202_ID = 0,
+	AXP209_ID,
+};
+
+#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;
+};
+
+#endif /* __LINUX_MFD_AXP20X_H */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 02/10] dt-bindings: add vendor-prefix for X-Powers
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29     ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
  Cc: Carlo Caione

Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 40ce2df..d06ba8c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -95,3 +95,4 @@ winbond Winbond Electronics corp.
 wlf	Wolfson Microelectronics
 wm	Wondermedia Technologies, Inc.
 xlnx	Xilinx
+x-powers	X-Powers
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 02/10] dt-bindings: add vendor-prefix for X-Powers
@ 2014-03-27 21:29     ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 40ce2df..d06ba8c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -95,3 +95,4 @@ winbond Winbond Electronics corp.
 wlf	Wolfson Microelectronics
 wm	Wondermedia Technologies, Inc.
 xlnx	Xilinx
+x-powers	X-Powers
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 03/10] mfd: AXP20x: Add bindings documentation
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29     ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
  Cc: Carlo Caione

Bindings documentation for the AXP20x driver. In this file also
sub-nodes are documented.

Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
---
 Documentation/devicetree/bindings/mfd/axp20x.txt | 83 ++++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt

diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
new file mode 100644
index 0000000..ebc6772
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
@@ -0,0 +1,83 @@
+* 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
+
+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:
+
+	- x-powers,dcdc-freq	: defines the work frequency of DC-DC in KHz
+				  (range: 750-1875). Default: 1.5MHz
+
+	For each DCDC:
+		- x-powers,dcdc-workmode: Optional. 1 for PWM mode, 0 for AUTO mode
+				  	  Default: AUTO mode
+
+Example:
+
+axp: axp20x@34 {
+	reg = <0x34>;
+	interrupt-parent = <&nmi_intc>;
+	interrupts = <0 8>;
+
+	compatible = "x-powers,axp209";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	regulators {
+		dcdc-freq = <1500>;
+
+		axp_dcdc2: dcdc2 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <2275000>;
+			regulator-always-on;
+		};
+
+		axp_dcdc3: dcdc3 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <3500000>;
+			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>;
+		};
+	};
+};
+
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 03/10] mfd: AXP20x: Add bindings documentation
@ 2014-03-27 21:29     ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

Bindings documentation for the AXP20x driver. In this file also
sub-nodes are documented.

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 Documentation/devicetree/bindings/mfd/axp20x.txt | 83 ++++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt

diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
new file mode 100644
index 0000000..ebc6772
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
@@ -0,0 +1,83 @@
+* 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
+
+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:
+
+	- x-powers,dcdc-freq	: defines the work frequency of DC-DC in KHz
+				  (range: 750-1875). Default: 1.5MHz
+
+	For each DCDC:
+		- x-powers,dcdc-workmode: Optional. 1 for PWM mode, 0 for AUTO mode
+				  	  Default: AUTO mode
+
+Example:
+
+axp: axp20x at 34 {
+	reg = <0x34>;
+	interrupt-parent = <&nmi_intc>;
+	interrupts = <0 8>;
+
+	compatible = "x-powers,axp209";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	regulators {
+		dcdc-freq = <1500>;
+
+		axp_dcdc2: dcdc2 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <2275000>;
+			regulator-always-on;
+		};
+
+		axp_dcdc3: dcdc3 {
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <3500000>;
+			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>;
+		};
+	};
+};
+
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29     ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
  Cc: 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.

Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
---
 drivers/input/misc/Kconfig      |  11 ++
 drivers/input/misc/Makefile     |   1 +
 drivers/input/misc/axp20x-pek.c | 260 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 272 insertions(+)
 create mode 100644 drivers/input/misc/axp20x-pek.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7904ab0..87244fb 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -393,6 +393,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
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index cda71fc..624abf5 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -50,6 +50,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
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
new file mode 100644
index 0000000..6698a69
--- /dev/null
+++ b/drivers/input/misc/axp20x-pek.c
@@ -0,0 +1,260 @@
+/*
+ * axp20x power button driver.
+ *
+ * Copyright (C) 2013 Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
+ *
+ * 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>
+#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" };
+
+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;
+}
+
+static 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;
+}
+
+static 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])) {
+
+			i <<= ffs(axp20x_ea->mask) - 1;
+			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 struct platform_driver axp20x_pek_driver = {
+	.probe		= axp20x_pek_probe,
+	.remove		= axp20x_pek_remove,
+	.driver		= {
+		.name		= "axp20x-pek",
+		.owner		= THIS_MODULE,
+	},
+};
+module_platform_driver(axp20x_pek_driver);
+
+MODULE_DESCRIPTION("axp20x Power Button");
+MODULE_AUTHOR("Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>");
+MODULE_LICENSE("GPL");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key
@ 2014-03-27 21:29     ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 drivers/input/misc/Kconfig      |  11 ++
 drivers/input/misc/Makefile     |   1 +
 drivers/input/misc/axp20x-pek.c | 260 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 272 insertions(+)
 create mode 100644 drivers/input/misc/axp20x-pek.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7904ab0..87244fb 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -393,6 +393,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
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index cda71fc..624abf5 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -50,6 +50,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
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
new file mode 100644
index 0000000..6698a69
--- /dev/null
+++ b/drivers/input/misc/axp20x-pek.c
@@ -0,0 +1,260 @@
+/*
+ * axp20x power button driver.
+ *
+ * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
+ *
+ * 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>
+#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" };
+
+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;
+}
+
+static 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;
+}
+
+static 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])) {
+
+			i <<= ffs(axp20x_ea->mask) - 1;
+			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 struct platform_driver axp20x_pek_driver = {
+	.probe		= axp20x_pek_probe,
+	.remove		= axp20x_pek_remove,
+	.driver		= {
+		.name		= "axp20x-pek",
+		.owner		= THIS_MODULE,
+	},
+};
+module_platform_driver(axp20x_pek_driver);
+
+MODULE_DESCRIPTION("axp20x Power Button");
+MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
+MODULE_LICENSE("GPL");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 05/10] input: misc: Add ABI docs for AXP20x PEK
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29   ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-sunxi, maxime.ripard, hdegoede, emilio,
	wens, sameo, dmitry.torokhov, linux-input, linux-doc, lgirdwood,
	broonie
  Cc: Carlo Caione

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

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 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

diff --git a/Documentation/ABI/testing/sysfs-driver-input-axp-pek b/Documentation/ABI/testing/sysfs-driver-input-axp-pek
new file mode 100644
index 0000000..f8cdad2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-input-axp-pek
@@ -0,0 +1,11 @@
+What:		/sys/class/input/input(x)/startup
+Date:		March 2014
+Contact:	Carlo Caione <carlo@caione.org>
+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 <carlo@caione.org>
+Description:	Shutdown time. Board is powered off if the button is pressed
+		for more than <shutdown_time>
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 05/10] input: misc: Add ABI docs for AXP20x PEK
@ 2014-03-27 21:29   ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 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

diff --git a/Documentation/ABI/testing/sysfs-driver-input-axp-pek b/Documentation/ABI/testing/sysfs-driver-input-axp-pek
new file mode 100644
index 0000000..f8cdad2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-input-axp-pek
@@ -0,0 +1,11 @@
+What:		/sys/class/input/input(x)/startup
+Date:		March 2014
+Contact:	Carlo Caione <carlo@caione.org>
+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 <carlo@caione.org>
+Description:	Shutdown time. Board is powered off if the button is pressed
+		for more than <shutdown_time>
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29   ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-sunxi, maxime.ripard, hdegoede, emilio,
	wens, sameo, dmitry.torokhov, linux-input, linux-doc, lgirdwood,
	broonie
  Cc: Carlo Caione

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

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 drivers/regulator/Kconfig            |   7 +
 drivers/regulator/Makefile           |   1 +
 drivers/regulator/axp20x-regulator.c | 280 +++++++++++++++++++++++++++++++++++
 3 files changed, 288 insertions(+)
 create mode 100644 drivers/regulator/axp20x-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 6a79328..9f3bc48 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -139,6 +139,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
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 979f9dd..1dd084a 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -20,6 +20,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
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
new file mode 100644
index 0000000..3f1db88
--- /dev/null
+++ b/drivers/regulator/axp20x-regulator.c
@@ -0,0 +1,280 @@
+/*
+ * AXP20x regulators driver.
+ *
+ * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#define AXP20X_IO_ENABLED		(0x03)
+#define AXP20X_IO_DISABLED		(0x07)
+
+#define AXP20X_WORKMODE_DCDC2_MASK	BIT(2)
+#define AXP20X_WORKMODE_DCDC3_MASK	BIT(1)
+
+#define AXP20X_FREQ_DCDC_MASK		(0x0f)
+
+#define AXP20X_DESC_IO(_id, _min, _max, _step, _vreg, _vmask, _ereg, _emask, 	\
+		       _enable_val, _disable_val)				\
+	[AXP20X_##_id] = {							\
+		.name		= #_id,						\
+		.type		= REGULATOR_VOLTAGE,				\
+		.id		= AXP20X_##_id,					\
+		.n_voltages	= (((_max) - (_min)) / (_step) + 1),		\
+		.owner		= THIS_MODULE,					\
+		.min_uV		= (_min) * 1000,				\
+		.uV_step	= (_step) * 1000,				\
+		.vsel_reg	= (_vreg),					\
+		.vsel_mask	= (_vmask),					\
+		.enable_reg	= (_ereg),					\
+		.enable_mask	= (_emask),					\
+		.enable_val	= (_enable_val),				\
+		.disable_val	= (_disable_val),				\
+		.ops		= &axp20x_ops,					\
+	}
+
+#define AXP20X_DESC(_id, _min, _max, _step, _vreg, _vmask, _ereg, _emask) 	\
+	AXP20X_DESC_IO(_id, _min, _max, _step, _vreg, _vmask, _ereg, _emask,	\
+		       0, 0)
+
+#define AXP20X_DESC_FIXED(_id, _volt)						\
+	[AXP20X_##_id] = {							\
+		.name		= #_id,						\
+		.type		= REGULATOR_VOLTAGE,				\
+		.id		= AXP20X_##_id,					\
+		.n_voltages	= 1,						\
+		.owner		= THIS_MODULE,					\
+		.min_uV		= (_volt) * 1000,				\
+		.ops		= &axp20x_ops,					\
+	}
+
+#define AXP20X_DESC_TABLE(_id, _table, _vreg, _vmask, _ereg, _emask)		\
+	[AXP20X_##_id] = {							\
+		.name		= #_id,						\
+		.type		= REGULATOR_VOLTAGE,				\
+		.id		= AXP20X_##_id,					\
+		.n_voltages	= ARRAY_SIZE(_table),				\
+		.owner		= THIS_MODULE,					\
+		.vsel_reg	= (_vreg),					\
+		.vsel_mask	= (_vmask),					\
+		.enable_reg	= (_ereg),					\
+		.enable_mask	= (_emask),					\
+		.volt_table	= (_table),					\
+		.ops		= &axp20x_ops_table,				\
+	}
+
+static int axp20x_ldo4_data[] = { 1250000, 1300000, 1400000, 1500000, 1600000, 1700000,
+				  1800000, 1900000, 2000000, 2500000, 2700000, 2800000,
+				  3000000, 3100000, 3200000, 3300000 };
+
+static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV)
+{
+	int sel = regulator_map_voltage_iterate(rdev, uV, uV);
+
+	if (sel < 0)
+		return sel;
+
+	return regulator_set_voltage_sel_regmap(rdev, sel);
+}
+
+static struct regulator_ops axp20x_ops_table = {
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_table,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.set_suspend_enable	= regulator_enable_regmap,
+	.set_suspend_disable	= regulator_disable_regmap,
+	.set_suspend_voltage	= axp20x_set_suspend_voltage,
+};
+
+
+static struct regulator_ops axp20x_ops = {
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.set_suspend_enable	= regulator_enable_regmap,
+	.set_suspend_disable	= regulator_disable_regmap,
+	.set_suspend_voltage	= axp20x_set_suspend_voltage,
+};
+
+static const struct regulator_desc axp20x_regulators[] = {
+	AXP20X_DESC(DCDC2, 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f,
+		    AXP20X_PWR_OUT_CTRL, 0x10),
+	AXP20X_DESC(DCDC3, 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f,
+		    AXP20X_PWR_OUT_CTRL, 0x02),
+	AXP20X_DESC_FIXED(LDO1, 1300),
+	AXP20X_DESC(LDO2, 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0,
+		    AXP20X_PWR_OUT_CTRL, 0x04),
+	AXP20X_DESC(LDO3, 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f,
+		    AXP20X_PWR_OUT_CTRL, 0x40),
+	AXP20X_DESC_TABLE(LDO4, axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f,
+			  AXP20X_PWR_OUT_CTRL, 0x08),
+	AXP20X_DESC_IO(LDO5, 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0,
+		       AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED,
+		       AXP20X_IO_DISABLED),
+};
+
+#define AXP_MATCH(_name, _id) \
+	[AXP20X_##_id] = { \
+		.name		= #_name, \
+		.driver_data	= (void *) &axp20x_regulators[AXP20X_##_id], \
+	}
+
+static struct of_regulator_match axp20x_matches[] = {
+	AXP_MATCH(dcdc2, DCDC2),
+	AXP_MATCH(dcdc3, DCDC3),
+	AXP_MATCH(ldo1, LDO1),
+	AXP_MATCH(ldo2, LDO2),
+	AXP_MATCH(ldo3, LDO3),
+	AXP_MATCH(ldo4, LDO4),
+	AXP_MATCH(ldo5, LDO5),
+};
+
+static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
+{
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+
+	if (dcdcfreq < 750) {
+		dcdcfreq = 750;
+		dev_warn(&pdev->dev, "DCDC frequency too low. Set to 750kHz\n");
+	}
+
+	if (dcdcfreq > 1875) {
+		dcdcfreq = 1875;
+		dev_warn(&pdev->dev, "DCDC frequency too high. Set to 1875kHz\n");
+	}
+
+	dcdcfreq = (dcdcfreq - 750) / 75;
+
+	return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ,
+				  AXP20X_FREQ_DCDC_MASK, dcdcfreq);
+}
+
+static int axp20x_regulator_parse_dt(struct platform_device *pdev)
+{
+	struct device_node *np, *regulators;
+	int ret;
+	u32 dcdcfreq;
+
+	np = of_node_get(pdev->dev.parent->of_node);
+	if (!np)
+		return 0;
+
+	regulators = of_find_node_by_name(np, "regulators");
+	if (!regulators) {
+		dev_warn(&pdev->dev, "regulators node not found\n");
+	} else {
+		ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches,
+					 ARRAY_SIZE(axp20x_matches));
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
+			return ret;
+		}
+
+		dcdcfreq = 1500;
+		of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
+		ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret);
+			return ret;
+		}
+
+		of_node_put(regulators);
+	}
+	
+	return 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;
+
+	workmode <<= ffs(mask) - 1;
+
+	return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
+}
+
+static int axp20x_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev;
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_config config = { };
+	struct regulator_init_data *init_data;
+	int ret, i;
+	u32 workmode;
+
+	ret = axp20x_regulator_parse_dt(pdev);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < AXP20X_REG_ID_MAX; i++) {
+		init_data = axp20x_matches[i].init_data;
+
+		config.dev = &pdev->dev;
+		config.init_data = init_data;
+		config.regmap = axp20x->regmap;
+		config.of_node = axp20x_matches[i].of_node;
+
+		rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i],
+							&config);
+		if (IS_ERR(rdev)) {
+			dev_err(&pdev->dev, "Failed to register %s\n",
+				axp20x_regulators[i].name);
+
+			return PTR_ERR(rdev);
+		}
+
+		ret = of_property_read_u32(axp20x_matches[i].of_node, "x-powers,dcdc-workmode",
+					   &workmode);
+		if (!ret) {
+			if (axp20x_set_dcdc_workmode(rdev, i, workmode))
+				dev_err(&pdev->dev, "Failed to set workmode on %s\n",
+					axp20x_regulators[i].name);
+		}
+	}
+
+	return 0;
+}
+
+static struct platform_driver axp20x_regulator_driver = {
+	.probe	= axp20x_regulator_probe,
+	.driver	= {
+		.name		= "axp20x-regulator",
+		.owner		= THIS_MODULE,
+	},
+};
+
+module_platform_driver(axp20x_regulator_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
+MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC");
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem
@ 2014-03-27 21:29   ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 drivers/regulator/Kconfig            |   7 +
 drivers/regulator/Makefile           |   1 +
 drivers/regulator/axp20x-regulator.c | 280 +++++++++++++++++++++++++++++++++++
 3 files changed, 288 insertions(+)
 create mode 100644 drivers/regulator/axp20x-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 6a79328..9f3bc48 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -139,6 +139,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
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 979f9dd..1dd084a 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -20,6 +20,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
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
new file mode 100644
index 0000000..3f1db88
--- /dev/null
+++ b/drivers/regulator/axp20x-regulator.c
@@ -0,0 +1,280 @@
+/*
+ * AXP20x regulators driver.
+ *
+ * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#define AXP20X_IO_ENABLED		(0x03)
+#define AXP20X_IO_DISABLED		(0x07)
+
+#define AXP20X_WORKMODE_DCDC2_MASK	BIT(2)
+#define AXP20X_WORKMODE_DCDC3_MASK	BIT(1)
+
+#define AXP20X_FREQ_DCDC_MASK		(0x0f)
+
+#define AXP20X_DESC_IO(_id, _min, _max, _step, _vreg, _vmask, _ereg, _emask, 	\
+		       _enable_val, _disable_val)				\
+	[AXP20X_##_id] = {							\
+		.name		= #_id,						\
+		.type		= REGULATOR_VOLTAGE,				\
+		.id		= AXP20X_##_id,					\
+		.n_voltages	= (((_max) - (_min)) / (_step) + 1),		\
+		.owner		= THIS_MODULE,					\
+		.min_uV		= (_min) * 1000,				\
+		.uV_step	= (_step) * 1000,				\
+		.vsel_reg	= (_vreg),					\
+		.vsel_mask	= (_vmask),					\
+		.enable_reg	= (_ereg),					\
+		.enable_mask	= (_emask),					\
+		.enable_val	= (_enable_val),				\
+		.disable_val	= (_disable_val),				\
+		.ops		= &axp20x_ops,					\
+	}
+
+#define AXP20X_DESC(_id, _min, _max, _step, _vreg, _vmask, _ereg, _emask) 	\
+	AXP20X_DESC_IO(_id, _min, _max, _step, _vreg, _vmask, _ereg, _emask,	\
+		       0, 0)
+
+#define AXP20X_DESC_FIXED(_id, _volt)						\
+	[AXP20X_##_id] = {							\
+		.name		= #_id,						\
+		.type		= REGULATOR_VOLTAGE,				\
+		.id		= AXP20X_##_id,					\
+		.n_voltages	= 1,						\
+		.owner		= THIS_MODULE,					\
+		.min_uV		= (_volt) * 1000,				\
+		.ops		= &axp20x_ops,					\
+	}
+
+#define AXP20X_DESC_TABLE(_id, _table, _vreg, _vmask, _ereg, _emask)		\
+	[AXP20X_##_id] = {							\
+		.name		= #_id,						\
+		.type		= REGULATOR_VOLTAGE,				\
+		.id		= AXP20X_##_id,					\
+		.n_voltages	= ARRAY_SIZE(_table),				\
+		.owner		= THIS_MODULE,					\
+		.vsel_reg	= (_vreg),					\
+		.vsel_mask	= (_vmask),					\
+		.enable_reg	= (_ereg),					\
+		.enable_mask	= (_emask),					\
+		.volt_table	= (_table),					\
+		.ops		= &axp20x_ops_table,				\
+	}
+
+static int axp20x_ldo4_data[] = { 1250000, 1300000, 1400000, 1500000, 1600000, 1700000,
+				  1800000, 1900000, 2000000, 2500000, 2700000, 2800000,
+				  3000000, 3100000, 3200000, 3300000 };
+
+static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV)
+{
+	int sel = regulator_map_voltage_iterate(rdev, uV, uV);
+
+	if (sel < 0)
+		return sel;
+
+	return regulator_set_voltage_sel_regmap(rdev, sel);
+}
+
+static struct regulator_ops axp20x_ops_table = {
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_table,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.set_suspend_enable	= regulator_enable_regmap,
+	.set_suspend_disable	= regulator_disable_regmap,
+	.set_suspend_voltage	= axp20x_set_suspend_voltage,
+};
+
+
+static struct regulator_ops axp20x_ops = {
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.set_suspend_enable	= regulator_enable_regmap,
+	.set_suspend_disable	= regulator_disable_regmap,
+	.set_suspend_voltage	= axp20x_set_suspend_voltage,
+};
+
+static const struct regulator_desc axp20x_regulators[] = {
+	AXP20X_DESC(DCDC2, 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f,
+		    AXP20X_PWR_OUT_CTRL, 0x10),
+	AXP20X_DESC(DCDC3, 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f,
+		    AXP20X_PWR_OUT_CTRL, 0x02),
+	AXP20X_DESC_FIXED(LDO1, 1300),
+	AXP20X_DESC(LDO2, 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0,
+		    AXP20X_PWR_OUT_CTRL, 0x04),
+	AXP20X_DESC(LDO3, 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f,
+		    AXP20X_PWR_OUT_CTRL, 0x40),
+	AXP20X_DESC_TABLE(LDO4, axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f,
+			  AXP20X_PWR_OUT_CTRL, 0x08),
+	AXP20X_DESC_IO(LDO5, 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0,
+		       AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED,
+		       AXP20X_IO_DISABLED),
+};
+
+#define AXP_MATCH(_name, _id) \
+	[AXP20X_##_id] = { \
+		.name		= #_name, \
+		.driver_data	= (void *) &axp20x_regulators[AXP20X_##_id], \
+	}
+
+static struct of_regulator_match axp20x_matches[] = {
+	AXP_MATCH(dcdc2, DCDC2),
+	AXP_MATCH(dcdc3, DCDC3),
+	AXP_MATCH(ldo1, LDO1),
+	AXP_MATCH(ldo2, LDO2),
+	AXP_MATCH(ldo3, LDO3),
+	AXP_MATCH(ldo4, LDO4),
+	AXP_MATCH(ldo5, LDO5),
+};
+
+static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
+{
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+
+	if (dcdcfreq < 750) {
+		dcdcfreq = 750;
+		dev_warn(&pdev->dev, "DCDC frequency too low. Set to 750kHz\n");
+	}
+
+	if (dcdcfreq > 1875) {
+		dcdcfreq = 1875;
+		dev_warn(&pdev->dev, "DCDC frequency too high. Set to 1875kHz\n");
+	}
+
+	dcdcfreq = (dcdcfreq - 750) / 75;
+
+	return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ,
+				  AXP20X_FREQ_DCDC_MASK, dcdcfreq);
+}
+
+static int axp20x_regulator_parse_dt(struct platform_device *pdev)
+{
+	struct device_node *np, *regulators;
+	int ret;
+	u32 dcdcfreq;
+
+	np = of_node_get(pdev->dev.parent->of_node);
+	if (!np)
+		return 0;
+
+	regulators = of_find_node_by_name(np, "regulators");
+	if (!regulators) {
+		dev_warn(&pdev->dev, "regulators node not found\n");
+	} else {
+		ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches,
+					 ARRAY_SIZE(axp20x_matches));
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
+			return ret;
+		}
+
+		dcdcfreq = 1500;
+		of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
+		ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret);
+			return ret;
+		}
+
+		of_node_put(regulators);
+	}
+	
+	return 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;
+
+	workmode <<= ffs(mask) - 1;
+
+	return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
+}
+
+static int axp20x_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev;
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_config config = { };
+	struct regulator_init_data *init_data;
+	int ret, i;
+	u32 workmode;
+
+	ret = axp20x_regulator_parse_dt(pdev);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < AXP20X_REG_ID_MAX; i++) {
+		init_data = axp20x_matches[i].init_data;
+
+		config.dev = &pdev->dev;
+		config.init_data = init_data;
+		config.regmap = axp20x->regmap;
+		config.of_node = axp20x_matches[i].of_node;
+
+		rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i],
+							&config);
+		if (IS_ERR(rdev)) {
+			dev_err(&pdev->dev, "Failed to register %s\n",
+				axp20x_regulators[i].name);
+
+			return PTR_ERR(rdev);
+		}
+
+		ret = of_property_read_u32(axp20x_matches[i].of_node, "x-powers,dcdc-workmode",
+					   &workmode);
+		if (!ret) {
+			if (axp20x_set_dcdc_workmode(rdev, i, workmode))
+				dev_err(&pdev->dev, "Failed to set workmode on %s\n",
+					axp20x_regulators[i].name);
+		}
+	}
+
+	return 0;
+}
+
+static struct platform_driver axp20x_regulator_driver = {
+	.probe	= axp20x_regulator_probe,
+	.driver	= {
+		.name		= "axp20x-regulator",
+		.owner		= THIS_MODULE,
+	},
+};
+
+module_platform_driver(axp20x_regulator_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
+MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 07/10] ARM: sunxi: dt: Add x-powers-axp209.dtsi file
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29   ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-sunxi, maxime.ripard, hdegoede, emilio,
	wens, sameo, dmitry.torokhov, linux-input, linux-doc, lgirdwood,
	broonie
  Cc: Carlo Caione

This dtsi describes the axp209 PMIC, and is to be included from inside
the i2c controller node to which the axp209 is connected.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Carlo Caione <carlo@caione.org>
---
 arch/arm/boot/dts/x-powers-axp209.dtsi | 54 ++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 arch/arm/boot/dts/x-powers-axp209.dtsi

diff --git a/arch/arm/boot/dts/x-powers-axp209.dtsi b/arch/arm/boot/dts/x-powers-axp209.dtsi
new file mode 100644
index 0000000..b05e54d
--- /dev/null
+++ b/arch/arm/boot/dts/x-powers-axp209.dtsi
@@ -0,0 +1,54 @@
+/*
+ * x-powers,axp209 common code to be include from inside the axp209 node
+ *
+ * Copyright 2014 - Carlo Caione <carlo@caione.org>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+regulators {
+	dcdc-freq = <1500>;
+
+	axp_dcdc2: dcdc2 {
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <2275000>;
+		regulator-always-on;
+	};
+
+	axp_dcdc3: dcdc3 {
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <3500000>;
+		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>;
+	};
+};
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 07/10] ARM: sunxi: dt: Add x-powers-axp209.dtsi file
@ 2014-03-27 21:29   ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

This dtsi describes the axp209 PMIC, and is to be included from inside
the i2c controller node to which the axp209 is connected.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Carlo Caione <carlo@caione.org>
---
 arch/arm/boot/dts/x-powers-axp209.dtsi | 54 ++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 arch/arm/boot/dts/x-powers-axp209.dtsi

diff --git a/arch/arm/boot/dts/x-powers-axp209.dtsi b/arch/arm/boot/dts/x-powers-axp209.dtsi
new file mode 100644
index 0000000..b05e54d
--- /dev/null
+++ b/arch/arm/boot/dts/x-powers-axp209.dtsi
@@ -0,0 +1,54 @@
+/*
+ * x-powers,axp209 common code to be include from inside the axp209 node
+ *
+ * Copyright 2014 - Carlo Caione <carlo@caione.org>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+regulators {
+	dcdc-freq = <1500>;
+
+	axp_dcdc2: dcdc2 {
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <2275000>;
+		regulator-always-on;
+	};
+
+	axp_dcdc3: dcdc3 {
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <3500000>;
+		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>;
+	};
+};
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29   ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-sunxi, maxime.ripard, hdegoede, emilio,
	wens, sameo, dmitry.torokhov, linux-input, linux-doc, lgirdwood,
	broonie
  Cc: Carlo Caione

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Carlo Caione <carlo@caione.org>
---
 arch/arm/boot/dts/sun4i-a10-a1000.dts           | 13 +++++++++++++
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts      | 13 +++++++++++++
 arch/arm/boot/dts/sun4i-a10-hackberry.dts       | 19 +++++++++++++++++++
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts       | 13 +++++++++++++
 arch/arm/boot/dts/sun4i-a10-mini-xplus.dts      | 19 +++++++++++++++++++
 arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts  | 19 +++++++++++++++++++
 arch/arm/boot/dts/sun4i-a10-pcduino.dts         | 13 +++++++++++++
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     | 14 ++++++++++++++
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 15 +++++++++++++++
 arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 14 ++++++++++++++
 10 files changed, 152 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
index fa746aea..cf18c4d 100644
--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -88,6 +88,19 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 	};
 
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 4684cbe..52d21bb 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -80,6 +80,19 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 
 		i2c1: i2c@01c2b000 {
diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
index d7c17e4..3960d67 100644
--- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts
+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
@@ -82,6 +82,25 @@
 			pinctrl-0 = <&uart0_pins_a>;
 			status = "okay";
 		};
+
+		i2c0: i2c@01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
+		};
 	};
 
 	reg_emac_3v3: emac-3v3 {
diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index fe9272e..c797f5c 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -34,6 +34,19 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 
 		usbphy: phy@01c13400 {
diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
index dd84a9e..c61902d 100644
--- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
@@ -47,6 +47,25 @@
 			pinctrl-0 = <&uart0_pins_a>;
 			status = "okay";
 		};
+
+		i2c0: i2c@01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
+		};
 	};
 
 	reg_usb1_vbus: usb1-vbus {
diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
index 66cf0c7..7e862d6 100644
--- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
@@ -81,6 +81,25 @@
 			pinctrl-0 = <&uart0_pins_a>;
 			status = "okay";
 		};
+
+		i2c0: i2c@01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
+		};
 	};
 
 	leds {
diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
index 255b47e..8ad0a86 100644
--- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts
+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
@@ -66,6 +66,19 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 	};
 
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 68de89f..c5c91b8 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -66,6 +66,20 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupt-parent = <&nmi_intc>;
+				interrupts = <0 8>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 
 		i2c1: i2c@01c2b000 {
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index cb25d3c..a42f5bc 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -73,6 +73,21 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupt-parent = <&nmi_intc>;
+				interrupts = <0 8>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
+
 		};
 
 		i2c1: i2c@01c2b000 {
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index eeadf76..63171c4 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -95,6 +95,20 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x@34 {
+				reg = <0x34>;
+				interrupt-parent = <&nmi_intc>;
+				interrupts = <0 8>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 
 		i2c1: i2c@01c2b000 {
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
@ 2014-03-27 21:29   ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Carlo Caione <carlo@caione.org>
---
 arch/arm/boot/dts/sun4i-a10-a1000.dts           | 13 +++++++++++++
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts      | 13 +++++++++++++
 arch/arm/boot/dts/sun4i-a10-hackberry.dts       | 19 +++++++++++++++++++
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts       | 13 +++++++++++++
 arch/arm/boot/dts/sun4i-a10-mini-xplus.dts      | 19 +++++++++++++++++++
 arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts  | 19 +++++++++++++++++++
 arch/arm/boot/dts/sun4i-a10-pcduino.dts         | 13 +++++++++++++
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     | 14 ++++++++++++++
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 15 +++++++++++++++
 arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 14 ++++++++++++++
 10 files changed, 152 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
index fa746aea..cf18c4d 100644
--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -88,6 +88,19 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 	};
 
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 4684cbe..52d21bb 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -80,6 +80,19 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 
 		i2c1: i2c at 01c2b000 {
diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
index d7c17e4..3960d67 100644
--- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts
+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
@@ -82,6 +82,25 @@
 			pinctrl-0 = <&uart0_pins_a>;
 			status = "okay";
 		};
+
+		i2c0: i2c at 01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
+		};
 	};
 
 	reg_emac_3v3: emac-3v3 {
diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index fe9272e..c797f5c 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -34,6 +34,19 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 
 		usbphy: phy at 01c13400 {
diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
index dd84a9e..c61902d 100644
--- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
@@ -47,6 +47,25 @@
 			pinctrl-0 = <&uart0_pins_a>;
 			status = "okay";
 		};
+
+		i2c0: i2c at 01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
+		};
 	};
 
 	reg_usb1_vbus: usb1-vbus {
diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
index 66cf0c7..7e862d6 100644
--- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
@@ -81,6 +81,25 @@
 			pinctrl-0 = <&uart0_pins_a>;
 			status = "okay";
 		};
+
+		i2c0: i2c at 01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
+		};
 	};
 
 	leds {
diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
index 255b47e..8ad0a86 100644
--- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts
+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
@@ -66,6 +66,19 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins_a>;
 			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			axp: axp20x at 34 {
+				reg = <0x34>;
+				interrupts = <0>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 	};
 
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 68de89f..c5c91b8 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -66,6 +66,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>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 
 		i2c1: i2c at 01c2b000 {
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index cb25d3c..a42f5bc 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -73,6 +73,21 @@
 			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>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
+
 		};
 
 		i2c1: i2c at 01c2b000 {
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index eeadf76..63171c4 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -95,6 +95,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>;
+
+				compatible = "x-powers,axp209";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+
+				/include/ "x-powers-axp209.dtsi"
+			};
 		};
 
 		i2c1: i2c at 01c2b000 {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 09/10] ARM: sunxi: Add AXP20x support in defconfig
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29     ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
  Cc: Carlo Caione

Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
---
 arch/arm/configs/sunxi_defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index b5df4a5..6e305da 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -40,6 +40,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
@@ -55,6 +57,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
@@ -69,3 +72,4 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS=y
 CONFIG_PRINTK_TIME=y
+CONFIG_REGULATOR_AXP20X=y
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 09/10] ARM: sunxi: Add AXP20x support in defconfig
@ 2014-03-27 21:29     ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 arch/arm/configs/sunxi_defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index b5df4a5..6e305da 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -40,6 +40,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
@@ -55,6 +57,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
@@ -69,3 +72,4 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS=y
 CONFIG_PRINTK_TIME=y
+CONFIG_REGULATOR_AXP20X=y
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 10/10] ARM: sunxi: Add AXP20x support multi_v7_defconfig
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-27 21:29   ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-sunxi, maxime.ripard, hdegoede, emilio,
	wens, sameo, dmitry.torokhov, linux-input, linux-doc, lgirdwood,
	broonie
  Cc: Carlo Caione

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 arch/arm/configs/multi_v7_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index ee69829..239c014 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -134,6 +134,7 @@ CONFIG_KEYBOARD_SPEAR=y
 CONFIG_KEYBOARD_CROS_EC=y
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AXP20X_PEK=y
 CONFIG_INPUT_MPU3050=y
 CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIAL_8250=y
@@ -189,6 +190,7 @@ CONFIG_SENSORS_LM90=y
 CONFIG_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
 CONFIG_MFD_AS3722=y
+CONFIG_MFD_AXP20X=y
 CONFIG_MFD_CROS_EC=y
 CONFIG_MFD_CROS_EC_SPI=y
 CONFIG_MFD_MAX8907=y
@@ -199,6 +201,7 @@ CONFIG_MFD_TPS65910=y
 CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
 CONFIG_REGULATOR_AB8500=y
 CONFIG_REGULATOR_AS3722=y
+CONFIG_REGULATOR_AXP20X=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MAX8907=y
 CONFIG_REGULATOR_PALMAS=y
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 10/10] ARM: sunxi: Add AXP20x support multi_v7_defconfig
@ 2014-03-27 21:29   ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-27 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Carlo Caione <carlo@caione.org>
---
 arch/arm/configs/multi_v7_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index ee69829..239c014 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -134,6 +134,7 @@ CONFIG_KEYBOARD_SPEAR=y
 CONFIG_KEYBOARD_CROS_EC=y
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AXP20X_PEK=y
 CONFIG_INPUT_MPU3050=y
 CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIAL_8250=y
@@ -189,6 +190,7 @@ CONFIG_SENSORS_LM90=y
 CONFIG_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
 CONFIG_MFD_AS3722=y
+CONFIG_MFD_AXP20X=y
 CONFIG_MFD_CROS_EC=y
 CONFIG_MFD_CROS_EC_SPI=y
 CONFIG_MFD_MAX8907=y
@@ -199,6 +201,7 @@ CONFIG_MFD_TPS65910=y
 CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
 CONFIG_REGULATOR_AB8500=y
 CONFIG_REGULATOR_AS3722=y
+CONFIG_REGULATOR_AXP20X=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MAX8907=y
 CONFIG_REGULATOR_PALMAS=y
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  2014-03-27 21:29   ` Carlo Caione
@ 2014-03-28  3:12     ` Chen-Yu Tsai
  -1 siblings, 0 replies; 58+ messages in thread
From: Chen-Yu Tsai @ 2014-03-28  3:12 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel, linux-sunxi, maxime.ripard, Hans De Goede,
	Emilio Lopez, sameo, dmitry.torokhov, linux-input, linux-doc,
	lgirdwood, broonie

On Fri, Mar 28, 2014 at 5:29 AM, Carlo Caione <carlo@caione.org> wrote:
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Signed-off-by: Carlo Caione <carlo@caione.org>
> ---
>  arch/arm/boot/dts/sun4i-a10-a1000.dts           | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-cubieboard.dts      | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-hackberry.dts       | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-inet97fv2.dts       | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-mini-xplus.dts      | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts  | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-pcduino.dts         | 13 +++++++++++++
>  arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     | 14 ++++++++++++++
>  arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 15 +++++++++++++++
>  arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 14 ++++++++++++++
>  10 files changed, 152 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
> index fa746aea..cf18c4d 100644
> --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
> +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
> @@ -88,6 +88,19 @@
>                         pinctrl-names = "default";
>                         pinctrl-0 = <&i2c0_pins_a>;
>                         status = "okay";
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       axp: axp20x@34 {

Hi,

Sorry for spotting this just now. I suggest you change it to

                          axp209: pmic@34 {

or

                          axp209_pmic@34 {

to match the ePAPR policy that node names should be generic and
describe functionality. The latter is what some DTs use.

> +                               reg = <0x34>;
> +                               interrupts = <0>;
> +
> +                               compatible = "x-powers,axp209";
> +                               interrupt-controller;
> +                               #interrupt-cells = <1>;
> +
> +                               /include/ "x-powers-axp209.dtsi"
> +                       };
>                 };
>         };
>

[...]

Same for all the other files.

Thanks for working on this!


ChenYu

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
@ 2014-03-28  3:12     ` Chen-Yu Tsai
  0 siblings, 0 replies; 58+ messages in thread
From: Chen-Yu Tsai @ 2014-03-28  3:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 5:29 AM, Carlo Caione <carlo@caione.org> wrote:
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Signed-off-by: Carlo Caione <carlo@caione.org>
> ---
>  arch/arm/boot/dts/sun4i-a10-a1000.dts           | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-cubieboard.dts      | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-hackberry.dts       | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-inet97fv2.dts       | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-mini-xplus.dts      | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts  | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-pcduino.dts         | 13 +++++++++++++
>  arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     | 14 ++++++++++++++
>  arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 15 +++++++++++++++
>  arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 14 ++++++++++++++
>  10 files changed, 152 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
> index fa746aea..cf18c4d 100644
> --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
> +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
> @@ -88,6 +88,19 @@
>                         pinctrl-names = "default";
>                         pinctrl-0 = <&i2c0_pins_a>;
>                         status = "okay";
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       axp: axp20x at 34 {

Hi,

Sorry for spotting this just now. I suggest you change it to

                          axp209: pmic at 34 {

or

                          axp209_pmic at 34 {

to match the ePAPR policy that node names should be generic and
describe functionality. The latter is what some DTs use.

> +                               reg = <0x34>;
> +                               interrupts = <0>;
> +
> +                               compatible = "x-powers,axp209";
> +                               interrupt-controller;
> +                               #interrupt-cells = <1>;
> +
> +                               /include/ "x-powers-axp209.dtsi"
> +                       };
>                 };
>         };
>

[...]

Same for all the other files.

Thanks for working on this!


ChenYu

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [linux-sunxi] Re: [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  2014-03-28  3:12     ` Chen-Yu Tsai
@ 2014-03-28  7:37       ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-28  7:37 UTC (permalink / raw)
  To: wens Tsai
  Cc: linux-arm-kernel, maxime.ripard, Hans De Goede, Emilio Lopez,
	sameo, dmitry.torokhov, linux-input, linux-doc, lgirdwood,
	broonie, linux-sunxi

On Fri, Mar 28, 2014 at 4:12 AM, Chen-Yu Tsai <wens@csie.org> wrote:
>> diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
>> index fa746aea..cf18c4d 100644
>> --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
>> +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
>> @@ -88,6 +88,19 @@
>>                         pinctrl-names = "default";
>>                         pinctrl-0 = <&i2c0_pins_a>;
>>                         status = "okay";
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +
>> +                       axp: axp20x@34 {
>
> Hi,
>
> Sorry for spotting this just now. I suggest you change it to
>
>                           axp209: pmic@34 {
>
> or
>
>                           axp209_pmic@34 {
>
> to match the ePAPR policy that node names should be generic and
> describe functionality. The latter is what some DTs use.

Right. Thanks for reviewing this.

> Same for all the other files.
>
> Thanks for working on this!

Thank you,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [linux-sunxi] Re: [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
@ 2014-03-28  7:37       ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-28  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 4:12 AM, Chen-Yu Tsai <wens@csie.org> wrote:
>> diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
>> index fa746aea..cf18c4d 100644
>> --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
>> +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
>> @@ -88,6 +88,19 @@
>>                         pinctrl-names = "default";
>>                         pinctrl-0 = <&i2c0_pins_a>;
>>                         status = "okay";
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +
>> +                       axp: axp20x at 34 {
>
> Hi,
>
> Sorry for spotting this just now. I suggest you change it to
>
>                           axp209: pmic at 34 {
>
> or
>
>                           axp209_pmic at 34 {
>
> to match the ePAPR policy that node names should be generic and
> describe functionality. The latter is what some DTs use.

Right. Thanks for reviewing this.

> Same for all the other files.
>
> Thanks for working on this!

Thank you,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key
  2014-03-27 21:29     ` Carlo Caione
@ 2014-03-28  7:38         ` Dmitry Torokhov
  -1 siblings, 0 replies; 58+ messages in thread
From: Dmitry Torokhov @ 2014-03-28  7:38 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A

Hi Carlo,

On Thu, Mar 27, 2014 at 10:29:18PM +0100, Carlo Caione wrote:
> 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.
> 
> Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> ---
>  drivers/input/misc/Kconfig      |  11 ++
>  drivers/input/misc/Makefile     |   1 +
>  drivers/input/misc/axp20x-pek.c | 260 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 272 insertions(+)
>  create mode 100644 drivers/input/misc/axp20x-pek.c
> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 7904ab0..87244fb 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -393,6 +393,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
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index cda71fc..624abf5 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -50,6 +50,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
> diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
> new file mode 100644
> index 0000000..6698a69
> --- /dev/null
> +++ b/drivers/input/misc/axp20x-pek.c
> @@ -0,0 +1,260 @@
> +/*
> + * axp20x power button driver.
> + *
> + * Copyright (C) 2013 Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> + *
> + * 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>
> +#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" };

Why not have everything expressed in milliseconds and have sysfs
attribute apply the closest one possible?

By the way, do you want to plumb these through device tree as well?

> +
> +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;
> +}
> +
> +static 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]);

Please just return the current value; why do we need pretty-printing?

> +	}
> +
> +	cnt += sprintf(buf + cnt, "\n");
> +
> +	return cnt;
> +}
> +
> +static 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])) {
> +
> +			i <<= ffs(axp20x_ea->mask) - 1;
> +			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);

Why does it have to be threaded IRQ?

> +	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;

These are not generic input attributes so they should belong to the platform
device, not input device.

> +	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);

No need to call input_unregister_device() for managed input devices.

> +
> +	return 0;
> +}
> +
> +static struct platform_driver axp20x_pek_driver = {
> +	.probe		= axp20x_pek_probe,
> +	.remove		= axp20x_pek_remove,
> +	.driver		= {
> +		.name		= "axp20x-pek",
> +		.owner		= THIS_MODULE,
> +	},
> +};
> +module_platform_driver(axp20x_pek_driver);
> +
> +MODULE_DESCRIPTION("axp20x Power Button");
> +MODULE_AUTHOR("Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>");
> +MODULE_LICENSE("GPL");
> -- 
> 1.8.3.2
> 

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key
@ 2014-03-28  7:38         ` Dmitry Torokhov
  0 siblings, 0 replies; 58+ messages in thread
From: Dmitry Torokhov @ 2014-03-28  7:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Carlo,

On Thu, Mar 27, 2014 at 10:29:18PM +0100, Carlo Caione wrote:
> 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.
> 
> Signed-off-by: Carlo Caione <carlo@caione.org>
> ---
>  drivers/input/misc/Kconfig      |  11 ++
>  drivers/input/misc/Makefile     |   1 +
>  drivers/input/misc/axp20x-pek.c | 260 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 272 insertions(+)
>  create mode 100644 drivers/input/misc/axp20x-pek.c
> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 7904ab0..87244fb 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -393,6 +393,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
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index cda71fc..624abf5 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -50,6 +50,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
> diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
> new file mode 100644
> index 0000000..6698a69
> --- /dev/null
> +++ b/drivers/input/misc/axp20x-pek.c
> @@ -0,0 +1,260 @@
> +/*
> + * axp20x power button driver.
> + *
> + * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
> + *
> + * 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>
> +#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" };

Why not have everything expressed in milliseconds and have sysfs
attribute apply the closest one possible?

By the way, do you want to plumb these through device tree as well?

> +
> +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;
> +}
> +
> +static 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]);

Please just return the current value; why do we need pretty-printing?

> +	}
> +
> +	cnt += sprintf(buf + cnt, "\n");
> +
> +	return cnt;
> +}
> +
> +static 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])) {
> +
> +			i <<= ffs(axp20x_ea->mask) - 1;
> +			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);

Why does it have to be threaded IRQ?

> +	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;

These are not generic input attributes so they should belong to the platform
device, not input device.

> +	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);

No need to call input_unregister_device() for managed input devices.

> +
> +	return 0;
> +}
> +
> +static struct platform_driver axp20x_pek_driver = {
> +	.probe		= axp20x_pek_probe,
> +	.remove		= axp20x_pek_remove,
> +	.driver		= {
> +		.name		= "axp20x-pek",
> +		.owner		= THIS_MODULE,
> +	},
> +};
> +module_platform_driver(axp20x_pek_driver);
> +
> +MODULE_DESCRIPTION("axp20x Power Button");
> +MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
> +MODULE_LICENSE("GPL");
> -- 
> 1.8.3.2
> 

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 00/10] mfd: AXP20x: Add support for AXP202 and AXP209
  2014-03-27 21:29 ` Carlo Caione
@ 2014-03-28  8:01   ` Lee Jones
  -1 siblings, 0 replies; 58+ messages in thread
From: Lee Jones @ 2014-03-28  8:01 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel, linux-sunxi, maxime.ripard, hdegoede, emilio,
	wens, sameo, dmitry.torokhov, linux-input, linux-doc, lgirdwood,
	broonie

> 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. 

[...]

> Carlo Caione (10):
>   mfd: AXP20x: Add mfd driver for AXP20x PMIC
>   dt-bindings: add vendor-prefix for X-Powers
>   mfd: AXP20x: Add bindings documentation
>   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: sunxi: dt: Add x-powers-axp209.dtsi file
>   ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
>   ARM: sunxi: Add AXP20x support in defconfig
>   ARM: sunxi: Add AXP20x support multi_v7_defconfig

I'm only CC'ed on two of these patches. In order to gain a full
appreciation what what the set is trying to achieve, can you CC me on
the entire set please?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 00/10] mfd: AXP20x: Add support for AXP202 and AXP209
@ 2014-03-28  8:01   ` Lee Jones
  0 siblings, 0 replies; 58+ messages in thread
From: Lee Jones @ 2014-03-28  8:01 UTC (permalink / raw)
  To: linux-arm-kernel

> 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. 

[...]

> Carlo Caione (10):
>   mfd: AXP20x: Add mfd driver for AXP20x PMIC
>   dt-bindings: add vendor-prefix for X-Powers
>   mfd: AXP20x: Add bindings documentation
>   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: sunxi: dt: Add x-powers-axp209.dtsi file
>   ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
>   ARM: sunxi: Add AXP20x support in defconfig
>   ARM: sunxi: Add AXP20x support multi_v7_defconfig

I'm only CC'ed on two of these patches. In order to gain a full
appreciation what what the set is trying to achieve, can you CC me on
the entire set please?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC
  2014-03-27 21:29     ` Carlo Caione
@ 2014-03-28  9:21         ` Lee Jones
  -1 siblings, 0 replies; 58+ messages in thread
From: Lee Jones @ 2014-03-28  9:21 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A

> 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
> 
> Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> ---
>  drivers/mfd/Kconfig        |  12 +++
>  drivers/mfd/Makefile       |   1 +
>  drivers/mfd/axp20x.c       | 240 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/axp20x.h | 180 ++++++++++++++++++++++++++++++++++
>  4 files changed, 433 insertions(+)
>  create mode 100644 drivers/mfd/axp20x.c
>  create mode 100644 include/linux/mfd/axp20x.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 49bb445..24ba61a 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -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.

Please tell us what this device is and what sub-devices are available?

[...]

> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> new file mode 100644
> index 0000000..f77a663
> --- /dev/null
> +++ b/drivers/mfd/axp20x.c
> @@ -0,0 +1,240 @@
> +/*
> + * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209

... which consist of ...

[...]

> +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,
> +	},
> +};

Have you considered doing this in the Device Tree? It's a lot less
code/overhead.

> +static const struct i2c_device_id axp20x_i2c_id[] = {
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
 
We really should consider changing the I2C subsystem!

Can you add a comment here describing why we have to add this
seemingly pointless empty struct please?

> +static struct mfd_cell axp20x_cells[] = {
> +	{
> +		.name		= "axp20x-pek",
> +		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
> +		.resources	= axp20x_pek_resources,
> +	}, {
> +		.name		= "axp20x-regulator",
> +	},
> +};

Do these drivers don't look inside the DTB at all?

[...]

> +	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;

'variant' needs to be a (unsigned?) long or it will break on 64bit
architectures.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC
@ 2014-03-28  9:21         ` Lee Jones
  0 siblings, 0 replies; 58+ messages in thread
From: Lee Jones @ 2014-03-28  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

> 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
> 
> Signed-off-by: Carlo Caione <carlo@caione.org>
> ---
>  drivers/mfd/Kconfig        |  12 +++
>  drivers/mfd/Makefile       |   1 +
>  drivers/mfd/axp20x.c       | 240 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/axp20x.h | 180 ++++++++++++++++++++++++++++++++++
>  4 files changed, 433 insertions(+)
>  create mode 100644 drivers/mfd/axp20x.c
>  create mode 100644 include/linux/mfd/axp20x.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 49bb445..24ba61a 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -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.

Please tell us what this device is and what sub-devices are available?

[...]

> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> new file mode 100644
> index 0000000..f77a663
> --- /dev/null
> +++ b/drivers/mfd/axp20x.c
> @@ -0,0 +1,240 @@
> +/*
> + * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209

... which consist of ...

[...]

> +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,
> +	},
> +};

Have you considered doing this in the Device Tree? It's a lot less
code/overhead.

> +static const struct i2c_device_id axp20x_i2c_id[] = {
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
 
We really should consider changing the I2C subsystem!

Can you add a comment here describing why we have to add this
seemingly pointless empty struct please?

> +static struct mfd_cell axp20x_cells[] = {
> +	{
> +		.name		= "axp20x-pek",
> +		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
> +		.resources	= axp20x_pek_resources,
> +	}, {
> +		.name		= "axp20x-regulator",
> +	},
> +};

Do these drivers don't look inside the DTB at all?

[...]

> +	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;

'variant' needs to be a (unsigned?) long or it will break on 64bit
architectures.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  2014-03-27 21:29   ` Carlo Caione
@ 2014-03-28 10:11       ` Maxime Ripard
  -1 siblings, 0 replies; 58+ messages in thread
From: Maxime Ripard @ 2014-03-28 10:11 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A

[-- Attachment #1: Type: text/plain, Size: 2203 bytes --]

On Thu, Mar 27, 2014 at 10:29:22PM +0100, Carlo Caione wrote:
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> ---
>  arch/arm/boot/dts/sun4i-a10-a1000.dts           | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-cubieboard.dts      | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-hackberry.dts       | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-inet97fv2.dts       | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-mini-xplus.dts      | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts  | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-pcduino.dts         | 13 +++++++++++++
>  arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     | 14 ++++++++++++++
>  arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 15 +++++++++++++++
>  arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 14 ++++++++++++++
>  10 files changed, 152 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
> index fa746aea..cf18c4d 100644
> --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
> +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
> @@ -88,6 +88,19 @@
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&i2c0_pins_a>;
>  			status = "okay";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			axp: axp20x@34 {
> +				reg = <0x34>;
> +				interrupts = <0>;
> +
> +				compatible = "x-powers,axp209";
> +				interrupt-controller;
> +				#interrupt-cells = <1>;
> +
> +				/include/ "x-powers-axp209.dtsi"
> +			};
>  		};
>  	};

Actually, you can make the whole thing much more robust by using the
&label syntax.

Here, you would just include the dtsi at the top of the file, and in
the DTSI, you would have something like:

&axp209 {
   regulators {
      ...
   }
}

(Given that the node in your DTS is axp209: pmic@something like
Chen-Yu suggested)

You don't rely any more on the position of the include, and you use a
standard DT syntax.

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
@ 2014-03-28 10:11       ` Maxime Ripard
  0 siblings, 0 replies; 58+ messages in thread
From: Maxime Ripard @ 2014-03-28 10:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 27, 2014 at 10:29:22PM +0100, Carlo Caione wrote:
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Signed-off-by: Carlo Caione <carlo@caione.org>
> ---
>  arch/arm/boot/dts/sun4i-a10-a1000.dts           | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-cubieboard.dts      | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-hackberry.dts       | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-inet97fv2.dts       | 13 +++++++++++++
>  arch/arm/boot/dts/sun4i-a10-mini-xplus.dts      | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts  | 19 +++++++++++++++++++
>  arch/arm/boot/dts/sun4i-a10-pcduino.dts         | 13 +++++++++++++
>  arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     | 14 ++++++++++++++
>  arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 15 +++++++++++++++
>  arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 14 ++++++++++++++
>  10 files changed, 152 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
> index fa746aea..cf18c4d 100644
> --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
> +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
> @@ -88,6 +88,19 @@
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&i2c0_pins_a>;
>  			status = "okay";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			axp: axp20x at 34 {
> +				reg = <0x34>;
> +				interrupts = <0>;
> +
> +				compatible = "x-powers,axp209";
> +				interrupt-controller;
> +				#interrupt-cells = <1>;
> +
> +				/include/ "x-powers-axp209.dtsi"
> +			};
>  		};
>  	};

Actually, you can make the whole thing much more robust by using the
&label syntax.

Here, you would just include the dtsi at the top of the file, and in
the DTSI, you would have something like:

&axp209 {
   regulators {
      ...
   }
}

(Given that the node in your DTS is axp209: pmic at something like
Chen-Yu suggested)

You don't rely any more on the position of the include, and you use a
standard DT syntax.

-- 
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/20140328/a64d1732/attachment.sig>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  2014-03-28 10:11       ` Maxime Ripard
@ 2014-03-28 11:38         ` Mark Brown
  -1 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-28 11:38 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Carlo Caione, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w

[-- Attachment #1: Type: text/plain, Size: 293 bytes --]

On Fri, Mar 28, 2014 at 11:11:46AM +0100, Maxime Ripard wrote:

> Here, you would just include the dtsi at the top of the file, and in
> the DTSI, you would have something like:

> &axp209 {
>    regulators {
>       ...
>    }
> }

Hang on, what is an include file setting up regulators for?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
@ 2014-03-28 11:38         ` Mark Brown
  0 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-28 11:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 11:11:46AM +0100, Maxime Ripard wrote:

> Here, you would just include the dtsi at the top of the file, and in
> the DTSI, you would have something like:

> &axp209 {
>    regulators {
>       ...
>    }
> }

Hang on, what is an include file setting up regulators for?
-------------- 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/20140328/9c468972/attachment.sig>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  2014-03-28 11:38         ` Mark Brown
@ 2014-03-28 12:54             ` Maxime Ripard
  -1 siblings, 0 replies; 58+ messages in thread
From: Maxime Ripard @ 2014-03-28 12:54 UTC (permalink / raw)
  To: Mark Brown
  Cc: Carlo Caione, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w

[-- Attachment #1: Type: text/plain, Size: 601 bytes --]

On Fri, Mar 28, 2014 at 11:38:39AM +0000, Mark Brown wrote:
> On Fri, Mar 28, 2014 at 11:11:46AM +0100, Maxime Ripard wrote:
> 
> > Here, you would just include the dtsi at the top of the file, and in
> > the DTSI, you would have something like:
> 
> > &axp209 {
> >    regulators {
> >       ...
> >    }
> > }
> 
> Hang on, what is an include file setting up regulators for?

Look at patch 7. To share the regulators declaration across all boards
and avoid duplication.

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
@ 2014-03-28 12:54             ` Maxime Ripard
  0 siblings, 0 replies; 58+ messages in thread
From: Maxime Ripard @ 2014-03-28 12:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 11:38:39AM +0000, Mark Brown wrote:
> On Fri, Mar 28, 2014 at 11:11:46AM +0100, Maxime Ripard wrote:
> 
> > Here, you would just include the dtsi at the top of the file, and in
> > the DTSI, you would have something like:
> 
> > &axp209 {
> >    regulators {
> >       ...
> >    }
> > }
> 
> Hang on, what is an include file setting up regulators for?

Look at patch 7. To share the regulators declaration across all boards
and avoid duplication.

-- 
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/20140328/a45285d7/attachment.sig>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
  2014-03-28 12:54             ` Maxime Ripard
@ 2014-03-28 13:12               ` Mark Brown
  -1 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-28 13:12 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Carlo Caione, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w

[-- Attachment #1: Type: text/plain, Size: 335 bytes --]

On Fri, Mar 28, 2014 at 01:54:12PM +0100, Maxime Ripard wrote:
> On Fri, Mar 28, 2014 at 11:38:39AM +0000, Mark Brown wrote:

> > Hang on, what is an include file setting up regulators for?

> Look at patch 7. To share the regulators declaration across all boards
> and avoid duplication.

Oh, wonderful.  I'll go and reply to that...

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards
@ 2014-03-28 13:12               ` Mark Brown
  0 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-28 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 01:54:12PM +0100, Maxime Ripard wrote:
> On Fri, Mar 28, 2014 at 11:38:39AM +0000, Mark Brown wrote:

> > Hang on, what is an include file setting up regulators for?

> Look at patch 7. To share the regulators declaration across all boards
> and avoid duplication.

Oh, wonderful.  I'll go and reply to that...
-------------- 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/20140328/dd8338e1/attachment.sig>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 07/10] ARM: sunxi: dt: Add x-powers-axp209.dtsi file
  2014-03-27 21:29   ` Carlo Caione
@ 2014-03-28 13:34       ` Mark Brown
  -1 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-28 13:34 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w

[-- Attachment #1: Type: text/plain, Size: 1745 bytes --]

On Thu, Mar 27, 2014 at 10:29:21PM +0100, Carlo Caione wrote:
> This dtsi describes the axp209 PMIC, and is to be included from inside
> the i2c controller node to which the axp209 is connected.

>  arch/arm/boot/dts/x-powers-axp209.dtsi | 54 ++++++++++++++++++++++++++++++++++

Something is wrong here.  Either the changelog is inaccurate or this is
broken, either way this should be cleaned up because this looks like
very bad practice.  If this is a common include file for boards derived
from some reference design then the changelog is misleading and the DT
should be clearer about the board tie ins.  Otherwise the .dtsi is
defining what should be board specific parameters.

The fact that the DT names everything after the regulator on the PMIC
and not after the supply names on the board is especially suspicious and
glancing at a couple of the regulators it looks like the constraints
here are the maximum ranges the PMIC supports rather than anything to do
with any board.

Please take a step back and think about what the regulator constraints
are intended to do - they're about matching the regulator capabilities
to the board since it is rare for boards to be able to do everything the
regulator can support.  Duplicating the basic device capabilities into
the DT would be a pointless waste of time.

> +	axp_dcdc2: dcdc2 {
> +		regulator-min-microvolt = <700000>;
> +		regulator-max-microvolt = <2275000>;
> +		regulator-always-on;
> +	};

What is this configuration actually for - what guarantee do we have that
the above is safe for a given board using this regulator?  

In general I'd expect to see anything specifying variability for a
regulator to also include the relevant consumer node.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 07/10] ARM: sunxi: dt: Add x-powers-axp209.dtsi file
@ 2014-03-28 13:34       ` Mark Brown
  0 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-28 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 27, 2014 at 10:29:21PM +0100, Carlo Caione wrote:
> This dtsi describes the axp209 PMIC, and is to be included from inside
> the i2c controller node to which the axp209 is connected.

>  arch/arm/boot/dts/x-powers-axp209.dtsi | 54 ++++++++++++++++++++++++++++++++++

Something is wrong here.  Either the changelog is inaccurate or this is
broken, either way this should be cleaned up because this looks like
very bad practice.  If this is a common include file for boards derived
from some reference design then the changelog is misleading and the DT
should be clearer about the board tie ins.  Otherwise the .dtsi is
defining what should be board specific parameters.

The fact that the DT names everything after the regulator on the PMIC
and not after the supply names on the board is especially suspicious and
glancing at a couple of the regulators it looks like the constraints
here are the maximum ranges the PMIC supports rather than anything to do
with any board.

Please take a step back and think about what the regulator constraints
are intended to do - they're about matching the regulator capabilities
to the board since it is rare for boards to be able to do everything the
regulator can support.  Duplicating the basic device capabilities into
the DT would be a pointless waste of time.

> +	axp_dcdc2: dcdc2 {
> +		regulator-min-microvolt = <700000>;
> +		regulator-max-microvolt = <2275000>;
> +		regulator-always-on;
> +	};

What is this configuration actually for - what guarantee do we have that
the above is safe for a given board using this regulator?  

In general I'd expect to see anything specifying variability for a
regulator to also include the relevant consumer node.
-------------- 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/20140328/e00d621d/attachment.sig>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem
  2014-03-27 21:29   ` Carlo Caione
@ 2014-03-28 13:39       ` Mark Brown
  -1 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-28 13:39 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w

[-- Attachment #1: Type: text/plain, Size: 675 bytes --]

On Thu, Mar 27, 2014 at 10:29:20PM +0100, Carlo Caione wrote:

> +static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV)
> +{
> +	int sel = regulator_map_voltage_iterate(rdev, uV, uV);
> +
> +	if (sel < 0)
> +		return sel;
> +
> +	return regulator_set_voltage_sel_regmap(rdev, sel);
> +}

This is fairly obviously broken - it's overwriting the normal runtime
value, this will disrupt the running system if we want the value we use
on suspend is different to the value we want at runtime.

Think about it - if this was a sane thing to do the core would just do
it without needing driver specific code, we already know how to set the
voltage for the device.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem
@ 2014-03-28 13:39       ` Mark Brown
  0 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-28 13:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 27, 2014 at 10:29:20PM +0100, Carlo Caione wrote:

> +static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV)
> +{
> +	int sel = regulator_map_voltage_iterate(rdev, uV, uV);
> +
> +	if (sel < 0)
> +		return sel;
> +
> +	return regulator_set_voltage_sel_regmap(rdev, sel);
> +}

This is fairly obviously broken - it's overwriting the normal runtime
value, this will disrupt the running system if we want the value we use
on suspend is different to the value we want at runtime.

Think about it - if this was a sane thing to do the core would just do
it without needing driver specific code, we already know how to set the
voltage for the 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/20140328/80a4b3b6/attachment.sig>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Re: [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key
  2014-03-28  7:38         ` Dmitry Torokhov
@ 2014-03-29 15:36             ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-29 15:36 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A

On Fri, Mar 28, 2014 at 12:38:03AM -0700, Dmitry Torokhov wrote:
> Hi Carlo,

Hi Dmitry,

> 
> On Thu, Mar 27, 2014 at 10:29:18PM +0100, Carlo Caione wrote:

[...]

> > +#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>
> > +#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" };
> 
> Why not have everything expressed in milliseconds and have sysfs
> attribute apply the closest one possible?

Yep, I agree that could be nice. Fix in v3.

> By the way, do you want to plumb these through device tree as well?

Hum, not sure about that. AFAIK device tree is used for hardware
description whereas these are configuration parameters. Moreover you
would have these parameters saved through reboots.

> > +
> > +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;
> > +}
> > +
> > +static 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]);
> 
> Please just return the current value; why do we need pretty-printing?

It was done to have the possibility to look at the accepted values. With
the modification you suggested before this is not necessary anymore.
I'll change it.

> > +	}
> > +
> > +	cnt += sprintf(buf + cnt, "\n");
> > +
> > +	return cnt;
> > +}
> > +
> > +static 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])) {
> > +
> > +			i <<= ffs(axp20x_ea->mask) - 1;
> > +			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);
> 
> Why does it have to be threaded IRQ?

Because this is already handled as a nested irq from a irq thread. The
parent threaded irq is installed by regmap_add_irq_chip() in the MFD
driver core.

> > +	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;
> 
> These are not generic input attributes so they should belong to the platform
> device, not input device.

Ok. Can I ask why they cannot be considered an input attributes?

> > +	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);
> 
> No need to call input_unregister_device() for managed input devices.

Right. Fix in v3.

> > +
> > +	return 0;
> > +}
> > +
> > +static struct platform_driver axp20x_pek_driver = {
> > +	.probe		= axp20x_pek_probe,
> > +	.remove		= axp20x_pek_remove,
> > +	.driver		= {
> > +		.name		= "axp20x-pek",
> > +		.owner		= THIS_MODULE,
> > +	},
> > +};
> > +module_platform_driver(axp20x_pek_driver);
> > +
> > +MODULE_DESCRIPTION("axp20x Power Button");
> > +MODULE_AUTHOR("Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>");
> > +MODULE_LICENSE("GPL");
> > -- 
> > 1.8.3.2
> > 
> 
> Thanks.

Thank you,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [linux-sunxi] Re: [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key
@ 2014-03-29 15:36             ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-29 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 12:38:03AM -0700, Dmitry Torokhov wrote:
> Hi Carlo,

Hi Dmitry,

> 
> On Thu, Mar 27, 2014 at 10:29:18PM +0100, Carlo Caione wrote:

[...]

> > +#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>
> > +#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" };
> 
> Why not have everything expressed in milliseconds and have sysfs
> attribute apply the closest one possible?

Yep, I agree that could be nice. Fix in v3.

> By the way, do you want to plumb these through device tree as well?

Hum, not sure about that. AFAIK device tree is used for hardware
description whereas these are configuration parameters. Moreover you
would have these parameters saved through reboots.

> > +
> > +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;
> > +}
> > +
> > +static 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]);
> 
> Please just return the current value; why do we need pretty-printing?

It was done to have the possibility to look at the accepted values. With
the modification you suggested before this is not necessary anymore.
I'll change it.

> > +	}
> > +
> > +	cnt += sprintf(buf + cnt, "\n");
> > +
> > +	return cnt;
> > +}
> > +
> > +static 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])) {
> > +
> > +			i <<= ffs(axp20x_ea->mask) - 1;
> > +			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);
> 
> Why does it have to be threaded IRQ?

Because this is already handled as a nested irq from a irq thread. The
parent threaded irq is installed by regmap_add_irq_chip() in the MFD
driver core.

> > +	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;
> 
> These are not generic input attributes so they should belong to the platform
> device, not input device.

Ok. Can I ask why they cannot be considered an input attributes?

> > +	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);
> 
> No need to call input_unregister_device() for managed input devices.

Right. Fix in v3.

> > +
> > +	return 0;
> > +}
> > +
> > +static struct platform_driver axp20x_pek_driver = {
> > +	.probe		= axp20x_pek_probe,
> > +	.remove		= axp20x_pek_remove,
> > +	.driver		= {
> > +		.name		= "axp20x-pek",
> > +		.owner		= THIS_MODULE,
> > +	},
> > +};
> > +module_platform_driver(axp20x_pek_driver);
> > +
> > +MODULE_DESCRIPTION("axp20x Power Button");
> > +MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
> > +MODULE_LICENSE("GPL");
> > -- 
> > 1.8.3.2
> > 
> 
> Thanks.

Thank you,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Re: [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC
  2014-03-28  9:21         ` Lee Jones
@ 2014-03-29 15:53           ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-29 15:53 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A

On Fri, Mar 28, 2014 at 09:21:54AM +0000, Lee Jones wrote:
> > 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
> > 
> > Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> > ---
> >  drivers/mfd/Kconfig        |  12 +++
> >  drivers/mfd/Makefile       |   1 +
> >  drivers/mfd/axp20x.c       | 240 +++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/mfd/axp20x.h | 180 ++++++++++++++++++++++++++++++++++
> >  4 files changed, 433 insertions(+)
> >  create mode 100644 drivers/mfd/axp20x.c
> >  create mode 100644 include/linux/mfd/axp20x.h
> > 
> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> > index 49bb445..24ba61a 100644
> > --- a/drivers/mfd/Kconfig
> > +++ b/drivers/mfd/Kconfig
> > @@ -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.
> 
> Please tell us what this device is and what sub-devices are available?

Ok

> [...]
> 
> > diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> > new file mode 100644
> > index 0000000..f77a663
> > --- /dev/null
> > +++ b/drivers/mfd/axp20x.c
> > @@ -0,0 +1,240 @@
> > +/*
> > + * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209
> 
> ... which consist of ...

Yeah, I should improve my code documentation :)

> [...]
> 
> > +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,
> > +	},
> > +};
> 
> Have you considered doing this in the Device Tree? It's a lot less
> code/overhead.

Ok, I'll change it in v4.

> > +static const struct i2c_device_id axp20x_i2c_id[] = {
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
>  
> We really should consider changing the I2C subsystem!
> 
> Can you add a comment here describing why we have to add this
> seemingly pointless empty struct please?

Sure.

> > +static struct mfd_cell axp20x_cells[] = {
> > +	{
> > +		.name		= "axp20x-pek",
> > +		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
> > +		.resources	= axp20x_pek_resources,
> > +	}, {
> > +		.name		= "axp20x-regulator",
> > +	},
> > +};
> 
> Do these drivers don't look inside the DTB at all?

Only the regulators driver.

> > +	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;
> 
> 'variant' needs to be a (unsigned?) long or it will break on 64bit
> architectures.

Ok, I really need to start thinking to 64bit also.

Thank you,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [linux-sunxi] Re: [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC
@ 2014-03-29 15:53           ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-29 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 09:21:54AM +0000, Lee Jones wrote:
> > 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
> > 
> > Signed-off-by: Carlo Caione <carlo@caione.org>
> > ---
> >  drivers/mfd/Kconfig        |  12 +++
> >  drivers/mfd/Makefile       |   1 +
> >  drivers/mfd/axp20x.c       | 240 +++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/mfd/axp20x.h | 180 ++++++++++++++++++++++++++++++++++
> >  4 files changed, 433 insertions(+)
> >  create mode 100644 drivers/mfd/axp20x.c
> >  create mode 100644 include/linux/mfd/axp20x.h
> > 
> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> > index 49bb445..24ba61a 100644
> > --- a/drivers/mfd/Kconfig
> > +++ b/drivers/mfd/Kconfig
> > @@ -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.
> 
> Please tell us what this device is and what sub-devices are available?

Ok

> [...]
> 
> > diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> > new file mode 100644
> > index 0000000..f77a663
> > --- /dev/null
> > +++ b/drivers/mfd/axp20x.c
> > @@ -0,0 +1,240 @@
> > +/*
> > + * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209
> 
> ... which consist of ...

Yeah, I should improve my code documentation :)

> [...]
> 
> > +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,
> > +	},
> > +};
> 
> Have you considered doing this in the Device Tree? It's a lot less
> code/overhead.

Ok, I'll change it in v4.

> > +static const struct i2c_device_id axp20x_i2c_id[] = {
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
>  
> We really should consider changing the I2C subsystem!
> 
> Can you add a comment here describing why we have to add this
> seemingly pointless empty struct please?

Sure.

> > +static struct mfd_cell axp20x_cells[] = {
> > +	{
> > +		.name		= "axp20x-pek",
> > +		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
> > +		.resources	= axp20x_pek_resources,
> > +	}, {
> > +		.name		= "axp20x-regulator",
> > +	},
> > +};
> 
> Do these drivers don't look inside the DTB at all?

Only the regulators driver.

> > +	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;
> 
> 'variant' needs to be a (unsigned?) long or it will break on 64bit
> architectures.

Ok, I really need to start thinking to 64bit also.

Thank you,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 07/10] ARM: sunxi: dt: Add x-powers-axp209.dtsi file
  2014-03-28 13:34       ` Mark Brown
@ 2014-03-29 16:14           ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-29 16:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w

On Fri, Mar 28, 2014 at 01:34:38PM +0000, Mark Brown wrote:
> On Thu, Mar 27, 2014 at 10:29:21PM +0100, Carlo Caione wrote:
> > This dtsi describes the axp209 PMIC, and is to be included from inside
> > the i2c controller node to which the axp209 is connected.
> 
> >  arch/arm/boot/dts/x-powers-axp209.dtsi | 54 ++++++++++++++++++++++++++++++++++
> 
> Something is wrong here.  Either the changelog is inaccurate or this is
> broken, either way this should be cleaned up because this looks like
> very bad practice.  If this is a common include file for boards derived
> from some reference design then the changelog is misleading and the DT
> should be clearer about the board tie ins.  Otherwise the .dtsi is
> defining what should be board specific parameters.
> 
> The fact that the DT names everything after the regulator on the PMIC
> and not after the supply names on the board is especially suspicious and
> glancing at a couple of the regulators it looks like the constraints
> here are the maximum ranges the PMIC supports rather than anything to do
> with any board.
> 
> Please take a step back and think about what the regulator constraints
> are intended to do - they're about matching the regulator capabilities
> to the board since it is rare for boards to be able to do everything the
> regulator can support.  Duplicating the basic device capabilities into
> the DT would be a pointless waste of time.
> 
> > +	axp_dcdc2: dcdc2 {
> > +		regulator-min-microvolt = <700000>;
> > +		regulator-max-microvolt = <2275000>;
> > +		regulator-always-on;
> > +	};
> 
> What is this configuration actually for - what guarantee do we have that
> the above is safe for a given board using this regulator?  
> 
> In general I'd expect to see anything specifying variability for a
> regulator to also include the relevant consumer node.

Ok, you are completely right. These values in the DTSI are wrongly the
maximum and minimum ranges for the PMIC. Even worst I didn't specify the
board specific parameters for the regulators.

Thank you for reviewing and noticing it,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 07/10] ARM: sunxi: dt: Add x-powers-axp209.dtsi file
@ 2014-03-29 16:14           ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-29 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 01:34:38PM +0000, Mark Brown wrote:
> On Thu, Mar 27, 2014 at 10:29:21PM +0100, Carlo Caione wrote:
> > This dtsi describes the axp209 PMIC, and is to be included from inside
> > the i2c controller node to which the axp209 is connected.
> 
> >  arch/arm/boot/dts/x-powers-axp209.dtsi | 54 ++++++++++++++++++++++++++++++++++
> 
> Something is wrong here.  Either the changelog is inaccurate or this is
> broken, either way this should be cleaned up because this looks like
> very bad practice.  If this is a common include file for boards derived
> from some reference design then the changelog is misleading and the DT
> should be clearer about the board tie ins.  Otherwise the .dtsi is
> defining what should be board specific parameters.
> 
> The fact that the DT names everything after the regulator on the PMIC
> and not after the supply names on the board is especially suspicious and
> glancing at a couple of the regulators it looks like the constraints
> here are the maximum ranges the PMIC supports rather than anything to do
> with any board.
> 
> Please take a step back and think about what the regulator constraints
> are intended to do - they're about matching the regulator capabilities
> to the board since it is rare for boards to be able to do everything the
> regulator can support.  Duplicating the basic device capabilities into
> the DT would be a pointless waste of time.
> 
> > +	axp_dcdc2: dcdc2 {
> > +		regulator-min-microvolt = <700000>;
> > +		regulator-max-microvolt = <2275000>;
> > +		regulator-always-on;
> > +	};
> 
> What is this configuration actually for - what guarantee do we have that
> the above is safe for a given board using this regulator?  
> 
> In general I'd expect to see anything specifying variability for a
> regulator to also include the relevant consumer node.

Ok, you are completely right. These values in the DTSI are wrongly the
maximum and minimum ranges for the PMIC. Even worst I didn't specify the
board specific parameters for the regulators.

Thank you for reviewing and noticing it,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [linux-sunxi] Re: [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem
  2014-03-28 13:39       ` Mark Brown
@ 2014-03-29 17:52         ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-29 17:52 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-arm-kernel, linux-sunxi, maxime.ripard, hdegoede, emilio,
	wens, sameo, dmitry.torokhov, linux-input, linux-doc, lgirdwood

On Fri, Mar 28, 2014 at 01:39:34PM +0000, Mark Brown wrote:
> On Thu, Mar 27, 2014 at 10:29:20PM +0100, Carlo Caione wrote:
> 
> > +static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV)
> > +{
> > +	int sel = regulator_map_voltage_iterate(rdev, uV, uV);
> > +
> > +	if (sel < 0)
> > +		return sel;
> > +
> > +	return regulator_set_voltage_sel_regmap(rdev, sel);
> > +}
> 
> This is fairly obviously broken - it's overwriting the normal runtime
> value, this will disrupt the running system if we want the value we use
> on suspend is different to the value we want at runtime.

Ok, silly question: isn't it exactly what we want? Set the voltage for
the regulator when the system is suspended?

> Think about it - if this was a sane thing to do the core would just do
> it without needing driver specific code, we already know how to set the
> voltage for the device.

I thought it was because some regulators can have specific regs for
managing the suspend mode.

BTW, but then what is the difference between my code and (i.e.) the same
routine in da9055-regulator.c?

http://lxr.linux.no/linux+v3.13.5/drivers/regulator/da9055-regulator.c#L276

Thanks,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [linux-sunxi] Re: [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem
@ 2014-03-29 17:52         ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-03-29 17:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 01:39:34PM +0000, Mark Brown wrote:
> On Thu, Mar 27, 2014 at 10:29:20PM +0100, Carlo Caione wrote:
> 
> > +static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV)
> > +{
> > +	int sel = regulator_map_voltage_iterate(rdev, uV, uV);
> > +
> > +	if (sel < 0)
> > +		return sel;
> > +
> > +	return regulator_set_voltage_sel_regmap(rdev, sel);
> > +}
> 
> This is fairly obviously broken - it's overwriting the normal runtime
> value, this will disrupt the running system if we want the value we use
> on suspend is different to the value we want at runtime.

Ok, silly question: isn't it exactly what we want? Set the voltage for
the regulator when the system is suspended?

> Think about it - if this was a sane thing to do the core would just do
> it without needing driver specific code, we already know how to set the
> voltage for the device.

I thought it was because some regulators can have specific regs for
managing the suspend mode.

BTW, but then what is the difference between my code and (i.e.) the same
routine in da9055-regulator.c?

http://lxr.linux.no/linux+v3.13.5/drivers/regulator/da9055-regulator.c#L276

Thanks,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Re: [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key
  2014-03-29 15:36             ` [linux-sunxi] " Carlo Caione
@ 2014-03-29 19:05                 ` Dmitry Torokhov
  -1 siblings, 0 replies; 58+ messages in thread
From: Dmitry Torokhov @ 2014-03-29 19:05 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A

On Sat, Mar 29, 2014 at 04:36:24PM +0100, Carlo Caione wrote:
> On Fri, Mar 28, 2014 at 12:38:03AM -0700, Dmitry Torokhov wrote:
> > Hi Carlo,
> 
> Hi Dmitry,
> 
> > 
> > On Thu, Mar 27, 2014 at 10:29:18PM +0100, Carlo Caione wrote:

[...]

> > > +
> > > +	error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbr,
> > > +					  NULL, axp20x_pek_irq, 0,
> > > +					  "axp20x-pek-dbr", idev);
> > 
> > Why does it have to be threaded IRQ?
> 
> Because this is already handled as a nested irq from a irq thread. The
> parent threaded irq is installed by regmap_add_irq_chip() in the MFD
> driver core.

Then you probably want to use devm_request_any_context_irq() - the
driver does not necessarily care if IRQ is threaded or not, t can work
either way.

> 
> > > +	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;
> > 
> > These are not generic input attributes so they should belong to the platform
> > device, not input device.
> 
> Ok. Can I ask why they cannot be considered an input attributes?

Input layer is an abstraction; I am trying to keep all attributes
generic and applicable to all input devices. If you look at other input
drivers you will see that attributes that control hardware behavior are
attached to the devices representing the hardware itself. For example
attributes to control report rate of PS/2 mouse belong to serio port
that represents the physical mouse device; typematic rate of AT
keyboards also tied to serio port, etc, etc.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [linux-sunxi] Re: [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key
@ 2014-03-29 19:05                 ` Dmitry Torokhov
  0 siblings, 0 replies; 58+ messages in thread
From: Dmitry Torokhov @ 2014-03-29 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 29, 2014 at 04:36:24PM +0100, Carlo Caione wrote:
> On Fri, Mar 28, 2014 at 12:38:03AM -0700, Dmitry Torokhov wrote:
> > Hi Carlo,
> 
> Hi Dmitry,
> 
> > 
> > On Thu, Mar 27, 2014 at 10:29:18PM +0100, Carlo Caione wrote:

[...]

> > > +
> > > +	error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbr,
> > > +					  NULL, axp20x_pek_irq, 0,
> > > +					  "axp20x-pek-dbr", idev);
> > 
> > Why does it have to be threaded IRQ?
> 
> Because this is already handled as a nested irq from a irq thread. The
> parent threaded irq is installed by regmap_add_irq_chip() in the MFD
> driver core.

Then you probably want to use devm_request_any_context_irq() - the
driver does not necessarily care if IRQ is threaded or not, t can work
either way.

> 
> > > +	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;
> > 
> > These are not generic input attributes so they should belong to the platform
> > device, not input device.
> 
> Ok. Can I ask why they cannot be considered an input attributes?

Input layer is an abstraction; I am trying to keep all attributes
generic and applicable to all input devices. If you look at other input
drivers you will see that attributes that control hardware behavior are
attached to the devices representing the hardware itself. For example
attributes to control report rate of PS/2 mouse belong to serio port
that represents the physical mouse device; typematic rate of AT
keyboards also tied to serio port, etc, etc.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Re: [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem
  2014-03-29 17:52         ` Carlo Caione
@ 2014-03-30  0:47             ` Mark Brown
  -1 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-30  0:47 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w

[-- Attachment #1: Type: text/plain, Size: 1448 bytes --]

On Sat, Mar 29, 2014 at 06:52:01PM +0100, Carlo Caione wrote:
> On Fri, Mar 28, 2014 at 01:39:34PM +0000, Mark Brown wrote:

> > This is fairly obviously broken - it's overwriting the normal runtime
> > value, this will disrupt the running system if we want the value we use
> > on suspend is different to the value we want at runtime.

> Ok, silly question: isn't it exactly what we want? Set the voltage for
> the regulator when the system is suspended?

This needs to be done without affecting the current system state - many
PMICs are aware of system suspend and have support for transitioning
into a separate suspend state, this should only be configuring that.  We
may call this function separately to the actual suspend.

> > Think about it - if this was a sane thing to do the core would just do
> > it without needing driver specific code, we already know how to set the
> > voltage for the device.

> I thought it was because some regulators can have specific regs for
> managing the suspend mode.

Right, but if the PMIC doesn't have that feature then it should indicate
that by not implementing the operation and letting the core worry about
how to handle the situation.

> BTW, but then what is the difference between my code and (i.e.) the same
> routine in da9055-regulator.c?

> http://lxr.linux.no/linux+v3.13.5/drivers/regulator/da9055-regulator.c#L276

That's updating the B register set which IIRC is used only in suspend
mode.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [linux-sunxi] Re: [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem
@ 2014-03-30  0:47             ` Mark Brown
  0 siblings, 0 replies; 58+ messages in thread
From: Mark Brown @ 2014-03-30  0:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 29, 2014 at 06:52:01PM +0100, Carlo Caione wrote:
> On Fri, Mar 28, 2014 at 01:39:34PM +0000, Mark Brown wrote:

> > This is fairly obviously broken - it's overwriting the normal runtime
> > value, this will disrupt the running system if we want the value we use
> > on suspend is different to the value we want at runtime.

> Ok, silly question: isn't it exactly what we want? Set the voltage for
> the regulator when the system is suspended?

This needs to be done without affecting the current system state - many
PMICs are aware of system suspend and have support for transitioning
into a separate suspend state, this should only be configuring that.  We
may call this function separately to the actual suspend.

> > Think about it - if this was a sane thing to do the core would just do
> > it without needing driver specific code, we already know how to set the
> > voltage for the device.

> I thought it was because some regulators can have specific regs for
> managing the suspend mode.

Right, but if the PMIC doesn't have that feature then it should indicate
that by not implementing the operation and letting the core worry about
how to handle the situation.

> BTW, but then what is the difference between my code and (i.e.) the same
> routine in da9055-regulator.c?

> http://lxr.linux.no/linux+v3.13.5/drivers/regulator/da9055-regulator.c#L276

That's updating the B register set which IIRC is used only in suspend
mode.
-------------- 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/20140330/924df094/attachment.sig>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Re: [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC
  2014-03-28  9:21         ` Lee Jones
@ 2014-04-11  9:26           ` Carlo Caione
  -1 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-04-11  9:26 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Fri, Mar 28, 2014 at 10:21 AM, Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:

[...]

>> +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,
>> +     },
>> +};
>
> Have you considered doing this in the Device Tree? It's a lot less
> code/overhead.

Hi Lee,
in v4 (I will send it soon) I left this code in since the resources
are well managed by the MFD core and adding it in the DT results in
pretty much the same code/overhead (atm the input device is not
present in the DT).
If you really think that it is the case to move the code in the DT,
please comment it in the v4.

Thanks,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [linux-sunxi] Re: [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC
@ 2014-04-11  9:26           ` Carlo Caione
  0 siblings, 0 replies; 58+ messages in thread
From: Carlo Caione @ 2014-04-11  9:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 28, 2014 at 10:21 AM, Lee Jones <lee.jones@linaro.org> wrote:

[...]

>> +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,
>> +     },
>> +};
>
> Have you considered doing this in the Device Tree? It's a lot less
> code/overhead.

Hi Lee,
in v4 (I will send it soon) I left this code in since the resources
are well managed by the MFD core and adding it in the DT results in
pretty much the same code/overhead (atm the input device is not
present in the DT).
If you really think that it is the case to move the code in the DT,
please comment it in the v4.

Thanks,

-- 
Carlo Caione

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2014-04-11  9:26 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-27 21:29 [PATCH v3 00/10] mfd: AXP20x: Add support for AXP202 and AXP209 Carlo Caione
2014-03-27 21:29 ` Carlo Caione
     [not found] ` <1395955764-18103-1-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2014-03-27 21:29   ` [PATCH v3 01/10] mfd: AXP20x: Add mfd driver for AXP20x PMIC Carlo Caione
2014-03-27 21:29     ` Carlo Caione
     [not found]     ` <1395955764-18103-2-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2014-03-28  9:21       ` Lee Jones
2014-03-28  9:21         ` Lee Jones
2014-03-29 15:53         ` Carlo Caione
2014-03-29 15:53           ` [linux-sunxi] " Carlo Caione
2014-04-11  9:26         ` Carlo Caione
2014-04-11  9:26           ` [linux-sunxi] " Carlo Caione
2014-03-27 21:29   ` [PATCH v3 02/10] dt-bindings: add vendor-prefix for X-Powers Carlo Caione
2014-03-27 21:29     ` Carlo Caione
2014-03-27 21:29   ` [PATCH v3 03/10] mfd: AXP20x: Add bindings documentation Carlo Caione
2014-03-27 21:29     ` Carlo Caione
2014-03-27 21:29   ` [PATCH v3 04/10] input: misc: Add driver for AXP20x Power Enable Key Carlo Caione
2014-03-27 21:29     ` Carlo Caione
     [not found]     ` <1395955764-18103-5-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2014-03-28  7:38       ` Dmitry Torokhov
2014-03-28  7:38         ` Dmitry Torokhov
     [not found]         ` <20140328073803.GA22093-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org>
2014-03-29 15:36           ` Carlo Caione
2014-03-29 15:36             ` [linux-sunxi] " Carlo Caione
     [not found]             ` <20140329153624.GA3952-bi+AKbBUZKZeIdyRz4JgOMwOAu8XWILU@public.gmane.org>
2014-03-29 19:05               ` Dmitry Torokhov
2014-03-29 19:05                 ` [linux-sunxi] " Dmitry Torokhov
2014-03-27 21:29   ` [PATCH v3 09/10] ARM: sunxi: Add AXP20x support in defconfig Carlo Caione
2014-03-27 21:29     ` Carlo Caione
2014-03-27 21:29 ` [PATCH v3 05/10] input: misc: Add ABI docs for AXP20x PEK Carlo Caione
2014-03-27 21:29   ` Carlo Caione
2014-03-27 21:29 ` [PATCH v3 06/10] regulator: AXP20x: Add support for regulators subsystem Carlo Caione
2014-03-27 21:29   ` Carlo Caione
     [not found]   ` <1395955764-18103-7-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2014-03-28 13:39     ` Mark Brown
2014-03-28 13:39       ` Mark Brown
2014-03-29 17:52       ` [linux-sunxi] " Carlo Caione
2014-03-29 17:52         ` Carlo Caione
     [not found]         ` <20140329175201.GD3952-bi+AKbBUZKZeIdyRz4JgOMwOAu8XWILU@public.gmane.org>
2014-03-30  0:47           ` Mark Brown
2014-03-30  0:47             ` [linux-sunxi] " Mark Brown
2014-03-27 21:29 ` [PATCH v3 07/10] ARM: sunxi: dt: Add x-powers-axp209.dtsi file Carlo Caione
2014-03-27 21:29   ` Carlo Caione
     [not found]   ` <1395955764-18103-8-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2014-03-28 13:34     ` Mark Brown
2014-03-28 13:34       ` Mark Brown
     [not found]       ` <20140328133438.GA19846-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2014-03-29 16:14         ` Carlo Caione
2014-03-29 16:14           ` Carlo Caione
2014-03-27 21:29 ` [PATCH v3 08/10] ARM: sun7i/sun4i: dt: Add AXP209 support to various boards Carlo Caione
2014-03-27 21:29   ` Carlo Caione
2014-03-28  3:12   ` Chen-Yu Tsai
2014-03-28  3:12     ` Chen-Yu Tsai
2014-03-28  7:37     ` [linux-sunxi] " Carlo Caione
2014-03-28  7:37       ` Carlo Caione
     [not found]   ` <1395955764-18103-9-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2014-03-28 10:11     ` Maxime Ripard
2014-03-28 10:11       ` Maxime Ripard
2014-03-28 11:38       ` Mark Brown
2014-03-28 11:38         ` Mark Brown
     [not found]         ` <20140328113839.GB30768-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2014-03-28 12:54           ` Maxime Ripard
2014-03-28 12:54             ` Maxime Ripard
2014-03-28 13:12             ` Mark Brown
2014-03-28 13:12               ` Mark Brown
2014-03-27 21:29 ` [PATCH v3 10/10] ARM: sunxi: Add AXP20x support multi_v7_defconfig Carlo Caione
2014-03-27 21:29   ` Carlo Caione
2014-03-28  8:01 ` [PATCH v3 00/10] mfd: AXP20x: Add support for AXP202 and AXP209 Lee Jones
2014-03-28  8:01   ` Lee Jones

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.