Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH v4 1/8] dt-bindings: mfd: document stpmic1
From: Pascal PAILLET-LME @ 2018-10-18  9:02 UTC (permalink / raw)
  To: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
  Cc: Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-1-git-send-email-p.paillet@st.com>

From: pascal paillet <p.paillet@st.com>

stpmic1 is a pmic from STMicroelectronics. The STPMIC1 integrates 10
regulators , 3 switches, a watchdog and an input for a power on key.

Signed-off-by: pascal paillet <p.paillet@st.com>
---
changes in v4:
* remove interrupt-parent description
* pmic1@33 renamed to pmic@33
* fix indentation

 .../devicetree/bindings/mfd/st,stpmic1.txt         | 131 +++++++++++++++++++++
 include/dt-bindings/mfd/st,stpmic1.h               |  46 ++++++++
 2 files changed, 177 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/st,stpmic1.txt
 create mode 100644 include/dt-bindings/mfd/st,stpmic1.h

diff --git a/Documentation/devicetree/bindings/mfd/st,stpmic1.txt b/Documentation/devicetree/bindings/mfd/st,stpmic1.txt
new file mode 100644
index 0000000..bb19cc8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/st,stpmic1.txt
@@ -0,0 +1,131 @@
+* STMicroelectronics STPMIC1 Power Management IC
+
+Required parent device properties:
+- compatible:			"st,stpmic1"
+- reg:				The I2C slave address for the STPMIC1 chip.
+- interrupts:			The interrupt line the device is connected to.
+- #interrupt-cells:		Should be 1.
+- interrupt-controller: 	Describes the STPMIC1 as an interrupt
+  controller (has its own domain). Interrupt number are the following:
+	/* Interrupt Register 1 (0x50 for latch) */
+	IT_SWOUT_R=0
+	IT_SWOUT_F=1
+	IT_VBUS_OTG_R=2
+	IT_VBUS_OTG_F=3
+	IT_WAKEUP_R=4
+	IT_WAKEUP_F=5
+	IT_PONKEY_R=6
+	IT_PONKEY_F=7
+	/* Interrupt Register 2 (0x51 for latch) */
+	IT_OVP_BOOST=8
+	IT_OCP_BOOST=9
+	IT_OCP_SWOUT=10
+	IT_OCP_OTG=11
+	IT_CURLIM_BUCK4=12
+	IT_CURLIM_BUCK3=13
+	IT_CURLIM_BUCK2=14
+	IT_CURLIM_BUCK1=15
+	/* Interrupt Register 3 (0x52 for latch) */
+	IT_SHORT_SWOUT=16
+	IT_SHORT_SWOTG=17
+	IT_CURLIM_LDO6=18
+	IT_CURLIM_LDO5=19
+	IT_CURLIM_LDO4=20
+	IT_CURLIM_LDO3=21
+	IT_CURLIM_LDO2=22
+	IT_CURLIM_LDO1=23
+	/* Interrupt Register 3 (0x52 for latch) */
+	IT_SWIN_R=24
+	IT_SWIN_F=25
+	IT_RESERVED_1=26
+	IT_RESERVED_2=27
+	IT_VINLOW_R=28
+	IT_VINLOW_F=29
+	IT_TWARN_R=30
+	IT_TWARN_F=31
+
+Optional parent device properties:
+- st,main-control-register:
+	-bit 1: Power cycling will be performed on turn OFF condition
+	-bit 2: PWRCTRL is functional
+	-bit 3: PWRCTRL active high
+- st,pads-pull-register:
+	-bit 1: WAKEUP pull down is not active
+	-bit 2: PWRCTRL pull up is active
+	-bit 3: PWRCTRL pull down is active
+	-bit 4: WAKEUP detector is disabled
+- st,vin-control-register:
+	-bit 0: VINLOW monitoring is enabled
+	-bit [1...3]: VINLOW rising threshold
+		000 VINOK_f + 50mV
+		001 VINOK_f + 100mV
+		010 VINOK_f + 150mV
+		011 VINOK_f + 200mV
+		100 VINOK_f + 250mV
+		101 VINOK_f + 300mV
+		110 VINOK_f + 350mV
+		111 VINOK_f + 400mV
+	-bit [4...5]: VINLOW hyst
+		00 100mV
+		01 200mV
+		10 300mV
+		11 400mV
+	-bit 6: SW_OUT detector is disabled
+	-bit 7: SW_IN detector is enabled.
+- st,usb-control-register:
+	-bit 3: SW_OUT current limit
+		0: 600mA
+		1: 1.1A
+	-bit 4: VBUS_OTG discharge is enabled
+	-bit 5: SW_OUT discharge is enabled
+	-bit 6: VBUS_OTG detection is enabled
+	-bit 7: BOOST_OVP is disabled
+
+STPMIC1 consists in a varied group of sub-devices.
+Each sub-device binding is be described in own documentation file.
+
+Device			 Description
+------			------------
+st,stpmic1-onkey	: Power on key, see ../input/st,stpmic1-onkey.txt
+st,stpmic1-regulators	: Regulators, see ../regulator/st,stpmic1-regulator.txt
+st,stpmic1-wdt		: Watchdog, see ../watchdog/st,stpmic1-wdt.txt
+
+Example:
+
+pmic: pmic@33 {
+	compatible = "st,stpmic1";
+	reg = <0x33>;
+	interrupt-parent = <&gpioa>;
+	interrupts = <0 2>;
+	st,main-control-register=<0x0c>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+
+	onkey {
+		compatible = "st,stpmic1-onkey";
+		interrupts = <IT_PONKEY_F 0>,<IT_PONKEY_R 1>;
+		interrupt-names = "onkey-falling", "onkey-rising";
+		power-off-time-sec = <10>;
+	};
+
+	watchdog {
+		compatible = "st,stpmic1-wdt";
+	};
+
+	regulators {
+		compatible = "st,stpmic1-regulators";
+
+		vdd_core: buck1 {
+			regulator-name = "vdd_core";
+			regulator-boot-on;
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <1200000>;
+		};
+		vdd: buck3 {
+			regulator-name = "vdd";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-boot-on;
+			regulator-pull-down;
+		};
+	};
diff --git a/include/dt-bindings/mfd/st,stpmic1.h b/include/dt-bindings/mfd/st,stpmic1.h
new file mode 100644
index 0000000..b2d6c83
--- /dev/null
+++ b/include/dt-bindings/mfd/st,stpmic1.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Philippe Peurichard <philippe.peurichard@st.com>,
+ * Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
+ */
+
+#ifndef __DT_BINDINGS_STPMIC1_H__
+#define __DT_BINDINGS_STPMIC1_H__
+
+/* IRQ definitions */
+#define IT_PONKEY_F	0
+#define IT_PONKEY_R	1
+#define IT_WAKEUP_F	2
+#define IT_WAKEUP_R	3
+#define IT_VBUS_OTG_F	4
+#define IT_VBUS_OTG_R	5
+#define IT_SWOUT_F	6
+#define IT_SWOUT_R	7
+
+#define IT_CURLIM_BUCK1	8
+#define IT_CURLIM_BUCK2	9
+#define IT_CURLIM_BUCK3	10
+#define IT_CURLIM_BUCK4	11
+#define IT_OCP_OTG	12
+#define IT_OCP_SWOUT	13
+#define IT_OCP_BOOST	14
+#define IT_OVP_BOOST	15
+
+#define IT_CURLIM_LDO1	16
+#define IT_CURLIM_LDO2	17
+#define IT_CURLIM_LDO3	18
+#define IT_CURLIM_LDO4	19
+#define IT_CURLIM_LDO5	20
+#define IT_CURLIM_LDO6	21
+#define IT_SHORT_SWOTG	22
+#define IT_SHORT_SWOUT	23
+
+#define IT_TWARN_F	24
+#define IT_TWARN_R	25
+#define IT_VINLOW_F	26
+#define IT_VINLOW_R	27
+#define IT_SWIN_F	30
+#define IT_SWIN_R	31
+
+#endif /* __DT_BINDINGS_STPMIC1_H__ */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 2/8] mfd: stpmic1: add stpmic1 driver
From: Pascal PAILLET-LME @ 2018-10-18  9:02 UTC (permalink / raw)
  To: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
  Cc: Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-1-git-send-email-p.paillet@st.com>

From: pascal paillet <p.paillet@st.com>

stpmic1 is a pmic from STMicroelectronics. The STPMIC1 integrates 10
regulators , 3 switches, a watchdog and an input for a power on key.

Signed-off-by: pascal paillet <p.paillet@st.com>
---
changes in v4:
* rename PONKEY_PU_ACTIVE to PONKEY_PU_INACTIVE

 drivers/mfd/Kconfig         |  13 ++
 drivers/mfd/Makefile        |   1 +
 drivers/mfd/stpmic1.c       | 401 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/stpmic1.h | 212 +++++++++++++++++++++++
 4 files changed, 627 insertions(+)
 create mode 100644 drivers/mfd/stpmic1.c
 create mode 100644 include/linux/mfd/stpmic1.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 11841f4..b8dabc7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1855,6 +1855,19 @@ config MFD_STM32_TIMERS
 	  for PWM and IIO Timer. This driver allow to share the
 	  registers between the others drivers.
 
+config MFD_STPMIC1
+	tristate "Support for STPMIC1 PMIC"
+	depends on (I2C=y && OF)
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	select MFD_CORE
+	help
+	  Support for ST Microelectronics STPMIC1 PMIC. STPMIC1 MFD driver is
+	  the core driver for STPMIC1 component that mainly handles interrupts.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called stpmic1.
+
 menu "Multimedia Capabilities Port drivers"
 	depends on ARCH_SA1100
 
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 5856a94..76fff14 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -232,6 +232,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI)	+= intel_soc_pmic_chtdc_ti.o
 obj-$(CONFIG_MFD_MT6397)	+= mt6397-core.o
 
 obj-$(CONFIG_MFD_ALTERA_A10SR)	+= altera-a10sr.o
+obj-$(CONFIG_MFD_STPMIC1)	+= stpmic1.o
 obj-$(CONFIG_MFD_SUN4I_GPADC)	+= sun4i-gpadc.o
 
 obj-$(CONFIG_MFD_STM32_LPTIMER)	+= stm32-lptimer.o
diff --git a/drivers/mfd/stpmic1.c b/drivers/mfd/stpmic1.c
new file mode 100644
index 0000000..90dfee4
--- /dev/null
+++ b/drivers/mfd/stpmic1.c
@@ -0,0 +1,401 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) STMicroelectronics 2018
+// Author: Pascal Paillet <p.paillet@st.com>
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/stpmic1.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/mfd/st,stpmic1.h>
+
+#define STPMIC1_MAIN_IRQ 0
+#define STPMIC1_WAKEUP_IRQ 1
+
+static bool stpmic1_reg_readable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TURN_ON_SR:
+	case TURN_OFF_SR:
+	case ICC_LDO_TURN_OFF_SR:
+	case ICC_BUCK_TURN_OFF_SR:
+	case RREQ_STATE_SR:
+	case VERSION_SR:
+	case SWOFF_PWRCTRL_CR:
+	case PADS_PULL_CR:
+	case BUCKS_PD_CR:
+	case LDO14_PD_CR:
+	case LDO56_VREF_PD_CR:
+	case VBUS_DET_VIN_CR:
+	case PKEY_TURNOFF_CR:
+	case BUCKS_MASK_RANK_CR:
+	case BUCKS_MASK_RESET_CR:
+	case LDOS_MASK_RANK_CR:
+	case LDOS_MASK_RESET_CR:
+	case WCHDG_CR:
+	case WCHDG_TIMER_CR:
+	case BUCKS_ICCTO_CR:
+	case LDOS_ICCTO_CR:
+	case BUCK1_ACTIVE_CR:
+	case BUCK2_ACTIVE_CR:
+	case BUCK3_ACTIVE_CR:
+	case BUCK4_ACTIVE_CR:
+	case VREF_DDR_ACTIVE_CR:
+	case LDO1_ACTIVE_CR:
+	case LDO2_ACTIVE_CR:
+	case LDO3_ACTIVE_CR:
+	case LDO4_ACTIVE_CR:
+	case LDO5_ACTIVE_CR:
+	case LDO6_ACTIVE_CR:
+	case BUCK1_STDBY_CR:
+	case BUCK2_STDBY_CR:
+	case BUCK3_STDBY_CR:
+	case BUCK4_STDBY_CR:
+	case VREF_DDR_STDBY_CR:
+	case LDO1_STDBY_CR:
+	case LDO2_STDBY_CR:
+	case LDO3_STDBY_CR:
+	case LDO4_STDBY_CR:
+	case LDO5_STDBY_CR:
+	case LDO6_STDBY_CR:
+	case BST_SW_CR:
+	case INT_PENDING_R1:
+	case INT_PENDING_R2:
+	case INT_PENDING_R3:
+	case INT_PENDING_R4:
+	case INT_DBG_LATCH_R1:
+	case INT_DBG_LATCH_R2:
+	case INT_DBG_LATCH_R3:
+	case INT_DBG_LATCH_R4:
+	case INT_CLEAR_R1:
+	case INT_CLEAR_R2:
+	case INT_CLEAR_R3:
+	case INT_CLEAR_R4:
+	case INT_MASK_R1:
+	case INT_MASK_R2:
+	case INT_MASK_R3:
+	case INT_MASK_R4:
+	case INT_SET_MASK_R1:
+	case INT_SET_MASK_R2:
+	case INT_SET_MASK_R3:
+	case INT_SET_MASK_R4:
+	case INT_CLEAR_MASK_R1:
+	case INT_CLEAR_MASK_R2:
+	case INT_CLEAR_MASK_R3:
+	case INT_CLEAR_MASK_R4:
+	case INT_SRC_R1:
+	case INT_SRC_R2:
+	case INT_SRC_R3:
+	case INT_SRC_R4:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool stpmic1_reg_writeable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SWOFF_PWRCTRL_CR:
+	case PADS_PULL_CR:
+	case BUCKS_PD_CR:
+	case LDO14_PD_CR:
+	case LDO56_VREF_PD_CR:
+	case VBUS_DET_VIN_CR:
+	case PKEY_TURNOFF_CR:
+	case BUCKS_MASK_RANK_CR:
+	case BUCKS_MASK_RESET_CR:
+	case LDOS_MASK_RANK_CR:
+	case LDOS_MASK_RESET_CR:
+	case WCHDG_CR:
+	case WCHDG_TIMER_CR:
+	case BUCKS_ICCTO_CR:
+	case LDOS_ICCTO_CR:
+	case BUCK1_ACTIVE_CR:
+	case BUCK2_ACTIVE_CR:
+	case BUCK3_ACTIVE_CR:
+	case BUCK4_ACTIVE_CR:
+	case VREF_DDR_ACTIVE_CR:
+	case LDO1_ACTIVE_CR:
+	case LDO2_ACTIVE_CR:
+	case LDO3_ACTIVE_CR:
+	case LDO4_ACTIVE_CR:
+	case LDO5_ACTIVE_CR:
+	case LDO6_ACTIVE_CR:
+	case BUCK1_STDBY_CR:
+	case BUCK2_STDBY_CR:
+	case BUCK3_STDBY_CR:
+	case BUCK4_STDBY_CR:
+	case VREF_DDR_STDBY_CR:
+	case LDO1_STDBY_CR:
+	case LDO2_STDBY_CR:
+	case LDO3_STDBY_CR:
+	case LDO4_STDBY_CR:
+	case LDO5_STDBY_CR:
+	case LDO6_STDBY_CR:
+	case BST_SW_CR:
+	case INT_DBG_LATCH_R1:
+	case INT_DBG_LATCH_R2:
+	case INT_DBG_LATCH_R3:
+	case INT_DBG_LATCH_R4:
+	case INT_CLEAR_R1:
+	case INT_CLEAR_R2:
+	case INT_CLEAR_R3:
+	case INT_CLEAR_R4:
+	case INT_SET_MASK_R1:
+	case INT_SET_MASK_R2:
+	case INT_SET_MASK_R3:
+	case INT_SET_MASK_R4:
+	case INT_CLEAR_MASK_R1:
+	case INT_CLEAR_MASK_R2:
+	case INT_CLEAR_MASK_R3:
+	case INT_CLEAR_MASK_R4:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool stpmic1_reg_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TURN_ON_SR:
+	case TURN_OFF_SR:
+	case ICC_LDO_TURN_OFF_SR:
+	case ICC_BUCK_TURN_OFF_SR:
+	case RREQ_STATE_SR:
+	case INT_PENDING_R1:
+	case INT_PENDING_R2:
+	case INT_PENDING_R3:
+	case INT_PENDING_R4:
+	case INT_SRC_R1:
+	case INT_SRC_R2:
+	case INT_SRC_R3:
+	case INT_SRC_R4:
+	case WCHDG_CR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+const struct regmap_config stpmic1_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+	.max_register = PMIC_MAX_REGISTER_ADDRESS,
+	.readable_reg = stpmic1_reg_readable,
+	.writeable_reg = stpmic1_reg_writeable,
+	.volatile_reg = stpmic1_reg_volatile,
+};
+
+static const struct regmap_irq stpmic1_irqs[] = {
+	[IT_PONKEY_F]		= { .mask = 0x01 },
+	[IT_PONKEY_R]		= { .mask = 0x02 },
+	[IT_WAKEUP_F]		= { .mask = 0x04 },
+	[IT_WAKEUP_R]		= { .mask = 0x08 },
+	[IT_VBUS_OTG_F]		= { .mask = 0x10 },
+	[IT_VBUS_OTG_R]		= { .mask = 0x20 },
+	[IT_SWOUT_F]		= { .mask = 0x40 },
+	[IT_SWOUT_R]		= { .mask = 0x80 },
+
+	[IT_CURLIM_BUCK1]	= { .reg_offset = 1, .mask = 0x01 },
+	[IT_CURLIM_BUCK2]	= { .reg_offset = 1, .mask = 0x02 },
+	[IT_CURLIM_BUCK3]	= { .reg_offset = 1, .mask = 0x04 },
+	[IT_CURLIM_BUCK4]	= { .reg_offset = 1, .mask = 0x08 },
+	[IT_OCP_OTG]		= { .reg_offset = 1, .mask = 0x10 },
+	[IT_OCP_SWOUT]		= { .reg_offset = 1, .mask = 0x20 },
+	[IT_OCP_BOOST]		= { .reg_offset = 1, .mask = 0x40 },
+	[IT_OVP_BOOST]		= { .reg_offset = 1, .mask = 0x80 },
+
+	[IT_CURLIM_LDO1]	= { .reg_offset = 2, .mask = 0x01 },
+	[IT_CURLIM_LDO2]	= { .reg_offset = 2, .mask = 0x02 },
+	[IT_CURLIM_LDO3]	= { .reg_offset = 2, .mask = 0x04 },
+	[IT_CURLIM_LDO4]	= { .reg_offset = 2, .mask = 0x08 },
+	[IT_CURLIM_LDO5]	= { .reg_offset = 2, .mask = 0x10 },
+	[IT_CURLIM_LDO6]	= { .reg_offset = 2, .mask = 0x20 },
+	[IT_SHORT_SWOTG]	= { .reg_offset = 2, .mask = 0x40 },
+	[IT_SHORT_SWOUT]	= { .reg_offset = 2, .mask = 0x80 },
+
+	[IT_TWARN_F]		= { .reg_offset = 3, .mask = 0x01 },
+	[IT_TWARN_R]		= { .reg_offset = 3, .mask = 0x02 },
+	[IT_VINLOW_F]		= { .reg_offset = 3, .mask = 0x04 },
+	[IT_VINLOW_R]		= { .reg_offset = 3, .mask = 0x08 },
+	[IT_SWIN_F]		= { .reg_offset = 3, .mask = 0x40 },
+	[IT_SWIN_R]		= { .reg_offset = 3, .mask = 0x80 },
+};
+
+static const struct regmap_irq_chip stpmic1_regmap_irq_chip = {
+	.name = "pmic_irq",
+	.status_base = INT_PENDING_R1,
+	.mask_base = INT_CLEAR_MASK_R1,
+	.unmask_base = INT_SET_MASK_R1,
+	.ack_base = INT_CLEAR_R1,
+	.num_regs = STPMIC1_PMIC_NUM_IRQ_REGS,
+	.irqs = stpmic1_irqs,
+	.num_irqs = ARRAY_SIZE(stpmic1_irqs),
+};
+
+static int stpmic1_probe(struct i2c_client *i2c,
+			 const struct i2c_device_id *id)
+{
+	struct stpmic1 *ddata;
+	struct device *dev = &i2c->dev;
+	int ret;
+	struct device_node *np = dev->of_node;
+	u32 reg;
+
+	ddata = devm_kzalloc(dev, sizeof(struct stpmic1), GFP_KERNEL);
+	if (!ddata)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, ddata);
+	ddata->dev = dev;
+
+	ddata->regmap = devm_regmap_init_i2c(i2c, &stpmic1_regmap_config);
+	if (IS_ERR(ddata->regmap))
+		return PTR_ERR(ddata->regmap);
+
+	ddata->irq = of_irq_get(np, STPMIC1_MAIN_IRQ);
+	if (ddata->irq < 0) {
+		dev_err(dev, "Failed to get main IRQ: %d\n", ddata->irq);
+		return ddata->irq;
+	}
+
+	if (!of_property_read_u32(np, "st,main-control-register", &reg)) {
+		ret = regmap_update_bits(ddata->regmap,
+					 SWOFF_PWRCTRL_CR,
+					 PWRCTRL_POLARITY_HIGH |
+					 PWRCTRL_PIN_VALID |
+					 RESTART_REQUEST_ENABLED,
+					 reg);
+		if (ret) {
+			dev_err(dev,
+				"Failed to update main control register: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	/* Read Version ID */
+	ret = regmap_read(ddata->regmap, VERSION_SR, &reg);
+	if (ret) {
+		dev_err(dev, "Unable to read pmic version\n");
+		return ret;
+	}
+	dev_info(dev, "PMIC Chip Version: 0x%x\n", reg);
+
+	if (!of_property_read_u32(np, "st,pads-pull-register", &reg)) {
+		ret = regmap_update_bits(ddata->regmap,
+					 PADS_PULL_CR,
+					 WAKEUP_DETECTOR_DISABLED |
+					 PWRCTRL_PD_ACTIVE |
+					 PWRCTRL_PU_ACTIVE |
+					 WAKEUP_PD_ACTIVE,
+					 reg);
+		if (ret) {
+			dev_err(dev,
+				"Failed to update pads control register: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	if (!of_property_read_u32(np, "st,vin-control-register", &reg)) {
+		ret = regmap_update_bits(ddata->regmap,
+					 VBUS_DET_VIN_CR,
+					 VINLOW_CTRL_REG_MASK,
+					 reg);
+		if (ret) {
+			dev_err(dev,
+				"Failed to update vin control register: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	if (!of_property_read_u32(np, "st,usb-control-register", &reg)) {
+		ret = regmap_update_bits(ddata->regmap, BST_SW_CR,
+					 BOOST_OVP_DISABLED |
+					 VBUS_OTG_DETECTION_DISABLED |
+					 SW_OUT_DISCHARGE |
+					 VBUS_OTG_DISCHARGE |
+					 OCP_LIMIT_HIGH,
+					 reg);
+		if (ret) {
+			dev_err(dev,
+				"Failed to update usb control register: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	/* Initialize PMIC IRQ Chip & IRQ domains associated */
+	ret = devm_regmap_add_irq_chip(dev, ddata->regmap, ddata->irq,
+				       IRQF_ONESHOT | IRQF_SHARED,
+				       0, &stpmic1_regmap_irq_chip,
+				       &ddata->irq_data);
+	if (ret) {
+		dev_err(dev, "IRQ Chip registration failed: %d\n", ret);
+		return ret;
+	}
+
+	return devm_of_platform_populate(dev);
+}
+
+static const struct i2c_device_id stpmic1_id[] = {
+	{ "stpmic1"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, stpmic1_id);
+
+#ifdef CONFIG_PM_SLEEP
+static int stpmic1_suspend(struct device *dev)
+{
+	struct i2c_client *i2c = to_i2c_client(dev);
+	struct stpmic1 *pmic_dev = i2c_get_clientdata(i2c);
+
+	disable_irq(pmic_dev->irq);
+
+	return 0;
+}
+
+static int stpmic1_resume(struct device *dev)
+{
+	struct i2c_client *i2c = to_i2c_client(dev);
+	struct stpmic1 *pmic_dev = i2c_get_clientdata(i2c);
+	int ret;
+
+	ret = regcache_sync(pmic_dev->regmap);
+	if (ret)
+		return ret;
+
+	enable_irq(pmic_dev->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(stpmic1_pm, stpmic1_suspend, stpmic1_resume);
+
+static struct i2c_driver stpmic1_driver = {
+	.driver = {
+		.name = "stpmic1",
+		.pm = &stpmic1_pm,
+	},
+	.probe = stpmic1_probe,
+	.id_table = stpmic1_id,
+};
+
+module_i2c_driver(stpmic1_driver);
+
+MODULE_DESCRIPTION("STPMIC1 PMIC Driver");
+MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/stpmic1.h b/include/linux/mfd/stpmic1.h
new file mode 100644
index 0000000..fa3f99f
--- /dev/null
+++ b/include/linux/mfd/stpmic1.h
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Philippe Peurichard <philippe.peurichard@st.com>,
+ * Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
+ */
+
+#ifndef __LINUX_MFD_STPMIC1_H
+#define __LINUX_MFD_STPMIC1_H
+
+#define TURN_ON_SR		0x1
+#define TURN_OFF_SR		0x2
+#define ICC_LDO_TURN_OFF_SR	0x3
+#define ICC_BUCK_TURN_OFF_SR	0x4
+#define RREQ_STATE_SR		0x5
+#define VERSION_SR		0x6
+
+#define SWOFF_PWRCTRL_CR	0x10
+#define PADS_PULL_CR		0x11
+#define BUCKS_PD_CR		0x12
+#define LDO14_PD_CR		0x13
+#define LDO56_VREF_PD_CR	0x14
+#define VBUS_DET_VIN_CR		0x15
+#define PKEY_TURNOFF_CR		0x16
+#define BUCKS_MASK_RANK_CR	0x17
+#define BUCKS_MASK_RESET_CR	0x18
+#define LDOS_MASK_RANK_CR	0x19
+#define LDOS_MASK_RESET_CR	0x1A
+#define WCHDG_CR		0x1B
+#define WCHDG_TIMER_CR		0x1C
+#define BUCKS_ICCTO_CR		0x1D
+#define LDOS_ICCTO_CR		0x1E
+
+#define BUCK1_ACTIVE_CR		0x20
+#define BUCK2_ACTIVE_CR		0x21
+#define BUCK3_ACTIVE_CR		0x22
+#define BUCK4_ACTIVE_CR		0x23
+#define VREF_DDR_ACTIVE_CR	0x24
+#define LDO1_ACTIVE_CR		0x25
+#define LDO2_ACTIVE_CR		0x26
+#define LDO3_ACTIVE_CR		0x27
+#define LDO4_ACTIVE_CR		0x28
+#define LDO5_ACTIVE_CR		0x29
+#define LDO6_ACTIVE_CR		0x2A
+
+#define BUCK1_STDBY_CR		0x30
+#define BUCK2_STDBY_CR		0x31
+#define BUCK3_STDBY_CR		0x32
+#define BUCK4_STDBY_CR		0x33
+#define VREF_DDR_STDBY_CR	0x34
+#define LDO1_STDBY_CR		0x35
+#define LDO2_STDBY_CR		0x36
+#define LDO3_STDBY_CR		0x37
+#define LDO4_STDBY_CR		0x38
+#define LDO5_STDBY_CR		0x39
+#define LDO6_STDBY_CR		0x3A
+
+#define BST_SW_CR		0x40
+
+#define INT_PENDING_R1		0x50
+#define INT_PENDING_R2		0x51
+#define INT_PENDING_R3		0x52
+#define INT_PENDING_R4		0x53
+
+#define INT_DBG_LATCH_R1	0x60
+#define INT_DBG_LATCH_R2	0x61
+#define INT_DBG_LATCH_R3	0x62
+#define INT_DBG_LATCH_R4	0x63
+
+#define INT_CLEAR_R1		0x70
+#define INT_CLEAR_R2		0x71
+#define INT_CLEAR_R3		0x72
+#define INT_CLEAR_R4		0x73
+
+#define INT_MASK_R1		0x80
+#define INT_MASK_R2		0x81
+#define INT_MASK_R3		0x82
+#define INT_MASK_R4		0x83
+
+#define INT_SET_MASK_R1		0x90
+#define INT_SET_MASK_R2		0x91
+#define INT_SET_MASK_R3		0x92
+#define INT_SET_MASK_R4		0x93
+
+#define INT_CLEAR_MASK_R1	0xA0
+#define INT_CLEAR_MASK_R2	0xA1
+#define INT_CLEAR_MASK_R3	0xA2
+#define INT_CLEAR_MASK_R4	0xA3
+
+#define INT_SRC_R1		0xB0
+#define INT_SRC_R2		0xB1
+#define INT_SRC_R3		0xB2
+#define INT_SRC_R4		0xB3
+
+#define PMIC_MAX_REGISTER_ADDRESS INT_SRC_R4
+
+#define STPMIC1_PMIC_NUM_IRQ_REGS 4
+
+#define TURN_OFF_SR_ICC_EVENT	0x08
+
+#define LDO_VOLTAGE_MASK		GENMASK(6, 2)
+#define BUCK_VOLTAGE_MASK		GENMASK(7, 2)
+#define LDO_BUCK_VOLTAGE_SHIFT		2
+
+#define LDO_ENABLE_MASK			BIT(0)
+#define BUCK_ENABLE_MASK		BIT(0)
+
+#define BUCK_HPLP_ENABLE_MASK		BIT(1)
+#define BUCK_HPLP_SHIFT			1
+
+#define STDBY_ENABLE_MASK  BIT(0)
+
+#define BUCKS_PD_CR_REG_MASK	GENMASK(7, 0)
+#define BUCK_MASK_RANK_REGISTER_MASK	GENMASK(3, 0)
+#define BUCK_MASK_RESET_REGISTER_MASK	GENMASK(3, 0)
+#define LDO1234_PULL_DOWN_REGISTER_MASK	GENMASK(7, 0)
+#define LDO56_VREF_PD_CR_REG_MASK	GENMASK(5, 0)
+#define LDO_MASK_RANK_REGISTER_MASK	GENMASK(5, 0)
+#define LDO_MASK_RESET_REGISTER_MASK	GENMASK(5, 0)
+
+#define BUCK1_PULL_DOWN_REG		BUCKS_PD_CR
+#define BUCK1_PULL_DOWN_MASK		BIT(0)
+#define BUCK2_PULL_DOWN_REG		BUCKS_PD_CR
+#define BUCK2_PULL_DOWN_MASK		BIT(2)
+#define BUCK3_PULL_DOWN_REG		BUCKS_PD_CR
+#define BUCK3_PULL_DOWN_MASK		BIT(4)
+#define BUCK4_PULL_DOWN_REG		BUCKS_PD_CR
+#define BUCK4_PULL_DOWN_MASK		BIT(6)
+
+#define LDO1_PULL_DOWN_REG		LDO14_PD_CR
+#define LDO1_PULL_DOWN_MASK		BIT(0)
+#define LDO2_PULL_DOWN_REG		LDO14_PD_CR
+#define LDO2_PULL_DOWN_MASK		BIT(2)
+#define LDO3_PULL_DOWN_REG		LDO14_PD_CR
+#define LDO3_PULL_DOWN_MASK		BIT(4)
+#define LDO4_PULL_DOWN_REG		LDO14_PD_CR
+#define LDO4_PULL_DOWN_MASK		BIT(6)
+#define LDO5_PULL_DOWN_REG		LDO56_VREF_PD_CR
+#define LDO5_PULL_DOWN_MASK		BIT(0)
+#define LDO6_PULL_DOWN_REG		LDO56_VREF_PD_CR
+#define LDO6_PULL_DOWN_MASK		BIT(2)
+#define VREF_DDR_PULL_DOWN_REG		LDO56_VREF_PD_CR
+#define VREF_DDR_PULL_DOWN_MASK		BIT(4)
+
+#define BUCKS_ICCTO_CR_REG_MASK	GENMASK(6, 0)
+#define LDOS_ICCTO_CR_REG_MASK	GENMASK(5, 0)
+
+#define LDO_BYPASS_MASK			BIT(7)
+
+/* Main PMIC Control Register
+ * SWOFF_PWRCTRL_CR
+ * Address : 0x10
+ */
+#define ICC_EVENT_ENABLED		BIT(4)
+#define PWRCTRL_POLARITY_HIGH		BIT(3)
+#define PWRCTRL_PIN_VALID		BIT(2)
+#define RESTART_REQUEST_ENABLED		BIT(1)
+#define SOFTWARE_SWITCH_OFF_ENABLED	BIT(0)
+
+/* Main PMIC PADS Control Register
+ * PADS_PULL_CR
+ * Address : 0x11
+ */
+#define WAKEUP_DETECTOR_DISABLED	BIT(4)
+#define PWRCTRL_PD_ACTIVE		BIT(3)
+#define PWRCTRL_PU_ACTIVE		BIT(2)
+#define WAKEUP_PD_ACTIVE		BIT(1)
+#define PONKEY_PU_INACTIVE		BIT(0)
+
+/* Main PMIC VINLOW Control Register
+ * VBUS_DET_VIN_CRC DMSC
+ * Address : 0x15
+ */
+#define SWIN_DETECTOR_ENABLED		BIT(7)
+#define SWOUT_DETECTOR_ENABLED		BIT(6)
+#define VINLOW_ENABLED			BIT(0)
+#define VINLOW_CTRL_REG_MASK		GENMASK(7, 0)
+
+/* USB Control Register
+ * Address : 0x40
+ */
+#define BOOST_OVP_DISABLED		BIT(7)
+#define VBUS_OTG_DETECTION_DISABLED	BIT(6)
+#define SW_OUT_DISCHARGE		BIT(5)
+#define VBUS_OTG_DISCHARGE		BIT(4)
+#define OCP_LIMIT_HIGH			BIT(3)
+#define SWIN_SWOUT_ENABLED		BIT(2)
+#define USBSW_OTG_SWITCH_ENABLED	BIT(1)
+#define BOOST_ENABLED			BIT(0)
+
+/* PKEY_TURNOFF_CR
+ * Address : 0x16
+ */
+#define PONKEY_PWR_OFF			BIT(7)
+#define PONKEY_CC_FLAG_CLEAR		BIT(6)
+#define PONKEY_TURNOFF_TIMER_MASK	GENMASK(3, 0)
+#define PONKEY_TURNOFF_MASK		GENMASK(7, 0)
+
+/*
+ * struct stpmic1 - stpmic1 master device for sub-drivers
+ * @dev: master device of the chip (can be used to access platform data)
+ * @irq: main IRQ number
+ * @regmap_irq_chip_data: irq chip data
+ */
+struct stpmic1 {
+	struct device *dev;
+	struct regmap *regmap;
+	int irq;
+	struct regmap_irq_chip_data *irq_data;
+};
+
+#endif /*  __LINUX_MFD_STPMIC1_H */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 4/8] regulator: stpmic1: add stpmic1 regulator driver
From: Pascal PAILLET-LME @ 2018-10-18  9:02 UTC (permalink / raw)
  To: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
  Cc: Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-1-git-send-email-p.paillet@st.com>

From: pascal paillet <p.paillet@st.com>

The stpmic1 PMIC embeds several regulators and switches with
different capabilities.

Signed-off-by: pascal paillet <p.paillet@st.com>

---
changes in v4: nothing

 drivers/regulator/Kconfig             |  12 +
 drivers/regulator/Makefile            |   1 +
 drivers/regulator/stpmic1_regulator.c | 674 ++++++++++++++++++++++++++++++++++
 3 files changed, 687 insertions(+)
 create mode 100644 drivers/regulator/stpmic1_regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 6e96ef1..026d480 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -803,6 +803,18 @@ config REGULATOR_STM32_VREFBUF
 	  This driver can also be built as a module. If so, the module
 	  will be called stm32-vrefbuf.
 
+config REGULATOR_STPMIC1
+	tristate "STMicroelectronics STPMIC1 PMIC Regulators"
+	depends on MFD_STPMIC1
+	help
+	  This driver supports STMicroelectronics STPMIC1 PMIC voltage
+	  regulators and switches. The STPMIC1 regulators supply power to
+	  an application processor as well as to external system
+	  peripherals such as DDR, Flash memories and system devices.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called stpmic1_regulator.
+
 config REGULATOR_TI_ABB
 	tristate "TI Adaptive Body Bias on-chip LDO"
 	depends on ARCH_OMAP
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index eac4d79..300bc4c 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
+obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
 obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
diff --git a/drivers/regulator/stpmic1_regulator.c b/drivers/regulator/stpmic1_regulator.c
new file mode 100644
index 0000000..96f1808
--- /dev/null
+++ b/drivers/regulator/stpmic1_regulator.c
@@ -0,0 +1,674 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) STMicroelectronics 2018
+// Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
+
+#include <linux/interrupt.h>
+#include <linux/mfd/stpmic1.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+/**
+ * stpmic1 regulator description
+ * @desc: regulator framework description
+ * @mask_reset_reg: mask reset register address
+ * @mask_reset_mask: mask rank and mask reset register mask
+ * @icc_reg: icc register address
+ * @icc_mask: icc register mask
+ */
+struct stpmic1_regulator_cfg {
+	struct regulator_desc desc;
+	u8 mask_reset_reg;
+	u8 mask_reset_mask;
+	u8 icc_reg;
+	u8 icc_mask;
+};
+
+/**
+ * stpmic1 regulator data: this structure is used as driver data
+ * @regul_id: regulator id
+ * @reg_node: DT node of regulator (unused on non-DT platforms)
+ * @cfg: stpmic specific regulator description
+ * @mask_reset: mask_reset bit value
+ * @irq_curlim: current limit interrupt number
+ * @regmap: point to parent regmap structure
+ */
+struct stpmic1_regulator {
+	unsigned int regul_id;
+	struct device_node *reg_node;
+	struct stpmic1_regulator_cfg *cfg;
+	u8 mask_reset;
+	int irq_curlim;
+	struct regmap *regmap;
+};
+
+static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode);
+static unsigned int stpmic1_get_mode(struct regulator_dev *rdev);
+static int stpmic1_set_icc(struct regulator_dev *rdev);
+static int stpmic1_regulator_parse_dt(void *driver_data);
+static unsigned int stpmic1_map_mode(unsigned int mode);
+
+enum {
+	STPMIC1_BUCK1 = 0,
+	STPMIC1_BUCK2 = 1,
+	STPMIC1_BUCK3 = 2,
+	STPMIC1_BUCK4 = 3,
+	STPMIC1_LDO1 = 4,
+	STPMIC1_LDO2 = 5,
+	STPMIC1_LDO3 = 6,
+	STPMIC1_LDO4 = 7,
+	STPMIC1_LDO5 = 8,
+	STPMIC1_LDO6 = 9,
+	STPMIC1_VREF_DDR = 10,
+	STPMIC1_BOOST = 11,
+	STPMIC1_VBUS_OTG = 12,
+	STPMIC1_SW_OUT = 13,
+};
+
+/* Enable time worst case is 5000mV/(2250uV/uS) */
+#define PMIC_ENABLE_TIME_US 2200
+
+#define STPMIC1_BUCK_MODE_NORMAL 0
+#define STPMIC1_BUCK_MODE_LP BUCK_HPLP_ENABLE_MASK
+
+struct regulator_linear_range buck1_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0, 30, 25000),
+	REGULATOR_LINEAR_RANGE(1350000, 31, 63, 0),
+};
+
+struct regulator_linear_range buck2_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1000000, 0, 17, 0),
+	REGULATOR_LINEAR_RANGE(1050000, 18, 19, 0),
+	REGULATOR_LINEAR_RANGE(1100000, 20, 21, 0),
+	REGULATOR_LINEAR_RANGE(1150000, 22, 23, 0),
+	REGULATOR_LINEAR_RANGE(1200000, 24, 25, 0),
+	REGULATOR_LINEAR_RANGE(1250000, 26, 27, 0),
+	REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0),
+	REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0),
+	REGULATOR_LINEAR_RANGE(1400000, 32, 33, 0),
+	REGULATOR_LINEAR_RANGE(1450000, 34, 35, 0),
+	REGULATOR_LINEAR_RANGE(1500000, 36, 63, 0),
+};
+
+struct regulator_linear_range buck3_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1000000, 0, 19, 0),
+	REGULATOR_LINEAR_RANGE(1100000, 20, 23, 0),
+	REGULATOR_LINEAR_RANGE(1200000, 24, 27, 0),
+	REGULATOR_LINEAR_RANGE(1300000, 28, 31, 0),
+	REGULATOR_LINEAR_RANGE(1400000, 32, 35, 0),
+	REGULATOR_LINEAR_RANGE(1500000, 36, 55, 100000),
+	REGULATOR_LINEAR_RANGE(3400000, 56, 63, 0),
+
+};
+
+struct regulator_linear_range buck4_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0, 27, 25000),
+	REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0),
+	REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0),
+	REGULATOR_LINEAR_RANGE(1400000, 32, 33, 0),
+	REGULATOR_LINEAR_RANGE(1450000, 34, 35, 0),
+	REGULATOR_LINEAR_RANGE(1500000, 36, 60, 100000),
+	REGULATOR_LINEAR_RANGE(3900000, 61, 63, 0),
+
+};
+
+struct regulator_linear_range ldo1_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
+	REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
+	REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
+
+};
+
+struct regulator_linear_range ldo2_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
+	REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
+	REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
+
+};
+
+struct regulator_linear_range ldo3_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
+	REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
+	REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
+	/* with index 31 LDO3 is in DDR mode */
+	REGULATOR_LINEAR_RANGE(500000, 31, 31, 0),
+};
+
+struct regulator_linear_range ldo5_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
+	REGULATOR_LINEAR_RANGE(1700000, 8, 30, 100000),
+	REGULATOR_LINEAR_RANGE(3900000, 31, 31, 0),
+};
+
+struct regulator_linear_range ldo6_ranges[] = {
+	REGULATOR_LINEAR_RANGE(900000, 0, 24, 100000),
+	REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
+};
+
+static struct regulator_ops stpmic1_ldo_ops = {
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+	.is_enabled = regulator_is_enabled_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.set_pull_down = regulator_set_pull_down_regmap,
+	.set_over_current_protection = stpmic1_set_icc,
+};
+
+static struct regulator_ops stpmic1_ldo3_ops = {
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_iterate,
+	.is_enabled = regulator_is_enabled_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.set_pull_down = regulator_set_pull_down_regmap,
+	.get_bypass = regulator_get_bypass_regmap,
+	.set_bypass = regulator_set_bypass_regmap,
+	.set_over_current_protection = stpmic1_set_icc,
+};
+
+static struct regulator_ops stpmic1_ldo4_fixed_regul_ops = {
+	.is_enabled = regulator_is_enabled_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.set_pull_down = regulator_set_pull_down_regmap,
+	.set_over_current_protection = stpmic1_set_icc,
+};
+
+static struct regulator_ops stpmic1_buck_ops = {
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+	.is_enabled = regulator_is_enabled_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.set_pull_down = regulator_set_pull_down_regmap,
+	.set_mode = stpmic1_set_mode,
+	.get_mode = stpmic1_get_mode,
+	.set_over_current_protection = stpmic1_set_icc,
+};
+
+static struct regulator_ops stpmic1_vref_ddr_ops = {
+	.is_enabled = regulator_is_enabled_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.set_pull_down = regulator_set_pull_down_regmap,
+};
+
+static struct regulator_ops stpmic1_switch_regul_ops = {
+	.is_enabled = regulator_is_enabled_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.set_over_current_protection = stpmic1_set_icc,
+};
+
+#define REG_LDO(ids, base) { \
+	.name = #ids, \
+	.id = STPMIC1_##ids, \
+	.n_voltages = 32, \
+	.ops = &stpmic1_ldo_ops, \
+	.linear_ranges = base ## _ranges, \
+	.n_linear_ranges = ARRAY_SIZE(base ## _ranges), \
+	.type = REGULATOR_VOLTAGE, \
+	.owner = THIS_MODULE, \
+	.vsel_reg = ids##_ACTIVE_CR, \
+	.vsel_mask = LDO_VOLTAGE_MASK, \
+	.enable_reg = ids##_ACTIVE_CR, \
+	.enable_mask = LDO_ENABLE_MASK, \
+	.enable_val = 1, \
+	.disable_val = 0, \
+	.enable_time = PMIC_ENABLE_TIME_US, \
+	.pull_down_reg = ids##_PULL_DOWN_REG, \
+	.pull_down_mask = ids##_PULL_DOWN_MASK, \
+	.supply_name = #base, \
+}
+
+#define REG_LDO3(ids, base) { \
+	.name = #ids, \
+	.id = STPMIC1_##ids, \
+	.n_voltages = 32, \
+	.ops = &stpmic1_ldo3_ops, \
+	.linear_ranges = ldo3_ranges, \
+	.n_linear_ranges = ARRAY_SIZE(ldo3_ranges), \
+	.type = REGULATOR_VOLTAGE, \
+	.owner = THIS_MODULE, \
+	.vsel_reg = LDO3_ACTIVE_CR, \
+	.vsel_mask = LDO_VOLTAGE_MASK, \
+	.enable_reg = LDO3_ACTIVE_CR, \
+	.enable_mask = LDO_ENABLE_MASK, \
+	.enable_val = 1, \
+	.disable_val = 0, \
+	.enable_time = PMIC_ENABLE_TIME_US, \
+	.bypass_reg = LDO3_ACTIVE_CR, \
+	.bypass_mask = LDO_BYPASS_MASK, \
+	.bypass_val_on = LDO_BYPASS_MASK, \
+	.bypass_val_off = 0, \
+	.pull_down_reg = ids##_PULL_DOWN_REG, \
+	.pull_down_mask = ids##_PULL_DOWN_MASK, \
+	.supply_name = #base, \
+}
+
+#define REG_LDO4(ids, base) { \
+	.name = #ids, \
+	.id = STPMIC1_##ids, \
+	.n_voltages = 1, \
+	.ops = &stpmic1_ldo4_fixed_regul_ops, \
+	.type = REGULATOR_VOLTAGE, \
+	.owner = THIS_MODULE, \
+	.min_uV = 3300000, \
+	.fixed_uV = 3300000, \
+	.enable_reg = LDO4_ACTIVE_CR, \
+	.enable_mask = LDO_ENABLE_MASK, \
+	.enable_val = 1, \
+	.disable_val = 0, \
+	.enable_time = PMIC_ENABLE_TIME_US, \
+	.pull_down_reg = ids##_PULL_DOWN_REG, \
+	.pull_down_mask = ids##_PULL_DOWN_MASK, \
+	.supply_name = #base, \
+}
+
+#define REG_BUCK(ids, base) { \
+	.name = #ids, \
+	.id = STPMIC1_##ids, \
+	.ops = &stpmic1_buck_ops, \
+	.n_voltages = 64, \
+	.linear_ranges = base ## _ranges, \
+	.n_linear_ranges = ARRAY_SIZE(base ## _ranges), \
+	.type = REGULATOR_VOLTAGE, \
+	.owner = THIS_MODULE, \
+	.vsel_reg = ids##_ACTIVE_CR, \
+	.vsel_mask = BUCK_VOLTAGE_MASK, \
+	.enable_reg = ids##_ACTIVE_CR, \
+	.enable_mask = BUCK_ENABLE_MASK, \
+	.enable_val = 1, \
+	.disable_val = 0, \
+	.enable_time = PMIC_ENABLE_TIME_US, \
+	.of_map_mode = stpmic1_map_mode, \
+	.pull_down_reg = ids##_PULL_DOWN_REG, \
+	.pull_down_mask = ids##_PULL_DOWN_MASK, \
+	.supply_name = #base, \
+}
+
+#define REG_VREF_DDR(ids, base) { \
+	.name = #ids, \
+	.id = STPMIC1_##ids, \
+	.n_voltages = 1, \
+	.ops = &stpmic1_vref_ddr_ops, \
+	.type = REGULATOR_VOLTAGE, \
+	.owner = THIS_MODULE, \
+	.min_uV = 500000, \
+	.fixed_uV = 500000, \
+	.enable_reg = VREF_DDR_ACTIVE_CR, \
+	.enable_mask = BUCK_ENABLE_MASK, \
+	.enable_val = 1, \
+	.disable_val = 0, \
+	.enable_time = PMIC_ENABLE_TIME_US, \
+	.pull_down_reg = ids##_PULL_DOWN_REG, \
+	.pull_down_mask = ids##_PULL_DOWN_MASK, \
+	.supply_name = #base, \
+}
+
+#define REG_SWITCH(ids, base, reg, mask, val) { \
+	.name = #ids, \
+	.id = STPMIC1_##ids, \
+	.n_voltages = 1, \
+	.ops = &stpmic1_switch_regul_ops, \
+	.type = REGULATOR_VOLTAGE, \
+	.owner = THIS_MODULE, \
+	.min_uV = 0, \
+	.fixed_uV = 5000000, \
+	.enable_reg = (reg), \
+	.enable_mask = (mask), \
+	.enable_val = (val), \
+	.disable_val = 0, \
+	.enable_time = PMIC_ENABLE_TIME_US, \
+	.supply_name = #base, \
+}
+
+struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = {
+	[STPMIC1_BUCK1] = {
+		.desc = REG_BUCK(BUCK1, buck1),
+		.icc_reg = BUCKS_ICCTO_CR,
+		.icc_mask = BIT(0),
+		.mask_reset_reg = BUCKS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(0),
+	},
+	[STPMIC1_BUCK2] = {
+		.desc = REG_BUCK(BUCK2, buck2),
+		.icc_reg = BUCKS_ICCTO_CR,
+		.icc_mask = BIT(1),
+		.mask_reset_reg = BUCKS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(1),
+	},
+	[STPMIC1_BUCK3] = {
+		.desc = REG_BUCK(BUCK3, buck3),
+		.icc_reg = BUCKS_ICCTO_CR,
+		.icc_mask = BIT(2),
+		.mask_reset_reg = BUCKS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(2),
+	},
+	[STPMIC1_BUCK4] = {
+		.desc = REG_BUCK(BUCK4, buck4),
+		.icc_reg = BUCKS_ICCTO_CR,
+		.icc_mask = BIT(3),
+		.mask_reset_reg = BUCKS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(3),
+	},
+	[STPMIC1_LDO1] = {
+		.desc = REG_LDO(LDO1, ldo1),
+		.icc_reg = LDOS_ICCTO_CR,
+		.icc_mask = BIT(0),
+		.mask_reset_reg = LDOS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(0),
+	},
+	[STPMIC1_LDO2] = {
+		.desc = REG_LDO(LDO2, ldo2),
+		.icc_reg = LDOS_ICCTO_CR,
+		.icc_mask = BIT(1),
+		.mask_reset_reg = LDOS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(1),
+	},
+	[STPMIC1_LDO3] = {
+		.desc = REG_LDO3(LDO3, ldo3),
+		.icc_reg = LDOS_ICCTO_CR,
+		.icc_mask = BIT(2),
+		.mask_reset_reg = LDOS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(2),
+	},
+	[STPMIC1_LDO4] = {
+		.desc = REG_LDO4(LDO4, ldo4),
+		.icc_reg = LDOS_ICCTO_CR,
+		.icc_mask = BIT(3),
+		.mask_reset_reg = LDOS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(3),
+	},
+	[STPMIC1_LDO5] = {
+		.desc = REG_LDO(LDO5, ldo5),
+		.icc_reg = LDOS_ICCTO_CR,
+		.icc_mask = BIT(4),
+		.mask_reset_reg = LDOS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(4),
+	},
+	[STPMIC1_LDO6] = {
+		.desc = REG_LDO(LDO6, ldo6),
+		.icc_reg = LDOS_ICCTO_CR,
+		.icc_mask = BIT(5),
+		.mask_reset_reg = LDOS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(5),
+	},
+	[STPMIC1_VREF_DDR] = {
+		.desc = REG_VREF_DDR(VREF_DDR, vref_ddr),
+		.mask_reset_reg = LDOS_MASK_RESET_CR,
+		.mask_reset_mask = BIT(6),
+	},
+	[STPMIC1_BOOST] = {
+		.desc = REG_SWITCH(BOOST, boost, BST_SW_CR,
+				   BOOST_ENABLED,
+				   BOOST_ENABLED),
+		.icc_reg = BUCKS_ICCTO_CR,
+		.icc_mask = BIT(6),
+	},
+	[STPMIC1_VBUS_OTG] = {
+		.desc = REG_SWITCH(VBUS_OTG, pwr_sw1, BST_SW_CR,
+				   USBSW_OTG_SWITCH_ENABLED,
+				   USBSW_OTG_SWITCH_ENABLED),
+		.icc_reg = BUCKS_ICCTO_CR,
+		.icc_mask = BIT(4),
+	},
+	[STPMIC1_SW_OUT] = {
+		.desc = REG_SWITCH(SW_OUT, pwr_sw2, BST_SW_CR,
+				   SWIN_SWOUT_ENABLED,
+				   SWIN_SWOUT_ENABLED),
+		.icc_reg = BUCKS_ICCTO_CR,
+		.icc_mask = BIT(5),
+	},
+};
+
+static unsigned int stpmic1_map_mode(unsigned int mode)
+{
+	switch (mode) {
+	case STPMIC1_BUCK_MODE_NORMAL:
+		return REGULATOR_MODE_NORMAL;
+	case STPMIC1_BUCK_MODE_LP:
+		return REGULATOR_MODE_STANDBY;
+	default:
+		return -EINVAL;
+	}
+}
+
+static unsigned int stpmic1_get_mode(struct regulator_dev *rdev)
+{
+	int value;
+
+	regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
+
+	if (value & STPMIC1_BUCK_MODE_LP)
+		return REGULATOR_MODE_STANDBY;
+
+	return REGULATOR_MODE_NORMAL;
+}
+
+static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	int value;
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		value = STPMIC1_BUCK_MODE_NORMAL;
+		break;
+	case REGULATOR_MODE_STANDBY:
+		value = STPMIC1_BUCK_MODE_LP;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+				  STPMIC1_BUCK_MODE_LP, value);
+}
+
+static int stpmic1_set_icc(struct regulator_dev *rdev)
+{
+	struct stpmic1_regulator *regul = rdev_get_drvdata(rdev);
+
+	/* enable switch off in case of over current */
+	return regmap_update_bits(regul->regmap, regul->cfg->icc_reg,
+				  regul->cfg->icc_mask, regul->cfg->icc_mask);
+}
+
+static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
+{
+	struct regulator_dev *rdev = (struct regulator_dev *)data;
+
+	mutex_lock(&rdev->mutex);
+
+	/* Send an overcurrent notification */
+	regulator_notifier_call_chain(rdev,
+				      REGULATOR_EVENT_OVER_CURRENT,
+				      NULL);
+
+	mutex_unlock(&rdev->mutex);
+
+	return IRQ_HANDLED;
+}
+
+static int stpmic1_regulator_init(struct platform_device *pdev,
+				  struct regulator_dev *rdev)
+{
+	struct stpmic1_regulator *regul = rdev_get_drvdata(rdev);
+	int ret = 0;
+
+	/* set mask reset */
+	if (regul->mask_reset && regul->cfg->mask_reset_reg != 0) {
+		ret = regmap_update_bits(regul->regmap,
+					 regul->cfg->mask_reset_reg,
+					 regul->cfg->mask_reset_mask,
+					 regul->cfg->mask_reset_mask);
+		if (ret) {
+			dev_err(&pdev->dev, "set mask reset failed\n");
+			return ret;
+		}
+	}
+
+	/* setup an irq handler for over-current detection */
+	if (regul->irq_curlim > 0) {
+		ret = devm_request_threaded_irq(&pdev->dev,
+						regul->irq_curlim, NULL,
+						stpmic1_curlim_irq_handler,
+						IRQF_ONESHOT | IRQF_SHARED,
+						pdev->name, rdev);
+		if (ret) {
+			dev_err(&pdev->dev, "Request IRQ failed\n");
+			return ret;
+		}
+	}
+	return 0;
+}
+
+#define MATCH(_name, _id) \
+	[STPMIC1_##_id] = { \
+		.name = #_name, \
+		.desc = &stpmic1_regulator_cfgs[STPMIC1_##_id].desc, \
+	}
+
+static struct of_regulator_match stpmic1_regulators_matches[] = {
+	MATCH(buck1, BUCK1),
+	MATCH(buck2, BUCK2),
+	MATCH(buck3, BUCK3),
+	MATCH(buck4, BUCK4),
+	MATCH(ldo1, LDO1),
+	MATCH(ldo2, LDO2),
+	MATCH(ldo3, LDO3),
+	MATCH(ldo4, LDO4),
+	MATCH(ldo5, LDO5),
+	MATCH(ldo6, LDO6),
+	MATCH(vref_ddr, VREF_DDR),
+	MATCH(boost, BOOST),
+	MATCH(pwr_sw1, VBUS_OTG),
+	MATCH(pwr_sw2, SW_OUT),
+};
+
+static int stpmic1_regulator_parse_dt(void *driver_data)
+{
+	struct stpmic1_regulator *regul =
+		(struct stpmic1_regulator *)driver_data;
+
+	if (!regul)
+		return -EINVAL;
+
+	if (of_get_property(regul->reg_node, "st,mask-reset", NULL))
+		regul->mask_reset = 1;
+
+	regul->irq_curlim = of_irq_get(regul->reg_node, 0);
+
+	return 0;
+}
+
+static struct
+regulator_dev *stpmic1_regulator_register(struct platform_device *pdev, int id,
+					  struct regulator_init_data *init_data,
+					  struct stpmic1_regulator *regul)
+{
+	struct stpmic1 *pmic_dev = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_dev *rdev;
+	struct regulator_config config = {};
+
+	config.dev = &pdev->dev;
+	config.init_data = init_data;
+	config.of_node = stpmic1_regulators_matches[id].of_node;
+	config.regmap = pmic_dev->regmap;
+	config.driver_data = regul;
+
+	regul->regul_id = id;
+	regul->reg_node = config.of_node;
+	regul->cfg = &stpmic1_regulator_cfgs[id];
+	regul->regmap = pmic_dev->regmap;
+
+	rdev = devm_regulator_register(&pdev->dev, &regul->cfg->desc, &config);
+	if (IS_ERR(rdev)) {
+		dev_err(&pdev->dev, "failed to register %s regulator\n",
+			regul->cfg->desc.name);
+	}
+
+	return rdev;
+}
+
+static int stpmic1_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev;
+	struct stpmic1_regulator *regul;
+	struct regulator_init_data *init_data;
+	struct device_node *np;
+	int i, ret;
+
+	np = pdev->dev.of_node;
+
+	ret = of_regulator_match(&pdev->dev, np,
+				 stpmic1_regulators_matches,
+				 ARRAY_SIZE(stpmic1_regulators_matches));
+	if (ret < 0) {
+		dev_err(&pdev->dev,
+			"Error in PMIC regulator device tree node");
+		return ret;
+	}
+
+	regul = devm_kzalloc(&pdev->dev, ARRAY_SIZE(stpmic1_regulator_cfgs) *
+			     sizeof(struct stpmic1_regulator),
+			     GFP_KERNEL);
+	if (!regul)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(stpmic1_regulator_cfgs); i++) {
+		/* Parse DT & find regulators to register */
+		init_data = stpmic1_regulators_matches[i].init_data;
+		if (init_data)
+			init_data->regulator_init = &stpmic1_regulator_parse_dt;
+
+		rdev = stpmic1_regulator_register(pdev, i, init_data, regul);
+		if (IS_ERR(rdev))
+			return PTR_ERR(rdev);
+
+		ret = stpmic1_regulator_init(pdev, rdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"failed to initialize regulator %d\n", ret);
+			return ret;
+		}
+
+		regul++;
+	}
+
+	dev_dbg(&pdev->dev, "stpmic1_regulator driver probed\n");
+
+	return 0;
+}
+
+static const struct of_device_id of_pmic_regulator_match[] = {
+	{ .compatible = "st,stpmic1-regulators" },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(of, of_pmic_regulator_match);
+
+static struct platform_driver stpmic1_regulator_driver = {
+	.driver = {
+		.name = "stpmic1-regulator",
+		.of_match_table = of_match_ptr(of_pmic_regulator_match),
+	},
+	.probe = stpmic1_regulator_probe,
+};
+
+module_platform_driver(stpmic1_regulator_driver);
+
+MODULE_DESCRIPTION("STPMIC1 PMIC voltage regulator driver");
+MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 3/8] dt-bindings: regulator: document stpmic1 pmic regulators
From: Pascal PAILLET-LME @ 2018-10-18  9:02 UTC (permalink / raw)
  To: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
  Cc: Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-1-git-send-email-p.paillet@st.com>

From: pascal paillet <p.paillet@st.com>

The STPMIC1 regulators supply power to the application processor as well as
to the external system peripherals such as DDR, Flash memories and system
devices.

Signed-off-by: pascal paillet <p.paillet@st.com>
Reviewed-by: Rob Herring <robh@kernel.org>

---
changes in v4: nothing

 .../bindings/regulator/st,stpmic1-regulator.txt    | 68 ++++++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/st,stpmic1-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/st,stpmic1-regulator.txt b/Documentation/devicetree/bindings/regulator/st,stpmic1-regulator.txt
new file mode 100644
index 0000000..a3f4762
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/st,stpmic1-regulator.txt
@@ -0,0 +1,68 @@
+STMicroelectronics STPMIC1 Voltage regulators
+
+Regulator Nodes are optional depending on needs.
+
+Available Regulators in STPMIC1 device are:
+  - buck1 for Buck BUCK1
+  - buck2 for Buck BUCK2
+  - buck3 for Buck BUCK3
+  - buck4 for Buck BUCK4
+  - ldo1 for LDO LDO1
+  - ldo2 for LDO LDO2
+  - ldo3 for LDO LDO3
+  - ldo4 for LDO LDO4
+  - ldo5 for LDO LDO5
+  - ldo6 for LDO LDO6
+  - vref_ddr for LDO Vref DDR
+  - boost for Buck BOOST
+  - pwr_sw1 for VBUS_OTG switch
+  - pwr_sw2 for SW_OUT switch
+
+Switches are fixed voltage regulators with only enable/disable capability.
+
+Optional properties:
+- st,mask-reset: mask reset for this regulator: the regulator configuration
+  is maintained during pmic reset.
+- regulator-pull-down: enable high pull down
+  if not specified light pull down is used
+- regulator-over-current-protection:
+    if set, all regulators are switched off in case of over-current detection
+    on this regulator,
+    if not set, the driver only sends an over-current event.
+- interrupt-parent: phandle to the parent interrupt controller
+- interrupts: index of current limit detection interrupt
+- <regulator>-supply: phandle to the parent supply/regulator node
+	each regulator supply can be described except vref_ddr.
+
+Example:
+regulators {
+	compatible = "st,stpmic1-regulators";
+
+	ldo6-supply = <&v3v3>;
+
+	vdd_core: buck1 {
+		regulator-name = "vdd_core";
+		interrupts = <IT_CURLIM_BUCK1 0>;
+		interrupt-parent = <&pmic>;
+		st,mask-reset;
+		regulator-pull-down;
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <1200000>;
+	};
+
+	v3v3: buck4 {
+		regulator-name = "v3v3";
+		interrupts = <IT_CURLIM_BUCK4 0>;
+		interrupt-parent = <&mypmic>;
+
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	v1v8: ldo6 {
+		regulator-name = "v1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-over-current-protection;
+	};
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 5/8] dt-bindings: input: document stpmic1 pmic onkey
From: Pascal PAILLET-LME @ 2018-10-18  9:02 UTC (permalink / raw)
  To: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
  Cc: Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-1-git-send-email-p.paillet@st.com>

From: pascal paillet <p.paillet@st.com>

The stpmic1 pmic is able to manage an onkey button. It can be configured
to shut-down the power supplies on a long key-press with an adjustable
duration.

Signed-off-by: pascal paillet <p.paillet@st.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
changes in v4:
* remove interrupt-parent description
* remove st,onkey-pwroff-enabled and power-off-time-sec properties

 .../devicetree/bindings/input/st,stpmic1-onkey.txt | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/st,stpmic1-onkey.txt

diff --git a/Documentation/devicetree/bindings/input/st,stpmic1-onkey.txt b/Documentation/devicetree/bindings/input/st,stpmic1-onkey.txt
new file mode 100644
index 0000000..4494613
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/st,stpmic1-onkey.txt
@@ -0,0 +1,28 @@
+STMicroelectronics STPMIC1 Onkey
+
+Required properties:
+
+- compatible = "st,stpmic1-onkey";
+- interrupts: interrupt line to use
+- interrupt-names = "onkey-falling", "onkey-rising"
+	onkey-falling: happens when onkey is pressed; IT_PONKEY_F of pmic
+	onkey-rising: happens when onkey is released; IT_PONKEY_R of pmic
+
+Optional properties:
+
+- st,onkey-clear-cc-flag: onkey is able power on after an
+  over-current shutdown event.
+- st,onkey-pu-inactive: onkey pull up is not active
+- power-off-time-sec: Duration in seconds which the key should be kept
+        pressed for device to power off automatically (from 1 to 16 seconds).
+        see See Documentation/devicetree/bindings/input/keys.txt
+
+Example:
+
+onkey {
+	compatible = "st,stpmic1-onkey";
+	interrupt-parent = <&pmic>;
+	interrupts = <IT_PONKEY_F 0>,<IT_PONKEY_R 1>;
+	interrupt-names = "onkey-falling", "onkey-rising";
+	power-off-time-sec = <10>;
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 6/8] input: stpmic1: add stpmic1 onkey driver
From: Pascal PAILLET-LME @ 2018-10-18  9:02 UTC (permalink / raw)
  To: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
  Cc: Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-1-git-send-email-p.paillet@st.com>

From: pascal paillet <p.paillet@st.com>

The stpmic1 pmic is able to manage an onkey button. This driver exposes
the stpmic1 onkey as an input device. It can also be configured to
shut-down the power supplies on a long key-press with an adjustable
duration.

Signed-off-by: pascal paillet <p.paillet@st.com>
---
changes in v4:
* remove remove function
* merge stpmic1_onkey_dt_params() in probe function
* suppresse struct pmic_onkey_config
* rename PONKEY_PU_ACTIVE to PONKEY_PU_INACTIVE

 drivers/input/misc/Kconfig         |  11 +++
 drivers/input/misc/Makefile        |   2 +
 drivers/input/misc/stpmic1_onkey.c | 197 +++++++++++++++++++++++++++++++++++++
 3 files changed, 210 insertions(+)
 create mode 100644 drivers/input/misc/stpmic1_onkey.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index ca59a2b..279fb02 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -851,4 +851,15 @@ config INPUT_SC27XX_VIBRA
 	  To compile this driver as a module, choose M here. The module will
 	  be called sc27xx_vibra.
 
+config INPUT_STPMIC1_ONKEY
+	tristate "STPMIC1 PMIC Onkey support"
+	depends on MFD_STPMIC1
+	help
+	  Say Y to enable support of onkey embedded into STPMIC1 PMIC. onkey
+	  can be used to wakeup from low power modes and force a shut-down on
+	  long press.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called stpmic1_onkey.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 9d0f9d1..1b44202 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
 obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)	+= sirfsoc-onkey.o
 obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY)	+= soc_button_array.o
 obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
+obj-$(CONFIG_INPUT_STPMIC1_ONKEY)  	+= stpmic1_onkey.o
 obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON)	+= tps65218-pwrbutton.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)	+= twl4030-pwrbutton.o
 obj-$(CONFIG_INPUT_TWL4030_VIBRA)	+= twl4030-vibra.o
@@ -81,3 +82,4 @@ obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o
 obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND)	+= xen-kbdfront.o
 obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
 obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR)	+= ideapad_slidebar.o
+
diff --git a/drivers/input/misc/stpmic1_onkey.c b/drivers/input/misc/stpmic1_onkey.c
new file mode 100644
index 0000000..6a7f08b
--- /dev/null
+++ b/drivers/input/misc/stpmic1_onkey.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) STMicroelectronics 2018
+// Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
+
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/stpmic1.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+/**
+ * struct stpmic1_onkey - OnKey data
+ * @input_dev:		pointer to input device
+ * @irq_falling:	irq that we are hooked on to
+ * @irq_rising:		irq that we are hooked on to
+ */
+struct stpmic1_onkey {
+	struct input_dev *input_dev;
+	int irq_falling;
+	int irq_rising;
+};
+
+static irqreturn_t onkey_falling_irq(int irq, void *ponkey)
+{
+	struct stpmic1_onkey *onkey = ponkey;
+	struct input_dev *input_dev = onkey->input_dev;
+
+	input_report_key(input_dev, KEY_POWER, 1);
+	pm_wakeup_event(input_dev->dev.parent, 0);
+	input_sync(input_dev);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t onkey_rising_irq(int irq, void *ponkey)
+{
+	struct stpmic1_onkey *onkey = ponkey;
+	struct input_dev *input_dev = onkey->input_dev;
+
+	input_report_key(input_dev, KEY_POWER, 0);
+	pm_wakeup_event(input_dev->dev.parent, 0);
+	input_sync(input_dev);
+
+	return IRQ_HANDLED;
+}
+
+static int stpmic1_onkey_probe(struct platform_device *pdev)
+{
+	struct stpmic1 *pmic = dev_get_drvdata(pdev->dev.parent);
+	struct device *dev = &pdev->dev;
+	struct input_dev *input_dev;
+	struct stpmic1_onkey *onkey;
+	unsigned int val, reg = 0;
+	int error;
+
+	onkey = devm_kzalloc(dev, sizeof(*onkey), GFP_KERNEL);
+	if (!onkey)
+		return -ENOMEM;
+
+	onkey->irq_falling = platform_get_irq_byname(pdev, "onkey-falling");
+	if (onkey->irq_falling < 0) {
+		dev_err(dev, "failed: request IRQ onkey-falling %d\n",
+			onkey->irq_falling);
+		return onkey->irq_falling;
+	}
+
+	onkey->irq_rising = platform_get_irq_byname(pdev, "onkey-rising");
+	if (onkey->irq_rising < 0) {
+		dev_err(dev, "failed: request IRQ onkey-rising %d\n",
+			onkey->irq_rising);
+		return onkey->irq_rising;
+	}
+
+	if (!device_property_read_u32(dev, "power-off-time-sec", &val)) {
+		if ((val > 0) && (val <= 16)) {
+			dev_dbg(dev, "power-off-time=%d seconds\n", val);
+			reg |= PONKEY_PWR_OFF;
+			reg |= ((16 - val) & PONKEY_TURNOFF_TIMER_MASK);
+		} else {
+			dev_err(dev, "power-off-time-sec out of range\n");
+			return -EINVAL;
+		}
+	}
+
+	if (device_property_present(dev, "st,onkey-clear-cc-flag"))
+		reg |= PONKEY_CC_FLAG_CLEAR;
+
+	error = regmap_update_bits(pmic->regmap, PKEY_TURNOFF_CR,
+				   PONKEY_TURNOFF_MASK, reg);
+	if (error) {
+		dev_err(dev, "PKEY_TURNOFF_CR write failed: %d\n", error);
+		return error;
+	}
+
+	if (device_property_present(dev, "st,onkey-pu-inactive")) {
+		error = regmap_update_bits(pmic->regmap, PADS_PULL_CR,
+					   PONKEY_PU_INACTIVE,
+					   PONKEY_PU_INACTIVE);
+		if (error) {
+			dev_err(dev, "ONKEY Pads configuration failed: %d\n", error);
+			return error;
+		}
+	}
+
+	input_dev = devm_input_allocate_device(dev);
+	if (!input_dev) {
+		dev_err(dev, "Can't allocate Pwr Onkey Input Device\n");
+		return -ENOMEM;
+	}
+
+	input_dev->name = "pmic_onkey";
+	input_dev->phys = "pmic_onkey/input0";
+
+	input_set_capability(input_dev, EV_KEY, KEY_POWER);
+
+	onkey->input_dev = input_dev;
+
+	/* interrupt is nested in a thread */
+	error = devm_request_threaded_irq(dev, onkey->irq_falling, NULL,
+					  onkey_falling_irq, IRQF_ONESHOT,
+					  dev_name(dev), onkey);
+	if (error) {
+		dev_err(dev, "Can't get IRQ Onkey Falling: %d\n", error);
+		return error;
+	}
+
+	error = devm_request_threaded_irq(dev, onkey->irq_rising, NULL,
+					  onkey_rising_irq, IRQF_ONESHOT,
+					  dev_name(dev), onkey);
+	if (error) {
+		dev_err(dev, "Can't get IRQ Onkey Rising: %d\n", error);
+		return error;
+	}
+
+	error = input_register_device(input_dev);
+	if (error) {
+		dev_err(dev, "Can't register power button: %d\n", error);
+		return error;
+	}
+
+	platform_set_drvdata(pdev, onkey);
+	device_init_wakeup(dev, true);
+
+	return 0;
+}
+
+static int __maybe_unused stpmic1_onkey_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(dev)) {
+		enable_irq_wake(onkey->irq_falling);
+		enable_irq_wake(onkey->irq_rising);
+	}
+	return 0;
+}
+
+static int __maybe_unused stpmic1_onkey_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(dev)) {
+		disable_irq_wake(onkey->irq_falling);
+		disable_irq_wake(onkey->irq_rising);
+	}
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(stpmic1_onkey_pm,
+			 stpmic1_onkey_suspend,
+			 stpmic1_onkey_resume);
+
+static const struct of_device_id of_stpmic1_onkey_match[] = {
+	{ .compatible = "st,stpmic1-onkey" },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(of, of_stpmic1_onkey_match);
+
+static struct platform_driver stpmic1_onkey_driver = {
+	.probe	= stpmic1_onkey_probe,
+	.driver	= {
+		.name	= "stpmic1_onkey",
+		.of_match_table = of_match_ptr(of_stpmic1_onkey_match),
+		.pm	= &stpmic1_onkey_pm,
+	},
+};
+module_platform_driver(stpmic1_onkey_driver);
+
+MODULE_DESCRIPTION("Onkey driver for STPMIC1");
+MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 7/8] dt-bindings: watchdog: document stpmic1 pmic watchdog
From: Pascal PAILLET-LME @ 2018-10-18  9:02 UTC (permalink / raw)
  To: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
  Cc: Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-1-git-send-email-p.paillet@st.com>

From: pascal paillet <p.paillet@st.com>

The stpmic1 PMIC embeds a watchdog which is disabled by default.
In case of watchdog, the PMIC goes off.

Signed-off-by: pascal paillet <p.paillet@st.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/watchdog/st,stpmic1-wdt.txt | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/st,stpmic1-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/st,stpmic1-wdt.txt b/Documentation/devicetree/bindings/watchdog/st,stpmic1-wdt.txt
new file mode 100644
index 0000000..7cc1407
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/st,stpmic1-wdt.txt
@@ -0,0 +1,11 @@
+STMicroelectronics STPMIC1 Watchdog
+
+Required properties:
+
+- compatible : should be "st,stpmic1-wdt"
+
+Example:
+
+watchdog {
+	compatible = "st,stpmic1-wdt";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 8/8] watchdog: stpmic1: add stpmic1 watchdog driver
From: Pascal PAILLET-LME @ 2018-10-18  9:02 UTC (permalink / raw)
  To: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
  Cc: Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-1-git-send-email-p.paillet@st.com>

From: pascal paillet <p.paillet@st.com>

The stpmic1 PMIC embeds a watchdog which is disabled by default. As soon
as the watchdog is started, it must be refreshed periodically otherwise
the PMIC goes off.

Signed-off-by: pascal paillet <p.paillet@st.com>
---
changes in v4:
* fix stop watchdog function
* Kconfig: fix grammar issue

 drivers/watchdog/Kconfig       |  12 ++++
 drivers/watchdog/Makefile      |   1 +
 drivers/watchdog/stpmic1_wdt.c | 139 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 152 insertions(+)
 create mode 100644 drivers/watchdog/stpmic1_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5ea8909..6d2ffef 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -806,6 +806,18 @@ config STM32_WATCHDOG
 	  To compile this driver as a module, choose M here: the
 	  module will be called stm32_iwdg.
 
+config STPMIC1_WATCHDOG
+	tristate "STPMIC1 PMIC watchdog support"
+	depends on MFD_STPMIC1
+	select WATCHDOG_CORE
+	help
+	  Say Y here to include watchdog support embedded into STPMIC1 PMIC.
+	  If the watchdog timer expires, stpmic1 will shut down all its power
+	  supplies.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called spmic1_wdt.
+
 config UNIPHIER_WATCHDOG
 	tristate "UniPhier watchdog support"
 	depends on ARCH_UNIPHIER || COMPILE_TEST
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index bf92e7b..2649cf3 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -217,3 +217,4 @@ obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
 obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o
 obj-$(CONFIG_MENZ069_WATCHDOG) += menz69_wdt.o
 obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o
+obj-$(CONFIG_STPMIC1_WATCHDOG) += stpmic1_wdt.o
diff --git a/drivers/watchdog/stpmic1_wdt.c b/drivers/watchdog/stpmic1_wdt.c
new file mode 100644
index 0000000..a6cbc27
--- /dev/null
+++ b/drivers/watchdog/stpmic1_wdt.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) STMicroelectronics 2018
+// Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
+
+#include <linux/kernel.h>
+#include <linux/mfd/stpmic1.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/watchdog.h>
+
+/* WATCHDOG CONTROL REGISTER bit */
+#define WDT_START		BIT(0)
+#define WDT_PING		BIT(1)
+#define WDT_START_MASK		BIT(0)
+#define WDT_PING_MASK		BIT(1)
+#define WDT_STOP		0
+
+#define PMIC_WDT_MIN_TIMEOUT 1
+#define PMIC_WDT_MAX_TIMEOUT 256
+#define PMIC_WDT_DEFAULT_TIMEOUT 30
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+		"Watchdog cannot be stopped once started (default="
+				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+struct stpmic1_wdt {
+	struct stpmic1 *pmic;
+	struct watchdog_device wdtdev;
+};
+
+static int pmic_wdt_start(struct watchdog_device *wdd)
+{
+	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	return regmap_update_bits(wdt->pmic->regmap,
+				  WCHDG_CR, WDT_START_MASK, WDT_START);
+}
+
+static int pmic_wdt_stop(struct watchdog_device *wdd)
+{
+	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	return regmap_update_bits(wdt->pmic->regmap,
+				  WCHDG_CR, WDT_START_MASK, WDT_STOP);
+}
+
+static int pmic_wdt_ping(struct watchdog_device *wdd)
+{
+	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	return regmap_update_bits(wdt->pmic->regmap,
+				  WCHDG_CR, WDT_PING_MASK, WDT_PING);
+}
+
+static int pmic_wdt_set_timeout(struct watchdog_device *wdd,
+				unsigned int timeout)
+{
+	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	wdd->timeout = timeout;
+	/* timeout is equal to register value + 1 */
+	return regmap_write(wdt->pmic->regmap, WCHDG_TIMER_CR, timeout - 1);
+}
+
+static const struct watchdog_info pmic_watchdog_info = {
+	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+	.identity = "STPMIC1 PMIC Watchdog",
+};
+
+static const struct watchdog_ops pmic_watchdog_ops = {
+	.owner = THIS_MODULE,
+	.start = pmic_wdt_start,
+	.stop = pmic_wdt_stop,
+	.ping = pmic_wdt_ping,
+	.set_timeout = pmic_wdt_set_timeout,
+};
+
+static int pmic_wdt_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct stpmic1 *pmic;
+	struct stpmic1_wdt *wdt;
+
+	if (!pdev->dev.parent)
+		return -EINVAL;
+
+	pmic = dev_get_drvdata(pdev->dev.parent);
+	if (!pmic)
+		return -EINVAL;
+
+	wdt = devm_kzalloc(&pdev->dev, sizeof(struct stpmic1_wdt), GFP_KERNEL);
+	if (!wdt)
+		return -ENOMEM;
+
+	wdt->pmic = pmic;
+
+	wdt->wdtdev.info = &pmic_watchdog_info;
+	wdt->wdtdev.ops = &pmic_watchdog_ops;
+	wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT;
+	wdt->wdtdev.max_timeout = PMIC_WDT_MAX_TIMEOUT;
+
+	wdt->wdtdev.timeout = PMIC_WDT_DEFAULT_TIMEOUT;
+	watchdog_init_timeout(&wdt->wdtdev, 0, &pdev->dev);
+
+	watchdog_set_nowayout(&wdt->wdtdev, nowayout);
+	watchdog_set_drvdata(&wdt->wdtdev, wdt);
+
+	ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev);
+	if (ret)
+		return ret;
+
+	dev_dbg(wdt->pmic->dev, "PMIC Watchdog driver probed\n");
+	return 0;
+}
+
+static const struct of_device_id of_pmic_wdt_match[] = {
+	{ .compatible = "st,stpmic1-wdt" },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(of, of_pmic_wdt_match);
+
+static struct platform_driver stpmic1_wdt_driver = {
+	.probe = pmic_wdt_probe,
+	.driver = {
+		.name = "stpmic1-wdt",
+		.of_match_table = of_pmic_wdt_match,
+	},
+};
+module_platform_driver(stpmic1_wdt_driver);
+
+MODULE_DESCRIPTION("Watchdog driver for STPMIC1 device");
+MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH 3/5] dt-bindings: add more optional properties for elan_i2c touchpads
From: Rob Herring @ 2018-10-18 13:04 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Hans de Goede, Dmitry Torokhov, KT Liao, linux-input,
	linux-kernel@vger.kernel.org, devicetree
In-Reply-To: <CAO-hwJ+z6YdnLdbzeh-7f99cBBjHfbLKLzKo-fQQaC_W8bt_Uw@mail.gmail.com>

On Thu, Oct 18, 2018 at 3:10 AM Benjamin Tissoires
<benjamin.tissoires@redhat.com> wrote:
>
> On Wed, Oct 17, 2018 at 10:15 PM Rob Herring <robh@kernel.org> wrote:
> >
> > On Fri, Oct 12, 2018 at 04:24:11PM +0200, Benjamin Tissoires wrote:
> > > Some new touchpads IC are connected through PS/2 and I2C. On some of these
> > > new IC, the I2C part doesn't have all of the information available.
> > > We need to be able to forward the touchpad parameters from PS/2 and
> > > thus, we need those new optional properties.
> > >
> > > Link: https://bugzilla.redhat.com/show_bug.cgi?id=1628715
> > > Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> > > ---
> > >  Documentation/devicetree/bindings/input/elan_i2c.txt | 8 ++++++++
> > >  1 file changed, 8 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/input/elan_i2c.txt b/Documentation/devicetree/bindings/input/elan_i2c.txt
> > > index 797607460735..ace6bcb0b4eb 100644
> > > --- a/Documentation/devicetree/bindings/input/elan_i2c.txt
> > > +++ b/Documentation/devicetree/bindings/input/elan_i2c.txt
> > > @@ -13,6 +13,14 @@ Optional properties:
> > >    pinctrl binding [1]).
> > >  - vcc-supply: a phandle for the regulator supplying 3.3V power.
> > >  - elan,trackpoint: touchpad can support a trackpoint (boolean)
> > > +- elan,clickpad: touchpad is a clickpad (the entire surface is a button)
> >
> > > +- elan,max_x: the maximum reported value on the X axis
> > > +- elan,max_y: the maximum reported value on the Y axis
> > > +- elan,min_x: the minimum reported value on the X axis
> > > +- elan,min_y: the minimum reported value on the Y axis
> > > +- elan,x_res: the resolution of the X axis (in units per mm)
> > > +- elan,y_res: the resolution of the Y axis (in units per mm)
> > > +- elan,width: max reported width of a blob
> >
> > Can't we use standard touchscreen properties here? (Yes, I get this is a
> > touchpad, not touchscreen).
>
> Hey Rob,
>
> Well, there is that (it's a touchpad driver) and we can't also really
> use the of_touchscreen.c implementation.
> If both concerns are not an issue, we can then move the [min/max/res]
> properties to the touchscreen ones.

Neither is problem for me. Bindings don't have to map 1:1 to kernel code.

> Regarding 'elan,width', this is something missing from the standard ts
> properties, and AFAICT, this controls the maximum reported
> width/height of a touch.
> I should probably rename them to max_width, max_height.

Sure, just use '-' rather than '_' in property names.

> Hans, do you think we should add such properties to of_touchscreen.c
> too? (the width/height ones)
>
> Cheers,
> Benjamin

^ permalink raw reply

* Re: [PATCH] HID: quirks: fix support for Apple Magic Keyboards
From: Benjamin Tissoires @ 2018-10-18 13:04 UTC (permalink / raw)
  To: gregkh; +Cc: ncopa, 3.8+, open list:HID CORE LAYER, Jiri Kosina, seobrien
In-Reply-To: <20181017165510.GA7468@kroah.com>

On Wed, Oct 17, 2018 at 6:55 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Wed, Oct 17, 2018 at 06:49:16PM +0200, Benjamin Tissoires wrote:
> > On Wed, Oct 17, 2018 at 5:55 PM Natanael Copa <ncopa@alpinelinux.org> wrote:
> > >
> > > On Wed, 17 Oct 2018 16:59:15 +0200
> > > Benjamin Tissoires <benjamin.tissoires@redhat.com> wrote:
> > >
> > > > Hi Natanael,
> > > >
> > > > On Wed, Oct 17, 2018 at 4:52 PM Natanael Copa <ncopa@alpinelinux.org> wrote:
> > > > >
> > > > > Commit ee3454924370 ("HID: add support for Apple Magic Keyboards") added
> > > > > support for the Magic Keyboard over Bluetooth, but did not add the
> > > > > BT_VENDOR_ID_APPLE to hid-quirks. Fix this so hid-apple driver is used
> > > > > over hid-generic.
> > > > >
> > > > > This fixes the Fn key, which does not work at all with hid-generic.
> > > > >
> > > > > Fixes: ee3454924370 ("HID: add support for Apple Magic Keyboards")
> > > > > Bugzilla-id: https://bugzilla.kernel.org/show_bug.cgi?id=99881
> > > > > Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
> > > > > ---
> > > > > This should be backported to stable too.
> > > > >
> > > > >  drivers/hid/hid-quirks.c | 3 +++
> > > > >  1 file changed, 3 insertions(+)
> > > > >
> > > > > diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
> > > > > index 249d49b6b16c..a3b3aecf8628 100644
> > > > > --- a/drivers/hid/hid-quirks.c
> > > > > +++ b/drivers/hid/hid-quirks.c
> > > > > @@ -270,6 +270,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
> > > > >         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) },
> > > > >         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS) },
> > > > >         { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI) },
> > > > > +       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI) },
> > > > > +       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI) },
> > > > > +       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI) },
> > > >
> > > > NACK, this should not be required with kernels v4.17+ IIRC.
> > > >
> > > > If it doesn't work on a recent kernel, please raise the issue, but I
> > > > am actually chasing down the new inclusions of these when we add new
> > > > device support.
> > >
> > > Fair enough. I think it may be needed for 4.14.y kernels though, to fix
> > > commit b6cc0ba2cbf4 (HID: add support for Apple Magic Keyboards).
> > >
> > > Fn key did not work without this patch on 4.14.76 for me.
> >
> > Right, b6cc0ba2cbf4 has been added to 4.14.75 and is not working
> > because tweaking hid_have_special_driver[] is not required in current
> > kernels anymore.
> >
> > @stable folks, would it be possible to take this patch in the v4.9 and
> > v4.14 trees? It can't go into Linus' tree, but I'd be glad to give my
> > Acked-by for a stable backport.
>
> Sure, if you resend it in a format that I can apply it in, with the text
> saying why this is not applicable to newer kernel versions.
>

Thanks Greg.

Natanel, can you resend this patch with the explanation to stable@ and
Cc me so I can give my Ack?

Cheers,
Benjamin

^ permalink raw reply

* Re: [PATCH v4 8/8] watchdog: stpmic1: add stpmic1 watchdog driver
From: Guenter Roeck @ 2018-10-18 13:34 UTC (permalink / raw)
  To: Pascal PAILLET-LME, dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
In-Reply-To: <1539853324-29051-9-git-send-email-p.paillet@st.com>

On 10/18/2018 02:02 AM, Pascal PAILLET-LME wrote:
> From: pascal paillet <p.paillet@st.com>
> 
> The stpmic1 PMIC embeds a watchdog which is disabled by default. As soon
> as the watchdog is started, it must be refreshed periodically otherwise
> the PMIC goes off.
> 
> Signed-off-by: pascal paillet <p.paillet@st.com>
> ---
> changes in v4:
> * fix stop watchdog function
> * Kconfig: fix grammar issue
> 
>   drivers/watchdog/Kconfig       |  12 ++++
>   drivers/watchdog/Makefile      |   1 +
>   drivers/watchdog/stpmic1_wdt.c | 139 +++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 152 insertions(+)
>   create mode 100644 drivers/watchdog/stpmic1_wdt.c
> 
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 5ea8909..6d2ffef 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -806,6 +806,18 @@ config STM32_WATCHDOG
>   	  To compile this driver as a module, choose M here: the
>   	  module will be called stm32_iwdg.
>   
> +config STPMIC1_WATCHDOG
> +	tristate "STPMIC1 PMIC watchdog support"
> +	depends on MFD_STPMIC1
> +	select WATCHDOG_CORE
> +	help
> +	  Say Y here to include watchdog support embedded into STPMIC1 PMIC.
> +	  If the watchdog timer expires, stpmic1 will shut down all its power
> +	  supplies.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called spmic1_wdt.
> +
>   config UNIPHIER_WATCHDOG
>   	tristate "UniPhier watchdog support"
>   	depends on ARCH_UNIPHIER || COMPILE_TEST
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index bf92e7b..2649cf3 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -217,3 +217,4 @@ obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
>   obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o
>   obj-$(CONFIG_MENZ069_WATCHDOG) += menz69_wdt.o
>   obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o
> +obj-$(CONFIG_STPMIC1_WATCHDOG) += stpmic1_wdt.o
> diff --git a/drivers/watchdog/stpmic1_wdt.c b/drivers/watchdog/stpmic1_wdt.c
> new file mode 100644
> index 0000000..a6cbc27
> --- /dev/null
> +++ b/drivers/watchdog/stpmic1_wdt.c
> @@ -0,0 +1,139 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) STMicroelectronics 2018
> +// Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
> +
> +#include <linux/kernel.h>
> +#include <linux/mfd/stpmic1.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/watchdog.h>
> +
> +/* WATCHDOG CONTROL REGISTER bit */
> +#define WDT_START		BIT(0)
> +#define WDT_PING		BIT(1)
> +#define WDT_START_MASK		BIT(0)
> +#define WDT_PING_MASK		BIT(1)
> +#define WDT_STOP		0
> +
> +#define PMIC_WDT_MIN_TIMEOUT 1
> +#define PMIC_WDT_MAX_TIMEOUT 256
> +#define PMIC_WDT_DEFAULT_TIMEOUT 30
> +
> +static bool nowayout = WATCHDOG_NOWAYOUT;
> +module_param(nowayout, bool, 0);
> +MODULE_PARM_DESC(nowayout,
> +		"Watchdog cannot be stopped once started (default="
> +				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> +
> +struct stpmic1_wdt {
> +	struct stpmic1 *pmic;
> +	struct watchdog_device wdtdev;
> +};
> +
> +static int pmic_wdt_start(struct watchdog_device *wdd)
> +{
> +	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
> +
> +	return regmap_update_bits(wdt->pmic->regmap,
> +				  WCHDG_CR, WDT_START_MASK, WDT_START);
> +}
> +
> +static int pmic_wdt_stop(struct watchdog_device *wdd)
> +{
> +	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
> +
> +	return regmap_update_bits(wdt->pmic->regmap,
> +				  WCHDG_CR, WDT_START_MASK, WDT_STOP);
> +}
> +
> +static int pmic_wdt_ping(struct watchdog_device *wdd)
> +{
> +	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
> +
> +	return regmap_update_bits(wdt->pmic->regmap,
> +				  WCHDG_CR, WDT_PING_MASK, WDT_PING);
> +}
> +
> +static int pmic_wdt_set_timeout(struct watchdog_device *wdd,
> +				unsigned int timeout)
> +{
> +	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
> +
> +	wdd->timeout = timeout;
> +	/* timeout is equal to register value + 1 */
> +	return regmap_write(wdt->pmic->regmap, WCHDG_TIMER_CR, timeout - 1);
> +}
> +
> +static const struct watchdog_info pmic_watchdog_info = {
> +	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
> +	.identity = "STPMIC1 PMIC Watchdog",
> +};
> +
> +static const struct watchdog_ops pmic_watchdog_ops = {
> +	.owner = THIS_MODULE,
> +	.start = pmic_wdt_start,
> +	.stop = pmic_wdt_stop,
> +	.ping = pmic_wdt_ping,
> +	.set_timeout = pmic_wdt_set_timeout,
> +};
> +
> +static int pmic_wdt_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	struct stpmic1 *pmic;
> +	struct stpmic1_wdt *wdt;
> +
> +	if (!pdev->dev.parent)
> +		return -EINVAL;
> +
> +	pmic = dev_get_drvdata(pdev->dev.parent);
> +	if (!pmic)
> +		return -EINVAL;
> +
> +	wdt = devm_kzalloc(&pdev->dev, sizeof(struct stpmic1_wdt), GFP_KERNEL);
> +	if (!wdt)
> +		return -ENOMEM;
> +
> +	wdt->pmic = pmic;
> +
> +	wdt->wdtdev.info = &pmic_watchdog_info;
> +	wdt->wdtdev.ops = &pmic_watchdog_ops;
> +	wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT;
> +	wdt->wdtdev.max_timeout = PMIC_WDT_MAX_TIMEOUT;

Sorry I missed that earlier: You'll also want to set wdtdev.parent.

Thanks,
Guenter

> +
> +	wdt->wdtdev.timeout = PMIC_WDT_DEFAULT_TIMEOUT;
> +	watchdog_init_timeout(&wdt->wdtdev, 0, &pdev->dev);
> +
> +	watchdog_set_nowayout(&wdt->wdtdev, nowayout);
> +	watchdog_set_drvdata(&wdt->wdtdev, wdt);
> +
> +	ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev);
> +	if (ret)
> +		return ret;
> +
> +	dev_dbg(wdt->pmic->dev, "PMIC Watchdog driver probed\n");
> +	return 0;
> +}
> +
> +static const struct of_device_id of_pmic_wdt_match[] = {
> +	{ .compatible = "st,stpmic1-wdt" },
> +	{ },
> +};
> +
> +MODULE_DEVICE_TABLE(of, of_pmic_wdt_match);
> +
> +static struct platform_driver stpmic1_wdt_driver = {
> +	.probe = pmic_wdt_probe,
> +	.driver = {
> +		.name = "stpmic1-wdt",
> +		.of_match_table = of_pmic_wdt_match,
> +	},
> +};
> +module_platform_driver(stpmic1_wdt_driver);
> +
> +MODULE_DESCRIPTION("Watchdog driver for STPMIC1 device");
> +MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
> +MODULE_LICENSE("GPL v2");
> 

^ permalink raw reply

* Re: [PATCH v4 6/8] input: stpmic1: add stpmic1 onkey driver
From: dmitry.torokhov @ 2018-10-18 18:12 UTC (permalink / raw)
  To: Pascal PAILLET-LME, lee.jones
  Cc: robh+dt@kernel.org, mark.rutland@arm.com, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
In-Reply-To: <1539853324-29051-7-git-send-email-p.paillet@st.com>

On Thu, Oct 18, 2018 at 09:02:13AM +0000, Pascal PAILLET-LME wrote:
> From: pascal paillet <p.paillet@st.com>
> 
> The stpmic1 pmic is able to manage an onkey button. This driver exposes
> the stpmic1 onkey as an input device. It can also be configured to
> shut-down the power supplies on a long key-press with an adjustable
> duration.
> 
> Signed-off-by: pascal paillet <p.paillet@st.com>

OK, so this has dependency on linux/mfd/stpmic1.h and therefore I expect
it will go in through Lee's tree.

Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

> ---
> changes in v4:
> * remove remove function
> * merge stpmic1_onkey_dt_params() in probe function
> * suppresse struct pmic_onkey_config
> * rename PONKEY_PU_ACTIVE to PONKEY_PU_INACTIVE
> 
>  drivers/input/misc/Kconfig         |  11 +++
>  drivers/input/misc/Makefile        |   2 +
>  drivers/input/misc/stpmic1_onkey.c | 197 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 210 insertions(+)
>  create mode 100644 drivers/input/misc/stpmic1_onkey.c
> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index ca59a2b..279fb02 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -851,4 +851,15 @@ config INPUT_SC27XX_VIBRA
>  	  To compile this driver as a module, choose M here. The module will
>  	  be called sc27xx_vibra.
>  
> +config INPUT_STPMIC1_ONKEY
> +	tristate "STPMIC1 PMIC Onkey support"
> +	depends on MFD_STPMIC1
> +	help
> +	  Say Y to enable support of onkey embedded into STPMIC1 PMIC. onkey
> +	  can be used to wakeup from low power modes and force a shut-down on
> +	  long press.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called stpmic1_onkey.
> +
>  endif
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 9d0f9d1..1b44202 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -71,6 +71,7 @@ obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
>  obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)	+= sirfsoc-onkey.o
>  obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY)	+= soc_button_array.o
>  obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
> +obj-$(CONFIG_INPUT_STPMIC1_ONKEY)  	+= stpmic1_onkey.o
>  obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON)	+= tps65218-pwrbutton.o
>  obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)	+= twl4030-pwrbutton.o
>  obj-$(CONFIG_INPUT_TWL4030_VIBRA)	+= twl4030-vibra.o
> @@ -81,3 +82,4 @@ obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o
>  obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND)	+= xen-kbdfront.o
>  obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
>  obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR)	+= ideapad_slidebar.o
> +
> diff --git a/drivers/input/misc/stpmic1_onkey.c b/drivers/input/misc/stpmic1_onkey.c
> new file mode 100644
> index 0000000..6a7f08b
> --- /dev/null
> +++ b/drivers/input/misc/stpmic1_onkey.c
> @@ -0,0 +1,197 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) STMicroelectronics 2018
> +// Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
> +
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/mfd/stpmic1.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/regmap.h>
> +
> +/**
> + * struct stpmic1_onkey - OnKey data
> + * @input_dev:		pointer to input device
> + * @irq_falling:	irq that we are hooked on to
> + * @irq_rising:		irq that we are hooked on to
> + */
> +struct stpmic1_onkey {
> +	struct input_dev *input_dev;
> +	int irq_falling;
> +	int irq_rising;
> +};
> +
> +static irqreturn_t onkey_falling_irq(int irq, void *ponkey)
> +{
> +	struct stpmic1_onkey *onkey = ponkey;
> +	struct input_dev *input_dev = onkey->input_dev;
> +
> +	input_report_key(input_dev, KEY_POWER, 1);
> +	pm_wakeup_event(input_dev->dev.parent, 0);
> +	input_sync(input_dev);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t onkey_rising_irq(int irq, void *ponkey)
> +{
> +	struct stpmic1_onkey *onkey = ponkey;
> +	struct input_dev *input_dev = onkey->input_dev;
> +
> +	input_report_key(input_dev, KEY_POWER, 0);
> +	pm_wakeup_event(input_dev->dev.parent, 0);
> +	input_sync(input_dev);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int stpmic1_onkey_probe(struct platform_device *pdev)
> +{
> +	struct stpmic1 *pmic = dev_get_drvdata(pdev->dev.parent);
> +	struct device *dev = &pdev->dev;
> +	struct input_dev *input_dev;
> +	struct stpmic1_onkey *onkey;
> +	unsigned int val, reg = 0;
> +	int error;
> +
> +	onkey = devm_kzalloc(dev, sizeof(*onkey), GFP_KERNEL);
> +	if (!onkey)
> +		return -ENOMEM;
> +
> +	onkey->irq_falling = platform_get_irq_byname(pdev, "onkey-falling");
> +	if (onkey->irq_falling < 0) {
> +		dev_err(dev, "failed: request IRQ onkey-falling %d\n",
> +			onkey->irq_falling);
> +		return onkey->irq_falling;
> +	}
> +
> +	onkey->irq_rising = platform_get_irq_byname(pdev, "onkey-rising");
> +	if (onkey->irq_rising < 0) {
> +		dev_err(dev, "failed: request IRQ onkey-rising %d\n",
> +			onkey->irq_rising);
> +		return onkey->irq_rising;
> +	}
> +
> +	if (!device_property_read_u32(dev, "power-off-time-sec", &val)) {
> +		if ((val > 0) && (val <= 16)) {
> +			dev_dbg(dev, "power-off-time=%d seconds\n", val);
> +			reg |= PONKEY_PWR_OFF;
> +			reg |= ((16 - val) & PONKEY_TURNOFF_TIMER_MASK);
> +		} else {
> +			dev_err(dev, "power-off-time-sec out of range\n");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (device_property_present(dev, "st,onkey-clear-cc-flag"))
> +		reg |= PONKEY_CC_FLAG_CLEAR;
> +
> +	error = regmap_update_bits(pmic->regmap, PKEY_TURNOFF_CR,
> +				   PONKEY_TURNOFF_MASK, reg);
> +	if (error) {
> +		dev_err(dev, "PKEY_TURNOFF_CR write failed: %d\n", error);
> +		return error;
> +	}
> +
> +	if (device_property_present(dev, "st,onkey-pu-inactive")) {
> +		error = regmap_update_bits(pmic->regmap, PADS_PULL_CR,
> +					   PONKEY_PU_INACTIVE,
> +					   PONKEY_PU_INACTIVE);
> +		if (error) {
> +			dev_err(dev, "ONKEY Pads configuration failed: %d\n", error);
> +			return error;
> +		}
> +	}
> +
> +	input_dev = devm_input_allocate_device(dev);
> +	if (!input_dev) {
> +		dev_err(dev, "Can't allocate Pwr Onkey Input Device\n");
> +		return -ENOMEM;
> +	}
> +
> +	input_dev->name = "pmic_onkey";
> +	input_dev->phys = "pmic_onkey/input0";
> +
> +	input_set_capability(input_dev, EV_KEY, KEY_POWER);
> +
> +	onkey->input_dev = input_dev;
> +
> +	/* interrupt is nested in a thread */
> +	error = devm_request_threaded_irq(dev, onkey->irq_falling, NULL,
> +					  onkey_falling_irq, IRQF_ONESHOT,
> +					  dev_name(dev), onkey);
> +	if (error) {
> +		dev_err(dev, "Can't get IRQ Onkey Falling: %d\n", error);
> +		return error;
> +	}
> +
> +	error = devm_request_threaded_irq(dev, onkey->irq_rising, NULL,
> +					  onkey_rising_irq, IRQF_ONESHOT,
> +					  dev_name(dev), onkey);
> +	if (error) {
> +		dev_err(dev, "Can't get IRQ Onkey Rising: %d\n", error);
> +		return error;
> +	}
> +
> +	error = input_register_device(input_dev);
> +	if (error) {
> +		dev_err(dev, "Can't register power button: %d\n", error);
> +		return error;
> +	}
> +
> +	platform_set_drvdata(pdev, onkey);
> +	device_init_wakeup(dev, true);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused stpmic1_onkey_suspend(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
> +
> +	if (device_may_wakeup(dev)) {
> +		enable_irq_wake(onkey->irq_falling);
> +		enable_irq_wake(onkey->irq_rising);
> +	}
> +	return 0;
> +}
> +
> +static int __maybe_unused stpmic1_onkey_resume(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
> +
> +	if (device_may_wakeup(dev)) {
> +		disable_irq_wake(onkey->irq_falling);
> +		disable_irq_wake(onkey->irq_rising);
> +	}
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(stpmic1_onkey_pm,
> +			 stpmic1_onkey_suspend,
> +			 stpmic1_onkey_resume);
> +
> +static const struct of_device_id of_stpmic1_onkey_match[] = {
> +	{ .compatible = "st,stpmic1-onkey" },
> +	{ },
> +};
> +
> +MODULE_DEVICE_TABLE(of, of_stpmic1_onkey_match);
> +
> +static struct platform_driver stpmic1_onkey_driver = {
> +	.probe	= stpmic1_onkey_probe,
> +	.driver	= {
> +		.name	= "stpmic1_onkey",
> +		.of_match_table = of_match_ptr(of_stpmic1_onkey_match),
> +		.pm	= &stpmic1_onkey_pm,
> +	},
> +};
> +module_platform_driver(stpmic1_onkey_driver);
> +
> +MODULE_DESCRIPTION("Onkey driver for STPMIC1");
> +MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.9.1

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v4 1/8] dt-bindings: mfd: document stpmic1
From: Rob Herring @ 2018-10-18 18:47 UTC (permalink / raw)
  Cc: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	broonie@kernel.org, wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com,
	Pascal PAILLET-LME
In-Reply-To: <1539853324-29051-2-git-send-email-p.paillet@st.com>

On Thu, 18 Oct 2018 09:02:11 +0000, Pascal PAILLET-LME wrote:
> From: pascal paillet <p.paillet@st.com>
> 
> stpmic1 is a pmic from STMicroelectronics. The STPMIC1 integrates 10
> regulators , 3 switches, a watchdog and an input for a power on key.
> 
> Signed-off-by: pascal paillet <p.paillet@st.com>
> ---
> changes in v4:
> * remove interrupt-parent description
> * pmic1@33 renamed to pmic@33
> * fix indentation
> 
>  .../devicetree/bindings/mfd/st,stpmic1.txt         | 131 +++++++++++++++++++++
>  include/dt-bindings/mfd/st,stpmic1.h               |  46 ++++++++
>  2 files changed, 177 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/st,stpmic1.txt
>  create mode 100644 include/dt-bindings/mfd/st,stpmic1.h
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* Re: [PATCH] Input: uinput - fix Spectre v1 vulnerability
From: Alan Cox @ 2018-10-18 19:43 UTC (permalink / raw)
  To: Gustavo A. R. Silva; +Cc: Dmitry Torokhov, linux-input, linux-kernel
In-Reply-To: <2856297d-9af0-e005-f926-e9596d437fad@embeddedor.com>

On Tue, 16 Oct 2018 20:12:43 +0200
"Gustavo A. R. Silva" <gustavo@embeddedor.com> wrote:

> On 10/16/18 8:09 PM, Dmitry Torokhov wrote:
> 
> > 
> > /dev/uinput   
> 
> I've got it. This explains it all. :)
> 
> > must be 0600, or accessible to equally privileged user, or you'll be opening your system to much mischief.

Still a correct change.

CAP_SYS_RAWIO is not the same as being root, especially in a container.

Alan

^ permalink raw reply

* Re: [PATCH] Input: uinput - fix Spectre v1 vulnerability
From: Dmitry Torokhov @ 2018-10-18 20:07 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: Gustavo A. R. Silva, linux-input@vger.kernel.org, lkml
In-Reply-To: <20181018204344.4c135203@alans-desktop>

On Thu, Oct 18, 2018 at 12:43 PM Alan Cox <gnomes@lxorguk.ukuu.org.uk> wrote:
>
> On Tue, 16 Oct 2018 20:12:43 +0200
> "Gustavo A. R. Silva" <gustavo@embeddedor.com> wrote:
>
> > On 10/16/18 8:09 PM, Dmitry Torokhov wrote:
> >
> > >
> > > /dev/uinput
> >
> > I've got it. This explains it all. :)
> >
> > > must be 0600, or accessible to equally privileged user, or you'll be opening your system to much mischief.
>
> Still a correct change.
>
> CAP_SYS_RAWIO is not the same as being root, especially in a container.

Giving access to uinput in an unprivileged container is nutty as well.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v2 1/8] dt-bindings: input: touchscreen: sx8654: add reset-gpio property
From: Rob Herring @ 2018-10-18 20:34 UTC (permalink / raw)
  Cc: dmitry.torokhov, robh+dt, mark.rutland, linux-input, devicetree,
	linux-kernel, Richard Leitner
In-Reply-To: <20181017125116.20077-2-richard.leitner@skidata.com>

On Wed, 17 Oct 2018 14:51:09 +0200, Richard Leitner wrote:
> Document the reset-gpio property for the sx8654 touchscreen controller
> driver.
> 
> Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
> ---
>  Documentation/devicetree/bindings/input/touchscreen/sx8654.txt | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* Re: [PATCH v2 3/8] dt-bindings: input: touchscreen: sx8654: add compatible models
From: Rob Herring @ 2018-10-18 20:35 UTC (permalink / raw)
  Cc: dmitry.torokhov, robh+dt, mark.rutland, linux-input, devicetree,
	linux-kernel, Richard Leitner
In-Reply-To: <20181017125116.20077-4-richard.leitner@skidata.com>

On Wed, 17 Oct 2018 14:51:11 +0200, Richard Leitner wrote:
> As the sx865[456] share the same datasheet and differ only in the
> presence of a "capacitive proximity detection circuit" and a "haptics
> motor driver for LRA/ERM" add them to the compatbiles. As the driver
> doesn't implement these features it should be no problem.
> 
> Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
> ---
>  Documentation/devicetree/bindings/input/touchscreen/sx8654.txt | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* Re: [PATCH v2 5/8] dt-bindings: input: touchscreen: sx8654: add sx8650 to comatibles
From: Rob Herring @ 2018-10-18 20:35 UTC (permalink / raw)
  Cc: dmitry.torokhov, robh+dt, mark.rutland, linux-input, devicetree,
	linux-kernel, Richard Leitner
In-Reply-To: <20181017125116.20077-6-richard.leitner@skidata.com>

On Wed, 17 Oct 2018 14:51:13 +0200, Richard Leitner wrote:
> As the sx8650 is quite similar to the sx8654 support for it will be
> added in the driver. Therefore add it to the compatibles.
> 
> Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
> ---
>  Documentation/devicetree/bindings/input/touchscreen/sx8654.txt | 1 +
>  1 file changed, 1 insertion(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* Re: [PATCH] Input: pm8941-pwrkey - Add pms405 pwrkey support
From: Dmitry Torokhov @ 2018-10-19  0:01 UTC (permalink / raw)
  To: Vinod, Rob Herring
  Cc: Bjorn Andersson, Mark Rutland, linux-input, devicetree,
	linux-kernel
In-Reply-To: <20181018052437.GW2400@vkoul-mobl>

On Thu, Oct 18, 2018 at 10:54:37AM +0530, Vinod wrote:
> On 19-09-18, 18:49, Bjorn Andersson wrote:
> > From: Vinod Koul <vkoul@kernel.org>
> > 
> > Update the binding and driver for pms405 pwrkey.
> 
> Rob, Dmitry
> 
> Gentle reminder for this patch...
> 
> > Signed-off-by: Vinod Koul <vkoul@kernel.org>
> > Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> > ---
> >  Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt | 1 +
> >  drivers/input/misc/pm8941-pwrkey.c                             | 1 +
> >  2 files changed, 2 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt
> > index 34ab5763f494..736fba3bad54 100644
> > --- a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt
> > +++ b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt
> > @@ -8,6 +8,7 @@ PROPERTIES
> >  	Definition: must be one of:
> >  		    "qcom,pm8941-pwrkey"
> >  		    "qcom,pm8941-resin"
> > +		    "qcom,pms405-pwrkey"
> >  
> >  - reg:
> >  	Usage: required
> > diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c
> > index 48153e0ca19a..fccf63263c1c 100644
> > --- a/drivers/input/misc/pm8941-pwrkey.c
> > +++ b/drivers/input/misc/pm8941-pwrkey.c
> > @@ -317,6 +317,7 @@ static const struct pm8941_data resin_data = {
> >  static const struct of_device_id pm8941_pwr_key_id_table[] = {
> >  	{ .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
> >  	{ .compatible = "qcom,pm8941-resin", .data = &resin_data },
> > +	{ .compatible = "qcom,pms405-pwrkey", .data = &pwrkey_data },

I am sure I asked this question before (in context of a different
driver), but why do we need this compatible if we already have
pm8941-pwrkey compatible? Isn't pms405-pwrkey compatible with
pm8941-pwrkey as far as power key block goes? In which cases do we need
new compatibles and when can we reuse existing ones? Rob?

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] Input: synaptics - avoid using uninitialized variable when probing
From: Peter Hutterer @ 2018-10-19  5:46 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, Benjamin Tissoires, linux-kernel
In-Reply-To: <20181017001443.GA232819@dtor-ws>

On Tue, Oct 16, 2018 at 05:14:43PM -0700, Dmitry Torokhov wrote:
> synaptics_detect() does not check whether sending commands to the
> device succeeds and instead relies on getting unique data from the
> device. Let's make sure we seed entire buffer with zeroes to make sure
> we not use garbage on stack that just happen to be 0x47.
> 
> Reported-by: syzbot+13cb3b01d0784e4ffc3f@syzkaller.appspotmail.com
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

doh, was just about to send out the same patch.

Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>

Cheers,
   Peter

> ---
>  drivers/input/mouse/synaptics.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
> index 55d33500d55e..5e85f3cca867 100644
> --- a/drivers/input/mouse/synaptics.c
> +++ b/drivers/input/mouse/synaptics.c
> @@ -99,9 +99,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, u8 mode)
>  int synaptics_detect(struct psmouse *psmouse, bool set_properties)
>  {
>  	struct ps2dev *ps2dev = &psmouse->ps2dev;
> -	u8 param[4];
> -
> -	param[0] = 0;
> +	u8 param[4] = { 0 };
>  
>  	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
>  	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> -- 
> 2.19.1.331.ge82ca0e54c-goog
> 
> 
> -- 
> Dmitry

^ permalink raw reply

* Fw: PROBLEM: Keyboard not responding after resuming from suspend/hibernate
From: Numan Demirdöğen @ 2018-10-19  7:20 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: peterz, mingo, linux-kernel, linux-input
In-Reply-To: <20180831215121.1b1f66bf@korsan.localdomain>

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

On Fri, 31 Aug 2018 21:53:11 +0300
Numan Demirdöğen <if.gnu.linux@gmail.com> wrote:

>If I put laptop to suspend or hibernate by closing lid, power
>manager or any other method and then I resume/wake up laptop, keyboard
>is not responding. My laptop is a Sony Vaio VPCEH2F1E. 
>
>Steps to produce bug:
>1. Boot
>2. Put laptop to sleep
>3. Resume
>
>What I expect to happen: Keyboard responds to key press.
>What happens: Keyboard does not respond but mouse and trackball are
>working.
>
>git bisect point 9d659ae14b545c4296e812c70493bfdc999b5c1c as the first
>bad commit.
>
>Bad commit link:
>https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?id=9d659ae14b545c4296e812c70493bfdc999b5c1c
>
> Link to actual bug report:
>https://bugzilla.kernel.org/show_bug.cgi?id=195471
>
>awk -f ver_linux
>Linux korsan 4.18.5-arch1-1-ARCH #1 SMP PREEMPT Fri Aug 24 12:48:58
>UTC 2018 x86_64 GNU/Linux GNU C               	8.2.0
>GNU Make            	4.2.1
>Binutils            	2.31.1
>Util-linux          	2.32.1
>Mount               	2.32.1
>Module-init-tools   	25
>E2fsprogs           	1.44.4
>Jfsutils            	1.1.15
>Reiserfsprogs       	3.6.27
>Xfsprogs            	4.17.0
>Pcmciautils         	018
>Linux C Library     	2.28
>Dynamic linker (ldd)	2.28
>Linux C++ Library   	6.0.25
>Procps              	3.3.15
>Kbd                 	2.0.4
>Console-tools       	2.0.4
>Sh-utils            	8.29
>Udev                	239
>Wireless-tools      	30
>Modules Loaded      	ac agpgart ahci arc4 ath ath3k ath9k
>ath9k_common ath9k_hw atkbd battery bluetooth bpfilter ccm cdrom
>cfg80211 coretemp crc16 crc32c_generic crc32c_intel crc32_pclmul
>crct10dif_pclmul cryptd drm drm_kms_helper ecdh_generic ehci_hcd
>ehci_pci evdev ext4 fb_sys_fops fscrypto fuse ghash_clmulni_intel
>gpio_ich hid hid_generic i2c_algo_bit i2c_i801 i8042 i915 input_leds
>intel_cstate intel_gtt intel_powerclamp intel_rapl intel_rapl_perf
>intel_uncore iptable_filter iptable_mangle iptable_nat ip_tables
>irqbypass iTCO_vendor_support iTCO_wdt jbd2 kvm kvm_intel led_class
>libahci libata libcrc32c libps2 lpc_ich mac80211 mac_hid mbcache mei
>mei_me mousedev msr nf_conntrack nf_conntrack_ipv4 nf_defrag_ipv4
>nf_nat nf_nat_ipv4 pcc_cpufreq psmouse rfkill rtc_cmos scsi_mod sd_mod
>serio serio_raw snd snd_hda_codec snd_hda_codec_conexant
>snd_hda_codec_generic snd_hda_codec_hdmi snd_hda_core snd_hda_intel
>snd_hwdep snd_pcm snd_timer sony_laptop soundcore sr_mod syscopyarea
>sysfillrect sysimgblt usb_common usbcore usbhid x86_pkg_temp_thermal
>x_tables
>
>dmesg | grep i8042
>[    0.574078] i8042: PNP: PS/2 Controller [PNP0303:PS2K,PNP0f13:PS2M]
>at 0x60,0x64 irq 1,12 [    0.575936] serio: i8042 KBD port at
>0x60,0x64 irq 1 [    0.576143] serio: i8042 AUX port at 0x60,0x64 irq
>12 [    0.618880] input: AT Translated Set 2 keyboard
>as /devices/platform/i8042/serio0/input/input3 [   11.248435] input:
>AlpsPS/2 ALPS GlidePoint as /devices/platform/i8042/serio1/input/input5
>
>cat /proc/interrupts 
>           CPU0       CPU1       CPU2       CPU3       
>  0:          8          0          0          0   IO-APIC
> 2-edge      timer 1:          0          0          0      10286
> IO-APIC   1-edge      i8042 8:          0          0
> 0          1   IO-APIC   8-edge      rtc0 9:          0
> 9479          0          0   IO-APIC   9-fasteoi   acpi 12:
> 0          0     370114          0   IO-APIC  12-edge      i8042
> 16:     197457          0          0          0   IO-APIC
> 16-fasteoi   ehci_hcd:usb1, ath9k 19:          0          0
> 0          0   IO-APIC  19-fasteoi   i801_smbus 23:
> 0          0      71055          0   IO-APIC  23-fasteoi
> ehci_hcd:usb2 24:          0      74549          0          0
> PCI-MSI 512000-edge      ahci[0000:00:1f.2] 25:          0
> 14          0          0   PCI-MSI 360448-edge      mei_me
> 26:          0          0     138870          0   PCI-MSI
> 32768-edge      i915 27:          0          0          0
> 330   PCI-MSI 442368-edge      snd_hda_intel:card0
>NMI:         24         22         25         21   Non-maskable
>interrupts LOC:     534734     446934     603337     440320   Local
>timer interrupts SPU:          0          0          0          0
>Spurious interrupts PMI:         24         22         25         21
>Performance monitoring interrupts IWI:         26         12
>43115         22   IRQ work interrupts RTR:          0
>0          0          0   APIC ICR read retries RES:      95282
>76970      60242      46409   Rescheduling interrupts CAL:
>66746      75300      70554      69119   Function call interrupts
>TLB:      50929      54528      51413      48017   TLB shootdowns
>TRM:          0          0          0          0   Thermal event
>interrupts THR:          0          0          0          0
>Threshold APIC interrupts DFR:          0          0
>0          0   Deferred Error APIC interrupts MCE:          0
>0          0          0   Machine check exceptions MCP:
>18         19         19         19   Machine check polls
>HYP:          0          0          0          0   Hypervisor callback
>interrupts HRE:          0          0          0          0   Hyper-V
>reenlightenment interrupts HVS:          0          0
>0          0   Hyper-V stimer0 interrupts ERR:          0
>MIS:          0 PIN:          0          0          0          0
>Posted-interrupt notification event NPI:          0
>0          0          0   Nested posted-interrupt event PIW:
>0          0          0          0   Posted-interrupt wakeup event
>
>P.S: My native language is not English.
>

Hi,

I am forwarding this e-mail which describes a problem related to
suspend/hibernate at the advise of Pavel Machek.

-- 
Numan Demirdöğen

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH] Input: pm8941-pwrkey - Add pms405 pwrkey support
From: Vinod @ 2018-10-19  9:05 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rob Herring, Bjorn Andersson, Mark Rutland, linux-input,
	devicetree, linux-kernel
In-Reply-To: <20181019000116.GD210757@dtor-ws>

On 18-10-18, 17:01, Dmitry Torokhov wrote:
> On Thu, Oct 18, 2018 at 10:54:37AM +0530, Vinod wrote:
> > On 19-09-18, 18:49, Bjorn Andersson wrote:
> > > From: Vinod Koul <vkoul@kernel.org>
> > > 
> > > Update the binding and driver for pms405 pwrkey.
> > 
> > Rob, Dmitry
> > 
> > Gentle reminder for this patch...
> > 
> > > Signed-off-by: Vinod Koul <vkoul@kernel.org>
> > > Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> > > ---
> > >  Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt | 1 +
> > >  drivers/input/misc/pm8941-pwrkey.c                             | 1 +
> > >  2 files changed, 2 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt
> > > index 34ab5763f494..736fba3bad54 100644
> > > --- a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt
> > > +++ b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt
> > > @@ -8,6 +8,7 @@ PROPERTIES
> > >  	Definition: must be one of:
> > >  		    "qcom,pm8941-pwrkey"
> > >  		    "qcom,pm8941-resin"
> > > +		    "qcom,pms405-pwrkey"
> > >  
> > >  - reg:
> > >  	Usage: required
> > > diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c
> > > index 48153e0ca19a..fccf63263c1c 100644
> > > --- a/drivers/input/misc/pm8941-pwrkey.c
> > > +++ b/drivers/input/misc/pm8941-pwrkey.c
> > > @@ -317,6 +317,7 @@ static const struct pm8941_data resin_data = {
> > >  static const struct of_device_id pm8941_pwr_key_id_table[] = {
> > >  	{ .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
> > >  	{ .compatible = "qcom,pm8941-resin", .data = &resin_data },
> > > +	{ .compatible = "qcom,pms405-pwrkey", .data = &pwrkey_data },
> 
> I am sure I asked this question before (in context of a different
> driver), but why do we need this compatible if we already have
> pm8941-pwrkey compatible? Isn't pms405-pwrkey compatible with
> pm8941-pwrkey as far as power key block goes? In which cases do we need
> new compatibles and when can we reuse existing ones? Rob?

Relooking I do think that reuse of pm8941-pwrkey is entirely feasible,
thanks for the suggestion. We can drop this and I will update DTS

-- 
~Vinod

^ permalink raw reply

* Re: [PATCH v4 4/8] regulator: stpmic1: add stpmic1 regulator driver
From: Mark Brown @ 2018-10-19 11:50 UTC (permalink / raw)
  To: Pascal PAILLET-LME
  Cc: dmitry.torokhov@gmail.com, robh+dt@kernel.org,
	mark.rutland@arm.com, lee.jones@linaro.org, lgirdwood@gmail.com,
	wim@linux-watchdog.org, linux@roeck-us.net,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
	benjamin.gaignard@linaro.org, eballetbo@gmail.com
In-Reply-To: <1539853324-29051-5-git-send-email-p.paillet@st.com>

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

On Thu, Oct 18, 2018 at 09:02:12AM +0000, Pascal PAILLET-LME wrote:

> +	for (i = 0; i < ARRAY_SIZE(stpmic1_regulator_cfgs); i++) {
> +		/* Parse DT & find regulators to register */
> +		init_data = stpmic1_regulators_matches[i].init_data;
> +		if (init_data)
> +			init_data->regulator_init = &stpmic1_regulator_parse_dt;
> +
> +		rdev = stpmic1_regulator_register(pdev, i, init_data, regul);
> +		if (IS_ERR(rdev))
> +			return PTR_ERR(rdev);

This looks mostly good, the only big thing is this - the default is to
just unconditionally register all the regulators that exist rather than
only those that are configured on that particular platform.  This is a
bit simpler and means that all the readback of the configuration for the
unconfigured regulators is available for diagnostics.  Is there a reason
not to do that?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH] platform/x86: touchscreen_dmi: Add info for the Trekstor Primetab T13B tablet
From: Andy Shevchenko @ 2018-10-19 12:48 UTC (permalink / raw)
  To: marian.cepok
  Cc: Hans de Goede, Darren Hart, Andy Shevchenko, linux-input,
	Platform Driver, Linux Kernel Mailing List
In-Reply-To: <20181008072505.GA8334@mcepok-pc>

On Mon, Oct 8, 2018 at 10:25 AM Marian Cepok <marian.cepok@gmail.com> wrote:
>
> Add touchscreen info for the Trekstor Primetab T13B tablet.
>

Pushed to my review and testing queue, thanks!

> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
> Signed-off-by: Marian Cepok <marian.cepok@gmail.com>
> ---
>  drivers/platform/x86/touchscreen_dmi.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
>
> diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
> index cb204f973491..c07954f0efc6 100644
> --- a/drivers/platform/x86/touchscreen_dmi.c
> +++ b/drivers/platform/x86/touchscreen_dmi.c
> @@ -381,6 +381,22 @@ static const struct ts_dmi_data trekstor_primebook_c13_data = {
>         .properties     = trekstor_primebook_c13_props,
>  };
>
> +static const struct property_entry trekstor_primetab_t13b_props[] = {
> +       PROPERTY_ENTRY_U32("touchscreen-size-x", 2500),
> +       PROPERTY_ENTRY_U32("touchscreen-size-y", 1900),
> +       PROPERTY_ENTRY_STRING("firmware-name",
> +                             "gsl1680-trekstor-primetab-t13b.fw"),
> +       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
> +       PROPERTY_ENTRY_BOOL("silead,home-button"),
> +       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
> +       { }
> +};
> +
> +static const struct ts_dmi_data trekstor_primetab_t13b_data = {
> +       .acpi_name  = "MSSL1680:00",
> +       .properties = trekstor_primetab_t13b_props,
> +};
> +
>  static const struct property_entry trekstor_surftab_twin_10_1_props[] = {
>         PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
>         PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
> @@ -648,6 +664,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
>                         DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
>                 },
>         },
> +       {
> +               /* Trekstor Primetab T13B */
> +               .driver_data = (void *)&trekstor_primetab_t13b_data,
> +               .matches = {
> +                       DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
> +                       DMI_MATCH(DMI_PRODUCT_NAME, "Primetab T13B"),
> +               },
> +       },
>         {
>                 /* TrekStor SurfTab twin 10.1 ST10432-8 */
>                 .driver_data = (void *)&trekstor_surftab_twin_10_1_data,
> --
> 2.17.1
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* [git pull] Input updates for v4.19-rc8
From: Dmitry Torokhov @ 2018-10-19 17:45 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, linux-input, Linus Torvalds

Hi Greg,

Please pull from:

	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive updates for the input subsystem. Just an addition to elan
touchpad driver ACPI table.

Changelog:
---------

Mikhail Nikiforov (1):
      Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15IGM

Diffstat:
--------

 drivers/input/mouse/elan_i2c_core.c | 1 +
 1 file changed, 1 insertion(+)

Thanks.


-- 
Dmitry

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox