linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V5 0/3] Add AMS AS3722 mfd, pincontrol and RTC driver.
@ 2013-10-09 12:29 Laxman Dewangan
  2013-10-09 12:29 ` [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC Laxman Dewangan
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Laxman Dewangan @ 2013-10-09 12:29 UTC (permalink / raw)
  To: lee.jones, sameo, broonie, linus.walleij, akpm
  Cc: devicetree, linux-doc, linux-kernel, linux-gpio, rtc-linux,
	rob.herring, mark.rutland, pawel.moll, swarren, rob,
	ijc+devicetree, grant.likely, Laxman Dewangan

This series add the driver support for AMS AS3722 PMIC. The driver includes MFD, pincontrol and GPIO, regulator and RTC.

Changes from V1: 
- Remove compatible string from DT for subnode.
- Add macro in regmap.h for definign range.
- Nit cleanups in driver and use module_i2c_driver/module_platform_driver.
- Use linear_range and added regulator_map_* on regulators.
- Move OC configuration to regulator_current limit setting.
- Get rid of clk32k out configuration from RTC. Will add clock driver.

Changes from V2: 
- Drop the already applied patches on V2 series
        regmap: add helper macro to set min/max range of register
        regulator: as3722: add regulator driver for AMS AS3722
- Move the GPIo driver to pincontrol driver to expose the pin configuration
  through pincontrol.
- rewrite the DT binding of the mfd.

Changes from V3:
- Change AMS to ams
- combine DT of regulator, pincontrol to the mfd.
- Taken care of Lee's nits feedback.

Changes from V4:
- Rephrased the DT binding document.
- Add header for dt-binding macros.

Laxman Dewangan (3):
  mfd: add support for ams AS3722 PMIC
  pincntrl: add support for ams AS3722 pin control driver
  drivers/rtc/rtc-as3722: add RTC driver

 Documentation/devicetree/bindings/mfd/as3722.txt |  194 +++++++
 drivers/mfd/Kconfig                              |   12 +
 drivers/mfd/Makefile                             |    1 +
 drivers/mfd/as3722.c                             |  449 +++++++++++++++
 drivers/pinctrl/Kconfig                          |   11 +
 drivers/pinctrl/Makefile                         |    1 +
 drivers/pinctrl/pinctrl-as3722.c                 |  630 ++++++++++++++++++++++
 drivers/rtc/Kconfig                              |   10 +
 drivers/rtc/Makefile                             |    1 +
 drivers/rtc/rtc-as3722.c                         |  296 ++++++++++
 include/dt-bindings/mfd/as3722.h                 |   52 ++
 include/linux/mfd/as3722.h                       |  423 +++++++++++++++
 12 files changed, 2080 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/as3722.txt
 create mode 100644 drivers/mfd/as3722.c
 create mode 100644 drivers/pinctrl/pinctrl-as3722.c
 create mode 100644 drivers/rtc/rtc-as3722.c
 create mode 100644 include/dt-bindings/mfd/as3722.h
 create mode 100644 include/linux/mfd/as3722.h


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

* [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC
  2013-10-09 12:29 [PATCH V5 0/3] Add AMS AS3722 mfd, pincontrol and RTC driver Laxman Dewangan
@ 2013-10-09 12:29 ` Laxman Dewangan
  2013-10-09 16:13   ` Stephen Warren
  2013-10-09 12:29 ` [PATCH V5 2/3] pincntrl: add support for ams AS3722 pin control driver Laxman Dewangan
  2013-10-09 12:29 ` [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver Laxman Dewangan
  2 siblings, 1 reply; 11+ messages in thread
From: Laxman Dewangan @ 2013-10-09 12:29 UTC (permalink / raw)
  To: lee.jones, sameo, broonie, linus.walleij, akpm
  Cc: devicetree, linux-doc, linux-kernel, linux-gpio, rtc-linux,
	rob.herring, mark.rutland, pawel.moll, swarren, rob,
	ijc+devicetree, grant.likely, Laxman Dewangan, Florian Lobmaier

The ams AS3722 is a compact system PMU suitable for mobile phones,
tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down
controller, 11 LDOs, RTC, automatic battery, temperature and
over-current monitoring, 8 GPIOs, ADC and a watchdog.

Add MFD core driver for the AS3722 to support core functionality.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Florian Lobmaier <florian.lobmaier@ams.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
Changes from V1:
- Remove compatible string from DT for subnode.
- Nit cleanups in driver and use module_i2c_driver

Changes from V2:
- Change DT file to reflect the changes in gpio/pincntrl driver.
  Now there is no extra subnode.

Changes from V3:
- Combine DT of pincontrol and regulator to mfd.
- Nits cleanups.
- AMS to ams.

Changes from V4:
- Rephrased the dt binding documents.
- Added dt-binding header for DTS file.
- Fix some of indention issue in dt documents.

 Documentation/devicetree/bindings/mfd/as3722.txt |  194 ++++++++++
 drivers/mfd/Kconfig                              |   12 +
 drivers/mfd/Makefile                             |    1 +
 drivers/mfd/as3722.c                             |  449 ++++++++++++++++++++++
 include/dt-bindings/mfd/as3722.h                 |   52 +++
 include/linux/mfd/as3722.h                       |  423 ++++++++++++++++++++
 6 files changed, 1131 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/as3722.txt
 create mode 100644 drivers/mfd/as3722.c
 create mode 100644 include/dt-bindings/mfd/as3722.h
 create mode 100644 include/linux/mfd/as3722.h

diff --git a/Documentation/devicetree/bindings/mfd/as3722.txt b/Documentation/devicetree/bindings/mfd/as3722.txt
new file mode 100644
index 0000000..fc2191e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/as3722.txt
@@ -0,0 +1,194 @@
+* ams AS3722 Power management IC.
+
+Required properties:
+-------------------
+- compatible: Must be "ams,as3722".
+- reg: I2C device address.
+- interrupt-controller: AS3722 has internal interrupt controller which takes the
+  interrupt request from internal sub-blocks like RTC, regulators, GPIOs as well
+  as external input.
+- #interrupt-cells: Should be set to 2 for IRQ number and flags.
+  The first cell is the IRQ number. IRQ numbers for different interrupt source
+  of AS3722 are defined at dt-bindings/mfd/as3722.h
+  The second cell is the flags, encoded as the trigger masks from binding document
+	interrupts.txt, using dt-bindings/irq.
+
+Optional submodule and their properties:
+=======================================
+
+Pinmux and GPIO:
+===============
+Device has 8 GPIO pins which can be configured as GPIO as well as the special IO
+functions.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+Following are properties which is needed if GPIO and pinmux functionality
+is required:
+    Required properties:
+    -------------------
+	- gpio-controller: Marks the device node as a GPIO controller.
+	- #gpio-cells: Number of GPIO cells. Refer to binding document
+			gpio/gpio.txt
+
+    Optional properties:
+    --------------------
+	Following properties are require if pin control setting is required
+	at boot.
+	- pinctrl-names: A pinctrl state named "default" be defined, using the
+		bindings in pinctrl/pinctrl-binding.txt.
+	- pinctrl[0...n]: Properties to contain the phandle that refer to
+		different nodes of pin control settings. These nodes represents
+		the pin control setting of state 0 to state n. Each of these
+		nodes contains different subnodes to represents some desired
+		configuration for a list of pins. This configuration can
+		include the mux function to select on those pin(s), and
+		various pin configuration parameters, such as pull-up,
+		open drain.
+
+		Each subnode have following properties:
+		Required properties:
+		    - pins: List of pins. Valid values of pins properties are:
+				gpio0, gpio1, gpio2, gpio3, gpio4, gpio5,
+				gpio6, gpio7
+
+		Optional properties:
+			function, bias-disable, bias-pull-up, bias-pull-down,
+			bias-high-impedance, drive-open-drain.
+
+			Valid values for function properties are:
+				gpio, interrupt-out, gpio-in-interrupt,
+				vsup-vbat-low-undebounce-out,
+				vsup-vbat-low-debounce-out,
+				voltage-in-standby, oc-pg-sd0, oc-pg-sd6,
+				powergood-out, pwm-in, pwm-out, clk32k-out,
+				watchdog-in, soft-reset-in
+
+Regulators:
+===========
+Device has multiple DCDC and LDOs. The node "regulators" is require if regulator
+functionality is needed.
+
+Following are properties of regulator subnode.
+
+    Optional properties:
+    -------------------
+	The input supply of regulators are the optional properties on the
+	regulator node. The input supply of these regulators are provided
+	through following properties:
+		vsup-sd2-supply: Input supply for SD2.
+		vsup-sd3-supply: Input supply for SD3.
+		vsup-sd4-supply: Input supply for SD4.
+		vsup-sd5-supply: Input supply for SD5.
+		vin-ldo0-supply: Input supply for LDO0.
+		vin-ldo1-6-supply: Input supply for LDO1 and LDO6.
+		vin-ldo2-5-7-supply: Input supply for LDO2, LDO5 and LDO7.
+		vin-ldo3-4-supply: Input supply for LDO3 and LDO4.
+		vin-ldo9-10-supply: Input supply for LDO9 and LDO10.
+		vin-ldo11-supply: Input supply for LDO11.
+
+    Optional sub nodes for regulators:
+    ---------------------------------
+	The subnodes name is the name of regulator and it must be one of:
+	sd[0-6], ldo[0-7], ldo[9-11]
+
+	Each sub-node should contain the constraints and initialization
+	information for that regulator. See regulator.txt for a description
+	of standard properties for these sub-nodes.
+	Additional optional custom properties  are listed below.
+		ams,ext-control: External control of the rail. The option of
+			this properties will tell which external input is
+			controlling this rail. Valid values are 0, 1, 2 ad 3.
+			0: There is no external control of this rail.
+			1: Rail is controlled by ENABLE1 input pin.
+			2: Rail is controlled by ENABLE2 input pin.
+			3: Rail is controlled by ENABLE3 input pin.
+			Missing this property on DT will be assume as no
+			external control. The external control pin macros
+			are defined @dt-bindings/mfd/as3722.h
+
+		ams,enable-tracking: Enable tracking with SD1, only supported
+			by LDO3.
+
+Example:
+--------
+#include <dt-bindings/mfd/as3722.h>
+...
+ams3722 {
+	compatible = "ams,as3722";
+	reg = <0x48>;
+
+	interrupt-parent = <&intc>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+
+	gpio-controller;
+	#gpio-cells = <2>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&as3722_default>;
+
+	as3722_default: pinmux {
+			gpio0 {
+				pins = "gpio0";
+				function = "gpio";
+				bias-pull-down;
+			};
+
+			gpio1_2_4_7 {
+				pins = "gpio1", "gpio2", "gpio4", "gpio7";
+				function = "gpio";
+				bias-pull-up;
+			};
+
+			gpio5 {
+				pins = "gpio5";
+				function = "clk32k_out";
+			};
+	}
+
+	regulators {
+			vsup-sd2-supply = <...>;
+			...
+
+			sd0 {
+				regulator-name = "vdd_cpu";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-always-on;
+				ams,ext-control = <2>;
+			};
+
+			sd1 {
+				regulator-name = "vdd_core";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-always-on;
+				ams,ext-control = <1>;
+			};
+
+			sd2 {
+				regulator-name = "vddio_ddr";
+				regulator-min-microvolt = <1350000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+			};
+
+			sd4 {
+				regulator-name = "avdd-hdmi-pex";
+				regulator-min-microvolt = <1050000>;
+				regulator-max-microvolt = <1050000>;
+				regulator-always-on;
+			};
+
+			sd5 {
+				regulator-name = "vdd-1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+			....
+	};
+};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d078fe4..b7c74a7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -27,6 +27,18 @@ config MFD_AS3711
 	help
 	  Support for the AS3711 PMIC from AMS
 
+config MFD_AS3722
+	bool "ams AS3722 Power Management IC"
+	select MFD_CORE
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	depends on I2C && OF
+	help
+	  The ams AS3722 is a compact system PMU suitable for mobile phones,
+	  tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down
+	  controllers, 11 LDOs, RTC, automatic battery, temperature and
+	  over current monitoring, GPIOs, ADC and a watchdog.
+
 config PMIC_ADP5520
 	bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
 	depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 656cec9..8a28dc9 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -162,4 +162,5 @@ obj-$(CONFIG_MFD_LM3533)	+= lm3533-core.o lm3533-ctrlbank.o
 obj-$(CONFIG_VEXPRESS_CONFIG)	+= vexpress-config.o vexpress-sysreg.o
 obj-$(CONFIG_MFD_RETU)		+= retu-mfd.o
 obj-$(CONFIG_MFD_AS3711)	+= as3711.o
+obj-$(CONFIG_MFD_AS3722)	+= as3722.o
 obj-$(CONFIG_MFD_STW481X)	+= stw481x.o
diff --git a/drivers/mfd/as3722.c b/drivers/mfd/as3722.c
new file mode 100644
index 0000000..cd8ee59
--- /dev/null
+++ b/drivers/mfd/as3722.c
@@ -0,0 +1,449 @@
+/*
+ * Core driver for ams AS3722 PMICs
+ *
+ * Copyright (C) 2013 AMS AG
+ * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
+ *
+ * Author: Florian Lobmaier <florian.lobmaier@ams.com>
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/as3722.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define AS3722_DEVICE_ID	0x0C
+
+static const struct resource as3722_rtc_resource[] = {
+	{
+		.name = "as3722-rtc-alarm",
+		.start = AS3722_IRQ_RTC_ALARM,
+		.end = AS3722_IRQ_RTC_ALARM,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static const struct resource as3722_adc_resource[] = {
+	{
+		.name = "as3722-adc",
+		.start = AS3722_IRQ_ADC,
+		.end = AS3722_IRQ_ADC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell as3722_devs[] = {
+	{
+		.name = "as3722-pinctrl",
+	},
+	{
+		.name = "as3722-regulator",
+	},
+	{
+		.name = "as3722-rtc",
+		.num_resources = ARRAY_SIZE(as3722_rtc_resource),
+		.resources = as3722_rtc_resource,
+	},
+	{
+		.name = "as3722-adc",
+		.num_resources = ARRAY_SIZE(as3722_adc_resource),
+		.resources = as3722_adc_resource,
+	},
+	{
+		.name = "as3722-power-off",
+	},
+};
+
+static const struct regmap_irq as3722_irqs[] = {
+	/* INT1 IRQs */
+	[AS3722_IRQ_LID] = {
+		.mask = AS3722_INTERRUPT_MASK1_LID,
+	},
+	[AS3722_IRQ_ACOK] = {
+		.mask = AS3722_INTERRUPT_MASK1_ACOK,
+	},
+	[AS3722_IRQ_ENABLE1] = {
+		.mask = AS3722_INTERRUPT_MASK1_ENABLE1,
+	},
+	[AS3722_IRQ_OCCUR_ALARM_SD0] = {
+		.mask = AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0,
+	},
+	[AS3722_IRQ_ONKEY_LONG_PRESS] = {
+		.mask = AS3722_INTERRUPT_MASK1_ONKEY_LONG,
+	},
+	[AS3722_IRQ_ONKEY] = {
+		.mask = AS3722_INTERRUPT_MASK1_ONKEY,
+	},
+	[AS3722_IRQ_OVTMP] = {
+		.mask = AS3722_INTERRUPT_MASK1_OVTMP,
+	},
+	[AS3722_IRQ_LOWBAT] = {
+		.mask = AS3722_INTERRUPT_MASK1_LOWBAT,
+	},
+
+	/* INT2 IRQs */
+	[AS3722_IRQ_SD0_LV] = {
+		.mask = AS3722_INTERRUPT_MASK2_SD0_LV,
+		.reg_offset = 1,
+	},
+	[AS3722_IRQ_SD1_LV] = {
+		.mask = AS3722_INTERRUPT_MASK2_SD1_LV,
+		.reg_offset = 1,
+	},
+	[AS3722_IRQ_SD2_LV] = {
+		.mask = AS3722_INTERRUPT_MASK2_SD2345_LV,
+		.reg_offset = 1,
+	},
+	[AS3722_IRQ_PWM1_OV_PROT] = {
+		.mask = AS3722_INTERRUPT_MASK2_PWM1_OV_PROT,
+		.reg_offset = 1,
+	},
+	[AS3722_IRQ_PWM2_OV_PROT] = {
+		.mask = AS3722_INTERRUPT_MASK2_PWM2_OV_PROT,
+		.reg_offset = 1,
+	},
+	[AS3722_IRQ_ENABLE2] = {
+		.mask = AS3722_INTERRUPT_MASK2_ENABLE2,
+		.reg_offset = 1,
+	},
+	[AS3722_IRQ_SD6_LV] = {
+		.mask = AS3722_INTERRUPT_MASK2_SD6_LV,
+		.reg_offset = 1,
+	},
+	[AS3722_IRQ_RTC_REP] = {
+		.mask = AS3722_INTERRUPT_MASK2_RTC_REP,
+		.reg_offset = 1,
+	},
+
+	/* INT3 IRQs */
+	[AS3722_IRQ_RTC_ALARM] = {
+		.mask = AS3722_INTERRUPT_MASK3_RTC_ALARM,
+		.reg_offset = 2,
+	},
+	[AS3722_IRQ_GPIO1] = {
+		.mask = AS3722_INTERRUPT_MASK3_GPIO1,
+		.reg_offset = 2,
+	},
+	[AS3722_IRQ_GPIO2] = {
+		.mask = AS3722_INTERRUPT_MASK3_GPIO2,
+		.reg_offset = 2,
+	},
+	[AS3722_IRQ_GPIO3] = {
+		.mask = AS3722_INTERRUPT_MASK3_GPIO3,
+		.reg_offset = 2,
+	},
+	[AS3722_IRQ_GPIO4] = {
+		.mask = AS3722_INTERRUPT_MASK3_GPIO4,
+		.reg_offset = 2,
+	},
+	[AS3722_IRQ_GPIO5] = {
+		.mask = AS3722_INTERRUPT_MASK3_GPIO5,
+		.reg_offset = 2,
+	},
+	[AS3722_IRQ_WATCHDOG] = {
+		.mask = AS3722_INTERRUPT_MASK3_WATCHDOG,
+		.reg_offset = 2,
+	},
+	[AS3722_IRQ_ENABLE3] = {
+		.mask = AS3722_INTERRUPT_MASK3_ENABLE3,
+		.reg_offset = 2,
+	},
+
+	/* INT4 IRQs */
+	[AS3722_IRQ_TEMP_SD0_SHUTDOWN] = {
+		.mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN,
+		.reg_offset = 3,
+	},
+	[AS3722_IRQ_TEMP_SD1_SHUTDOWN] = {
+		.mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN,
+		.reg_offset = 3,
+	},
+	[AS3722_IRQ_TEMP_SD2_SHUTDOWN] = {
+		.mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN,
+		.reg_offset = 3,
+	},
+	[AS3722_IRQ_TEMP_SD0_ALARM] = {
+		.mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM,
+		.reg_offset = 3,
+	},
+	[AS3722_IRQ_TEMP_SD1_ALARM] = {
+		.mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM,
+		.reg_offset = 3,
+	},
+	[AS3722_IRQ_TEMP_SD6_ALARM] = {
+		.mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM,
+		.reg_offset = 3,
+	},
+	[AS3722_IRQ_OCCUR_ALARM_SD6] = {
+		.mask = AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6,
+		.reg_offset = 3,
+	},
+	[AS3722_IRQ_ADC] = {
+		.mask = AS3722_INTERRUPT_MASK4_ADC,
+		.reg_offset = 3,
+	},
+};
+
+static const struct regmap_irq_chip as3722_irq_chip = {
+	.name = "as3722",
+	.irqs = as3722_irqs,
+	.num_irqs = ARRAY_SIZE(as3722_irqs),
+	.num_regs = 4,
+	.status_base = AS3722_INTERRUPT_STATUS1_REG,
+	.mask_base = AS3722_INTERRUPT_MASK1_REG,
+};
+
+static int as3722_check_device_id(struct as3722 *as3722)
+{
+	u32 val;
+	int ret;
+
+	/* Check that this is actually a AS3722 */
+	ret = as3722_read(as3722, AS3722_ASIC_ID1_REG, &val);
+	if (ret < 0) {
+		dev_err(as3722->dev, "ASIC_ID1 read failed: %d\n", ret);
+		return ret;
+	}
+
+	if (val != AS3722_DEVICE_ID) {
+		dev_err(as3722->dev, "Device is not AS3722, ID is 0x%x\n", val);
+		return -ENODEV;
+	}
+
+	ret = as3722_read(as3722, AS3722_ASIC_ID2_REG, &val);
+	if (ret < 0) {
+		dev_err(as3722->dev, "ASIC_ID2 read failed: %d\n", ret);
+		return ret;
+	}
+
+	dev_info(as3722->dev, "AS3722 with revision 0x%x found\n", val);
+	return 0;
+}
+
+static int as3722_configure_pullups(struct as3722 *as3722)
+{
+	int ret;
+	u32 val = 0;
+
+	if (as3722->en_intern_int_pullup)
+		val |= AS3722_INT_PULL_UP;
+	if (as3722->en_intern_i2c_pullup)
+		val |= AS3722_I2C_PULL_UP;
+
+	ret = as3722_update_bits(as3722, AS3722_IOVOLTAGE_REG,
+			AS3722_INT_PULL_UP | AS3722_I2C_PULL_UP, val);
+	if (ret < 0)
+		dev_err(as3722->dev, "IOVOLTAGE_REG update failed: %d\n", ret);
+	return ret;
+}
+
+static const struct regmap_range as3722_readable_ranges[] = {
+	regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG),
+	regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG),
+	regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_REG_SEQU_MOD3_REG),
+	regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG),
+	regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG),
+	regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG,
+					AS3722_BATTERY_VOLTAGE_MONITOR2_REG),
+	regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG),
+	regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG),
+	regmap_reg_range(AS3722_RTC_ACCESS_REG, AS3722_RTC_ACCESS_REG),
+	regmap_reg_range(AS3722_RTC_STATUS_REG, AS3722_TEMP_STATUS_REG),
+	regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG),
+	regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG),
+	regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
+};
+
+static const struct regmap_access_table as3722_readable_table = {
+	.yes_ranges = as3722_readable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(as3722_readable_ranges),
+};
+
+static const struct regmap_range as3722_writable_ranges[] = {
+	regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG),
+	regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG),
+	regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_GPIO_SIGNAL_OUT_REG),
+	regmap_reg_range(AS3722_REG_SEQU_MOD1_REG, AS3722_REG_SEQU_MOD3_REG),
+	regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG),
+	regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG),
+	regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG,
+					AS3722_BATTERY_VOLTAGE_MONITOR2_REG),
+	regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG),
+	regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG),
+	regmap_reg_range(AS3722_INTERRUPT_MASK1_REG, AS3722_TEMP_STATUS_REG),
+	regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC1_CONTROL_REG),
+	regmap_reg_range(AS3722_ADC1_THRESHOLD_HI_MSB_REG,
+					AS3722_ADC_CONFIGURATION_REG),
+	regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
+};
+
+static const struct regmap_access_table as3722_writable_table = {
+	.yes_ranges = as3722_writable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(as3722_writable_ranges),
+};
+
+static const struct regmap_range as3722_cacheable_ranges[] = {
+	regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_LDO11_VOLTAGE_REG),
+	regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_LDOCONTROL1_REG),
+};
+
+static const struct regmap_access_table as3722_volatile_table = {
+	.no_ranges = as3722_cacheable_ranges,
+	.n_no_ranges = ARRAY_SIZE(as3722_cacheable_ranges),
+};
+
+const struct regmap_config as3722_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = AS3722_MAX_REGISTER,
+	.cache_type = REGCACHE_RBTREE,
+	.rd_table = &as3722_readable_table,
+	.wr_table = &as3722_writable_table,
+	.volatile_table = &as3722_volatile_table,
+};
+
+static int as3722_i2c_of_probe(struct i2c_client *i2c,
+			struct as3722 *as3722)
+{
+	struct device_node *np = i2c->dev.of_node;
+	struct irq_data *irq_data;
+
+	if (!np) {
+		dev_err(&i2c->dev, "Device Tree not found\n");
+		return -EINVAL;
+	}
+
+	irq_data = irq_get_irq_data(i2c->irq);
+	if (!irq_data) {
+		dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq);
+		return -EINVAL;
+	}
+
+	as3722->en_intern_int_pullup = of_property_read_bool(np,
+					"ams,enable-internal-int-pullup");
+	as3722->en_intern_i2c_pullup = of_property_read_bool(np,
+					"ams,enable-internal-i2c-pullup");
+	as3722->irq_flags = irqd_get_trigger_type(irq_data);
+	dev_dbg(&i2c->dev, "IRQ flags are 0x%08lx\n", as3722->irq_flags);
+	return 0;
+}
+
+static int as3722_i2c_probe(struct i2c_client *i2c,
+			const struct i2c_device_id *id)
+{
+	struct as3722 *as3722;
+	unsigned long irq_flags;
+	int ret;
+
+	as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL);
+	if (!as3722)
+		return -ENOMEM;
+
+	as3722->dev = &i2c->dev;
+	as3722->chip_irq = i2c->irq;
+	i2c_set_clientdata(i2c, as3722);
+
+	ret = as3722_i2c_of_probe(i2c, as3722);
+	if (ret < 0)
+		return ret;
+
+	as3722->regmap = devm_regmap_init_i2c(i2c, &as3722_regmap_config);
+	if (IS_ERR(as3722->regmap)) {
+		ret = PTR_ERR(as3722->regmap);
+		dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = as3722_check_device_id(as3722);
+	if (ret < 0)
+		return ret;
+
+	irq_flags = as3722->irq_flags | IRQF_ONESHOT;
+	ret = regmap_add_irq_chip(as3722->regmap, as3722->chip_irq,
+			irq_flags, -1, &as3722_irq_chip,
+			&as3722->irq_data);
+	if (ret < 0) {
+		dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret);
+		return ret;
+	}
+
+	ret = as3722_configure_pullups(as3722);
+	if (ret < 0)
+		goto scrub;
+
+	ret = mfd_add_devices(&i2c->dev, -1, as3722_devs,
+			ARRAY_SIZE(as3722_devs), NULL, 0,
+			regmap_irq_get_domain(as3722->irq_data));
+	if (ret) {
+		dev_err(as3722->dev, "Failed to add MFD devices: %d\n", ret);
+		goto scrub;
+	}
+
+	dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n");
+	return 0;
+
+scrub:
+	regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data);
+	return ret;
+}
+
+static int as3722_i2c_remove(struct i2c_client *i2c)
+{
+	struct as3722 *as3722 = i2c_get_clientdata(i2c);
+
+	mfd_remove_devices(as3722->dev);
+	regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data);
+	return 0;
+}
+
+static const struct of_device_id as3722_of_match[] = {
+	{ .compatible = "ams,as3722", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, as3722_of_match);
+
+static const struct i2c_device_id as3722_i2c_id[] = {
+	{ "as3722", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, as3722_i2c_id);
+
+static struct i2c_driver as3722_i2c_driver = {
+	.driver = {
+		.name = "as3722",
+		.owner = THIS_MODULE,
+		.of_match_table = as3722_of_match,
+	},
+	.probe = as3722_i2c_probe,
+	.remove = as3722_i2c_remove,
+	.id_table = as3722_i2c_id,
+};
+
+module_i2c_driver(as3722_i2c_driver);
+
+MODULE_DESCRIPTION("I2C support for AS3722 PMICs");
+MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>");
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/dt-bindings/mfd/as3722.h b/include/dt-bindings/mfd/as3722.h
new file mode 100644
index 0000000..0e69256
--- /dev/null
+++ b/include/dt-bindings/mfd/as3722.h
@@ -0,0 +1,52 @@
+/*
+ * This header provides macros for ams AS3722 device bindings.
+ *
+ * Copyright (c) 2013, NVIDIA Corporation.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_AS3722_H__
+#define __DT_BINDINGS_AS3722_H__
+
+/* External control pins */
+#define AS3722_EXT_CONTROL_PIN_ENABLE1 1
+#define AS3722_EXT_CONTROL_PIN_ENABLE2 2
+#define AS3722_EXT_CONTROL_PIN_ENABLE2 3
+
+/* Interrupt numbers for AS3722 */
+#define AS3722_IRQ_LID			0
+#define AS3722_IRQ_ACOK			1
+#define AS3722_IRQ_ENABLE1		2
+#define AS3722_IRQ_OCCUR_ALARM_SD0	3
+#define AS3722_IRQ_ONKEY_LONG_PRESS	4
+#define AS3722_IRQ_ONKEY		5
+#define AS3722_IRQ_OVTMP		6
+#define AS3722_IRQ_LOWBAT		7
+#define AS3722_IRQ_SD0_LV		8
+#define AS3722_IRQ_SD1_LV		9
+#define AS3722_IRQ_SD2_LV		10
+#define AS3722_IRQ_PWM1_OV_PROT		11
+#define AS3722_IRQ_PWM2_OV_PROT		12
+#define AS3722_IRQ_ENABLE2		13
+#define AS3722_IRQ_SD6_LV		14
+#define AS3722_IRQ_RTC_REP		15
+#define AS3722_IRQ_RTC_ALARM		16
+#define AS3722_IRQ_GPIO1		17
+#define AS3722_IRQ_GPIO2		18
+#define AS3722_IRQ_GPIO3		19
+#define AS3722_IRQ_GPIO4		20
+#define AS3722_IRQ_GPIO5		21
+#define AS3722_IRQ_WATCHDOG		22
+#define AS3722_IRQ_ENABLE3		23
+#define AS3722_IRQ_TEMP_SD0_SHUTDOWN	24
+#define AS3722_IRQ_TEMP_SD1_SHUTDOWN	25
+#define AS3722_IRQ_TEMP_SD2_SHUTDOWN	26
+#define AS3722_IRQ_TEMP_SD0_ALARM	27
+#define AS3722_IRQ_TEMP_SD1_ALARM	28
+#define AS3722_IRQ_TEMP_SD6_ALARM	29
+#define AS3722_IRQ_OCCUR_ALARM_SD6	30
+#define AS3722_IRQ_ADC			31
+
+#endif /* __DT_BINDINGS_AS3722_H__ */
diff --git a/include/linux/mfd/as3722.h b/include/linux/mfd/as3722.h
new file mode 100644
index 0000000..16bf8a0
--- /dev/null
+++ b/include/linux/mfd/as3722.h
@@ -0,0 +1,423 @@
+/*
+ * as3722 definitions
+ *
+ * Copyright (C) 2013 ams
+ * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
+ *
+ * Author: Florian Lobmaier <florian.lobmaier@ams.com>
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#ifndef __LINUX_MFD_AS3722_H__
+#define __LINUX_MFD_AS3722_H__
+
+#include <linux/regmap.h>
+
+/* AS3722 registers */
+#define AS3722_SD0_VOLTAGE_REG				0x00
+#define AS3722_SD1_VOLTAGE_REG				0x01
+#define AS3722_SD2_VOLTAGE_REG				0x02
+#define AS3722_SD3_VOLTAGE_REG				0x03
+#define AS3722_SD4_VOLTAGE_REG				0x04
+#define AS3722_SD5_VOLTAGE_REG				0x05
+#define AS3722_SD6_VOLTAGE_REG				0x06
+#define AS3722_GPIO0_CONTROL_REG			0x08
+#define AS3722_GPIO1_CONTROL_REG			0x09
+#define AS3722_GPIO2_CONTROL_REG			0x0A
+#define AS3722_GPIO3_CONTROL_REG			0x0B
+#define AS3722_GPIO4_CONTROL_REG			0x0C
+#define AS3722_GPIO5_CONTROL_REG			0x0D
+#define AS3722_GPIO6_CONTROL_REG			0x0E
+#define AS3722_GPIO7_CONTROL_REG			0x0F
+#define AS3722_LDO0_VOLTAGE_REG				0x10
+#define AS3722_LDO1_VOLTAGE_REG				0x11
+#define AS3722_LDO2_VOLTAGE_REG				0x12
+#define AS3722_LDO3_VOLTAGE_REG				0x13
+#define AS3722_LDO4_VOLTAGE_REG				0x14
+#define AS3722_LDO5_VOLTAGE_REG				0x15
+#define AS3722_LDO6_VOLTAGE_REG				0x16
+#define AS3722_LDO7_VOLTAGE_REG				0x17
+#define AS3722_LDO9_VOLTAGE_REG				0x19
+#define AS3722_LDO10_VOLTAGE_REG			0x1A
+#define AS3722_LDO11_VOLTAGE_REG			0x1B
+#define AS3722_GPIO_DEB1_REG				0x1E
+#define AS3722_GPIO_DEB2_REG				0x1F
+#define AS3722_GPIO_SIGNAL_OUT_REG			0x20
+#define AS3722_GPIO_SIGNAL_IN_REG			0x21
+#define AS3722_REG_SEQU_MOD1_REG			0x22
+#define AS3722_REG_SEQU_MOD2_REG			0x23
+#define AS3722_REG_SEQU_MOD3_REG			0x24
+#define AS3722_SD_PHSW_CTRL_REG				0x27
+#define AS3722_SD_PHSW_STATUS				0x28
+#define AS3722_SD0_CONTROL_REG				0x29
+#define AS3722_SD1_CONTROL_REG				0x2A
+#define AS3722_SDmph_CONTROL_REG			0x2B
+#define AS3722_SD23_CONTROL_REG				0x2C
+#define AS3722_SD4_CONTROL_REG				0x2D
+#define AS3722_SD5_CONTROL_REG				0x2E
+#define AS3722_SD6_CONTROL_REG				0x2F
+#define AS3722_SD_DVM_REG				0x30
+#define AS3722_RESET_REASON_REG				0x31
+#define AS3722_BATTERY_VOLTAGE_MONITOR_REG		0x32
+#define AS3722_STARTUP_CONTROL_REG			0x33
+#define AS3722_RESET_TIMER_REG				0x34
+#define AS3722_REFERENCE_CONTROL_REG			0x35
+#define AS3722_RESET_CONTROL_REG			0x36
+#define AS3722_OVER_TEMP_CONTROL_REG			0x37
+#define AS3722_WATCHDOG_CONTROL_REG			0x38
+#define AS3722_REG_STANDBY_MOD1_REG			0x39
+#define AS3722_REG_STANDBY_MOD2_REG			0x3A
+#define AS3722_REG_STANDBY_MOD3_REG			0x3B
+#define AS3722_ENABLE_CTRL1_REG				0x3C
+#define AS3722_ENABLE_CTRL2_REG				0x3D
+#define AS3722_ENABLE_CTRL3_REG				0x3E
+#define AS3722_ENABLE_CTRL4_REG				0x3F
+#define AS3722_ENABLE_CTRL5_REG				0x40
+#define AS3722_PWM_CONTROL_L_REG			0x41
+#define AS3722_PWM_CONTROL_H_REG			0x42
+#define AS3722_WATCHDOG_TIMER_REG			0x46
+#define AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG		0x48
+#define AS3722_IOVOLTAGE_REG				0x49
+#define AS3722_BATTERY_VOLTAGE_MONITOR2_REG		0x4A
+#define AS3722_SD_CONTROL_REG				0x4D
+#define AS3722_LDOCONTROL0_REG				0x4E
+#define AS3722_LDOCONTROL1_REG				0x4F
+#define AS3722_SD0_PROTECT_REG				0x50
+#define AS3722_SD6_PROTECT_REG				0x51
+#define AS3722_PWM_VCONTROL1_REG			0x52
+#define AS3722_PWM_VCONTROL2_REG			0x53
+#define AS3722_PWM_VCONTROL3_REG			0x54
+#define AS3722_PWM_VCONTROL4_REG			0x55
+#define AS3722_BB_CHARGER_REG				0x57
+#define AS3722_CTRL_SEQU1_REG				0x58
+#define AS3722_CTRL_SEQU2_REG				0x59
+#define AS3722_OVCURRENT_REG				0x5A
+#define AS3722_OVCURRENT_DEB_REG			0x5B
+#define AS3722_SDLV_DEB_REG				0x5C
+#define AS3722_OC_PG_CTRL_REG				0x5D
+#define AS3722_OC_PG_CTRL2_REG				0x5E
+#define AS3722_CTRL_STATUS				0x5F
+#define AS3722_RTC_CONTROL_REG				0x60
+#define AS3722_RTC_SECOND_REG				0x61
+#define AS3722_RTC_MINUTE_REG				0x62
+#define AS3722_RTC_HOUR_REG				0x63
+#define AS3722_RTC_DAY_REG				0x64
+#define AS3722_RTC_MONTH_REG				0x65
+#define AS3722_RTC_YEAR_REG				0x66
+#define AS3722_RTC_ALARM_SECOND_REG			0x67
+#define AS3722_RTC_ALARM_MINUTE_REG			0x68
+#define AS3722_RTC_ALARM_HOUR_REG			0x69
+#define AS3722_RTC_ALARM_DAY_REG			0x6A
+#define AS3722_RTC_ALARM_MONTH_REG			0x6B
+#define AS3722_RTC_ALARM_YEAR_REG			0x6C
+#define AS3722_SRAM_REG					0x6D
+#define AS3722_RTC_ACCESS_REG				0x6F
+#define AS3722_RTC_STATUS_REG				0x73
+#define AS3722_INTERRUPT_MASK1_REG			0x74
+#define AS3722_INTERRUPT_MASK2_REG			0x75
+#define AS3722_INTERRUPT_MASK3_REG			0x76
+#define AS3722_INTERRUPT_MASK4_REG			0x77
+#define AS3722_INTERRUPT_STATUS1_REG			0x78
+#define AS3722_INTERRUPT_STATUS2_REG			0x79
+#define AS3722_INTERRUPT_STATUS3_REG			0x7A
+#define AS3722_INTERRUPT_STATUS4_REG			0x7B
+#define AS3722_TEMP_STATUS_REG				0x7D
+#define AS3722_ADC0_CONTROL_REG				0x80
+#define AS3722_ADC1_CONTROL_REG				0x81
+#define AS3722_ADC0_MSB_RESULT_REG			0x82
+#define AS3722_ADC0_LSB_RESULT_REG			0x83
+#define AS3722_ADC1_MSB_RESULT_REG			0x84
+#define AS3722_ADC1_LSB_RESULT_REG			0x85
+#define AS3722_ADC1_THRESHOLD_HI_MSB_REG		0x86
+#define AS3722_ADC1_THRESHOLD_HI_LSB_REG		0x87
+#define AS3722_ADC1_THRESHOLD_LO_MSB_REG		0x88
+#define AS3722_ADC1_THRESHOLD_LO_LSB_REG		0x89
+#define AS3722_ADC_CONFIGURATION_REG			0x8A
+#define AS3722_ASIC_ID1_REG				0x90
+#define AS3722_ASIC_ID2_REG				0x91
+#define AS3722_LOCK_REG					0x9E
+#define AS3722_MAX_REGISTER				0xF4
+
+#define AS3722_SD0_EXT_ENABLE_MASK			0x03
+#define AS3722_SD1_EXT_ENABLE_MASK			0x0C
+#define AS3722_SD2_EXT_ENABLE_MASK			0x30
+#define AS3722_SD3_EXT_ENABLE_MASK			0xC0
+#define AS3722_SD4_EXT_ENABLE_MASK			0x03
+#define AS3722_SD5_EXT_ENABLE_MASK			0x0C
+#define AS3722_SD6_EXT_ENABLE_MASK			0x30
+#define AS3722_LDO0_EXT_ENABLE_MASK			0x03
+#define AS3722_LDO1_EXT_ENABLE_MASK			0x0C
+#define AS3722_LDO2_EXT_ENABLE_MASK			0x30
+#define AS3722_LDO3_EXT_ENABLE_MASK			0xC0
+#define AS3722_LDO4_EXT_ENABLE_MASK			0x03
+#define AS3722_LDO5_EXT_ENABLE_MASK			0x0C
+#define AS3722_LDO6_EXT_ENABLE_MASK			0x30
+#define AS3722_LDO7_EXT_ENABLE_MASK			0xC0
+#define AS3722_LDO9_EXT_ENABLE_MASK			0x0C
+#define AS3722_LDO10_EXT_ENABLE_MASK			0x30
+#define AS3722_LDO11_EXT_ENABLE_MASK			0xC0
+
+#define AS3722_OVCURRENT_SD0_ALARM_MASK			0x07
+#define AS3722_OVCURRENT_SD0_ALARM_SHIFT		0x01
+#define AS3722_OVCURRENT_SD0_TRIP_MASK			0x18
+#define AS3722_OVCURRENT_SD0_TRIP_SHIFT			0x03
+#define AS3722_OVCURRENT_SD1_TRIP_MASK			0x60
+#define AS3722_OVCURRENT_SD1_TRIP_SHIFT			0x05
+
+#define AS3722_OVCURRENT_SD6_ALARM_MASK			0x07
+#define AS3722_OVCURRENT_SD6_ALARM_SHIFT		0x01
+#define AS3722_OVCURRENT_SD6_TRIP_MASK			0x18
+#define AS3722_OVCURRENT_SD6_TRIP_SHIFT			0x03
+
+/* AS3722 register bits and bit masks */
+#define AS3722_LDO_ILIMIT_MASK				BIT(7)
+#define AS3722_LDO_ILIMIT_BIT				BIT(7)
+#define AS3722_LDO0_VSEL_MASK				0x1F
+#define AS3722_LDO0_VSEL_MIN				0x01
+#define AS3722_LDO0_VSEL_MAX				0x12
+#define AS3722_LDO0_NUM_VOLT				0x12
+#define AS3722_LDO3_VSEL_MASK				0x3F
+#define AS3722_LDO3_VSEL_MIN				0x01
+#define AS3722_LDO3_VSEL_MAX				0x2D
+#define AS3722_LDO3_NUM_VOLT				0x2D
+#define AS3722_LDO_VSEL_MASK				0x7F
+#define AS3722_LDO_VSEL_MIN				0x01
+#define AS3722_LDO_VSEL_MAX				0x7F
+#define AS3722_LDO_VSEL_DNU_MIN				0x25
+#define AS3722_LDO_VSEL_DNU_MAX				0x3F
+#define AS3722_LDO_NUM_VOLT				0x80
+
+#define AS3722_LDO0_CTRL				BIT(0)
+#define AS3722_LDO1_CTRL				BIT(1)
+#define AS3722_LDO2_CTRL				BIT(2)
+#define AS3722_LDO3_CTRL				BIT(3)
+#define AS3722_LDO4_CTRL				BIT(4)
+#define AS3722_LDO5_CTRL				BIT(5)
+#define AS3722_LDO6_CTRL				BIT(6)
+#define AS3722_LDO7_CTRL				BIT(7)
+#define AS3722_LDO9_CTRL				BIT(1)
+#define AS3722_LDO10_CTRL				BIT(2)
+#define AS3722_LDO11_CTRL				BIT(3)
+
+#define AS3722_LDO3_MODE_MASK				(3 << 6)
+#define AS3722_LDO3_MODE_VAL(n)				(((n) & 0x3) << 6)
+#define AS3722_LDO3_MODE_PMOS				AS3722_LDO3_MODE_VAL(0)
+#define AS3722_LDO3_MODE_PMOS_TRACKING			AS3722_LDO3_MODE_VAL(1)
+#define AS3722_LDO3_MODE_NMOS				AS3722_LDO3_MODE_VAL(2)
+#define AS3722_LDO3_MODE_SWITCH				AS3722_LDO3_MODE_VAL(3)
+
+#define AS3722_SD_VSEL_MASK				0x7F
+#define AS3722_SD0_VSEL_MIN				0x01
+#define AS3722_SD0_VSEL_MAX				0x5A
+#define AS3722_SD2_VSEL_MIN				0x01
+#define AS3722_SD2_VSEL_MAX				0x7F
+
+#define AS3722_SDn_CTRL(n)				BIT(n)
+
+#define AS3722_SD0_MODE_FAST				BIT(4)
+#define AS3722_SD1_MODE_FAST				BIT(4)
+#define AS3722_SD2_MODE_FAST				BIT(2)
+#define AS3722_SD3_MODE_FAST				BIT(6)
+#define AS3722_SD4_MODE_FAST				BIT(2)
+#define AS3722_SD5_MODE_FAST				BIT(2)
+#define AS3722_SD6_MODE_FAST				BIT(4)
+
+#define AS3722_POWER_OFF				BIT(1)
+
+#define AS3722_INTERRUPT_MASK1_LID			BIT(0)
+#define AS3722_INTERRUPT_MASK1_ACOK			BIT(1)
+#define AS3722_INTERRUPT_MASK1_ENABLE1			BIT(2)
+#define AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0		BIT(3)
+#define AS3722_INTERRUPT_MASK1_ONKEY_LONG		BIT(4)
+#define AS3722_INTERRUPT_MASK1_ONKEY			BIT(5)
+#define AS3722_INTERRUPT_MASK1_OVTMP			BIT(6)
+#define AS3722_INTERRUPT_MASK1_LOWBAT			BIT(7)
+
+#define AS3722_INTERRUPT_MASK2_SD0_LV			BIT(0)
+#define AS3722_INTERRUPT_MASK2_SD1_LV			BIT(1)
+#define AS3722_INTERRUPT_MASK2_SD2345_LV		BIT(2)
+#define AS3722_INTERRUPT_MASK2_PWM1_OV_PROT		BIT(3)
+#define AS3722_INTERRUPT_MASK2_PWM2_OV_PROT		BIT(4)
+#define AS3722_INTERRUPT_MASK2_ENABLE2			BIT(5)
+#define AS3722_INTERRUPT_MASK2_SD6_LV			BIT(6)
+#define AS3722_INTERRUPT_MASK2_RTC_REP			BIT(7)
+
+#define AS3722_INTERRUPT_MASK3_RTC_ALARM		BIT(0)
+#define AS3722_INTERRUPT_MASK3_GPIO1			BIT(1)
+#define AS3722_INTERRUPT_MASK3_GPIO2			BIT(2)
+#define AS3722_INTERRUPT_MASK3_GPIO3			BIT(3)
+#define AS3722_INTERRUPT_MASK3_GPIO4			BIT(4)
+#define AS3722_INTERRUPT_MASK3_GPIO5			BIT(5)
+#define AS3722_INTERRUPT_MASK3_WATCHDOG			BIT(6)
+#define AS3722_INTERRUPT_MASK3_ENABLE3			BIT(7)
+
+#define AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN	BIT(0)
+#define AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN	BIT(1)
+#define AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN	BIT(2)
+#define AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM		BIT(3)
+#define AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM		BIT(4)
+#define AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM		BIT(5)
+#define AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6		BIT(6)
+#define AS3722_INTERRUPT_MASK4_ADC			BIT(7)
+
+#define AS3722_ADC1_INTERVAL_TIME			BIT(0)
+#define AS3722_ADC1_INT_MODE_ON				BIT(1)
+#define AS3722_ADC_BUF_ON				BIT(2)
+#define AS3722_ADC1_LOW_VOLTAGE_RANGE			BIT(5)
+#define AS3722_ADC1_INTEVAL_SCAN			BIT(6)
+#define AS3722_ADC1_INT_MASK				BIT(7)
+
+#define AS3722_ADC_MSB_VAL_MASK				0x7F
+#define AS3722_ADC_LSB_VAL_MASK				0x07
+
+#define AS3722_ADC0_CONV_START				BIT(7)
+#define AS3722_ADC0_CONV_NOTREADY			BIT(7)
+#define AS3722_ADC0_SOURCE_SELECT_MASK			0x1F
+
+#define AS3722_ADC1_CONV_START				BIT(7)
+#define AS3722_ADC1_CONV_NOTREADY			BIT(7)
+#define AS3722_ADC1_SOURCE_SELECT_MASK			0x1F
+
+/* GPIO modes */
+#define AS3722_GPIO_MODE_MASK				0x07
+#define AS3722_GPIO_MODE_INPUT				0x00
+#define AS3722_GPIO_MODE_OUTPUT_VDDH			0x01
+#define AS3722_GPIO_MODE_IO_OPEN_DRAIN			0x02
+#define AS3722_GPIO_MODE_ADC_IN				0x03
+#define AS3722_GPIO_MODE_INPUT_PULL_UP			0x04
+#define AS3722_GPIO_MODE_INPUT_PULL_DOWN		0x05
+#define AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP		0x06
+#define AS3722_GPIO_MODE_OUTPUT_VDDL			0x07
+#define AS3722_GPIO_MODE_VAL(n)			((n) & AS3722_GPIO_MODE_MASK)
+
+#define AS3722_GPIO_INV					BIT(7)
+#define AS3722_GPIO_IOSF_MASK				0x78
+#define AS3722_GPIO_IOSF_VAL(n)				(((n) & 0xF) << 3)
+#define AS3722_GPIO_IOSF_NORMAL				AS3722_GPIO_IOSF_VAL(0)
+#define AS3722_GPIO_IOSF_INTERRUPT_OUT			AS3722_GPIO_IOSF_VAL(1)
+#define AS3722_GPIO_IOSF_VSUP_LOW_OUT			AS3722_GPIO_IOSF_VAL(2)
+#define AS3722_GPIO_IOSF_GPIO_INTERRUPT_IN		AS3722_GPIO_IOSF_VAL(3)
+#define AS3722_GPIO_IOSF_ISINK_PWM_IN			AS3722_GPIO_IOSF_VAL(4)
+#define AS3722_GPIO_IOSF_VOLTAGE_STBY			AS3722_GPIO_IOSF_VAL(5)
+#define AS3722_GPIO_IOSF_PWR_GOOD_OUT			AS3722_GPIO_IOSF_VAL(7)
+#define AS3722_GPIO_IOSF_Q32K_OUT			AS3722_GPIO_IOSF_VAL(8)
+#define AS3722_GPIO_IOSF_WATCHDOG_IN			AS3722_GPIO_IOSF_VAL(9)
+#define AS3722_GPIO_IOSF_SOFT_RESET_IN			AS3722_GPIO_IOSF_VAL(11)
+#define AS3722_GPIO_IOSF_PWM_OUT			AS3722_GPIO_IOSF_VAL(12)
+#define AS3722_GPIO_IOSF_VSUP_LOW_DEB_OUT		AS3722_GPIO_IOSF_VAL(13)
+#define AS3722_GPIO_IOSF_SD6_LOW_VOLT_LOW		AS3722_GPIO_IOSF_VAL(14)
+
+#define AS3722_GPIOn_SIGNAL(n)				BIT(n)
+#define AS3722_GPIOn_CONTROL_REG(n)		(AS3722_GPIO0_CONTROL_REG + n)
+#define AS3722_I2C_PULL_UP				BIT(4)
+#define AS3722_INT_PULL_UP				BIT(5)
+
+#define AS3722_RTC_REP_WAKEUP_EN			BIT(0)
+#define AS3722_RTC_ALARM_WAKEUP_EN			BIT(1)
+#define AS3722_RTC_ON					BIT(2)
+#define AS3722_RTC_IRQMODE				BIT(3)
+#define AS3722_RTC_CLK32K_OUT_EN			BIT(5)
+
+#define AS3722_WATCHDOG_TIMER_MAX			0x7F
+#define AS3722_WATCHDOG_ON				BIT(0)
+#define AS3722_WATCHDOG_SW_SIG				BIT(0)
+
+#define AS3722_EXT_CONTROL_ENABLE1			0x1
+#define AS3722_EXT_CONTROL_ENABLE2			0x2
+#define AS3722_EXT_CONTROL_ENABLE3			0x3
+
+/* Interrupt IDs */
+enum as3722_irq {
+	AS3722_IRQ_LID,
+	AS3722_IRQ_ACOK,
+	AS3722_IRQ_ENABLE1,
+	AS3722_IRQ_OCCUR_ALARM_SD0,
+	AS3722_IRQ_ONKEY_LONG_PRESS,
+	AS3722_IRQ_ONKEY,
+	AS3722_IRQ_OVTMP,
+	AS3722_IRQ_LOWBAT,
+	AS3722_IRQ_SD0_LV,
+	AS3722_IRQ_SD1_LV,
+	AS3722_IRQ_SD2_LV,
+	AS3722_IRQ_PWM1_OV_PROT,
+	AS3722_IRQ_PWM2_OV_PROT,
+	AS3722_IRQ_ENABLE2,
+	AS3722_IRQ_SD6_LV,
+	AS3722_IRQ_RTC_REP,
+	AS3722_IRQ_RTC_ALARM,
+	AS3722_IRQ_GPIO1,
+	AS3722_IRQ_GPIO2,
+	AS3722_IRQ_GPIO3,
+	AS3722_IRQ_GPIO4,
+	AS3722_IRQ_GPIO5,
+	AS3722_IRQ_WATCHDOG,
+	AS3722_IRQ_ENABLE3,
+	AS3722_IRQ_TEMP_SD0_SHUTDOWN,
+	AS3722_IRQ_TEMP_SD1_SHUTDOWN,
+	AS3722_IRQ_TEMP_SD2_SHUTDOWN,
+	AS3722_IRQ_TEMP_SD0_ALARM,
+	AS3722_IRQ_TEMP_SD1_ALARM,
+	AS3722_IRQ_TEMP_SD6_ALARM,
+	AS3722_IRQ_OCCUR_ALARM_SD6,
+	AS3722_IRQ_ADC,
+	AS3722_IRQ_MAX,
+};
+
+struct as3722 {
+	struct device *dev;
+	struct regmap *regmap;
+	int chip_irq;
+	unsigned long irq_flags;
+	bool en_intern_int_pullup;
+	bool en_intern_i2c_pullup;
+	struct regmap_irq_chip_data *irq_data;
+};
+
+static inline int as3722_read(struct as3722 *as3722, u32 reg, u32 *dest)
+{
+	return regmap_read(as3722->regmap, reg, dest);
+}
+
+static inline int as3722_write(struct as3722 *as3722, u32 reg, u32 value)
+{
+	return regmap_write(as3722->regmap, reg, value);
+}
+
+static inline int as3722_block_read(struct as3722 *as3722, u32 reg,
+		int count, u8 *buf)
+{
+	return regmap_bulk_read(as3722->regmap, reg, buf, count);
+}
+
+static inline int as3722_block_write(struct as3722 *as3722, u32 reg,
+		int count, u8 *data)
+{
+	return regmap_bulk_write(as3722->regmap, reg, data, count);
+}
+
+static inline int as3722_update_bits(struct as3722 *as3722, u32 reg,
+		u32 mask, u8 val)
+{
+	return regmap_update_bits(as3722->regmap, reg, mask, val);
+}
+
+static inline int as3722_irq_get_virq(struct as3722 *as3722, int irq)
+{
+	return regmap_irq_get_virq(as3722->irq_data, irq);
+}
+#endif /* __LINUX_MFD_AS3722_H__ */
-- 
1.7.1.1


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

* [PATCH V5 2/3] pincntrl: add support for ams AS3722 pin control driver
  2013-10-09 12:29 [PATCH V5 0/3] Add AMS AS3722 mfd, pincontrol and RTC driver Laxman Dewangan
  2013-10-09 12:29 ` [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC Laxman Dewangan
@ 2013-10-09 12:29 ` Laxman Dewangan
  2013-10-09 12:29 ` [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver Laxman Dewangan
  2 siblings, 0 replies; 11+ messages in thread
From: Laxman Dewangan @ 2013-10-09 12:29 UTC (permalink / raw)
  To: lee.jones, sameo, broonie, linus.walleij, akpm
  Cc: devicetree, linux-doc, linux-kernel, linux-gpio, rtc-linux,
	rob.herring, mark.rutland, pawel.moll, swarren, rob,
	ijc+devicetree, grant.likely, Laxman Dewangan

The AS3722 is a compact system PMU suitable for mobile phones, tablets etc.

Add a driver to support accessing the GPIO, pinmux and pin configuration
of 8 GPIO pins found on the ams AS3722 through pin control driver and
gpiolib.

The driver will register itself as the pincontrol driver and gpio driver.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
Changes from V1:
- Nit cleanups in driver and use module_platform_driver.
        
Changes from V2:
- Move the gpio driver from gpio folder to pinctnrl driver and register
  driver as pincontrol driver.
- Provide pin configuration through pincntrl framework.

Changes from V3: 
- Added gpio ranges and pinctrl_gpio calls.
- Used pinctrl_gpio_* calls on gpio chips callback.
- Remove dummy function which just return not supported.
- Nit cleanups.

Changes from V4:
- Drop separate DT binding document as it is moved to mfd/as3722.txt.
- Added ack from Linus.

 drivers/pinctrl/Kconfig          |   11 +
 drivers/pinctrl/Makefile         |    1 +
 drivers/pinctrl/pinctrl-as3722.c |  630 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 642 insertions(+), 0 deletions(-)
 create mode 100644 drivers/pinctrl/pinctrl-as3722.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 21db201..85f5462 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -59,6 +59,17 @@ config PINCTRL_ADI2
 	  future processors. This option is selected automatically when specific
 	  machine and arch are selected to build.
 
+config PINCTRL_AS3722
+	bool "Pinctrl and GPIO driver for ams AS3722 PMIC"
+	depends on MFD_AS3722 && GPIOLIB
+	select PINMUX
+	select GENERIC_PINCONF
+	help
+	  AS3722 device supports the configuration of GPIO pins for different
+	  functionality. This driver supports the pinmux, push-pull and
+	  open drain configuration for the GPIO pins of AS3722 devices. It also
+	  supports the GPIO functionality through gpiolib.
+
 config PINCTRL_BF54x
 	def_bool y if BF54x
 	select PINCTRL_ADI2
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index bbeb980..3d14cb8 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_AB8540)	+= pinctrl-ab8540.o
 obj-$(CONFIG_PINCTRL_AB9540)	+= pinctrl-ab9540.o
 obj-$(CONFIG_PINCTRL_AB8505)	+= pinctrl-ab8505.o
 obj-$(CONFIG_PINCTRL_ADI2)	+= pinctrl-adi2.o
+obj-$(CONFIG_PINCTRL_AS3722)	+= pinctrl-as3722.o
 obj-$(CONFIG_PINCTRL_BF54x)	+= pinctrl-adi2-bf54x.o
 obj-$(CONFIG_PINCTRL_BF60x)	+= pinctrl-adi2-bf60x.o
 obj-$(CONFIG_PINCTRL_AT91)	+= pinctrl-at91.o
diff --git a/drivers/pinctrl/pinctrl-as3722.c b/drivers/pinctrl/pinctrl-as3722.c
new file mode 100644
index 0000000..01bffc1
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-as3722.c
@@ -0,0 +1,630 @@
+/*
+ * ams AS3722 pin control and GPIO driver.
+ *
+ * Copyright (c) 2013, NVIDIA Corporation.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/as3722.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-utils.h"
+
+#define AS3722_PIN_GPIO0		0
+#define AS3722_PIN_GPIO1		1
+#define AS3722_PIN_GPIO2		2
+#define AS3722_PIN_GPIO3		3
+#define AS3722_PIN_GPIO4		4
+#define AS3722_PIN_GPIO5		5
+#define AS3722_PIN_GPIO6		6
+#define AS3722_PIN_GPIO7		7
+#define AS3722_PIN_NUM			(AS3722_PIN_GPIO7 + 1)
+
+#define AS3722_GPIO_MODE_PULL_UP           BIT(PIN_CONFIG_BIAS_PULL_UP)
+#define AS3722_GPIO_MODE_PULL_DOWN         BIT(PIN_CONFIG_BIAS_PULL_DOWN)
+#define AS3722_GPIO_MODE_HIGH_IMPED        BIT(PIN_CONFIG_BIAS_HIGH_IMPEDANCE)
+#define AS3722_GPIO_MODE_OPEN_DRAIN        BIT(PIN_CONFIG_DRIVE_OPEN_DRAIN)
+
+struct as3722_pin_function {
+	const char *name;
+	const char * const *groups;
+	unsigned ngroups;
+	int mux_option;
+};
+
+struct as3722_gpio_pin_control {
+	bool enable_gpio_invert;
+	unsigned mode_prop;
+	int io_function;
+};
+
+struct as3722_pingroup {
+	const char *name;
+	const unsigned pins[1];
+	unsigned npins;
+};
+
+struct as3722_pctrl_info {
+	struct device *dev;
+	struct pinctrl_dev *pctl;
+	struct as3722 *as3722;
+	struct gpio_chip gpio_chip;
+	int pins_current_opt[AS3722_PIN_NUM];
+	const struct as3722_pin_function *functions;
+	unsigned num_functions;
+	const struct as3722_pingroup *pin_groups;
+	int num_pin_groups;
+	const struct pinctrl_pin_desc *pins;
+	unsigned num_pins;
+	struct as3722_gpio_pin_control gpio_control[AS3722_PIN_NUM];
+};
+
+static const struct pinctrl_pin_desc as3722_pins_desc[] = {
+	PINCTRL_PIN(AS3722_PIN_GPIO0, "gpio0"),
+	PINCTRL_PIN(AS3722_PIN_GPIO1, "gpio1"),
+	PINCTRL_PIN(AS3722_PIN_GPIO2, "gpio2"),
+	PINCTRL_PIN(AS3722_PIN_GPIO3, "gpio3"),
+	PINCTRL_PIN(AS3722_PIN_GPIO4, "gpio4"),
+	PINCTRL_PIN(AS3722_PIN_GPIO5, "gpio5"),
+	PINCTRL_PIN(AS3722_PIN_GPIO6, "gpio6"),
+	PINCTRL_PIN(AS3722_PIN_GPIO7, "gpio7"),
+};
+
+static const char * const gpio_groups[] = {
+	"gpio0",
+	"gpio1",
+	"gpio2",
+	"gpio3",
+	"gpio4",
+	"gpio5",
+	"gpio6",
+	"gpio7",
+};
+
+enum as3722_pinmux_option {
+	AS3722_PINMUX_GPIO			= 0,
+	AS3722_PINMUX_INTERRUPT_OUT		= 1,
+	AS3722_PINMUX_VSUB_VBAT_UNDEB_LOW_OUT	= 2,
+	AS3722_PINMUX_GPIO_INTERRUPT		= 3,
+	AS3722_PINMUX_PWM_INPUT			= 4,
+	AS3722_PINMUX_VOLTAGE_IN_STBY		= 5,
+	AS3722_PINMUX_OC_PG_SD0			= 6,
+	AS3722_PINMUX_PG_OUT			= 7,
+	AS3722_PINMUX_CLK32K_OUT		= 8,
+	AS3722_PINMUX_WATCHDOG_INPUT		= 9,
+	AS3722_PINMUX_SOFT_RESET_IN		= 11,
+	AS3722_PINMUX_PWM_OUTPUT		= 12,
+	AS3722_PINMUX_VSUB_VBAT_LOW_DEB_OUT	= 13,
+	AS3722_PINMUX_OC_PG_SD6			= 14,
+};
+
+#define FUNCTION_GROUP(fname, mux)			\
+	{						\
+		.name = #fname,				\
+		.groups = gpio_groups,			\
+		.ngroups = ARRAY_SIZE(gpio_groups),	\
+		.mux_option = AS3722_PINMUX_##mux,	\
+	}
+
+static const struct as3722_pin_function as3722_pin_function[] = {
+	FUNCTION_GROUP(gpio, GPIO),
+	FUNCTION_GROUP(interrupt-out, INTERRUPT_OUT),
+	FUNCTION_GROUP(gpio-in-interrupt, GPIO_INTERRUPT),
+	FUNCTION_GROUP(vsup-vbat-low-undebounce-out, VSUB_VBAT_UNDEB_LOW_OUT),
+	FUNCTION_GROUP(vsup-vbat-low-debounce-out, VSUB_VBAT_LOW_DEB_OUT),
+	FUNCTION_GROUP(voltage-in-standby, VOLTAGE_IN_STBY),
+	FUNCTION_GROUP(oc-pg-sd0, OC_PG_SD0),
+	FUNCTION_GROUP(oc-pg-sd6, OC_PG_SD6),
+	FUNCTION_GROUP(powergood-out, PG_OUT),
+	FUNCTION_GROUP(pwm-in, PWM_INPUT),
+	FUNCTION_GROUP(pwm-out, PWM_OUTPUT),
+	FUNCTION_GROUP(clk32k-out, CLK32K_OUT),
+	FUNCTION_GROUP(watchdog-in, WATCHDOG_INPUT),
+	FUNCTION_GROUP(soft-reset-in, SOFT_RESET_IN),
+};
+
+#define AS3722_PINGROUP(pg_name, pin_id) \
+	{								\
+		.name = #pg_name,					\
+		.pins = {AS3722_PIN_##pin_id},				\
+		.npins = 1,						\
+	}
+
+static const struct as3722_pingroup as3722_pingroups[] = {
+	AS3722_PINGROUP(gpio0,	GPIO0),
+	AS3722_PINGROUP(gpio1,	GPIO1),
+	AS3722_PINGROUP(gpio2,	GPIO2),
+	AS3722_PINGROUP(gpio3,	GPIO3),
+	AS3722_PINGROUP(gpio4,	GPIO4),
+	AS3722_PINGROUP(gpio5,	GPIO5),
+	AS3722_PINGROUP(gpio6,	GPIO6),
+	AS3722_PINGROUP(gpio7,	GPIO7),
+};
+
+static int as3722_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+	return as_pci->num_pin_groups;
+}
+
+static const char *as3722_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+		unsigned group)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+	return as_pci->pin_groups[group].name;
+}
+
+static int as3722_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+		unsigned group, const unsigned **pins, unsigned *num_pins)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = as_pci->pin_groups[group].pins;
+	*num_pins = as_pci->pin_groups[group].npins;
+	return 0;
+}
+
+static const struct pinctrl_ops as3722_pinctrl_ops = {
+	.get_groups_count = as3722_pinctrl_get_groups_count,
+	.get_group_name = as3722_pinctrl_get_group_name,
+	.get_group_pins = as3722_pinctrl_get_group_pins,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+static int as3722_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+	return as_pci->num_functions;
+}
+
+static const char *as3722_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+			unsigned function)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+	return as_pci->functions[function].name;
+}
+
+static int as3722_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+		unsigned function, const char * const **groups,
+		unsigned * const num_groups)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = as_pci->functions[function].groups;
+	*num_groups = as_pci->functions[function].ngroups;
+	return 0;
+}
+
+static int as3722_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
+		unsigned group)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+	int gpio_cntr_reg = AS3722_GPIOn_CONTROL_REG(group);
+	u8 val = AS3722_GPIO_IOSF_VAL(as_pci->functions[function].mux_option);
+	int ret;
+
+	dev_dbg(as_pci->dev, "%s(): GPIO %u pin to function %u and val %u\n",
+		__func__, group, function, val);
+
+	ret = as3722_update_bits(as_pci->as3722, gpio_cntr_reg,
+			AS3722_GPIO_IOSF_MASK, val);
+	if (ret < 0) {
+		dev_err(as_pci->dev, "GPIO%d_CTRL_REG update failed %d\n",
+			group, ret);
+		return ret;
+	}
+	as_pci->gpio_control[group].io_function = function;
+	return ret;
+}
+
+static int as3722_pinctrl_gpio_get_mode(unsigned gpio_mode_prop, bool input)
+{
+	if (gpio_mode_prop & AS3722_GPIO_MODE_HIGH_IMPED)
+		return -EINVAL;
+
+	if (gpio_mode_prop & AS3722_GPIO_MODE_OPEN_DRAIN) {
+		if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_UP)
+			return AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP;
+		return AS3722_GPIO_MODE_IO_OPEN_DRAIN;
+	}
+	if (input) {
+		if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_UP)
+			return AS3722_GPIO_MODE_INPUT_PULL_UP;
+		else if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_DOWN)
+			return AS3722_GPIO_MODE_INPUT_PULL_DOWN;
+		return AS3722_GPIO_MODE_INPUT;
+	}
+	if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_DOWN)
+		return AS3722_GPIO_MODE_OUTPUT_VDDL;
+	return AS3722_GPIO_MODE_OUTPUT_VDDH;
+}
+
+static int as3722_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range, unsigned offset)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+	if (as_pci->gpio_control[offset].io_function)
+		return -EBUSY;
+	return 0;
+}
+
+static int as3722_pinctrl_gpio_set_direction(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range, unsigned offset, bool input)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+	struct as3722 *as3722 = as_pci->as3722;
+	int mode;
+
+	mode = as3722_pinctrl_gpio_get_mode(
+			as_pci->gpio_control[offset].mode_prop, input);
+	if (mode < 0) {
+		dev_err(as_pci->dev, "%s direction for GPIO %d not supported\n",
+			(input) ? "Input" : "Output", offset);
+		return mode;
+	}
+
+	if (as_pci->gpio_control[offset].enable_gpio_invert)
+		mode |= AS3722_GPIO_INV;
+
+	return as3722_write(as3722, AS3722_GPIOn_CONTROL_REG(offset), mode);
+}
+
+static const struct pinmux_ops as3722_pinmux_ops = {
+	.get_functions_count	= as3722_pinctrl_get_funcs_count,
+	.get_function_name	= as3722_pinctrl_get_func_name,
+	.get_function_groups	= as3722_pinctrl_get_func_groups,
+	.enable			= as3722_pinctrl_enable,
+	.gpio_request_enable	= as3722_pinctrl_gpio_request_enable,
+	.gpio_set_direction	= as3722_pinctrl_gpio_set_direction,
+};
+
+static int as3722_pinconf_get(struct pinctrl_dev *pctldev,
+			unsigned pin, unsigned long *config)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	int arg = 0;
+	u16 prop;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		prop = AS3722_GPIO_MODE_PULL_UP |
+				AS3722_GPIO_MODE_PULL_DOWN;
+		if (!(as_pci->gpio_control[pin].mode_prop & prop))
+			arg = 1;
+		prop = 0;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		prop = AS3722_GPIO_MODE_PULL_UP;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		prop = AS3722_GPIO_MODE_PULL_DOWN;
+		break;
+
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		prop = AS3722_GPIO_MODE_OPEN_DRAIN;
+		break;
+
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		prop = AS3722_GPIO_MODE_HIGH_IMPED;
+		break;
+
+	default:
+		dev_err(as_pci->dev, "Properties not supported\n");
+		return -ENOTSUPP;
+	}
+
+	if (as_pci->gpio_control[pin].mode_prop & prop)
+		arg = 1;
+
+	*config = pinconf_to_config_packed(param, (u16)arg);
+	return 0;
+}
+
+static int as3722_pinconf_set(struct pinctrl_dev *pctldev,
+			unsigned pin, unsigned long *configs,
+			unsigned num_configs)
+{
+	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param;
+	int mode_prop;
+	int i;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		mode_prop = as_pci->gpio_control[pin].mode_prop;
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+			break;
+
+		case PIN_CONFIG_BIAS_DISABLE:
+			mode_prop &= ~(AS3722_GPIO_MODE_PULL_UP |
+					AS3722_GPIO_MODE_PULL_DOWN);
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			mode_prop |= AS3722_GPIO_MODE_PULL_UP;
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			mode_prop |= AS3722_GPIO_MODE_PULL_DOWN;
+			break;
+
+		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+			mode_prop |= AS3722_GPIO_MODE_HIGH_IMPED;
+			break;
+
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+			mode_prop |= AS3722_GPIO_MODE_OPEN_DRAIN;
+			break;
+
+		default:
+			dev_err(as_pci->dev, "Properties not supported\n");
+			return -ENOTSUPP;
+		}
+
+		as_pci->gpio_control[pin].mode_prop = mode_prop;
+	}
+	return 0;
+}
+
+static const struct pinconf_ops as3722_pinconf_ops = {
+	.pin_config_get = as3722_pinconf_get,
+	.pin_config_set = as3722_pinconf_set,
+};
+
+static struct pinctrl_desc as3722_pinctrl_desc = {
+	.pctlops = &as3722_pinctrl_ops,
+	.pmxops = &as3722_pinmux_ops,
+	.confops = &as3722_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+static inline struct as3722_pctrl_info *to_as_pci(struct gpio_chip *chip)
+{
+	return container_of(chip, struct as3722_pctrl_info, gpio_chip);
+}
+
+static int as3722_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct as3722_pctrl_info *as_pci = to_as_pci(chip);
+	struct as3722 *as3722 = as_pci->as3722;
+	int ret;
+	u32 reg;
+	u32 control;
+	u32 val;
+	int mode;
+	int invert_enable;
+
+	ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &control);
+	if (ret < 0) {
+		dev_err(as_pci->dev,
+			"GPIO_CONTROL%d_REG read failed: %d\n", offset, ret);
+		return ret;
+	}
+
+	invert_enable = !!(control & AS3722_GPIO_INV);
+	mode = control & AS3722_GPIO_MODE_MASK;
+	switch (mode) {
+	case AS3722_GPIO_MODE_INPUT:
+	case AS3722_GPIO_MODE_INPUT_PULL_UP:
+	case AS3722_GPIO_MODE_INPUT_PULL_DOWN:
+	case AS3722_GPIO_MODE_IO_OPEN_DRAIN:
+	case AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP:
+		reg = AS3722_GPIO_SIGNAL_IN_REG;
+		break;
+	case AS3722_GPIO_MODE_OUTPUT_VDDH:
+	case AS3722_GPIO_MODE_OUTPUT_VDDL:
+		reg = AS3722_GPIO_SIGNAL_OUT_REG;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = as3722_read(as3722, reg, &val);
+	if (ret < 0) {
+		dev_err(as_pci->dev,
+			"GPIO_SIGNAL_IN_REG read failed: %d\n", ret);
+		return ret;
+	}
+
+	val = !!(val & AS3722_GPIOn_SIGNAL(offset));
+	return (invert_enable) ? !val : val;
+}
+
+static void as3722_gpio_set(struct gpio_chip *chip, unsigned offset,
+		int value)
+{
+	struct as3722_pctrl_info *as_pci = to_as_pci(chip);
+	struct as3722 *as3722 = as_pci->as3722;
+	int en_invert = as_pci->gpio_control[offset].enable_gpio_invert;
+	u32 val;
+	int ret;
+
+	if (value)
+		val = (en_invert) ? 0 : AS3722_GPIOn_SIGNAL(offset);
+	else
+		val = (en_invert) ? AS3722_GPIOn_SIGNAL(offset) : 0;
+
+	ret = as3722_update_bits(as3722, AS3722_GPIO_SIGNAL_OUT_REG,
+			AS3722_GPIOn_SIGNAL(offset), val);
+	if (ret < 0)
+		dev_err(as_pci->dev,
+			"GPIO_SIGNAL_OUT_REG update failed: %d\n", ret);
+}
+
+static int as3722_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int as3722_gpio_direction_output(struct gpio_chip *chip,
+		unsigned offset, int value)
+{
+	as3722_gpio_set(chip, offset, value);
+	return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static int as3722_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct as3722_pctrl_info *as_pci = to_as_pci(chip);
+
+	return as3722_irq_get_virq(as_pci->as3722, offset);
+}
+
+static int as3722_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void as3722_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static const struct gpio_chip as3722_gpio_chip = {
+	.label			= "as3722-gpio",
+	.owner			= THIS_MODULE,
+	.request		= as3722_gpio_request,
+	.free			= as3722_gpio_free,
+	.get			= as3722_gpio_get,
+	.set			= as3722_gpio_set,
+	.direction_input	= as3722_gpio_direction_input,
+	.direction_output	= as3722_gpio_direction_output,
+	.to_irq			= as3722_gpio_to_irq,
+	.can_sleep		= 1,
+	.ngpio			= AS3722_PIN_NUM,
+	.base			= -1,
+};
+
+static int as3722_pinctrl_probe(struct platform_device *pdev)
+{
+	struct as3722_pctrl_info *as_pci;
+	int ret;
+	int tret;
+
+	as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
+	if (!as_pci)
+		return -ENOMEM;
+
+	as_pci->dev = &pdev->dev;
+	as_pci->dev->of_node = pdev->dev.parent->of_node;
+	as_pci->as3722 = dev_get_drvdata(pdev->dev.parent);
+	platform_set_drvdata(pdev, as_pci);
+
+	as_pci->pins = as3722_pins_desc;
+	as_pci->num_pins = ARRAY_SIZE(as3722_pins_desc);
+	as_pci->functions = as3722_pin_function;
+	as_pci->num_functions = ARRAY_SIZE(as3722_pin_function);
+	as_pci->pin_groups = as3722_pingroups;
+	as_pci->num_pin_groups = ARRAY_SIZE(as3722_pingroups);
+	as3722_pinctrl_desc.name = dev_name(&pdev->dev);
+	as3722_pinctrl_desc.pins = as3722_pins_desc;
+	as3722_pinctrl_desc.npins = ARRAY_SIZE(as3722_pins_desc);
+	as_pci->pctl = pinctrl_register(&as3722_pinctrl_desc,
+					&pdev->dev, as_pci);
+	if (!as_pci->pctl) {
+		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+		return -EINVAL;
+	}
+
+	as_pci->gpio_chip = as3722_gpio_chip;
+	as_pci->gpio_chip.dev = &pdev->dev;
+	as_pci->gpio_chip.of_node = pdev->dev.parent->of_node;
+	ret = gpiochip_add(&as_pci->gpio_chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Couldn't register gpiochip, %d\n", ret);
+		goto fail_chip_add;
+	}
+
+	ret = gpiochip_add_pin_range(&as_pci->gpio_chip, dev_name(&pdev->dev),
+				0, 0, AS3722_PIN_NUM);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Couldn't add pin range, %d\n", ret);
+		goto fail_range_add;
+	}
+
+	return 0;
+
+fail_range_add:
+	tret = gpiochip_remove(&as_pci->gpio_chip);
+	if (tret < 0)
+		dev_warn(&pdev->dev, "Couldn't remove gpio chip, %d\n", tret);
+
+fail_chip_add:
+	pinctrl_unregister(as_pci->pctl);
+	return ret;
+}
+
+static int as3722_pinctrl_remove(struct platform_device *pdev)
+{
+	struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = gpiochip_remove(&as_pci->gpio_chip);
+	if (ret < 0)
+		return ret;
+	pinctrl_unregister(as_pci->pctl);
+	return 0;
+}
+
+static struct of_device_id as3722_pinctrl_of_match[] = {
+	{ .compatible = "ams,as3722-pinctrl", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, as3722_pinctrl_of_match);
+
+static struct platform_driver as3722_pinctrl_driver = {
+	.driver = {
+		.name = "as3722-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = as3722_pinctrl_of_match,
+	},
+	.probe = as3722_pinctrl_probe,
+	.remove = as3722_pinctrl_remove,
+};
+module_platform_driver(as3722_pinctrl_driver);
+
+MODULE_ALIAS("platform:as3722-pinctrl");
+MODULE_DESCRIPTION("AS3722 pin control and GPIO driver");
+MODULE_AUTHOR("Laxman Dewangan<ldewangan@nvidia.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.1.1


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

* [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver
  2013-10-09 12:29 [PATCH V5 0/3] Add AMS AS3722 mfd, pincontrol and RTC driver Laxman Dewangan
  2013-10-09 12:29 ` [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC Laxman Dewangan
  2013-10-09 12:29 ` [PATCH V5 2/3] pincntrl: add support for ams AS3722 pin control driver Laxman Dewangan
@ 2013-10-09 12:29 ` Laxman Dewangan
  2013-10-10 22:24   ` Andrew Morton
  2 siblings, 1 reply; 11+ messages in thread
From: Laxman Dewangan @ 2013-10-09 12:29 UTC (permalink / raw)
  To: lee.jones, sameo, broonie, linus.walleij, akpm
  Cc: devicetree, linux-doc, linux-kernel, linux-gpio, rtc-linux,
	rob.herring, mark.rutland, pawel.moll, swarren, rob,
	ijc+devicetree, grant.likely, Laxman Dewangan, Florian Lobmaier

The ams AS3722 is a compact system PMU suitable for mobile phones,
tablets etc.

Add a driver to support accessing the RTC found on the ams AS3722
PMIC using RTC framework.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Florian Lobmaier <florian.lobmaier@ams.com>
---
Changes from V1:
- Get rid of clk32k out configuration from RTC. Will add clock driver.

Changes from V2:
- None. 

Changes form V3:
- Change AMS to ams.

Changes form V4:
- None

 drivers/rtc/Kconfig      |   10 ++
 drivers/rtc/Makefile     |    1 +
 drivers/rtc/rtc-as3722.c |  296 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 307 insertions(+), 0 deletions(-)
 create mode 100644 drivers/rtc/rtc-as3722.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 9654aa3..d8785d7 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -153,6 +153,16 @@ config RTC_DRV_88PM80X
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-88pm80x.
 
+config RTC_DRV_AS3722
+	tristate "ams AS3722 RTC driver"
+	depends on MFD_AS3722
+	help
+	  If you say yes here you get support for the RTC of ams AS3722 PMIC
+	  chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-as3722.
+
 config RTC_DRV_DS1307
 	tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
 	help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2dff3d2..fdb5764 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_RTC_DRV_88PM860X)  += rtc-88pm860x.o
 obj-$(CONFIG_RTC_DRV_88PM80X)	+= rtc-88pm80x.o
 obj-$(CONFIG_RTC_DRV_AB3100)	+= rtc-ab3100.o
 obj-$(CONFIG_RTC_DRV_AB8500)	+= rtc-ab8500.o
+obj-$(CONFIG_RTC_DRV_AS3722)	+= rtc-as3722.o
 obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
 obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
 obj-$(CONFIG_RTC_DRV_AT91SAM9)	+= rtc-at91sam9.o
diff --git a/drivers/rtc/rtc-as3722.c b/drivers/rtc/rtc-as3722.c
new file mode 100644
index 0000000..430a927
--- /dev/null
+++ b/drivers/rtc/rtc-as3722.c
@@ -0,0 +1,296 @@
+/*
+ * rtc-as3722.c - Real Time Clock driver for ams AS3722 PMICs
+ *
+ * Copyright (C) 2013 ams AG
+ * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
+ *
+ * Author: Florian Lobmaier <florian.lobmaier@ams.com>
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/bcd.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/as3722.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/time.h>
+
+#define AS3722_RTC_START_YEAR	  2000
+struct as3722_rtc {
+	struct rtc_device	*rtc;
+	struct device		*dev;
+	struct as3722		*as3722;
+	int			alarm_irq;
+	bool			irq_enable;
+};
+
+static void as3722_time_to_reg(u8 *rbuff, struct rtc_time *tm)
+{
+	rbuff[0] = bin2bcd(tm->tm_sec);
+	rbuff[1] = bin2bcd(tm->tm_min);
+	rbuff[2] = bin2bcd(tm->tm_hour);
+	rbuff[3] = bin2bcd(tm->tm_mday);
+	rbuff[4] = bin2bcd(tm->tm_mon);
+	rbuff[5] = bin2bcd(tm->tm_year - (AS3722_RTC_START_YEAR - 1900));
+}
+
+static void as3722_reg_to_time(u8 *rbuff, struct rtc_time *tm)
+{
+	tm->tm_sec = bcd2bin(rbuff[0] & 0x7F);
+	tm->tm_min = bcd2bin(rbuff[1] & 0x7F);
+	tm->tm_hour = bcd2bin(rbuff[2] & 0x3F);
+	tm->tm_mday = bcd2bin(rbuff[3] & 0x3F);
+	tm->tm_mon = bcd2bin(rbuff[4] & 0x1F);
+	tm->tm_year = (AS3722_RTC_START_YEAR - 1900) + bcd2bin(rbuff[5] & 0x7F);
+	return;
+}
+
+static int as3722_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
+	struct as3722 *as3722 = as3722_rtc->as3722;
+	u8 as_time_array[6];
+	int ret;
+
+	ret = as3722_block_read(as3722, AS3722_RTC_SECOND_REG,
+			6, as_time_array);
+	if (ret < 0) {
+		dev_err(dev, "RTC_SECOND reg block read failed %d\n", ret);
+		return ret;
+	}
+	as3722_reg_to_time(as_time_array, tm);
+	return 0;
+}
+
+static int as3722_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
+	struct as3722 *as3722 = as3722_rtc->as3722;
+	u8 as_time_array[6];
+	int ret;
+
+	if (tm->tm_year < (AS3722_RTC_START_YEAR - 1900))
+		return -EINVAL;
+
+	as3722_time_to_reg(as_time_array, tm);
+	ret = as3722_block_write(as3722, AS3722_RTC_SECOND_REG, 6,
+			as_time_array);
+	if (ret < 0)
+		dev_err(dev, "RTC_SECOND reg block write failed %d\n", ret);
+	return ret;
+}
+
+static int as3722_rtc_alarm_irq_enable(struct device *dev,
+		unsigned int enabled)
+{
+	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
+
+	if (enabled && !as3722_rtc->irq_enable) {
+		enable_irq(as3722_rtc->alarm_irq);
+		as3722_rtc->irq_enable = true;
+	} else if (!enabled && as3722_rtc->irq_enable)  {
+		disable_irq(as3722_rtc->alarm_irq);
+		as3722_rtc->irq_enable = false;
+	}
+	return 0;
+}
+
+static int as3722_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
+	struct as3722 *as3722 = as3722_rtc->as3722;
+	u8 as_time_array[6];
+	int ret;
+
+	ret = as3722_block_read(as3722, AS3722_RTC_ALARM_SECOND_REG, 6,
+			as_time_array);
+	if (ret < 0) {
+		dev_err(dev, "RTC_ALARM_SECOND block read failed %d\n", ret);
+		return ret;
+	}
+
+	as3722_reg_to_time(as_time_array, &alrm->time);
+	return 0;
+}
+
+static int as3722_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
+	struct as3722 *as3722 = as3722_rtc->as3722;
+	u8 as_time_array[6];
+	int ret;
+
+	if (alrm->time.tm_year < (AS3722_RTC_START_YEAR - 1900))
+		return -EINVAL;
+
+	ret = as3722_rtc_alarm_irq_enable(dev, 0);
+	if (ret < 0) {
+		dev_err(dev, "Disable RTC alarm failed\n");
+		return ret;
+	}
+
+	as3722_time_to_reg(as_time_array, &alrm->time);
+	ret = as3722_block_write(as3722, AS3722_RTC_ALARM_SECOND_REG, 6,
+			as_time_array);
+	if (ret < 0) {
+		dev_err(dev, "RTC_ALARM_SECOND block write failed %d\n", ret);
+		return ret;
+	}
+
+	if (alrm->enabled)
+		ret = as3722_rtc_alarm_irq_enable(dev, alrm->enabled);
+	return ret;
+}
+
+static irqreturn_t as3722_alarm_irq(int irq, void *data)
+{
+	struct as3722_rtc *as3722_rtc = data;
+
+	rtc_update_irq(as3722_rtc->rtc, 1, RTC_IRQF | RTC_AF);
+	return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops as3722_rtc_ops = {
+	.read_time = as3722_rtc_read_time,
+	.set_time = as3722_rtc_set_time,
+	.read_alarm = as3722_rtc_read_alarm,
+	.set_alarm = as3722_rtc_set_alarm,
+	.alarm_irq_enable = as3722_rtc_alarm_irq_enable,
+};
+
+static int as3722_rtc_probe(struct platform_device *pdev)
+{
+	struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent);
+	struct as3722_rtc *as3722_rtc;
+	int val;
+	int ret;
+
+	as3722_rtc = devm_kzalloc(&pdev->dev, sizeof(*as3722_rtc), GFP_KERNEL);
+	if (!as3722_rtc)
+		return -ENOMEM;
+
+	as3722_rtc->as3722 = as3722;
+	as3722_rtc->dev = &pdev->dev;
+	platform_set_drvdata(pdev, as3722_rtc);
+
+	/* Enable the RTC to make sure it is running. */
+	ret = as3722_update_bits(as3722, AS3722_RTC_CONTROL_REG,
+				AS3722_RTC_ON, AS3722_RTC_ON);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "RTC_CONTROL reg update failed: %d\n", ret);
+		return ret;
+	}
+
+	val = AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN;
+	ret = as3722_write(as3722, AS3722_RTC_CONTROL_REG, val);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "RTC_CONTROL reg write failed: %d\n", ret);
+		return ret;
+	}
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	as3722_rtc->rtc = rtc_device_register("as3722", &pdev->dev,
+				&as3722_rtc_ops, THIS_MODULE);
+	if (IS_ERR(as3722_rtc->rtc)) {
+		ret = PTR_ERR(as3722_rtc->rtc);
+		dev_err(&pdev->dev, "RTC register failed: %d\n", ret);
+		return ret;
+	}
+
+	as3722_rtc->alarm_irq = platform_get_irq(pdev, 0);
+	dev_info(&pdev->dev, "RTC interrupt %d\n", as3722_rtc->alarm_irq);
+
+	ret = request_threaded_irq(as3722_rtc->alarm_irq, NULL,
+			as3722_alarm_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME,
+			"rtc-alarm", as3722_rtc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
+				as3722_rtc->alarm_irq, ret);
+		goto scrub;
+	}
+	disable_irq(as3722_rtc->alarm_irq);
+	return 0;
+scrub:
+	rtc_device_unregister(as3722_rtc->rtc);
+	return ret;
+}
+
+static int as3722_rtc_remove(struct platform_device *pdev)
+{
+	struct as3722_rtc *as3722_rtc = platform_get_drvdata(pdev);
+
+	free_irq(as3722_rtc->alarm_irq, as3722_rtc);
+	rtc_device_unregister(as3722_rtc->rtc);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int as3722_rtc_suspend(struct device *dev)
+{
+	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(as3722_rtc->alarm_irq);
+
+	return 0;
+}
+
+static int as3722_rtc_resume(struct device *dev)
+{
+	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(as3722_rtc->alarm_irq);
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops as3722_rtc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(as3722_rtc_suspend, as3722_rtc_resume)
+};
+
+static const struct of_device_id of_as3722_rtc_match[] = {
+	{ .compatible = "ams,as3722-rtc"},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, of_as3722_rtc_match);
+
+static struct platform_driver as3722_rtc_driver = {
+	.probe = as3722_rtc_probe,
+	.remove = as3722_rtc_remove,
+	.driver = {
+		.name = "as3722-rtc",
+		.pm = &as3722_rtc_pm_ops,
+		.of_match_table = of_as3722_rtc_match,
+	},
+};
+module_platform_driver(as3722_rtc_driver);
+
+MODULE_DESCRIPTION("RTC driver for AS3722 PMICs");
+MODULE_ALIAS("platform:as3722-rtc");
+MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>");
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.1.1


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

* Re: [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC
  2013-10-09 12:29 ` [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC Laxman Dewangan
@ 2013-10-09 16:13   ` Stephen Warren
  2013-10-21 11:18     ` Laxman Dewangan
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Warren @ 2013-10-09 16:13 UTC (permalink / raw)
  To: Laxman Dewangan, lee.jones, sameo, broonie, linus.walleij, akpm
  Cc: devicetree, linux-doc, linux-kernel, linux-gpio, rtc-linux,
	rob.herring, mark.rutland, pawel.moll, rob, ijc+devicetree,
	grant.likely, Florian Lobmaier

On 10/09/2013 06:29 AM, Laxman Dewangan wrote:
> The ams AS3722 is a compact system PMU suitable for mobile phones,
> tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down
> controller, 11 LDOs, RTC, automatic battery, temperature and
> over-current monitoring, 8 GPIOs, ADC and a watchdog.
> 
> Add MFD core driver for the AS3722 to support core functionality.

OK, I think the binding here is about clear enough, so the binding,
Acked-by: Stephen Warren <swarren@nvidia.com>

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

* Re: [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver
  2013-10-09 12:29 ` [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver Laxman Dewangan
@ 2013-10-10 22:24   ` Andrew Morton
  2013-10-10 22:47     ` Mark Brown
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Morton @ 2013-10-10 22:24 UTC (permalink / raw)
  To: Laxman Dewangan
  Cc: lee.jones, sameo, broonie, linus.walleij, devicetree, linux-doc,
	linux-kernel, linux-gpio, rtc-linux, rob.herring, mark.rutland,
	pawel.moll, swarren, rob, ijc+devicetree, grant.likely,
	Florian Lobmaier

On Wed, 9 Oct 2013 17:59:21 +0530 Laxman Dewangan <ldewangan@nvidia.com> wrote:

> The ams AS3722 is a compact system PMU suitable for mobile phones,
> tablets etc.
> 
> Add a driver to support accessing the RTC found on the ams AS3722
> PMIC using RTC framework.

I hate these patchsets, because ...

> index 9654aa3..d8785d7 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -153,6 +153,16 @@ config RTC_DRV_88PM80X
>  	  This driver can also be built as a module. If so, the module
>  	  will be called rtc-88pm80x.
>  
> +config RTC_DRV_AS3722
> +	tristate "ams AS3722 RTC driver"
> +	depends on MFD_AS3722

... the rtc patch depends on an mfd patch, so everyone ends up sitting
around looking at everyone else, wondering who will merge it all.

> +	help
> +	  If you say yes here you get support for the RTC of ams AS3722 PMIC
> +	  chips.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called rtc-as3722.
> +
>
> ...
>
> +static int as3722_rtc_probe(struct platform_device *pdev)
> +{
> +	struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent);
> +	struct as3722_rtc *as3722_rtc;
> +	int val;
> +	int ret;
> +
> +	as3722_rtc = devm_kzalloc(&pdev->dev, sizeof(*as3722_rtc), GFP_KERNEL);
> +	if (!as3722_rtc)
> +		return -ENOMEM;
> +
> +	as3722_rtc->as3722 = as3722;
> +	as3722_rtc->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, as3722_rtc);
> +
> +	/* Enable the RTC to make sure it is running. */
> +	ret = as3722_update_bits(as3722, AS3722_RTC_CONTROL_REG,
> +				AS3722_RTC_ON, AS3722_RTC_ON);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "RTC_CONTROL reg update failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	val = AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN;
> +	ret = as3722_write(as3722, AS3722_RTC_CONTROL_REG, val);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "RTC_CONTROL reg write failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	device_init_wakeup(&pdev->dev, 1);
> +
> +	as3722_rtc->rtc = rtc_device_register("as3722", &pdev->dev,
> +				&as3722_rtc_ops, THIS_MODULE);

devm_rtc_device_register()?

> +	if (IS_ERR(as3722_rtc->rtc)) {
> +		ret = PTR_ERR(as3722_rtc->rtc);
> +		dev_err(&pdev->dev, "RTC register failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	as3722_rtc->alarm_irq = platform_get_irq(pdev, 0);
> +	dev_info(&pdev->dev, "RTC interrupt %d\n", as3722_rtc->alarm_irq);
> +
> +	ret = request_threaded_irq(as3722_rtc->alarm_irq, NULL,
> +			as3722_alarm_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME,
> +			"rtc-alarm", as3722_rtc);

devm_request_threaded_irq()?

> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
> +				as3722_rtc->alarm_irq, ret);
> +		goto scrub;
> +	}
> +	disable_irq(as3722_rtc->alarm_irq);

It seems strange to disable your IRQ here.

> +	return 0;
> +scrub:
> +	rtc_device_unregister(as3722_rtc->rtc);
> +	return ret;
> +}

The function is a bit confused.  It uses a mix of the "returns
sprinkled all over the place" approach and the "goto out" approach. 
The latter is preferred.

> +static int as3722_rtc_remove(struct platform_device *pdev)
> +{
> +	struct as3722_rtc *as3722_rtc = platform_get_drvdata(pdev);
> +
> +	free_irq(as3722_rtc->alarm_irq, as3722_rtc);
> +	rtc_device_unregister(as3722_rtc->rtc);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM

Most (but not all!) rtc drivers use CONFIG_PM_SLEEP.  People have madly
mucked with CONFIG_PM* and I don't know the difference and I don't know
what's going on and I don't know of a convenient place to go to find
out.  If you work it out, please be sure to tell me!  But as soon as I
figure it out I'm sure they'll go and madly muck with it again.



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

* Re: [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver
  2013-10-10 22:24   ` Andrew Morton
@ 2013-10-10 22:47     ` Mark Brown
  2013-10-11  8:08       ` [rtc-linux] " Linus Walleij
  2013-10-21 11:14       ` Laxman Dewangan
  0 siblings, 2 replies; 11+ messages in thread
From: Mark Brown @ 2013-10-10 22:47 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Laxman Dewangan, lee.jones, sameo, linus.walleij, devicetree,
	linux-doc, linux-kernel, linux-gpio, rtc-linux, rob.herring,
	mark.rutland, pawel.moll, swarren, rob, ijc+devicetree,
	grant.likely, Florian Lobmaier

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

On Thu, Oct 10, 2013 at 03:24:46PM -0700, Andrew Morton wrote:
> On Wed, 9 Oct 2013 17:59:21 +0530 Laxman Dewangan <ldewangan@nvidia.com> wrote:

> > +config RTC_DRV_AS3722
> > +	tristate "ams AS3722 RTC driver"
> > +	depends on MFD_AS3722

> ... the rtc patch depends on an mfd patch, so everyone ends up sitting
> around looking at everyone else, wondering who will merge it all.

With the MFD ones providing you trust the interfaces with the core
are going to be OK there's no problem to just merge them via individual
trees - the dependency on the MFD will prevent bisection problems.

> > +#ifdef CONFIG_PM
> 
> Most (but not all!) rtc drivers use CONFIG_PM_SLEEP.  People have madly
> mucked with CONFIG_PM* and I don't know the difference and I don't know
> what's going on and I don't know of a convenient place to go to find
> out.  If you work it out, please be sure to tell me!  But as soon as I
> figure it out I'm sure they'll go and madly muck with it again.

The two effective options for this stuff are PM_SLEEP (for system
suspend) and PM_RUNTIME (for runtime suspend which RTCs are unlikely to
use I guess).  PM mostly just enables selection of the other two.

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

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

* Re: [rtc-linux] Re: [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver
  2013-10-10 22:47     ` Mark Brown
@ 2013-10-11  8:08       ` Linus Walleij
  2013-10-21 11:14       ` Laxman Dewangan
  1 sibling, 0 replies; 11+ messages in thread
From: Linus Walleij @ 2013-10-11  8:08 UTC (permalink / raw)
  To: rtc-linux
  Cc: Andrew Morton, Laxman Dewangan, Lee Jones, Samuel Ortiz,
	devicetree, linux-doc, linux-kernel, linux-gpio, Rob Herring,
	Mark Rutland, Pawel Moll, Stephen Warren, Rob Landley,
	ijc+devicetree, Grant Likely, Florian Lobmaier

On Fri, Oct 11, 2013 at 12:47 AM, Mark Brown <broonie@kernel.org> wrote:
> On Thu, Oct 10, 2013 at 03:24:46PM -0700, Andrew Morton wrote:
>> On Wed, 9 Oct 2013 17:59:21 +0530 Laxman Dewangan <ldewangan@nvidia.com> wrote:
>
>> > +config RTC_DRV_AS3722
>> > +   tristate "ams AS3722 RTC driver"
>> > +   depends on MFD_AS3722
>
>> ... the rtc patch depends on an mfd patch, so everyone ends up sitting
>> around looking at everyone else, wondering who will merge it all.
>
> With the MFD ones providing you trust the interfaces with the core
> are going to be OK there's no problem to just merge them via individual
> trees - the dependency on the MFD will prevent bisection problems.

Yes this is why I merged the pinctrl portions into the pinctrl tree.
We do have some indication that the MFD driver is in good shape
and will be accepted. In the worst case (if it's not getting in through
the same merge window or the next) we can just revert it.

Yours,
Linus Walleij

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

* Re: [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver
  2013-10-10 22:47     ` Mark Brown
  2013-10-11  8:08       ` [rtc-linux] " Linus Walleij
@ 2013-10-21 11:14       ` Laxman Dewangan
  1 sibling, 0 replies; 11+ messages in thread
From: Laxman Dewangan @ 2013-10-21 11:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: Andrew Morton, lee.jones, sameo, linus.walleij, devicetree,
	linux-doc, linux-kernel, linux-gpio, rtc-linux, rob.herring,
	mark.rutland, pawel.moll, swarren, rob, ijc+devicetree,
	grant.likely, Florian Lobmaier

On Friday 11 October 2013 04:17 AM, Mark Brown wrote:
> * PGP Signed by an unknown key
>
> On Thu, Oct 10, 2013 at 03:24:46PM -0700, Andrew Morton wrote:
>
>>> +#ifdef CONFIG_PM
>> Most (but not all!) rtc drivers use CONFIG_PM_SLEEP.  People have madly
>> mucked with CONFIG_PM* and I don't know the difference and I don't know
>> what's going on and I don't know of a convenient place to go to find
>> out.  If you work it out, please be sure to tell me!  But as soon as I
>> figure it out I'm sure they'll go and madly muck with it again.
> The two effective options for this stuff are PM_SLEEP (for system
> suspend) and PM_RUNTIME (for runtime suspend which RTCs are unlikely to
> use I guess).  PM mostly just enables selection of the other two.

I think, correct defs is  CONFIG_PM_SLEEP here. I will re-spin this patch.

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

* Re: [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC
  2013-10-09 16:13   ` Stephen Warren
@ 2013-10-21 11:18     ` Laxman Dewangan
  2013-10-22  6:58       ` Lee Jones
  0 siblings, 1 reply; 11+ messages in thread
From: Laxman Dewangan @ 2013-10-21 11:18 UTC (permalink / raw)
  To: Stephen Warren
  Cc: lee.jones, sameo, broonie, linus.walleij, akpm, devicetree,
	linux-doc, linux-kernel, linux-gpio, rtc-linux, rob.herring,
	mark.rutland, pawel.moll, rob, ijc+devicetree, grant.likely,
	Florian Lobmaier

Hi Lee/Samuel,

On Wednesday 09 October 2013 09:43 PM, Stephen Warren wrote:
> On 10/09/2013 06:29 AM, Laxman Dewangan wrote:
>> The ams AS3722 is a compact system PMU suitable for mobile phones,
>> tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down
>> controller, 11 LDOs, RTC, automatic battery, temperature and
>> over-current monitoring, 8 GPIOs, ADC and a watchdog.
>>
>> Add MFD core driver for the AS3722 to support core functionality.
> OK, I think the binding here is about clear enough, so the binding,
> Acked-by: Stephen Warren <swarren@nvidia.com>


I saw that Lee has already acked this (V4) for the nondt side.

As there is no issue on dt side also, can it be apply please?



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

* Re: [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC
  2013-10-21 11:18     ` Laxman Dewangan
@ 2013-10-22  6:58       ` Lee Jones
  0 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2013-10-22  6:58 UTC (permalink / raw)
  To: Laxman Dewangan
  Cc: Stephen Warren, sameo, broonie, linus.walleij, akpm, devicetree,
	linux-doc, linux-kernel, linux-gpio, rtc-linux, rob.herring,
	mark.rutland, pawel.moll, rob, ijc+devicetree, grant.likely,
	Florian Lobmaier

>>> The ams AS3722 is a compact system PMU suitable for mobile phones,
>>> tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down
>>> controller, 11 LDOs, RTC, automatic battery, temperature and
>>> over-current monitoring, 8 GPIOs, ADC and a watchdog.
>>>
>>> Add MFD core driver for the AS3722 to support core functionality.
>>
>> OK, I think the binding here is about clear enough, so the binding,
>> Acked-by: Stephen Warren <swarren@nvidia.com>
>
> I saw that Lee has already acked this (V4) for the nondt side.
>
> As there is no issue on dt side also, can it be apply please?

There is no IMAP access here at the Summit.

Would you be able to do me a favour and resend this patch with
Stephen's and my Acks and I will apply?

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

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

end of thread, other threads:[~2013-10-22  6:58 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-09 12:29 [PATCH V5 0/3] Add AMS AS3722 mfd, pincontrol and RTC driver Laxman Dewangan
2013-10-09 12:29 ` [PATCH V5 1/3] mfd: add support for ams AS3722 PMIC Laxman Dewangan
2013-10-09 16:13   ` Stephen Warren
2013-10-21 11:18     ` Laxman Dewangan
2013-10-22  6:58       ` Lee Jones
2013-10-09 12:29 ` [PATCH V5 2/3] pincntrl: add support for ams AS3722 pin control driver Laxman Dewangan
2013-10-09 12:29 ` [PATCH V5 3/3] drivers/rtc/rtc-as3722: add RTC driver Laxman Dewangan
2013-10-10 22:24   ` Andrew Morton
2013-10-10 22:47     ` Mark Brown
2013-10-11  8:08       ` [rtc-linux] " Linus Walleij
2013-10-21 11:14       ` Laxman Dewangan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).