From nobody Sun Sep 7 13:50:59 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D4480171D2; Tue, 16 Apr 2024 02:44:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713235481; cv=none; b=YnkuggRMlpAbvY+1PggAMlmF5E2i5GbtYrbb20wG2/WQ7yaloxVvQRBScCF1rKD5o2YpAnr2BWvb/QD1X0lpf9pb1g1EJUY1m1RTDypilcSDhan7eP7SXyDcBe8/4o214Cimii/qSlIXj5JeoUTcC9Sg3t1KpOOVyRsWJEXpSvQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713235481; c=relaxed/simple; bh=3ygo566KgNes/y1LnnasDIozu4wqPQgtkAmJdJFtQ0U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DxCiqFfEdNO7EHDCJRaPnKXKS2RV0IZt580Y8HSt6dxIH9Qae/Z0lfLI/6eqg6gBRQ8mXF+ssR4l6XKQLIhmu5EZpI3MatvvlfIRhyHuni2wwHv5n7iAPKqEdwPgGyxjGJI177bZoawGCBvBAtvxGvQiAJq8vVzZxMOJMXtuFp8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QZ40ErWr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QZ40ErWr" Received: by smtp.kernel.org (Postfix) with ESMTPS id 6F17DC4AF0C; Tue, 16 Apr 2024 02:44:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713235481; bh=3ygo566KgNes/y1LnnasDIozu4wqPQgtkAmJdJFtQ0U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=QZ40ErWrn5XtEtonMojY5vHzFnnHAwMKEGafsomu8FfPecoagy8UIaz6TJ5C9VvE2 TpFJRy6PH+PayzGui8+OMBqhMFXrq3w9zaQ/KrE+VbRfMDnHRFNyvk//+cx/PA3KgV Mmmb40/5HnY0pMiiHTxszGpWPfwmFSo9vKw+ps2hXA7BUVaw/AhrcymyQzLRuFRnYe kIzzzgzFcygnb4SKwXDxipu9aol7b/m7qxELm6o0Cl8KTA3vTwfp1iVCzhleKBAB6M 0znEDxieW3OG1GzqyJ9URbPiGi9THpBTtX9zkhOJ+Xuxw1CveYr9/S07EEiHcGBhBd 1K3g3SuO7zvtQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59803C04FFE; Tue, 16 Apr 2024 02:44:41 +0000 (UTC) From: Fenglin Wu via B4 Relay Date: Tue, 16 Apr 2024 10:44:34 +0800 Subject: [PATCH v11 3/3] input: pm8xxx-vibrator: add new SPMI vibrator support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240416-pm8xxx-vibrator-new-design-v11-3-7b1c951e1515@quicinc.com> References: <20240416-pm8xxx-vibrator-new-design-v11-0-7b1c951e1515@quicinc.com> In-Reply-To: <20240416-pm8xxx-vibrator-new-design-v11-0-7b1c951e1515@quicinc.com> To: kernel@quicinc.com, Andy Gross , Bjorn Andersson , Konrad Dybcio , Dmitry Torokhov , Rob Herring , Krzysztof Kozlowski , Dmitry Baryshkov Cc: linux-arm-msm@vger.kernel.org, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Fenglin Wu X-Mailer: b4 0.13-dev-83828 X-Developer-Signature: v=1; a=ed25519-sha256; t=1713235479; l=5248; i=quic_fenglinw@quicinc.com; s=20240327; h=from:subject:message-id; bh=O6jY1vE2jMlOuUDvAlQRyMO4JqLMmvGnt6KvdZSWoX4=; b=DoVE674AWh7yt0zyoiZS7k+TyNiecyJD6qsCJWj6VcIDOmE8qE0HfBZR8zD/tDtfLs4P4Die3 wPTFMEcosIoC5u84zbHjJVsJI1xojlhrLWDyobziNQDybr+cg6EEK1H X-Developer-Key: i=quic_fenglinw@quicinc.com; a=ed25519; pk=BF8SA4IVDk8/EBCwlBehKtn2hp6kipuuAuDAHh9s+K4= X-Endpoint-Received: by B4 Relay for quic_fenglinw@quicinc.com/20240327 with auth_id=146 X-Original-From: Fenglin Wu Reply-To: quic_fenglinw@quicinc.com From: Fenglin Wu Add support for a new SPMI vibrator module which is very similar to the vibrator module inside PM8916 but has a finer drive voltage step and different output voltage range, its drive level control is expanded across 2 registers. The vibrator module can be found in following Qualcomm PMICs: PMI632, PM7250B, PM7325B, PM7550BA. Signed-off-by: Fenglin Wu Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio --- drivers/input/misc/pm8xxx-vibrator.c | 52 +++++++++++++++++++++++++++++---= ---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8x= xx-vibrator.c index 2bcfa7ed3d6b..381b06473279 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c @@ -11,10 +11,11 @@ #include #include =20 -#define VIB_MAX_LEVEL_mV (3100) -#define VIB_MIN_LEVEL_mV (1200) -#define VIB_PER_STEP_mV (100) -#define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV + VIB_PER_STE= P_mV) +#define VIB_MAX_LEVEL_mV(vib) (vib->drv2_addr ? 3544 : 3100) +#define VIB_MIN_LEVEL_mV(vib) (vib->drv2_addr ? 1504 : 1200) +#define VIB_PER_STEP_mV(vib) (vib->drv2_addr ? 8 : 100) +#define VIB_MAX_LEVELS(vib) \ + (VIB_MAX_LEVEL_mV(vib) - VIB_MIN_LEVEL_mV(vib) + VIB_PER_STEP_mV(vib)) =20 #define MAX_FF_SPEED 0xff =20 @@ -25,7 +26,11 @@ struct pm8xxx_regs { unsigned int drv_offset; unsigned int drv_mask; unsigned int drv_shift; + unsigned int drv2_offset; + unsigned int drv2_mask; + unsigned int drv2_shift; unsigned int drv_en_manual_mask; + bool drv_in_step; }; =20 static const struct pm8xxx_regs pm8058_regs =3D { @@ -33,6 +38,7 @@ static const struct pm8xxx_regs pm8058_regs =3D { .drv_mask =3D GENMASK(7, 3), .drv_shift =3D 3, .drv_en_manual_mask =3D 0xfc, + .drv_in_step =3D true, }; =20 static struct pm8xxx_regs pm8916_regs =3D { @@ -42,6 +48,20 @@ static struct pm8xxx_regs pm8916_regs =3D { .drv_mask =3D GENMASK(4, 0), .drv_shift =3D 0, .drv_en_manual_mask =3D 0, + .drv_in_step =3D true, +}; + +static struct pm8xxx_regs pmi632_regs =3D { + .enable_offset =3D 0x46, + .enable_mask =3D BIT(7), + .drv_offset =3D 0x40, + .drv_mask =3D GENMASK(7, 0), + .drv_shift =3D 0, + .drv2_offset =3D 0x41, + .drv2_mask =3D GENMASK(3, 0), + .drv2_shift =3D 8, + .drv_en_manual_mask =3D 0, + .drv_in_step =3D false, }; =20 /** @@ -52,6 +72,7 @@ static struct pm8xxx_regs pm8916_regs =3D { * @regs: registers' info * @enable_addr: vibrator enable register * @drv_addr: vibrator drive strength register + * @drv2_addr: vibrator drive strength upper byte register * @speed: speed of vibration set from userland * @active: state of vibrator * @level: level of vibration to set in the chip @@ -64,6 +85,7 @@ struct pm8xxx_vib { const struct pm8xxx_regs *regs; unsigned int enable_addr; unsigned int drv_addr; + unsigned int drv2_addr; int speed; int level; bool active; @@ -81,6 +103,9 @@ static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool o= n) unsigned int val =3D vib->reg_vib_drv; const struct pm8xxx_regs *regs =3D vib->regs; =20 + if (regs->drv_in_step) + vib->level /=3D VIB_PER_STEP_mV(vib); + if (on) val |=3D (vib->level << regs->drv_shift) & regs->drv_mask; else @@ -92,6 +117,14 @@ static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool = on) =20 vib->reg_vib_drv =3D val; =20 + if (regs->drv2_mask) { + val =3D vib->level << regs->drv2_shift; + rc =3D regmap_write_bits(vib->regmap, vib->drv2_addr, + regs->drv2_mask, on ? val : 0); + if (rc < 0) + return rc; + } + if (regs->enable_mask) rc =3D regmap_update_bits(vib->regmap, vib->enable_addr, regs->enable_mask, on ? regs->enable_mask : 0); @@ -114,17 +147,16 @@ static void pm8xxx_work_handler(struct work_struct *w= ork) return; =20 /* - * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so + * pmic vibrator supports voltage ranges from MIN_LEVEL to MAX_LEVEL, so * scale the level to fit into these ranges. */ if (vib->speed) { vib->active =3D true; - vib->level =3D ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) + - VIB_MIN_LEVEL_mV; - vib->level /=3D VIB_PER_STEP_mV; + vib->level =3D VIB_MIN_LEVEL_mV(vib); + vib->level +=3D mult_frac(VIB_MAX_LEVELS(vib), vib->speed, MAX_FF_SPEED); } else { vib->active =3D false; - vib->level =3D VIB_MIN_LEVEL_mV / VIB_PER_STEP_mV; + vib->level =3D VIB_MIN_LEVEL_mV(vib); } =20 pm8xxx_vib_set(vib, vib->active); @@ -197,6 +229,7 @@ static int pm8xxx_vib_probe(struct platform_device *pde= v) regs =3D of_device_get_match_data(&pdev->dev); vib->enable_addr =3D reg_base + regs->enable_offset; vib->drv_addr =3D reg_base + regs->drv_offset; + vib->drv2_addr =3D reg_base + regs->drv2_offset; =20 /* operate in manual mode */ error =3D regmap_read(vib->regmap, vib->drv_addr, &val); @@ -251,6 +284,7 @@ static const struct of_device_id pm8xxx_vib_id_table[] = =3D { { .compatible =3D "qcom,pm8058-vib", .data =3D &pm8058_regs }, { .compatible =3D "qcom,pm8921-vib", .data =3D &pm8058_regs }, { .compatible =3D "qcom,pm8916-vib", .data =3D &pm8916_regs }, + { .compatible =3D "qcom,pmi632-vib", .data =3D &pmi632_regs }, { } }; MODULE_DEVICE_TABLE(of, pm8xxx_vib_id_table); --=20 2.25.1