From patchwork Wed Mar 5 21:11:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlo Caione X-Patchwork-Id: 3779171 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 7AA68BF540 for ; Wed, 5 Mar 2014 21:11:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 70B36201FE for ; Wed, 5 Mar 2014 21:11:52 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6E416201E9 for ; Wed, 5 Mar 2014 21:11:51 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLJ6J-000625-Cn; Wed, 05 Mar 2014 21:11:39 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLJ6G-0000Es-GF; Wed, 05 Mar 2014 21:11:36 +0000 Received: from mail-ea0-f182.google.com ([209.85.215.182]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLJ68-0000Dy-HJ for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2014 21:11:34 +0000 Received: by mail-ea0-f182.google.com with SMTP id b10so1291924eae.41 for ; Wed, 05 Mar 2014 13:11:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=from:to:cc:subject:date:message-id; bh=y9lsiGtMuvTHMurvrjY9RXUtU6U9LtnqPjPTZ3c63ic=; b=B7SqUxXbm8zovWQWCrWF5j6M2DJeoNnV2RkUzwgHyzieaYipDIp58r4iLyVpBQwPuZ K5l72AofUd0MwkyKyRns8HrB4+xu5AoiApEiPs+onv4CbdTo3vBEzQMNUnLC5p1Tk15p ykp/s1DL1D2ECf1d0+1nOP8uj6P7KZlOPyQf/wzZ3gUAOrIexZ/xqtWQAiDjMaUP0NRh MGSbQmH4lkEgu56f1kMpm/zgq0NZrFtBdIFTARqUu29o1dBwSBggBI58MWsshPJfX42v GyS34W5mZMtaa+b5UlbNbL9uc5QwyaEdIAzO2GoFew+le6z5A5aMeg/4EfUvjxHOaPni uzCQ== X-Received: by 10.14.205.3 with SMTP id i3mr8004878eeo.23.1394053866271; Wed, 05 Mar 2014 13:11:06 -0800 (PST) Received: from localhost.fastwebnet.it (2-238-57-164.ip242.fastwebnet.it. [2.238.57.164]) by mx.google.com with ESMTPSA id a2sm13754264eem.18.2014.03.05.13.11.03 for (version=TLSv1.2 cipher=AES128-GCM-SHA256 bits=128/128); Wed, 05 Mar 2014 13:11:04 -0800 (PST) From: Carlo Caione To: linux-arm-kernel@lists.infradead.org, lgirdwood@gmail.com, broonie@kernel.org, maxime.ripard@free-electrons.com, hdegoede@redhat.com, linux-sunxi@googlegroups.com Subject: [PATCH] regulator: helpers: Modify helpers enabling multi-bit control Date: Wed, 5 Mar 2014 22:11:29 +0100 Message-Id: <1394053889-7273-1-git-send-email-carlo@caione.org> X-Mailer: git-send-email 1.8.3.2 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140305_161128_676413_C3FC9A72 X-CRM114-Status: GOOD ( 13.93 ) X-Spam-Score: -2.6 (--) Cc: Carlo Caione X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch extends the regulator helpers to account for device that use multiple bits for control when using regmap enable/disable/bypass ops. The actual regulator helpers wrongly assume that the regulator control is always performed using single bits, using in the regulator_desc struct only two parameters *_reg and *_mask defining register and mask for control. This patch extends this struct and introduces the helpers to take into account devices where control is performed using multiple bits and specific multi-bit values are used for enabling/disabling/bypassing the regulator. Signed-off-by: Carlo Caione --- drivers/regulator/helpers.c | 48 ++++++++++++++++++++++++++-------------- include/linux/regulator/driver.h | 8 +++++++ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c index e221a27..cbc3909 100644 --- a/drivers/regulator/helpers.c +++ b/drivers/regulator/helpers.c @@ -37,10 +37,17 @@ int regulator_is_enabled_regmap(struct regulator_dev *rdev) if (ret != 0) return ret; - if (rdev->desc->enable_is_inverted) - return (val & rdev->desc->enable_mask) == 0; - else - return (val & rdev->desc->enable_mask) != 0; + val &= rdev->desc->enable_mask; + + if (rdev->desc->enable_is_inverted) { + if (rdev->desc->enable_val) + return val != rdev->desc->enable_val; + return val == 0; + } else { + if (rdev->desc->enable_val) + return val == rdev->desc->enable_val; + return val != 0; + } } EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); @@ -57,10 +64,13 @@ int regulator_enable_regmap(struct regulator_dev *rdev) { unsigned int val; - if (rdev->desc->enable_is_inverted) - val = 0; - else - val = rdev->desc->enable_mask; + if (rdev->desc->enable_is_inverted) { + val = rdev->desc->disable_val; + } else { + val = rdev->desc->enable_val; + if (!val) + val = rdev->desc->enable_mask; + } return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val); @@ -80,10 +90,13 @@ int regulator_disable_regmap(struct regulator_dev *rdev) { unsigned int val; - if (rdev->desc->enable_is_inverted) - val = rdev->desc->enable_mask; - else - val = 0; + if (rdev->desc->enable_is_inverted) { + val = rdev->desc->enable_val; + if (!val) + val = rdev->desc->enable_mask; + } else { + val = rdev->desc->disable_val; + } return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val); @@ -419,10 +432,13 @@ int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) { unsigned int val; - if (enable) - val = rdev->desc->bypass_mask; - else - val = 0; + if (enable) { + val = rdev->desc->bypass_val_on; + if (!val) + val = rdev->desc->bypass_mask; + } else { + val = rdev->desc->bypass_val_off; + } return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, rdev->desc->bypass_mask, val); diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 9370e65..bbe03a1 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -228,10 +228,14 @@ enum regulator_type { * output when using regulator_set_voltage_sel_regmap * @enable_reg: Register for control when using regmap enable/disable ops * @enable_mask: Mask for control when using regmap enable/disable ops + * @enable_val: Enabling value for control when using regmap enable/disable ops + * @disable_val: Disabling value for control when using regmap enable/disable ops * @enable_is_inverted: A flag to indicate set enable_mask bits to disable * when using regulator_enable_regmap and friends APIs. * @bypass_reg: Register for control when using regmap set_bypass * @bypass_mask: Mask for control when using regmap set_bypass + * @bypass_val_on: Enabling value for control when using regmap set_bypass + * @bypass_val_off: Disabling value for control when using regmap set_bypass * * @enable_time: Time taken for initial enable of regulator (in uS). */ @@ -263,9 +267,13 @@ struct regulator_desc { unsigned int apply_bit; unsigned int enable_reg; unsigned int enable_mask; + unsigned int enable_val; + unsigned int disable_val; bool enable_is_inverted; unsigned int bypass_reg; unsigned int bypass_mask; + unsigned int bypass_val_on; + unsigned int bypass_val_off; unsigned int enable_time; };