Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp799556pxf; Wed, 7 Apr 2021 11:51:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJycTkpMcj7IN3TI0INQx5eJX64Q/E21aKQAbcBzV1qKpgqrIWSu4Vvs8e665eLWLiJlMmoT X-Received: by 2002:a05:6638:d47:: with SMTP id d7mr4961473jak.2.1617821465880; Wed, 07 Apr 2021 11:51:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617821465; cv=none; d=google.com; s=arc-20160816; b=j0l6GB8A7GvOKHAX4B4zwyOQLxLybU7hPuykpWmPUQEbU41ybxXdNLTXALNj94Iv7c QuRykctJXDPevhCH8kZ8Y/AfJYxKKbmU9Bf8mGULC4Qcaww3MoXkLOULjlMDf+pfyYAW I4Dhq5eje1T2VigGaA/34e14qu2LPhjnUn9esrBO9HME1MwNQN7GWggY1nFDf8t8mclH GbxXq2xAP9PW0LpzbedrxeRm8/AXg5LgBVins214egOZhYttJvJH8IiLtVllb0aMwwmR +9kof8E+nD0okmrN3Ch7J0V4LwJxMjM5htt0QQ2bb0gOZaXoHs/4F4fqxV7NsSEd4c9b ChTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=ll9D4uQTTYddJFsxiUK9WeBLzV/UMYXPBz4HRQguJhk=; b=aggxzqkvrNDHXhi1atCHQV6VmQ/GpraTK0RlNwGy0WiL964IJC78a/7jb61bflIudN iSPQ48aWzH2te0BpgO9NzeoySCcbwlY+ToMxyBDAtgUGVZypbKdI7VliXphhXcUu9nuE NsACgvPI3YGASw/jOQBbK/OJYRYC9JyYQ4udjjrDF75l7vjXAlYnP5883WAguaFvKn3y rjBKmYntJhO81IBYP+s4p4rRfZUdd2LtxpKlZK81sHQqXC4E36zdQFrLJMETo4YUiuxD aZ20wuXJL8IawmAb7EKBfC/5jvcn0NYV+oSX3rvybRUsL9of1GC2+Jz8RnnrcyD+SGV3 3lGw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e16si21536944iog.74.2021.04.07.11.50.53; Wed, 07 Apr 2021 11:51:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240702AbhDGFbt (ORCPT + 99 others); Wed, 7 Apr 2021 01:31:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237043AbhDGFbt (ORCPT ); Wed, 7 Apr 2021 01:31:49 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4AE21C06174A for ; Tue, 6 Apr 2021 22:31:40 -0700 (PDT) Received: from ptx.hi.pengutronix.de ([2001:67c:670:100:1d::c0]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lU0mt-0001HF-Ns; Wed, 07 Apr 2021 07:31:35 +0200 Received: from ukl by ptx.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1lU0mt-0001NR-4z; Wed, 07 Apr 2021 07:31:35 +0200 Date: Wed, 7 Apr 2021 07:31:35 +0200 From: Uwe =?utf-8?Q?Kleine-K=C3=B6nig?= To: Clemens Gruber Cc: linux-pwm@vger.kernel.org, Thierry Reding , Sven Van Asbroeck , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v7 2/8] pwm: pca9685: Support hardware readout Message-ID: <20210407053135.tx2q4bzxf2lwtqna@pengutronix.de> References: <20210406164140.81423-1-clemens.gruber@pqgruber.com> <20210406164140.81423-2-clemens.gruber@pqgruber.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="f53dyvgu3gwnood4" Content-Disposition: inline In-Reply-To: <20210406164140.81423-2-clemens.gruber@pqgruber.com> X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::c0 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --f53dyvgu3gwnood4 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Apr 06, 2021 at 06:41:34PM +0200, Clemens Gruber wrote: > Implements .get_state to read-out the current hardware state. >=20 > The hardware readout may return slightly different values than those > that were set in apply due to the limited range of possible prescale and > counter register values. >=20 > Also note that although the datasheet mentions 200 Hz as default > frequency when using the internal 25 MHz oscillator, the calculated > period from the default prescaler register setting of 30 is 5079040ns. >=20 > Signed-off-by: Clemens Gruber > --- > Changes since v6: > - Added a comment regarding the division (Suggested by Uwe) > - Rebased >=20 > drivers/pwm/pwm-pca9685.c | 46 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 46 insertions(+) >=20 > diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c > index 5a2ce97e71fd..d4474c5ff96f 100644 > --- a/drivers/pwm/pwm-pca9685.c > +++ b/drivers/pwm/pwm-pca9685.c > @@ -333,6 +333,51 @@ static int pca9685_pwm_apply(struct pwm_chip *chip, = struct pwm_device *pwm, > return 0; > } > =20 > +static void pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_devi= ce *pwm, > + struct pwm_state *state) > +{ > + struct pca9685 *pca =3D to_pca(chip); > + unsigned long long duty; > + unsigned int val =3D 0; > + > + /* Calculate (chip-wide) period from prescale value */ > + regmap_read(pca->regmap, PCA9685_PRESCALE, &val); > + /* > + * PCA9685_OSC_CLOCK_MHZ is 25, i.e. an integer divider of 1000. > + * The following calculation is therefore only a multiplication > + * and we are not losing precision. > + */ > + state->period =3D (PCA9685_COUNTER_RANGE * 1000 / PCA9685_OSC_CLOCK_MHZ= ) * > + (val + 1); > + > + /* The (per-channel) polarity is fixed */ > + state->polarity =3D PWM_POLARITY_NORMAL; > + > + if (pwm->hwpwm >=3D PCA9685_MAXCHAN) { > + /* > + * The "all LEDs" channel does not support HW readout > + * Return 0 and disabled for backwards compatibility > + */ > + state->duty_cycle =3D 0; > + state->enabled =3D false; > + return; > + } > + > + duty =3D pca9685_pwm_get_duty(pca, pwm->hwpwm); > + > + state->enabled =3D !!duty; > + if (!state->enabled) { > + state->duty_cycle =3D 0; > + return; > + } else if (duty =3D=3D PCA9685_COUNTER_RANGE) { > + state->duty_cycle =3D state->period; > + return; > + } > + > + duty *=3D state->period; > + state->duty_cycle =3D duty / PCA9685_COUNTER_RANGE; Given that with duty =3D 0 the chip is still "on" and changing the duty will first complete the currently running period, I'd model duty=3D0 as enabled. This also simplifies the code a bit, to something like: state->enabled =3D true; duty =3D pca9685_pwm_get_duty(pca, pwm->hwpwm); state->duty_cycle =3D div_round_up(duty * state->period, PCA9685_COUNTER_R= ANGE); (I'm using round-up here assuming apply uses round-down to get idempotency. In the current patch set state this is wrong however.) > +} > + > static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device = *pwm) > { > struct pca9685 *pca =3D to_pca(chip); Best regards Uwe --=20 Pengutronix e.K. | Uwe Kleine-K=F6nig | Industrial Linux Solutions | https://www.pengutronix.de/ | --f53dyvgu3gwnood4 Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEfnIqFpAYrP8+dKQLwfwUeK3K7AkFAmBtQ7QACgkQwfwUeK3K 7AkX9wf/blgS6vZsQ1SwUqSIc6dnjbCjt5py+Y2ue+uEGeGB2B3yuHpkBE/r/VAh aG3W0PDDnQePff8J8XrCOG4omhPx7C2H5DGieGSRQirppnJKsQK/50sEhCjdRRpU kU1e6sLuR4pqtzsetk6gZ57EnbRm6XGaWmVLlFowYvWu1SBTAlSozseQU+xXuF4k txzlL3Xp1G4VEWbXendbf4xbs/P43Z+dpeqV4cXsv4tZaPNzQ1PZbylyEol5Vsh8 UdFWjnRmNzroPdyv153ejiJHnRRMxb43cEmhNmhOO2iG3XzVkhqTsuT4gEuoOg9E AvY2HL6z00K5zjkKHTRMxqlOAThe0g== =d4qo -----END PGP SIGNATURE----- --f53dyvgu3gwnood4--