From c7a641ee85a85aec60586a909dea43fba6e8eca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20S=C5=82abo=C5=84?= Date: Wed, 22 Nov 2023 13:10:26 +0100 Subject: [PATCH] Add ERM actuator support in QCOM spmi-haptics driver and enable it for pmi8950 --- .../boot/dts/qcom/msm8937-lenovo-l38011.dts | 4 ++ arch/arm64/boot/dts/qcom/pmi8950.dtsi | 19 ++++++++++ drivers/input/misc/qcom-spmi-haptics.c | 38 ++++++++++++------- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8937-lenovo-l38011.dts b/arch/arm64/boot/dts/qcom/msm8937-lenovo-l38011.dts index e8a24847657a18..abb6132ba7027c 100644 --- a/arch/arm64/boot/dts/qcom/msm8937-lenovo-l38011.dts +++ b/arch/arm64/boot/dts/qcom/msm8937-lenovo-l38011.dts @@ -138,6 +138,10 @@ }; }; +&pmi8950_haptics { + status = "okay"; +}; + &rpm_requests { regulators-0 { compatible = "qcom,rpm-pm8937-regulators"; diff --git a/arch/arm64/boot/dts/qcom/pmi8950.dtsi b/arch/arm64/boot/dts/qcom/pmi8950.dtsi index 49e97ebdbb3c7c..9b3b66ff418a58 100644 --- a/arch/arm64/boot/dts/qcom/pmi8950.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi8950.dtsi @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2019, AngeloGioacchino Del Regno +#include #include #include #include @@ -108,5 +109,23 @@ status = "disabled"; }; + + pmi8950_haptics: haptics@c000 { + compatible = "qcom,pmi8941-haptics", "qcom,spmi-haptics"; + reg = <0xc000>; + + interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>, + <0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "short", "play"; + + qcom,actuator-type = ; + qcom,wave-shape = ; + + /* Downstream defines direct play mode */ + qcom,play-mode = ; + qcom,brake-pattern = <0x3 0x3 0x0 0x0>; + + status = "disabled"; + }; }; }; diff --git a/drivers/input/misc/qcom-spmi-haptics.c b/drivers/input/misc/qcom-spmi-haptics.c index bfed023c38165a..b331aeda429ad8 100644 --- a/drivers/input/misc/qcom-spmi-haptics.c +++ b/drivers/input/misc/qcom-spmi-haptics.c @@ -528,19 +528,29 @@ static int spmi_haptics_init(struct spmi_haptics *haptics) if (ret < 0) return ret; - /* - * Configure auto resonance - * see spmi_haptics_lra_auto_res_config downstream - * This is greatly simplified. - */ - val = FIELD_PREP(LRA_RES_CAL_MASK, ilog2(32 / HAP_RES_CAL_PERIOD_MIN)) | - FIELD_PREP(LRA_AUTO_RES_MODE_MASK, HAP_AUTO_RES_ZXD_EOP) | - FIELD_PREP(LRA_HIGH_Z_MASK, 1); - - mask = LRA_AUTO_RES_MODE_MASK | LRA_HIGH_Z_MASK | LRA_RES_CAL_MASK; - - ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_LRA_AUTO_RES_REG, - mask, val); + if (haptics->actuator_type == HAP_TYPE_LRA) + { + /* + * Configure auto resonance + * see spmi_haptics_lra_auto_res_config downstream + * This is greatly simplified. + */ + val = FIELD_PREP(LRA_RES_CAL_MASK, ilog2(32 / HAP_RES_CAL_PERIOD_MIN)) | + FIELD_PREP(LRA_AUTO_RES_MODE_MASK, HAP_AUTO_RES_ZXD_EOP) | + FIELD_PREP(LRA_HIGH_Z_MASK, 1); + + mask = LRA_AUTO_RES_MODE_MASK | LRA_HIGH_Z_MASK | LRA_RES_CAL_MASK; + + ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_LRA_AUTO_RES_REG, + mask, val); + } + else + { + /* Disable auto resonance */ + val = HAP_AUTO_RES_NONE; + ret = spmi_haptics_write(haptics, haptics->base + HAP_LRA_AUTO_RES_REG, + &val, 1); + } /* Configure the PLAY MODE register */ ret = spmi_haptics_write_play_mode(haptics); @@ -817,7 +827,7 @@ static int spmi_haptics_probe(struct platform_device *pdev) haptics->actuator_type = HAP_TYPE_LRA; ret = of_property_read_u32(node, "qcom,actuator-type", &val); if (!ret) { - if (val != HAP_TYPE_LRA) { + if (val != HAP_TYPE_LRA && val != HAP_TYPE_ERM) { dev_err(&pdev->dev, "qcom,actuator-type (%d) isn't supported\n", val); ret = -EINVAL; goto register_fail;