From patchwork Sun Jun 2 10:23:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Young X-Patchwork-Id: 1108912 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 45GvRZ4W2Jz9s7h for ; Sun, 2 Jun 2019 20:23:54 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726269AbfFBKXx (ORCPT ); Sun, 2 Jun 2019 06:23:53 -0400 Received: from gofer.mess.org ([88.97.38.141]:37827 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726122AbfFBKXx (ORCPT ); Sun, 2 Jun 2019 06:23:53 -0400 Received: by gofer.mess.org (Postfix, from userid 1000) id A747D60474; Sun, 2 Jun 2019 11:23:50 +0100 (BST) Date: Sun, 2 Jun 2019 11:23:50 +0100 From: Sean Young To: Thierry Reding , Eric Anholt , Stefan Wahren , 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] pwm: bcm2835: increase precision of pwm Message-ID: <20190602102350.zzwmfvlky3mnlqln@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. A carrier of 455kHz has a period of 2198ns, but the arithmetic truncates this to 2.1ns rather than 2.2ns. 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 --- drivers/pwm/pwm-bcm2835.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c index 5652f461d994..edb2387c49a2 100644 --- a/drivers/pwm/pwm-bcm2835.c +++ b/drivers/pwm/pwm-bcm2835.c @@ -63,14 +63,14 @@ static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, { struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); unsigned long rate = clk_get_rate(pc->clk); - unsigned long scaler; + unsigned int scaler; if (!rate) { dev_err(pc->dev, "failed to get clock rate\n"); 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; }