LKML Archive on lore.kernel.org
 help / color / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
						download: 
* Re: spmi: pmic-arb: Always allocate ppid_to_apid table
  @ 2017-07-09 11:31 99% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2017-07-09 11:31 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Greg Kroah-Hartman, linux-kernel, linux-arm-msm,
	linux-arm-kernel, Abhijeet Dharmapurikar, Kiran Gunda

On Dienstag, 27. Juni 2017 04:17:46 CEST Stephen Boyd wrote:
> After commit 7f1d4e58dabb ("spmi: pmic-arb: optimize table
> lookups") we always need the ppid_to_apid table regardless of the
> version of pmic arbiter we have. Otherwise, we will try to deref
> the array when we don't allocate it on v2 hardware like the
> msm8974 SoCs.
> 
> Cc: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
> Cc: Kiran Gunda <kgunda@codeaurora.org>
> Fixes: 7f1d4e58dabb ("spmi: pmic-arb: optimize table lookups")
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> Reviewed-by: Kiran Gunda <kgunda@codeaurora.org>
> ---
>  drivers/spmi/spmi-pmic-arb.c | 17 +++++++----------
>  1 file changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> index 2afe3597982e..f4b7a98a7913 100644
> --- a/drivers/spmi/spmi-pmic-arb.c
> +++ b/drivers/spmi/spmi-pmic-arb.c
> @@ -134,7 +134,6 @@ struct apid_data {
>   * @spmic:		SPMI controller object
>   * @ver_ops:		version dependent operations.
>   * @ppid_to_apid	in-memory copy of PPID -> channel (APID) mapping table.
> - *			v2 only.
>   */
>  struct spmi_pmic_arb {
>  	void __iomem		*rd_base;
> @@ -1016,6 +1015,13 @@ static int spmi_pmic_arb_probe(struct platform_device
> *pdev) goto err_put_ctrl;
>  	}
> 
> +	pa->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
> +					sizeof(*pa->ppid_to_apid), GFP_KERNEL);
> +	if (!pa->ppid_to_apid) {
> +		err = -ENOMEM;
> +		goto err_put_ctrl;
> +	}
> +
>  	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
> 
>  	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
> @@ -1048,15 +1054,6 @@ static int spmi_pmic_arb_probe(struct platform_device
> *pdev) err = PTR_ERR(pa->wr_base);
>  			goto err_put_ctrl;
>  		}
> -
> -		pa->ppid_to_apid = devm_kcalloc(&ctrl->dev,
> -						PMIC_ARB_MAX_PPID,
> -						sizeof(*pa->ppid_to_apid),
> -						GFP_KERNEL);
> -		if (!pa->ppid_to_apid) {
> -			err = -ENOMEM;
> -			goto err_put_ctrl;
> -		}
>  	}
> 
>  	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",

Tested-by: Luca Weiss <luca@z3ntu.xyz>

^ permalink raw reply	[relevance 99%]

* Re: [v2] mmc: sdhci-msm: Optionally wait for signal level changes
  @ 2017-11-21 19:38 99% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2017-11-21 19:38 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Adrian Hunter, Ulf Hansson, linux-mmc, linux-kernel,
	linux-arm-msm, Stephen Boyd, Sahitya Tummala, Vijay Viswanath

On Montag, 20. November 2017 20:56:47 CET Bjorn Andersson wrote:
> Not all instances of the SDCC core supports changing signal voltage and
> as such will not generate a power interrupt when the software attempts
> to change the voltage. This results in probing the eMMC on some devices
> to take over 2 minutes.
> 
> Check that the SWITCHABLE_SIGNALING_VOLTAGE bit in MCI_GENERICS is set
> before waiting for the power interrupt.
> 
> Cc: Sahitya Tummala <stummala@codeaurora.org>
> Cc: Vijay Viswanath <vviswana@codeaurora.org>
> Fixes: c0309b3803fe ("mmc: sdhci-msm: Add sdhci msm register write APIs
> which wait for pwr irq") Signed-off-by: Bjorn Andersson
> <bjorn.andersson@linaro.org>
Tested-by: Luca Weiss <luca@z3ntu.xyz>
> ---
> 
> The offending patch is part of your v4.15 pull request, so please pick
> this up for the -rcs.
> 
> Changes since v1:
> - Fixed spelling of swichable...
> 
>  drivers/mmc/host/sdhci-msm.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index 3fb7d2eec93f..c283291db705 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -29,6 +29,9 @@
>  #define CORE_VERSION_MAJOR_MASK		(0xf << CORE_VERSION_MAJOR_SHIFT)
>  #define CORE_VERSION_MINOR_MASK		0xff
> 
> +#define CORE_MCI_GENERICS		0x70
> +#define SWITCHABLE_SIGNALING_VOLTAGE	BIT(29)
> +
>  #define CORE_HC_MODE		0x78
>  #define HC_MODE_EN		0x1
>  #define CORE_POWER		0x0
> @@ -1028,11 +1031,22 @@ static void sdhci_msm_check_power_status(struct
> sdhci_host *host, u32 req_type) struct sdhci_pltfm_host *pltfm_host =
> sdhci_priv(host);
>  	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
>  	bool done = false;
> +	u32 val;
> 
>  	pr_debug("%s: %s: request %d curr_pwr_state %x curr_io_level %x\n",
>  			mmc_hostname(host->mmc), __func__, req_type,
>  			msm_host->curr_pwr_state, msm_host->curr_io_level);
> 
> +	/*
> +	 * The power interrupt will not be generated for signal voltage
> +	 * switches if SWITCHABLE_SIGNALING_VOLTAGE in MCI_GENERICS is not set.
> +	 */
> +	val = readl(msm_host->core_mem + CORE_MCI_GENERICS);
> +	if ((req_type & REQ_IO_HIGH || req_type & REQ_IO_LOW) &&
> +	    !(val & SWITCHABLE_SIGNALING_VOLTAGE)) {
> +		return;
> +	}
> +
>  	/*
>  	 * The IRQ for request type IO High/LOW will be generated when -
>  	 * there is a state change in 1.8V enable bit (bit 3) of

^ permalink raw reply	[relevance 99%]

* [PATCH] drm/msm: Fix NULL pointer dereference
@ 2019-03-02 12:35 77% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-03-02 12:35 UTC (permalink / raw)
  Cc: Luca Weiss, Rob Clark, David Airlie, Daniel Vetter,
	open list:DRM DRIVER FOR MSM ADRENO GPU,
	open list:DRM DRIVER FOR MSM ADRENO GPU,
	open list:DRM DRIVER FOR MSM ADRENO GPU, open list

[    3.707412] Unable to handle kernel NULL pointer dereference at virtual address 0000009c
[    3.714511] pgd = (ptrval)
[    3.722742] [0000009c] *pgd=00000000
[    3.725238] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[    3.728968] Modules linked in:
[    3.734265] CPU: 3 PID: 112 Comm: kworker/3:2 Tainted: G        W         5.0.0-rc7-00183-g06a1c31df9eb #4
[    3.737142] Hardware name: Generic DT based system
[    3.746778] Workqueue: events deferred_probe_work_func
[    3.751542] PC is at msm_gem_map_vma+0x3c/0xac
[    3.756669] LR is at msm_gem_get_and_pin_iova+0xd8/0x134
[    3.761086] pc : [<c07d3b7c>]    lr : [<c07d14f8>]    psr: 60000013
[    3.766560] sp : ee297be8  ip : ed9ab1c0  fp : ed93b800
[    3.772546] r10: ee35e180  r9 : 00000000  r8 : ee297c80
[    3.777752] r7 : 00000000  r6 : 7c100000  r5 : 00000000  r4 : ee35e180
[    3.782968] r3 : 00000001  r2 : 00000003  r1 : ee35e180  r0 : 00000000
[    3.789562] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[    3.796079] Control: 10c5787d  Table: 2e3a806a  DAC: 00000051
[    3.803282] Process kworker/3:2 (pid: 112, stack limit = 0x(ptrval))
[    3.809006] Stack: (0xee297be8 to 0xee298000)
[    3.815445] 7be0:                   00000000 c1108c48 eda8c000 00000003 eda8c0fc c1108c48
[    3.819715] 7c00: eda8c000 00000003 eda8c0fc c07d14f8 00000001 c07d1100 7c100000 00000000
[    3.827873] 7c20: eda8c000 bb7ffb78 00000000 eda8c000 00000000 00000000 c0c8b1d4 ee3bfa00
[    3.836037] 7c40: ee3b9800 c07d1684 00000000 c1108c48 ee0d7810 ee3b9800 c0c8b1d4 c07d222c
[    3.844193] 7c60: ee3bfd84 ee297c80 00000000 c0b1d5b0 ee3bfc40 c07dcfd8 ee3bfd84 ee297c80
[    3.852357] 7c80: 0000006d ee3bfc40 ee0d7810 bb7ffb78 c0c8b1d4 00000000 ee3bfc40 c07ddb48
[    3.860516] 7ca0: 00002004 c0eba384 ee3bfc40 c079eba0 ee3bd040 ee3b9800 00000001 ed93b800
[    3.868673] 7cc0: ed9aa100 c07db7e8 ee3bf240 ed9a6500 00000001 ee3b9800 ee3bf2d4 c07a0a30
[    3.876834] 7ce0: ed93b800 7d100000 c1108c48 ee0d7610 ee3b9800 ed93b800 c1108c48 00000000
[    3.884991] 7d00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    3.893151] 7d20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bb7ffb78
[    3.901310] 7d40: c12113c4 ed93b800 ee3b9800 c1108c48 ee9eec10 00000000 ed93b800 7d100000
[    3.909472] 7d60: eff7b000 c07cf748 7d100000 00000000 c0e9a350 c0b1d5b0 c12113c4 c0961e40
[    3.917633] 7d80: c12113c4 40000113 eeff4bec c0ebe004 00000019 c0b1d230 ee9eeda8 60000113
[    3.925791] 7da0: ee35d300 ee9eeda8 c07ce260 bb7ffb78 c07ce260 ee35d2c0 00000028 00000002
[    3.933950] 7dc0: eeb76280 c118f884 ee0be640 c11c6128 c07ce260 c07ea4ac 00000000 c0962b48
[    3.942108] 7de0: c118f868 00000001 c0ebbc98 ee35d2c0 00000000 eeb76280 00000000 c118f87c
[    3.950270] 7e00: ee35d2c0 00000000 c11c63e0 c118f694 00000019 c07ea5d0 ee0d7810 00000000
[    3.958430] 7e20: c118f694 00000000 00000000 c07f2b0c c120f55c ee0d7810 c120f560 00000000
[    3.966590] 7e40: 00000000 c07f08c4 c07f0e8c ee0d7810 c11ba3d0 ee0d7810 c118f694 c07f0e8c
[    3.974748] 7e60: c1108c48 00000001 c0ebc3cc c11c63f8 c11ba3d0 c07f0c08 00000001 c07f2f8c
[    3.982908] 7e80: c118f694 00000000 ee297ed4 c07f0e8c c1108c48 00000001 c0ebc3cc c11c63f8
[    3.991068] 7ea0: c11ba3d0 c07ee8a0 c11ba3d0 ee82686c ee0baf38 bb7ffb78 ee0d7810 ee0d7810
[    3.999227] 7ec0: c1108c48 ee0d7844 c118faac c07f05b0 ee0d7810 ee0d7810 00000001 bb7ffb78
[    4.007389] 7ee0: ee0d7810 ee0d7810 c118fd18 c118faac c11c63e0 c07ef7d0 ee0d7810 c118fa90
[    4.015548] 7f00: c118fa90 c07efd68 c118fac8 ee27fe00 eefd9c80 eefdcd00 00000000 c118facc
[    4.023708] 7f20: 00000000 c033c038 eefd9c80 eefd9c80 00000008 ee27fe00 ee27fe14 eefd9c80
[    4.031866] 7f40: 00000008 c1103d00 eefd9c98 ee296000 eefd9c80 c033ce54 ee907eac c0b1d230
[    4.040026] 7f60: ee907eac eea24440 ee285000 00000000 ee296000 ee27fe00 c033ce24 eea2445c
[    4.048188] 7f80: ee907eac c0341db0 00000000 ee285000 c0341c8c 00000000 00000000 00000000
[    4.056346] 7fa0: 00000000 00000000 00000000 c03010e8 00000000 00000000 00000000 00000000
[    4.064505] 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    4.072665] 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[    4.080828] [<c07d3b7c>] (msm_gem_map_vma) from [<c07d14f8>] (msm_gem_get_and_pin_iova+0xd8/0x134)
[    4.088983] [<c07d14f8>] (msm_gem_get_and_pin_iova) from [<c07d1684>] (_msm_gem_kernel_new+0x38/0xac)
[    4.097839] [<c07d1684>] (_msm_gem_kernel_new) from [<c07d222c>] (msm_gem_kernel_new+0x24/0x2c)
[    4.107130] [<c07d222c>] (msm_gem_kernel_new) from [<c07dcfd8>] (dsi_tx_buf_alloc_6g+0x44/0x90)
[    4.115631] [<c07dcfd8>] (dsi_tx_buf_alloc_6g) from [<c07ddb48>] (msm_dsi_host_modeset_init+0x80/0x104)
[    4.124313] [<c07ddb48>] (msm_dsi_host_modeset_init) from [<c07db7e8>] (msm_dsi_modeset_init+0x34/0x1c0)
[    4.133691] [<c07db7e8>] (msm_dsi_modeset_init) from [<c07a0a30>] (mdp5_kms_init+0x764/0x7e0)
[    4.143409] [<c07a0a30>] (mdp5_kms_init) from [<c07cf748>] (msm_drm_bind+0x56c/0x740)
[    4.151824] [<c07cf748>] (msm_drm_bind) from [<c07ea4ac>] (try_to_bring_up_master+0x238/0x2b4)
[    4.159636] [<c07ea4ac>] (try_to_bring_up_master) from [<c07ea5d0>] (component_add+0xa8/0x170)
[    4.168146] [<c07ea5d0>] (component_add) from [<c07f2b0c>] (platform_drv_probe+0x48/0x9c)
[    4.176737] [<c07f2b0c>] (platform_drv_probe) from [<c07f08c4>] (really_probe+0x278/0x404)
[    4.184981] [<c07f08c4>] (really_probe) from [<c07f0c08>] (driver_probe_device+0x78/0x1c0)
[    4.193147] [<c07f0c08>] (driver_probe_device) from [<c07ee8a0>] (bus_for_each_drv+0x74/0xb8)
[    4.201389] [<c07ee8a0>] (bus_for_each_drv) from [<c07f05b0>] (__device_attach+0xd0/0x164)
[    4.209984] [<c07f05b0>] (__device_attach) from [<c07ef7d0>] (bus_probe_device+0x84/0x8c)
[    4.218143] [<c07ef7d0>] (bus_probe_device) from [<c07efd68>] (deferred_probe_work_func+0x48/0xc4)
[    4.226398] [<c07efd68>] (deferred_probe_work_func) from [<c033c038>] (process_one_work+0x204/0x574)
[    4.235254] [<c033c038>] (process_one_work) from [<c033ce54>] (worker_thread+0x30/0x560)
[    4.244534] [<c033ce54>] (worker_thread) from [<c0341db0>] (kthread+0x124/0x154)
[    4.252606] [<c0341db0>] (kthread) from [<c03010e8>] (ret_from_fork+0x14/0x2c)
[    4.259966] Exception stack(0xee297fb0 to 0xee297ff8)
[    4.266998] 7fa0:                                     00000000 00000000 00000000 00000000
[    4.272143] 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    4.280297] 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[    4.288451] Code: e5813080 1a000013 e3a03001 e5c4307c (e590009c)
[    4.294933] ---[ end trace 18729cc2bca2b4b3 ]---

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/gpu/drm/msm/msm_gem_vma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index 49c04829cf34..fcf7a83f0e6f 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -85,7 +85,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace,
 
 	vma->mapped = true;
 
-	if (aspace->mmu)
+	if (aspace && aspace->mmu)
 		ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt,
 				size, prot);
 
-- 
2.21.0


^ permalink raw reply	[relevance 77%]

* [PATCH 1/2] dt-bindings: input: add GPIO controllable vibrator
@ 2019-03-02 14:11 98% Luca Weiss
  2019-03-02 14:11 73% ` [PATCH 2/2] Input: add a driver for GPIO controllable vibrators Luca Weiss
  0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-03-02 14:11 UTC (permalink / raw)
  Cc: Luca Weiss, Dmitry Torokhov, Rob Herring, Mark Rutland,
	open list:INPUT (KEYBOARD, MOUSE, JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 .../devicetree/bindings/input/gpio-vibrator.txt  | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-vibrator.txt

diff --git a/Documentation/devicetree/bindings/input/gpio-vibrator.txt b/Documentation/devicetree/bindings/input/gpio-vibrator.txt
new file mode 100644
index 000000000000..9e2e9acf497b
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-vibrator.txt
@@ -0,0 +1,16 @@
+* GPIO vibrator device tree bindings
+
+Registers a GPIO device as vibrator, where the vibration motor just has the capability to turn on or off. If the device is connected to a pwm, you should use the pwm-vibrator driver instead.
+
+Required properties:
+- compatible: should contain "gpio-vibrator"
+- enable-gpios: Should contain a GPIO handle
+- vcc-supply: Phandle for the regulator supplying power
+
+Example from Fairphone 2:
+
+vibrator {
+	compatible = "gpio-vibrator";
+	enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+	vcc-supply = <&pm8941_l18>;
+};
-- 
2.21.0


^ permalink raw reply	[relevance 98%]

* [PATCH 2/2] Input: add a driver for GPIO controllable vibrators
  2019-03-02 14:11 98% [PATCH 1/2] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
@ 2019-03-02 14:11 73% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-03-02 14:11 UTC (permalink / raw)
  Cc: Luca Weiss, Dmitry Torokhov, Xiaotong Lu, Coly Li, Stephen Boyd,
	Lucas Stach, Mauro Carvalho Chehab, Andrey Smirnov,
	Arnd Bergmann, Aaron Wu, Rob Herring, open list,
	open list:INPUT (KEYBOARD, MOUSE, JOYSTICK , TOUCHSCREEN)...

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/input/misc/Kconfig      |  12 ++
 drivers/input/misc/Makefile     |   1 +
 drivers/input/misc/gpio-vibra.c | 214 ++++++++++++++++++++++++++++++++
 3 files changed, 227 insertions(+)
 create mode 100644 drivers/input/misc/gpio-vibra.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index ca59a2be9bc5..77480268fef2 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -280,6 +280,18 @@ config INPUT_GPIO_DECODER
 	 To compile this driver as a module, choose M here: the module
 	 will be called gpio_decoder.
 
+config INPUT_GPIO_VIBRA
+	tristate "GPIO vibrator support"
+	depends on GPIOLIB || COMPILE_TEST
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here to get support for GPIO based vibrator devices.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called gpio-vibra.
+
 config INPUT_IXP4XX_BEEPER
 	tristate "IXP4XX Beeper support"
 	depends on ARCH_IXP4XX
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 9d0f9d1ff68f..79edbad44cf3 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
 obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
 obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
+obj-$(CONFIG_INPUT_GPIO_VIBRA)		+= gpio-vibra.o
 obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IMS_PCU)		+= ims-pcu.o
diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c
new file mode 100644
index 000000000000..14f9534668c8
--- /dev/null
+++ b/drivers/input/misc/gpio-vibra.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  GPIO vibrator driver
+ *
+ *  Copyright (C) 2019 Luca Weiss <luca@z3ntu.xyz>
+ *
+ *  Based on PWM vibrator driver:
+ *  Copyright (C) 2017 Collabora Ltd.
+ *
+ *  Based on previous work from:
+ *  Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com>
+ *
+ *  Based on PWM beeper driver:
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+enum vibrator_state {
+	VIBRATOR_OFF,
+	VIBRATOR_ON
+};
+
+struct gpio_vibrator {
+	struct input_dev *input;
+	struct gpio_desc *gpio;
+	struct regulator *vcc;
+
+	struct work_struct play_work;
+	enum vibrator_state state;
+	bool vcc_on;
+};
+
+static int gpio_vibrator_start(struct gpio_vibrator *vibrator)
+{
+	struct device *pdev = vibrator->input->dev.parent;
+	int err;
+
+	if (!vibrator->vcc_on) {
+		err = regulator_enable(vibrator->vcc);
+		if (err) {
+			dev_err(pdev, "failed to enable regulator: %d", err);
+			return err;
+		}
+		vibrator->vcc_on = true;
+	}
+
+	gpiod_set_value(vibrator->gpio, 1);
+
+	return 0;
+}
+
+static void gpio_vibrator_stop(struct gpio_vibrator *vibrator)
+{
+	gpiod_set_value(vibrator->gpio, 0);
+
+	if (vibrator->vcc_on) {
+		regulator_disable(vibrator->vcc);
+		vibrator->vcc_on = false;
+	}
+}
+
+static void gpio_vibrator_play_work(struct work_struct *work)
+{
+	struct gpio_vibrator *vibrator = container_of(work,
+					struct gpio_vibrator, play_work);
+
+	if (vibrator->state == VIBRATOR_ON)
+		gpio_vibrator_start(vibrator);
+	else
+		gpio_vibrator_stop(vibrator);
+}
+
+static int gpio_vibrator_play_effect(struct input_dev *dev, void *data,
+				    struct ff_effect *effect)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(dev);
+
+	int level = effect->u.rumble.strong_magnitude;
+
+	if (!level)
+		level = effect->u.rumble.weak_magnitude;
+
+	if (level)
+		vibrator->state = VIBRATOR_ON;
+	else
+		vibrator->state = VIBRATOR_OFF;
+
+	schedule_work(&vibrator->play_work);
+
+	return 0;
+}
+
+static void gpio_vibrator_close(struct input_dev *input)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(input);
+
+	cancel_work_sync(&vibrator->play_work);
+	gpio_vibrator_stop(vibrator);
+}
+
+static int gpio_vibrator_probe(struct platform_device *pdev)
+{
+	struct gpio_vibrator *vibrator;
+	int err;
+
+	vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
+	if (!vibrator)
+		return -ENOMEM;
+
+	vibrator->input = devm_input_allocate_device(&pdev->dev);
+	if (!vibrator->input)
+		return -ENOMEM;
+
+	vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
+	err = PTR_ERR_OR_ZERO(vibrator->vcc);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request regulator: %d",
+				err);
+		return err;
+	}
+
+	vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	err = PTR_ERR_OR_ZERO(vibrator->gpio);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request main gpio: %d",
+				err);
+		return err;
+	}
+
+	INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work);
+
+	vibrator->input->name = "gpio-vibrator";
+	vibrator->input->id.bustype = BUS_HOST;
+	vibrator->input->dev.parent = &pdev->dev;
+	vibrator->input->close = gpio_vibrator_close;
+
+	input_set_drvdata(vibrator->input, vibrator);
+	input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
+
+	err = input_ff_create_memless(vibrator->input, NULL,
+				      gpio_vibrator_play_effect);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't create FF dev: %d", err);
+		return err;
+	}
+
+	err = input_register_device(vibrator->input);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't register input dev: %d", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	cancel_work_sync(&vibrator->play_work);
+	if (vibrator->state == VIBRATOR_ON)
+		gpio_vibrator_stop(vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_resume(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	if (vibrator->state == VIBRATOR_ON)
+		gpio_vibrator_start(vibrator);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(gpio_vibrator_pm_ops,
+			 gpio_vibrator_suspend, gpio_vibrator_resume);
+
+#ifdef CONFIG_OF
+static const struct of_device_id gpio_vibra_dt_match_table[] = {
+	{ .compatible = "gpio-vibrator" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table);
+#endif
+
+static struct platform_driver gpio_vibrator_driver = {
+	.probe	= gpio_vibrator_probe,
+	.driver	= {
+		.name	= "gpio-vibrator",
+		.pm	= &gpio_vibrator_pm_ops,
+		.of_match_table = of_match_ptr(gpio_vibra_dt_match_table),
+	},
+};
+module_platform_driver(gpio_vibrator_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xy>");
+MODULE_DESCRIPTION("GPIO vibrator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio-vibrator");
-- 
2.21.0


^ permalink raw reply	[relevance 73%]

* [PATCH v2 2/3] Input: add a driver for GPIO controllable vibrators
  2019-04-07 15:58 93% [PATCH v2 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
@ 2019-04-07 15:58 71% ` Luca Weiss
    2019-04-07 15:58 99% ` [PATCH v2 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
  1 sibling, 1 reply; 84+ results
From: Luca Weiss @ 2019-04-07 15:58 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, Andy Gross,
	David Brown, open list:ARM/QUALCOMM SUPPORT,
	open list:INPUT (KEYBOARD, MOUSE, JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/input/misc/Kconfig      |  12 ++
 drivers/input/misc/Makefile     |   1 +
 drivers/input/misc/gpio-vibra.c | 214 ++++++++++++++++++++++++++++++++
 3 files changed, 227 insertions(+)
 create mode 100644 drivers/input/misc/gpio-vibra.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index e15ed1bb8558..6dfe9e2fe5b1 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -290,6 +290,18 @@ config INPUT_GPIO_DECODER
 	 To compile this driver as a module, choose M here: the module
 	 will be called gpio_decoder.
 
+config INPUT_GPIO_VIBRA
+	tristate "GPIO vibrator support"
+	depends on GPIOLIB || COMPILE_TEST
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here to get support for GPIO based vibrator devices.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called gpio-vibra.
+
 config INPUT_IXP4XX_BEEPER
 	tristate "IXP4XX Beeper support"
 	depends on ARCH_IXP4XX
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index b936c5b1d4ac..f38ebbdb05e2 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
 obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
 obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
+obj-$(CONFIG_INPUT_GPIO_VIBRA)		+= gpio-vibra.o
 obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IMS_PCU)		+= ims-pcu.o
diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c
new file mode 100644
index 000000000000..14f9534668c8
--- /dev/null
+++ b/drivers/input/misc/gpio-vibra.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  GPIO vibrator driver
+ *
+ *  Copyright (C) 2019 Luca Weiss <luca@z3ntu.xyz>
+ *
+ *  Based on PWM vibrator driver:
+ *  Copyright (C) 2017 Collabora Ltd.
+ *
+ *  Based on previous work from:
+ *  Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com>
+ *
+ *  Based on PWM beeper driver:
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+enum vibrator_state {
+	VIBRATOR_OFF,
+	VIBRATOR_ON
+};
+
+struct gpio_vibrator {
+	struct input_dev *input;
+	struct gpio_desc *gpio;
+	struct regulator *vcc;
+
+	struct work_struct play_work;
+	enum vibrator_state state;
+	bool vcc_on;
+};
+
+static int gpio_vibrator_start(struct gpio_vibrator *vibrator)
+{
+	struct device *pdev = vibrator->input->dev.parent;
+	int err;
+
+	if (!vibrator->vcc_on) {
+		err = regulator_enable(vibrator->vcc);
+		if (err) {
+			dev_err(pdev, "failed to enable regulator: %d", err);
+			return err;
+		}
+		vibrator->vcc_on = true;
+	}
+
+	gpiod_set_value(vibrator->gpio, 1);
+
+	return 0;
+}
+
+static void gpio_vibrator_stop(struct gpio_vibrator *vibrator)
+{
+	gpiod_set_value(vibrator->gpio, 0);
+
+	if (vibrator->vcc_on) {
+		regulator_disable(vibrator->vcc);
+		vibrator->vcc_on = false;
+	}
+}
+
+static void gpio_vibrator_play_work(struct work_struct *work)
+{
+	struct gpio_vibrator *vibrator = container_of(work,
+					struct gpio_vibrator, play_work);
+
+	if (vibrator->state == VIBRATOR_ON)
+		gpio_vibrator_start(vibrator);
+	else
+		gpio_vibrator_stop(vibrator);
+}
+
+static int gpio_vibrator_play_effect(struct input_dev *dev, void *data,
+				    struct ff_effect *effect)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(dev);
+
+	int level = effect->u.rumble.strong_magnitude;
+
+	if (!level)
+		level = effect->u.rumble.weak_magnitude;
+
+	if (level)
+		vibrator->state = VIBRATOR_ON;
+	else
+		vibrator->state = VIBRATOR_OFF;
+
+	schedule_work(&vibrator->play_work);
+
+	return 0;
+}
+
+static void gpio_vibrator_close(struct input_dev *input)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(input);
+
+	cancel_work_sync(&vibrator->play_work);
+	gpio_vibrator_stop(vibrator);
+}
+
+static int gpio_vibrator_probe(struct platform_device *pdev)
+{
+	struct gpio_vibrator *vibrator;
+	int err;
+
+	vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
+	if (!vibrator)
+		return -ENOMEM;
+
+	vibrator->input = devm_input_allocate_device(&pdev->dev);
+	if (!vibrator->input)
+		return -ENOMEM;
+
+	vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
+	err = PTR_ERR_OR_ZERO(vibrator->vcc);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request regulator: %d",
+				err);
+		return err;
+	}
+
+	vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	err = PTR_ERR_OR_ZERO(vibrator->gpio);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request main gpio: %d",
+				err);
+		return err;
+	}
+
+	INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work);
+
+	vibrator->input->name = "gpio-vibrator";
+	vibrator->input->id.bustype = BUS_HOST;
+	vibrator->input->dev.parent = &pdev->dev;
+	vibrator->input->close = gpio_vibrator_close;
+
+	input_set_drvdata(vibrator->input, vibrator);
+	input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
+
+	err = input_ff_create_memless(vibrator->input, NULL,
+				      gpio_vibrator_play_effect);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't create FF dev: %d", err);
+		return err;
+	}
+
+	err = input_register_device(vibrator->input);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't register input dev: %d", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	cancel_work_sync(&vibrator->play_work);
+	if (vibrator->state == VIBRATOR_ON)
+		gpio_vibrator_stop(vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_resume(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	if (vibrator->state == VIBRATOR_ON)
+		gpio_vibrator_start(vibrator);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(gpio_vibrator_pm_ops,
+			 gpio_vibrator_suspend, gpio_vibrator_resume);
+
+#ifdef CONFIG_OF
+static const struct of_device_id gpio_vibra_dt_match_table[] = {
+	{ .compatible = "gpio-vibrator" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table);
+#endif
+
+static struct platform_driver gpio_vibrator_driver = {
+	.probe	= gpio_vibrator_probe,
+	.driver	= {
+		.name	= "gpio-vibrator",
+		.pm	= &gpio_vibrator_pm_ops,
+		.of_match_table = of_match_ptr(gpio_vibra_dt_match_table),
+	},
+};
+module_platform_driver(gpio_vibrator_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xy>");
+MODULE_DESCRIPTION("GPIO vibrator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio-vibrator");
-- 
2.21.0


^ permalink raw reply	[relevance 71%]

* [PATCH v2 3/3] ARM: dts: msm8974-FP2: Add vibration motor
  2019-04-07 15:58 93% [PATCH v2 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
  2019-04-07 15:58 71% ` [PATCH v2 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
@ 2019-04-07 15:58 99% ` Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-07 15:58 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, Andy Gross,
	David Brown, open list:ARM/QUALCOMM SUPPORT,
	open list:INPUT (KEYBOARD, MOUSE, JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index 643c57f84818..bf402ae39226 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -50,6 +50,12 @@
 		};
 	};
 
+	vibrator {
+		compatible = "gpio-vibrator";
+		enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+		vcc-supply = <&pm8941_l18>;
+	};
+
 	smd {
 		rpm {
 			rpm_requests {
-- 
2.21.0


^ permalink raw reply	[relevance 99%]

* [PATCH v2 1/3] dt-bindings: input: add GPIO controllable vibrator
@ 2019-04-07 15:58 93% Luca Weiss
  2019-04-07 15:58 71% ` [PATCH v2 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
  2019-04-07 15:58 99% ` [PATCH v2 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
  0 siblings, 2 replies; 84+ results
From: Luca Weiss @ 2019-04-07 15:58 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, Andy Gross,
	David Brown, open list:ARM/QUALCOMM SUPPORT,
	open list:INPUT (KEYBOARD, MOUSE, JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes from v1:
- Mark vcc-supply as optional

 .../bindings/input/gpio-vibrator.txt          | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-vibrator.txt

diff --git a/Documentation/devicetree/bindings/input/gpio-vibrator.txt b/Documentation/devicetree/bindings/input/gpio-vibrator.txt
new file mode 100644
index 000000000000..93e5a8e7622d
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-vibrator.txt
@@ -0,0 +1,20 @@
+* GPIO vibrator device tree bindings
+
+Registers a GPIO device as vibrator, where the vibration motor just has the
+capability to turn on or off. If the device is connected to a pwm, you should
+use the pwm-vibrator driver instead.
+
+Required properties:
+- compatible: should contain "gpio-vibrator"
+- enable-gpios: Should contain a GPIO handle
+
+Optional properties:
+- vcc-supply: Phandle for the regulator supplying power
+
+Example from Fairphone 2:
+
+vibrator {
+	compatible = "gpio-vibrator";
+	enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+	vcc-supply = <&pm8941_l18>;
+};
-- 
2.21.0


^ permalink raw reply	[relevance 93%]

* Re: [PATCH v2 2/3] Input: add a driver for GPIO controllable vibrators
  @ 2019-04-09 11:48 96%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-09 11:48 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rob Herring, Mark Rutland, Mauro Carvalho Chehab,
	Pascal PAILLET-LME, Coly Li, Lee Jones, Xiaotong Lu,
	Brian Masney, Rob Herring, Baolin Wang, Andy Gross, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK, TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

Hello Dmitry,

see inline comments - and:
your last two comments should probably be also applied to the pwm-vibra.c 
driver, as that's where these code blocks come from.

On Montag, 8. April 2019 00:18:57 CEST Dmitry Torokhov wrote:
> Hi Luca,
> 
> On Sun, Apr 07, 2019 at 05:58:41PM +0200, Luca Weiss wrote:
> > Provide a simple driver for GPIO controllable vibrators.
> > It will be used by the Fairphone 2.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > ---
> > 
> >  drivers/input/misc/Kconfig      |  12 ++
> >  drivers/input/misc/Makefile     |   1 +
> >  drivers/input/misc/gpio-vibra.c | 214 ++++++++++++++++++++++++++++++++
> >  3 files changed, 227 insertions(+)
> >  create mode 100644 drivers/input/misc/gpio-vibra.c
> > 
> > diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> > index e15ed1bb8558..6dfe9e2fe5b1 100644
> > --- a/drivers/input/misc/Kconfig
> > +++ b/drivers/input/misc/Kconfig
> > @@ -290,6 +290,18 @@ config INPUT_GPIO_DECODER
> > 
> >  	 To compile this driver as a module, choose M here: the module
> >  	 will be called gpio_decoder.
> > 
> > +config INPUT_GPIO_VIBRA
> > +	tristate "GPIO vibrator support"
> > +	depends on GPIOLIB || COMPILE_TEST
> > +	select INPUT_FF_MEMLESS
> > +	help
> > +	  Say Y here to get support for GPIO based vibrator devices.
> > +
> > +	  If unsure, say N.
> > +
> > +	  To compile this driver as a module, choose M here: the module 
will be
> > +	  called gpio-vibra.
> > +
> > 
> >  config INPUT_IXP4XX_BEEPER
> >  
> >  	tristate "IXP4XX Beeper support"
> >  	depends on ARCH_IXP4XX
> > 
> > diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> > index b936c5b1d4ac..f38ebbdb05e2 100644
> > --- a/drivers/input/misc/Makefile
> > +++ b/drivers/input/misc/Makefile
> > @@ -36,6 +36,7 @@ obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
> > 
> >  obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
> >  obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
> >  obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
> > 
> > +obj-$(CONFIG_INPUT_GPIO_VIBRA)		+= gpio-vibra.o
> > 
> >  obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
> >  obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
> >  obj-$(CONFIG_INPUT_IMS_PCU)		+= ims-pcu.o
> > 
> > diff --git a/drivers/input/misc/gpio-vibra.c
> > b/drivers/input/misc/gpio-vibra.c new file mode 100644
> > index 000000000000..14f9534668c8
> > --- /dev/null
> > +++ b/drivers/input/misc/gpio-vibra.c
> > @@ -0,0 +1,214 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + *  GPIO vibrator driver
> > + *
> > + *  Copyright (C) 2019 Luca Weiss <luca@z3ntu.xyz>
> > + *
> > + *  Based on PWM vibrator driver:
> > + *  Copyright (C) 2017 Collabora Ltd.
> > + *
> > + *  Based on previous work from:
> > + *  Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > + *
> > + *  Based on PWM beeper driver:
> > + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
> > + */
> > +
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/input.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/property.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <linux/slab.h>
> > +
> > +enum vibrator_state {
> > +	VIBRATOR_OFF,
> > +	VIBRATOR_ON
> > +};
> 
> I'd probably go with simple "bool running".
Changed.
> 
> > +
> > +struct gpio_vibrator {
> > +	struct input_dev *input;
> > +	struct gpio_desc *gpio;
> > +	struct regulator *vcc;
> > +
> > +	struct work_struct play_work;
> > +	enum vibrator_state state;
> > +	bool vcc_on;
> > +};
> > +
> > +static int gpio_vibrator_start(struct gpio_vibrator *vibrator)
> > +{
> > +	struct device *pdev = vibrator->input->dev.parent;
> > +	int err;
> > +
> > +	if (!vibrator->vcc_on) {
> > +		err = regulator_enable(vibrator->vcc);
> > +		if (err) {
> > +			dev_err(pdev, "failed to enable regulator: 
%d", err);
> > +			return err;
> > +		}
> > +		vibrator->vcc_on = true;
> > +	}
> > +
> > +	gpiod_set_value(vibrator->gpio, 1);
> 
> Since this is called by work item and thus from context that can sleep,
> we can use gpiod_set_value_cansleep() so that "slow" GPIOs can be used
> with the driver.
Changed.
> 
> > +
> > +	return 0;
> > +}
> > +
> > +static void gpio_vibrator_stop(struct gpio_vibrator *vibrator)
> > +{
> > +	gpiod_set_value(vibrator->gpio, 0);
> > +
> > +	if (vibrator->vcc_on) {
> > +		regulator_disable(vibrator->vcc);
> > +		vibrator->vcc_on = false;
> > +	}
> > +}
> > +
> > +static void gpio_vibrator_play_work(struct work_struct *work)
> > +{
> > +	struct gpio_vibrator *vibrator = container_of(work,
> > +					struct gpio_vibrator, 
play_work);
> > +
> > +	if (vibrator->state == VIBRATOR_ON)
> > +		gpio_vibrator_start(vibrator);
> > +	else
> > +		gpio_vibrator_stop(vibrator);
> > +}
> > +
> > +static int gpio_vibrator_play_effect(struct input_dev *dev, void *data,
> > +				    struct ff_effect *effect)
> > +{
> > +	struct gpio_vibrator *vibrator = input_get_drvdata(dev);
> > +
> > +	int level = effect->u.rumble.strong_magnitude;
> > +
> > +	if (!level)
> > +		level = effect->u.rumble.weak_magnitude;
> > +
> > +	if (level)
> > +		vibrator->state = VIBRATOR_ON;
> > +	else
> > +		vibrator->state = VIBRATOR_OFF;
> > +
> > +	schedule_work(&vibrator->play_work);
> > +
> > +	return 0;
> > +}
> > +
> > +static void gpio_vibrator_close(struct input_dev *input)
> > +{
> > +	struct gpio_vibrator *vibrator = input_get_drvdata(input);
> > +
> > +	cancel_work_sync(&vibrator->play_work);
> > +	gpio_vibrator_stop(vibrator);
> 
> Do you want to update vibrator->state here?
I've looked at that a bit and it makes sense when the vibrator is on, the 
input it closed (and the vibrator stopped but the variable is still 'on'), 
then the device is suspended and resumed, the vibrator will be turned on 
again, so I'll change that.
> 
> > +}
> > +
> > +static int gpio_vibrator_probe(struct platform_device *pdev)
> > +{
> > +	struct gpio_vibrator *vibrator;
> > +	int err;
> > +
> > +	vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), 
GFP_KERNEL);
> > +	if (!vibrator)
> > +		return -ENOMEM;
> > +
> > +	vibrator->input = devm_input_allocate_device(&pdev->dev);
> > +	if (!vibrator->input)
> > +		return -ENOMEM;
> > +
> > +	vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
> > +	err = PTR_ERR_OR_ZERO(vibrator->vcc);
> > +	if (err) {
> > +		if (err != -EPROBE_DEFER)
> > +			dev_err(&pdev->dev, "Failed to request 
regulator: %d",
> > +				err);
> > +		return err;
> > +	}
> > +
> > +	vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", 
GPIOD_OUT_LOW);
> > +	err = PTR_ERR_OR_ZERO(vibrator->gpio);
> > +	if (err) {
> > +		if (err != -EPROBE_DEFER)
> > +			dev_err(&pdev->dev, "Failed to request main 
gpio: %d",
> > +				err);
> > +		return err;
> > +	}
> > +
> > +	INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work);
> > +
> > +	vibrator->input->name = "gpio-vibrator";
> > +	vibrator->input->id.bustype = BUS_HOST;
> > +	vibrator->input->dev.parent = &pdev->dev;
> 
> No need to set as you used devm_input_device_alloc().
Changed.
> > +	vibrator->input->close = gpio_vibrator_close;
> > +
> > +	input_set_drvdata(vibrator->input, vibrator);
> > +	input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
> > +
> > +	err = input_ff_create_memless(vibrator->input, NULL,
> > +				      gpio_vibrator_play_effect);
> > +	if (err) {
> > +		dev_err(&pdev->dev, "Couldn't create FF dev: %d", err);
> > +		return err;
> > +	}
> > +
> > +	err = input_register_device(vibrator->input);
> > +	if (err) {
> > +		dev_err(&pdev->dev, "Couldn't register input dev: %d", 
err);
> > +		return err;
> > +	}
> > +
> > +	platform_set_drvdata(pdev, vibrator);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
> > +{
> > +	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
> > +
> > +	cancel_work_sync(&vibrator->play_work);
> > +	if (vibrator->state == VIBRATOR_ON)
> > +		gpio_vibrator_stop(vibrator);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused gpio_vibrator_resume(struct device *dev)
> > +{
> > +	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
> > +
> > +	if (vibrator->state == VIBRATOR_ON)
> > +		gpio_vibrator_start(vibrator);
> > +
> > +	return 0;
> > +}
> > +
> > +static SIMPLE_DEV_PM_OPS(gpio_vibrator_pm_ops,
> > +			 gpio_vibrator_suspend, 
gpio_vibrator_resume);
> > +
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id gpio_vibra_dt_match_table[] = {
> > +	{ .compatible = "gpio-vibrator" },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table);
> > +#endif
> > +
> > +static struct platform_driver gpio_vibrator_driver = {
> > +	.probe	= gpio_vibrator_probe,
> > +	.driver	= {
> > +		.name	= "gpio-vibrator",
> > +		.pm	= &gpio_vibrator_pm_ops,
> > +		.of_match_table = 
of_match_ptr(gpio_vibra_dt_match_table),
> > +	},
> > +};
> > +module_platform_driver(gpio_vibrator_driver);
> > +
> > +MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xy>");
> > +MODULE_DESCRIPTION("GPIO vibrator driver");
> > +MODULE_LICENSE("GPL");
> > +MODULE_ALIAS("platform:gpio-vibrator");
> 
> Thanks.

Thank you for the review, will send a v3 soon!
Luca



^ permalink raw reply	[relevance 96%]

* [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator
@ 2019-04-12 15:06 94% Luca Weiss
  2019-04-12 15:06 72% ` [PATCH v3 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
                   ` (2 more replies)
  0 siblings, 3 replies; 84+ results
From: Luca Weiss @ 2019-04-12 15:06 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 .../bindings/input/gpio-vibrator.txt          | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-vibrator.txt

diff --git a/Documentation/devicetree/bindings/input/gpio-vibrator.txt b/Documentation/devicetree/bindings/input/gpio-vibrator.txt
new file mode 100644
index 000000000000..93e5a8e7622d
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-vibrator.txt
@@ -0,0 +1,20 @@
+* GPIO vibrator device tree bindings
+
+Registers a GPIO device as vibrator, where the vibration motor just has the
+capability to turn on or off. If the device is connected to a pwm, you should
+use the pwm-vibrator driver instead.
+
+Required properties:
+- compatible: should contain "gpio-vibrator"
+- enable-gpios: Should contain a GPIO handle
+
+Optional properties:
+- vcc-supply: Phandle for the regulator supplying power
+
+Example from Fairphone 2:
+
+vibrator {
+	compatible = "gpio-vibrator";
+	enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+	vcc-supply = <&pm8941_l18>;
+};
-- 
2.21.0


^ permalink raw reply	[relevance 94%]

* [PATCH v3 2/3] Input: add a driver for GPIO controllable vibrators
  2019-04-12 15:06 94% [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
@ 2019-04-12 15:06 72% ` Luca Weiss
    2019-04-12 15:06 99% ` [PATCH v3 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
  2019-04-17 16:02 99% ` [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
  2 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-04-12 15:06 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/input/misc/Kconfig      |  12 ++
 drivers/input/misc/Makefile     |   1 +
 drivers/input/misc/gpio-vibra.c | 209 ++++++++++++++++++++++++++++++++
 3 files changed, 222 insertions(+)
 create mode 100644 drivers/input/misc/gpio-vibra.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index e15ed1bb8558..6dfe9e2fe5b1 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -290,6 +290,18 @@ config INPUT_GPIO_DECODER
 	 To compile this driver as a module, choose M here: the module
 	 will be called gpio_decoder.
 
+config INPUT_GPIO_VIBRA
+	tristate "GPIO vibrator support"
+	depends on GPIOLIB || COMPILE_TEST
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here to get support for GPIO based vibrator devices.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called gpio-vibra.
+
 config INPUT_IXP4XX_BEEPER
 	tristate "IXP4XX Beeper support"
 	depends on ARCH_IXP4XX
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index b936c5b1d4ac..f38ebbdb05e2 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
 obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
 obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
+obj-$(CONFIG_INPUT_GPIO_VIBRA)		+= gpio-vibra.o
 obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IMS_PCU)		+= ims-pcu.o
diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c
new file mode 100644
index 000000000000..3fd2dfd4f670
--- /dev/null
+++ b/drivers/input/misc/gpio-vibra.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  GPIO vibrator driver
+ *
+ *  Copyright (C) 2019 Luca Weiss <luca@z3ntu.xyz>
+ *
+ *  Based on PWM vibrator driver:
+ *  Copyright (C) 2017 Collabora Ltd.
+ *
+ *  Based on previous work from:
+ *  Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com>
+ *
+ *  Based on PWM beeper driver:
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+struct gpio_vibrator {
+	struct input_dev *input;
+	struct gpio_desc *gpio;
+	struct regulator *vcc;
+
+	struct work_struct play_work;
+	bool running;
+	bool vcc_on;
+};
+
+static int gpio_vibrator_start(struct gpio_vibrator *vibrator)
+{
+	struct device *pdev = vibrator->input->dev.parent;
+	int err;
+
+	if (!vibrator->vcc_on) {
+		err = regulator_enable(vibrator->vcc);
+		if (err) {
+			dev_err(pdev, "failed to enable regulator: %d", err);
+			return err;
+		}
+		vibrator->vcc_on = true;
+	}
+
+	gpiod_set_value_cansleep(vibrator->gpio, 1);
+
+	return 0;
+}
+
+static void gpio_vibrator_stop(struct gpio_vibrator *vibrator)
+{
+	gpiod_set_value_cansleep(vibrator->gpio, 0);
+
+	if (vibrator->vcc_on) {
+		regulator_disable(vibrator->vcc);
+		vibrator->vcc_on = false;
+	}
+}
+
+static void gpio_vibrator_play_work(struct work_struct *work)
+{
+	struct gpio_vibrator *vibrator =
+		container_of(work, struct gpio_vibrator, play_work);
+
+	if (vibrator->running)
+		gpio_vibrator_start(vibrator);
+	else
+		gpio_vibrator_stop(vibrator);
+}
+
+static int gpio_vibrator_play_effect(struct input_dev *dev, void *data,
+				     struct ff_effect *effect)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(dev);
+
+	int level = effect->u.rumble.strong_magnitude;
+
+	if (!level)
+		level = effect->u.rumble.weak_magnitude;
+
+	if (level)
+		vibrator->running = true;
+	else
+		vibrator->running = false;
+
+	schedule_work(&vibrator->play_work);
+
+	return 0;
+}
+
+static void gpio_vibrator_close(struct input_dev *input)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(input);
+
+	cancel_work_sync(&vibrator->play_work);
+	gpio_vibrator_stop(vibrator);
+	vibrator->running = false;
+}
+
+static int gpio_vibrator_probe(struct platform_device *pdev)
+{
+	struct gpio_vibrator *vibrator;
+	int err;
+
+	vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
+	if (!vibrator)
+		return -ENOMEM;
+
+	vibrator->input = devm_input_allocate_device(&pdev->dev);
+	if (!vibrator->input)
+		return -ENOMEM;
+
+	vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
+	err = PTR_ERR_OR_ZERO(vibrator->vcc);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request regulator: %d",
+				err);
+		return err;
+	}
+
+	vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	err = PTR_ERR_OR_ZERO(vibrator->gpio);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request main gpio: %d",
+				err);
+		return err;
+	}
+
+	INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work);
+
+	vibrator->input->name = "gpio-vibrator";
+	vibrator->input->id.bustype = BUS_HOST;
+	vibrator->input->close = gpio_vibrator_close;
+
+	input_set_drvdata(vibrator->input, vibrator);
+	input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
+
+	err = input_ff_create_memless(vibrator->input, NULL,
+				      gpio_vibrator_play_effect);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't create FF dev: %d", err);
+		return err;
+	}
+
+	err = input_register_device(vibrator->input);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't register input dev: %d", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	cancel_work_sync(&vibrator->play_work);
+	if (vibrator->running)
+		gpio_vibrator_stop(vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_resume(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	if (vibrator->running)
+		gpio_vibrator_start(vibrator);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(gpio_vibrator_pm_ops,
+			 gpio_vibrator_suspend, gpio_vibrator_resume);
+
+#ifdef CONFIG_OF
+static const struct of_device_id gpio_vibra_dt_match_table[] = {
+	{ .compatible = "gpio-vibrator" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table);
+#endif
+
+static struct platform_driver gpio_vibrator_driver = {
+	.probe	= gpio_vibrator_probe,
+	.driver	= {
+		.name	= "gpio-vibrator",
+		.pm	= &gpio_vibrator_pm_ops,
+		.of_match_table = of_match_ptr(gpio_vibra_dt_match_table),
+	},
+};
+module_platform_driver(gpio_vibrator_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xy>");
+MODULE_DESCRIPTION("GPIO vibrator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio-vibrator");
-- 
2.21.0


^ permalink raw reply	[relevance 72%]

* [PATCH v3 3/3] ARM: dts: msm8974-FP2: Add vibration motor
  2019-04-12 15:06 94% [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
  2019-04-12 15:06 72% ` [PATCH v3 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
@ 2019-04-12 15:06 99% ` Luca Weiss
  2019-04-17 16:02 99% ` [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
  2 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-12 15:06 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index 643c57f84818..bf402ae39226 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -50,6 +50,12 @@
 		};
 	};
 
+	vibrator {
+		compatible = "gpio-vibrator";
+		enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+		vcc-supply = <&pm8941_l18>;
+	};
+
 	smd {
 		rpm {
 			rpm_requests {
-- 
2.21.0


^ permalink raw reply	[relevance 99%]

* Re: [PATCH v3 2/3] Input: add a driver for GPIO controllable vibrators
  @ 2019-04-16 16:02 99%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-16 16:02 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

On Freitag, 12. April 2019 19:43:52 CEST Stephen Boyd wrote:
> Quoting Luca Weiss (2019-04-12 08:06:24)
> 
> > diff --git a/drivers/input/misc/gpio-vibra.c
> > b/drivers/input/misc/gpio-vibra.c new file mode 100644
> > index 000000000000..3fd2dfd4f670
> > --- /dev/null
> > +++ b/drivers/input/misc/gpio-vibra.c
> > @@ -0,0 +1,209 @@
> > +
> > +static int gpio_vibrator_probe(struct platform_device *pdev)
> > +{
> 
> [...]
> 
> > +       vibrator->input->id.bustype = BUS_HOST;
> > +       vibrator->input->close = gpio_vibrator_close;
> > +
> > +       input_set_drvdata(vibrator->input, vibrator);
> > +       input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
> > +
> > +       err = input_ff_create_memless(vibrator->input, NULL,
> > +                                     gpio_vibrator_play_effect);
> > +       if (err) {
> > +               dev_err(&pdev->dev, "Couldn't create FF dev: %d", err);
> > +               return err;
> > +       }
> > +
> > +       err = input_register_device(vibrator->input);
> > +       if (err) {
> > +               dev_err(&pdev->dev, "Couldn't register input dev: %d",
> > err);
> All the printks in this file need a newline.
Fixed.
> > +               return err;
> > +       }
> > +
> > +       platform_set_drvdata(pdev, vibrator);
> > +
> > +       return 0;
> > +}
> > +
> > +
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id gpio_vibra_dt_match_table[] = {
> > +       { .compatible = "gpio-vibrator" },
> > +       {},
> 
> Nitpick: Drop the comma on the sentinel so nothing can go after it
> without causing a compilation error.
Changed as well.
> > +};
> > +MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table);
> > +#endif
> > +

Thanks for the review! Will send a v4 shortly.
Luca



^ permalink raw reply	[relevance 99%]

* Re: [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator
  2019-04-12 15:06 94% [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
  2019-04-12 15:06 72% ` [PATCH v3 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
  2019-04-12 15:06 99% ` [PATCH v3 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
@ 2019-04-17 16:02 99% ` Luca Weiss
  2 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-17 16:02 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rob Herring, Mark Rutland, Mauro Carvalho Chehab,
	Pascal PAILLET-LME, Coly Li, Lee Jones, Xiaotong Lu,
	Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK, TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

On Freitag, 12. April 2019 17:06:23 CEST Luca Weiss wrote:
> Provide a simple driver for GPIO controllable vibrators.
> It will be used by the Fairphone 2.
> 
> Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> ---
>  .../bindings/input/gpio-vibrator.txt          | 20 +++++++++++++++++++
>  1 file changed, 20 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/input/gpio-vibrator.txt
> 
> diff --git a/Documentation/devicetree/bindings/input/gpio-vibrator.txt
> b/Documentation/devicetree/bindings/input/gpio-vibrator.txt new file mode
> 100644
> index 000000000000..93e5a8e7622d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/gpio-vibrator.txt
> @@ -0,0 +1,20 @@
> +* GPIO vibrator device tree bindings
> +
> +Registers a GPIO device as vibrator, where the vibration motor just has the
> +capability to turn on or off. If the device is connected to a pwm, you
> should +use the pwm-vibrator driver instead.
> +
> +Required properties:
> +- compatible: should contain "gpio-vibrator"
> +- enable-gpios: Should contain a GPIO handle
> +
> +Optional properties:
> +- vcc-supply: Phandle for the regulator supplying power
> +
> +Example from Fairphone 2:
> +
> +vibrator {
> +	compatible = "gpio-vibrator";
> +	enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
> +	vcc-supply = <&pm8941_l18>;
> +};

I see that the yaml based device tree binding docs seem to be the new hotness? 
Is there any "policy" / preference about new drivers?

Luca




^ permalink raw reply	[relevance 99%]

* [PATCH v4 1/3] dt-bindings: input: add GPIO controllable vibrator
@ 2019-04-20 12:23 93% Luca Weiss
  2019-04-20 12:23 71% ` [PATCH v4 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
  2019-04-20 12:23 99% ` [PATCH v4 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
  0 siblings, 2 replies; 84+ results
From: Luca Weiss @ 2019-04-20 12:23 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes from v3:
- Convert .txt based doc to the new yaml based format

 .../bindings/input/gpio-vibrator.yaml         | 39 +++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-vibrator.yaml

diff --git a/Documentation/devicetree/bindings/input/gpio-vibrator.yaml b/Documentation/devicetree/bindings/input/gpio-vibrator.yaml
new file mode 100644
index 000000000000..bca1b6ea07a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-vibrator.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bindings/input/gpio-vibrator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIO vibrator
+
+maintainers:
+  - Luca Weiss <luca@z3ntu.xyz>
+
+description: |+
+  Registers a GPIO device as vibrator, where the on/off capability is controlled by a GPIO.
+
+properties:
+  compatible:
+    items:
+      - const: gpio-vibrator
+
+  enable-gpios:
+    maxItems: 1
+
+  vcc-supply:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Regulator that provides power
+
+required:
+  - compatible
+  - enable-gpios
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    vibrator {
+        compatible = "gpio-vibrator";
+        enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+        vcc-supply = <&pm8941_l18>;
+    };
-- 
2.21.0


^ permalink raw reply	[relevance 93%]

* [PATCH v4 2/3] Input: add a driver for GPIO controllable vibrators
  2019-04-20 12:23 93% [PATCH v4 " Luca Weiss
@ 2019-04-20 12:23 71% ` Luca Weiss
  2019-04-20 12:23 99% ` [PATCH v4 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-20 12:23 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes from v3:
- Apply suggestions from Stephen Boyd

 drivers/input/misc/Kconfig      |  12 ++
 drivers/input/misc/Makefile     |   1 +
 drivers/input/misc/gpio-vibra.c | 209 ++++++++++++++++++++++++++++++++
 3 files changed, 222 insertions(+)
 create mode 100644 drivers/input/misc/gpio-vibra.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index e15ed1bb8558..6dfe9e2fe5b1 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -290,6 +290,18 @@ config INPUT_GPIO_DECODER
 	 To compile this driver as a module, choose M here: the module
 	 will be called gpio_decoder.
 
+config INPUT_GPIO_VIBRA
+	tristate "GPIO vibrator support"
+	depends on GPIOLIB || COMPILE_TEST
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here to get support for GPIO based vibrator devices.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called gpio-vibra.
+
 config INPUT_IXP4XX_BEEPER
 	tristate "IXP4XX Beeper support"
 	depends on ARCH_IXP4XX
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index b936c5b1d4ac..f38ebbdb05e2 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
 obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
 obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
+obj-$(CONFIG_INPUT_GPIO_VIBRA)		+= gpio-vibra.o
 obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IMS_PCU)		+= ims-pcu.o
diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c
new file mode 100644
index 000000000000..b76c81015de9
--- /dev/null
+++ b/drivers/input/misc/gpio-vibra.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  GPIO vibrator driver
+ *
+ *  Copyright (C) 2019 Luca Weiss <luca@z3ntu.xyz>
+ *
+ *  Based on PWM vibrator driver:
+ *  Copyright (C) 2017 Collabora Ltd.
+ *
+ *  Based on previous work from:
+ *  Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com>
+ *
+ *  Based on PWM beeper driver:
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+struct gpio_vibrator {
+	struct input_dev *input;
+	struct gpio_desc *gpio;
+	struct regulator *vcc;
+
+	struct work_struct play_work;
+	bool running;
+	bool vcc_on;
+};
+
+static int gpio_vibrator_start(struct gpio_vibrator *vibrator)
+{
+	struct device *pdev = vibrator->input->dev.parent;
+	int err;
+
+	if (!vibrator->vcc_on) {
+		err = regulator_enable(vibrator->vcc);
+		if (err) {
+			dev_err(pdev, "failed to enable regulator: %d\n", err);
+			return err;
+		}
+		vibrator->vcc_on = true;
+	}
+
+	gpiod_set_value_cansleep(vibrator->gpio, 1);
+
+	return 0;
+}
+
+static void gpio_vibrator_stop(struct gpio_vibrator *vibrator)
+{
+	gpiod_set_value_cansleep(vibrator->gpio, 0);
+
+	if (vibrator->vcc_on) {
+		regulator_disable(vibrator->vcc);
+		vibrator->vcc_on = false;
+	}
+}
+
+static void gpio_vibrator_play_work(struct work_struct *work)
+{
+	struct gpio_vibrator *vibrator =
+		container_of(work, struct gpio_vibrator, play_work);
+
+	if (vibrator->running)
+		gpio_vibrator_start(vibrator);
+	else
+		gpio_vibrator_stop(vibrator);
+}
+
+static int gpio_vibrator_play_effect(struct input_dev *dev, void *data,
+				     struct ff_effect *effect)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(dev);
+
+	int level = effect->u.rumble.strong_magnitude;
+
+	if (!level)
+		level = effect->u.rumble.weak_magnitude;
+
+	if (level)
+		vibrator->running = true;
+	else
+		vibrator->running = false;
+
+	schedule_work(&vibrator->play_work);
+
+	return 0;
+}
+
+static void gpio_vibrator_close(struct input_dev *input)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(input);
+
+	cancel_work_sync(&vibrator->play_work);
+	gpio_vibrator_stop(vibrator);
+	vibrator->running = false;
+}
+
+static int gpio_vibrator_probe(struct platform_device *pdev)
+{
+	struct gpio_vibrator *vibrator;
+	int err;
+
+	vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
+	if (!vibrator)
+		return -ENOMEM;
+
+	vibrator->input = devm_input_allocate_device(&pdev->dev);
+	if (!vibrator->input)
+		return -ENOMEM;
+
+	vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
+	err = PTR_ERR_OR_ZERO(vibrator->vcc);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request regulator: %d\n",
+				err);
+		return err;
+	}
+
+	vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	err = PTR_ERR_OR_ZERO(vibrator->gpio);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request main gpio: %d\n",
+				err);
+		return err;
+	}
+
+	INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work);
+
+	vibrator->input->name = "gpio-vibrator";
+	vibrator->input->id.bustype = BUS_HOST;
+	vibrator->input->close = gpio_vibrator_close;
+
+	input_set_drvdata(vibrator->input, vibrator);
+	input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
+
+	err = input_ff_create_memless(vibrator->input, NULL,
+				      gpio_vibrator_play_effect);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't create FF dev: %d\n", err);
+		return err;
+	}
+
+	err = input_register_device(vibrator->input);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't register input dev: %d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	cancel_work_sync(&vibrator->play_work);
+	if (vibrator->running)
+		gpio_vibrator_stop(vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_resume(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	if (vibrator->running)
+		gpio_vibrator_start(vibrator);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(gpio_vibrator_pm_ops,
+			 gpio_vibrator_suspend, gpio_vibrator_resume);
+
+#ifdef CONFIG_OF
+static const struct of_device_id gpio_vibra_dt_match_table[] = {
+	{ .compatible = "gpio-vibrator" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table);
+#endif
+
+static struct platform_driver gpio_vibrator_driver = {
+	.probe	= gpio_vibrator_probe,
+	.driver	= {
+		.name	= "gpio-vibrator",
+		.pm	= &gpio_vibrator_pm_ops,
+		.of_match_table = of_match_ptr(gpio_vibra_dt_match_table),
+	},
+};
+module_platform_driver(gpio_vibrator_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xy>");
+MODULE_DESCRIPTION("GPIO vibrator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio-vibrator");
-- 
2.21.0


^ permalink raw reply	[relevance 71%]

* [PATCH v4 3/3] ARM: dts: msm8974-FP2: Add vibration motor
  2019-04-20 12:23 93% [PATCH v4 " Luca Weiss
  2019-04-20 12:23 71% ` [PATCH v4 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
@ 2019-04-20 12:23 99% ` Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-20 12:23 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index 643c57f84818..bf402ae39226 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -50,6 +50,12 @@
 		};
 	};
 
+	vibrator {
+		compatible = "gpio-vibrator";
+		enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+		vcc-supply = <&pm8941_l18>;
+	};
+
 	smd {
 		rpm {
 			rpm_requests {
-- 
2.21.0


^ permalink raw reply	[relevance 99%]

* [PATCH v5 1/3] dt-bindings: input: add GPIO controllable vibrator
@ 2019-04-26 19:47 93% Luca Weiss
  2019-04-26 19:47 72% ` [PATCH v5 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
  2019-04-26 19:47 99% ` [PATCH v5 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
  0 siblings, 2 replies; 84+ results
From: Luca Weiss @ 2019-04-26 19:47 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changes for v5:
- Simply compatible property definition
- Remove reference to regulator schema

 .../bindings/input/gpio-vibrator.yaml         | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-vibrator.yaml

diff --git a/Documentation/devicetree/bindings/input/gpio-vibrator.yaml b/Documentation/devicetree/bindings/input/gpio-vibrator.yaml
new file mode 100644
index 000000000000..903475f52dbd
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-vibrator.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bindings/input/gpio-vibrator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIO vibrator
+
+maintainers:
+  - Luca Weiss <luca@z3ntu.xyz>
+
+description: |+
+  Registers a GPIO device as vibrator, where the on/off capability is controlled by a GPIO.
+
+properties:
+  compatible:
+    const: gpio-vibrator
+
+  enable-gpios:
+    maxItems: 1
+
+  vcc-supply:
+    description: Regulator that provides power
+
+required:
+  - compatible
+  - enable-gpios
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    vibrator {
+        compatible = "gpio-vibrator";
+        enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+        vcc-supply = <&pm8941_l18>;
+    };
-- 
2.21.0


^ permalink raw reply	[relevance 93%]

* [PATCH v5 3/3] ARM: dts: msm8974-FP2: Add vibration motor
  2019-04-26 19:47 93% [PATCH v5 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
  2019-04-26 19:47 72% ` [PATCH v5 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
@ 2019-04-26 19:47 99% ` Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-26 19:47 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Add a node describing the vibration motor on the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index 643c57f84818..bf402ae39226 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -50,6 +50,12 @@
 		};
 	};
 
+	vibrator {
+		compatible = "gpio-vibrator";
+		enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
+		vcc-supply = <&pm8941_l18>;
+	};
+
 	smd {
 		rpm {
 			rpm_requests {
-- 
2.21.0


^ permalink raw reply	[relevance 99%]

* [PATCH v5 2/3] Input: add a driver for GPIO controllable vibrators
  2019-04-26 19:47 93% [PATCH v5 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
@ 2019-04-26 19:47 72% ` Luca Weiss
  2019-04-26 19:47 99% ` [PATCH v5 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2019-04-26 19:47 UTC (permalink / raw)
  Cc: Dmitry Torokhov, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Pascal PAILLET-LME, Coly Li, Lee Jones,
	Xiaotong Lu, Brian Masney, Rob Herring, Baolin Wang, David Brown,
	open list:ARM/QUALCOMM SUPPORT, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, Luca Weiss

Provide a simple driver for GPIO controllable vibrators.
It will be used by the Fairphone 2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/input/misc/Kconfig      |  12 ++
 drivers/input/misc/Makefile     |   1 +
 drivers/input/misc/gpio-vibra.c | 209 ++++++++++++++++++++++++++++++++
 3 files changed, 222 insertions(+)
 create mode 100644 drivers/input/misc/gpio-vibra.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index e15ed1bb8558..6dfe9e2fe5b1 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -290,6 +290,18 @@ config INPUT_GPIO_DECODER
 	 To compile this driver as a module, choose M here: the module
 	 will be called gpio_decoder.
 
+config INPUT_GPIO_VIBRA
+	tristate "GPIO vibrator support"
+	depends on GPIOLIB || COMPILE_TEST
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here to get support for GPIO based vibrator devices.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called gpio-vibra.
+
 config INPUT_IXP4XX_BEEPER
 	tristate "IXP4XX Beeper support"
 	depends on ARCH_IXP4XX
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index b936c5b1d4ac..f38ebbdb05e2 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
 obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
 obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
+obj-$(CONFIG_INPUT_GPIO_VIBRA)		+= gpio-vibra.o
 obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IMS_PCU)		+= ims-pcu.o
diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c
new file mode 100644
index 000000000000..b76c81015de9
--- /dev/null
+++ b/drivers/input/misc/gpio-vibra.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  GPIO vibrator driver
+ *
+ *  Copyright (C) 2019 Luca Weiss <luca@z3ntu.xyz>
+ *
+ *  Based on PWM vibrator driver:
+ *  Copyright (C) 2017 Collabora Ltd.
+ *
+ *  Based on previous work from:
+ *  Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com>
+ *
+ *  Based on PWM beeper driver:
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+struct gpio_vibrator {
+	struct input_dev *input;
+	struct gpio_desc *gpio;
+	struct regulator *vcc;
+
+	struct work_struct play_work;
+	bool running;
+	bool vcc_on;
+};
+
+static int gpio_vibrator_start(struct gpio_vibrator *vibrator)
+{
+	struct device *pdev = vibrator->input->dev.parent;
+	int err;
+
+	if (!vibrator->vcc_on) {
+		err = regulator_enable(vibrator->vcc);
+		if (err) {
+			dev_err(pdev, "failed to enable regulator: %d\n", err);
+			return err;
+		}
+		vibrator->vcc_on = true;
+	}
+
+	gpiod_set_value_cansleep(vibrator->gpio, 1);
+
+	return 0;
+}
+
+static void gpio_vibrator_stop(struct gpio_vibrator *vibrator)
+{
+	gpiod_set_value_cansleep(vibrator->gpio, 0);
+
+	if (vibrator->vcc_on) {
+		regulator_disable(vibrator->vcc);
+		vibrator->vcc_on = false;
+	}
+}
+
+static void gpio_vibrator_play_work(struct work_struct *work)
+{
+	struct gpio_vibrator *vibrator =
+		container_of(work, struct gpio_vibrator, play_work);
+
+	if (vibrator->running)
+		gpio_vibrator_start(vibrator);
+	else
+		gpio_vibrator_stop(vibrator);
+}
+
+static int gpio_vibrator_play_effect(struct input_dev *dev, void *data,
+				     struct ff_effect *effect)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(dev);
+
+	int level = effect->u.rumble.strong_magnitude;
+
+	if (!level)
+		level = effect->u.rumble.weak_magnitude;
+
+	if (level)
+		vibrator->running = true;
+	else
+		vibrator->running = false;
+
+	schedule_work(&vibrator->play_work);
+
+	return 0;
+}
+
+static void gpio_vibrator_close(struct input_dev *input)
+{
+	struct gpio_vibrator *vibrator = input_get_drvdata(input);
+
+	cancel_work_sync(&vibrator->play_work);
+	gpio_vibrator_stop(vibrator);
+	vibrator->running = false;
+}
+
+static int gpio_vibrator_probe(struct platform_device *pdev)
+{
+	struct gpio_vibrator *vibrator;
+	int err;
+
+	vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
+	if (!vibrator)
+		return -ENOMEM;
+
+	vibrator->input = devm_input_allocate_device(&pdev->dev);
+	if (!vibrator->input)
+		return -ENOMEM;
+
+	vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
+	err = PTR_ERR_OR_ZERO(vibrator->vcc);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request regulator: %d\n",
+				err);
+		return err;
+	}
+
+	vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	err = PTR_ERR_OR_ZERO(vibrator->gpio);
+	if (err) {
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request main gpio: %d\n",
+				err);
+		return err;
+	}
+
+	INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work);
+
+	vibrator->input->name = "gpio-vibrator";
+	vibrator->input->id.bustype = BUS_HOST;
+	vibrator->input->close = gpio_vibrator_close;
+
+	input_set_drvdata(vibrator->input, vibrator);
+	input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
+
+	err = input_ff_create_memless(vibrator->input, NULL,
+				      gpio_vibrator_play_effect);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't create FF dev: %d\n", err);
+		return err;
+	}
+
+	err = input_register_device(vibrator->input);
+	if (err) {
+		dev_err(&pdev->dev, "Couldn't register input dev: %d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	cancel_work_sync(&vibrator->play_work);
+	if (vibrator->running)
+		gpio_vibrator_stop(vibrator);
+
+	return 0;
+}
+
+static int __maybe_unused gpio_vibrator_resume(struct device *dev)
+{
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
+
+	if (vibrator->running)
+		gpio_vibrator_start(vibrator);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(gpio_vibrator_pm_ops,
+			 gpio_vibrator_suspend, gpio_vibrator_resume);
+
+#ifdef CONFIG_OF
+static const struct of_device_id gpio_vibra_dt_match_table[] = {
+	{ .compatible = "gpio-vibrator" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table);
+#endif
+
+static struct platform_driver gpio_vibrator_driver = {
+	.probe	= gpio_vibrator_probe,
+	.driver	= {
+		.name	= "gpio-vibrator",
+		.pm	= &gpio_vibrator_pm_ops,
+		.of_match_table = of_match_ptr(gpio_vibra_dt_match_table),
+	},
+};
+module_platform_driver(gpio_vibrator_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xy>");
+MODULE_DESCRIPTION("GPIO vibrator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio-vibrator");
-- 
2.21.0


^ permalink raw reply	[relevance 72%]

* [PATCH] arm64: dts: allwinner: a64: Add lradc node
@ 2019-05-18 17:09 99% Luca Weiss
    0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-05-18 17:09 UTC (permalink / raw)
  Cc: Luca Weiss, Maxime Ripard, Chen-Yu Tsai, Rob Herring,
	Mark Rutland, moderated list:ARM/Allwinner sunXi SoC support,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

Add a node describing the KEYADC on the A64.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 7734f70e1057..dc1bf8c1afb5 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -704,6 +704,13 @@
 			status = "disabled";
 		};
 
+		lradc: lradc@1c21800 {
+			compatible = "allwinner,sun4i-a10-lradc-keys";
+			reg = <0x01c21800 0x100>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
 		i2s0: i2s@1c22000 {
 			#sound-dai-cells = <0>;
 			compatible = "allwinner,sun50i-a64-i2s",
-- 
2.21.0


^ permalink raw reply	[relevance 99%]

* Re: [PATCH] arm64: dts: allwinner: a64: Add lradc node
  @ 2019-05-24  8:35 99%     ` Luca Weiss
    0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-05-24  8:35 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, Mark Rutland,
	moderated list:ARM/Allwinner sunXi SoC support,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

On Dienstag, 21. Mai 2019 16:25:44 CEST Maxime Ripard wrote:
> On Tue, May 21, 2019 at 03:52:47PM +0200, luca@z3ntu.xyz wrote:
> > On May 21, 2019 3:09:55 PM GMT+02:00, Maxime Ripard 
<maxime.ripard@bootlin.com> wrote:
> > >On Tue, May 21, 2019 at 08:43:45AM +0200, luca@z3ntu.xyz wrote:
> > >> On May 20, 2019 1:07:42 PM GMT+02:00, Maxime Ripard
> > >
> > ><maxime.ripard@bootlin.com> wrote:
> > >> >On Sat, May 18, 2019 at 07:09:30PM +0200, Luca Weiss wrote:
> > >> >> Add a node describing the KEYADC on the A64.
> > >> >> 
> > >> >> Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > >> >> ---
> > >> >> 
> > >> >>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 7 +++++++
> > >> >>  1 file changed, 7 insertions(+)
> > >> >> 
> > >> >> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > >> >
> > >> >b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > >> >
> > >> >> index 7734f70e1057..dc1bf8c1afb5 100644
> > >> >> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > >> >> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > >> >> @@ -704,6 +704,13 @@
> > >> >> 
> > >> >>  			status = "disabled";
> > >> >>  		
> > >> >>  		};
> > >> >> 
> > >> >> +		lradc: lradc@1c21800 {
> > >> >> +			compatible = "allwinner,sun4i-a10-lradc-
keys";
> > >> >> +			reg = <0x01c21800 0x100>;
> > >> >> +			interrupts = <GIC_SPI 30 
IRQ_TYPE_LEVEL_HIGH>;
> > >> >> +			status = "disabled";
> > >> >> +		};
> > >> >> +
> > >> >
> > >> >The controller is pretty different on the A64 compared to the A10.
> > >
> > >The
> > >
> > >> >A10 has two channels for example, while the A64 has only one.
> > >> >
> > >> >It looks like the one in the A83t though, so you can use that
> > >> >compatible instead.
> > >> 
> > >> Looking at the patch for the A83t, the only difference is that it
> > >> uses a 3/4 instead of a 2/3 voltage divider, nothing is changed with
> > >> the channels.
> > >
> > >I guess you can reuse the A83t compatible here then, and a more
> > >specific a64 compatible in case we ever need to fix this.
> > >
> > >> But I'm also not sure which one (or a different one)
> > >> is used from looking at the "A64 User Manual".
> > >
> > >I'm sorry, what are you referring to with "one" in that sentence?
> > 
> > Sorry, I meant I didn't find anything in the A64 user manual whether
> > a 3/4 or a 2/3 voltage divider (or one with different values) is
> > used on the A64.
> 
> Ok :)
> 
> I guess you can just reuse the A83t compatible then, together with the
> A64's.
> 
> Maxime
> 
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

Hi Maxime,
I'd submit a v2 with these changes to v1 then:
                lradc: lradc@1c21800 {
-                       compatible = "allwinner,sun4i-a10-lradc-keys";
-                       reg = <0x01c21800 0x100>;
+                       compatible = "allwinner,sun50i-a64-lradc-keys",
+                                    "allwinner,sun8i-a83t-r-lradc";
+                       reg = <0x01c21800 0x400>;
                        interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
Does that look okay?
The reg change is due to me not spotting the address being 0x01C2 
1800---0x01C2 1BFF, so the size should be 0x400 and not 0x100.

Thanks for the feedback,
Luca



^ permalink raw reply	[relevance 99%]

* Re: [PATCH] arm64: dts: allwinner: a64: Add lradc node
  @ 2019-05-31 10:27 99%         ` Luca Weiss
    0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-05-31 10:27 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, Mark Rutland,
	moderated list:ARM/Allwinner sunXi SoC support,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

On Freitag, 24. Mai 2019 11:20:01 CEST Maxime Ripard wrote:
> 
> It would be great to drop the -keys from the compatible, and to
> document the bindings
> 
> Looks good otherwise
> 
> Maxime

Hi again,

So I should just document the "allwinner,sun50i-a64-lradc" string in 
Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt ? Don't I also 
have to add the compatible to the driver code then? Just adding the a64 
compatible to a dts wouldn't work without that.

Thanks, Luca




^ permalink raw reply	[relevance 99%]

* Re: [PATCH] arm64: dts: allwinner: a64: Add lradc node
  @ 2019-06-03 15:20 99%             ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-06-03 15:20 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, Mark Rutland,
	moderated list:ARM/Allwinner sunXi SoC support,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list


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

On Montag, 3. Juni 2019 09:42:47 CEST Maxime Ripard wrote:
> Hi,
> 
> On Fri, May 31, 2019 at 12:27:55PM +0200, Luca Weiss wrote:
> > On Freitag, 24. Mai 2019 11:20:01 CEST Maxime Ripard wrote:
> > > It would be great to drop the -keys from the compatible, and to
> > > document the bindings
> > > 
> > > Looks good otherwise
> > > 
> > > Maxime
> > 
> > So I should just document the "allwinner,sun50i-a64-lradc" string in
> > Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt ? Don't I
> > also
> > have to add the compatible to the driver code then? Just adding the a64
> > compatible to a dts wouldn't work without that.
> 
> What I meant was that you needed both, something like:
> 
> compatible = "allwinner,sun50i-a64-lradc", "allwinner,sun8i-a83t-lradc";
> 
> That way, the OS will try to match a driver for the A64 compatible if
> any, and fallback to the A83's otherwise. And since we don't have any
> quirk at the moment, there's no change needed to the driver.
> 
> Maxime
> 
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

Hi Maxime,
sorry for the long back and forth, I hope I understood you correctly now.
Here's what I would submit as v2 then (I'll split the two files into seperate 
patches as the devicetree documentation suggests)

Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt:
  - compatible: should be one of the following string:
                "allwinner,sun4i-a10-lradc-keys"
                "allwinner,sun8i-a83t-r-lradc"
+               "allwinner,sun50i-a64-lradc", "allwinner,sun8i-a83t-r-lradc"

arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi:
+               lradc: lradc@1c21800 {
+                       compatible = "allwinner,sun50i-a64-lradc",
+                                    "allwinner,sun8i-a83t-r-lradc";
+                       reg = <0x01c21800 0x400>;
+                       interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+

Thanks,
Luca

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[relevance 99%]

* [PATCH] iio: light: stk3310: Add support for stk3335
@ 2019-06-03 19:20 98% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-06-03 19:20 UTC (permalink / raw)
  Cc: Martijn Braam, Luca Weiss, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler,
	open list:IIO SUBSYSTEM AND DRIVERS, open list

From: Martijn Braam <martijn@brixit.nl>

The stk3335 light/proximity sensor is similar to the stk3310 and stk3311
sensors and works with the stk3310 driver.

Signed-off-by: Martijn Braam <martijn@brixit.nl>
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/iio/light/stk3310.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index 6e2a169da950..a25cc35f334e 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -40,6 +40,7 @@
 
 #define STK3310_CHIP_ID_VAL			0x13
 #define STK3311_CHIP_ID_VAL			0x1D
+#define STK3335_CHIP_ID_VAL			0x51
 #define STK3310_PSINT_EN			0x01
 #define STK3310_PS_MAX_VAL			0xFFFF
 
@@ -454,7 +455,8 @@ static int stk3310_init(struct iio_dev *indio_dev)
 		return ret;
 
 	if (chipid != STK3310_CHIP_ID_VAL &&
-	    chipid != STK3311_CHIP_ID_VAL) {
+	    chipid != STK3311_CHIP_ID_VAL &&
+	    chipid != STK3335_CHIP_ID_VAL) {
 		dev_err(&client->dev, "invalid chip id: 0x%x\n", chipid);
 		return -ENODEV;
 	}
@@ -666,6 +668,7 @@ static SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend, stk3310_resume);
 static const struct i2c_device_id stk3310_i2c_id[] = {
 	{"STK3310", 0},
 	{"STK3311", 0},
+	{"STK3335", 0},
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id);
@@ -673,6 +676,7 @@ MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id);
 static const struct acpi_device_id stk3310_acpi_id[] = {
 	{"STK3310", 0},
 	{"STK3311", 0},
+	{"STK3335", 0},
 	{}
 };
 
-- 
2.21.0


^ permalink raw reply	[relevance 98%]

* [PATCH] arm64: dts: allwinner: a64: Add lradc node
@ 2019-06-04 14:42 95% Luca Weiss
    0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-06-04 14:42 UTC (permalink / raw)
  Cc: Luca Weiss, Hans de Goede, Dmitry Torokhov, Rob Herring,
	Mark Rutland, Maxime Ripard, Chen-Yu Tsai,
	open list:SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/Allwinner sunXi SoC support, open list

Add a node describing the KEYADC on the A64.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 .../devicetree/bindings/input/sun4i-lradc-keys.txt        | 1 +
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi             | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
index 496125c6bfb7..507b737612ea 100644
--- a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
+++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
@@ -5,6 +5,7 @@ Required properties:
  - compatible: should be one of the following string:
 		"allwinner,sun4i-a10-lradc-keys"
 		"allwinner,sun8i-a83t-r-lradc"
+		"allwinner,sun50i-a64-lradc", "allwinner,sun8i-a83t-r-lradc"
  - reg: mmio address range of the chip
  - interrupts: interrupt to which the chip is connected
  - vref-supply: powersupply for the lradc reference voltage
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 7734f70e1057..3a42352b5c9f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -704,6 +704,14 @@
 			status = "disabled";
 		};
 
+		lradc: lradc@1c21800 {
+			compatible = "allwinner,sun50i-a64-lradc",
+				     "allwinner,sun8i-a83t-r-lradc";
+			reg = <0x01c21800 0x400>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
 		i2s0: i2s@1c22000 {
 			#sound-dai-cells = <0>;
 			compatible = "allwinner,sun50i-a64-i2s",
-- 
2.21.0


^ permalink raw reply	[relevance 95%]

* Re: [PATCH] arm64: dts: allwinner: a64: Add lradc node
  @ 2019-06-04 15:07 99%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-06-04 15:07 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Hans de Goede, Dmitry Torokhov, Rob Herring, Mark Rutland,
	Chen-Yu Tsai,
	open list:SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/Allwinner sunXi SoC support, open list


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

Hi Maxime,
sorry I forgot to mark it as a v2 and add the changelog to v1.

I've actually not split the patch into two on purpose as it's a pretty small 
change and the patch adding support for the A83T didn't split out the device 
tree changes - and recently in another patch of mine, the extra devicetree 
patch was squashed into the driver patch by the maintainer while merging. I'll 
fix this up asap.

Luca

On Dienstag, 4. Juni 2019 16:59:07 CEST Maxime Ripard wrote:
> Hi Luca,
> 
> On Tue, Jun 04, 2019 at 04:42:53PM +0200, Luca Weiss wrote:
> > Add a node describing the KEYADC on the A64.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> 
> You should have a changelog detailing which changes you made to your
> patch with the previous version, and why you made those changes (for
> example because we looked at the a83t datasheet and found the two
> controllers to be very similar).
> 
> > ---
> > 
> >  .../devicetree/bindings/input/sun4i-lradc-keys.txt        | 1 +
> >  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi             | 8 ++++++++
> >  2 files changed, 9 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
> > b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt index
> > 496125c6bfb7..507b737612ea 100644
> > --- a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
> > +++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
> > 
> > @@ -5,6 +5,7 @@ Required properties:
> >   - compatible: should be one of the following string:
> >  		"allwinner,sun4i-a10-lradc-keys"
> >  		"allwinner,sun8i-a83t-r-lradc"
> > 
> > +		"allwinner,sun50i-a64-lradc", "allwinner,sun8i-a83t-r-
lradc"
> > 
> >   - reg: mmio address range of the chip
> >   - interrupts: interrupt to which the chip is connected
> >   - vref-supply: powersupply for the lradc reference voltage
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index
> > 7734f70e1057..3a42352b5c9f 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > @@ -704,6 +704,14 @@
> > 
> >  			status = "disabled";
> >  		
> >  		};
> > 
> > +		lradc: lradc@1c21800 {
> > +			compatible = "allwinner,sun50i-a64-lradc",
> > +				     "allwinner,sun8i-a83t-r-
lradc";
> > +			reg = <0x01c21800 0x400>;
> > +			interrupts = <GIC_SPI 30 
IRQ_TYPE_LEVEL_HIGH>;
> > +			status = "disabled";
> > +		};
> > +
> 
> The bindings and the dt changes should be two different patches as
> well.
> 
> Thanks!
> Maxime
> 
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[relevance 99%]

* [PATCH v2 1/2] dt-bindings: input: sun4i-lradc-keys: Add A64 compatible
@ 2019-06-04 17:21 97% Luca Weiss
  2019-06-04 17:21 97% ` [PATCH v2 2/2] arm64: dts: allwinner: a64: Add lradc node Luca Weiss
  0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-06-04 17:21 UTC (permalink / raw)
  Cc: Luca Weiss, Hans de Goede, Dmitry Torokhov, Rob Herring,
	Mark Rutland, Maxime Ripard, Chen-Yu Tsai,
	open list:SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/Allwinner sunXi SoC support, open list,
	~martijnbraam/pmos-upstream

Add the A64 compatible with a fallback to the A83T compatible.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes from v1:
 - New patch. Document new compatible string.

 Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
index 496125c6bfb7..507b737612ea 100644
--- a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
+++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
@@ -5,6 +5,7 @@ Required properties:
  - compatible: should be one of the following string:
 		"allwinner,sun4i-a10-lradc-keys"
 		"allwinner,sun8i-a83t-r-lradc"
+		"allwinner,sun50i-a64-lradc", "allwinner,sun8i-a83t-r-lradc"
  - reg: mmio address range of the chip
  - interrupts: interrupt to which the chip is connected
  - vref-supply: powersupply for the lradc reference voltage
-- 
2.21.0


^ permalink raw reply	[relevance 97%]

* [PATCH v2 2/2] arm64: dts: allwinner: a64: Add lradc node
  2019-06-04 17:21 97% [PATCH v2 1/2] dt-bindings: input: sun4i-lradc-keys: Add A64 compatible Luca Weiss
@ 2019-06-04 17:21 97% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-06-04 17:21 UTC (permalink / raw)
  Cc: Luca Weiss, Hans de Goede, Dmitry Torokhov, Rob Herring,
	Mark Rutland, Maxime Ripard, Chen-Yu Tsai,
	open list:SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/Allwinner sunXi SoC support, open list,
	~martijnbraam/pmos-upstream

Add a node describing the KEYADC on the A64.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes since v1:
 - Use a a64 compatible with a fallback to the a83t one (the A64 also
   uses a 3/4 voltage divider, as is the case with the A83T)
 - Correct the reg property (size 0x100 => 0x400)

 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 8c5b521e6389..ba0ab1045e00 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -730,6 +730,14 @@
 			status = "disabled";
 		};
 
+		lradc: lradc@1c21800 {
+			compatible = "allwinner,sun50i-a64-lradc",
+				     "allwinner,sun8i-a83t-r-lradc";
+			reg = <0x01c21800 0x400>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
 		i2s0: i2s@1c22000 {
 			#sound-dai-cells = <0>;
 			compatible = "allwinner,sun50i-a64-i2s",
-- 
2.21.0


^ permalink raw reply	[relevance 97%]

* [PATCH] ARM: dts: msm8974-FP2: add reboot-mode node
@ 2019-06-20 22:58 99% Luca Weiss
    0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-06-20 22:58 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: ~martijnbraam/pmos-upstream, Luca Weiss, Andy Gross, David Brown,
	Rob Herring, Mark Rutland, devicetree, linux-kernel

This enables userspace to signal the bootloader to go into the
bootloader or recovery mode.

The magic values can be found in both the downstream kernel and the LK
kernel (bootloader).

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Sidenote: Why are there no userspace tools to be found that support
this? Anyways, we have one now in postmarketOS :)

 arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index 643c57f84818..f86736a6d77e 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -338,6 +338,20 @@
 			};
 		};
 	};
+
+	imem@fe805000 {
+		compatible = "syscon", "simple-mfd";
+		reg = <0xfe805000 0x1000>;
+
+		reboot-mode {
+			compatible = "syscon-reboot-mode";
+			offset = <0x65c>;
+
+			mode-normal	= <0x77665501>;
+			mode-bootloader	= <0x77665500>;
+			mode-recovery	= <0x77665502>;
+		};
+	};
 };
 
 &spmi_bus {
-- 
2.22.0


^ permalink raw reply	[relevance 99%]

* [PATCH] media: ov5640: Add support for flash and lens devices
@ 2019-06-21 17:20 99% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-06-21 17:20 UTC (permalink / raw)
  To: linux-media
  Cc: ~martijnbraam/pmos-upstream, Luca Weiss, Steve Longerbeam,
	Mauro Carvalho Chehab, linux-kernel

Parse async sub-devices related to the sensor by switching the async
sub-device registration function.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/media/i2c/ov5640.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 82d4ce93312c..0c6f890bc708 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -3054,7 +3054,7 @@ static int ov5640_probe(struct i2c_client *client,
 	if (ret)
 		goto entity_cleanup;
 
-	ret = v4l2_async_register_subdev(&sensor->sd);
+	ret = v4l2_async_register_subdev_sensor_common(&sensor->sd);
 	if (ret)
 		goto free_ctrls;
 
-- 
2.22.0


^ permalink raw reply	[relevance 99%]

* Re: [PATCH] ARM: dts: msm8974-FP2: add reboot-mode node
  @ 2019-06-21 19:25 99%   ` Luca Weiss
    0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-06-21 19:25 UTC (permalink / raw)
  To: Brian Masney
  Cc: linux-arm-msm, ~martijnbraam/pmos-upstream, Andy Gross,
	David Brown, Rob Herring, Mark Rutland, devicetree, linux-kernel


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

On Freitag, 21. Juni 2019 02:01:22 CEST you wrote:
> I think that it makes sense to put this snippet in qcom-msm8974.dtsi
> with a status of disabled, and then enable it in
> qcom-msm8974-fairphone-fp2.dts like so:
> 
> imem@fe805000 {
> 	status = "ok";
> };

Do you want me to put the whole node in the the dtsi file? Even though these 
values are the same, there are also custom vendor-specified values for specific 
phones.

This opens another question, which values we should put into the dts files. For 
example in the fairphone 2 bootloader source there's also the unused
#define ALARM_BOOT        0x77665503

and behind a #if VERIFIED_BOOT :
#define DM_VERITY_LOGGING    0x77665508
#define DM_VERITY_ENFORCING  0x77665509
#define DM_VERITY_KEYSCLEAR  0x7766550A

and 0x77665501 ("mode-normal") isn't used in the bootloader at all.

On the Linux kernel side, it has bootloader (0x77665500), recovery 
(0x77665502), rtc (0x77665503), oem-* (0x6f656d00 | somevalue), edl (some 
other addresses), and the else statements writes the 0x77665501 value in my 
patch.

> What's the pmOS utility that utilizes this? I'll test it on the Nexus 5.

"reboot-mode" at https://gitlab.com/postmarketOS/pmaports/merge_requests/442

> Thanks,
> 
> Brian


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[relevance 99%]

* [PATCH] ASoC: sunxi: sun50i-codec-analog: Add earpiece
@ 2019-07-02 19:16 88% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-07-02 19:16 UTC (permalink / raw)
  To: alsa-devel
  Cc: ~martijnbraam/pmos-upstream, Luca Weiss, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Maxime Ripard,
	Chen-Yu Tsai, Vasily Khoruzhick, linux-arm-kernel, linux-kernel

This adds the necessary registers and audio routes to play audio using
the Earpiece, that's supported on the A64.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
So, first of all: This is my first audio patch and I hope I didn't make
too many mistakes :) , especially with the routes at the bottom of
the patch.

What I'm really unsure about, is how the enable & mute registers should
be handled. Should I put both registers into a SOC_DOUBLE("Earpiece
Playback Switch",...)?

 sound/soc/sunxi/sun50i-codec-analog.c | 51 +++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index d105c90c3706..6c19fea992c5 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -49,6 +49,15 @@
 #define SUN50I_ADDA_OR_MIX_CTRL_DACR		1
 #define SUN50I_ADDA_OR_MIX_CTRL_DACL		0
 
+#define SUN50I_ADDA_EARPIECE_CTRL0	0x03
+#define SUN50I_ADDA_EARPIECE_CTRL0_EAR_RAMP_TIME	4
+#define SUN50I_ADDA_EARPIECE_CTRL0_ESPSR		0
+
+#define SUN50I_ADDA_EARPIECE_CTRL1	0x04
+#define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN	7
+#define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE	6
+#define SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL	0
+
 #define SUN50I_ADDA_LINEOUT_CTRL0	0x05
 #define SUN50I_ADDA_LINEOUT_CTRL0_LEN		7
 #define SUN50I_ADDA_LINEOUT_CTRL0_REN		6
@@ -172,6 +181,10 @@ static const DECLARE_TLV_DB_RANGE(sun50i_codec_lineout_vol_scale,
 	2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
 );
 
+static const DECLARE_TLV_DB_RANGE(sun50i_codec_earpiece_vol_scale,
+	0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
+	2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
+);
 
 /* volume / mute controls */
 static const struct snd_kcontrol_new sun50i_a64_codec_controls[] = {
@@ -225,6 +238,19 @@ static const struct snd_kcontrol_new sun50i_a64_codec_controls[] = {
 		   SUN50I_ADDA_LINEOUT_CTRL0_LEN,
 		   SUN50I_ADDA_LINEOUT_CTRL0_REN, 1, 0),
 
+	SOC_SINGLE_TLV("Earpiece Playback Volume",
+		       SUN50I_ADDA_EARPIECE_CTRL1,
+		       SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL, 0x1f, 0,
+		       sun50i_codec_earpiece_vol_scale),
+
+	SOC_SINGLE("Earpiece Playback Switch (enable)",
+		   SUN50I_ADDA_EARPIECE_CTRL1,
+		   SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN, 1, 0),
+
+	SOC_SINGLE("Earpiece Playback Switch",
+		   SUN50I_ADDA_EARPIECE_CTRL1,
+		   SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0),
+
 };
 
 static const char * const sun50i_codec_hp_src_enum_text[] = {
@@ -257,6 +283,20 @@ static const struct snd_kcontrol_new sun50i_codec_lineout_src[] = {
 		      sun50i_codec_lineout_src_enum),
 };
 
+static const char * const sun50i_codec_earpiece_src_enum_text[] = {
+	"DACR", "DACL", "Right Analog Mixer", "Left Analog Mixer",
+};
+
+static SOC_ENUM_SINGLE_DECL(sun50i_codec_earpiece_src_enum,
+			    SUN50I_ADDA_EARPIECE_CTRL0,
+			    SUN50I_ADDA_EARPIECE_CTRL0_ESPSR,
+			    sun50i_codec_earpiece_src_enum_text);
+
+static const struct snd_kcontrol_new sun50i_codec_earpiece_src[] = {
+	SOC_DAPM_ENUM("Earpiece Source Playback Route",
+		      sun50i_codec_earpiece_src_enum),
+};
+
 static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 	/* DAC */
 	SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL,
@@ -285,6 +325,10 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 			 SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src),
 	SND_SOC_DAPM_OUTPUT("LINEOUT"),
 
+	SND_SOC_DAPM_MUX("Earpiece Source Playback Route",
+			 SND_SOC_NOPM, 0, 0, sun50i_codec_earpiece_src),
+	SND_SOC_DAPM_OUTPUT("EARPIECE"),
+
 	/* Microphone inputs */
 	SND_SOC_DAPM_INPUT("MIC1"),
 
@@ -388,6 +432,13 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 	{ "Line Out Source Playback Route", "Mono Differential",
 		"Right Mixer" },
 	{ "LINEOUT", NULL, "Line Out Source Playback Route" },
+
+	/* Earpiece Routes */
+	{ "Earpiece Source Playback Route", "DACL", "Left DAC" },
+	{ "Earpiece Source Playback Route", "DACR", "Right DAC" },
+	{ "Earpiece Source Playback Route", "Left Analog Mixer", "Left Mixer" },
+	{ "Earpiece Source Playback Route", "Right Analog Mixer", "Right Mixer" },
+	{ "EARPIECE", NULL, "Earpiece Source Playback Route" },
 };
 
 static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
-- 
2.22.0


^ permalink raw reply	[relevance 88%]

* [PATCH 1/3] dt-bindings: Add vendor prefix for sensortek
@ 2019-07-03 18:05 97% Luca Weiss
  2019-07-03 18:05 94% ` [PATCH 2/3] dt-bindings: iio: light: add stk33xx Luca Weiss
  2019-07-03 18:05 97% ` [PATCH 3/3] iio: light: stk3310: Add device tree support Luca Weiss
  0 siblings, 2 replies; 84+ results
From: Luca Weiss @ 2019-07-03 18:05 UTC (permalink / raw)
  To: linux-iio
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Luca Weiss,
	Maxime Ripard, Mauro Carvalho Chehab, Hans Verkuil,
	Fabrizio Castro, Angus Ainslie (Purism),
	Vivek Unune, Hannes Schmelzer, Greg Kroah-Hartman,
	Thomas Gleixner, Allison Randal, Martijn Braam, devicetree,
	linux-kernel, ~martijnbraam/pmos-upstream, Chris Paterson,
	Michael Tretter

Sensortek Technology Corp. produces Proximity Sensors with ALS and
Accelerometers.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
This patch series depends on "iio: light: stk3310: Add support for
stk3335", that's curerntly in linux-next.

 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 342bb23e0a73..d197c9609ea7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -813,6 +813,8 @@ patternProperties:
     description: Semtech Corporation
   "^sensirion,.*":
     description: Sensirion AG
+  "^sensortek,.*":
+    description: Sensortek Technology Corporation
   "^sff,.*":
     description: Small Form Factor Committee
   "^sgd,.*":
-- 
2.22.0


^ permalink raw reply	[relevance 97%]

* [PATCH 2/3] dt-bindings: iio: light: add stk33xx
  2019-07-03 18:05 97% [PATCH 1/3] dt-bindings: Add vendor prefix for sensortek Luca Weiss
@ 2019-07-03 18:05 94% ` Luca Weiss
  2019-07-03 18:05 97% ` [PATCH 3/3] iio: light: stk3310: Add device tree support Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2019-07-03 18:05 UTC (permalink / raw)
  To: linux-iio
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Luca Weiss,
	Maxime Ripard, Mauro Carvalho Chehab, Hans Verkuil,
	Fabrizio Castro, Angus Ainslie (Purism),
	Vivek Unune, Hannes Schmelzer, Greg Kroah-Hartman,
	Thomas Gleixner, Allison Randal, Martijn Braam, devicetree,
	linux-kernel, ~martijnbraam/pmos-upstream

Add binding documentation for the stk33xx family of ambient light
sensors.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 .../bindings/iio/light/stk33xx.yaml           | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/light/stk33xx.yaml

diff --git a/Documentation/devicetree/bindings/iio/light/stk33xx.yaml b/Documentation/devicetree/bindings/iio/light/stk33xx.yaml
new file mode 100644
index 000000000000..aae8a6d627c9
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/light/stk33xx.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/light/stk33xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: |
+  Sensortek STK33xx I2C Ambient Light and Proximity sensor
+
+maintainers:
+  - Jonathan Cameron <jic23@kernel.org>
+
+description: |
+  Ambient light and proximity sensor over an i2c interface.
+
+properties:
+  compatible:
+    enum:
+      - sensortek,stk3310
+      - sensortek,stk3311
+      - sensortek,stk3335
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        stk3310@48 {
+                compatible = "sensortek,stk3310";
+                reg = <0x48>;
+                interrupt-parent = <&gpio1>;
+                interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+        };
+    };
+...
-- 
2.22.0


^ permalink raw reply	[relevance 94%]

* [PATCH 3/3] iio: light: stk3310: Add device tree support
  2019-07-03 18:05 97% [PATCH 1/3] dt-bindings: Add vendor prefix for sensortek Luca Weiss
  2019-07-03 18:05 94% ` [PATCH 2/3] dt-bindings: iio: light: add stk33xx Luca Weiss
@ 2019-07-03 18:05 97% ` Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2019-07-03 18:05 UTC (permalink / raw)
  To: linux-iio
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Luca Weiss,
	Maxime Ripard, Mauro Carvalho Chehab, Hans Verkuil,
	Fabrizio Castro, Angus Ainslie (Purism),
	Vivek Unune, Hannes Schmelzer, Greg Kroah-Hartman,
	Thomas Gleixner, Allison Randal, Martijn Braam, devicetree,
	linux-kernel, ~martijnbraam/pmos-upstream, Kate Stewart

Add device tree support for the stk33xx family of ambient light sensors.

Tested-by: Martijn Braam <martijn@brixit.nl>
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/iio/light/stk3310.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index b955183edfe8..185c24a75ae6 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -679,9 +679,18 @@ static const struct acpi_device_id stk3310_acpi_id[] = {
 
 MODULE_DEVICE_TABLE(acpi, stk3310_acpi_id);
 
+static const struct of_device_id stk3310_of_match[] = {
+	{ .compatible = "sensortek,stk3310", },
+	{ .compatible = "sensortek,stk3311", },
+	{ .compatible = "sensortek,stk3335", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, stk3310_of_match);
+
 static struct i2c_driver stk3310_driver = {
 	.driver = {
 		.name = "stk3310",
+		.of_match_table = stk3310_of_match,
 		.pm = STK3310_PM_OPS,
 		.acpi_match_table = ACPI_PTR(stk3310_acpi_id),
 	},
-- 
2.22.0


^ permalink raw reply	[relevance 97%]

* [PATCH v2] ASoC: sunxi: sun50i-codec-analog: Add earpiece
@ 2019-07-03 18:48 89% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-07-03 18:48 UTC (permalink / raw)
  To: alsa-devel
  Cc: ~martijnbraam/pmos-upstream, Luca Weiss, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Maxime Ripard,
	Chen-Yu Tsai, Vasily Khoruzhick, linux-arm-kernel, linux-kernel

This adds the necessary registers and audio routes to play audio using
the Earpiece, that's supported on the A64.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes v1 -> v2:
* Make the earpiece enable register a DAPM widget
* Adjust the audio routes to include the new Earpiece Amp widget
* Left/Right Analog Mixer => Left/Right Mixer

 sound/soc/sunxi/sun50i-codec-analog.c | 50 +++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index d105c90c3706..6d1de565350e 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -49,6 +49,15 @@
 #define SUN50I_ADDA_OR_MIX_CTRL_DACR		1
 #define SUN50I_ADDA_OR_MIX_CTRL_DACL		0
 
+#define SUN50I_ADDA_EARPIECE_CTRL0	0x03
+#define SUN50I_ADDA_EARPIECE_CTRL0_EAR_RAMP_TIME	4
+#define SUN50I_ADDA_EARPIECE_CTRL0_ESPSR		0
+
+#define SUN50I_ADDA_EARPIECE_CTRL1	0x04
+#define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN	7
+#define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE	6
+#define SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL	0
+
 #define SUN50I_ADDA_LINEOUT_CTRL0	0x05
 #define SUN50I_ADDA_LINEOUT_CTRL0_LEN		7
 #define SUN50I_ADDA_LINEOUT_CTRL0_REN		6
@@ -172,6 +181,10 @@ static const DECLARE_TLV_DB_RANGE(sun50i_codec_lineout_vol_scale,
 	2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
 );
 
+static const DECLARE_TLV_DB_RANGE(sun50i_codec_earpiece_vol_scale,
+	0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
+	2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
+);
 
 /* volume / mute controls */
 static const struct snd_kcontrol_new sun50i_a64_codec_controls[] = {
@@ -225,6 +238,15 @@ static const struct snd_kcontrol_new sun50i_a64_codec_controls[] = {
 		   SUN50I_ADDA_LINEOUT_CTRL0_LEN,
 		   SUN50I_ADDA_LINEOUT_CTRL0_REN, 1, 0),
 
+	SOC_SINGLE_TLV("Earpiece Playback Volume",
+		       SUN50I_ADDA_EARPIECE_CTRL1,
+		       SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL, 0x1f, 0,
+		       sun50i_codec_earpiece_vol_scale),
+
+	SOC_SINGLE("Earpiece Playback Switch",
+		   SUN50I_ADDA_EARPIECE_CTRL1,
+		   SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0),
+
 };
 
 static const char * const sun50i_codec_hp_src_enum_text[] = {
@@ -257,6 +279,20 @@ static const struct snd_kcontrol_new sun50i_codec_lineout_src[] = {
 		      sun50i_codec_lineout_src_enum),
 };
 
+static const char * const sun50i_codec_earpiece_src_enum_text[] = {
+	"DACR", "DACL", "Right Mixer", "Left Mixer",
+};
+
+static SOC_ENUM_SINGLE_DECL(sun50i_codec_earpiece_src_enum,
+			    SUN50I_ADDA_EARPIECE_CTRL0,
+			    SUN50I_ADDA_EARPIECE_CTRL0_ESPSR,
+			    sun50i_codec_earpiece_src_enum_text);
+
+static const struct snd_kcontrol_new sun50i_codec_earpiece_src[] = {
+	SOC_DAPM_ENUM("Earpiece Source Playback Route",
+		      sun50i_codec_earpiece_src_enum),
+};
+
 static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 	/* DAC */
 	SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL,
@@ -285,6 +321,12 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 			 SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src),
 	SND_SOC_DAPM_OUTPUT("LINEOUT"),
 
+	SND_SOC_DAPM_MUX("Earpiece Source Playback Route",
+			 SND_SOC_NOPM, 0, 0, sun50i_codec_earpiece_src),
+	SND_SOC_DAPM_OUT_DRV("Earpiece Amp", SUN50I_ADDA_EARPIECE_CTRL1,
+			     SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN, 0, NULL, 0),
+	SND_SOC_DAPM_OUTPUT("EARPIECE"),
+
 	/* Microphone inputs */
 	SND_SOC_DAPM_INPUT("MIC1"),
 
@@ -388,6 +430,14 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 	{ "Line Out Source Playback Route", "Mono Differential",
 		"Right Mixer" },
 	{ "LINEOUT", NULL, "Line Out Source Playback Route" },
+
+	/* Earpiece Routes */
+	{ "Earpiece Source Playback Route", "DACL", "Left DAC" },
+	{ "Earpiece Source Playback Route", "DACR", "Right DAC" },
+	{ "Earpiece Source Playback Route", "Left Mixer", "Left Mixer" },
+	{ "Earpiece Source Playback Route", "Right Mixer", "Right Mixer" },
+	{ "Earpiece Amp", NULL, "Earpiece Source Playback Route" },
+	{ "EARPIECE", NULL, "Earpiece Amp" },
 };
 
 static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
-- 
2.22.0


^ permalink raw reply	[relevance 89%]

* Re: [PATCH] ARM: dts: msm8974-FP2: add reboot-mode node
  @ 2019-07-13 11:26 98%       ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-07-13 11:26 UTC (permalink / raw)
  To: Brian Masney
  Cc: linux-arm-msm, ~martijnbraam/pmos-upstream, Andy Gross,
	David Brown, Rob Herring, Mark Rutland, devicetree, linux-kernel

Hi Brian,
how about something like that (formatting is surely broken because I'm not 
sending this with git-send-email^^)?

I'd says this should be work fine with all devices as all modes are defined in 
the device-specific dts but the reg and offset values are in the board dts. 
Should I also add a status = "disabled" to the reboot-mode node in the board 
dts?

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/
dts/qcom-msm8974-fairphone-fp2.dts
index 643c57f84818..ff4a3e0aa746 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -338,6 +338,16 @@
 			};
 		};
 	};
+
+	imem@fe805000 {
+		status = "okay";
+
+		reboot-mode {
+			mode-normal	= <0x77665501>;
+			mode-bootloader	= <0x77665500>;
+			mode-recovery	= <0x77665502>;
+		};
+	};
 };
 
 &spmi_bus {
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-
msm8974.dtsi
index 45b5c8ef0374..1927430bded7 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1085,6 +1085,17 @@
 				};
 			};
 		};
+
+		imem@fe805000 {
+			status = "disabled";
+			compatible = "syscon", "simple-mfd";
+			reg = <0xfe805000 0x1000>;
+
+			reboot-mode {
+				compatible = "syscon-reboot-mode";
+				offset = <0x65c>;
+			};
+		};
 	};
 
 	smd {


Regards,
Luca



^ permalink raw reply	[relevance 98%]

* [PATCH v2] ARM: dts: msm8974-FP2: add reboot-mode node
@ 2019-07-13 15:48 98% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-07-13 15:48 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: ~martijnbraam/pmos-upstream, Luca Weiss, Brian Masney,
	Andy Gross, David Brown, Rob Herring, Mark Rutland, devicetree,
	linux-kernel

This enables userspace to signal the bootloader to go into the
bootloader or recovery mode.

The magic values can be found in both the downstream kernel and the LK
kernel (bootloader).

Reviewed-by: Brian Masney <masneyb@onstation.org>
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes v1 -> v2:
- Move the majority of the node into the board dts, just keep the magic
  values in the device-specific dts.

 arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 10 ++++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi              | 11 +++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index 643c57f84818..ff4a3e0aa746 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -338,6 +338,16 @@
 			};
 		};
 	};
+
+	imem@fe805000 {
+		status = "okay";
+
+		reboot-mode {
+			mode-normal	= <0x77665501>;
+			mode-bootloader	= <0x77665500>;
+			mode-recovery	= <0x77665502>;
+		};
+	};
 };
 
 &spmi_bus {
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 45b5c8ef0374..1927430bded7 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1085,6 +1085,17 @@
 				};
 			};
 		};
+
+		imem@fe805000 {
+			status = "disabled";
+			compatible = "syscon", "simple-mfd";
+			reg = <0xfe805000 0x1000>;
+
+			reboot-mode {
+				compatible = "syscon-reboot-mode";
+				offset = <0x65c>;
+			};
+		};
 	};
 
 	smd {
-- 
2.22.0


^ permalink raw reply	[relevance 98%]

* Re: [PATCH 12/15] arm64: dts: msm8974: thermal: Add interrupt support
  @ 2019-07-29  9:03 99%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-07-29  9:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Amit Kucheria, linux-arm-msm, bjorn.andersson, edubezval,
	andy.gross, Andy Gross, Daniel Lezcano, Mark Rutland,
	Rob Herring, Zhang Rui, masneyb, devicetree


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

On Freitag, 26. Juli 2019 00:18:47 CEST Amit Kucheria wrote:
> Register upper-lower interrupt for the tsens controller.
> 
> Signed-off-by: Amit Kucheria <amit.kucheria@linaro.org>
> ---
> Cc: masneyb@onstation.org
> 
>  arch/arm/boot/dts/qcom-msm8974.dtsi | 36 +++++++++++++++--------------
>  1 file changed, 19 insertions(+), 17 deletions(-)
> 

Hi, the title of this patch should be "arm" and not "arm64".

Luca

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[relevance 99%]

* Re: [PATCH 00/15] thermal: qcom: tsens: Add interrupt support
  @ 2019-07-29  9:32 99%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-07-29  9:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Brian Masney, Amit Kucheria, linux-arm-msm, Bjorn Andersson,
	Eduardo Valentin, Andy Gross, Andy Gross, Daniel Lezcano,
	Mark Rutland, Rob Herring, Zhang Rui, Marc Gonzalez,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux PM list


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

On Montag, 29. Juli 2019 11:07:35 CEST Brian Masney wrote:
> On Sat, Jul 27, 2019 at 12:58:54PM +0530, Amit Kucheria wrote:
> > On Fri, Jul 26, 2019 at 4:59 PM Brian Masney <masneyb@onstation.org> wrote:
> > > On Fri, Jul 26, 2019 at 04:40:16PM +0530, Amit Kucheria wrote:
> > > > How well does cpufreq work on 8974? I haven't looked at it yet but
> > > > we'll need it for thermal throttling.
> > > 
> > > I'm not sure how to tell if the frequency is dynamically changed during
> > > runtime on arm. x86-64 shows this information in /proc/cpuinfo. Here's
> > 
> > > the /proc/cpuinfo on the Nexus 5:
> > Nah. /proc/cpuinfo won't show what we need.
> > 
> > Try the following:
> > 
> > $ grep "" /sys/devices/system/cpu/cpufreq/policy?/*
> > 
> > More specifically, the following files have the information you need.
> > Run watch -n1 on them.
> > 
> > $ grep "" /sys/devices/system/cpu/cpufreq/policy?/scaling_*_freq
> 
> There's no cpufreq directory on msm8974:
> 
>     # ls -1 /sys/devices/system/cpu/
>     cpu0
>     cpu1
>     cpu2
>     cpu3
>     cpuidle
>     hotplug
>     isolated
>     kernel_max
>     modalias
>     offline
>     online
>     possible
>     power
>     present
>     smt
>     uevent
> 
> I'm using qcom_defconfig.
> 
> Brian

Hi Brian,
cpufreq isn't supported on msm8974 yet.
I have these patches [0] in my tree but I'm not sure they work correctly, but I haven't tested much with them. Feel free to try them on hammerhead.

Luca

[0] https://github.com/z3ntu/linux/compare/b0917f53ada0e929896a094b451219cd8091366e...6459ca6aff498c9d12acd35709b4903effc4c3f8

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[relevance 99%]

* [PATCH 1/2] ARM: dts: msm8974-FP2: Drop unused card-detect pin
@ 2019-09-26 18:44 99% Luca Weiss
  2019-09-26 18:44 99% ` [PATCH 2/2] ARM: dts: msm8974-FP2: Increase load on l20 for sdhci Luca Weiss
  0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-09-26 18:44 UTC (permalink / raw)
  Cc: Luca Weiss, Andy Gross, Rob Herring, Mark Rutland, linux-arm-msm,
	devicetree, linux-kernel

The gpio is not used for SD card detection on the FP2.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index bf402ae39226..2869be16bc6e 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -272,14 +272,6 @@
 			};
 		};
 
-		sdhc2_cd_pin_a: sdhc2-cd-pin-active {
-			pins = "gpio62";
-			function = "gpio";
-
-			drive-strength = <2>;
-			bias-disable;
-		};
-
 		sdhc2_pin_a: sdhc2-pin-active {
 			clk {
 				pins = "sdc2_clk";
@@ -317,7 +309,7 @@
 		bus-width = <4>;
 
 		pinctrl-names = "default";
-		pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+		pinctrl-0 = <&sdhc2_pin_a>;
 	};
 
 	usb@f9a55000 {
-- 
2.23.0


^ permalink raw reply	[relevance 99%]

* [PATCH 2/2] ARM: dts: msm8974-FP2: Increase load on l20 for sdhci
  2019-09-26 18:44 99% [PATCH 1/2] ARM: dts: msm8974-FP2: Drop unused card-detect pin Luca Weiss
@ 2019-09-26 18:44 99% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-09-26 18:44 UTC (permalink / raw)
  Cc: Luca Weiss, Andy Gross, Rob Herring, Mark Rutland, linux-arm-msm,
	devicetree, linux-kernel

Before this change, trying to boot from the internal storage would
result in a lot of errors like:

[   11.224046] mmc0: cache flush error -110
[   11.224180] blk_update_request: I/O error, dev mmcblk0, sector 0 op 0x1:(WRITE) flags 0x800 phys_seg 0 prio class 0

or:

[  137.544673] mmc0: tuning execution failed: -5
[  137.569832] mmcblk0: error -110 requesting status
[  137.593558] mmcblk0: recovery failed!

With this patch, there are no more sdhci errors and booting works fine.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index 2869be16bc6e..dfab2518df60 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -221,6 +221,8 @@
 						regulator-max-microvolt = <2950000>;
 
 						regulator-boot-on;
+						regulator-system-load = <200000>;
+						regulator-allow-set-load;
 					};
 
 					l21 {
-- 
2.23.0


^ permalink raw reply	[relevance 99%]

* [PATCH 2/2] ARM: qcom_defconfig: Enable QRTR
  2019-11-04 21:09 86% [PATCH 1/2] ARM: qcom_defconfig: Regenerate Luca Weiss
@ 2019-11-04 21:09 99% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-11-04 21:09 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Luca Weiss, Russell King, Brian Masney, Bjorn Andersson,
	Linus Walleij, Andy Gross, Jordan Crouse, Krzysztof Kozlowski,
	Miquel Raynal, linux-arm-kernel, linux-kernel

This option is useful on msm8974, so enable it.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/configs/qcom_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 94d5e1a8c61a..a71201fdc8c9 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -45,6 +45,8 @@ CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6 is not set
+CONFIG_QRTR=y
+CONFIG_QRTR_SMD=y
 CONFIG_CFG80211=m
 CONFIG_MAC80211=m
 CONFIG_RFKILL=y
-- 
2.23.0


^ permalink raw reply	[relevance 99%]

* [PATCH 1/2] ARM: qcom_defconfig: Regenerate
@ 2019-11-04 21:09 86% Luca Weiss
  2019-11-04 21:09 99% ` [PATCH 2/2] ARM: qcom_defconfig: Enable QRTR Luca Weiss
  0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-11-04 21:09 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Luca Weiss, Russell King, Bjorn Andersson, Brian Masney,
	Linus Walleij, Sudeep Holla, Krzysztof Kozlowski, Miquel Raynal,
	Jordan Crouse, linux-arm-kernel, linux-kernel

Several options were dropped a while ago and the options QCOM_ADSP_PIL
and QCOM_Q6V5_PIL have been renamed.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/configs/qcom_defconfig | 45 ++++++++++++---------------------
 1 file changed, 16 insertions(+), 29 deletions(-)

diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 9792dd0aae0c..94d5e1a8c61a 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -1,6 +1,7 @@
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -11,32 +12,28 @@ CONFIG_EMBEDDED=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-CONFIG_KPROBES=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8X60=y
 CONFIG_ARCH_MSM8960=y
 CONFIG_ARCH_MSM8974=y
 CONFIG_ARCH_MDM9615=y
-CONFIG_PCI=y
-CONFIG_PCI_MSI=y
-CONFIG_PCIE_QCOM=y
 CONFIG_SMP=y
-CONFIG_PREEMPT=y
 CONFIG_HIGHMEM=y
-CONFIG_CLEANCACHE=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_CLEANCACHE=y
 CONFIG_CMA=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -47,18 +44,17 @@ CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_IPV6 is not set
 CONFIG_CFG80211=m
 CONFIG_MAC80211=m
 CONFIG_RFKILL=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCIE_QCOM=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
@@ -113,7 +109,6 @@ CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_QUP=y
 CONFIG_SPI=y
@@ -140,7 +135,6 @@ CONFIG_QCOM_TSENS=y
 CONFIG_MFD_PM8XXX=y
 CONFIG_MFD_QCOM_RPM=y
 CONFIG_MFD_SPMI_PMIC=y
-CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_QCOM_RPM=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=y
@@ -149,13 +143,11 @@ CONFIG_MEDIA_SUPPORT=y
 CONFIG_DRM=y
 CONFIG_DRM_MSM=m
 CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_BACKLIGHT_LM3630A=y
 CONFIG_BACKLIGHT_LP855X=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_DYNAMIC_MINORS=y
@@ -169,15 +161,12 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_OTG=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_MSM=y
 CONFIG_USB_ACM=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_UDC=y
 CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_ULPI=y
 CONFIG_USB_SERIAL=y
 CONFIG_USB_HSIC_USB4604=y
-CONFIG_USB_MSM_OTG=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_VBUS_DRAW=500
@@ -185,7 +174,6 @@ CONFIG_USB_CONFIGFS=y
 CONFIG_USB_CONFIGFS_NCM=y
 CONFIG_USB_CONFIGFS_ECM=y
 CONFIG_USB_CONFIGFS_F_FS=y
-CONFIG_USB_ULPI_BUS=y
 CONFIG_USB_ETH=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
@@ -215,13 +203,13 @@ CONFIG_MSM_LCC_8960=y
 CONFIG_MDM_LCC_9615=y
 CONFIG_MSM_MMCC_8960=y
 CONFIG_MSM_MMCC_8974=y
-CONFIG_MSM_IOMMU=y
 CONFIG_HWSPINLOCK=y
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_MAILBOX=y
+CONFIG_MSM_IOMMU=y
 CONFIG_REMOTEPROC=y
-CONFIG_QCOM_ADSP_PIL=y
-CONFIG_QCOM_Q6V5_PIL=y
+CONFIG_QCOM_Q6V5_MSS=y
+CONFIG_QCOM_Q6V5_PAS=y
 CONFIG_QCOM_WCNSS_PIL=y
 CONFIG_RPMSG_CHAR=y
 CONFIG_RPMSG_QCOM_SMD=y
@@ -257,7 +245,6 @@ CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
-- 
2.23.0


^ permalink raw reply	[relevance 86%]

* [PATCH 1/2] ARM: dts: msm8974: Introduce the wcnss remoteproc node
@ 2019-11-04 21:23 94% Luca Weiss
  2019-11-04 21:23 99% ` [PATCH 2/2] ARM: dts: msm8974-FP2: " Luca Weiss
  0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-11-04 21:23 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Bjorn Andersson, Bjorn Andersson, Luca Weiss, Andy Gross,
	Rob Herring, Mark Rutland, devicetree, linux-kernel

From: Bjorn Andersson <bjorn.andersson@sonymobile.com>

Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 66 ++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 9a84eb0cbbe6..f8f02342c53d 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -30,7 +30,7 @@
 			no-map;
 		};
 
-		reserved@d200000 {
+		wcnss_region: wcnss@d200000 {
 			reg = <0x0d200000 0xa00000>;
 			no-map;
 		};
@@ -795,6 +795,70 @@
 			clock-names = "core";
 		};
 
+		pronto: remoteproc@fb21b000 {
+			compatible = "qcom,pronto-v2-pil", "qcom,pronto";
+			reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>;
+			reg-names = "ccu", "dxe", "pmu";
+
+			memory-region = <&wcnss_region>;
+
+			interrupts-extended = <&intc GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
+					      <&wcnss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&wcnss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&wcnss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&wcnss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+
+			vddpx-supply = <&pm8941_s3>;
+
+			qcom,smem-states = <&wcnss_smp2p_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			iris {
+				compatible = "qcom,wcn3680";
+
+				clocks = <&rpmcc RPM_SMD_CXO_A2>;
+				clock-names = "xo";
+
+				vddxo-supply = <&pm8941_l6>;
+				vddrfa-supply = <&pm8941_l11>;
+				vddpa-supply = <&pm8941_l19>;
+				vdddig-supply = <&pm8941_s3>;
+			};
+
+			smd-edge {
+				interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
+
+				qcom,ipc = <&apcs 8 17>;
+				qcom,smd-edge = <6>;
+
+				wcnss {
+					compatible = "qcom,wcnss";
+					qcom,smd-channels = "WCNSS_CTRL";
+					status = "disabled";
+
+					qcom,mmio = <&pronto>;
+
+					bt {
+						compatible = "qcom,wcnss-bt";
+					};
+
+					wifi {
+						compatible = "qcom,wcnss-wlan";
+
+						interrupts = <GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
+							     <GIC_SPI 146 IRQ_TYPE_EDGE_RISING>;
+						interrupt-names = "tx", "rx";
+
+						qcom,smem-states = <&apps_smsm 10>, <&apps_smsm 9>;
+						qcom,smem-state-names = "tx-enable", "tx-rings-empty";
+					};
+				};
+			};
+		};
+
 		msmgpio: pinctrl@fd510000 {
 			compatible = "qcom,msm8974-pinctrl";
 			reg = <0xfd510000 0x4000>;
-- 
2.23.0


^ permalink raw reply	[relevance 94%]

* [PATCH 2/2] ARM: dts: msm8974-FP2: Introduce the wcnss remoteproc node
  2019-11-04 21:23 94% [PATCH 1/2] ARM: dts: msm8974: Introduce the wcnss remoteproc node Luca Weiss
@ 2019-11-04 21:23 99% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-11-04 21:23 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Luca Weiss, Andy Gross, Rob Herring, Mark Rutland, devicetree,
	linux-kernel

Enable the remoteproc node and add the necessary pinctrl states.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 .../boot/dts/qcom-msm8974-fairphone-fp2.dts   | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
index 26160394d717..d2d48770ec0f 100644
--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
@@ -259,6 +259,25 @@
 		status = "ok";
 	};
 
+	remoteproc@fb21b000 {
+		status = "ok";
+
+		vddmx-supply = <&pm8841_s1>;
+		vddcx-supply = <&pm8841_s2>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&wcnss_pin_a>;
+
+		smd-edge {
+			qcom,remote-pid = <4>;
+			label = "pronto";
+
+			wcnss {
+				status = "ok";
+			};
+		};
+	};
+
 	pinctrl@fd510000 {
 		sdhc1_pin_a: sdhc1-pin-active {
 			clk {
@@ -287,6 +306,32 @@
 				bias-pull-up;
 			};
 		};
+
+		wcnss_pin_a: wcnss-pin-active {
+			wlan {
+				pins =  "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
+				function = "wlan";
+
+				drive-strength = <6>;
+				bias-pull-down;
+			};
+
+			bt {
+				pins = "gpio35", "gpio43", "gpio44";
+				function = "bt";
+
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+
+			fm {
+				pins = "gpio41", "gpio42";
+				function = "fm";
+
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+		};
 	};
 
 	sdhci@f9824900 {
-- 
2.23.0


^ permalink raw reply	[relevance 99%]

* Re: [PATCH v2 2/2] remoteproc: qcom_q6v5_mss: Validate each segment during loading
  @ 2019-11-10 14:05 99%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-11-10 14:05 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Bjorn Andersson, Ohad Ben-Cohen, Avaneesh Kumar Dwivedi,
	linux-remoteproc, linux-kernel, Sibi Sankar, Jeffrey Hugo,
	Brian Masney


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

Hi Bjorn,

with your patches and modifications in qcom-msm8974.dtsi, I can boot the modem 
successfully on the Fairphone 2, without the 'hack' commit we had in the tree 
before! Thanks!

Tested-by: Luca Weiss <luca@z3ntu.xyz>

On Samstag, 9. November 2019 01:40:33 CET Bjorn Andersson wrote:
> The code used to sync with the MBA after each segment loaded and this is
> still what's done downstream. So reduce the delta towards downstream by
> switching to a model where the content is iteratively validated.
> 
> Reviewed-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
> Tested-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
> 
> Changes since v1:
> - Picked up Jeff's r-b and t-b
> 
>  drivers/remoteproc/qcom_q6v5_mss.c | 76 ++++++++++++++++++++----------
>  1 file changed, 51 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_mss.c
> b/drivers/remoteproc/qcom_q6v5_mss.c index efab574b2e12..914d5546e1cf
> 100644
> --- a/drivers/remoteproc/qcom_q6v5_mss.c
> +++ b/drivers/remoteproc/qcom_q6v5_mss.c
> @@ -358,23 +358,29 @@ static void q6v5_pds_disable(struct q6v5 *qproc,
> struct device **pds, }
> 
>  static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm,
> -				   bool remote_owner, phys_addr_t 
addr,
> +				   bool local, bool remote, 
phys_addr_t addr,
>  				   size_t size)
>  {
> -	struct qcom_scm_vmperm next;
> +	struct qcom_scm_vmperm next[2];
> +	int perms = 0;
> 
>  	if (!qproc->need_mem_protection)
>  		return 0;
> -	if (remote_owner && *current_perm == BIT(QCOM_SCM_VMID_MSS_MSA))
> -		return 0;
> -	if (!remote_owner && *current_perm == BIT(QCOM_SCM_VMID_HLOS))
> -		return 0;
> 
> -	next.vmid = remote_owner ? QCOM_SCM_VMID_MSS_MSA : 
QCOM_SCM_VMID_HLOS;
> -	next.perm = remote_owner ? QCOM_SCM_PERM_RW : QCOM_SCM_PERM_RWX;
> +	if (local) {
> +		next[perms].vmid = QCOM_SCM_VMID_HLOS;
> +		next[perms].perm = QCOM_SCM_PERM_RWX;
> +		perms++;
> +	}
> +
> +	if (remote) {
> +		next[perms].vmid = QCOM_SCM_VMID_MSS_MSA;
> +		next[perms].perm = QCOM_SCM_PERM_RW;
> +		perms++;
> +	}
> 
>  	return qcom_scm_assign_mem(addr, ALIGN(size, SZ_4K),
> -				   current_perm, &next, 1);
> +				   current_perm, next, perms);
>  }
> 
>  static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
> @@ -681,7 +687,7 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc,
> const struct firmware *fw)
> 
>  	/* Hypervisor mapping to access metadata by modem */
>  	mdata_perm = BIT(QCOM_SCM_VMID_HLOS);
> -	ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, phys, 
size);
> +	ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, true, 
phys,
> size); if (ret) {
>  		dev_err(qproc->dev,
>  			"assigning Q6 access to metadata failed: 
%d\n", ret);
> @@ -699,7 +705,7 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc,
> const struct firmware *fw) dev_err(qproc->dev, "MPSS header authentication
> failed: %d\n", ret);
> 
>  	/* Metadata authentication done, remove modem access */
> -	xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, 
phys,
> size); +	xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true,
> false, phys, size); if (xferop_ret)
>  		dev_warn(qproc->dev,
>  			 "mdt buffer not reclaimed system may become 
unstable\n");
> @@ -786,7 +792,7 @@ static int q6v5_mba_load(struct q6v5 *qproc)
>  	}
> 
>  	/* Assign MBA image access in DDR to q6 */
> -	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true,
> +	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, true,
>  				      qproc->mba_phys, qproc-
>mba_size);
>  	if (ret) {
>  		dev_err(qproc->dev,
> @@ -820,8 +826,8 @@ static int q6v5_mba_load(struct q6v5 *qproc)
>  	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
> 
>  reclaim_mba:
> -	xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, 
false,
> -						qproc-
>mba_phys,
> +	xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, 
true,
> +						false, 
qproc->mba_phys,
>  						qproc-
>mba_size);
>  	if (xfermemop_ret) {
>  		dev_err(qproc->dev,
> @@ -888,7 +894,7 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc)
>  	/* In case of failure or coredump scenario where reclaiming MBA 
memory
>  	 * could not happen reclaim it here.
>  	 */
> -	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false,
> +	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false,
>  				      qproc->mba_phys,
>  				      qproc->mba_size);
>  	WARN_ON(ret);
> @@ -915,6 +921,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>  	phys_addr_t boot_addr;
>  	phys_addr_t min_addr = PHYS_ADDR_MAX;
>  	phys_addr_t max_addr = 0;
> +	u32 code_length;
>  	bool relocate = false;
>  	char *fw_name;
>  	size_t fw_name_len;
> @@ -965,9 +972,19 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>  	}
> 
>  	/* Try to reset ownership back to Linux */
> -	q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false,
> +	q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, false,
>  				qproc->mpss_phys, qproc-
>mpss_size);
> 
> +	/* Share ownership between Linux and MSS, during segment loading */
> +	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, true,
> +				      qproc->mpss_phys, qproc-
>mpss_size);
> +	if (ret) {
> +		dev_err(qproc->dev,
> +			"assigning Q6 access to mpss memory failed: 
%d\n", ret);
> +		ret = -EAGAIN;
> +		goto release_firmware;
> +	}
> +
>  	mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
>  	qproc->mpss_reloc = mpss_reloc;
>  	/* Load firmware segments */
> @@ -1016,10 +1033,24 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>  			       phdr->p_memsz - phdr->p_filesz);
>  		}
>  		size += phdr->p_memsz;
> +
> +		code_length = readl(qproc->rmb_base + 
RMB_PMI_CODE_LENGTH_REG);
> +		if (!code_length) {
> +			boot_addr = relocate ? qproc->mpss_phys : 
min_addr;
> +			writel(boot_addr, qproc->rmb_base + 
RMB_PMI_CODE_START_REG);
> +			writel(RMB_CMD_LOAD_READY, qproc->rmb_base + 
RMB_MBA_COMMAND_REG);
> +		}
> +		writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
> +
> +		ret = readl(qproc->rmb_base + RMB_MBA_STATUS_REG);
> +		if (ret < 0) {
> +			dev_err(qproc->dev, "MPSS authentication 
failed: %d\n", ret);
> +			goto release_firmware;
> +		}
>  	}
> 
>  	/* Transfer ownership of modem ddr region to q6 */
> -	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true,
> +	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, 
true,
>  				      qproc->mpss_phys, qproc-
>mpss_size);
>  	if (ret) {
>  		dev_err(qproc->dev,
> @@ -1028,11 +1059,6 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>  		goto release_firmware;
>  	}
> 
> -	boot_addr = relocate ? qproc->mpss_phys : min_addr;
> -	writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
> -	writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
> -	writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
> -
>  	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
>  	if (ret == -ETIMEDOUT)
>  		dev_err(qproc->dev, "MPSS authentication timed out\n");
> @@ -1061,7 +1087,7 @@ static void qcom_q6v5_dump_segment(struct rproc
> *rproc, ret = q6v5_mba_load(qproc);
> 
>  		/* Try to reset ownership back to Linux */
> -		q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, 
false,
> +		q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, 
false,
>  					qproc->mpss_phys, 
qproc->mpss_size);
>  	}
> 
> @@ -1101,8 +1127,8 @@ static int q6v5_start(struct rproc *rproc)
>  		goto reclaim_mpss;
>  	}
> 
> -	xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, 
false,
> -						qproc-
>mba_phys,
> +	xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, 
true,
> +						false, 
qproc->mba_phys,
>  						qproc-
>mba_size);
>  	if (xfermemop_ret)
>  		dev_err(qproc->dev,


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[relevance 99%]

* [PATCH 2/2] ARM: dts: msm8974: Move ADSP smd edge to ADSP PIL
  2019-11-14 17:53 91% [PATCH 1/2] ARM: dts: msm8974: Add modem remoteproc node Luca Weiss
@ 2019-11-14 17:53 99% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-11-14 17:53 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Bjorn Andersson, Luca Weiss, Andy Gross, Rob Herring,
	Mark Rutland, devicetree, linux-kernel

From: Bjorn Andersson <bjorn.andersson@linaro.org>

With the introduction of SSR support in the ADSP PIL we should describe
the SMD edge inside the ADSP PIL node.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
[luca@z3ntu.xyz: Add label for the smd edge]
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index b357cb51c0fb..9c8089e26a60 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -360,6 +360,15 @@ adsp-pil {
 
 		qcom,smem-states = <&adsp_smp2p_out 0>;
 		qcom,smem-state-names = "stop";
+
+		smd-edge {
+			interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+
+			qcom,ipc = <&apcs 8 8>;
+			qcom,smd-edge = <1>;
+
+			label = "lpass";
+		};
 	};
 
 	smem {
@@ -1569,13 +1578,6 @@ reboot-mode {
 	smd {
 		compatible = "qcom,smd";
 
-		adsp {
-			interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
-
-			qcom,ipc = <&apcs 8 8>;
-			qcom,smd-edge = <1>;
-		};
-
 		rpm {
 			interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
 			qcom,ipc = <&apcs 8 0>;
-- 
2.24.0


^ permalink raw reply	[relevance 99%]

* [PATCH 1/2] ARM: dts: msm8974: Add modem remoteproc node
@ 2019-11-14 17:53 91% Luca Weiss
  2019-11-14 17:53 99% ` [PATCH 2/2] ARM: dts: msm8974: Move ADSP smd edge to ADSP PIL Luca Weiss
  0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2019-11-14 17:53 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Bjorn Andersson, Luca Weiss, Andy Gross, Rob Herring,
	Mark Rutland, devicetree, linux-kernel

From: Bjorn Andersson <bjorn.andersson@linaro.org>

Add the remoteproc node for the modem on msm8974.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
[luca@z3ntu.xyz: cleanups, add label to smd-edge node]
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Note: This patch needs "remoteproc: qcom_q6v5_mss: Validate each segment
during loading" from the mailing list to be functional.

 arch/arm/boot/dts/qcom-msm8974.dtsi | 63 ++++++++++++++++++++++++-----
 1 file changed, 54 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 6f24dc9a7924..b357cb51c0fb 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -21,12 +21,12 @@ reserved-memory {
 		#size-cells = <1>;
 		ranges;
 
-		mpss@8000000 {
+		mpss_region: mpss@8000000 {
 			reg = <0x08000000 0x5100000>;
 			no-map;
 		};
 
-		mba@d100000 {
+		mba_region: mba@d100000 {
 			reg = <0x0d100000 0x100000>;
 			no-map;
 		};
@@ -62,8 +62,11 @@ rfsa@fd60000 {
 		};
 
 		rmtfs@fd80000 {
+			compatible = "qcom,rmtfs-mem";
 			reg = <0x0fd80000 0x180000>;
 			no-map;
+
+			qcom,client-id = <1>;
 		};
 	};
 
@@ -807,6 +810,55 @@ rng@f9bff000 {
 			clock-names = "core";
 		};
 
+		remoteproc@fc880000 {
+			compatible = "qcom,msm8974-mss-pil";
+			reg = <0xfc880000 0x100>, <0xfc820000 0x020>;
+			reg-names = "qdsp6", "rmb";
+
+			interrupts-extended = <&intc GIC_SPI 24 IRQ_TYPE_EDGE_RISING>,
+					      <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&modem_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&modem_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&modem_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+
+			clocks = <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>,
+				 <&gcc GCC_MSS_CFG_AHB_CLK>,
+				 <&gcc GCC_BOOT_ROM_AHB_CLK>,
+				 <&xo_board>;
+			clock-names = "iface", "bus", "mem", "xo";
+
+			resets = <&gcc GCC_MSS_RESTART>;
+			reset-names = "mss_restart";
+
+			cx-supply = <&pm8841_s2>;
+			mss-supply = <&pm8841_s3>;
+			mx-supply = <&pm8841_s1>;
+			pll-supply = <&pm8941_l12>;
+
+			qcom,halt-regs = <&tcsr_mutex_block 0x1180 0x1200 0x1280>;
+
+			qcom,smem-states = <&modem_smp2p_out 0>;
+			qcom,smem-state-names = "stop";
+
+			mba {
+				memory-region = <&mba_region>;
+			};
+
+			mpss {
+				memory-region = <&mpss_region>;
+			};
+
+			smd-edge {
+				interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
+
+				qcom,ipc = <&apcs 8 12>;
+				qcom,smd-edge = <0>;
+
+				label = "modem";
+			};
+		};
+
 		pronto: remoteproc@fb21b000 {
 			compatible = "qcom,pronto-v2-pil", "qcom,pronto";
 			reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>;
@@ -1524,13 +1576,6 @@ adsp {
 			qcom,smd-edge = <1>;
 		};
 
-		modem {
-			interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
-
-			qcom,ipc = <&apcs 8 12>;
-			qcom,smd-edge = <0>;
-		};
-
 		rpm {
 			interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
 			qcom,ipc = <&apcs 8 0>;
-- 
2.24.0


^ permalink raw reply	[relevance 91%]

* [PATCH] Input: ili210x - add ili2120 support
@ 2019-11-19 18:05 82% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2019-11-19 18:05 UTC (permalink / raw)
  To: linux-input
  Cc: Luca Weiss, Dmitry Torokhov, Rob Herring, Mark Rutland,
	Marek Vasut, Thomas Gleixner, Greg Kroah-Hartman, devicetree,
	linux-kernel

This adds support for the Ilitek ili2120 touchscreen found in the
Fairphone 2 smartphone.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
From some testing, the touchscreen works fine with this patch but I'm
not sure it's 100% correct.
I've uploaded the data the panel produces onto pastebin [1], maybe
someone who knows more can take a look at the packets.

Additionally, I know that the code in the driver for querying the
firmware version doesn't work on this panel. The downstream driver
uses some code which I don't really understand, see [2] ; but as the
version string is only used for a dev_dbg statement, I didn't spend
more time with that.

If wanted, I can split out the dt-binding changes to a separate
commit but looking at the git log, many patches are touching both
dt-bindings and driver.

[1] https://pastebin.com/raw/LPeAske5
[2] https://github.com/FairphoneMirrors/android_kernel_fairphone_msm8974/blob/fp2-m-sibon/drivers/input/touchscreen/ilitek/ilitek_aim.c#L850-L861

 .../bindings/input/ilitek,ili2xxx.txt         |  3 +-
 drivers/input/touchscreen/ili210x.c           | 34 +++++++++++++++++--
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt b/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
index b2a76301e632..045d1587d17a 100644
--- a/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
+++ b/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
@@ -1,8 +1,9 @@
-Ilitek ILI210x/ILI251x touchscreen controller
+Ilitek ILI210x/ILI212x/ILI251x touchscreen controller
 
 Required properties:
 - compatible:
     ilitek,ili210x for ILI210x
+    ilitek,ili212x for ILI212x
     ilitek,ili251x for ILI251x
 
 - reg: The I2C address of the device
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index e9006407c9bc..8331286ac950 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -13,6 +13,7 @@
 #include <asm/unaligned.h>
 
 #define ILI210X_TOUCHES		2
+#define ILI212X_TOUCHES		10
 #define ILI251X_TOUCHES		10
 #define DEFAULT_POLL_PERIOD	20
 
@@ -30,6 +31,7 @@ struct firmware_version {
 
 enum ili2xxx_model {
 	MODEL_ILI210X,
+	MODEL_ILI212X,
 	MODEL_ILI251X,
 };
 
@@ -118,6 +120,23 @@ static bool ili210x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata,
 	return true;
 }
 
+static bool ili212x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata,
+					unsigned int finger,
+					unsigned int *x, unsigned int *y)
+{
+	if (finger >= ILI212X_TOUCHES)
+		return false;
+
+	*x = get_unaligned_be16(touchdata + 3 + (finger * 5) + 0);
+	if (!(*x & BIT(15)))	/* Touch indication */
+		return false;
+
+	*x &= 0x3fff;
+	*y = get_unaligned_be16(touchdata + 3 + (finger * 5) + 2);
+
+	return true;
+}
+
 static bool ili251x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata,
 					unsigned int finger,
 					unsigned int *x, unsigned int *y)
@@ -146,6 +165,12 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
 		if (priv->model == MODEL_ILI210X) {
 			touch = ili210x_touchdata_to_coords(priv, touchdata,
 							    i, &x, &y);
+		} else if (priv->model == MODEL_ILI212X) {
+			touch = ili212x_touchdata_to_coords(priv, touchdata,
+							    i, &x, &y);
+
+			if (touch)
+				contact = true;
 		} else if (priv->model == MODEL_ILI251X) {
 			touch = ili251x_touchdata_to_coords(priv, touchdata,
 							    i, &x, &y);
@@ -179,7 +204,8 @@ static void ili210x_work(struct work_struct *work)
 	bool touch;
 	int error = -EINVAL;
 
-	if (priv->model == MODEL_ILI210X) {
+	if (priv->model == MODEL_ILI210X ||
+	    priv->model == MODEL_ILI212X) {
 		error = ili210x_read_reg(client, REG_TOUCHDATA,
 					 touchdata, sizeof(touchdata));
 	} else if (priv->model == MODEL_ILI251X) {
@@ -311,7 +337,9 @@ static int ili210x_i2c_probe(struct i2c_client *client,
 	priv->model = model;
 	if (model == MODEL_ILI210X)
 		priv->max_touches = ILI210X_TOUCHES;
-	if (model == MODEL_ILI251X)
+	else if (model == MODEL_ILI212X)
+		priv->max_touches = ILI212X_TOUCHES;
+	else if (model == MODEL_ILI251X)
 		priv->max_touches = ILI251X_TOUCHES;
 
 	i2c_set_clientdata(client, priv);
@@ -395,6 +423,7 @@ static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm,
 
 static const struct i2c_device_id ili210x_i2c_id[] = {
 	{ "ili210x", MODEL_ILI210X },
+	{ "ili212x", MODEL_ILI212X },
 	{ "ili251x", MODEL_ILI251X },
 	{ }
 };
@@ -402,6 +431,7 @@ MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id);
 
 static const struct of_device_id ili210x_dt_ids[] = {
 	{ .compatible = "ilitek,ili210x", .data = (void *)MODEL_ILI210X },
+	{ .compatible = "ilitek,ili212x", .data = (void *)MODEL_ILI212X },
 	{ .compatible = "ilitek,ili251x", .data = (void *)MODEL_ILI251X },
 	{ },
 };
-- 
2.24.0


^ permalink raw reply	[relevance 82%]

* [PATCH] Input: ili210x - fix return value of is_visible function
@ 2020-02-09 14:56 99% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-02-09 14:56 UTC (permalink / raw)
  To: linux-input
  Cc: ~postmarketos/upstreaming, Luca Weiss, Dmitry Torokhov,
	Sven Van Asbroeck, Marek Vasut, Thomas Gleixner, linux-kernel

The is_visible function expects the permissions associated with an
attribute of the sysfs group or 0 if an attribute is not visible.

Change the code to return the attribute permissions when the attribute
should be visible which resolves the warning:

  Attribute calibrate: Invalid permissions 01

Fixes: cc12ba1872c6 ("Input: ili210x - optionally show calibrate sysfs attribute")
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/input/touchscreen/ili210x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index 37526baff8a6..199cf3daec10 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -351,7 +351,7 @@ static umode_t ili210x_calibrate_visible(struct kobject *kobj,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct ili210x *priv = i2c_get_clientdata(client);
 
-	return priv->chip->has_calibrate_reg;
+	return priv->chip->has_calibrate_reg ? attr->mode : 0;
 }
 
 static const struct attribute_group ili210x_attr_group = {
-- 
2.25.0


^ permalink raw reply	[relevance 99%]

* [PATCH v2] Input: ili210x - add ili2120 support
@ 2020-02-09 15:19 92% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-02-09 15:19 UTC (permalink / raw)
  To: linux-input
  Cc: ~postmarketos/upstreaming, Luca Weiss, Dmitry Torokhov,
	Rob Herring, Mark Rutland, Sven Van Asbroeck, Marek Vasut,
	Thomas Gleixner, devicetree, linux-kernel

This adds support for the Ilitek ili2120 touchscreen found in the
Fairphone 2 smartphone.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes from v1:
- Rebase on master, adjust for upstream changes

 .../bindings/input/ilitek,ili2xxx.txt         |  3 +-
 drivers/input/touchscreen/ili210x.c           | 32 +++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt b/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
index dc194b2c151a..cdcaa3f52d25 100644
--- a/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
+++ b/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
@@ -1,9 +1,10 @@
-Ilitek ILI210x/ILI2117/ILI251x touchscreen controller
+Ilitek ILI210x/ILI2117/ILI2120/ILI251x touchscreen controller
 
 Required properties:
 - compatible:
     ilitek,ili210x for ILI210x
     ilitek,ili2117 for ILI2117
+    ilitek,ili2120 for ILI2120
     ilitek,ili251x for ILI251x
 
 - reg: The I2C address of the device
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index 84bf51d79888..199cf3daec10 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -167,6 +167,36 @@ static const struct ili2xxx_chip ili211x_chip = {
 	.resolution		= 2048,
 };
 
+static bool ili212x_touchdata_to_coords(const u8 *touchdata,
+					unsigned int finger,
+					unsigned int *x, unsigned int *y)
+{
+	u16 val;
+
+	val = get_unaligned_be16(touchdata + 3 + (finger * 5) + 0);
+	if (!(val & BIT(15)))	/* Touch indication */
+		return false;
+
+	*x = val & 0x3fff;
+	*y = get_unaligned_be16(touchdata + 3 + (finger * 5) + 2);
+
+	return true;
+}
+
+static bool ili212x_check_continue_polling(const u8 *data, bool touch)
+{
+	return touch;
+}
+
+static const struct ili2xxx_chip ili212x_chip = {
+	.read_reg		= ili210x_read_reg,
+	.get_touch_data		= ili210x_read_touch_data,
+	.parse_touch_data	= ili212x_touchdata_to_coords,
+	.continue_polling	= ili212x_check_continue_polling,
+	.max_touches		= 10,
+	.has_calibrate_reg	= true,
+};
+
 static int ili251x_read_reg(struct i2c_client *client,
 			    u8 reg, void *buf, size_t len)
 {
@@ -447,6 +477,7 @@ static int ili210x_i2c_probe(struct i2c_client *client,
 static const struct i2c_device_id ili210x_i2c_id[] = {
 	{ "ili210x", (long)&ili210x_chip },
 	{ "ili2117", (long)&ili211x_chip },
+	{ "ili2120", (long)&ili212x_chip },
 	{ "ili251x", (long)&ili251x_chip },
 	{ }
 };
@@ -455,6 +486,7 @@ MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id);
 static const struct of_device_id ili210x_dt_ids[] = {
 	{ .compatible = "ilitek,ili210x", .data = &ili210x_chip },
 	{ .compatible = "ilitek,ili2117", .data = &ili211x_chip },
+	{ .compatible = "ilitek,ili2120", .data = &ili212x_chip },
 	{ .compatible = "ilitek,ili251x", .data = &ili251x_chip },
 	{ }
 };
-- 
2.25.0


^ permalink raw reply	[relevance 92%]

* [PATCH v2] ARM: qcom_defconfig: Enable QRTR
@ 2020-02-14 18:31 99% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-02-14 18:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: ~postmarketos/upstreaming, linux-arm-msm, Luca Weiss,
	Russell King, Bjorn Andersson, Brian Masney, Linus Walleij,
	Georgi Djakov, Krzysztof Kozlowski, Jordan Crouse,
	Matti Lehtimäki, linux-kernel

This option is useful on msm8974, so enable it.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes from v1:
- set options as =m instead of =y

 arch/arm/configs/qcom_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index ad3417a63cdf..4702feef2cc9 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -44,6 +44,8 @@ CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6 is not set
+CONFIG_QRTR=m
+CONFIG_QRTR_SMD=m
 CONFIG_CFG80211=m
 CONFIG_MAC80211=m
 CONFIG_RFKILL=y
-- 
2.25.0


^ permalink raw reply	[relevance 99%]

* [RFC PATCH] leds: add sgm3140 driver
@ 2020-02-27 18:50 69% Luca Weiss
                     ` (3 more replies)
  0 siblings, 4 replies; 84+ results
From: Luca Weiss @ 2020-02-27 18:50 UTC (permalink / raw)
  To: linux-leds
  Cc: ~postmarketos/upstreaming, Luca Weiss, Jacek Anaszewski,
	Pavel Machek, Dan Murphy, linux-kernel

Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.

This device is controller by two GPIO lines, one for enabling the LED
and the second one for switching between torch and flash mode.

The device will automatically switch to torch mode after being in flash
mode for about 250-300ms, so after that time the driver will turn the
LED off again automatically.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Hi, this driver is controllable via sysfs and v4l2 APIs (as documented
in Documentation/leds/leds-class-flash.rst).

The following is possible:

# Torch on
echo 1 > /sys/class/leds/white\:flash/brightness
# Torch off
echo 0 > /sys/class/leds/white\:flash/brightness
# Activate flash
echo 1 > /sys/class/leds/white\:flash/flash_strobe

# Torch on
v4l2-ctl -d /dev/video1 -c led_mode=2
# Torch off
v4l2-ctl -d /dev/video1 -c led_mode=0
# Activate flash
v4l2-ctl -d /dev/video1 -c strobe=1

Unfortunately the last command (enabling the 'flash' via v4l2 results in
the following being printed and nothing happening:

  VIDIOC_S_EXT_CTRLS: failed: Resource busy
  strobe: Resource busy

Unfortunately I couldn't figure out the reason so I'm hoping to get some
guidance for this. iirc it worked at some point but then stopped.

I will also write dt bindings for the driver once I have "strobe"
working.

Regards,
Luca

 drivers/leds/Kconfig        |   9 ++
 drivers/leds/Makefile       |   1 +
 drivers/leds/leds-sgm3140.c | 210 ++++++++++++++++++++++++++++++++++++
 3 files changed, 220 insertions(+)
 create mode 100644 drivers/leds/leds-sgm3140.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 4b68520ac251..7c391af8b380 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -836,6 +836,15 @@ config LEDS_LM36274
 	  Say Y to enable the LM36274 LED driver for TI LMU devices.
 	  This supports the LED device LM36274.
 
+config LEDS_SGM3140
+	tristate "LED support for the SGM3140"
+	depends on LEDS_CLASS_FLASH
+	depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
+	depends on OF
+	help
+	  This option enables support for the SGM3140 500mA Buck/Boost Charge
+	  Pump LED Driver. It has supports flash and torch mode.
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 2da39e896ce8..38d57dd53e4b 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X)		+= leds-lm3601x.o
 obj-$(CONFIG_LEDS_TI_LMU_COMMON)	+= leds-ti-lmu-common.o
 obj-$(CONFIG_LEDS_LM3697)		+= leds-lm3697.o
 obj-$(CONFIG_LEDS_LM36274)		+= leds-lm36274.o
+obj-$(CONFIG_LEDS_SGM3140)		+= leds-sgm3140.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_CR0014114)		+= leds-cr0014114.o
diff --git a/drivers/leds/leds-sgm3140.c b/drivers/leds/leds-sgm3140.c
new file mode 100644
index 000000000000..9e91392f0343
--- /dev/null
+++ b/drivers/leds/leds-sgm3140.c
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2020 Luca Weiss <luca@z3ntu.xyz>
+
+#include <linux/gpio/consumer.h>
+#include <linux/led-class-flash.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <media/v4l2-flash-led-class.h>
+
+#define SGM3140_NAME "sgm3140"
+
+struct sgm3140 {
+	struct gpio_desc *flash_gpio;
+	struct gpio_desc *enable_gpio;
+
+	struct led_classdev_flash fled_cdev;
+	struct v4l2_flash *v4l2_flash;
+
+	struct timer_list powerdown_timer;
+};
+
+static struct sgm3140 *flcdev_to_sgm3140(struct led_classdev_flash *flcdev)
+{
+	return container_of(flcdev, struct sgm3140, fled_cdev);
+}
+
+int sgm3140_strobe_set(struct led_classdev_flash *fled_cdev, bool state)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	if (state) {
+		gpiod_set_value_cansleep(priv->flash_gpio, 1);
+		gpiod_set_value_cansleep(priv->enable_gpio, 1);
+		mod_timer(&priv->powerdown_timer,
+			  jiffies + msecs_to_jiffies(250));
+	} else {
+		gpiod_set_value_cansleep(priv->enable_gpio, 0);
+		gpiod_set_value_cansleep(priv->flash_gpio, 0);
+		del_timer_sync(&priv->powerdown_timer);
+	}
+
+	return 0;
+}
+
+struct led_flash_ops sgm3140_flash_ops = {
+	.strobe_set = sgm3140_strobe_set,
+};
+
+int sgm3140_brightness_set(struct led_classdev *led_cdev,
+			   enum led_brightness brightness)
+{
+	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	if (brightness == LED_OFF)
+		gpiod_set_value_cansleep(priv->enable_gpio, 0);
+	else
+		gpiod_set_value_cansleep(priv->enable_gpio, 1);
+
+	return 0;
+}
+
+static void sgm3140_powerdown_timer(struct timer_list *t)
+{
+	struct sgm3140 *priv = from_timer(priv, t, powerdown_timer);
+
+	gpiod_set_value_cansleep(priv->enable_gpio, 0);
+	gpiod_set_value_cansleep(priv->flash_gpio, 0);
+}
+
+#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
+static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
+					   struct v4l2_flash_config *v4l2_sd_cfg)
+{
+	struct led_classdev *led_cdev = &priv->fled_cdev.led_cdev;
+	struct led_flash_setting *s;
+
+	strlcpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name,
+		sizeof(v4l2_sd_cfg->dev_name));
+
+	s = &v4l2_sd_cfg->intensity;
+	s->min = 0;
+	s->max = 1;
+	s->step = 1;
+	s->val = 1;
+}
+
+#else
+static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
+					   struct v4l2_flash_config *v4l2_sd_cfg)
+{
+}
+#endif
+
+static int sgm3140_probe(struct platform_device *pdev)
+{
+	struct sgm3140 *priv;
+	struct led_classdev *led_cdev;
+	struct led_classdev_flash *fled_cdev;
+	struct led_init_data init_data = {};
+	struct device_node *child_node;
+	struct v4l2_flash_config v4l2_sd_cfg;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->flash_gpio = devm_gpiod_get(&pdev->dev, "flash", GPIOD_OUT_LOW);
+	ret = PTR_ERR_OR_ZERO(priv->flash_gpio);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request flash gpio: %d\n",
+				ret);
+		return ret;
+	}
+
+	priv->enable_gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	ret = PTR_ERR_OR_ZERO(priv->enable_gpio);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request enable gpio: %d\n",
+				ret);
+		return ret;
+	}
+
+	child_node = of_get_next_available_child(pdev->dev.of_node, NULL);
+	if (!child_node) {
+		dev_err(&pdev->dev, "No DT child node found for connected LED.\n");
+		return -EINVAL;
+	}
+
+	timer_setup(&priv->powerdown_timer, sgm3140_powerdown_timer, 0);
+
+	fled_cdev = &priv->fled_cdev;
+	led_cdev = &fled_cdev->led_cdev;
+
+	fled_cdev->ops = &sgm3140_flash_ops;
+
+	led_cdev->brightness_set_blocking = sgm3140_brightness_set;
+	led_cdev->max_brightness = LED_ON;
+	led_cdev->flags |= LED_DEV_CAP_FLASH;
+
+	init_data.fwnode = of_fwnode_handle(child_node);
+	init_data.devicename = SGM3140_NAME;
+
+	platform_set_drvdata(pdev, priv);
+
+	/* Register in the LED subsystem */
+	ret = led_classdev_flash_register_ext(&pdev->dev, fled_cdev, &init_data);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register flash device: %d\n",
+			ret);
+		goto err_flash_register;
+	}
+
+	sgm3140_init_v4l2_flash_config(priv, &v4l2_sd_cfg);
+
+	/* Create V4L2 Flash subdev */
+	priv->v4l2_flash = v4l2_flash_init(&pdev->dev, of_fwnode_handle(child_node),
+					   fled_cdev, NULL,
+					   &v4l2_sd_cfg);
+	if (IS_ERR(priv->v4l2_flash)) {
+		ret = PTR_ERR(priv->v4l2_flash);
+		goto err_v4l2_flash_init;
+	}
+
+	return 0;
+
+err_v4l2_flash_init:
+	led_classdev_flash_unregister(fled_cdev);
+err_flash_register:
+	of_node_put(child_node);
+	return ret;
+}
+
+static int sgm3140_remove(struct platform_device *pdev)
+{
+	struct sgm3140 *priv = platform_get_drvdata(pdev);
+
+	del_timer_sync(&priv->powerdown_timer);
+
+	v4l2_flash_release(priv->v4l2_flash);
+	led_classdev_flash_unregister(&priv->fled_cdev);
+
+	return 0;
+}
+
+static const struct of_device_id sgm3140_dt_match[] = {
+	{ .compatible = "sgmicro,sgm3140" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sgm3140_dt_match);
+
+static struct platform_driver sgm3140_driver = {
+	.probe	= sgm3140_probe,
+	.remove	= sgm3140_remove,
+	.driver	= {
+		.name	= "sgm3140",
+		.of_match_table = sgm3140_dt_match,
+	},
+};
+
+module_platform_driver(sgm3140_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xyz>");
+MODULE_DESCRIPTION("SG Micro SGM3140 charge pump led driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1


^ permalink raw reply	[relevance 69%]

* Re: [RFC PATCH] leds: add sgm3140 driver
  @ 2020-03-05 11:01 99%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-05 11:01 UTC (permalink / raw)
  To: linux-leds, Dan Murphy; +Cc: Jacek Anaszewski, Pavel Machek, linux-kernel


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

On Donnerstag, 27. Februar 2020 20:50:40 CET Dan Murphy wrote:
> Luca
> 
> On 2/27/20 12:50 PM, Luca Weiss wrote:
> > Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> > 
> > This device is controller by two GPIO lines, one for enabling the LED
> > and the second one for switching between torch and flash mode.
> > 
> > The device will automatically switch to torch mode after being in flash
> > mode for about 250-300ms, so after that time the driver will turn the
> > LED off again automatically.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > ---
> 
> You seem to be missing the devictree bindings doc for the GPIOs.

As written in the initial email:

> I will also write dt bindings for the driver once I have "strobe"
> working.

I was hoping to get some guidance on the code by posting the WIP patch - the 
issues I see are documented in the initial email.

Regards
Luca

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[relevance 99%]

* Re: [RFC PATCH] leds: add sgm3140 driver
  @ 2020-03-08 11:32 92%   ` Luca Weiss
    0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2020-03-08 11:32 UTC (permalink / raw)
  To: linux-leds, Jacek Anaszewski
  Cc: ~postmarketos/upstreaming, Pavel Machek, Dan Murphy, linux-kernel

Hi Jacek,

Thanks for your review! Replies are inline below.

I'm wondering if I should implement support for the flash-max-timeout-us dt 
property ("Maximum timeout in microseconds after which the flash LED is turned 
off.") to configure the timeout to turn the flash off as I've currently hardcoded 
250ms but this might not be ideal for all uses of the sgm3140. The datasheet 
states:

> Flash mode is usually used with a pulse of about 200 to 300 milliseconds to 
> generate a high intensity Flash.

so it might be useful to have this configurable in the devicetree. The value of 
250ms works fine for my use case.

Theoretically also the .timeout_set op could be implemented but I'm not sure 
if this fits nicely into the existing "timeout" API and if it even makes sense 
to implement that.

Regards,
Luca

On Donnerstag, 5. März 2020 22:09:16 CET Jacek Anaszewski wrote:
> Hi Luca,
> 
> Thank you for the patch.
> 
> On 2/27/20 7:50 PM, Luca Weiss wrote:
> > Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> > 
> > This device is controller by two GPIO lines, one for enabling the LED
> > and the second one for switching between torch and flash mode.
> > 
> > The device will automatically switch to torch mode after being in flash
> > mode for about 250-300ms, so after that time the driver will turn the
> > LED off again automatically.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > ---
> > Hi, this driver is controllable via sysfs and v4l2 APIs (as documented
> > in Documentation/leds/leds-class-flash.rst).
> > 
> > The following is possible:
> > 
> > # Torch on
> > echo 1 > /sys/class/leds/white\:flash/brightness
> > # Torch off
> > echo 0 > /sys/class/leds/white\:flash/brightness
> > # Activate flash
> > echo 1 > /sys/class/leds/white\:flash/flash_strobe
> > 
> > # Torch on
> > v4l2-ctl -d /dev/video1 -c led_mode=2
> > # Torch off
> > v4l2-ctl -d /dev/video1 -c led_mode=0
> > # Activate flash
> > v4l2-ctl -d /dev/video1 -c strobe=1
> 
> What is /dev/video1 ? Did you register vl42 flash subdev
> in some v4l2 media controller device?

On the Allwinner A64 SoC /dev/video0 is the node for cedrus (video encoder/
decoder), so the sun6i-csi driver gets to be /dev/video1

# v4l2-ctl --list-devices
cedrus (platform:cedrus):
        /dev/video0
        /dev/media0

sun6i-csi (platform:csi):
        /dev/video1

Allwinner Video Capture Device (platform:sun6i-csi):
        /dev/media1


Here's the relevant part from my dts:

sgm3140 {
    compatible = "sgmicro,sgm3140";
    flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* FLASH_TRIGOUT: PD24 */
    enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* FLASH_EN: PC3 */

    sgm3140_flash: led {
        function = LED_FUNCTION_FLASH;
        color = <LED_COLOR_ID_WHITE>;
    };
};

/* as subnode of csi (compatible: allwinner,sun50i-a64-csi) */
ov5640: rear-camera@4c {
    compatible = "ovti,ov5640";
    <snip>
    flash-leds = <&sgm3140_flash>;
};

> 
> > Unfortunately the last command (enabling the 'flash' via v4l2 results in
> > 
> > the following being printed and nothing happening:
> >   VIDIOC_S_EXT_CTRLS: failed: Resource busy
> >   strobe: Resource busy
> > 
> > Unfortunately I couldn't figure out the reason so I'm hoping to get some
> > guidance for this. iirc it worked at some point but then stopped.
> 
> You have to be in flash mode to strobe i.e. led_mode=1.

Of course..! Makes sense, I just never realized the v4l2 device had to be in 
this mode for the strobe button to work. It works nicely with that, thanks!

> <<snip>>

> > +static void sgm3140_powerdown_timer(struct timer_list *t)
> > +{
> > +	struct sgm3140 *priv = from_timer(priv, t, powerdown_timer);
> > +
> > +	gpiod_set_value_cansleep(priv->enable_gpio, 0);
> > +	gpiod_set_value_cansleep(priv->flash_gpio, 0);
> 
> You could also implement strobe_get op and return from it a flag
> indicating if LED is strobing.

Makes sense.
> > +}
> > +
> > +#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
> > +static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
> > +					   struct 
v4l2_flash_config *v4l2_sd_cfg)
> > +{
> > +	struct led_classdev *led_cdev = &priv->fled_cdev.led_cdev;
> > +	struct led_flash_setting *s;
> > +
> > +	strlcpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name,
> > +		sizeof(v4l2_sd_cfg->dev_name));
> > +
> > +	s = &v4l2_sd_cfg->intensity;
> > +	s->min = 0;
> > +	s->max = 1;
> > +	s->step = 1;
> > +	s->val = 1;
> > +}
> > +
> > +#else
> > +static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
> > +					   struct 
v4l2_flash_config *v4l2_sd_cfg)
> > +{
> > +}
> > +#endif
> > +
> > +static int sgm3140_probe(struct platform_device *pdev)
> > +{
> > +	struct sgm3140 *priv;
> > +	struct led_classdev *led_cdev;
> > +	struct led_classdev_flash *fled_cdev;
> > +	struct led_init_data init_data = {};
> > +	struct device_node *child_node;
> > +	struct v4l2_flash_config v4l2_sd_cfg;
> 
> s/v4l2_sd_cfg;/v4l2_sd_cfg = {};/
> 
> Otherwise it is possible that some controls would be initialized
> to random values.
> 

Ack

> > +	int ret;
> > +
> > +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->flash_gpio = devm_gpiod_get(&pdev->dev, "flash", 
GPIOD_OUT_LOW);
> > +	ret = PTR_ERR_OR_ZERO(priv->flash_gpio);
> > +	if (ret) {
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(&pdev->dev, "Failed to request flash 
gpio: %d\n",
> > +				ret);
> > +		return ret;
> > +	}
> > +
> > +	priv->enable_gpio = devm_gpiod_get(&pdev->dev, "enable", 
GPIOD_OUT_LOW);
> > +	ret = PTR_ERR_OR_ZERO(priv->enable_gpio);
> > +	if (ret) {
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(&pdev->dev, "Failed to request 
enable gpio: %d\n",
> > +				ret);
> > +		return ret;
> > +	}
> > +
> > +	child_node = of_get_next_available_child(pdev->dev.of_node, NULL);
> > +	if (!child_node) {
> > +		dev_err(&pdev->dev, "No DT child node found for 
connected LED.\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	timer_setup(&priv->powerdown_timer, sgm3140_powerdown_timer, 0);
> > +
> > +	fled_cdev = &priv->fled_cdev;
> > +	led_cdev = &fled_cdev->led_cdev;
> > +
> > +	fled_cdev->ops = &sgm3140_flash_ops;
> > +
> > +	led_cdev->brightness_set_blocking = sgm3140_brightness_set;
> > +	led_cdev->max_brightness = LED_ON;
> > +	led_cdev->flags |= LED_DEV_CAP_FLASH;
> > +
> > +	init_data.fwnode = of_fwnode_handle(child_node);
> > +	init_data.devicename = SGM3140_NAME;
> 
> devicename should be skipped in new drivers.
> 

Ack

> > +
> > +	platform_set_drvdata(pdev, priv);
> > +
> > +	/* Register in the LED subsystem */
> > +	ret = led_classdev_flash_register_ext(&pdev->dev, fled_cdev,
> > &init_data);
> 
> We already have devm_* prefixed version thereof.
> 

Ack, switched to the devm_ variant

> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "Failed to register flash device: 
%d\n",
> > +			ret);
> > +		goto err_flash_register;
> > +	}
> > +
> > +	sgm3140_init_v4l2_flash_config(priv, &v4l2_sd_cfg);
> > +
> > +	/* Create V4L2 Flash subdev */
> > +	priv->v4l2_flash = v4l2_flash_init(&pdev->dev,
> > of_fwnode_handle(child_node), +					
   fled_cdev, NULL,
> > +					   &v4l2_sd_cfg);
> > +	if (IS_ERR(priv->v4l2_flash)) {
> > +		ret = PTR_ERR(priv->v4l2_flash);
> > +		goto err_v4l2_flash_init;
> > +	}
> > +
> > +	return 0;
> > +
> > +err_v4l2_flash_init:
> > +	led_classdev_flash_unregister(fled_cdev);
> > +err_flash_register:
> > +	of_node_put(child_node);
> 
> You need to relase of_node also in case of success.
> 

Done.

> > +	return ret;
> > +}
> > +
> > +static int sgm3140_remove(struct platform_device *pdev)
> > +{
> > +	struct sgm3140 *priv = platform_get_drvdata(pdev);
> > +
> > +	del_timer_sync(&priv->powerdown_timer);
> > +
> > +	v4l2_flash_release(priv->v4l2_flash);
> > +	led_classdev_flash_unregister(&priv->fled_cdev);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id sgm3140_dt_match[] = {
> > +	{ .compatible = "sgmicro,sgm3140" },
> > +	{ /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, sgm3140_dt_match);
> > +
> > +static struct platform_driver sgm3140_driver = {
> > +	.probe	= sgm3140_probe,
> > +	.remove	= sgm3140_remove,
> > +	.driver	= {
> > +		.name	= "sgm3140",
> > +		.of_match_table = sgm3140_dt_match,
> > +	},
> > +};
> > +
> > +module_platform_driver(sgm3140_driver);
> > +
> > +MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xyz>");
> > +MODULE_DESCRIPTION("SG Micro SGM3140 charge pump led driver");
> > +MODULE_LICENSE("GPL v2");





^ permalink raw reply	[relevance 92%]

* Re: [RFC PATCH] leds: add sgm3140 driver
  @ 2020-03-08 12:31 91%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-08 12:31 UTC (permalink / raw)
  To: Pavel Machek
  Cc: linux-leds, ~postmarketos/upstreaming, Jacek Anaszewski,
	Dan Murphy, linux-kernel

Hi Pavel

On Sonntag, 8. März 2020 13:08:55 CET Pavel Machek wrote:
> Hi!
> 
> > Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> 
> That's pinephone, right?

Yes

> 
> > This device is controller by two GPIO lines, one for enabling the LED
> > and the second one for switching between torch and flash mode.
> > 
> > The device will automatically switch to torch mode after being in flash
> > mode for about 250-300ms, so after that time the driver will turn the
> > LED off again automatically.
> 
> I don't quite see how this is supposed to work.
> 

The sgm3140 works like this:

Set EN pin to low  -> off
Set EN pin to high and FLASH pin low -> torch mode
Set EN pin to high and FLASH pin high -> flash mode for 200-300ms, then it 
switches automatically to torch mode

If it's still unclear, here's the datasheet which explains it nicely imo:
http://www.sg-micro.com/uploads/soft/20190626/1561535688.pdf

For strobe/flash operation the driver from this patch sets up a timer (using 
mod_timer) in sgm3140_strobe_set to turn off the flash completely after 250ms so 
that it doesn't remain in torch mode after these 200-300ms. In case the strobe 
is disabled earlier, the timer is cancelled (del_timer_sync). That's 
essentially what the driver is doing.

> > Hi, this driver is controllable via sysfs and v4l2 APIs (as documented
> > in Documentation/leds/leds-class-flash.rst).
> > 
> > The following is possible:
> > 
> > # Torch on
> > echo 1 > /sys/class/leds/white\:flash/brightness
> > # Torch off
> > echo 0 > /sys/class/leds/white\:flash/brightness
> > # Activate flash
> > echo 1 > /sys/class/leds/white\:flash/flash_strobe
> 
> So.. "activate flash" will turn the LED on in very bright mode, then
> put it back to previous brightness after a timeout?
> 
> What happens if some kind of malware does flash_strobe every 300msec?
> 

Then the LED will essentially be in torch mode until the sgm3140 determines 
that it can use flash mode again.

> > # Torch on
> > v4l2-ctl -d /dev/video1 -c led_mode=2
> > # Torch off
> > v4l2-ctl -d /dev/video1 -c led_mode=0
> > # Activate flash
> > v4l2-ctl -d /dev/video1 -c strobe=1
> > 
> > Unfortunately the last command (enabling the 'flash' via v4l2 results in
> > 
> > the following being printed and nothing happening:
> >   VIDIOC_S_EXT_CTRLS: failed: Resource busy
> >   strobe: Resource busy
> > 
> > Unfortunately I couldn't figure out the reason so I'm hoping to get some
> > guidance for this. iirc it worked at some point but then stopped.
> 
> Actually, LED flash drivers are getting quite common. Having common
> code (so we could just say this is led flash, register it to both v4l
> and LED) might be quite interesting.
> 
> Unfortunately, some LED flashes also have integrated red LED for
> indication, further complicating stuff.
> 

See https://www.kernel.org/doc/html/latest/leds/leds-class-flash.html ? That's 
what I am using in this driver.

> > diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
> > index 2da39e896ce8..38d57dd53e4b 100644
> > --- a/drivers/leds/Makefile
> > +++ b/drivers/leds/Makefile
> > @@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X)		+= leds-
lm3601x.o
> > 
> >  obj-$(CONFIG_LEDS_TI_LMU_COMMON)	+= leds-ti-lmu-common.o
> >  obj-$(CONFIG_LEDS_LM3697)		+= leds-lm3697.o
> >  obj-$(CONFIG_LEDS_LM36274)		+= leds-lm36274.o
> > 
> > +obj-$(CONFIG_LEDS_SGM3140)		+= leds-sgm3140.o
> 
> I would not mind "flash" drivers going to separate directory.
> 

That would apply to these existing drivers as well at least:
* drivers/leds/leds-aat1290.c
* drivers/leds/leds-as3645a.c
* drivers/leds/leds-max77693.c
* drivers/leds/leds-lm3601x.c (probably should be made to use v4l2_flash_init 
as well)

> > +int sgm3140_brightness_set(struct led_classdev *led_cdev,
> > +			   enum led_brightness brightness)
> > +{
> > +	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
> > +	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
> > +
> > +	if (brightness == LED_OFF)
> > +		gpiod_set_value_cansleep(priv->enable_gpio, 0);
> > +	else
> > +		gpiod_set_value_cansleep(priv->enable_gpio, 1);
> > +
> > +	return 0;
> > +}
> 
> Umm. So this cancels running strobe?
> 

Setting brightness to 0 here turns off the flash, yes.

> > +static void sgm3140_powerdown_timer(struct timer_list *t)
> > +{
> > +	struct sgm3140 *priv = from_timer(priv, t, powerdown_timer);
> > +
> > +	gpiod_set_value_cansleep(priv->enable_gpio, 0);
> > +	gpiod_set_value_cansleep(priv->flash_gpio, 0);
> > +}
> 
> And this does not return to previous brightness.
> 

There's no real "brightness" level, it's either on or off. Or do you mean that 
when the torch is on and the strobe is activated it should go back to torch 
mode instead of being turned off?

> Do we want to provide the "strobe" functionality through sysfs at all?
> Should we make it v4l-only, and independend of the LED stuff?
> 

I've just followed 
https://www.kernel.org/doc/html/latest/leds/leds-class-flash.html , but I like 
the simple sysfs interface for simple uses and for more advanced applications 
(e.g. camera apps) the v4l2 interface.

> Best regards,
> 								
	Pavel

Regards
Luca



^ permalink raw reply	[relevance 91%]

* Re: [RFC PATCH] leds: add sgm3140 driver
  @ 2020-03-08 12:37 99%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-08 12:37 UTC (permalink / raw)
  To: Pavel Machek
  Cc: linux-leds, ~postmarketos/upstreaming, Jacek Anaszewski,
	Dan Murphy, linux-kernel

Hi Pavel,

On Sonntag, 8. März 2020 13:11:32 CET Pavel Machek wrote:
> Hi!
> 
> > Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> > 
> > This device is controller by two GPIO lines, one for enabling the LED
> > and the second one for switching between torch and flash mode.
> > 
> > The device will automatically switch to torch mode after being in flash
> > mode for about 250-300ms, so after that time the driver will turn the
> > LED off again automatically.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> 
> Cc: ~postmarketos/upstreaming@lists.sr.ht, Luca Weiss <luca@z3ntu.xyz>,
> Jacek Anaszewski
> 
> Strange entry in cc list...?

You mean the '~postmarketos/upstreaming@lists.sr.ht' entry with a tilde and a 
slash character? Both are valid characters in email addresses and you can view 
the archive of that mailing list here:

https://lists.sr.ht/~postmarketos/upstreaming

See also https://man.sr.ht/lists.sr.ht/#listssrht-manual

> And btw if you get the dt parts, and simple LED-only driver w/o the
> strobe functinality, you may be able to get it merged rather quickly.
> 

I'm not really interested in having a torch-only driver merged if a full 
driver with torch & strobe is already working. For the PinePhone we maintain a 
separate kernel repository anyways so it doesn't matter much when exactly the 
driver is going to get merged.

> Best regards,
> 								
Pavel

Regards
Luca



^ permalink raw reply	[relevance 99%]

* Re: [RFC PATCH] leds: add sgm3140 driver
  @ 2020-03-08 16:55 99%       ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-08 16:55 UTC (permalink / raw)
  To: linux-leds, Jacek Anaszewski
  Cc: ~postmarketos/upstreaming, Pavel Machek, Dan Murphy, linux-kernel

Hi Jacek,

On Sonntag, 8. März 2020 17:47:17 CET Jacek Anaszewski wrote:
> Hi Luca,
> 
> On 3/8/20 12:32 PM, Luca Weiss wrote:
> > Hi Jacek,
> > 
> > Thanks for your review! Replies are inline below.
> > 
> > I'm wondering if I should implement support for the flash-max-timeout-us
> > dt
> > property ("Maximum timeout in microseconds after which the flash LED is
> > turned off.") to configure the timeout to turn the flash off as I've
> > currently hardcoded 250ms but this might not be ideal for all uses of the
> > sgm3140. The datasheet> 
> > states:
> >> Flash mode is usually used with a pulse of about 200 to 300 milliseconds
> >> to
> >> generate a high intensity Flash.
> > 
> > so it might be useful to have this configurable in the devicetree. The
> > value of 250ms works fine for my use case.
> 
> Yeah, I was to mentioned that.
> 
> > Theoretically also the .timeout_set op could be implemented but I'm not
> > sure if this fits nicely into the existing "timeout" API and if it even
> > makes sense to implement that.
> 
> Why wouldn't it fit? You can implement timeout_set op and cache flash
> timeout value in it. Then that cached value would be passed in
> strobe_set to mod_timer() in place of currently hard coded 250.
> 

I'll implement that then.

> > Regards,
> > Luca
> > 
> > On Donnerstag, 5. März 2020 22:09:16 CET Jacek Anaszewski wrote:
> >> Hi Luca,
> >> 
> >> Thank you for the patch.
> >> 
> >> On 2/27/20 7:50 PM, Luca Weiss wrote:
> >>> Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> >>> 
> >>> This device is controller by two GPIO lines, one for enabling the LED
> >>> and the second one for switching between torch and flash mode.
> >>> 
> >>> The device will automatically switch to torch mode after being in flash
> >>> mode for about 250-300ms, so after that time the driver will turn the
> >>> LED off again automatically.
> >>> 
> >>> Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> >>> ---
> >>> Hi, this driver is controllable via sysfs and v4l2 APIs (as documented
> >>> in Documentation/leds/leds-class-flash.rst).
> >>> 
> >>> The following is possible:
> >>> 
> >>> # Torch on
> >>> echo 1 > /sys/class/leds/white\:flash/brightness
> >>> # Torch off
> >>> echo 0 > /sys/class/leds/white\:flash/brightness
> >>> # Activate flash
> >>> echo 1 > /sys/class/leds/white\:flash/flash_strobe
> >>> 
> >>> # Torch on
> >>> v4l2-ctl -d /dev/video1 -c led_mode=2
> >>> # Torch off
> >>> v4l2-ctl -d /dev/video1 -c led_mode=0
> >>> # Activate flash
> >>> v4l2-ctl -d /dev/video1 -c strobe=1
> >> 
> >> What is /dev/video1 ? Did you register vl42 flash subdev
> >> in some v4l2 media controller device?
> > 
> > On the Allwinner A64 SoC /dev/video0 is the node for cedrus (video
> > encoder/
> > decoder), so the sun6i-csi driver gets to be /dev/video1
> > 
> > # v4l2-ctl --list-devices
> > 
> > cedrus (platform:cedrus):
> >         /dev/video0
> >         /dev/media0
> > 
> > sun6i-csi (platform:csi):
> >         /dev/video1
> > 
> > Allwinner Video Capture Device (platform:sun6i-csi):
> >         /dev/media1
> > 
> > Here's the relevant part from my dts:
> > 
> > sgm3140 {
> > 
> >     compatible = "sgmicro,sgm3140";
> >     flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* FLASH_TRIGOUT: PD24 */
> >     enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* FLASH_EN: PC3 */
> >     
> >     sgm3140_flash: led {
> >     
> >         function = LED_FUNCTION_FLASH;
> >         color = <LED_COLOR_ID_WHITE>;
> >     
> >     };
> > 
> > };
> 
> This needs to be documented in DT bindings for this driver.
> 

I have already written some yesterday, will post them with my v1 :)

> > /* as subnode of csi (compatible: allwinner,sun50i-a64-csi) */
> > ov5640: rear-camera@4c {
> > 
> >     compatible = "ovti,ov5640";
> >     <snip>
> >     flash-leds = <&sgm3140_flash>;
> > 
> > };
> 
> And this in camera bindings.

This is documented at 
Documentation/devicetree/bindings/media/video-interfaces.txt:

- flash-leds: An array of phandles, each referring to a flash LED, a sub-node
  of the LED driver device node.

Without referencing the flash device in a camera node, the v4l2 controls won't 
even show up from what I saw.
The binding is apparently only used in omap3-n9 and omap3-n950 currently; only 
phones have flash leds normally and the phones that are currently in mainline 
Linux don't have camera support yet.

Regards
Luca



^ permalink raw reply	[relevance 99%]

* [PATCH 0/3] Add sgm3140 flash led driver
@ 2020-03-09 20:35 99% Luca Weiss
  2020-03-09 20:35 99% ` [PATCH 1/3] dt-bindings: Add vendor prefix for SG Micro Corp Luca Weiss
                   ` (3 more replies)
  0 siblings, 4 replies; 84+ results
From: Luca Weiss @ 2020-03-09 20:35 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

This series introduces a driver for the SGMICRO SGM3140 charge pump
used in the PinePhone smartphone.

Luca Weiss (3):
  dt-bindings: Add vendor prefix for SG Micro Corp
  dt-bindings: leds: Add binding for sgm3140
  leds: add sgm3140 driver

 .../bindings/leds/leds-sgm3140.yaml           |  53 ++++
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 drivers/leds/Kconfig                          |   9 +
 drivers/leds/Makefile                         |   1 +
 drivers/leds/leds-sgm3140.c                   | 260 ++++++++++++++++++
 5 files changed, 325 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
 create mode 100644 drivers/leds/leds-sgm3140.c

-- 
2.25.1


^ permalink raw reply	[relevance 99%]

* [PATCH 3/3] leds: add sgm3140 driver
  2020-03-09 20:35 99% [PATCH 0/3] Add sgm3140 flash led driver Luca Weiss
  2020-03-09 20:35 99% ` [PATCH 1/3] dt-bindings: Add vendor prefix for SG Micro Corp Luca Weiss
  2020-03-09 20:35 90% ` [PATCH 2/3] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
@ 2020-03-09 20:35 68% ` Luca Weiss
      3 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2020-03-09 20:35 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.

This device is controlled by two GPIO pins, one for enabling and the
second one for switching between torch and flash mode.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes since RFC:
- address review comments from Jacek Anaszewski:
  - implement strobe_get op
  - implement timeout_set op
  - init v4l2_sd_cfg variable
  - remove init_data.devicename assignemnt
  - use devm_ version of led_classdev_flash_register_ext
  - release child_node in case of success

 drivers/leds/Kconfig        |   9 ++
 drivers/leds/Makefile       |   1 +
 drivers/leds/leds-sgm3140.c | 260 ++++++++++++++++++++++++++++++++++++
 3 files changed, 270 insertions(+)
 create mode 100644 drivers/leds/leds-sgm3140.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 4b68520ac251..9206fc66799d 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -836,6 +836,15 @@ config LEDS_LM36274
 	  Say Y to enable the LM36274 LED driver for TI LMU devices.
 	  This supports the LED device LM36274.
 
+config LEDS_SGM3140
+	tristate "LED support for the SGM3140"
+	depends on LEDS_CLASS_FLASH
+	depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
+	depends on OF
+	help
+	  This option enables support for the SGM3140 500mA Buck/Boost Charge
+	  Pump LED Driver.
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 2da39e896ce8..38d57dd53e4b 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X)		+= leds-lm3601x.o
 obj-$(CONFIG_LEDS_TI_LMU_COMMON)	+= leds-ti-lmu-common.o
 obj-$(CONFIG_LEDS_LM3697)		+= leds-lm3697.o
 obj-$(CONFIG_LEDS_LM36274)		+= leds-lm36274.o
+obj-$(CONFIG_LEDS_SGM3140)		+= leds-sgm3140.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_CR0014114)		+= leds-cr0014114.o
diff --git a/drivers/leds/leds-sgm3140.c b/drivers/leds/leds-sgm3140.c
new file mode 100644
index 000000000000..357f4cbb279a
--- /dev/null
+++ b/drivers/leds/leds-sgm3140.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2020 Luca Weiss <luca@z3ntu.xyz>
+
+#include <linux/gpio/consumer.h>
+#include <linux/led-class-flash.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <media/v4l2-flash-led-class.h>
+
+#define FLASH_TIMEOUT_DEFAULT		250000 /* 250ms */
+#define FLASH_MAX_TIMEOUT_DEFAULT	300000 /* 300ms */
+
+struct sgm3140 {
+	struct gpio_desc *flash_gpio;
+	struct gpio_desc *enable_gpio;
+
+	/* current timeout in us */
+	u32 timeout;
+	/* maximum timeout in us */
+	u32 max_timeout;
+
+	struct led_classdev_flash fled_cdev;
+	struct v4l2_flash *v4l2_flash;
+
+	struct timer_list powerdown_timer;
+};
+
+static struct sgm3140 *flcdev_to_sgm3140(struct led_classdev_flash *flcdev)
+{
+	return container_of(flcdev, struct sgm3140, fled_cdev);
+}
+
+static int sgm3140_strobe_set(struct led_classdev_flash *fled_cdev, bool state)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	if (state) {
+		gpiod_set_value_cansleep(priv->flash_gpio, 1);
+		gpiod_set_value_cansleep(priv->enable_gpio, 1);
+		mod_timer(&priv->powerdown_timer,
+			  jiffies + usecs_to_jiffies(priv->timeout));
+	} else {
+		gpiod_set_value_cansleep(priv->enable_gpio, 0);
+		gpiod_set_value_cansleep(priv->flash_gpio, 0);
+		del_timer_sync(&priv->powerdown_timer);
+	}
+
+	return 0;
+}
+
+static int sgm3140_strobe_get(struct led_classdev_flash *fled_cdev, bool *state)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	*state = timer_pending(&priv->powerdown_timer);
+
+	return 0;
+}
+
+static int sgm3140_timeout_set(struct led_classdev_flash *fled_cdev, u32 timeout)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	priv->timeout = timeout;
+
+	return 0;
+}
+
+struct led_flash_ops sgm3140_flash_ops = {
+	.strobe_set = sgm3140_strobe_set,
+	.strobe_get = sgm3140_strobe_get,
+	.timeout_set = sgm3140_timeout_set,
+};
+
+int sgm3140_brightness_set(struct led_classdev *led_cdev,
+			   enum led_brightness brightness)
+{
+	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	if (brightness == LED_OFF)
+		gpiod_set_value_cansleep(priv->enable_gpio, 0);
+	else
+		gpiod_set_value_cansleep(priv->enable_gpio, 1);
+
+	return 0;
+}
+
+static void sgm3140_powerdown_timer(struct timer_list *t)
+{
+	struct sgm3140 *priv = from_timer(priv, t, powerdown_timer);
+
+	gpiod_set_value_cansleep(priv->enable_gpio, 0);
+	gpiod_set_value_cansleep(priv->flash_gpio, 0);
+}
+
+static void sgm3140_init_flash_timeout(struct sgm3140 *priv)
+{
+	struct led_classdev_flash *fled_cdev = &priv->fled_cdev;
+	struct led_flash_setting *s;
+
+	/* Init flash timeout setting */
+	s = &fled_cdev->timeout;
+	s->min = 1;
+	s->max = priv->max_timeout;
+	s->step = 1;
+	s->val = FLASH_TIMEOUT_DEFAULT;
+}
+
+#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
+static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
+					   struct v4l2_flash_config *v4l2_sd_cfg)
+{
+	struct led_classdev *led_cdev = &priv->fled_cdev.led_cdev;
+	struct led_flash_setting *s;
+
+	strlcpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name,
+		sizeof(v4l2_sd_cfg->dev_name));
+
+	/* Init flash intensity setting */
+	s = &v4l2_sd_cfg->intensity;
+	s->min = 0;
+	s->max = 1;
+	s->step = 1;
+	s->val = 1;
+}
+
+#else
+static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
+					   struct v4l2_flash_config *v4l2_sd_cfg)
+{
+}
+#endif
+
+static int sgm3140_probe(struct platform_device *pdev)
+{
+	struct sgm3140 *priv;
+	struct led_classdev *led_cdev;
+	struct led_classdev_flash *fled_cdev;
+	struct led_init_data init_data = {};
+	struct device_node *child_node;
+	struct v4l2_flash_config v4l2_sd_cfg = {};
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->flash_gpio = devm_gpiod_get(&pdev->dev, "flash", GPIOD_OUT_LOW);
+	ret = PTR_ERR_OR_ZERO(priv->flash_gpio);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request flash gpio: %d\n",
+				ret);
+		return ret;
+	}
+
+	priv->enable_gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	ret = PTR_ERR_OR_ZERO(priv->enable_gpio);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Failed to request enable gpio: %d\n",
+				ret);
+		return ret;
+	}
+
+	child_node = of_get_next_available_child(pdev->dev.of_node, NULL);
+	if (!child_node) {
+		dev_err(&pdev->dev, "No DT child node found for connected LED.\n");
+		return -EINVAL;
+	}
+
+
+	ret = of_property_read_u32(child_node, "flash-max-timeout-us",
+				   &priv->max_timeout);
+	if (ret < 0) {
+		priv->max_timeout = FLASH_MAX_TIMEOUT_DEFAULT;
+		dev_warn(&pdev->dev, "flash-max-timeout-us DT property missing\n");
+	}
+
+	/*
+	 * Set default timeout to FLASH_DEFAULT_TIMEOUT except if max_timeout
+	 * from DT is lower.
+	 */
+	priv->timeout = min(priv->max_timeout, (u32)FLASH_TIMEOUT_DEFAULT);
+
+	timer_setup(&priv->powerdown_timer, sgm3140_powerdown_timer, 0);
+
+	fled_cdev = &priv->fled_cdev;
+	led_cdev = &fled_cdev->led_cdev;
+
+	fled_cdev->ops = &sgm3140_flash_ops;
+
+	led_cdev->brightness_set_blocking = sgm3140_brightness_set;
+	led_cdev->max_brightness = LED_ON;
+	led_cdev->flags |= LED_DEV_CAP_FLASH;
+
+	sgm3140_init_flash_timeout(priv);
+
+	init_data.fwnode = of_fwnode_handle(child_node);
+
+	platform_set_drvdata(pdev, priv);
+
+	/* Register in the LED subsystem */
+	ret = devm_led_classdev_flash_register_ext(&pdev->dev, fled_cdev, &init_data);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register flash device: %d\n",
+			ret);
+		goto err;
+	}
+
+	sgm3140_init_v4l2_flash_config(priv, &v4l2_sd_cfg);
+
+	/* Create V4L2 Flash subdev */
+	priv->v4l2_flash = v4l2_flash_init(&pdev->dev, of_fwnode_handle(child_node),
+					   fled_cdev, NULL,
+					   &v4l2_sd_cfg);
+	if (IS_ERR(priv->v4l2_flash)) {
+		ret = PTR_ERR(priv->v4l2_flash);
+		goto err;
+	}
+
+err:
+	of_node_put(child_node);
+	return ret;
+}
+
+static int sgm3140_remove(struct platform_device *pdev)
+{
+	struct sgm3140 *priv = platform_get_drvdata(pdev);
+
+	del_timer_sync(&priv->powerdown_timer);
+
+	v4l2_flash_release(priv->v4l2_flash);
+
+	return 0;
+}
+
+static const struct of_device_id sgm3140_dt_match[] = {
+	{ .compatible = "sgmicro,sgm3140" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sgm3140_dt_match);
+
+static struct platform_driver sgm3140_driver = {
+	.probe	= sgm3140_probe,
+	.remove	= sgm3140_remove,
+	.driver	= {
+		.name	= "sgm3140",
+		.of_match_table = sgm3140_dt_match,
+	},
+};
+
+module_platform_driver(sgm3140_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xyz>");
+MODULE_DESCRIPTION("SG Micro SGM3140 charge pump led driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1


^ permalink raw reply	[relevance 68%]

* [PATCH 2/3] dt-bindings: leds: Add binding for sgm3140
  2020-03-09 20:35 99% [PATCH 0/3] Add sgm3140 flash led driver Luca Weiss
  2020-03-09 20:35 99% ` [PATCH 1/3] dt-bindings: Add vendor prefix for SG Micro Corp Luca Weiss
@ 2020-03-09 20:35 90% ` Luca Weiss
      2020-03-09 20:35 68% ` [PATCH 3/3] leds: add sgm3140 driver Luca Weiss
    3 siblings, 2 replies; 84+ results
From: Luca Weiss @ 2020-03-09 20:35 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

Add YAML devicetree binding for SGMICRO SGM3140 charge pump used for
camera flash LEDs.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes since RFC:
- new patch

I'm not sure about the completeness of this binding as it doesn't
mention the led subnode at all.
The only existing led yaml binding is leds/leds-max77650.yaml which
mentions the subnode but duplicates properties from documented in 
leds/common.txt.

 .../bindings/leds/leds-sgm3140.yaml           | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-sgm3140.yaml

diff --git a/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
new file mode 100644
index 000000000000..be9384573d02
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/leds-sgm3140.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SGMICRO SGM3140 500mA Buck/Boost Charge Pump LED Driver
+
+maintainers:
+  - Luca Weiss <luca@z3ntu.xyz>
+
+description: |
+  The SGM3140 is a current-regulated charge pump which can regulate two current
+  levels for Flash and Torch modes.
+
+  It is controlled with two GPIO pins.
+
+  The data sheet can be found at:
+    http://www.sg-micro.com/uploads/soft/20190626/1561535688.pdf
+
+properties:
+  compatible:
+    const: sgmicro,sgm3140
+
+  enable-gpios:
+    maxItems: 1
+    description: A connection to the 'EN' pin.
+
+  flash-gpios:
+    maxItems: 1
+    description: A connection to the 'FLASH' pin.
+
+required:
+  - compatible
+  - flash-gpios
+  - enable-gpios
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/leds/common.h>
+
+    sgm3140 {
+        compatible = "sgmicro,sgm3140";
+        flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
+        enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
+
+        sgm3140_flash: led {
+            function = LED_FUNCTION_FLASH;
+            color = <LED_COLOR_ID_WHITE>;
+            flash-max-timeout-us = <250000>;
+        };
+    };
-- 
2.25.1


^ permalink raw reply	[relevance 90%]

* [PATCH 1/3] dt-bindings: Add vendor prefix for SG Micro Corp
  2020-03-09 20:35 99% [PATCH 0/3] Add sgm3140 flash led driver Luca Weiss
@ 2020-03-09 20:35 99% ` Luca Weiss
  2020-03-09 20:35 90% ` [PATCH 2/3] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-09 20:35 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

"SG Micro Corp (SGMICRO) specializes in high performance, high quality
analog IC design, marketing and sales." (http://www.sg-micro.com/)

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes since RFC:
- new patch

 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 8d306af435a3..059ff7bc0c79 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -843,6 +843,8 @@ patternProperties:
     description: Small Form Factor Committee
   "^sgd,.*":
     description: Solomon Goldentek Display Corporation
+  "^sgmicro,.*":
+    description: SG Micro Corp
   "^sgx,.*":
     description: SGX Sensortech
   "^sharp,.*":
-- 
2.25.1


^ permalink raw reply	[relevance 99%]

* Re: [PATCH 3/3] leds: add sgm3140 driver
  @ 2020-03-09 22:52 96%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-09 22:52 UTC (permalink / raw)
  To: Sakari Ailus, Pavel Machek
  Cc: linux-leds, Dan Murphy, Heiko Stuebner, Icenowy Zheng,
	Jacek Anaszewski, Laurent Pinchart, Mark Rutland, Maxime Ripard,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming

Hi Pavel

On Montag, 9. März 2020 23:49:27 CET Pavel Machek wrote:
> Hi!
> 
> > > +#define FLASH_TIMEOUT_DEFAULT		250000 /* 250ms */
> > > +#define FLASH_MAX_TIMEOUT_DEFAULT	300000 /* 300ms */
> > 
> > Add U, and you can remove the cast elsewhere.
> 
> I'll disagree here. Avoid U, avoid cast. Neither is needed.

If neither cast to u32 nor the U suffix is used, then this warning will be 
printed:

In file included from ./include/asm-generic/bug.h:19,
                 from ./arch/arm64/include/asm/bug.h:26,
                 from ./include/linux/bug.h:5,
                 from ./include/linux/gpio/consumer.h:5,
                 from drivers/leds/leds-sgm3140.c:4:
drivers/leds/leds-sgm3140.c: In function 'sgm3140_probe':
./include/linux/kernel.h:835:29: warning: comparison of distinct pointer types 
lacks a cast
  835 |   (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
      |                             ^~
./include/linux/kernel.h:849:4: note: in expansion of macro '__typecheck'
  849 |   (__typecheck(x, y) && __no_side_effects(x, y))
      |    ^~~~~~~~~~~
./include/linux/kernel.h:859:24: note: in expansion of macro '__safe_cmp'
  859 |  __builtin_choose_expr(__safe_cmp(x, y), \
      |                        ^~~~~~~~~~
./include/linux/kernel.h:868:19: note: in expansion of macro '__careful_cmp'
  868 | #define min(x, y) __careful_cmp(x, y, <)
      |                   ^~~~~~~~~~~~~
drivers/leds/leds-sgm3140.c:187:18: note: in expansion of macro 'min'
  187 |  priv->timeout = min(priv->max_timeout, FLASH_TIMEOUT_DEFAULT);
      |                  ^~~

So one of both is needed.

> 
> Best regards,
> 								
	Pavel

Regards
Luca



^ permalink raw reply	[relevance 96%]

* Re: [PATCH 3/3] leds: add sgm3140 driver
  @ 2020-03-15 10:42 95%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-15 10:42 UTC (permalink / raw)
  To: linux-leds, Dan Murphy
  Cc: Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming

Hi Dan,

On Mittwoch, 11. März 2020 14:02:44 CET Dan Murphy wrote:
> Luca
> 
> On 3/9/20 3:35 PM, Luca Weiss wrote:
> > Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> > 
> > This device is controlled by two GPIO pins, one for enabling and the
> > second one for switching between torch and flash mode.
> 
> How does one enable torch and one enable flash?
> 
> Is the flash-gpio control this or does the enable-gpio enable the flash?

Enabling torch mode means making EN pin high and FLASH pin low.
Enabling flash mode means making EN pin high and FLASH pin high.

The users of this driver can just use standard v4l2 apis or sysfs so I 
wouldn't say this is relevant for the users.

> 
> The DT binding did not indicate what the GPIOs are really going to control.

I'm not sure if this is relevant in the dt bindings because how the device 
works is described in the datasheet and not really relevant for users of the 
binding? I also didn't necessarily want to copy-paste the datasheet into the 
dt bindings because of copyright.

> 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > ---
> > Changes since RFC:
> > 
> > - address review comments from Jacek Anaszewski:
> >    - implement strobe_get op
> >    - implement timeout_set op
> >    - init v4l2_sd_cfg variable
> >    - remove init_data.devicename assignemnt
> >    - use devm_ version of led_classdev_flash_register_ext
> >    - release child_node in case of success
> >   
> >   drivers/leds/Kconfig        |   9 ++
> >   drivers/leds/Makefile       |   1 +
> >   drivers/leds/leds-sgm3140.c | 260 ++++++++++++++++++++++++++++++++++++
> >   3 files changed, 270 insertions(+)
> >   create mode 100644 drivers/leds/leds-sgm3140.c
> > 

> SNIP

> > +	if (!child_node) {
> > +		dev_err(&pdev->dev, "No DT child node found for 
connected LED.\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +
> > +	ret = of_property_read_u32(child_node, "flash-max-timeout-us",
> > +				   &priv->max_timeout);
> 
> Please use the device_property api's to retrieve DT settings.  Then
> there is no need to release the "of" child node.
> 

I'm guessing you mean

device_property_read_u32(&pdev->dev, "flash-max-timeout-us", &priv-
>max_timeout);

?

I still need the child_node for "init_data.fwnode" and v4l2_flash_init so I 
still have to call of_node_put, right?

> > +	if (ret < 0) {
> 
> if (ret)

Ack

> SNIP

> > +	/* Create V4L2 Flash subdev */
> > +	priv->v4l2_flash = v4l2_flash_init(&pdev->dev,
> > of_fwnode_handle(child_node), +					
   fled_cdev, NULL,
> > +					   &v4l2_sd_cfg);
> > +	if (IS_ERR(priv->v4l2_flash)) {
> > +		ret = PTR_ERR(priv->v4l2_flash);
> > +		goto err;
> 
> Do you need to jump here?  This should just fall out and go through err
> anyway.

Should I just do

if (IS_ERR(priv->v4l2_flash))
	ret = PTR_ERR(priv->v4l2_flash);

?

I thought about removing the goto but I decided to keep it in case code is 
added below that statement so that the goto wouldn't be forgotten. But I can 
change it of course if wanted.

> 
> Dan

Regards
Luca



^ permalink raw reply	[relevance 95%]

* Re: [PATCH 2/3] dt-bindings: leds: Add binding for sgm3140
  @ 2020-03-15 10:47 99%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-15 10:47 UTC (permalink / raw)
  To: linux-leds, Dan Murphy
  Cc: Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming

Hi Dan

On Mittwoch, 11. März 2020 13:49:35 CET Dan Murphy wrote:
> Luca
> 
> On 3/9/20 3:35 PM, Luca Weiss wrote:
> > Add YAML devicetree binding for SGMICRO SGM3140 charge pump used for
> > camera flash LEDs.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > ---
> > Changes since RFC:
> > - new patch
> > 
> > I'm not sure about the completeness of this binding as it doesn't
> > mention the led subnode at all.
> > The only existing led yaml binding is leds/leds-max77650.yaml which
> > mentions the subnode but duplicates properties from documented in
> > leds/common.txt.
> > 
> >   .../bindings/leds/leds-sgm3140.yaml           | 53 +++++++++++++++++++
> >   1 file changed, 53 insertions(+)
> >   create mode 100644
> >   Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
> > b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml new file mode
> > 100644
> > index 000000000000..be9384573d02
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
> > @@ -0,0 +1,53 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/leds/leds-sgm3140.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: SGMICRO SGM3140 500mA Buck/Boost Charge Pump LED Driver
> > +
> > +maintainers:
> > +  - Luca Weiss <luca@z3ntu.xyz>
> > +
> > +description: |
> > +  The SGM3140 is a current-regulated charge pump which can regulate two
> > current +  levels for Flash and Torch modes.
> > +
> > +  It is controlled with two GPIO pins.
> 
> Please define "It".  Not sure what is controlled here.
> 

"It" means the SGM3140. Not sure how else to write that or what the correct 
term for such a component is.

> 
> Dan

Regards
Luca




^ permalink raw reply	[relevance 99%]

* Re: [v2 6/6] arm64: defconfig: Enable QCOM CAMCC, CAMSS and CCI drivers
  @ 2020-03-20 19:52 99%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-20 19:52 UTC (permalink / raw)
  To: agross, bjorn.andersson, robh+dt, mark.rutland, catalin.marinas,
	will, shawnguo, olof, maxime, Anson.Huang, dinguyen,
	leonard.crestez, marcin.juszkiewicz, linux-arm-msm, devicetree,
	linux-kernel, linux-arm-kernel, Loic Poulain, Robert Foss
  Cc: Robert Foss

Hi Robert,

On Dienstag, 17. März 2020 14:57:40 CET Robert Foss wrote:
> Build camera clock, isp and controller drivers as modules.
> 
> Signed-off-by: Robert Foss <robert.foss@linaro.org>
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
>  arch/arm64/configs/defconfig | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 4db223dbc549..7cb6989249ab 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -376,6 +376,7 @@ CONFIG_I2C_MESON=y
>  CONFIG_I2C_MV64XXX=y
>  CONFIG_I2C_OWL=y
>  CONFIG_I2C_PXA=y
> +CONFIG_I2C_QCOM_CCI=m
>  CONFIG_I2C_QCOM_GENI=m
>  CONFIG_I2C_QUP=y
>  CONFIG_I2C_RK3X=y
> @@ -530,6 +531,7 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
>  CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
>  CONFIG_VIDEO_RENESAS_FCP=m
>  CONFIG_VIDEO_RENESAS_VSP1=m
> +CONFIG_VIDEO_QCOM_CAMSS=m
>  CONFIG_DRM=m
>  CONFIG_DRM_I2C_NXP_TDA998X=m
>  CONFIG_DRM_NOUVEAU=m
> @@ -732,6 +734,7 @@ CONFIG_MSM_GCC_8994=y
>  CONFIG_MSM_MMCC_8996=y
>  CONFIG_MSM_GCC_8998=y
>  CONFIG_QCS_GCC_404=y
> +CONFIG_SDM_CAMCC_845=m

You seem to have this option twice in this patch.

>  CONFIG_SDM_GCC_845=y
>  CONFIG_SM_GCC_8150=y
>  CONFIG_QCOM_HFPLL=y
> @@ -762,6 +765,7 @@ CONFIG_QCOM_COMMAND_DB=y
>  CONFIG_QCOM_GENI_SE=y
>  CONFIG_QCOM_GLINK_SSR=m
>  CONFIG_QCOM_RMTFS_MEM=m
> +CONFIG_SDM_CAMCC_845=m

^

>  CONFIG_QCOM_RPMH=y
>  CONFIG_QCOM_RPMHPD=y
>  CONFIG_QCOM_SMEM=y

Regards
Luca



^ permalink raw reply	[relevance 99%]

* Re: [PATCH 2/3] dt-bindings: leds: Add binding for sgm3140
  @ 2020-03-24 20:02 99%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-24 20:02 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-leds, Dan Murphy, Heiko Stuebner, Icenowy Zheng,
	Jacek Anaszewski, Laurent Pinchart, Mark Rutland, Maxime Ripard,
	Pavel Machek, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming

Hi Rob,

On Montag, 23. März 2020 21:57:27 CET Rob Herring wrote:
> On Mon, Mar 09, 2020 at 09:35:57PM +0100, Luca Weiss wrote:
> > Add YAML devicetree binding for SGMICRO SGM3140 charge pump used for
> > camera flash LEDs.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > ---
> > Changes since RFC:
> > - new patch
> > 
> > I'm not sure about the completeness of this binding as it doesn't
> > mention the led subnode at all.
> > The only existing led yaml binding is leds/leds-max77650.yaml which
> > mentions the subnode but duplicates properties from documented in
> > leds/common.txt.
> 
> It's common.yaml now. Reference it from a child node defined here.

Thanks, that helps a lot!

> 
> >  .../bindings/leds/leds-sgm3140.yaml           | 53 +++++++++++++++++++
> >  1 file changed, 53 insertions(+)
> >  create mode 100644
> >  Documentation/devicetree/bindings/leds/leds-sgm3140.yaml

Regards
Luca



^ permalink raw reply	[relevance 99%]

* [PATCH v2 0/2] Add sgm3140 flash led driver
@ 2020-03-30 19:47 99% Luca Weiss
  2020-03-30 19:47 91% ` [PATCH v2 1/2] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
  2020-03-30 19:47 64% ` [PATCH v2 2/2] leds: add sgm3140 driver Luca Weiss
  0 siblings, 2 replies; 84+ results
From: Luca Weiss @ 2020-03-30 19:47 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

This series introduces a driver for the SGMICRO SGM3140 charge pump
used in the PinePhone smartphone.

Luca Weiss (2):
  dt-bindings: leds: Add binding for sgm3140
  leds: add sgm3140 driver

 .../bindings/leds/leds-sgm3140.yaml           |  61 ++++
 drivers/leds/Kconfig                          |   9 +
 drivers/leds/Makefile                         |   1 +
 drivers/leds/leds-sgm3140.c                   | 317 ++++++++++++++++++
 4 files changed, 388 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
 create mode 100644 drivers/leds/leds-sgm3140.c

-- 
2.26.0


^ permalink raw reply	[relevance 99%]

* [PATCH v2 1/2] dt-bindings: leds: Add binding for sgm3140
  2020-03-30 19:47 99% [PATCH v2 0/2] Add sgm3140 flash led driver Luca Weiss
@ 2020-03-30 19:47 91% ` Luca Weiss
  2020-03-30 19:47 64% ` [PATCH v2 2/2] leds: add sgm3140 driver Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2020-03-30 19:47 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

Add YAML devicetree binding for SGMICRO SGM3140 charge pump used for
camera flash LEDs.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes since v1:
- Add vin-supply
- Add led subnode (common.yaml)

 .../bindings/leds/leds-sgm3140.yaml           | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-sgm3140.yaml

diff --git a/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
new file mode 100644
index 000000000000..24ca178e5d0a
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/leds-sgm3140.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SGMICRO SGM3140 500mA Buck/Boost Charge Pump LED Driver
+
+maintainers:
+  - Luca Weiss <luca@z3ntu.xyz>
+
+description: |
+  The SGM3140 is a current-regulated charge pump which can regulate two current
+  levels for Flash and Torch modes.
+
+  The data sheet can be found at:
+    http://www.sg-micro.com/uploads/soft/20190626/1561535688.pdf
+
+properties:
+  compatible:
+    const: sgmicro,sgm3140
+
+  enable-gpios:
+    maxItems: 1
+    description: A connection to the 'EN' pin.
+
+  flash-gpios:
+    maxItems: 1
+    description: A connection to the 'FLASH' pin.
+
+  vin-supply:
+    description: Regulator providing power to the 'VIN' pin.
+
+  led:
+    allOf:
+      - $ref: common.yaml#
+
+required:
+  - compatible
+  - flash-gpios
+  - enable-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/leds/common.h>
+
+    sgm3140 {
+        compatible = "sgmicro,sgm3140";
+        flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
+        enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
+        vin-supply = <&reg_dcdc1>;
+
+        sgm3140_flash: led {
+            function = LED_FUNCTION_FLASH;
+            color = <LED_COLOR_ID_WHITE>;
+            flash-max-timeout-us = <250000>;
+        };
+    };
-- 
2.26.0


^ permalink raw reply	[relevance 91%]

* [PATCH v2 2/2] leds: add sgm3140 driver
  2020-03-30 19:47 99% [PATCH v2 0/2] Add sgm3140 flash led driver Luca Weiss
  2020-03-30 19:47 91% ` [PATCH v2 1/2] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
@ 2020-03-30 19:47 64% ` Luca Weiss
      1 sibling, 2 replies; 84+ results
From: Luca Weiss @ 2020-03-30 19:47 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.

This device is controlled by two GPIO pins, one for enabling and the
second one for switching between torch and flash mode.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes since v1:
- Add vin-supply (keep track of 'enabled' state for that)
- Wrap lines
- static const -ify some structs and methods
- use strscpy instead of strlcpy
- remove u32 cast by adding 'U' suffix to constants
- rebase on linux-next

 drivers/leds/Kconfig        |   9 +
 drivers/leds/Makefile       |   1 +
 drivers/leds/leds-sgm3140.c | 317 ++++++++++++++++++++++++++++++++++++
 3 files changed, 327 insertions(+)
 create mode 100644 drivers/leds/leds-sgm3140.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 7599dbee8de1..f5beeff16bdd 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -871,6 +871,15 @@ config LEDS_IP30
 	  To compile this driver as a module, choose M here: the module
 	  will be called leds-ip30.
 
+config LEDS_SGM3140
+	tristate "LED support for the SGM3140"
+	depends on LEDS_CLASS_FLASH
+	depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
+	depends on OF
+	help
+	  This option enables support for the SGM3140 500mA Buck/Boost Charge
+	  Pump LED Driver.
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index fd61421f7d40..f60ed0c09d4c 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_LEDS_PWM)			+= leds-pwm.o
 obj-$(CONFIG_LEDS_REGULATOR)		+= leds-regulator.o
 obj-$(CONFIG_LEDS_S3C24XX)		+= leds-s3c24xx.o
 obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
+obj-$(CONFIG_LEDS_SGM3140)		+= leds-sgm3140.o
 obj-$(CONFIG_LEDS_SUNFIRE)		+= leds-sunfire.o
 obj-$(CONFIG_LEDS_SYSCON)		+= leds-syscon.o
 obj-$(CONFIG_LEDS_TCA6507)		+= leds-tca6507.o
diff --git a/drivers/leds/leds-sgm3140.c b/drivers/leds/leds-sgm3140.c
new file mode 100644
index 000000000000..28fe5e34f931
--- /dev/null
+++ b/drivers/leds/leds-sgm3140.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2020 Luca Weiss <luca@z3ntu.xyz>
+
+#include <linux/gpio/consumer.h>
+#include <linux/led-class-flash.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+#include <linux/platform_device.h>
+
+#include <media/v4l2-flash-led-class.h>
+
+#define FLASH_TIMEOUT_DEFAULT		250000U /* 250ms */
+#define FLASH_MAX_TIMEOUT_DEFAULT	300000U /* 300ms */
+
+struct sgm3140 {
+	bool enabled;
+	struct gpio_desc *flash_gpio;
+	struct gpio_desc *enable_gpio;
+	struct regulator *vin_regulator;
+
+	/* current timeout in us */
+	u32 timeout;
+	/* maximum timeout in us */
+	u32 max_timeout;
+
+	struct led_classdev_flash fled_cdev;
+	struct v4l2_flash *v4l2_flash;
+
+	struct timer_list powerdown_timer;
+};
+
+static struct sgm3140 *flcdev_to_sgm3140(struct led_classdev_flash *flcdev)
+{
+	return container_of(flcdev, struct sgm3140, fled_cdev);
+}
+
+static int sgm3140_strobe_set(struct led_classdev_flash *fled_cdev, bool state)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+	int ret;
+
+	if (priv->enabled == state)
+		return 0;
+
+	if (state) {
+		ret = regulator_enable(priv->vin_regulator);
+		if (ret) {
+			dev_err(fled_cdev->led_cdev.dev,
+				"failed to enable regulator: %d\n", ret);
+			return ret;
+		}
+		gpiod_set_value_cansleep(priv->flash_gpio, 1);
+		gpiod_set_value_cansleep(priv->enable_gpio, 1);
+		mod_timer(&priv->powerdown_timer,
+			  jiffies + usecs_to_jiffies(priv->timeout));
+	} else {
+		del_timer_sync(&priv->powerdown_timer);
+		gpiod_set_value_cansleep(priv->enable_gpio, 0);
+		gpiod_set_value_cansleep(priv->flash_gpio, 0);
+		ret = regulator_disable(priv->vin_regulator);
+		if (ret) {
+			dev_err(fled_cdev->led_cdev.dev,
+				"failed to disable regulator: %d\n", ret);
+			return ret;
+		}
+	}
+
+	priv->enabled = state;
+
+	return 0;
+}
+
+static int sgm3140_strobe_get(struct led_classdev_flash *fled_cdev, bool *state)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	*state = timer_pending(&priv->powerdown_timer);
+
+	return 0;
+}
+
+static int sgm3140_timeout_set(struct led_classdev_flash *fled_cdev,
+			       u32 timeout)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	priv->timeout = timeout;
+
+	return 0;
+}
+
+static const struct led_flash_ops sgm3140_flash_ops = {
+	.strobe_set = sgm3140_strobe_set,
+	.strobe_get = sgm3140_strobe_get,
+	.timeout_set = sgm3140_timeout_set,
+};
+
+static int sgm3140_brightness_set(struct led_classdev *led_cdev,
+				  enum led_brightness brightness)
+{
+	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+	bool enable = brightness == LED_ON;
+	int ret;
+
+	if (priv->enabled == enable)
+		return 0;
+
+	if (enable) {
+		ret = regulator_enable(priv->vin_regulator);
+		if (ret) {
+			dev_err(led_cdev->dev,
+				"failed to enable regulator: %d\n", ret);
+			return ret;
+		}
+		gpiod_set_value_cansleep(priv->enable_gpio, 1);
+	} else {
+		gpiod_set_value_cansleep(priv->enable_gpio, 0);
+		ret = regulator_disable(priv->vin_regulator);
+		if (ret) {
+			dev_err(led_cdev->dev,
+				"failed to disable regulator: %d\n", ret);
+			return ret;
+		}
+	}
+
+	priv->enabled = enable;
+
+	return 0;
+}
+
+static void sgm3140_powerdown_timer(struct timer_list *t)
+{
+	struct sgm3140 *priv = from_timer(priv, t, powerdown_timer);
+
+	gpiod_set_value(priv->enable_gpio, 0);
+	gpiod_set_value(priv->flash_gpio, 0);
+	regulator_disable(priv->vin_regulator);
+
+	priv->enabled = false;
+}
+
+static void sgm3140_init_flash_timeout(struct sgm3140 *priv)
+{
+	struct led_classdev_flash *fled_cdev = &priv->fled_cdev;
+	struct led_flash_setting *s;
+
+	/* Init flash timeout setting */
+	s = &fled_cdev->timeout;
+	s->min = 1;
+	s->max = priv->max_timeout;
+	s->step = 1;
+	s->val = FLASH_TIMEOUT_DEFAULT;
+}
+
+#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
+static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
+					struct v4l2_flash_config *v4l2_sd_cfg)
+{
+	struct led_classdev *led_cdev = &priv->fled_cdev.led_cdev;
+	struct led_flash_setting *s;
+
+	strscpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name,
+		sizeof(v4l2_sd_cfg->dev_name));
+
+	/* Init flash intensity setting */
+	s = &v4l2_sd_cfg->intensity;
+	s->min = 0;
+	s->max = 1;
+	s->step = 1;
+	s->val = 1;
+}
+
+#else
+static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
+					struct v4l2_flash_config *v4l2_sd_cfg)
+{
+}
+#endif
+
+static int sgm3140_probe(struct platform_device *pdev)
+{
+	struct sgm3140 *priv;
+	struct led_classdev *led_cdev;
+	struct led_classdev_flash *fled_cdev;
+	struct led_init_data init_data = {};
+	struct device_node *child_node;
+	struct v4l2_flash_config v4l2_sd_cfg = {};
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->flash_gpio = devm_gpiod_get(&pdev->dev, "flash", GPIOD_OUT_LOW);
+	ret = PTR_ERR_OR_ZERO(priv->flash_gpio);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to request flash gpio: %d\n", ret);
+		return ret;
+	}
+
+	priv->enable_gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	ret = PTR_ERR_OR_ZERO(priv->enable_gpio);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to request enable gpio: %d\n", ret);
+		return ret;
+	}
+
+	priv->vin_regulator = devm_regulator_get(&pdev->dev, "vin");
+	ret = PTR_ERR_OR_ZERO(priv->vin_regulator);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to request regulator: %d\n", ret);
+		return ret;
+	}
+
+	child_node = of_get_next_available_child(pdev->dev.of_node, NULL);
+	if (!child_node) {
+		dev_err(&pdev->dev,
+			"No DT child node found for connected LED.\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(child_node, "flash-max-timeout-us",
+				   &priv->max_timeout);
+	if (ret) {
+		priv->max_timeout = FLASH_MAX_TIMEOUT_DEFAULT;
+		dev_warn(&pdev->dev,
+			 "flash-max-timeout-us DT property missing\n");
+	}
+
+	/*
+	 * Set default timeout to FLASH_DEFAULT_TIMEOUT except if max_timeout
+	 * from DT is lower.
+	 */
+	priv->timeout = min(priv->max_timeout, FLASH_TIMEOUT_DEFAULT);
+
+	timer_setup(&priv->powerdown_timer, sgm3140_powerdown_timer, 0);
+
+	fled_cdev = &priv->fled_cdev;
+	led_cdev = &fled_cdev->led_cdev;
+
+	fled_cdev->ops = &sgm3140_flash_ops;
+
+	led_cdev->brightness_set_blocking = sgm3140_brightness_set;
+	led_cdev->max_brightness = LED_ON;
+	led_cdev->flags |= LED_DEV_CAP_FLASH;
+
+	sgm3140_init_flash_timeout(priv);
+
+	init_data.fwnode = of_fwnode_handle(child_node);
+
+	platform_set_drvdata(pdev, priv);
+
+	/* Register in the LED subsystem */
+	ret = devm_led_classdev_flash_register_ext(&pdev->dev,
+						   fled_cdev, &init_data);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register flash device: %d\n",
+			ret);
+		goto err;
+	}
+
+	sgm3140_init_v4l2_flash_config(priv, &v4l2_sd_cfg);
+
+	/* Create V4L2 Flash subdev */
+	priv->v4l2_flash = v4l2_flash_init(&pdev->dev,
+					   of_fwnode_handle(child_node),
+					   fled_cdev, NULL,
+					   &v4l2_sd_cfg);
+	if (IS_ERR(priv->v4l2_flash)) {
+		ret = PTR_ERR(priv->v4l2_flash);
+		goto err;
+	}
+
+err:
+	of_node_put(child_node);
+	return ret;
+}
+
+static int sgm3140_remove(struct platform_device *pdev)
+{
+	struct sgm3140 *priv = platform_get_drvdata(pdev);
+
+	del_timer_sync(&priv->powerdown_timer);
+
+	v4l2_flash_release(priv->v4l2_flash);
+
+	return 0;
+}
+
+static const struct of_device_id sgm3140_dt_match[] = {
+	{ .compatible = "sgmicro,sgm3140" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sgm3140_dt_match);
+
+static struct platform_driver sgm3140_driver = {
+	.probe	= sgm3140_probe,
+	.remove	= sgm3140_remove,
+	.driver	= {
+		.name	= "sgm3140",
+		.of_match_table = sgm3140_dt_match,
+	},
+};
+
+module_platform_driver(sgm3140_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xyz>");
+MODULE_DESCRIPTION("SG Micro SGM3140 charge pump led driver");
+MODULE_LICENSE("GPL v2");
-- 
2.26.0


^ permalink raw reply	[relevance 64%]

* Re: [PATCH v2 2/2] leds: add sgm3140 driver
  @ 2020-04-04  9:36 96%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-04-04  9:36 UTC (permalink / raw)
  To: linux-leds, Dan Murphy
  Cc: Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming

Hi Dan,

On Freitag, 3. April 2020 19:31:52 CEST Dan Murphy wrote:
> Luca
> 
> On 3/30/20 2:47 PM, Luca Weiss wrote:
> > Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> > 
> > This device is controlled by two GPIO pins, one for enabling and the
> > second one for switching between torch and flash mode.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > ---
> > Changes since v1:
> > - Add vin-supply (keep track of 'enabled' state for that)
> > - Wrap lines
> > - static const -ify some structs and methods
> > - use strscpy instead of strlcpy
> > - remove u32 cast by adding 'U' suffix to constants
> > - rebase on linux-next
> > 
> >   drivers/leds/Kconfig        |   9 +
> >   drivers/leds/Makefile       |   1 +
> >   drivers/leds/leds-sgm3140.c | 317 ++++++++++++++++++++++++++++++++++++
> >   3 files changed, 327 insertions(+)
> >   create mode 100644 drivers/leds/leds-sgm3140.c
> > 
-snip-
> > +
> > +	priv->vin_regulator = devm_regulator_get(&pdev->dev, "vin");
> > +	ret = PTR_ERR_OR_ZERO(priv->vin_regulator);
> > +	if (ret) {
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(&pdev->dev,
> > +				"Failed to request regulator: 
%d\n", ret);
> > +		return ret;
> 
> This regulator is optional so why would you return here?  You should
> only return if -EPROBE_DEFER.

If the regulator is not specified in the dts, then a dummy regulator will be 
used:

[    1.027114] sgm3140 sgm3140: sgm3140 supply vin not found, using dummy 
regulator

So this code will only be called if something really failed (or was defered)

> 
> > +	}
> > +
> > +	child_node = of_get_next_available_child(pdev->dev.of_node, NULL);
> 
> Maybe this should be the first check before doing all the processing to
> make sure that the DT is not
> 
> malformed.

If e.g. the devm_gpiod_get calls fail (because the gpios weren't declared in 
the dts) then the dt is also "malformed" which isn't as different as the 
subnode being missing imo. I don't think it matters much here. And this way I 
don't have to care about calling of_node_put in case of an error for the 
statements above.

> 
> > +	if (!child_node) {
> > +		dev_err(&pdev->dev,
> > +			"No DT child node found for connected LED.
\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	ret = of_property_read_u32(child_node, "flash-max-timeout-us",
> > +				   &priv->max_timeout);
> > +	if (ret) {
> > +		priv->max_timeout = FLASH_MAX_TIMEOUT_DEFAULT;
> > +		dev_warn(&pdev->dev,
> > +			 "flash-max-timeout-us DT property 
missing\n");
> > +	}
> > +
> > +	/*
> > +	 * Set default timeout to FLASH_DEFAULT_TIMEOUT except if 
max_timeout
> > +	 * from DT is lower.
> > +	 */
> > +	priv->timeout = min(priv->max_timeout, FLASH_TIMEOUT_DEFAULT);
> > +
> > +	timer_setup(&priv->powerdown_timer, sgm3140_powerdown_timer, 0);
> > +
> > +	fled_cdev = &priv->fled_cdev;
> > +	led_cdev = &fled_cdev->led_cdev;
> > +
> > +	fled_cdev->ops = &sgm3140_flash_ops;
> > +
> > +	led_cdev->brightness_set_blocking = sgm3140_brightness_set;
> > +	led_cdev->max_brightness = LED_ON;
> > +	led_cdev->flags |= LED_DEV_CAP_FLASH;
> > +
> > +	sgm3140_init_flash_timeout(priv);
> > +
> > +	init_data.fwnode = of_fwnode_handle(child_node);
> > +
> > +	platform_set_drvdata(pdev, priv);
> > +
> > +	/* Register in the LED subsystem */
> > +	ret = devm_led_classdev_flash_register_ext(&pdev->dev,
> > +						   
fled_cdev, &init_data);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Failed to register flash device: 
%d\n",
> > +			ret);
> > +		goto err;
> > +	}
> > +
> > +	sgm3140_init_v4l2_flash_config(priv, &v4l2_sd_cfg);
> > +
> > +	/* Create V4L2 Flash subdev */
> > +	priv->v4l2_flash = v4l2_flash_init(&pdev->dev,
> > +					   
of_fwnode_handle(child_node),
> > +					   fled_cdev, NULL,
> > +					   &v4l2_sd_cfg);
> > +	if (IS_ERR(priv->v4l2_flash)) {
> > +		ret = PTR_ERR(priv->v4l2_flash);
> > +		goto err;
> 
> Not sure why this is here you are not in a for loop and this will fall
> through anyway to the err label.
> 

I kept the goto in, in case more code is added below that statement so the 
author doesn't forget that this error needs to be handled.
If wanted I can remove it of course.

> > +	}
> > +
> > +err:
> > +	of_node_put(child_node);
> > +	return ret;
> > +}
> > +
> 
> Dan

Regards
Luca



^ permalink raw reply	[relevance 96%]

* Re: [PATCH v2 2/2] leds: add sgm3140 driver
  @ 2020-04-05 18:45 97%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-04-05 18:45 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Linux LED Subsystem, Dan Murphy, Heiko Stuebner, Icenowy Zheng,
	Jacek Anaszewski, Laurent Pinchart, Mark Rutland, Maxime Ripard,
	Pavel Machek, Rob Herring, Shawn Guo, devicetree,
	Linux Kernel Mailing List, ~postmarketos/upstreaming

Hi Andy,

On Samstag, 4. April 2020 11:58:31 CEST Andy Shevchenko wrote:
> On Mon, Mar 30, 2020 at 10:49 PM Luca Weiss <luca@z3ntu.xyz> wrote:
> > Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> > 
> > This device is controlled by two GPIO pins, one for enabling and the
> > second one for switching between torch and flash mode.
> 
> ...
> 
> > +config LEDS_SGM3140
> > +       tristate "LED support for the SGM3140"
> > +       depends on LEDS_CLASS_FLASH
> > +       depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
> > 
> > +       depends on OF
> 
> depends on OF || COMPILE_TEST ?
> But hold on...
> 
> ...
> 
> > +#include <linux/of.h>
> 
> Perhaps switch this to property.h and replace OF with more generic
> device property / fwnode API?
> 

I didn't find clear documentation on this, the functions in drivers/base/
property.c can be used instead of the of_* (device tree) functions?

As far as I can tell, the device_property_* functions are supposed to be used 
for simple "give me a property for this 'struct device*'" while the fwnode_* 
functions are used as generic equivalent of the of_* functions?

So in this case I can replace 

struct device_node *child_node;
child_node = of_get_next_available_child(pdev->dev.of_node, NULL);

with

struct fwnode_handle *child_node;
child_node = fwnode_get_next_available_child_node(pdev->dev.fwnode, NULL);

and then instead of

ret = of_property_read_u32(child_node, "flash-max-timeout-us",
		   &priv->max_timeout);

use

ret = fwnode_property_read_u32(child_node, "flash-max-timeout-us",
		            &priv->max_timeout);

and finally instead of

init_data.fwnode = of_fwnode_handle(child_node);

I can probably directly do

init_data.fwnode = child_node;

Does that sound correct?

> ...
> 
> > +struct sgm3140 {
> > +       bool enabled;
> > +       struct gpio_desc *flash_gpio;
> > +       struct gpio_desc *enable_gpio;
> > +       struct regulator *vin_regulator;
> > +
> > +       /* current timeout in us */
> > +       u32 timeout;
> > +       /* maximum timeout in us */
> > +       u32 max_timeout;
> > +
> > 
> > +       struct led_classdev_flash fled_cdev;
> 
> I guess it might be slightly better to make it first member of the
> struct (I didn't check but the rationale is to put more often used
> members at the beginning to utilize cachelines).
> 
> > +       struct v4l2_flash *v4l2_flash;
> > +
> > +       struct timer_list powerdown_timer;
> > +};
> 
> ...
> 
> > +static struct sgm3140 *flcdev_to_sgm3140(struct led_classdev_flash
> > *flcdev) +{
> > +       return container_of(flcdev, struct sgm3140, fled_cdev);
> > +}
> 
> ...and this becomes a no-op AFAICS (doesn't mean you need to remove it).
> 
> ...
> 
> > +       struct device_node *child_node;
> > 
> > +       child_node = of_get_next_available_child(pdev->dev.of_node, NULL);
> > 
> > +       ret = of_property_read_u32(child_node, "flash-max-timeout-us",
> > +                                  &priv->max_timeout);
> > 
> > +       init_data.fwnode = of_fwnode_handle(child_node);
> > 
> > +       of_node_put(child_node);
> 
> Device property / fwnode API?
> 
> --
> With Best Regards,
> Andy Shevchenko

Regards
Luca




^ permalink raw reply	[relevance 97%]

* [PATCH v3 1/2] dt-bindings: leds: Add binding for sgm3140
  2020-04-21 19:13 99% [PATCH v3 0/2] Add sgm3140 flash led driver Luca Weiss
@ 2020-04-21 19:13 90% ` Luca Weiss
  2020-04-21 19:13 65% ` [PATCH v3 2/2] leds: add sgm3140 driver Luca Weiss
  1 sibling, 0 replies; 84+ results
From: Luca Weiss @ 2020-04-21 19:13 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss, Rob Herring

Add YAML devicetree binding for SGMICRO SGM3140 charge pump used for
camera flash LEDs.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Reviewed-by: Dan Murphy <dmurphy@ti.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changes since v2:
 - add 'type: object' to led property
 - rename dt node in example from sgm3140 to led-controller to match dt spec

 .../bindings/leds/leds-sgm3140.yaml           | 62 +++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-sgm3140.yaml

diff --git a/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
new file mode 100644
index 0000000000000..ecf7ac9ab0673
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/leds-sgm3140.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SGMICRO SGM3140 500mA Buck/Boost Charge Pump LED Driver
+
+maintainers:
+  - Luca Weiss <luca@z3ntu.xyz>
+
+description: |
+  The SGM3140 is a current-regulated charge pump which can regulate two current
+  levels for Flash and Torch modes.
+
+  The data sheet can be found at:
+    http://www.sg-micro.com/uploads/soft/20190626/1561535688.pdf
+
+properties:
+  compatible:
+    const: sgmicro,sgm3140
+
+  enable-gpios:
+    maxItems: 1
+    description: A connection to the 'EN' pin.
+
+  flash-gpios:
+    maxItems: 1
+    description: A connection to the 'FLASH' pin.
+
+  vin-supply:
+    description: Regulator providing power to the 'VIN' pin.
+
+  led:
+    type: object
+    allOf:
+      - $ref: common.yaml#
+
+required:
+  - compatible
+  - flash-gpios
+  - enable-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/leds/common.h>
+
+    led-controller {
+        compatible = "sgmicro,sgm3140";
+        flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
+        enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
+        vin-supply = <&reg_dcdc1>;
+
+        sgm3140_flash: led {
+            function = LED_FUNCTION_FLASH;
+            color = <LED_COLOR_ID_WHITE>;
+            flash-max-timeout-us = <250000>;
+        };
+    };
-- 
2.26.1


^ permalink raw reply	[relevance 90%]

* [PATCH v3 2/2] leds: add sgm3140 driver
  2020-04-21 19:13 99% [PATCH v3 0/2] Add sgm3140 flash led driver Luca Weiss
  2020-04-21 19:13 90% ` [PATCH v3 1/2] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
@ 2020-04-21 19:13 65% ` Luca Weiss
    1 sibling, 1 reply; 84+ results
From: Luca Weiss @ 2020-04-21 19:13 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.

This device is controlled by two GPIO pins, one for enabling and the
second one for switching between torch and flash mode.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
Changes since v2:
 - switch from of to fwnode API

 drivers/leds/Kconfig        |   8 +
 drivers/leds/Makefile       |   1 +
 drivers/leds/leds-sgm3140.c | 320 ++++++++++++++++++++++++++++++++++++
 3 files changed, 329 insertions(+)
 create mode 100644 drivers/leds/leds-sgm3140.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 7599dbee8de13..e746c4429a288 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -871,6 +871,14 @@ config LEDS_IP30
 	  To compile this driver as a module, choose M here: the module
 	  will be called leds-ip30.
 
+config LEDS_SGM3140
+	tristate "LED support for the SGM3140"
+	depends on LEDS_CLASS_FLASH
+	depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
+	help
+	  This option enables support for the SGM3140 500mA Buck/Boost Charge
+	  Pump LED Driver.
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index fd61421f7d405..f60ed0c09d4c9 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_LEDS_PWM)			+= leds-pwm.o
 obj-$(CONFIG_LEDS_REGULATOR)		+= leds-regulator.o
 obj-$(CONFIG_LEDS_S3C24XX)		+= leds-s3c24xx.o
 obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
+obj-$(CONFIG_LEDS_SGM3140)		+= leds-sgm3140.o
 obj-$(CONFIG_LEDS_SUNFIRE)		+= leds-sunfire.o
 obj-$(CONFIG_LEDS_SYSCON)		+= leds-syscon.o
 obj-$(CONFIG_LEDS_TCA6507)		+= leds-tca6507.o
diff --git a/drivers/leds/leds-sgm3140.c b/drivers/leds/leds-sgm3140.c
new file mode 100644
index 0000000000000..c494b934ae095
--- /dev/null
+++ b/drivers/leds/leds-sgm3140.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2020 Luca Weiss <luca@z3ntu.xyz>
+
+#include <linux/gpio/consumer.h>
+#include <linux/led-class-flash.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/platform_device.h>
+
+#include <media/v4l2-flash-led-class.h>
+
+#define FLASH_TIMEOUT_DEFAULT		250000U /* 250ms */
+#define FLASH_MAX_TIMEOUT_DEFAULT	300000U /* 300ms */
+
+struct sgm3140 {
+	struct led_classdev_flash fled_cdev;
+	struct v4l2_flash *v4l2_flash;
+
+	struct timer_list powerdown_timer;
+
+	struct gpio_desc *flash_gpio;
+	struct gpio_desc *enable_gpio;
+	struct regulator *vin_regulator;
+
+	bool enabled;
+
+	/* current timeout in us */
+	u32 timeout;
+	/* maximum timeout in us */
+	u32 max_timeout;
+};
+
+static struct sgm3140 *flcdev_to_sgm3140(struct led_classdev_flash *flcdev)
+{
+	return container_of(flcdev, struct sgm3140, fled_cdev);
+}
+
+static int sgm3140_strobe_set(struct led_classdev_flash *fled_cdev, bool state)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+	int ret;
+
+	if (priv->enabled == state)
+		return 0;
+
+	if (state) {
+		ret = regulator_enable(priv->vin_regulator);
+		if (ret) {
+			dev_err(fled_cdev->led_cdev.dev,
+				"failed to enable regulator: %d\n", ret);
+			return ret;
+		}
+		gpiod_set_value_cansleep(priv->flash_gpio, 1);
+		gpiod_set_value_cansleep(priv->enable_gpio, 1);
+		mod_timer(&priv->powerdown_timer,
+			  jiffies + usecs_to_jiffies(priv->timeout));
+	} else {
+		del_timer_sync(&priv->powerdown_timer);
+		gpiod_set_value_cansleep(priv->enable_gpio, 0);
+		gpiod_set_value_cansleep(priv->flash_gpio, 0);
+		ret = regulator_disable(priv->vin_regulator);
+		if (ret) {
+			dev_err(fled_cdev->led_cdev.dev,
+				"failed to disable regulator: %d\n", ret);
+			return ret;
+		}
+	}
+
+	priv->enabled = state;
+
+	return 0;
+}
+
+static int sgm3140_strobe_get(struct led_classdev_flash *fled_cdev, bool *state)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	*state = timer_pending(&priv->powerdown_timer);
+
+	return 0;
+}
+
+static int sgm3140_timeout_set(struct led_classdev_flash *fled_cdev,
+			       u32 timeout)
+{
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+
+	priv->timeout = timeout;
+
+	return 0;
+}
+
+static const struct led_flash_ops sgm3140_flash_ops = {
+	.strobe_set = sgm3140_strobe_set,
+	.strobe_get = sgm3140_strobe_get,
+	.timeout_set = sgm3140_timeout_set,
+};
+
+static int sgm3140_brightness_set(struct led_classdev *led_cdev,
+				  enum led_brightness brightness)
+{
+	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
+	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
+	bool enable = brightness == LED_ON;
+	int ret;
+
+	if (priv->enabled == enable)
+		return 0;
+
+	if (enable) {
+		ret = regulator_enable(priv->vin_regulator);
+		if (ret) {
+			dev_err(led_cdev->dev,
+				"failed to enable regulator: %d\n", ret);
+			return ret;
+		}
+		gpiod_set_value_cansleep(priv->enable_gpio, 1);
+	} else {
+		gpiod_set_value_cansleep(priv->enable_gpio, 0);
+		ret = regulator_disable(priv->vin_regulator);
+		if (ret) {
+			dev_err(led_cdev->dev,
+				"failed to disable regulator: %d\n", ret);
+			return ret;
+		}
+	}
+
+	priv->enabled = enable;
+
+	return 0;
+}
+
+static void sgm3140_powerdown_timer(struct timer_list *t)
+{
+	struct sgm3140 *priv = from_timer(priv, t, powerdown_timer);
+
+	gpiod_set_value(priv->enable_gpio, 0);
+	gpiod_set_value(priv->flash_gpio, 0);
+	regulator_disable(priv->vin_regulator);
+
+	priv->enabled = false;
+}
+
+static void sgm3140_init_flash_timeout(struct sgm3140 *priv)
+{
+	struct led_classdev_flash *fled_cdev = &priv->fled_cdev;
+	struct led_flash_setting *s;
+
+	/* Init flash timeout setting */
+	s = &fled_cdev->timeout;
+	s->min = 1;
+	s->max = priv->max_timeout;
+	s->step = 1;
+	s->val = FLASH_TIMEOUT_DEFAULT;
+}
+
+#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
+static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
+					struct v4l2_flash_config *v4l2_sd_cfg)
+{
+	struct led_classdev *led_cdev = &priv->fled_cdev.led_cdev;
+	struct led_flash_setting *s;
+
+	strscpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name,
+		sizeof(v4l2_sd_cfg->dev_name));
+
+	/* Init flash intensity setting */
+	s = &v4l2_sd_cfg->intensity;
+	s->min = 0;
+	s->max = 1;
+	s->step = 1;
+	s->val = 1;
+}
+
+#else
+static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
+					struct v4l2_flash_config *v4l2_sd_cfg)
+{
+}
+#endif
+
+static int sgm3140_probe(struct platform_device *pdev)
+{
+	struct sgm3140 *priv;
+	struct led_classdev *led_cdev;
+	struct led_classdev_flash *fled_cdev;
+	struct led_init_data init_data = {};
+	struct fwnode_handle *child_node;
+	struct v4l2_flash_config v4l2_sd_cfg = {};
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->flash_gpio = devm_gpiod_get(&pdev->dev, "flash", GPIOD_OUT_LOW);
+	ret = PTR_ERR_OR_ZERO(priv->flash_gpio);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to request flash gpio: %d\n", ret);
+		return ret;
+	}
+
+	priv->enable_gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
+	ret = PTR_ERR_OR_ZERO(priv->enable_gpio);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to request enable gpio: %d\n", ret);
+		return ret;
+	}
+
+	priv->vin_regulator = devm_regulator_get(&pdev->dev, "vin");
+	ret = PTR_ERR_OR_ZERO(priv->vin_regulator);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to request regulator: %d\n", ret);
+		return ret;
+	}
+
+	child_node = fwnode_get_next_available_child_node(pdev->dev.fwnode,
+							  NULL);
+	if (!child_node) {
+		dev_err(&pdev->dev,
+			"No fwnode child node found for connected LED.\n");
+		return -EINVAL;
+	}
+
+	ret = fwnode_property_read_u32(child_node, "flash-max-timeout-us",
+				       &priv->max_timeout);
+	if (ret) {
+		priv->max_timeout = FLASH_MAX_TIMEOUT_DEFAULT;
+		dev_warn(&pdev->dev,
+			 "flash-max-timeout-us property missing\n");
+	}
+
+	/*
+	 * Set default timeout to FLASH_DEFAULT_TIMEOUT except if max_timeout
+	 * from DT is lower.
+	 */
+	priv->timeout = min(priv->max_timeout, FLASH_TIMEOUT_DEFAULT);
+
+	timer_setup(&priv->powerdown_timer, sgm3140_powerdown_timer, 0);
+
+	fled_cdev = &priv->fled_cdev;
+	led_cdev = &fled_cdev->led_cdev;
+
+	fled_cdev->ops = &sgm3140_flash_ops;
+
+	led_cdev->brightness_set_blocking = sgm3140_brightness_set;
+	led_cdev->max_brightness = LED_ON;
+	led_cdev->flags |= LED_DEV_CAP_FLASH;
+
+	sgm3140_init_flash_timeout(priv);
+
+	init_data.fwnode = child_node;
+
+	platform_set_drvdata(pdev, priv);
+
+	/* Register in the LED subsystem */
+	ret = devm_led_classdev_flash_register_ext(&pdev->dev,
+						   fled_cdev, &init_data);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register flash device: %d\n",
+			ret);
+		goto err;
+	}
+
+	sgm3140_init_v4l2_flash_config(priv, &v4l2_sd_cfg);
+
+	/* Create V4L2 Flash subdev */
+	priv->v4l2_flash = v4l2_flash_init(&pdev->dev,
+					   child_node,
+					   fled_cdev, NULL,
+					   &v4l2_sd_cfg);
+	if (IS_ERR(priv->v4l2_flash)) {
+		ret = PTR_ERR(priv->v4l2_flash);
+		goto err;
+	}
+
+	return ret;
+
+err:
+	fwnode_handle_put(child_node);
+	return ret;
+}
+
+static int sgm3140_remove(struct platform_device *pdev)
+{
+	struct sgm3140 *priv = platform_get_drvdata(pdev);
+
+	del_timer_sync(&priv->powerdown_timer);
+
+	v4l2_flash_release(priv->v4l2_flash);
+
+	return 0;
+}
+
+static const struct of_device_id sgm3140_dt_match[] = {
+	{ .compatible = "sgmicro,sgm3140" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sgm3140_dt_match);
+
+static struct platform_driver sgm3140_driver = {
+	.probe	= sgm3140_probe,
+	.remove	= sgm3140_remove,
+	.driver	= {
+		.name	= "sgm3140",
+		.of_match_table = sgm3140_dt_match,
+	},
+};
+
+module_platform_driver(sgm3140_driver);
+
+MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xyz>");
+MODULE_DESCRIPTION("SG Micro SGM3140 charge pump led driver");
+MODULE_LICENSE("GPL v2");
-- 
2.26.1


^ permalink raw reply	[relevance 65%]

* [PATCH v3 0/2] Add sgm3140 flash led driver
@ 2020-04-21 19:13 99% Luca Weiss
  2020-04-21 19:13 90% ` [PATCH v3 1/2] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
  2020-04-21 19:13 65% ` [PATCH v3 2/2] leds: add sgm3140 driver Luca Weiss
  0 siblings, 2 replies; 84+ results
From: Luca Weiss @ 2020-04-21 19:13 UTC (permalink / raw)
  To: linux-leds
  Cc: Dan Murphy, Heiko Stuebner, Icenowy Zheng, Jacek Anaszewski,
	Laurent Pinchart, Mark Rutland, Maxime Ripard, Pavel Machek,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming, Luca Weiss

This series introduces a driver for the SGMICRO SGM3140 charge pump
used in the PinePhone smartphone.

Luca Weiss (2):
  dt-bindings: leds: Add binding for sgm3140
  leds: add sgm3140 driver

 .../bindings/leds/leds-sgm3140.yaml           |  62 ++++
 drivers/leds/Kconfig                          |   8 +
 drivers/leds/Makefile                         |   1 +
 drivers/leds/leds-sgm3140.c                   | 320 ++++++++++++++++++
 4 files changed, 391 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-sgm3140.yaml
 create mode 100644 drivers/leds/leds-sgm3140.c

-- 
2.26.1


^ permalink raw reply	[relevance 99%]

* Re: [PATCH v3 2/2] leds: add sgm3140 driver
  @ 2020-04-27 19:49 99%     ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-04-27 19:49 UTC (permalink / raw)
  To: Pavel Machek
  Cc: linux-leds, Dan Murphy, Heiko Stuebner, Icenowy Zheng,
	Jacek Anaszewski, Laurent Pinchart, Mark Rutland, Maxime Ripard,
	Rob Herring, Shawn Guo, devicetree, linux-kernel,
	~postmarketos/upstreaming


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

On Montag, 27. April 2020 11:51:02 CEST Pavel Machek wrote:
> Hi!
> 
> > Add a driver for the SGMICRO SGM3140 Buck/Boost Charge Pump LED driver.
> > 
> > This device is controlled by two GPIO pins, one for enabling and the
> > second one for switching between torch and flash mode.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> 
> Thanks, applied, but... I may remove it again.
> 
> > +++ b/drivers/leds/leds-sgm3140.c
> > @@ -0,0 +1,320 @@
> > +// SPDX-License-Identifier: GPL-2.0
> 
> Would you consider GPL-2+?

I don't really have a preference either way but GPL-2.0-or-later is fine for 
me.

> 
> > +#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
> > +static void sgm3140_init_v4l2_flash_config(struct sgm3140 *priv,
> 
> Ok.
> 
> > +static int sgm3140_probe(struct platform_device *pdev)
> > +{
> 
> ...
> 
> > +	led_cdev->brightness_set_blocking = sgm3140_brightness_set;
> > +	led_cdev->max_brightness = LED_ON;
> 
> Don't do this, unless you really have 255 levels of brightness.

LED_ON is 1, so the brightness available is 0 - 1.

> 
> > +	/* Create V4L2 Flash subdev */
> > +	priv->v4l2_flash = v4l2_flash_init(&pdev->dev,
> > +					   child_node,
> > +					   fled_cdev, NULL,
> > +					   &v4l2_sd_cfg);
> > +	if (IS_ERR(priv->v4l2_flash)) {
> 
> Does this need some #ifdef guards?

v4l2_flash_init has a NULL-returning version when CONFIG_V4L2_FLASH_LED_CLASS 
is not defined (see https://elixir.bootlin.com/linux/latest/source/include/
media/v4l2-flash-led-class.h#L166 )

> 
> > +		ret = PTR_ERR(priv->v4l2_flash);
> > +		goto err;
> > +	}
> > +
> > +	return ret;
> 
> Should this return 0?

ret should be 0 here, so it shouldn't matter much.

> 
> > +err:
> > +	fwnode_handle_put(child_node);
> > +	return ret;
> > +}
> 
> Does non-error path needs handle_put, too?

I don't think so, I'm passing child_node to v4l2_flash_init which then saves 
the pointer to v4l2_subdev->fwnode. 

The devm_led_classdev_flash_register_ext function also seems to store the 
pointer (led_cdev->dev->fwnode = init_data->fwnode; in 
led_classdev_register_ext)

> 
> Best regards,
> 								
	Pavel

Regards,
Luca

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[relevance 99%]

* [PATCH] arm64: dts: sun50i-pinephone: add led flash
@ 2020-07-25 11:08 94% Luca Weiss
    0 siblings, 1 reply; 84+ results
From: Luca Weiss @ 2020-07-25 11:08 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: ~postmarketos/upstreaming, Luca Weiss, Rob Herring,
	Maxime Ripard, Chen-Yu Tsai, devicetree, linux-kernel

All revisions of the PinePhone have an SGM3140 LED flash. The gpios were
swapped on v1.0 of the board but this was fixed in later revisions.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 .../boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts   |  5 +++++
 .../boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts   |  5 +++++
 .../boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts   |  5 +++++
 .../boot/dts/allwinner/sun50i-a64-pinephone.dtsi      | 11 +++++++++++
 4 files changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
index 0c42272106afa..b579b03d4e026 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
@@ -9,3 +9,8 @@ / {
 	model = "Pine64 PinePhone Developer Batch (1.0)";
 	compatible = "pine64,pinephone-1.0", "allwinner,sun50i-a64";
 };
+
+&sgm3140 {
+	flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
+	enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
index 3e99a87e9ce52..8552587aac248 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
@@ -28,3 +28,8 @@ &backlight {
 	num-interpolated-steps = <50>;
 	default-brightness-level = <400>;
 };
+
+&sgm3140 {
+	flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
+	enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
index a9f5b670c9b82..ec77715ba4a2a 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
@@ -38,3 +38,8 @@ &lis3mdl {
 	interrupt-parent = <&pio>;
 	interrupts = <1 1 IRQ_TYPE_EDGE_RISING>; /* PB1 */
 };
+
+&sgm3140 {
+	flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
+	enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index 25150aba749dc..e0bc1bcc1c1f3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -60,6 +60,17 @@ vibrator {
 		enable-gpios = <&pio 3 2 GPIO_ACTIVE_HIGH>; /* PD2 */
 		vcc-supply = <&reg_dcdc1>;
 	};
+
+	sgm3140: led-controller {
+		compatible = "sgmicro,sgm3140";
+		vin-supply = <&reg_dcdc1>;
+
+		sgm3140_flash: led {
+			function = LED_FUNCTION_FLASH;
+			color = <LED_COLOR_ID_WHITE>;
+			flash-max-timeout-us = <250000>;
+		};
+	};
 };
 
 &codec {
-- 
2.27.0


^ permalink raw reply	[relevance 94%]

* Re: [PATCH] arm64: dts: sun50i-pinephone: add led flash
  @ 2020-07-29 16:23 99%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-07-29 16:23 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-arm-kernel, ~postmarketos/upstreaming, Rob Herring,
	Chen-Yu Tsai, devicetree, linux-kernel

Hi Maxime,

On Mittwoch, 29. Juli 2020 14:34:44 CEST Maxime Ripard wrote:
> Hi!
> 
> On Sat, Jul 25, 2020 at 01:08:12PM +0200, Luca Weiss wrote:
> > All revisions of the PinePhone have an SGM3140 LED flash. The gpios were
> > swapped on v1.0 of the board but this was fixed in later revisions.
> > 
> > Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
> > ---
> > 
> >  .../boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts   |  5 +++++
> >  .../boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts   |  5 +++++
> >  .../boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts   |  5 +++++
> >  .../boot/dts/allwinner/sun50i-a64-pinephone.dtsi      | 11 +++++++++++
> >  4 files changed, 26 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
> > b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts index
> > 0c42272106afa..b579b03d4e026 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
> > @@ -9,3 +9,8 @@ / {
> > 
> >  	model = "Pine64 PinePhone Developer Batch (1.0)";
> >  	compatible = "pine64,pinephone-1.0", "allwinner,sun50i-a64";
> >  
> >  };
> > 
> > +
> > +&sgm3140 {
> > +	flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
> > +	enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
> > +};
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
> > b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts index
> > 3e99a87e9ce52..8552587aac248 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
> > @@ -28,3 +28,8 @@ &backlight {
> > 
> >  	num-interpolated-steps = <50>;
> >  	default-brightness-level = <400>;
> >  
> >  };
> > 
> > +
> > +&sgm3140 {
> > +	flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
> > +	enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
> > +};
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
> > b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts index
> > a9f5b670c9b82..ec77715ba4a2a 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
> > @@ -38,3 +38,8 @@ &lis3mdl {
> > 
> >  	interrupt-parent = <&pio>;
> >  	interrupts = <1 1 IRQ_TYPE_EDGE_RISING>; /* PB1 */
> >  
> >  };
> > 
> > +
> > +&sgm3140 {
> > +	flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
> > +	enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
> > +};
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi index
> > 25150aba749dc..e0bc1bcc1c1f3 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > @@ -60,6 +60,17 @@ vibrator {
> > 
> >  		enable-gpios = <&pio 3 2 GPIO_ACTIVE_HIGH>; /* PD2 */
> >  		vcc-supply = <&reg_dcdc1>;
> >  	
> >  	};
> > 
> > +
> > +	sgm3140: led-controller {
> 
> The nodes should be ordered by node-name here

Will update the patch, forgot about that.

> > +		compatible = "sgmicro,sgm3140";
> > +		vin-supply = <&reg_dcdc1>;
> > +
> > +		sgm3140_flash: led {
> 
> What do you need the label for?

The label will be used for connecting the flash to the rear camera (which 
hasn't been upstreamed yet) using:

    flash-leds = <&sgm3140_flash>;

Hope that clears it up.

> 
> Thanks!
> Maxime

Regards
Luca



^ permalink raw reply	[relevance 99%]

* [PATCH] drm/msm/adreno: fix probe without iommu
@ 2020-09-11 16:08 98% Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-09-11 16:08 UTC (permalink / raw)
  To: freedreno
  Cc: ~postmarketos/upstreaming, Luca Weiss, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Jordan Crouse, Bjorn Andersson,
	Jonathan Marek, Brian Masney, John Stultz, linux-arm-msm,
	dri-devel, linux-kernel

The function iommu_domain_alloc returns NULL on platforms without IOMMU
such as msm8974. This resulted in PTR_ERR(-ENODEV) being assigned to
gpu->aspace so the correct code path wasn't taken.

Fixes: ccac7ce373c1 ("drm/msm: Refactor address space initialization")
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 862dd35b27d3..6e8bef1a9ea2 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -189,10 +189,16 @@ struct msm_gem_address_space *
 adreno_iommu_create_address_space(struct msm_gpu *gpu,
 		struct platform_device *pdev)
 {
-	struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
-	struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, iommu);
+	struct iommu_domain *iommu;
+	struct msm_mmu *mmu;
 	struct msm_gem_address_space *aspace;
 
+	iommu = iommu_domain_alloc(&platform_bus_type);
+	if (!iommu)
+		return NULL;
+
+	mmu = msm_iommu_new(&pdev->dev, iommu);
+
 	aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
 		0xffffffff - SZ_16M);
 
-- 
2.28.0


^ permalink raw reply	[relevance 98%]

* Re: [PATCH v4 2/4] leds: Add driver for Qualcomm LPG
  @ 2020-10-07  9:40 99% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-10-07  9:40 UTC (permalink / raw)
  To: Bjorn Andersson, Pavel Machek, Dan Murphy, Rob Herring,
	Andy Gross, Thierry Reding, Uwe Kleine-König, Lee Jones,
	Martin Botka
  Cc: linux-leds, devicetree, linux-kernel, linux-arm-msm, linux-pwm

Hi Bjorn,

On Mon Sep 28, 2020 at 8:15 PM, Bjorn Andersson wrote:
> The Light Pulse Generator (LPG) is a PWM-block found in a wide range of
> PMICs from Qualcomm. It can operate on fixed parameters or based on a
> lookup-table, altering the duty cycle over time - which provides the
> means for e.g. hardware assisted transitions of LED brightness.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
>
> Changes since v3:
> - Adopt multicolor model
> - Simplified hw_pattern implementation
>
> drivers/leds/Kconfig | 9 +
> drivers/leds/Makefile | 1 +
> drivers/leds/leds-qcom-lpg.c | 1213 ++++++++++++++++++++++++++++++++++
> 3 files changed, 1223 insertions(+)
> create mode 100644 drivers/leds/leds-qcom-lpg.c

<snip>

> +static int lpg_pwm_request(struct pwm_chip *chip, struct pwm_device
> *pwm)
> +{
> + struct lpg *lpg = container_of(chip, struct lpg, pwm);
> + struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
> +
> + return chan->in_use ? -EBUSY : 0;
> +}
> +
> +static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> + const struct pwm_state *state)
> +{
> + struct lpg *lpg = container_of(chip, struct lpg, pwm);
> + struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
> +
> + lpg_calc_freq(chan, state->period / NSEC_PER_USEC);
> + lpg_calc_duty(chan, state->duty_cycle / NSEC_PER_USEC);

As written on IRC this has to be wrapped div_u64() to compile on arm32;
should also fix the buildbot failure.

> + chan->enabled = state->enabled;
> +
> + lpg_apply(chan);
> +
> + triled_set(lpg, chan->triled_mask, chan->enabled);
> +
> + return 0;
> +}

Other than that, this works great on msm8974-fairphone-fp2 (pm8941)
with reg 7 (red), 6 (green) & 5 (blue). Thanks for updating this
patchset!

Regards
Luca

^ permalink raw reply	[relevance 99%]

* Re: [PATCH v6 2/4] leds: Add driver for Qualcomm LPG
  @ 2020-10-22 19:25 99%   ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-10-22 19:25 UTC (permalink / raw)
  To: Pavel Machek, Dan Murphy, Rob Herring, Andy Gross,
	Bjorn Andersson, Thierry Reding, Uwe Kleine-König,
	Lee Jones, Martin Botka, linux-arm-msm
  Cc: linux-leds, devicetree, linux-kernel, linux-arm-msm, linux-pwm,
	Bjorn Andersson

Hi Bjorn,

On Mittwoch, 21. Oktober 2020 22:12:22 CEST Bjorn Andersson wrote:
> The Light Pulse Generator (LPG) is a PWM-block found in a wide range of
> PMICs from Qualcomm. It can operate on fixed parameters or based on a
> lookup-table, altering the duty cycle over time - which provides the
> means for e.g. hardware assisted transitions of LED brightness.
> 
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
> 
> Changes since v5:
> - Make sure to not used the state of the last channel in a group to
> determine if the current sink should be active for all channels in the
> group. - Replacement of unsigned -1 with UINT_MAX
> - Work around potential overflow by using larger data types, instead of
> separate code paths - Use cpu_to_l16() rather than hand rolling them
> - Minor style cleanups
> 
>  drivers/leds/Kconfig         |    9 +
>  drivers/leds/Makefile        |    1 +
>  drivers/leds/leds-qcom-lpg.c | 1190 ++++++++++++++++++++++++++++++++++
>  3 files changed, 1200 insertions(+)
>  create mode 100644 drivers/leds/leds-qcom-lpg.c

Tested on msm8974 (pm8941) on the Fairphone 2, works great there!

Tested-by: Luca Weiss <luca@z3ntu.xyz>

Regards
Luca



^ permalink raw reply	[relevance 99%]

* Re: [PATCH] interconnect: qcom: msm8974: Don't boost the NoC rate during boot
  @ 2020-11-17 19:22 99% ` Luca Weiss
  0 siblings, 0 replies; 84+ results
From: Luca Weiss @ 2020-11-17 19:22 UTC (permalink / raw)
  To: linux-pm, masneyb, Georgi Djakov
  Cc: bjorn.andersson, saravanak, linux-arm-msm, linux-kernel, Georgi Djakov

Hi Georgi

On Montag, 9. November 2020 13:45:12 CET Georgi Djakov wrote:
> It has been reported that on Fairphone 2 (msm8974-based), increasing
> the clock rate for some of the NoCs during boot may lead to hangs.
> Let's restore the original behavior and not touch the clock rate of
> any of the NoCs to fix the regression.
> 
> Reported-by: Luca Weiss <luca@z3ntu.xyz>
> Fixes: b1d681d8d324 ("interconnect: Add sync state support")
> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>

Tested-by: Luca Weiss <luca@z3ntu.xyz>

> ---
>  drivers/interconnect/qcom/msm8974.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/interconnect/qcom/msm8974.c
> b/drivers/interconnect/qcom/msm8974.c index b6b639dad691..da68ce375a89
> 100644
> --- a/drivers/interconnect/qcom/msm8974.c
> +++ b/drivers/interconnect/qcom/msm8974.c
> @@ -637,6 +637,14 @@ static int msm8974_icc_set(struct icc_node *src, struct
> icc_node *dst) return 0;
>  }
> 
> +static int msm8974_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
> +{
> +	*avg = 0;
> +	*peak = 0;
> +
> +	return 0;
> +}
> +
>  static int msm8974_icc_probe(struct platform_device *pdev)
>  {
>  	const struct msm8974_icc_desc *desc;
> @@ -690,6 +698,7 @@ static int msm8974_icc_probe(struct platform_device
> *pdev) provider->aggregate = icc_std_aggregate;
>  	provider->xlate = of_icc_xlate_onecell;
>  	provider->data = data;
> +	provider->get_bw = msm8974_get_bw;
> 
>  	ret = icc_provider_add(provider);
>  	if (ret) {

Regards
Luca



^ permalink raw reply	[relevance 99%]

Results 1-84 of 84 | reverse results
2017-06-27  2:17     [PATCH] spmi: pmic-arb: Always allocate ppid_to_apid table Stephen Boyd
2017-07-09 11:31 99% ` Luca Weiss
2017-11-20 19:56     [PATCH v2] mmc: sdhci-msm: Optionally wait for signal level changes Bjorn Andersson
2017-11-21 19:38 99% ` [v2] " Luca Weiss
2019-03-02 12:35 77% [PATCH] drm/msm: Fix NULL pointer dereference Luca Weiss
2019-03-02 14:11 98% [PATCH 1/2] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
2019-03-02 14:11 73% ` [PATCH 2/2] Input: add a driver for GPIO controllable vibrators Luca Weiss
2019-04-07 15:58 93% [PATCH v2 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
2019-04-07 15:58 71% ` [PATCH v2 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
2019-04-07 22:18       ` Dmitry Torokhov
2019-04-09 11:48 96%     ` Luca Weiss
2019-04-07 15:58 99% ` [PATCH v2 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
2019-04-12 15:06 94% [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
2019-04-12 15:06 72% ` [PATCH v3 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
2019-04-12 17:43       ` Stephen Boyd
2019-04-16 16:02 99%     ` Luca Weiss
2019-04-12 15:06 99% ` [PATCH v3 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
2019-04-17 16:02 99% ` [PATCH v3 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
2019-04-20 12:23 93% [PATCH v4 " Luca Weiss
2019-04-20 12:23 71% ` [PATCH v4 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
2019-04-20 12:23 99% ` [PATCH v4 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
2019-04-26 19:47 93% [PATCH v5 1/3] dt-bindings: input: add GPIO controllable vibrator Luca Weiss
2019-04-26 19:47 72% ` [PATCH v5 2/3] Input: add a driver for GPIO controllable vibrators Luca Weiss
2019-04-26 19:47 99% ` [PATCH v5 3/3] ARM: dts: msm8974-FP2: Add vibration motor Luca Weiss
2019-05-18 17:09 99% [PATCH] arm64: dts: allwinner: a64: Add lradc node Luca Weiss
2019-05-21 13:52     ` luca
2019-05-21 14:25       ` Maxime Ripard
2019-05-24  8:35 99%     ` Luca Weiss
2019-05-24  9:20           ` Maxime Ripard
2019-05-31 10:27 99%         ` Luca Weiss
2019-06-03  7:42               ` Maxime Ripard
2019-06-03 15:20 99%             ` Luca Weiss
2019-06-03 19:20 98% [PATCH] iio: light: stk3310: Add support for stk3335 Luca Weiss
2019-06-04 14:42 95% [PATCH] arm64: dts: allwinner: a64: Add lradc node Luca Weiss
2019-06-04 14:59     ` Maxime Ripard
2019-06-04 15:07 99%   ` Luca Weiss
2019-06-04 17:21 97% [PATCH v2 1/2] dt-bindings: input: sun4i-lradc-keys: Add A64 compatible Luca Weiss
2019-06-04 17:21 97% ` [PATCH v2 2/2] arm64: dts: allwinner: a64: Add lradc node Luca Weiss
2019-06-20 22:58 99% [PATCH] ARM: dts: msm8974-FP2: add reboot-mode node Luca Weiss
2019-06-21  0:01     ` Brian Masney
2019-06-21 19:25 99%   ` Luca Weiss
2019-06-22  1:43         ` Brian Masney
2019-07-13 11:26 98%       ` Luca Weiss
2019-06-21 17:20 99% [PATCH] media: ov5640: Add support for flash and lens devices Luca Weiss
2019-07-02 19:16 88% [PATCH] ASoC: sunxi: sun50i-codec-analog: Add earpiece Luca Weiss
2019-07-03 18:05 97% [PATCH 1/3] dt-bindings: Add vendor prefix for sensortek Luca Weiss
2019-07-03 18:05 94% ` [PATCH 2/3] dt-bindings: iio: light: add stk33xx Luca Weiss
2019-07-03 18:05 97% ` [PATCH 3/3] iio: light: stk3310: Add device tree support Luca Weiss
2019-07-03 18:48 89% [PATCH v2] ASoC: sunxi: sun50i-codec-analog: Add earpiece Luca Weiss
2019-07-13 15:48 98% [PATCH v2] ARM: dts: msm8974-FP2: add reboot-mode node Luca Weiss
2019-07-25 22:18     [PATCH 00/15] thermal: qcom: tsens: Add interrupt support Amit Kucheria
2019-07-25 22:18     ` [PATCH 12/15] arm64: dts: msm8974: thermal: " Amit Kucheria
2019-07-29  9:03 99%   ` Luca Weiss
2019-07-27  7:28     ` [PATCH 00/15] thermal: qcom: tsens: " Amit Kucheria
2019-07-29  9:07       ` Brian Masney
2019-07-29  9:32 99%     ` Luca Weiss
2019-09-26 18:44 99% [PATCH 1/2] ARM: dts: msm8974-FP2: Drop unused card-detect pin Luca Weiss
2019-09-26 18:44 99% ` [PATCH 2/2] ARM: dts: msm8974-FP2: Increase load on l20 for sdhci Luca Weiss
2019-11-04 21:09 86% [PATCH 1/2] ARM: qcom_defconfig: Regenerate Luca Weiss
2019-11-04 21:09 99% ` [PATCH 2/2] ARM: qcom_defconfig: Enable QRTR Luca Weiss
2019-11-04 21:23 94% [PATCH 1/2] ARM: dts: msm8974: Introduce the wcnss remoteproc node Luca Weiss
2019-11-04 21:23 99% ` [PATCH 2/2] ARM: dts: msm8974-FP2: " Luca Weiss
2019-11-09  0:40     [PATCH v2 0/2] remoteproc: mss: Improve mem_assign and firmware load Bjorn Andersson
2019-11-09  0:40     ` [PATCH v2 2/2] remoteproc: qcom_q6v5_mss: Validate each segment during loading Bjorn Andersson
2019-11-10 14:05 99%   ` Luca Weiss
2019-11-14 17:53 91% [PATCH 1/2] ARM: dts: msm8974: Add modem remoteproc node Luca Weiss
2019-11-14 17:53 99% ` [PATCH 2/2] ARM: dts: msm8974: Move ADSP smd edge to ADSP PIL Luca Weiss
2019-11-19 18:05 82% [PATCH] Input: ili210x - add ili2120 support Luca Weiss
2020-02-09 14:56 99% [PATCH] Input: ili210x - fix return value of is_visible function Luca Weiss
2020-02-09 15:19 92% [PATCH v2] Input: ili210x - add ili2120 support Luca Weiss
2020-02-14 18:31 99% [PATCH v2] ARM: qcom_defconfig: Enable QRTR Luca Weiss
2020-02-27 18:50 69% [RFC PATCH] leds: add sgm3140 driver Luca Weiss
2020-02-27 19:50     ` Dan Murphy
2020-03-05 11:01 99%   ` Luca Weiss
2020-03-05 21:09     ` Jacek Anaszewski
2020-03-08 11:32 92%   ` Luca Weiss
2020-03-08 16:47         ` Jacek Anaszewski
2020-03-08 16:55 99%       ` Luca Weiss
2020-03-08 12:08     ` Pavel Machek
2020-03-08 12:31 91%   ` Luca Weiss
2020-03-08 12:11     ` Pavel Machek
2020-03-08 12:37 99%   ` Luca Weiss
2020-03-09 20:35 99% [PATCH 0/3] Add sgm3140 flash led driver Luca Weiss
2020-03-09 20:35 99% ` [PATCH 1/3] dt-bindings: Add vendor prefix for SG Micro Corp Luca Weiss
2020-03-09 20:35 90% ` [PATCH 2/3] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
2020-03-11 12:49       ` Dan Murphy
2020-03-15 10:47 99%     ` Luca Weiss
2020-03-23 20:57       ` Rob Herring
2020-03-24 20:02 99%     ` Luca Weiss
2020-03-09 20:35 68% ` [PATCH 3/3] leds: add sgm3140 driver Luca Weiss
2020-03-11 13:02       ` Dan Murphy
2020-03-15 10:42 95%     ` Luca Weiss
2020-03-09 22:18     ` Sakari Ailus
2020-03-09 22:49       ` Pavel Machek
2020-03-09 22:52 96%     ` Luca Weiss
2020-03-17 13:57     [v2 0/6] Qualcomm CCI & Camera for db410c & db845c Robert Foss
2020-03-17 13:57     ` [v2 6/6] arm64: defconfig: Enable QCOM CAMCC, CAMSS and CCI drivers Robert Foss
2020-03-20 19:52 99%   ` Luca Weiss
2020-03-30 19:47 99% [PATCH v2 0/2] Add sgm3140 flash led driver Luca Weiss
2020-03-30 19:47 91% ` [PATCH v2 1/2] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
2020-03-30 19:47 64% ` [PATCH v2 2/2] leds: add sgm3140 driver Luca Weiss
2020-04-03 17:31       ` Dan Murphy
2020-04-04  9:36 96%     ` Luca Weiss
2020-04-04  9:58       ` Andy Shevchenko
2020-04-05 18:45 97%     ` Luca Weiss
2020-04-21 19:13 99% [PATCH v3 0/2] Add sgm3140 flash led driver Luca Weiss
2020-04-21 19:13 90% ` [PATCH v3 1/2] dt-bindings: leds: Add binding for sgm3140 Luca Weiss
2020-04-21 19:13 65% ` [PATCH v3 2/2] leds: add sgm3140 driver Luca Weiss
2020-04-27  9:51       ` Pavel Machek
2020-04-27 19:49 99%     ` Luca Weiss
2020-07-25 11:08 94% [PATCH] arm64: dts: sun50i-pinephone: add led flash Luca Weiss
2020-07-29 12:34     ` Maxime Ripard
2020-07-29 16:23 99%   ` Luca Weiss
2020-09-11 16:08 98% [PATCH] drm/msm/adreno: fix probe without iommu Luca Weiss
2020-09-29  3:15     [PATCH v4 2/4] leds: Add driver for Qualcomm LPG Bjorn Andersson
2020-10-07  9:40 99% ` Luca Weiss
2020-10-21 20:12     [PATCH v6 0/4] Qualcomm Light Pulse Generator Bjorn Andersson
2020-10-21 20:12     ` [PATCH v6 2/4] leds: Add driver for Qualcomm LPG Bjorn Andersson
2020-10-22 19:25 99%   ` Luca Weiss
2020-11-09 12:45     [PATCH] interconnect: qcom: msm8974: Don't boost the NoC rate during boot Georgi Djakov
2020-11-17 19:22 99% ` Luca Weiss


LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git