From patchwork Mon Jun 3 09:00:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Young X-Patchwork-Id: 1109134 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mess.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45HTYT6Pfbz9s4V for ; Mon, 3 Jun 2019 19:01:01 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726792AbfFCJBA (ORCPT ); Mon, 3 Jun 2019 05:01:00 -0400 Received: from gofer.mess.org ([88.97.38.141]:36829 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726555AbfFCJBA (ORCPT ); Mon, 3 Jun 2019 05:01:00 -0400 Received: by gofer.mess.org (Postfix, from userid 1000) id 8805160599; Mon, 3 Jun 2019 10:00:58 +0100 (BST) Date: Mon, 3 Jun 2019 10:00:58 +0100 From: Sean Young To: Stefan Wahren Cc: Thierry Reding , Eric Anholt , Florian Fainelli , Ray Jui , Scott Branden , bcm-kernel-feedback-list@broadcom.com, linux-pwm@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, Andreas Christ Subject: [PATCH v2] pwm: bcm2835: improve precision of pwm Message-ID: <20190603090058.qd3tbiffmdgqm34d@gofer.mess.org> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org If sending IR with carrier of 455kHz using the pwm-ir-tx driver, the carrier ends up being 476kHz. The clock is set to bcm2835-pwm with a rate of 10MHz. A carrier of 455kHz has a period of 2198ns, but the arithmetic truncates this to 2100ns rather than 2200ns. So, use DIV_ROUND_CLOSEST() to reduce rounding errors, and we have a much more accurate carrier of 454.5kHz. Reported-by: Andreas Christ Signed-off-by: Sean Young Acked-by: Stefan Wahren Acked-by: Stefan Wahren --- drivers/pwm/pwm-bcm2835.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c index 5652f461d994..f6fe0b922e1e 100644 --- a/drivers/pwm/pwm-bcm2835.c +++ b/drivers/pwm/pwm-bcm2835.c @@ -70,7 +70,7 @@ static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, return -EINVAL; } - scaler = NSEC_PER_SEC / rate; + scaler = DIV_ROUND_CLOSEST(NSEC_PER_SEC, rate); if (period_ns <= MIN_PERIOD) { dev_err(pc->dev, "period %d not supported, minimum %d\n", @@ -78,8 +78,10 @@ static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, return -EINVAL; } - writel(duty_ns / scaler, pc->base + DUTY(pwm->hwpwm)); - writel(period_ns / scaler, pc->base + PERIOD(pwm->hwpwm)); + writel(DIV_ROUND_CLOSEST(duty_ns, scaler), + pc->base + DUTY(pwm->hwpwm)); + writel(DIV_ROUND_CLOSEST(period_ns, scaler), + pc->base + PERIOD(pwm->hwpwm)); return 0; }