From patchwork Wed Apr 29 06:53:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516093 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BB292112C for ; Wed, 29 Apr 2020 06:54:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A14F320784 for ; Wed, 29 Apr 2020 06:54:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726366AbgD2Gye (ORCPT ); Wed, 29 Apr 2020 02:54:34 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:34459 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726355AbgD2Gyd (ORCPT ); Wed, 29 Apr 2020 02:54:33 -0400 Received: by mail-lj1-f196.google.com with SMTP id f11so1445872ljp.1; Tue, 28 Apr 2020 23:54:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=7OF8Jqroi8SEKwU+6NdbITJv7+zIFGlSSzopGeFoceA=; b=Js43ELrawYLhdbJMqjgWdz47DD39L/GoVB+pPFwsDJ8uZT1LGkJxSEeduCv+iXO77s 6XymFy7LzX/2mawI4a39cMhtQZ3i0+KaemY2EbkfbNEzEmYRFERlQYT1OSv1VIGIJFK3 WyUyt9Bw3iq2PL3dRU2EJw6zoH2/DyUzMyX0MvDEpFIAzBU5g0TAsBpwZq5eKUBcQZAl YR8o/RBhIUQYgTHkOkIySSEa8oyFSSX/DXXF9ph4V3ZAYlvor4NSKD8dURVyYxFp+qmU t+YNCopRQKWnundrjmyG6PPCGhtOtHa1OhoUn5rXzprD3k5h4pqZZt0WJQmvQO1+m6df vNbg== X-Gm-Message-State: AGi0PuYZxlnBxpmdisL+RMiNk2w3XFuiZD17RVbfBqST/tyRlwFb1Bq6 b0Hi+xlZeYmDu1jpe6G+Q88= X-Google-Smtp-Source: APiQypJS9v2Egip8gzdyF5eH1CS8R5ekW3k+NP28hA1czTgiOrK+XLDiPtX4DT3nRmziLcVCQVvmrA== X-Received: by 2002:a2e:9990:: with SMTP id w16mr19662322lji.194.1588143269514; Tue, 28 Apr 2020 23:54:29 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id a10sm1520782ljp.16.2020.04.28.23.54.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2020 23:54:28 -0700 (PDT) Date: Wed, 29 Apr 2020 09:53:43 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 01/11] lib: add linear ranges helpers Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Many devices have control registers which control some measurable property. Often a register contains control field so that change in this field causes linear change in the controlled property. It is not a rare case that user wants to give 'meaningful' control values and driver needs to convert them to register field values. Even more often user wants to 'see' the currently set value - again in meaningful units - and driver needs to convert the values it reads from register to these meaningful units. Examples of this include: - regulators, voltage/current configurations - power, voltage/current configurations - clk(?) NCOs and maybe others I can't think of right now. Provide a linear_range helper which can do conversion from user value to register value 'selector'. The idea here is stolen from regulator framework and patches refactoring the regulator helpers to use this are following. Current implementation does not support inversely proportional ranges but it might be useful if we could support also inversely proportional ranges? Signed-off-by: Matti Vaittinen Reviewed-by: Mark Brown Reviewed-by: Linus Walleij Reviewed-by: Andy Shevchenko --- No changes since v9 include/linux/linear_range.h | 48 +++++++ lib/Kconfig | 3 + lib/Makefile | 1 + lib/linear_ranges.c | 241 +++++++++++++++++++++++++++++++++++ 4 files changed, 293 insertions(+) create mode 100644 include/linux/linear_range.h create mode 100644 lib/linear_ranges.c diff --git a/include/linux/linear_range.h b/include/linux/linear_range.h new file mode 100644 index 000000000000..17b5943727d5 --- /dev/null +++ b/include/linux/linear_range.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2020 ROHM Semiconductors */ + +#ifndef LINEAR_RANGE_H +#define LINEAR_RANGE_H + +#include + +/** + * struct linear_range - table of selector - value pairs + * + * Define a lookup-table for range of values. Intended to help when looking + * for a register value matching certaing physical measure (like voltage). + * Usable when increment of one in register always results a constant increment + * of the physical measure (like voltage). + * + * @min: Lowest value in range + * @min_sel: Lowest selector for range + * @max_sel: Highest selector for range + * @step: Value step size + */ +struct linear_range { + unsigned int min; + unsigned int min_sel; + unsigned int max_sel; + unsigned int step; +}; + +unsigned int linear_range_values_in_range(const struct linear_range *r); +unsigned int linear_range_values_in_range_array(const struct linear_range *r, + int ranges); +unsigned int linear_range_get_max_value(const struct linear_range *r); + +int linear_range_get_value(const struct linear_range *r, unsigned int selector, + unsigned int *val); +int linear_range_get_value_array(const struct linear_range *r, int ranges, + unsigned int selector, unsigned int *val); +int linear_range_get_selector_low(const struct linear_range *r, + unsigned int val, unsigned int *selector, + bool *found); +int linear_range_get_selector_high(const struct linear_range *r, + unsigned int val, unsigned int *selector, + bool *found); +int linear_range_get_selector_low_array(const struct linear_range *r, + int ranges, unsigned int val, + unsigned int *selector, bool *found); + +#endif diff --git a/lib/Kconfig b/lib/Kconfig index 5d53f9609c25..8ec05335426c 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -19,6 +19,9 @@ config RAID6_PQ_BENCHMARK Benchmark all available RAID6 PQ functions on init and choose the fastest one. +config LINEAR_RANGES + tristate + config PACKING bool "Generic bitfield packing and unpacking" default n diff --git a/lib/Makefile b/lib/Makefile index 685aee60de1d..20b9cfdcad69 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -125,6 +125,7 @@ obj-$(CONFIG_DEBUG_LIST) += list_debug.o obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o obj-$(CONFIG_BITREVERSE) += bitrev.o +obj-$(CONFIG_LINEAR_RANGES) += linear_ranges.o obj-$(CONFIG_PACKING) += packing.o obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o obj-$(CONFIG_CRC16) += crc16.o diff --git a/lib/linear_ranges.c b/lib/linear_ranges.c new file mode 100644 index 000000000000..d1336c75ccd7 --- /dev/null +++ b/lib/linear_ranges.c @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * helpers to map values in a linear range to range index + * + * Original idea borrowed from regulator framework + * + * It might be useful if we could support also inversely proportional ranges? + * Copyright 2020 ROHM Semiconductors + */ + +#include +#include +#include +#include + +/** + * linear_range_values_in_range - return the amount of values in a range + * @r: pointer to linear range where values are counted + * + * Compute the amount of values in range pointed by @r. Note, values can + * be all equal - range with selectors 0,...,2 with step 0 still contains + * 3 values even though they are all equal. + * + * Return: the amount of values in range pointed by @r + */ +unsigned int linear_range_values_in_range(const struct linear_range *r) +{ + if (!r) + return 0; + return r->max_sel - r->min_sel + 1; +} +EXPORT_SYMBOL_GPL(linear_range_values_in_range); + +/** + * linear_range_values_in_range_array - return the amount of values in ranges + * @r: pointer to array of linear ranges where values are counted + * @ranges: amount of ranges we include in computation. + * + * Compute the amount of values in ranges pointed by @r. Note, values can + * be all equal - range with selectors 0,...,2 with step 0 still contains + * 3 values even though they are all equal. + * + * Return: the amount of values in first @ranges ranges pointed by @r + */ +unsigned int linear_range_values_in_range_array(const struct linear_range *r, + int ranges) +{ + int i, values_in_range = 0; + + for (i = 0; i < ranges; i++) { + int values; + + values = linear_range_values_in_range(&r[i]); + if (!values) + return values; + + values_in_range += values; + } + return values_in_range; +} +EXPORT_SYMBOL_GPL(linear_range_values_in_range_array); + +/** + * linear_range_get_max_value - return the largest value in a range + * @r: pointer to linear range where value is looked from + * + * Return: the largest value in the given range + */ +unsigned int linear_range_get_max_value(const struct linear_range *r) +{ + return r->min + (r->max_sel - r->min_sel) * r->step; +} +EXPORT_SYMBOL_GPL(linear_range_get_max_value); + +/** + * linear_range_get_value - fetch a value from given range + * @r: pointer to linear range where value is looked from + * @selector: selector for which the value is searched + * @val: address where found value is updated + * + * Search given ranges for value which matches given selector. + * + * Return: 0 on success, -EINVAL given selector is not found from any of the + * ranges. + */ +int linear_range_get_value(const struct linear_range *r, unsigned int selector, + unsigned int *val) +{ + if (r->min_sel > selector || r->max_sel < selector) + return -EINVAL; + + *val = r->min + (selector - r->min_sel) * r->step; + + return 0; +} +EXPORT_SYMBOL_GPL(linear_range_get_value); + +/** + * linear_range_get_value_array - fetch a value from array of ranges + * @r: pointer to array of linear ranges where value is looked from + * @ranges: amount of ranges in an array + * @selector: selector for which the value is searched + * @val: address where found value is updated + * + * Search through an array of ranges for value which matches given selector. + * + * Return: 0 on success, -EINVAL given selector is not found from any of the + * ranges. + */ +int linear_range_get_value_array(const struct linear_range *r, int ranges, + unsigned int selector, unsigned int *val) +{ + int i; + + for (i = 0; i < ranges; i++) + if (r[i].min_sel <= selector && r[i].max_sel >= selector) + return linear_range_get_value(&r[i], selector, val); + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(linear_range_get_value_array); + +/** + * linear_range_get_selector_low - return linear range selector for value + * @r: pointer to linear range where selector is looked from + * @val: value for which the selector is searched + * @selector: address where found selector value is updated + * @found: flag to indicate that given value was in the range + * + * Return selector which which range value is closest match for given + * input value. Value is matching if it is equal or smaller than given + * value. If given value is in the range, then @found is set true. + * + * Return: 0 on success, -EINVAL if range is invalid or does not contain + * value smaller or equal to given value + */ +int linear_range_get_selector_low(const struct linear_range *r, + unsigned int val, unsigned int *selector, + bool *found) +{ + *found = false; + + if (r->min > val) + return -EINVAL; + + if (linear_range_get_max_value(r) < val) { + *selector = r->max_sel; + return 0; + } + + *found = true; + + if (r->step == 0) + *selector = r->min_sel; + else + *selector = (val - r->min) / r->step + r->min_sel; + + return 0; +} +EXPORT_SYMBOL_GPL(linear_range_get_selector_low); + +/** + * linear_range_get_selector_low_array - return linear range selector for value + * @r: pointer to array of linear ranges where selector is looked from + * @ranges: amount of ranges to scan from array + * @val: value for which the selector is searched + * @selector: address where found selector value is updated + * @found: flag to indicate that given value was in the range + * + * Scan array of ranges for selector which which range value matches given + * input value. Value is matching if it is equal or smaller than given + * value. If given value is found to be in a range scanning is stopped and + * @found is set true. If a range with values smaller than given value is found + * but the range max is being smaller than given value, then the ranges + * biggest selector is updated to @selector but scanning ranges is continued + * and @found is set to false. + * + * Return: 0 on success, -EINVAL if range array is invalid or does not contain + * range with a value smaller or equal to given value + */ +int linear_range_get_selector_low_array(const struct linear_range *r, + int ranges, unsigned int val, + unsigned int *selector, bool *found) +{ + int i; + int ret = -EINVAL; + + for (i = 0; i < ranges; i++) { + int tmpret; + + tmpret = linear_range_get_selector_low(&r[i], val, selector, + found); + if (!tmpret) + ret = 0; + + if (*found) + break; + } + + return ret; +} +EXPORT_SYMBOL_GPL(linear_range_get_selector_low_array); + +/** + * linear_range_get_selector_high - return linear range selector for value + * @r: pointer to linear range where selector is looked from + * @val: value for which the selector is searched + * @selector: address where found selector value is updated + * @found: flag to indicate that given value was in the range + * + * Return selector which which range value is closest match for given + * input value. Value is matching if it is equal or higher than given + * value. If given value is in the range, then @found is set true. + * + * Return: 0 on success, -EINVAL if range is invalid or does not contain + * value greater or equal to given value + */ +int linear_range_get_selector_high(const struct linear_range *r, + unsigned int val, unsigned int *selector, + bool *found) +{ + *found = false; + + if (linear_range_get_max_value(r) < val) + return -EINVAL; + + if (r->min > val) { + *selector = r->min_sel; + return 0; + } + + *found = true; + + if (r->step == 0) + *selector = r->max_sel; + else + *selector = DIV_ROUND_UP(val - r->min, r->step) + r->min_sel; + + return 0; +} +EXPORT_SYMBOL_GPL(linear_range_get_selector_high); From patchwork Wed Apr 29 06:54:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516095 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7A8D6112C for ; Wed, 29 Apr 2020 06:55:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 61912206D6 for ; Wed, 29 Apr 2020 06:55:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726436AbgD2Gzq (ORCPT ); Wed, 29 Apr 2020 02:55:46 -0400 Received: from mail-lj1-f195.google.com ([209.85.208.195]:38467 "EHLO mail-lj1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726355AbgD2Gzq (ORCPT ); Wed, 29 Apr 2020 02:55:46 -0400 Received: by mail-lj1-f195.google.com with SMTP id e25so1425886ljg.5; Tue, 28 Apr 2020 23:55:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=76AwQED9Us2wlfnledgM2REzlhCh0kvNjSLqoUFIJcA=; b=DvlhjrzITTzPpKivdvDdqVVChyi7+5XQPe7ikOypGBZTnRcQVs1iydziV43BWig6V9 h4pvwanzuMGx9EjslUBDUZFBIhhCjLz702NNqYGj91G6DJPxp9LHP1MLP+BBpfPUNQfx LCfNcCua5IpfkPhSkm/bzxFHakyOtxH2eLR9yEb0gNBwb4Ensiz3tyH6bEnFCbT/N08Z jCBhK5VTLP/9AdqOo66pOWfLdTrBUIWUQATkqXooeX37AovNInDC4/t5EP0J9oaIpsZ6 RCJWwrgvTk2MVmZLZDwJmcBuGU3bcRTrJpPdiOyb51CiQlxwI9olDe2alc0Jb3YH6kmz p7ow== X-Gm-Message-State: AGi0Pub3JstB41AyujOIR6PvcG4d/lNxteyt1vSXTG8laf6gP0n3QBhK RBKoSiCFYnFpukwrXI9qk77fK5mZ X-Google-Smtp-Source: APiQypI/R/D/X3h8YHIzZrUvsJyjD4Pucsy7uOdWZhK7sO5P8SbkxHVpTr5M+qScTSn/RANf36kpuw== X-Received: by 2002:a2e:b0f5:: with SMTP id h21mr20089006ljl.3.1588143342836; Tue, 28 Apr 2020 23:55:42 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id c2sm1537579ljk.97.2020.04.28.23.55.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2020 23:55:42 -0700 (PDT) Date: Wed, 29 Apr 2020 09:54:56 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 02/11] lib/test_linear_ranges: add a test for the 'linear_ranges' Message-ID: <8290db0984a1c64f478d8b00f7e9ae2bffde8fb7.1586925868.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add a KUnit test for the linear_ranges helper. Signed-off-by: Matti Vaittinen Reviewed-by: Brendan Higgins --- No changes since v9 lib/Kconfig.debug | 11 ++ lib/Makefile | 1 + lib/test_linear_ranges.c | 228 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 lib/test_linear_ranges.c diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 50c1f5f08e6f..a4bfa80dc8a3 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2090,6 +2090,17 @@ config LIST_KUNIT_TEST If unsure, say N. +config LINEAR_RANGES_TEST + tristate "KUnit test for linear_ranges" + depends on KUNIT + help + This builds the linear_ranges unit test, which runs on boot. + Tests the linear_ranges logic correctness. + For more information on KUnit and unit tests in general please refer + to the KUnit documentation in Documentation/dev-tools/kunit/. + + If unsure, say N. + config TEST_UDELAY tristate "udelay test driver" help diff --git a/lib/Makefile b/lib/Makefile index 20b9cfdcad69..cd548bfa8df9 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -310,3 +310,4 @@ obj-$(CONFIG_OBJAGG) += objagg.o # KUnit tests obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o +obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o diff --git a/lib/test_linear_ranges.c b/lib/test_linear_ranges.c new file mode 100644 index 000000000000..676e0b8abcdd --- /dev/null +++ b/lib/test_linear_ranges.c @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit test for the linear_ranges helper. + * + * Copyright (C) 2020, ROHM Semiconductors. + * Author: Matti Vaittinen + */ +#include + +#include + +/* First things first. I deeply dislike unit-tests. I have seen all the hell + * breaking loose when people who think the unit tests are "the silver bullet" + * to kill bugs get to decide how a company should implement testing strategy... + * + * Believe me, it may get _really_ ridiculous. It is tempting to think that + * walking through all the possible execution branches will nail down 100% of + * bugs. This may lead to ideas about demands to get certain % of "test + * coverage" - measured as line coverage. And that is one of the worst things + * you can do. + * + * Ask people to provide line coverage and they do. I've seen clever tools + * which generate test cases to test the existing functions - and by default + * these tools expect code to be correct and just generate checks which are + * passing when ran against current code-base. Run this generator and you'll get + * tests that do not test code is correct but just verify nothing changes. + * Problem is that testing working code is pointless. And if it is not + * working, your test must not assume it is working. You won't catch any bugs + * by such tests. What you can do is to generate a huge amount of tests. + * Especially if you were are asked to proivde 100% line-coverage x_x. So what + * does these tests - which are not finding any bugs now - do? + * + * They add inertia to every future development. I think it was Terry Pratchet + * who wrote someone having same impact as thick syrup has to chronometre. + * Excessive amount of unit-tests have this effect to development. If you do + * actually find _any_ bug from code in such environment and try fixing it... + * ...chances are you also need to fix the test cases. In sunny day you fix one + * test. But I've done refactoring which resulted 500+ broken tests (which had + * really zero value other than proving to managers that we do do "quality")... + * + * After this being said - there are situations where UTs can be handy. If you + * have algorithms which take some input and should produce output - then you + * can implement few, carefully selected simple UT-cases which test this. I've + * previously used this for example for netlink and device-tree data parsing + * functions. Feed some data examples to functions and verify the output is as + * expected. I am not covering all the cases but I will see the logic should be + * working. + * + * Here we also do some minor testing. I don't want to go through all branches + * or test more or less obvious things - but I want to see the main logic is + * working. And I definitely don't want to add 500+ test cases that break when + * some simple fix is done x_x. So - let's only add few, well selected tests + * which ensure as much logic is good as possible. + */ + +/* + * Test Range 1: + * selectors: 2 3 4 5 6 + * values (5): 10 20 30 40 50 + * + * Test Range 2: + * selectors: 7 8 9 10 + * values (4): 100 150 200 250 + */ + +#define RANGE1_MIN 10 +#define RANGE1_MIN_SEL 2 +#define RANGE1_STEP 10 + +/* 2, 3, 4, 5, 6 */ +static const unsigned int range1_sels[] = { RANGE1_MIN_SEL, RANGE1_MIN_SEL + 1, + RANGE1_MIN_SEL + 2, + RANGE1_MIN_SEL + 3, + RANGE1_MIN_SEL + 4 }; +/* 10, 20, 30, 40, 50 */ +static const unsigned int range1_vals[] = { RANGE1_MIN, RANGE1_MIN + + RANGE1_STEP, + RANGE1_MIN + RANGE1_STEP * 2, + RANGE1_MIN + RANGE1_STEP * 3, + RANGE1_MIN + RANGE1_STEP * 4 }; + +#define RANGE2_MIN 100 +#define RANGE2_MIN_SEL 7 +#define RANGE2_STEP 50 + +/* 7, 8, 9, 10 */ +static const unsigned int range2_sels[] = { RANGE2_MIN_SEL, RANGE2_MIN_SEL + 1, + RANGE2_MIN_SEL + 2, + RANGE2_MIN_SEL + 3 }; +/* 100, 150, 200, 250 */ +static const unsigned int range2_vals[] = { RANGE2_MIN, RANGE2_MIN + + RANGE2_STEP, + RANGE2_MIN + RANGE2_STEP * 2, + RANGE2_MIN + RANGE2_STEP * 3 }; + +#define RANGE1_NUM_VALS (ARRAY_SIZE(range1_vals)) +#define RANGE2_NUM_VALS (ARRAY_SIZE(range2_vals)) +#define RANGE_NUM_VALS (RANGE1_NUM_VALS + RANGE2_NUM_VALS) + +#define RANGE1_MAX_SEL (RANGE1_MIN_SEL + RANGE1_NUM_VALS - 1) +#define RANGE1_MAX_VAL (range1_vals[RANGE1_NUM_VALS - 1]) + +#define RANGE2_MAX_SEL (RANGE2_MIN_SEL + RANGE2_NUM_VALS - 1) +#define RANGE2_MAX_VAL (range2_vals[RANGE2_NUM_VALS - 1]) + +#define SMALLEST_SEL RANGE1_MIN_SEL +#define SMALLEST_VAL RANGE1_MIN + +static struct linear_range testr[] = { + { + .min = RANGE1_MIN, + .min_sel = RANGE1_MIN_SEL, + .max_sel = RANGE1_MAX_SEL, + .step = RANGE1_STEP, + }, { + .min = RANGE2_MIN, + .min_sel = RANGE2_MIN_SEL, + .max_sel = RANGE2_MAX_SEL, + .step = RANGE2_STEP + }, +}; + +static void range_test_get_value(struct kunit *test) +{ + int ret, i; + unsigned int sel, val; + + for (i = 0; i < RANGE1_NUM_VALS; i++) { + sel = range1_sels[i]; + ret = linear_range_get_value_array(&testr[0], 2, sel, &val); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, val, range1_vals[i]); + } + for (i = 0; i < RANGE2_NUM_VALS; i++) { + sel = range2_sels[i]; + ret = linear_range_get_value_array(&testr[0], 2, sel, &val); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, val, range2_vals[i]); + } + ret = linear_range_get_value_array(&testr[0], 2, sel + 1, &val); + KUNIT_EXPECT_NE(test, 0, ret); +} + +static void range_test_get_selector_high(struct kunit *test) +{ + int ret, i; + unsigned int sel; + bool found; + + for (i = 0; i < RANGE1_NUM_VALS; i++) { + ret = linear_range_get_selector_high(&testr[0], range1_vals[i], + &sel, &found); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, sel, range1_sels[i]); + KUNIT_EXPECT_TRUE(test, found); + } + + ret = linear_range_get_selector_high(&testr[0], RANGE1_MAX_VAL + 1, + &sel, &found); + KUNIT_EXPECT_LE(test, ret, 0); + + ret = linear_range_get_selector_high(&testr[0], RANGE1_MIN - 1, + &sel, &found); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_FALSE(test, found); + KUNIT_EXPECT_EQ(test, sel, range1_sels[0]); +} + +static void range_test_get_value_amount(struct kunit *test) +{ + int ret; + + ret = linear_range_values_in_range_array(&testr[0], 2); + KUNIT_EXPECT_EQ(test, (int)RANGE_NUM_VALS, ret); +} + +static void range_test_get_selector_low(struct kunit *test) +{ + int i, ret; + unsigned int sel; + bool found; + + for (i = 0; i < RANGE1_NUM_VALS; i++) { + ret = linear_range_get_selector_low_array(&testr[0], 2, + range1_vals[i], &sel, + &found); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, sel, range1_sels[i]); + KUNIT_EXPECT_TRUE(test, found); + } + for (i = 0; i < RANGE2_NUM_VALS; i++) { + ret = linear_range_get_selector_low_array(&testr[0], 2, + range2_vals[i], &sel, + &found); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, sel, range2_sels[i]); + KUNIT_EXPECT_TRUE(test, found); + } + + /* + * Seek value greater than range max => get_selector_*_low should + * return Ok - but set found to false as value is not in range + */ + ret = linear_range_get_selector_low_array(&testr[0], 2, + range2_vals[RANGE2_NUM_VALS - 1] + 1, + &sel, &found); + + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, sel, range2_sels[RANGE2_NUM_VALS - 1]); + KUNIT_EXPECT_FALSE(test, found); +} + +static struct kunit_case range_test_cases[] = { + KUNIT_CASE(range_test_get_value_amount), + KUNIT_CASE(range_test_get_selector_high), + KUNIT_CASE(range_test_get_selector_low), + KUNIT_CASE(range_test_get_value), + {}, +}; + +static struct kunit_suite range_test_module = { + .name = "linear-ranges-test", + .test_cases = range_test_cases, +}; + +kunit_test_suites(&range_test_module); + +MODULE_LICENSE("GPL"); From patchwork Wed Apr 29 06:56:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516097 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2240F112C for ; Wed, 29 Apr 2020 06:57:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1493B2076B for ; Wed, 29 Apr 2020 06:57:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726401AbgD2G5S (ORCPT ); Wed, 29 Apr 2020 02:57:18 -0400 Received: from mail-lj1-f195.google.com ([209.85.208.195]:43827 "EHLO mail-lj1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726274AbgD2G5R (ORCPT ); Wed, 29 Apr 2020 02:57:17 -0400 Received: by mail-lj1-f195.google.com with SMTP id l19so1390566lje.10; Tue, 28 Apr 2020 23:57:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=V8t969m/oAfp2aM5Orm4ogSiRH3cmyANou7ORBIqnUg=; b=LPftrBaxYNYVbLfDY/QhuVbYIFu1j1gxgbT002HbigEQnvK1+LotkwGONnACTobDGz YgWyF6gAoiezN9u0/CZxnmh9lqdrxQjurwLaTfXqXiwynJzNFdKwRPVDJxUc7A67RVzo 0H3wOE3dtQG5OJx+o7+9n6XaVJmoX5JgS9BOlUfNl71+KPu09H/CVN+leqPq5gV1931F vJiRqO9Ody880fhmnGJF5SBzf++OIxdd7UvE+JmiwxuULZr17igXDldOoT2MewNcV8Nu 2Xw/it4vcdnGhjP0RaDpqkF4zmHNsgm2HJTG3oNqeAqnnIAbC7GCQnEZhQ8WNDIudXOd Bvlg== X-Gm-Message-State: AGi0PuaUns/EM0t123z1ZbryEfRgOCu7bmF3CEkkelQsA7I05sXh2C6w 6yqBd5xWewj1I0Q4GTYXP1M= X-Google-Smtp-Source: APiQypLNkx1MPoFtWRe+XOeHpvSmb/kUqhvngmODpWEvMPNNdwU1SKx1Td/D6Hyk3elOWVLMskClog== X-Received: by 2002:a2e:7d12:: with SMTP id y18mr20986970ljc.211.1588143435144; Tue, 28 Apr 2020 23:57:15 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id a13sm1526442ljm.25.2020.04.28.23.57.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2020 23:57:14 -0700 (PDT) Date: Wed, 29 Apr 2020 09:56:27 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 03/11] power: supply: bd70528: rename linear_range to avoid collision Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Follow-up patches in this series will add a generic struct linear_range. Rename bd70528 internal struct to avoid collision. Signed-off-by: Matti Vaittinen Reviewed-by: Sebastian Reichel --- No changes since v9 drivers/power/supply/bd70528-charger.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/power/supply/bd70528-charger.c b/drivers/power/supply/bd70528-charger.c index b8e1ec106627..3b820110ecfa 100644 --- a/drivers/power/supply/bd70528-charger.c +++ b/drivers/power/supply/bd70528-charger.c @@ -335,14 +335,14 @@ static int bd70528_get_present(struct bd70528_psy *bdpsy, int *val) return 0; } -struct linear_range { +struct bd70528_linear_range { int min; int step; int vals; int low_sel; }; -static const struct linear_range current_limit_ranges[] = { +static const struct bd70528_linear_range current_limit_ranges[] = { { .min = 5, .step = 1, @@ -374,7 +374,7 @@ static const struct linear_range current_limit_ranges[] = { * voltage for low temperatures. The driver currently only reads * the charge current at room temperature. We do set both though. */ -static const struct linear_range warm_charge_curr[] = { +static const struct bd70528_linear_range warm_charge_curr[] = { { .min = 10, .step = 10, @@ -398,7 +398,7 @@ static const struct linear_range warm_charge_curr[] = { #define MAX_WARM_CHG_CURR_SEL 0x1f #define MIN_CHG_CURR_SEL 0x0 -static int find_value_for_selector_low(const struct linear_range *r, +static int find_value_for_selector_low(const struct bd70528_linear_range *r, int selectors, unsigned int sel, unsigned int *val) { @@ -420,7 +420,7 @@ static int find_value_for_selector_low(const struct linear_range *r, * I guess it is enough if we use voltage/current which is closest (below) * the requested? */ -static int find_selector_for_value_low(const struct linear_range *r, +static int find_selector_for_value_low(const struct bd70528_linear_range *r, int selectors, unsigned int val, unsigned int *sel, bool *found) { From patchwork Wed Apr 29 06:57:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516099 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 09AAE15AB for ; Wed, 29 Apr 2020 06:58:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D6C342076B for ; Wed, 29 Apr 2020 06:58:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726381AbgD2G6w (ORCPT ); Wed, 29 Apr 2020 02:58:52 -0400 Received: from mail-lf1-f67.google.com ([209.85.167.67]:42603 "EHLO mail-lf1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726274AbgD2G6v (ORCPT ); Wed, 29 Apr 2020 02:58:51 -0400 Received: by mail-lf1-f67.google.com with SMTP id j14so701714lfg.9; Tue, 28 Apr 2020 23:58:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=ME0XqzR8m104yf8FtgshjjSQGLzbwBEUD1fLytTfX/Y=; b=GF7iNLQxxBpuQi+A6QjniPSQ2/fl8A6oB67Va1JUOmG7oI26vaMIS3tOXdj58UpxiU SUV82paiwcjNkkg6UMDhwWhafY0NSyXxVn1KoO1XHOOTf5omzjOLUqV2fHAnM4cnLS5W BiBcDlq0YQi6O0UmynrQGhsNCT/+UrWPlDT82s7e7ZuB75VLZqY5Sf6JkoC/infxhtid KRADilyarNbp/lJI9+TbWRC/Qex/NuzOdL9MHltFt5qQDgxY5ZytkumXKE8J/iRoSJKR HDmXuffltrfhzdUg3xg2BTq/RJQcni/Doa1qYzWzoKM2wI4h9pU4LYO8M+oBjpLbja24 PCPA== X-Gm-Message-State: AGi0Pub7est5lVN7+tRR6S5QikUzyNbUEjC0l0OPGGocdys7iAXqDsG5 MNVqIqCsqD1sKN/wT0Xq/GU= X-Google-Smtp-Source: APiQypK1BKhUe77k2tl1vmg1e1DrdRlgsMlaj0EQdoSEFJifeoirJpacGtETCJwkPIZuHMY9c4ZPNg== X-Received: by 2002:a19:42c3:: with SMTP id p186mr3482086lfa.194.1588143523350; Tue, 28 Apr 2020 23:58:43 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id s7sm1805587lfb.40.2020.04.28.23.58.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2020 23:58:42 -0700 (PDT) Date: Wed, 29 Apr 2020 09:57:52 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 04/11] regulator: use linear_ranges helper Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Change the regulator helpers to use common linear_ranges code. Signed-off-by: Matti Vaittinen Acked-by: Charles Keepax Acked-by: Adam Thomson Reviewed-by: Mark Brown --- Changes since v9: - Fix also ranges added to qcom_smd-regulator in v5.7-rc1 drivers/regulator/88pg86x.c | 4 +- drivers/regulator/88pm800-regulator.c | 4 +- drivers/regulator/Kconfig | 1 + drivers/regulator/act8865-regulator.c | 4 +- drivers/regulator/act8945a-regulator.c | 2 +- drivers/regulator/arizona-ldo1.c | 2 +- drivers/regulator/arizona-micsupp.c | 4 +- drivers/regulator/as3711-regulator.c | 6 +- drivers/regulator/as3722-regulator.c | 4 +- drivers/regulator/axp20x-regulator.c | 16 +-- drivers/regulator/bcm590xx-regulator.c | 8 +- drivers/regulator/bd70528-regulator.c | 8 +- drivers/regulator/bd71828-regulator.c | 10 +- drivers/regulator/bd718x7-regulator.c | 26 ++--- drivers/regulator/da903x.c | 2 +- drivers/regulator/helpers.c | 130 +++++++++++------------- drivers/regulator/hi6421-regulator.c | 4 +- drivers/regulator/lochnagar-regulator.c | 4 +- drivers/regulator/lp873x-regulator.c | 4 +- drivers/regulator/lp87565-regulator.c | 2 +- drivers/regulator/lp8788-buck.c | 2 +- drivers/regulator/max77650-regulator.c | 2 +- drivers/regulator/mcp16502.c | 4 +- drivers/regulator/mp8859.c | 2 +- drivers/regulator/mt6323-regulator.c | 6 +- drivers/regulator/mt6358-regulator.c | 8 +- drivers/regulator/mt6380-regulator.c | 6 +- drivers/regulator/mt6397-regulator.c | 6 +- drivers/regulator/palmas-regulator.c | 4 +- drivers/regulator/qcom-rpmh-regulator.c | 2 +- drivers/regulator/qcom_rpm-regulator.c | 14 +-- drivers/regulator/qcom_smd-regulator.c | 78 +++++++------- drivers/regulator/rk808-regulator.c | 10 +- drivers/regulator/s2mps11.c | 14 +-- drivers/regulator/sky81452-regulator.c | 2 +- drivers/regulator/stpmic1_regulator.c | 18 ++-- drivers/regulator/tps65086-regulator.c | 10 +- drivers/regulator/tps65217-regulator.c | 4 +- drivers/regulator/tps65218-regulator.c | 6 +- drivers/regulator/tps65912-regulator.c | 4 +- drivers/regulator/twl-regulator.c | 4 +- drivers/regulator/twl6030-regulator.c | 2 +- drivers/regulator/wm831x-dcdc.c | 2 +- drivers/regulator/wm831x-ldo.c | 4 +- drivers/regulator/wm8350-regulator.c | 2 +- drivers/regulator/wm8400-regulator.c | 2 +- include/linux/regulator/driver.h | 27 +---- 47 files changed, 229 insertions(+), 261 deletions(-) diff --git a/drivers/regulator/88pg86x.c b/drivers/regulator/88pg86x.c index d5ef55c81185..71cfa2c5de5e 100644 --- a/drivers/regulator/88pg86x.c +++ b/drivers/regulator/88pg86x.c @@ -11,13 +11,13 @@ static const struct regulator_ops pg86x_ops = { .list_voltage = regulator_list_voltage_linear_range, }; -static const struct regulator_linear_range pg86x_buck1_ranges[] = { +static const struct linear_range pg86x_buck1_ranges[] = { REGULATOR_LINEAR_RANGE( 0, 0, 10, 0), REGULATOR_LINEAR_RANGE(1000000, 11, 34, 25000), REGULATOR_LINEAR_RANGE(1600000, 35, 47, 50000), }; -static const struct regulator_linear_range pg86x_buck2_ranges[] = { +static const struct linear_range pg86x_buck2_ranges[] = { REGULATOR_LINEAR_RANGE( 0, 0, 15, 0), REGULATOR_LINEAR_RANGE(1000000, 16, 39, 25000), REGULATOR_LINEAR_RANGE(1600000, 40, 52, 50000), diff --git a/drivers/regulator/88pm800-regulator.c b/drivers/regulator/88pm800-regulator.c index 69ae25886181..d08ee81ed1ac 100644 --- a/drivers/regulator/88pm800-regulator.c +++ b/drivers/regulator/88pm800-regulator.c @@ -134,13 +134,13 @@ struct pm800_regulator_info { } /* Ranges are sorted in ascending order. */ -static const struct regulator_linear_range buck1_volt_range[] = { +static const struct linear_range buck1_volt_range[] = { REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500), REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x54, 50000), }; /* BUCK 2~5 have same ranges. */ -static const struct regulator_linear_range buck2_5_volt_range[] = { +static const struct linear_range buck2_5_volt_range[] = { REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500), REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x72, 50000), }; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index f4b72cb098ef..f4447f5d940f 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig REGULATOR bool "Voltage and Current Regulator Support" + select LINEAR_RANGES help Generic Voltage and Current Regulator support. diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 0fa97f934df4..19b9742c9ecc 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -220,13 +220,13 @@ static const struct regmap_config act8865_regmap_config = { .val_bits = 8, }; -static const struct regulator_linear_range act8865_voltage_ranges[] = { +static const struct linear_range act8865_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000), REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000), REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000), }; -static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = { +static const struct linear_range act8600_sudcdc_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(3000000, 0, 63, 0), REGULATOR_LINEAR_RANGE(3000000, 64, 159, 100000), REGULATOR_LINEAR_RANGE(12600000, 160, 191, 200000), diff --git a/drivers/regulator/act8945a-regulator.c b/drivers/regulator/act8945a-regulator.c index d2f804dbc785..6a62f946ccae 100644 --- a/drivers/regulator/act8945a-regulator.c +++ b/drivers/regulator/act8945a-regulator.c @@ -73,7 +73,7 @@ struct act8945a_pmic { u32 op_mode[ACT8945A_ID_MAX]; }; -static const struct regulator_linear_range act8945a_voltage_ranges[] = { +static const struct linear_range act8945a_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000), REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000), REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000), diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 1a3d7b720f5e..ade0bef4569d 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -87,7 +87,7 @@ static const struct regulator_ops arizona_ldo1_hc_ops = { .set_bypass = regulator_set_bypass_regmap, }; -static const struct regulator_linear_range arizona_ldo1_hc_ranges[] = { +static const struct linear_range arizona_ldo1_hc_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 0x6, 50000), REGULATOR_LINEAR_RANGE(1800000, 0x7, 0x7, 0), }; diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index ae1a5de3e57d..f6cfd3f6f0dd 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -125,7 +125,7 @@ static const struct regulator_ops arizona_micsupp_ops = { .set_bypass = arizona_micsupp_set_bypass, }; -static const struct regulator_linear_range arizona_micsupp_ranges[] = { +static const struct linear_range arizona_micsupp_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 0x1e, 50000), REGULATOR_LINEAR_RANGE(3300000, 0x1f, 0x1f, 0), }; @@ -152,7 +152,7 @@ static const struct regulator_desc arizona_micsupp = { .owner = THIS_MODULE, }; -static const struct regulator_linear_range arizona_micsupp_ext_ranges[] = { +static const struct linear_range arizona_micsupp_ext_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 0x14, 25000), REGULATOR_LINEAR_RANGE(1500000, 0x15, 0x27, 100000), }; diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index ece88103f2fd..b6b9206969ae 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -103,18 +103,18 @@ static const struct regulator_ops as3711_dldo_ops = { .map_voltage = regulator_map_voltage_linear_range, }; -static const struct regulator_linear_range as3711_sd_ranges[] = { +static const struct linear_range as3711_sd_ranges[] = { REGULATOR_LINEAR_RANGE(612500, 0x1, 0x40, 12500), REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000), REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7f, 50000), }; -static const struct regulator_linear_range as3711_aldo_ranges[] = { +static const struct linear_range as3711_aldo_ranges[] = { REGULATOR_LINEAR_RANGE(1200000, 0, 0xf, 50000), REGULATOR_LINEAR_RANGE(1800000, 0x10, 0x1f, 100000), }; -static const struct regulator_linear_range as3711_dldo_ranges[] = { +static const struct linear_range as3711_dldo_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 0x10, 50000), REGULATOR_LINEAR_RANGE(1750000, 0x20, 0x3f, 50000), }; diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index bd5d0bacb08d..33ca197860b3 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -389,7 +389,7 @@ static const struct regulator_ops as3722_ldo6_extcntrl_ops = { .set_bypass = regulator_set_bypass_regmap, }; -static const struct regulator_linear_range as3722_ldo_ranges[] = { +static const struct linear_range as3722_ldo_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0), REGULATOR_LINEAR_RANGE(825000, 0x01, 0x24, 25000), REGULATOR_LINEAR_RANGE(1725000, 0x40, 0x7F, 25000), @@ -487,7 +487,7 @@ static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs) return false; } -static const struct regulator_linear_range as3722_sd2345_ranges[] = { +static const struct linear_range as3722_sd2345_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0), REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500), REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000), diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 1e6eb5b1f8d8..fbc95cadaf53 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -510,7 +510,7 @@ static const struct regulator_ops axp20x_ops_sw = { .is_enabled = regulator_is_enabled_regmap, }; -static const struct regulator_linear_range axp20x_ldo4_ranges[] = { +static const struct linear_range axp20x_ldo4_ranges[] = { REGULATOR_LINEAR_RANGE(1250000, AXP20X_LDO4_V_OUT_1250mV_START, AXP20X_LDO4_V_OUT_1250mV_END, @@ -638,7 +638,7 @@ static const struct regulator_desc axp22x_drivevbus_regulator = { }; /* DCDC ranges shared with AXP813 */ -static const struct regulator_linear_range axp803_dcdc234_ranges[] = { +static const struct linear_range axp803_dcdc234_ranges[] = { REGULATOR_LINEAR_RANGE(500000, AXP803_DCDC234_500mV_START, AXP803_DCDC234_500mV_END, @@ -649,7 +649,7 @@ static const struct regulator_linear_range axp803_dcdc234_ranges[] = { 20000), }; -static const struct regulator_linear_range axp803_dcdc5_ranges[] = { +static const struct linear_range axp803_dcdc5_ranges[] = { REGULATOR_LINEAR_RANGE(800000, AXP803_DCDC5_800mV_START, AXP803_DCDC5_800mV_END, @@ -660,7 +660,7 @@ static const struct regulator_linear_range axp803_dcdc5_ranges[] = { 20000), }; -static const struct regulator_linear_range axp803_dcdc6_ranges[] = { +static const struct linear_range axp803_dcdc6_ranges[] = { REGULATOR_LINEAR_RANGE(600000, AXP803_DCDC6_600mV_START, AXP803_DCDC6_600mV_END, @@ -672,7 +672,7 @@ static const struct regulator_linear_range axp803_dcdc6_ranges[] = { }; /* AXP806's CLDO2 and AXP809's DLDO1 share the same range */ -static const struct regulator_linear_range axp803_dldo2_ranges[] = { +static const struct linear_range axp803_dldo2_ranges[] = { REGULATOR_LINEAR_RANGE(700000, AXP803_DLDO2_700mV_START, AXP803_DLDO2_700mV_END, @@ -758,7 +758,7 @@ static const struct regulator_desc axp803_regulators[] = { AXP_DESC_FIXED(AXP803, RTC_LDO, "rtc-ldo", "ips", 3000), }; -static const struct regulator_linear_range axp806_dcdca_ranges[] = { +static const struct linear_range axp806_dcdca_ranges[] = { REGULATOR_LINEAR_RANGE(600000, AXP806_DCDCA_600mV_START, AXP806_DCDCA_600mV_END, @@ -769,7 +769,7 @@ static const struct regulator_linear_range axp806_dcdca_ranges[] = { 20000), }; -static const struct regulator_linear_range axp806_dcdcd_ranges[] = { +static const struct linear_range axp806_dcdcd_ranges[] = { REGULATOR_LINEAR_RANGE(600000, AXP806_DCDCD_600mV_START, AXP806_DCDCD_600mV_END, @@ -834,7 +834,7 @@ static const struct regulator_desc axp806_regulators[] = { AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_SW_MASK), }; -static const struct regulator_linear_range axp809_dcdc4_ranges[] = { +static const struct linear_range axp809_dcdc4_ranges[] = { REGULATOR_LINEAR_RANGE(600000, AXP809_DCDC4_600mV_START, AXP809_DCDC4_600mV_END, diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 8c98c3f07660..65e23fc5f9c3 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -116,14 +116,14 @@ static const unsigned int ldo_vbus[] = { }; /* DCDC group CSR: supported voltages in microvolts */ -static const struct regulator_linear_range dcdc_csr_ranges[] = { +static const struct linear_range dcdc_csr_ranges[] = { REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000), REGULATOR_LINEAR_RANGE(900000, 56, 63, 0), }; /* DCDC group IOSR1: supported voltages in microvolts */ -static const struct regulator_linear_range dcdc_iosr1_ranges[] = { +static const struct linear_range dcdc_iosr1_ranges[] = { REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000), REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0), REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0), @@ -131,7 +131,7 @@ static const struct regulator_linear_range dcdc_iosr1_ranges[] = { }; /* DCDC group SDSR1: supported voltages in microvolts */ -static const struct regulator_linear_range dcdc_sdsr1_ranges[] = { +static const struct linear_range dcdc_sdsr1_ranges[] = { REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0), REGULATOR_LINEAR_RANGE(900000, 52, 63, 0), @@ -143,7 +143,7 @@ struct bcm590xx_info { u8 n_voltages; const unsigned int *volt_table; u8 n_linear_ranges; - const struct regulator_linear_range *linear_ranges; + const struct linear_range *linear_ranges; }; #define BCM590XX_REG_TABLE(_name, _table) \ diff --git a/drivers/regulator/bd70528-regulator.c b/drivers/regulator/bd70528-regulator.c index 5bf8a2dc5fe7..d44adf7e875a 100644 --- a/drivers/regulator/bd70528-regulator.c +++ b/drivers/regulator/bd70528-regulator.c @@ -20,22 +20,22 @@ #define BUCK_RAMPRATE_125MV 1 #define BUCK_RAMP_MAX 250 -static const struct regulator_linear_range bd70528_buck1_volts[] = { +static const struct linear_range bd70528_buck1_volts[] = { REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000), REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000), }; -static const struct regulator_linear_range bd70528_buck2_volts[] = { +static const struct linear_range bd70528_buck2_volts[] = { REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000), REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000), REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000), }; -static const struct regulator_linear_range bd70528_buck3_volts[] = { +static const struct linear_range bd70528_buck3_volts[] = { REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000), REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0), }; /* All LDOs have same voltage ranges */ -static const struct regulator_linear_range bd70528_ldo_volts[] = { +static const struct linear_range bd70528_ldo_volts[] = { REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000), REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000), REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000), diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c index b2fa17be4988..85c0b9000963 100644 --- a/drivers/regulator/bd71828-regulator.c +++ b/drivers/regulator/bd71828-regulator.c @@ -65,27 +65,27 @@ static const struct reg_init buck7_inits[] = { }, }; -static const struct regulator_linear_range bd71828_buck1267_volts[] = { +static const struct linear_range bd71828_buck1267_volts[] = { REGULATOR_LINEAR_RANGE(500000, 0x00, 0xef, 6250), REGULATOR_LINEAR_RANGE(2000000, 0xf0, 0xff, 0), }; -static const struct regulator_linear_range bd71828_buck3_volts[] = { +static const struct linear_range bd71828_buck3_volts[] = { REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x0f, 50000), REGULATOR_LINEAR_RANGE(2000000, 0x10, 0x1f, 0), }; -static const struct regulator_linear_range bd71828_buck4_volts[] = { +static const struct linear_range bd71828_buck4_volts[] = { REGULATOR_LINEAR_RANGE(1000000, 0x00, 0x1f, 25000), REGULATOR_LINEAR_RANGE(1800000, 0x20, 0x3f, 0), }; -static const struct regulator_linear_range bd71828_buck5_volts[] = { +static const struct linear_range bd71828_buck5_volts[] = { REGULATOR_LINEAR_RANGE(2500000, 0x00, 0x0f, 50000), REGULATOR_LINEAR_RANGE(3300000, 0x10, 0x1f, 0), }; -static const struct regulator_linear_range bd71828_ldo_volts[] = { +static const struct linear_range bd71828_ldo_volts[] = { REGULATOR_LINEAR_RANGE(800000, 0x00, 0x31, 50000), REGULATOR_LINEAR_RANGE(3300000, 0x32, 0x3f, 0), }; diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index cf3872837abc..819573610ee2 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -152,7 +152,7 @@ static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = { * BD71847 BUCK1/2 * 0.70 to 1.30V (10mV step) */ -static const struct regulator_linear_range bd718xx_dvs_buck_volts[] = { +static const struct linear_range bd718xx_dvs_buck_volts[] = { REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000), REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0), }; @@ -163,7 +163,7 @@ static const struct regulator_linear_range bd718xx_dvs_buck_volts[] = { * and * 0.675 to 1.325 (range 1) */ -static const struct regulator_linear_range bd71837_buck5_volts[] = { +static const struct linear_range bd71837_buck5_volts[] = { /* Ranges when VOLT_SEL bit is 0 */ REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000), REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000), @@ -185,7 +185,7 @@ static const unsigned int bd71837_buck5_volt_range_sel[] = { /* * BD71847 BUCK3 */ -static const struct regulator_linear_range bd71847_buck3_volts[] = { +static const struct linear_range bd71847_buck3_volts[] = { /* Ranges when VOLT_SEL bits are 00 */ REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000), REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000), @@ -202,7 +202,7 @@ static const unsigned int bd71847_buck3_volt_range_sel[] = { 0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80 }; -static const struct regulator_linear_range bd71847_buck4_volts[] = { +static const struct linear_range bd71847_buck4_volts[] = { REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000), }; @@ -213,7 +213,7 @@ static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 }; * BUCK6 * 3.0V to 3.3V (step 100mV) */ -static const struct regulator_linear_range bd71837_buck6_volts[] = { +static const struct linear_range bd71837_buck6_volts[] = { REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), }; @@ -237,7 +237,7 @@ static const unsigned int bd718xx_3rd_nodvs_buck_volts[] = { * BUCK8 * 0.8V to 1.40V (step 10mV) */ -static const struct regulator_linear_range bd718xx_4th_nodvs_buck_volts[] = { +static const struct linear_range bd718xx_4th_nodvs_buck_volts[] = { REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000), }; @@ -245,7 +245,7 @@ static const struct regulator_linear_range bd718xx_4th_nodvs_buck_volts[] = { * LDO1 * 3.0 to 3.3V (100mV step) */ -static const struct regulator_linear_range bd718xx_ldo1_volts[] = { +static const struct linear_range bd718xx_ldo1_volts[] = { REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000), }; @@ -264,7 +264,7 @@ static const unsigned int ldo_2_volts[] = { * LDO3 * 1.8 to 3.3V (100mV step) */ -static const struct regulator_linear_range bd718xx_ldo3_volts[] = { +static const struct linear_range bd718xx_ldo3_volts[] = { REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), }; @@ -272,7 +272,7 @@ static const struct regulator_linear_range bd718xx_ldo3_volts[] = { * LDO4 * 0.9 to 1.8V (100mV step) */ -static const struct regulator_linear_range bd718xx_ldo4_volts[] = { +static const struct linear_range bd718xx_ldo4_volts[] = { REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000), }; @@ -280,7 +280,7 @@ static const struct regulator_linear_range bd718xx_ldo4_volts[] = { * LDO5 for BD71837 * 1.8 to 3.3V (100mV step) */ -static const struct regulator_linear_range bd71837_ldo5_volts[] = { +static const struct linear_range bd71837_ldo5_volts[] = { REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), }; @@ -288,7 +288,7 @@ static const struct regulator_linear_range bd71837_ldo5_volts[] = { * LDO5 for BD71837 * 1.8 to 3.3V (100mV step) */ -static const struct regulator_linear_range bd71847_ldo5_volts[] = { +static const struct linear_range bd71847_ldo5_volts[] = { REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000), }; @@ -299,7 +299,7 @@ static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 }; * LDO6 * 0.9 to 1.8V (100mV step) */ -static const struct regulator_linear_range bd718xx_ldo6_volts[] = { +static const struct linear_range bd718xx_ldo6_volts[] = { REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000), }; @@ -307,7 +307,7 @@ static const struct regulator_linear_range bd718xx_ldo6_volts[] = { * LDO7 * 1.8 to 3.3V (100mV step) */ -static const struct regulator_linear_range bd71837_ldo7_volts[] = { +static const struct linear_range bd71837_ldo7_volts[] = { REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), }; diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 5493c3a86426..770e694824ac 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -248,7 +248,7 @@ static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev, return ret; } -static const struct regulator_linear_range da9034_ldo12_ranges[] = { +static const struct linear_range da9034_ldo12_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000), REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000), }; diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c index bb16c465426e..e970e9d2f8be 100644 --- a/drivers/regulator/helpers.c +++ b/drivers/regulator/helpers.c @@ -131,10 +131,11 @@ int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev) unsigned int r_val; int range; unsigned int val; - int ret, i; - unsigned int voltages_in_range = 0; + int ret; + unsigned int voltages = 0; + const struct linear_range *r = rdev->desc->linear_ranges; - if (!rdev->desc->linear_ranges) + if (!r) return -EINVAL; ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); @@ -152,11 +153,9 @@ int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev) if (range < 0) return -EINVAL; - for (i = 0; i < range; i++) - voltages_in_range += (rdev->desc->linear_ranges[i].max_sel - - rdev->desc->linear_ranges[i].min_sel) + 1; + voltages = linear_range_values_in_range_array(r, range); - return val + voltages_in_range; + return val + voltages; } EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap); @@ -179,8 +178,11 @@ int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev, unsigned int voltages_in_range = 0; for (i = 0; i < rdev->desc->n_linear_ranges; i++) { - voltages_in_range = (rdev->desc->linear_ranges[i].max_sel - - rdev->desc->linear_ranges[i].min_sel) + 1; + const struct linear_range *r; + + r = &rdev->desc->linear_ranges[i]; + voltages_in_range = linear_range_values_in_range(r); + if (sel < voltages_in_range) break; sel -= voltages_in_range; @@ -405,8 +407,10 @@ EXPORT_SYMBOL_GPL(regulator_map_voltage_linear); int regulator_map_voltage_linear_range(struct regulator_dev *rdev, int min_uV, int max_uV) { - const struct regulator_linear_range *range; + const struct linear_range *range; int ret = -EINVAL; + unsigned int sel; + bool found; int voltage, i; if (!rdev->desc->n_linear_ranges) { @@ -415,35 +419,19 @@ int regulator_map_voltage_linear_range(struct regulator_dev *rdev, } for (i = 0; i < rdev->desc->n_linear_ranges; i++) { - int linear_max_uV; - range = &rdev->desc->linear_ranges[i]; - linear_max_uV = range->min_uV + - (range->max_sel - range->min_sel) * range->uV_step; - if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV)) + ret = linear_range_get_selector_high(range, min_uV, &sel, + &found); + if (ret) continue; - - if (min_uV <= range->min_uV) - min_uV = range->min_uV; - - /* range->uV_step == 0 means fixed voltage range */ - if (range->uV_step == 0) { - ret = 0; - } else { - ret = DIV_ROUND_UP(min_uV - range->min_uV, - range->uV_step); - if (ret < 0) - return ret; - } - - ret += range->min_sel; + ret = sel; /* * Map back into a voltage to verify we're still in bounds. * If we are not, then continue checking rest of the ranges. */ - voltage = rdev->desc->ops->list_voltage(rdev, ret); + voltage = rdev->desc->ops->list_voltage(rdev, sel); if (voltage >= min_uV && voltage <= max_uV) break; } @@ -468,7 +456,7 @@ EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range); int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev, int min_uV, int max_uV) { - const struct regulator_linear_range *range; + const struct linear_range *range; int ret = -EINVAL; int voltage, i; unsigned int selector = 0; @@ -480,30 +468,25 @@ int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev, for (i = 0; i < rdev->desc->n_linear_ranges; i++) { int linear_max_uV; + bool found; + unsigned int sel; range = &rdev->desc->linear_ranges[i]; - linear_max_uV = range->min_uV + - (range->max_sel - range->min_sel) * range->uV_step; + linear_max_uV = linear_range_get_max_value(range); - if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV)) { - selector += (range->max_sel - range->min_sel + 1); + if (!(min_uV <= linear_max_uV && max_uV >= range->min)) { + selector += linear_range_values_in_range(range); continue; } - if (min_uV <= range->min_uV) - min_uV = range->min_uV; - - /* range->uV_step == 0 means fixed voltage range */ - if (range->uV_step == 0) { - ret = 0; - } else { - ret = DIV_ROUND_UP(min_uV - range->min_uV, - range->uV_step); - if (ret < 0) - return ret; + ret = linear_range_get_selector_high(range, min_uV, &sel, + &found); + if (ret) { + selector += linear_range_values_in_range(range); + continue; } - ret += selector; + ret = selector + sel; voltage = rdev->desc->ops->list_voltage(rdev, ret); @@ -513,7 +496,7 @@ int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev, * exit but retry until we have checked all ranges. */ if (voltage < min_uV || voltage > max_uV) - selector += (range->max_sel - range->min_sel + 1); + selector += linear_range_values_in_range(range); else break; } @@ -561,7 +544,7 @@ EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev, unsigned int selector) { - const struct regulator_linear_range *range; + const struct linear_range *range; int i; unsigned int all_sels = 0; @@ -571,18 +554,28 @@ int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev, } for (i = 0; i < rdev->desc->n_linear_ranges; i++) { - unsigned int sels_in_range; + unsigned int sel_indexes; range = &rdev->desc->linear_ranges[i]; - sels_in_range = range->max_sel - range->min_sel; + sel_indexes = linear_range_values_in_range(range) - 1; - if (all_sels + sels_in_range >= selector) { + if (all_sels + sel_indexes >= selector) { selector -= all_sels; - return range->min_uV + (range->uV_step * selector); + /* + * As we see here, pickable ranges work only as + * long as the first selector for each pickable + * range is 0, and the each subsequent range for + * this 'pick' follow immediately at next unused + * selector (Eg. there is no gaps between ranges). + * I think this is fine but it probably should be + * documented. OTOH, whole pickable range stuff + * might benefit from some documentation + */ + return range->min + (range->step * selector); } - all_sels += (sels_in_range + 1); + all_sels += (sel_indexes + 1); } return -EINVAL; @@ -604,27 +597,18 @@ EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range); int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc, unsigned int selector) { - const struct regulator_linear_range *range; - int i; - - if (!desc->n_linear_ranges) { - BUG_ON(!desc->n_linear_ranges); - return -EINVAL; - } - - for (i = 0; i < desc->n_linear_ranges; i++) { - range = &desc->linear_ranges[i]; - - if (!(selector >= range->min_sel && - selector <= range->max_sel)) - continue; + unsigned int val; + int ret; - selector -= range->min_sel; + BUG_ON(!desc->n_linear_ranges); - return range->min_uV + (range->uV_step * selector); - } + ret = linear_range_get_value_array(desc->linear_ranges, + desc->n_linear_ranges, selector, + &val); + if (ret) + return ret; - return -EINVAL; + return val; } EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear_range); diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index 5ac3d7c29725..66219d8dfc1a 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -87,7 +87,7 @@ static const unsigned int ldo_8_voltages[] = { }; /* Ranges are sorted in ascending order. */ -static const struct regulator_linear_range ldo_audio_volt_range[] = { +static const struct linear_range ldo_audio_volt_range[] = { REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000), REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000), }; @@ -195,7 +195,7 @@ static const struct regulator_ops hi6421_buck345_ops; * _id - LDO id name string * _match - of match name string * n_volt - number of votages available - * volt_ranges - array of regulator_linear_range + * volt_ranges - array of linear_range * vstep - voltage increase in each linear step in uV * vreg - voltage select register * vmask - voltage select mask diff --git a/drivers/regulator/lochnagar-regulator.c b/drivers/regulator/lochnagar-regulator.c index 9b05e03ba830..5ea3e4141684 100644 --- a/drivers/regulator/lochnagar-regulator.c +++ b/drivers/regulator/lochnagar-regulator.c @@ -36,7 +36,7 @@ static const struct regulator_ops lochnagar_micvdd_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, }; -static const struct regulator_linear_range lochnagar_micvdd_ranges[] = { +static const struct linear_range lochnagar_micvdd_ranges[] = { REGULATOR_LINEAR_RANGE(1000000, 0, 0xC, 50000), REGULATOR_LINEAR_RANGE(1700000, 0xD, 0x1F, 100000), }; @@ -97,7 +97,7 @@ static const struct regulator_ops lochnagar_vddcore_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, }; -static const struct regulator_linear_range lochnagar_vddcore_ranges[] = { +static const struct linear_range lochnagar_vddcore_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0x8, 0x41, 12500), }; diff --git a/drivers/regulator/lp873x-regulator.c b/drivers/regulator/lp873x-regulator.c index b55de293ca7a..fe049b67e7d5 100644 --- a/drivers/regulator/lp873x-regulator.c +++ b/drivers/regulator/lp873x-regulator.c @@ -54,14 +54,14 @@ struct lp873x_regulator { static const struct lp873x_regulator regulators[]; -static const struct regulator_linear_range buck0_buck1_ranges[] = { +static const struct linear_range buck0_buck1_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x0, 0x13, 0), REGULATOR_LINEAR_RANGE(700000, 0x14, 0x17, 10000), REGULATOR_LINEAR_RANGE(735000, 0x18, 0x9d, 5000), REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000), }; -static const struct regulator_linear_range ldo0_ldo1_ranges[] = { +static const struct linear_range ldo0_ldo1_ranges[] = { REGULATOR_LINEAR_RANGE(800000, 0x0, 0x19, 100000), }; diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c index 4ae12ac1f4c6..5d525dacf959 100644 --- a/drivers/regulator/lp87565-regulator.c +++ b/drivers/regulator/lp87565-regulator.c @@ -46,7 +46,7 @@ struct lp87565_regulator { static const struct lp87565_regulator regulators[]; -static const struct regulator_linear_range buck0_1_2_3_ranges[] = { +static const struct linear_range buck0_1_2_3_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0xA, 0x17, 10000), REGULATOR_LINEAR_RANGE(735000, 0x18, 0x9d, 5000), REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000), diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index 222502a29658..74b7b496b12d 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -92,7 +92,7 @@ struct lp8788_buck { }; /* BUCK 1 ~ 4 voltage ranges */ -static const struct regulator_linear_range buck_volt_ranges[] = { +static const struct linear_range buck_volt_ranges[] = { REGULATOR_LINEAR_RANGE(500000, 0, 0, 0), REGULATOR_LINEAR_RANGE(800000, 1, 25, 50000), }; diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c index ac89a412f665..ca08f94a368d 100644 --- a/drivers/regulator/max77650-regulator.c +++ b/drivers/regulator/max77650-regulator.c @@ -49,7 +49,7 @@ static const unsigned int max77651_sbb1_volt_range_sel[] = { 0x0, 0x1, 0x2, 0x3 }; -static const struct regulator_linear_range max77651_sbb1_volt_ranges[] = { +static const struct linear_range max77651_sbb1_volt_ranges[] = { /* range index 0 */ REGULATOR_LINEAR_RANGE(2400000, 0x00, 0x0f, 50000), /* range index 1 */ diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c index e5a02711cb46..6d0ad74935b3 100644 --- a/drivers/regulator/mcp16502.c +++ b/drivers/regulator/mcp16502.c @@ -391,11 +391,11 @@ static const struct of_device_id mcp16502_ids[] = { }; MODULE_DEVICE_TABLE(of, mcp16502_ids); -static const struct regulator_linear_range b1l12_ranges[] = { +static const struct linear_range b1l12_ranges[] = { REGULATOR_LINEAR_RANGE(1200000, VDD_LOW_SEL, VDD_HIGH_SEL, 50000), }; -static const struct regulator_linear_range b234_ranges[] = { +static const struct linear_range b234_ranges[] = { REGULATOR_LINEAR_RANGE(600000, VDD_LOW_SEL, VDD_HIGH_SEL, 25000), }; diff --git a/drivers/regulator/mp8859.c b/drivers/regulator/mp8859.c index 6ed987648188..f2300714d5a9 100644 --- a/drivers/regulator/mp8859.c +++ b/drivers/regulator/mp8859.c @@ -73,7 +73,7 @@ static int mp8859_get_voltage_sel(struct regulator_dev *rdev) return val; } -static const struct regulator_linear_range mp8859_dcdc_ranges[] = { +static const struct linear_range mp8859_dcdc_ranges[] = { REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000), }; diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c index 893ea190788a..ff9016170db3 100644 --- a/drivers/regulator/mt6323-regulator.c +++ b/drivers/regulator/mt6323-regulator.c @@ -102,15 +102,15 @@ struct mt6323_regulator_info { .modeset_mask = _modeset_mask, \ } -static const struct regulator_linear_range buck_volt_range1[] = { +static const struct linear_range buck_volt_range1[] = { REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250), }; -static const struct regulator_linear_range buck_volt_range2[] = { +static const struct linear_range buck_volt_range2[] = { REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500), }; -static const struct regulator_linear_range buck_volt_range3[] = { +static const struct linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), }; diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c index ba42682e06f3..13cb6ac9a892 100644 --- a/drivers/regulator/mt6358-regulator.c +++ b/drivers/regulator/mt6358-regulator.c @@ -137,19 +137,19 @@ struct mt6358_regulator_info { .qi = BIT(15), \ } -static const struct regulator_linear_range buck_volt_range1[] = { +static const struct linear_range buck_volt_range1[] = { REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250), }; -static const struct regulator_linear_range buck_volt_range2[] = { +static const struct linear_range buck_volt_range2[] = { REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500), }; -static const struct regulator_linear_range buck_volt_range3[] = { +static const struct linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), }; -static const struct regulator_linear_range buck_volt_range4[] = { +static const struct linear_range buck_volt_range4[] = { REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500), }; diff --git a/drivers/regulator/mt6380-regulator.c b/drivers/regulator/mt6380-regulator.c index b6aed090b5e0..9efd8710a6f3 100644 --- a/drivers/regulator/mt6380-regulator.c +++ b/drivers/regulator/mt6380-regulator.c @@ -152,15 +152,15 @@ struct mt6380_regulator_info { .modeset_mask = _modeset_mask, \ } -static const struct regulator_linear_range buck_volt_range1[] = { +static const struct linear_range buck_volt_range1[] = { REGULATOR_LINEAR_RANGE(600000, 0, 0xfe, 6250), }; -static const struct regulator_linear_range buck_volt_range2[] = { +static const struct linear_range buck_volt_range2[] = { REGULATOR_LINEAR_RANGE(600000, 0, 0xfe, 6250), }; -static const struct regulator_linear_range buck_volt_range3[] = { +static const struct linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(1200000, 0, 0x3c, 25000), }; diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c index fd9ed864a0c1..269c2a6028e8 100644 --- a/drivers/regulator/mt6397-regulator.c +++ b/drivers/regulator/mt6397-regulator.c @@ -102,15 +102,15 @@ struct mt6397_regulator_info { .qi = BIT(15), \ } -static const struct regulator_linear_range buck_volt_range1[] = { +static const struct linear_range buck_volt_range1[] = { REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250), }; -static const struct regulator_linear_range buck_volt_range2[] = { +static const struct linear_range buck_volt_range2[] = { REGULATOR_LINEAR_RANGE(800000, 0, 0x7f, 6250), }; -static const struct regulator_linear_range buck_volt_range3[] = { +static const struct linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000), }; diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 31325912d311..337dd614695e 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -22,14 +22,14 @@ #include #include -static const struct regulator_linear_range smps_low_ranges[] = { +static const struct linear_range smps_low_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0), REGULATOR_LINEAR_RANGE(510000, 0x7, 0x79, 10000), REGULATOR_LINEAR_RANGE(1650000, 0x7A, 0x7f, 0), }; -static const struct regulator_linear_range smps_high_ranges[] = { +static const struct linear_range smps_high_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x6, 0), REGULATOR_LINEAR_RANGE(1020000, 0x7, 0x79, 20000), diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index c86ad40015ce..953c7fba8d9d 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -86,7 +86,7 @@ enum rpmh_regulator_type { struct rpmh_vreg_hw_data { enum rpmh_regulator_type regulator_type; const struct regulator_ops *ops; - const struct regulator_linear_range voltage_range; + const struct linear_range voltage_range; int n_voltages; int hpm_min_load_uA; const int *pmic_mode_map; diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index 7fc97f23fcf4..a4562a23aa57 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c @@ -148,41 +148,41 @@ static const struct rpm_reg_parts rpm8960_ncp_parts = { /* * Physically available PMIC regulator voltage ranges */ -static const struct regulator_linear_range pldo_ranges[] = { +static const struct linear_range pldo_ranges[] = { REGULATOR_LINEAR_RANGE( 750000, 0, 59, 12500), REGULATOR_LINEAR_RANGE(1500000, 60, 123, 25000), REGULATOR_LINEAR_RANGE(3100000, 124, 160, 50000), }; -static const struct regulator_linear_range nldo_ranges[] = { +static const struct linear_range nldo_ranges[] = { REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500), }; -static const struct regulator_linear_range nldo1200_ranges[] = { +static const struct linear_range nldo1200_ranges[] = { REGULATOR_LINEAR_RANGE( 375000, 0, 59, 6250), REGULATOR_LINEAR_RANGE( 750000, 60, 123, 12500), }; -static const struct regulator_linear_range smps_ranges[] = { +static const struct linear_range smps_ranges[] = { REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500), REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500), REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000), }; -static const struct regulator_linear_range ftsmps_ranges[] = { +static const struct linear_range ftsmps_ranges[] = { REGULATOR_LINEAR_RANGE( 350000, 0, 6, 50000), REGULATOR_LINEAR_RANGE( 700000, 7, 63, 12500), REGULATOR_LINEAR_RANGE(1500000, 64, 100, 50000), }; -static const struct regulator_linear_range smb208_ranges[] = { +static const struct linear_range smb208_ranges[] = { REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500), REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500), REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000), REGULATOR_LINEAR_RANGE(3100000, 154, 234, 25000), }; -static const struct regulator_linear_range ncp_ranges[] = { +static const struct linear_range ncp_ranges[] = { REGULATOR_LINEAR_RANGE(1500000, 0, 31, 50000), }; diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index fdde4195cefb..53a64d856926 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -199,7 +199,7 @@ static const struct regulator_ops rpm_bob_ops = { }; static const struct regulator_desc pma8084_hfsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000), }, @@ -209,7 +209,7 @@ static const struct regulator_desc pma8084_hfsmps = { }; static const struct regulator_desc pma8084_ftsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000), }, @@ -219,7 +219,7 @@ static const struct regulator_desc pma8084_ftsmps = { }; static const struct regulator_desc pma8084_pldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500), REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000), REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000), @@ -230,7 +230,7 @@ static const struct regulator_desc pma8084_pldo = { }; static const struct regulator_desc pma8084_nldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500), }, .n_linear_ranges = 1, @@ -243,7 +243,7 @@ static const struct regulator_desc pma8084_switch = { }; static const struct regulator_desc pm8x41_hfsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500), REGULATOR_LINEAR_RANGE(1575000, 96, 158, 25000), }, @@ -253,7 +253,7 @@ static const struct regulator_desc pm8x41_hfsmps = { }; static const struct regulator_desc pm8841_ftsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000), }, @@ -263,7 +263,7 @@ static const struct regulator_desc pm8841_ftsmps = { }; static const struct regulator_desc pm8941_boost = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000), }, .n_linear_ranges = 1, @@ -272,7 +272,7 @@ static const struct regulator_desc pm8941_boost = { }; static const struct regulator_desc pm8941_pldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500), REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000), REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000), @@ -283,7 +283,7 @@ static const struct regulator_desc pm8941_pldo = { }; static const struct regulator_desc pm8941_nldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500), }, .n_linear_ranges = 1, @@ -302,7 +302,7 @@ static const struct regulator_desc pm8941_switch = { }; static const struct regulator_desc pm8916_pldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500), }, .n_linear_ranges = 1, @@ -311,7 +311,7 @@ static const struct regulator_desc pm8916_pldo = { }; static const struct regulator_desc pm8916_nldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500), }, .n_linear_ranges = 1, @@ -320,7 +320,7 @@ static const struct regulator_desc pm8916_nldo = { }; static const struct regulator_desc pm8916_buck_lvo_smps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), REGULATOR_LINEAR_RANGE(750000, 96, 127, 25000), }, @@ -330,7 +330,7 @@ static const struct regulator_desc pm8916_buck_lvo_smps = { }; static const struct regulator_desc pm8916_buck_hvo_smps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1550000, 0, 31, 25000), }, .n_linear_ranges = 1, @@ -339,7 +339,7 @@ static const struct regulator_desc pm8916_buck_hvo_smps = { }; static const struct regulator_desc pm8950_hfsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), REGULATOR_LINEAR_RANGE(1550000, 96, 127, 25000), }, @@ -349,7 +349,7 @@ static const struct regulator_desc pm8950_hfsmps = { }; static const struct regulator_desc pm8950_ftsmps2p5 = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(80000, 0, 255, 5000), REGULATOR_LINEAR_RANGE(160000, 256, 460, 10000), }, @@ -359,7 +359,7 @@ static const struct regulator_desc pm8950_ftsmps2p5 = { }; static const struct regulator_desc pm8950_ult_nldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(375000, 0, 202, 12500), }, .n_linear_ranges = 1, @@ -368,7 +368,7 @@ static const struct regulator_desc pm8950_ult_nldo = { }; static const struct regulator_desc pm8950_ult_pldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1750000, 0, 127, 12500), }, .n_linear_ranges = 1, @@ -377,7 +377,7 @@ static const struct regulator_desc pm8950_ult_pldo = { }; static const struct regulator_desc pm8950_pldo_lv = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1500000, 0, 16, 25000), }, .n_linear_ranges = 1, @@ -386,7 +386,7 @@ static const struct regulator_desc pm8950_pldo_lv = { }; static const struct regulator_desc pm8950_pldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(975000, 0, 164, 12500), }, .n_linear_ranges = 1, @@ -396,7 +396,7 @@ static const struct regulator_desc pm8950_pldo = { static const struct regulator_desc pm8994_hfsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500), REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000), }, @@ -406,7 +406,7 @@ static const struct regulator_desc pm8994_hfsmps = { }; static const struct regulator_desc pm8994_ftsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(350000, 0, 199, 5000), REGULATOR_LINEAR_RANGE(700000, 200, 349, 10000), }, @@ -416,7 +416,7 @@ static const struct regulator_desc pm8994_ftsmps = { }; static const struct regulator_desc pm8994_nldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500), }, .n_linear_ranges = 1, @@ -425,7 +425,7 @@ static const struct regulator_desc pm8994_nldo = { }; static const struct regulator_desc pm8994_pldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500), REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000), REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000), @@ -446,7 +446,7 @@ static const struct regulator_desc pm8994_lnldo = { }; static const struct regulator_desc pmi8994_ftsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(350000, 0, 199, 5000), REGULATOR_LINEAR_RANGE(700000, 200, 349, 10000), }, @@ -456,7 +456,7 @@ static const struct regulator_desc pmi8994_ftsmps = { }; static const struct regulator_desc pmi8994_hfsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(350000, 0, 80, 12500), REGULATOR_LINEAR_RANGE(700000, 81, 141, 25000), }, @@ -466,7 +466,7 @@ static const struct regulator_desc pmi8994_hfsmps = { }; static const struct regulator_desc pmi8994_bby = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(3000000, 0, 44, 50000), }, .n_linear_ranges = 1, @@ -475,7 +475,7 @@ static const struct regulator_desc pmi8994_bby = { }; static const struct regulator_desc pmi8994_boost = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000), }, .n_linear_ranges = 1, @@ -484,7 +484,7 @@ static const struct regulator_desc pmi8994_boost = { }; static const struct regulator_desc pm8998_ftsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000), }, .n_linear_ranges = 1, @@ -493,7 +493,7 @@ static const struct regulator_desc pm8998_ftsmps = { }; static const struct regulator_desc pm8998_hfsmps = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000), }, .n_linear_ranges = 1, @@ -502,7 +502,7 @@ static const struct regulator_desc pm8998_hfsmps = { }; static const struct regulator_desc pm8998_nldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000), }, .n_linear_ranges = 1, @@ -511,7 +511,7 @@ static const struct regulator_desc pm8998_nldo = { }; static const struct regulator_desc pm8998_pldo = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000), }, .n_linear_ranges = 1, @@ -520,7 +520,7 @@ static const struct regulator_desc pm8998_pldo = { }; static const struct regulator_desc pm8998_pldo_lv = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000), }, .n_linear_ranges = 1, @@ -533,7 +533,7 @@ static const struct regulator_desc pm8998_switch = { }; static const struct regulator_desc pmi8998_bob = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000), }, .n_linear_ranges = 1, @@ -542,7 +542,7 @@ static const struct regulator_desc pmi8998_bob = { }; static const struct regulator_desc pms405_hfsmps3 = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000), }, .n_linear_ranges = 1, @@ -551,7 +551,7 @@ static const struct regulator_desc pms405_hfsmps3 = { }; static const struct regulator_desc pms405_nldo300 = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000), }, .n_linear_ranges = 1, @@ -560,7 +560,7 @@ static const struct regulator_desc pms405_nldo300 = { }; static const struct regulator_desc pms405_nldo1200 = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000), }, .n_linear_ranges = 1, @@ -569,7 +569,7 @@ static const struct regulator_desc pms405_nldo1200 = { }; static const struct regulator_desc pms405_pldo50 = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1664000, 0, 128, 16000), }, .n_linear_ranges = 1, @@ -578,7 +578,7 @@ static const struct regulator_desc pms405_pldo50 = { }; static const struct regulator_desc pms405_pldo150 = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1664000, 0, 128, 16000), }, .n_linear_ranges = 1, @@ -587,7 +587,7 @@ static const struct regulator_desc pms405_pldo150 = { }; static const struct regulator_desc pms405_pldo600 = { - .linear_ranges = (struct regulator_linear_range[]) { + .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1256000, 0, 98, 8000), }, .n_linear_ranges = 1, diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 31f79fda3238..e926c1a85846 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -165,14 +165,14 @@ static const int rk808_buck_config_regs[] = { RK808_BUCK4_CONFIG_REG, }; -static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = { +static const struct linear_range rk808_ldo3_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000), REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0), }; #define RK809_BUCK5_SEL_CNT (8) -static const struct regulator_linear_range rk809_buck5_voltage_ranges[] = { +static const struct linear_range rk809_buck5_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(1500000, 0, 0, 0), REGULATOR_LINEAR_RANGE(1800000, 1, 3, 200000), REGULATOR_LINEAR_RANGE(2800000, 4, 5, 200000), @@ -201,14 +201,14 @@ static const struct regulator_linear_range rk809_buck5_voltage_ranges[] = { #define RK817_BUCK1_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK1_SEL1 + 1) #define RK817_BUCK3_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK3_SEL1 + 1) -static const struct regulator_linear_range rk817_buck1_voltage_ranges[] = { +static const struct linear_range rk817_buck1_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0, RK817_BUCK1_SEL0, RK817_BUCK1_STP0), REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1, RK817_BUCK1_SEL_CNT, RK817_BUCK1_STP1), }; -static const struct regulator_linear_range rk817_buck3_voltage_ranges[] = { +static const struct linear_range rk817_buck3_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0, RK817_BUCK1_SEL0, RK817_BUCK1_STP0), REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1, @@ -665,7 +665,7 @@ static const struct regulator_ops rk808_switch_ops = { .set_suspend_disable = rk808_set_suspend_disable, }; -static const struct regulator_linear_range rk805_buck_1_2_voltage_ranges[] = { +static const struct linear_range rk805_buck_1_2_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500), REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000), REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0), diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 23d288278957..33cf84bce05a 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -749,37 +749,37 @@ static const struct regulator_ops s2mps15_reg_buck_ops = { } /* voltage range for s2mps15 LDO 3, 5, 15, 16, 18, 20, 23 and 27 */ -static const struct regulator_linear_range s2mps15_ldo_voltage_ranges1[] = { +static const struct linear_range s2mps15_ldo_voltage_ranges1[] = { REGULATOR_LINEAR_RANGE(1000000, 0xc, 0x38, 25000), }; /* voltage range for s2mps15 LDO 2, 6, 14, 17, 19, 21, 24 and 25 */ -static const struct regulator_linear_range s2mps15_ldo_voltage_ranges2[] = { +static const struct linear_range s2mps15_ldo_voltage_ranges2[] = { REGULATOR_LINEAR_RANGE(1800000, 0x0, 0x3f, 25000), }; /* voltage range for s2mps15 LDO 4, 11, 12, 13, 22 and 26 */ -static const struct regulator_linear_range s2mps15_ldo_voltage_ranges3[] = { +static const struct linear_range s2mps15_ldo_voltage_ranges3[] = { REGULATOR_LINEAR_RANGE(700000, 0x0, 0x34, 12500), }; /* voltage range for s2mps15 LDO 7, 8, 9 and 10 */ -static const struct regulator_linear_range s2mps15_ldo_voltage_ranges4[] = { +static const struct linear_range s2mps15_ldo_voltage_ranges4[] = { REGULATOR_LINEAR_RANGE(700000, 0x10, 0x20, 25000), }; /* voltage range for s2mps15 LDO 1 */ -static const struct regulator_linear_range s2mps15_ldo_voltage_ranges5[] = { +static const struct linear_range s2mps15_ldo_voltage_ranges5[] = { REGULATOR_LINEAR_RANGE(500000, 0x0, 0x20, 12500), }; /* voltage range for s2mps15 BUCK 1, 2, 3, 4, 5, 6 and 7 */ -static const struct regulator_linear_range s2mps15_buck_voltage_ranges1[] = { +static const struct linear_range s2mps15_buck_voltage_ranges1[] = { REGULATOR_LINEAR_RANGE(500000, 0x20, 0xc0, 6250), }; /* voltage range for s2mps15 BUCK 8, 9 and 10 */ -static const struct regulator_linear_range s2mps15_buck_voltage_ranges2[] = { +static const struct linear_range s2mps15_buck_voltage_ranges2[] = { REGULATOR_LINEAR_RANGE(1000000, 0x20, 0x78, 12500), }; diff --git a/drivers/regulator/sky81452-regulator.c b/drivers/regulator/sky81452-regulator.c index 177dede82a61..37658affe072 100644 --- a/drivers/regulator/sky81452-regulator.c +++ b/drivers/regulator/sky81452-regulator.c @@ -32,7 +32,7 @@ static const struct regulator_ops sky81452_reg_ops = { .is_enabled = regulator_is_enabled_regmap, }; -static const struct regulator_linear_range sky81452_reg_ranges[] = { +static const struct linear_range sky81452_reg_ranges[] = { REGULATOR_LINEAR_RANGE(4500000, 0, 14, 250000), REGULATOR_LINEAR_RANGE(9000000, 15, 31, 1000000), }; diff --git a/drivers/regulator/stpmic1_regulator.c b/drivers/regulator/stpmic1_regulator.c index f3d7d007ecbb..adc9973d1b2f 100644 --- a/drivers/regulator/stpmic1_regulator.c +++ b/drivers/regulator/stpmic1_regulator.c @@ -57,13 +57,13 @@ enum { /* Ramp delay worst case is (2250uV/uS) */ #define PMIC_RAMP_DELAY 2200 -static const struct regulator_linear_range buck1_ranges[] = { +static const struct linear_range buck1_ranges[] = { REGULATOR_LINEAR_RANGE(725000, 0, 4, 0), REGULATOR_LINEAR_RANGE(725000, 5, 36, 25000), REGULATOR_LINEAR_RANGE(1500000, 37, 63, 0), }; -static const struct regulator_linear_range buck2_ranges[] = { +static const struct linear_range buck2_ranges[] = { REGULATOR_LINEAR_RANGE(1000000, 0, 17, 0), REGULATOR_LINEAR_RANGE(1050000, 18, 19, 0), REGULATOR_LINEAR_RANGE(1100000, 20, 21, 0), @@ -77,7 +77,7 @@ static const struct regulator_linear_range buck2_ranges[] = { REGULATOR_LINEAR_RANGE(1500000, 36, 63, 0), }; -static const struct regulator_linear_range buck3_ranges[] = { +static const struct linear_range buck3_ranges[] = { REGULATOR_LINEAR_RANGE(1000000, 0, 19, 0), REGULATOR_LINEAR_RANGE(1100000, 20, 23, 0), REGULATOR_LINEAR_RANGE(1200000, 24, 27, 0), @@ -87,7 +87,7 @@ static const struct regulator_linear_range buck3_ranges[] = { REGULATOR_LINEAR_RANGE(3400000, 56, 63, 0), }; -static const struct regulator_linear_range buck4_ranges[] = { +static const struct linear_range buck4_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0, 27, 25000), REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0), REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0), @@ -97,19 +97,19 @@ static const struct regulator_linear_range buck4_ranges[] = { REGULATOR_LINEAR_RANGE(3900000, 61, 63, 0), }; -static const struct regulator_linear_range ldo1_ranges[] = { +static const struct linear_range ldo1_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0), REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000), REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0), }; -static const struct regulator_linear_range ldo2_ranges[] = { +static const struct linear_range ldo2_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0), REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000), REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0), }; -static const struct regulator_linear_range ldo3_ranges[] = { +static const struct linear_range ldo3_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0), REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000), REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0), @@ -117,13 +117,13 @@ static const struct regulator_linear_range ldo3_ranges[] = { REGULATOR_LINEAR_RANGE(500000, 31, 31, 0), }; -static const struct regulator_linear_range ldo5_ranges[] = { +static const struct linear_range ldo5_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0), REGULATOR_LINEAR_RANGE(1700000, 8, 30, 100000), REGULATOR_LINEAR_RANGE(3900000, 31, 31, 0), }; -static const struct regulator_linear_range ldo6_ranges[] = { +static const struct linear_range ldo6_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 24, 100000), REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0), }; diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c index 5a5e9b5bf4be..9910e949373c 100644 --- a/drivers/regulator/tps65086-regulator.c +++ b/drivers/regulator/tps65086-regulator.c @@ -71,23 +71,23 @@ struct tps65086_regulator { unsigned int decay_mask; }; -static const struct regulator_linear_range tps65086_10mv_ranges[] = { +static const struct linear_range tps65086_10mv_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000), }; -static const struct regulator_linear_range tps65086_buck126_25mv_ranges[] = { +static const struct linear_range tps65086_buck126_25mv_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x18, 0), REGULATOR_LINEAR_RANGE(1025000, 0x19, 0x7F, 25000), }; -static const struct regulator_linear_range tps65086_buck345_25mv_ranges[] = { +static const struct linear_range tps65086_buck345_25mv_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(425000, 0x1, 0x7F, 25000), }; -static const struct regulator_linear_range tps65086_ldoa1_ranges[] = { +static const struct linear_range tps65086_ldoa1_ranges[] = { REGULATOR_LINEAR_RANGE(1350000, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(1500000, 0x1, 0x7, 100000), REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xB, 100000), @@ -95,7 +95,7 @@ static const struct regulator_linear_range tps65086_ldoa1_ranges[] = { REGULATOR_LINEAR_RANGE(3300000, 0xE, 0xE, 0), }; -static const struct regulator_linear_range tps65086_ldoa23_ranges[] = { +static const struct linear_range tps65086_ldoa23_ranges[] = { REGULATOR_LINEAR_RANGE(700000, 0x0, 0xD, 50000), REGULATOR_LINEAR_RANGE(1400000, 0xE, 0xF, 100000), }; diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 67ba78da77ec..d27dbbafcf72 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -56,14 +56,14 @@ static const unsigned int LDO1_VSEL_table[] = { 2800000, 3000000, 3100000, 3300000, }; -static const struct regulator_linear_range tps65217_uv1_ranges[] = { +static const struct linear_range tps65217_uv1_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 24, 25000), REGULATOR_LINEAR_RANGE(1550000, 25, 52, 50000), REGULATOR_LINEAR_RANGE(3000000, 53, 55, 100000), REGULATOR_LINEAR_RANGE(3300000, 56, 63, 0), }; -static const struct regulator_linear_range tps65217_uv2_ranges[] = { +static const struct linear_range tps65217_uv2_ranges[] = { REGULATOR_LINEAR_RANGE(1500000, 0, 8, 50000), REGULATOR_LINEAR_RANGE(2000000, 9, 13, 100000), REGULATOR_LINEAR_RANGE(2450000, 14, 31, 50000), diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index b72035610013..05d13f807918 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -56,17 +56,17 @@ .bypass_mask = _sm, \ } \ -static const struct regulator_linear_range dcdc1_dcdc2_ranges[] = { +static const struct linear_range dcdc1_dcdc2_ranges[] = { REGULATOR_LINEAR_RANGE(850000, 0x0, 0x32, 10000), REGULATOR_LINEAR_RANGE(1375000, 0x33, 0x3f, 25000), }; -static const struct regulator_linear_range ldo1_dcdc3_ranges[] = { +static const struct linear_range ldo1_dcdc3_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0x0, 0x1a, 25000), REGULATOR_LINEAR_RANGE(1600000, 0x1b, 0x3f, 50000), }; -static const struct regulator_linear_range dcdc4_ranges[] = { +static const struct linear_range dcdc4_ranges[] = { REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000), REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000), }; diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index 276faeddc370..15c79931ea89 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -46,11 +46,11 @@ enum tps65912_regulators { DCDC1, DCDC2, DCDC3, DCDC4, LDO1, LDO2, LDO3, .n_linear_ranges = ARRAY_SIZE(_lr), \ } -static const struct regulator_linear_range tps65912_dcdc_ranges[] = { +static const struct linear_range tps65912_dcdc_ranges[] = { REGULATOR_LINEAR_RANGE(500000, 0x0, 0x3f, 50000), }; -static const struct regulator_linear_range tps65912_ldo_ranges[] = { +static const struct linear_range tps65912_ldo_ranges[] = { REGULATOR_LINEAR_RANGE(800000, 0x0, 0x20, 25000), REGULATOR_LINEAR_RANGE(1650000, 0x21, 0x3c, 50000), REGULATOR_LINEAR_RANGE(3100000, 0x3d, 0x3f, 100000), diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 866b4dd01da9..4a51cfea45ac 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -360,12 +360,12 @@ static const u16 VINTANA2_VSEL_table[] = { }; /* 600mV to 1450mV in 12.5 mV steps */ -static const struct regulator_linear_range VDD1_ranges[] = { +static const struct linear_range VDD1_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0, 68, 12500) }; /* 600mV to 1450mV in 12.5 mV steps, everything above = 1500mV */ -static const struct regulator_linear_range VDD2_ranges[] = { +static const struct linear_range VDD2_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0, 68, 12500), REGULATOR_LINEAR_RANGE(1500000, 69, 69, 12500) }; diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c index b8100c3cedad..f7db250a7583 100644 --- a/drivers/regulator/twl6030-regulator.c +++ b/drivers/regulator/twl6030-regulator.c @@ -495,7 +495,7 @@ static const struct regulator_ops twlsmps_ops = { }; /*----------------------------------------------------------------------*/ -static const struct regulator_linear_range twl6030ldo_linear_range[] = { +static const struct linear_range twl6030ldo_linear_range[] = { REGULATOR_LINEAR_RANGE(0, 0, 0, 0), REGULATOR_LINEAR_RANGE(1000000, 1, 24, 100000), REGULATOR_LINEAR_RANGE(2750000, 31, 31, 0), diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 018dbbd96771..ad2203d11a88 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -204,7 +204,7 @@ static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data) * BUCKV specifics */ -static const struct regulator_linear_range wm831x_buckv_ranges[] = { +static const struct linear_range wm831x_buckv_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0, 0x7, 0), REGULATOR_LINEAR_RANGE(600000, 0x8, 0x68, 12500), }; diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 56754686c982..7b6cf4810cb7 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -59,7 +59,7 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data) * General purpose LDOs */ -static const struct regulator_linear_range wm831x_gp_ldo_ranges[] = { +static const struct linear_range wm831x_gp_ldo_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 14, 50000), REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000), }; @@ -312,7 +312,7 @@ static struct platform_driver wm831x_gp_ldo_driver = { * Analogue LDOs */ -static const struct regulator_linear_range wm831x_aldo_ranges[] = { +static const struct linear_range wm831x_aldo_ranges[] = { REGULATOR_LINEAR_RANGE(1000000, 0, 12, 50000), REGULATOR_LINEAR_RANGE(1700000, 13, 31, 100000), }; diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 56d6168a888d..ae5f0e7fce8b 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -470,7 +470,7 @@ static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev, return 0; } -static const struct regulator_linear_range wm8350_ldo_ranges[] = { +static const struct linear_range wm8350_ldo_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 15, 50000), REGULATOR_LINEAR_RANGE(1800000, 16, 31, 100000), }; diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 6f331b51e479..4cb1fbb59722 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -13,7 +13,7 @@ #include #include -static const struct regulator_linear_range wm8400_ldo_ranges[] = { +static const struct linear_range wm8400_ldo_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 14, 50000), REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000), }; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 29d920516e0b..7eb9fea8e482 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -13,6 +13,7 @@ #define __LINUX_REGULATOR_DRIVER_H_ #include +#include #include #include #include @@ -39,31 +40,13 @@ enum regulator_status { REGULATOR_STATUS_UNDEFINED, }; -/** - * struct regulator_linear_range - specify linear voltage ranges - * - * Specify a range of voltages for regulator_map_linear_range() and - * regulator_list_linear_range(). - * - * @min_uV: Lowest voltage in range - * @min_sel: Lowest selector for range - * @max_sel: Highest selector for range - * @uV_step: Step size - */ -struct regulator_linear_range { - unsigned int min_uV; - unsigned int min_sel; - unsigned int max_sel; - unsigned int uV_step; -}; - -/* Initialize struct regulator_linear_range */ +/* Initialize struct linear_range for regulators */ #define REGULATOR_LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV) \ { \ - .min_uV = _min_uV, \ + .min = _min_uV, \ .min_sel = _min_sel, \ .max_sel = _max_sel, \ - .uV_step = _step_uV, \ + .step = _step_uV, \ } /** @@ -348,7 +331,7 @@ struct regulator_desc { unsigned int ramp_delay; int min_dropout_uV; - const struct regulator_linear_range *linear_ranges; + const struct linear_range *linear_ranges; const unsigned int *linear_range_selectors; int n_linear_ranges; From patchwork Wed Apr 29 06:59:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516101 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B69B31392 for ; Wed, 29 Apr 2020 07:00:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A34CB2073E for ; Wed, 29 Apr 2020 07:00:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726474AbgD2G77 (ORCPT ); Wed, 29 Apr 2020 02:59:59 -0400 Received: from mail-lf1-f65.google.com ([209.85.167.65]:35407 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726158AbgD2G77 (ORCPT ); Wed, 29 Apr 2020 02:59:59 -0400 Received: by mail-lf1-f65.google.com with SMTP id r17so728680lff.2; Tue, 28 Apr 2020 23:59:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=sp4Q0pxUVysVvGlDJYjuzQkE2LcHHYkVNEZ4IUcHcII=; b=Jl0s51wywtnxndRpTBDMS23rfio26GeT9T3VEYrCjoccIBw+wkk8KuBs3r/Jl52s7M 7RrJllGCk10E1AwQy9/yzUUEJitXQRw52mO5d40i9gTTvbT/5FKRx2i3qzSWkwO/sVzw kaWzUV1l+9oNdt6BZPvdoNdZYDCF+SMBZZhEzkh3yDFDVUi5l4Ee6z1vTtImROvR1fqG uYvbTs4ScPzdyydqVYx7bGiXz4HH+HI3tjSsyFttf0xLS43n9/IGUfdL0x406jMGUkTB otYj5jJhpHO0YPF/UUidI2j73dOtAHEFZB2i6LKYRsdjAUSO/zl0Gq7C3j7i6jU/Nym2 NZ7g== X-Gm-Message-State: AGi0PubraJOMMSPoqYJfMYS55WI8h4jT+dNuTCSEOS5Q/vza+Gi37ZvF +HHsIF1F36WXFd/nH9gfOA4= X-Google-Smtp-Source: APiQypKStLl9Za1B95Bwx+XF6pKyPEwRFwXM2rV+0XVJAIVTm/bX6g7vISufkwR15UnD3CkCOFcWIQ== X-Received: by 2002:a19:5f04:: with SMTP id t4mr21859571lfb.208.1588143595216; Tue, 28 Apr 2020 23:59:55 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id k18sm1971777lfg.81.2020.04.28.23.59.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2020 23:59:54 -0700 (PDT) Date: Wed, 29 Apr 2020 09:59:08 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 05/11] power: supply: bd70528: use linear ranges Message-ID: <88a69f3726d6031c83cde549157b93d737c8e828.1586925868.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Change the bd70528 to use common linear_range code instead of implementing a copy of it in this driver. Signed-off-by: Matti Vaittinen Reviewed-by: Sebastian Reichel --- Changes since v9: - Add commas to last struct members as suggested by Andy drivers/power/supply/Kconfig | 1 + drivers/power/supply/bd70528-charger.c | 144 ++++++++++--------------- 2 files changed, 56 insertions(+), 89 deletions(-) diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index f3424fdce341..9f19636db922 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -695,6 +695,7 @@ config CHARGER_UCS1002 config CHARGER_BD70528 tristate "ROHM bd70528 charger driver" depends on MFD_ROHM_BD70528 + select LINEAR_RANGES default n help Say Y here to enable support for getting battery status diff --git a/drivers/power/supply/bd70528-charger.c b/drivers/power/supply/bd70528-charger.c index 3b820110ecfa..7c1f0b99c71b 100644 --- a/drivers/power/supply/bd70528-charger.c +++ b/drivers/power/supply/bd70528-charger.c @@ -72,6 +72,7 @@ #include #include #include +#include #define CHG_STAT_SUSPEND 0x0 #define CHG_STAT_TRICKLE 0x1 @@ -335,38 +336,37 @@ static int bd70528_get_present(struct bd70528_psy *bdpsy, int *val) return 0; } -struct bd70528_linear_range { - int min; - int step; - int vals; - int low_sel; -}; - -static const struct bd70528_linear_range current_limit_ranges[] = { +static const struct linear_range current_limit_ranges[] = { { .min = 5, .step = 1, - .vals = 36, - .low_sel = 0, + .min_sel = 0, + .max_sel = 0x22, }, { .min = 40, .step = 5, - .vals = 5, - .low_sel = 0x23, + .min_sel = 0x23, + .max_sel = 0x26, }, { .min = 60, .step = 20, - .vals = 8, - .low_sel = 0x27, + .min_sel = 0x27, + .max_sel = 0x2d, }, { .min = 200, .step = 50, - .vals = 7, - .low_sel = 0x2e, - } + .min_sel = 0x2e, + .max_sel = 0x34, + }, + { + .min = 500, + .step = 0, + .min_sel = 0x35, + .max_sel = 0x3f, + }, }; /* @@ -374,18 +374,18 @@ static const struct bd70528_linear_range current_limit_ranges[] = { * voltage for low temperatures. The driver currently only reads * the charge current at room temperature. We do set both though. */ -static const struct bd70528_linear_range warm_charge_curr[] = { +static const struct linear_range warm_charge_curr[] = { { .min = 10, .step = 10, - .vals = 20, - .low_sel = 0, + .min_sel = 0, + .max_sel = 0x12, }, { .min = 200, .step = 25, - .vals = 13, - .low_sel = 0x13, + .min_sel = 0x13, + .max_sel = 0x1f, }, }; @@ -398,56 +398,6 @@ static const struct bd70528_linear_range warm_charge_curr[] = { #define MAX_WARM_CHG_CURR_SEL 0x1f #define MIN_CHG_CURR_SEL 0x0 -static int find_value_for_selector_low(const struct bd70528_linear_range *r, - int selectors, unsigned int sel, - unsigned int *val) -{ - int i; - - for (i = 0; i < selectors; i++) { - if (r[i].low_sel <= sel && r[i].low_sel + r[i].vals >= sel) { - *val = r[i].min + (sel - r[i].low_sel) * r[i].step; - return 0; - } - } - return -EINVAL; -} - -/* - * For BD70528 voltage/current limits we happily accept any value which - * belongs the range. We could check if value matching the selector is - * desired by computing the range min + (sel - sel_low) * range step - but - * I guess it is enough if we use voltage/current which is closest (below) - * the requested? - */ -static int find_selector_for_value_low(const struct bd70528_linear_range *r, - int selectors, unsigned int val, - unsigned int *sel, bool *found) -{ - int i; - int ret = -EINVAL; - - *found = false; - for (i = 0; i < selectors; i++) { - if (r[i].min <= val) { - if (r[i].min + r[i].step * r[i].vals >= val) { - *found = true; - *sel = r[i].low_sel + (val - r[i].min) / - r[i].step; - ret = 0; - break; - } - /* - * If the range max is smaller than requested - * we can set the max supported value from range - */ - *sel = r[i].low_sel + r[i].vals; - ret = 0; - } - } - return ret; -} - static int get_charge_current(struct bd70528_psy *bdpsy, int *ma) { unsigned int sel; @@ -463,9 +413,9 @@ static int get_charge_current(struct bd70528_psy *bdpsy, int *ma) sel &= BD70528_MASK_CHG_CHG_CURR; - ret = find_value_for_selector_low(&warm_charge_curr[0], - ARRAY_SIZE(warm_charge_curr), sel, - ma); + ret = linear_range_get_value_array(&warm_charge_curr[0], + ARRAY_SIZE(warm_charge_curr), + sel, ma); if (ret) { dev_err(bdpsy->dev, "Unknown charge current value 0x%x\n", @@ -491,10 +441,9 @@ static int get_current_limit(struct bd70528_psy *bdpsy, int *ma) sel &= BD70528_MASK_CHG_DCIN_ILIM; - ret = find_value_for_selector_low(¤t_limit_ranges[0], - ARRAY_SIZE(current_limit_ranges), sel, - ma); - + ret = linear_range_get_value_array(¤t_limit_ranges[0], + ARRAY_SIZE(current_limit_ranges), + sel, ma); if (ret) { /* Unspecified values mean 500 mA */ *ma = 500; @@ -588,15 +537,28 @@ static int set_charge_current(struct bd70528_psy *bdpsy, int ma) goto set; } - ret = find_selector_for_value_low(&warm_charge_curr[0], - ARRAY_SIZE(warm_charge_curr), ma, - ®, &found); +/* + * For BD70528 voltage/current limits we happily accept any value which + * belongs the range. We could check if value matching the selector is + * desired by computing the range min + (sel - sel_low) * range step - but + * I guess it is enough if we use voltage/current which is closest (below) + * the requested? + */ + + ret = linear_range_get_selector_low_array(warm_charge_curr, + ARRAY_SIZE(warm_charge_curr), + ma, ®, &found); if (ret) { + dev_err(bdpsy->dev, + "Unsupported charge current %u mA\n", ma); reg = MIN_CHG_CURR_SEL; goto set; } if (!found) { - /* There was a gap in supported values and we hit it */ + /* + * There was a gap in supported values and we hit it. + * Yet a smaller value was found so we use it. + */ dev_warn(bdpsy->dev, "Unsupported charge current %u mA\n", ma); } @@ -648,17 +610,21 @@ static int set_current_limit(struct bd70528_psy *bdpsy, int ma) goto set; } - ret = find_selector_for_value_low(¤t_limit_ranges[0], - ARRAY_SIZE(current_limit_ranges), ma, - ®, &found); + ret = linear_range_get_selector_low_array(current_limit_ranges, + ARRAY_SIZE(current_limit_ranges), + ma, ®, &found); if (ret) { + dev_err(bdpsy->dev, "Unsupported current limit %umA\n", ma); reg = MIN_CURR_LIMIT_SEL; goto set; } if (!found) { - /* There was a gap in supported values and we hit it ?*/ - dev_warn(bdpsy->dev, "Unsupported current limit %umA\n", - ma); + /* + * There was a gap in supported values and we hit it. + * We found a smaller value from ranges and use it. + * Warn user though. + */ + dev_warn(bdpsy->dev, "Unsupported current limit %umA\n", ma); } set: From patchwork Wed Apr 29 07:00:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516105 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2568692A for ; Wed, 29 Apr 2020 07:01:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 16A192073E for ; Wed, 29 Apr 2020 07:01:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726274AbgD2HBL (ORCPT ); Wed, 29 Apr 2020 03:01:11 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:40291 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726158AbgD2HBL (ORCPT ); Wed, 29 Apr 2020 03:01:11 -0400 Received: by mail-lj1-f196.google.com with SMTP id y4so1416205ljn.7; Wed, 29 Apr 2020 00:01:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=ptPYLDei9LMsvhdKW9/nay5bhWp9Qq4b7cAcaUxshS0=; b=sI7Q3oMH3ORGN4oKJKwqzteji/kk9Q7ewqE3/Y7odvuM0e2BrYhh5TWi3hPNyAj0G0 tFqetBv5RxQj0P0V2mM8noMXqZrkJVRTHYJs0BKIB7RlihiLUxu9JduA1P+ows7wG0nJ R3O5NfaOyrbAAxh3vMvyQkLb2pav5CBz2HYhdiLQSzPbalLiH3RGTrvKIH6g93eWD3cZ sj9zHrnrysnAwJdjPUm0h1/3SsfazfuWrQHE+pgvu7URXktOoYH2bQ8FDBc6L0PL15wx GXdHWUeQCgjht+EeuABBiT8XZUa/CSUoQ9mFkzxD4HRu8tPTsBZmTSePgwtnoaVPr0kn KwlA== X-Gm-Message-State: AGi0PuaPI+LONLGG8aNn+8X+fhPKfHhPahUFeSee6ysBkFRleRigCGyf VY0SNZgmqXTKEcDNo9qxzWU= X-Google-Smtp-Source: APiQypKMS7huMXVCwkN0xqaQZEasmGknHyh+qzVqmq/W6qhQomOoC00vc8yxZ9z4Kv8EM7paUv0ttQ== X-Received: by 2002:a2e:96c2:: with SMTP id d2mr20730865ljj.214.1588143668845; Wed, 29 Apr 2020 00:01:08 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id w29sm1775466lfq.35.2020.04.29.00.01.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2020 00:01:08 -0700 (PDT) Date: Wed, 29 Apr 2020 10:00:22 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 06/11] dt-bindings: battery: add new battery parameters Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add: - trickle-charge-current-microamp: Some chargers have 3 charging stages. First one when battery is almost empty is often called as trickle-charge. Last state when battery has been "woken up" is usually called as fast-charge. In addition to this some chargers have a 'middle state' which ROHM BD99954 data-sheet describes as pre-charge. Some batteries can benefit from this 3-phase charging [citation needed]. Introduce trickle-charge-current-microamp so that batteries can give charging current limit for all three states. - precharge-upper-limit-microvolt: When battery voltage has reached certain limit we change from trickle-charge to next charging state (pre-charge for BD99954). Allow battery to specify this limit. - re-charge-voltage-microvolt: Allow giving a battery specific voltage limit for chargers which can automatically re-start charging when battery has discharghed down to this limit. - over-voltage-threshold-microvolt Allow specifying voltage threshold after which the battery is assumed to be faulty. Signed-off-by: Matti Vaittinen Reviewed-by: Rob Herring Reviewed-by: Sebastian Reichel --- No changes since v9 Documentation/devicetree/bindings/power/supply/battery.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt index 3049cf88bdcf..5e29595edd74 100644 --- a/Documentation/devicetree/bindings/power/supply/battery.txt +++ b/Documentation/devicetree/bindings/power/supply/battery.txt @@ -11,15 +11,21 @@ different type. This prevents unpredictable, potentially harmful, behavior should a replacement that changes the battery type occur without a corresponding update to the dtb. +Please note that not all charger drivers respect all of the properties. + Required Properties: - compatible: Must be "simple-battery" Optional Properties: + - over-voltage-threshold-microvolt: battery over-voltage limit + - re-charge-voltage-microvolt: limit to automatically start charging again - voltage-min-design-microvolt: drained battery voltage - voltage-max-design-microvolt: fully charged battery voltage - energy-full-design-microwatt-hours: battery design energy - charge-full-design-microamp-hours: battery design capacity + - trickle-charge-current-microamp: current for trickle-charge phase - precharge-current-microamp: current for pre-charge phase + - precharge-upper-limit-microvolt: limit when to change to constant charging - charge-term-current-microamp: current for charge termination phase - constant-charge-current-max-microamp: maximum constant input current - constant-charge-voltage-max-microvolt: maximum constant input voltage From patchwork Wed Apr 29 07:01:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516107 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F2F3C92C for ; Wed, 29 Apr 2020 07:02:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5F412076B for ; Wed, 29 Apr 2020 07:02:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726423AbgD2HCl (ORCPT ); Wed, 29 Apr 2020 03:02:41 -0400 Received: from mail-lf1-f68.google.com ([209.85.167.68]:35632 "EHLO mail-lf1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726158AbgD2HCk (ORCPT ); Wed, 29 Apr 2020 03:02:40 -0400 Received: by mail-lf1-f68.google.com with SMTP id r17so735235lff.2; Wed, 29 Apr 2020 00:02:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=r85BWktV4eKffhP5bEUSsTAbCcixIe97gDFSAa6NS3Q=; b=d8MO2agmSpgE0t4Hwc90drXsc3Pv1WIi8szDM6PgnW9tGkvHMCKa2FXPicLcaz5cRk VoC5Ku1ChYdJxOEk1Ry1m8wojb6TR1gra6U3vGnuoBFj80dYS6ced27SOsft25wOiGwX 0gCtCruF4C8PokGM1nVQHp79akAtxAloqfIRAAbECwpCH1EqYp1mRP6t3CblnvJYJwuJ 6A9cK15ooQvgWyXEJa/DHmAThnspbBwbK7LGrW/tfPqPZA/9OwiLneDYhtnm6JEMit/M OLn/uxKAq7kOt9aAyJrVUNC2VrSO2rJoyvWJXxjDGZ1uomaQSHWPrfHovWDyjrt/iyRR 7zwA== X-Gm-Message-State: AGi0Pubrxt37PQaeOvRhUYeEYRnkGk+OBjy/Gjvxe1EdpYQhGdqWK4Ot frKKgVFQCFHpgngvySXEooXRkB+D X-Google-Smtp-Source: APiQypIFi9ou7QBNuT6F+ieYM01MLBxKnRbK+Vb4zU2l2zTUMF/LaQAO7c13hHD9GVjqgs8VW8hnsg== X-Received: by 2002:ac2:47f0:: with SMTP id b16mr21856798lfp.81.1588143758172; Wed, 29 Apr 2020 00:02:38 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id h24sm1618370lji.99.2020.04.29.00.02.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2020 00:02:37 -0700 (PDT) Date: Wed, 29 Apr 2020 10:01:49 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 07/11] power: supply: add battery parameters Message-ID: <9b59e3674ad89fddf83aa6396c8699e71836be0c.1586925868.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add parsing of new device-tree battery bindings. - trickle-charge-current-microamp - precharge-upper-limit-microvolt - re-charge-voltage-microvolt - over-voltage-threshold-microvolt Signed-off-by: Matti Vaittinen Reviewed-by: Sebastian Reichel --- No changes since v9 drivers/power/supply/power_supply_core.c | 8 ++++++++ include/linux/power_supply.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 1a9a9fae73d3..02b37fe6061c 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -620,10 +620,18 @@ int power_supply_get_battery_info(struct power_supply *psy, &info->voltage_min_design_uv); of_property_read_u32(battery_np, "voltage-max-design-microvolt", &info->voltage_max_design_uv); + of_property_read_u32(battery_np, "trickle-charge-current-microamp", + &info->tricklecharge_current_ua); of_property_read_u32(battery_np, "precharge-current-microamp", &info->precharge_current_ua); + of_property_read_u32(battery_np, "precharge-upper-limit-microvolt", + &info->precharge_voltage_max_uv); of_property_read_u32(battery_np, "charge-term-current-microamp", &info->charge_term_current_ua); + of_property_read_u32(battery_np, "re-charge-voltage-microvolt", + &info->charge_restart_voltage_uv); + of_property_read_u32(battery_np, "over-voltage-threshold-microvolt", + &info->overvoltage_limit_uv); of_property_read_u32(battery_np, "constant-charge-current-max-microamp", &info->constant_charge_current_max_ua); of_property_read_u32(battery_np, "constant-charge-voltage-max-microvolt", diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index dcd5a71e6c67..d01322d1ab52 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -346,8 +346,12 @@ struct power_supply_battery_info { int charge_full_design_uah; /* microAmp-hours */ int voltage_min_design_uv; /* microVolts */ int voltage_max_design_uv; /* microVolts */ + int tricklecharge_current_ua; /* microAmps */ int precharge_current_ua; /* microAmps */ + int precharge_voltage_max_uv; /* microVolts */ int charge_term_current_ua; /* microAmps */ + int charge_restart_voltage_uv; /* microVolts */ + int overvoltage_limit_uv; /* microVolts */ int constant_charge_current_max_ua; /* microAmps */ int constant_charge_voltage_max_uv; /* microVolts */ int factory_internal_resistance_uohm; /* microOhms */ From patchwork Wed Apr 29 07:03:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516109 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8C2DD92A for ; Wed, 29 Apr 2020 07:04:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7686620775 for ; Wed, 29 Apr 2020 07:04:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726366AbgD2HER (ORCPT ); Wed, 29 Apr 2020 03:04:17 -0400 Received: from mail-lf1-f65.google.com ([209.85.167.65]:39484 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726158AbgD2HEQ (ORCPT ); Wed, 29 Apr 2020 03:04:16 -0400 Received: by mail-lf1-f65.google.com with SMTP id m2so724866lfo.6; Wed, 29 Apr 2020 00:04:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=I001WhKMG3x+17SpdPQZfl+Qc5F3pr+KIVKbQtKWM4Y=; b=lXUirkccHg4PdqkBnBqcoGDZLT/kSLYXckL1El5cV2NCZXNrpNU2JLOroYzP6+5EJQ nxsryE7MYcjtFIgJDrbqIKjAbganjZVShHWP2S8k6t2mdq1BSyh4LFHhOEkiDYE4gs7U 15u/1ot2Z2kR/AGI1v1sRZFzrCn+2Ej4m8rRVkq/mxRbGR1NHbFx/5DiITb9DkLtGrl/ +Xh79vUqTW/8C5R7nlA4N8TZIRYg3TDbSS+inV/vnU61vqhWkl0LErIoLpW6VTwHvGrO foTImXcJX06ig2YwD8FxvaL2PozUw+yUVH9VVG+vuRjYJMBhOvHIuMyTziSCSgGV858s Ks4g== X-Gm-Message-State: AGi0PuZDPpkuOuhYobJVxNmtnjw6McX6Q4NXbszJe5pNK667frv5MYXb Sd+KQzdECImtqryiFWDX/40= X-Google-Smtp-Source: APiQypKZwteu5753Vc3nU9f7SGI9nFFcyAsVyUiSKUsC9D3dzT0XpF2ZbhDu50d5lnNJeMVLtmKuFw== X-Received: by 2002:a19:f611:: with SMTP id x17mr22073807lfe.51.1588143852950; Wed, 29 Apr 2020 00:04:12 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id n14sm1777353lfe.31.2020.04.29.00.04.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2020 00:04:12 -0700 (PDT) Date: Wed, 29 Apr 2020 10:03:26 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 08/11] dt_bindings: ROHM BD99954 Charger Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The ROHM BD99954 is a Battery Management LSI for 1-4 cell Lithium-Ion secondary battery. Intended to be used in space-constraint equipment such as Low profile Notebook PC, Tablets and other applications. BD99954 provides a Dual-source Battery Charger, two port BC1.2 detection and a Battery Monitor. Document the DT bindings for BD99954 Signed-off-by: Matti Vaittinen Reviewed-by: Rob Herring Reviewed-by: Sebastian Reichel --- No changes since v9 .../bindings/power/supply/rohm,bd99954.yaml | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/rohm,bd99954.yaml diff --git a/Documentation/devicetree/bindings/power/supply/rohm,bd99954.yaml b/Documentation/devicetree/bindings/power/supply/rohm,bd99954.yaml new file mode 100644 index 000000000000..7e0f73a898c7 --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/rohm,bd99954.yaml @@ -0,0 +1,155 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/supply/rohm,bd99954.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ROHM BD99954 Battery charger + +maintainers: + - Matti Vaittinen + - Markus Laine + - Mikko Mutanen + +description: | + The ROHM BD99954 is a Battery Management LSI for 1-4 cell Lithium-Ion + secondary battery intended to be used in space-constraint equipment such + as Low profile Notebook PC, Tablets and other applications. BD99954 + provides a Dual-source Battery Charger, two port BC1.2 detection and a + Battery Monitor. + + +properties: + compatible: + const: rohm,bd99954 +# +# The battery charging profile of BD99954. +# +# Curve (1) represents charging current. +# Curve (2) represents battery voltage. +# +# The BD99954 data sheet divides charging to three phases. +# a) Trickle-charge with constant current (8). +# b) pre-charge with constant current (6) +# c) fast-charge with: +# First a constant current (5) phase (CC) +# Then constant voltage (CV) phase (after the battery voltage has reached +# target level - until charging current has dropped to termination +# level (7) +# +# V ^ ^ I +# . . +# . . +# (4)- -.- - - - - - - - - - - - - - +++++++++++++++++++++++++++. +# . / . +# . ++++++/++ - - - - - - - - - - - - -.- - (5) +# . + / + . +# . + - -- . +# . + - + . +# . +.- -: . +# . .+ +` . +# . .- + | `/ . +# . .." + .: . +# . -" + -- . +# . (2) ..." + | :- . +# . ..."" + -: . +# (3)- -.-.""- - - - -+++++++++ - - - - - - -.:- - - - - - - - - .- - (6) +# . + `:. . +# . + | -: . +# . + -: . +# . + .. . +# . (1) + | "+++- - - -.- - (7) +# -++++++++++++++- - - - - - - - - - - - - - - - - + - - - .- - (8) +# . + - +# -------------------------------------------------+++++++++--> +# | | | CC | CV | +# | --trickle-- | -pre- | ---------fast----------- | +# +# The charger uses the following battery properties +# - trickle-charge-current-microamp: +# Current used at trickle-charge phase (8 in above chart) +# minimum: 64000 +# maximum: 1024000 +# multipleOf: 64000 +# - precharge-current-microamp: +# Current used at pre-charge phase (6 in above chart) +# minimum: 64000 +# maximum: 1024000 +# multipleOf: 64000 +# - constant-charge-current-max-microamp +# Current used at fast charge constant current phase (5 in above chart) +# minimum: 64000 +# maximum: 1024000 +# multipleOf: 64000 +# - constant-charge-voltage-max-microvolt +# The constant voltage used in fast charging phase (4 in above chart) +# minimum: 2560000 +# maximum: 19200000 +# multipleOf: 16000 +# - precharge-upper-limit-microvolt +# charging mode is changed from trickle charging to pre-charging +# when battery voltage exceeds this limit voltage (3 in above chart) +# minimum: 2048000 +# maximum: 19200000 +# multipleOf: 64000 +# - re-charge-voltage-microvolt +# minimum: 2560000 +# maximum: 19200000 +# multipleOf: 16000 +# re-charging is automatically started when battry has been discharging +# to the point where the battery voltage drops below this limit +# - over-voltage-threshold-microvolt +# battery is expected to be faulty if battery voltage exceeds this limit. +# Charger will then enter to a "battery faulty" -state +# minimum: 2560000 +# maximum: 19200000 +# multipleOf: 16000 +# - charge-term-current-microamp +# minimum: 0 +# maximum: 1024000 +# multipleOf: 64000 +# a charge cycle terminates when the battery voltage is above recharge +# threshold, and the current is below this setting (7 in above chart) +# See also Documentation/devicetree/bindings/power/supply/battery.txt + + monitored-battery: + description: + phandle of battery characteristics devicetree node + + rohm,vsys-regulation-microvolt: + description: system specific lower limit for system voltage. + minimum: 2560000 + maximum: 19200000 + multipleOf: 64000 + + rohm,vbus-input-current-limit-microamp: + description: system specific VBUS input current limit (in microamps). + minimum: 32000 + maximum: 16352000 + multipleOf: 32000 + + rohm,vcc-input-current-limit-microamp: + description: system specific VCC/VACP input current limit (in microamps). + minimum: 32000 + maximum: 16352000 + multipleOf: 32000 + +required: + - compatible + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + charger@9 { + compatible = "rohm,bd99954"; + monitored-battery = <&battery>; + reg = <0x9>; + interrupt-parent = <&gpio1>; + interrupts = <29 8>; + rohm,vsys-regulation-microvolt = <8960000>; + rohm,vbus-input-current-limit-microamp = <1472000>; + rohm,vcc-input-current-limit-microamp = <1472000>; + }; + }; From patchwork Wed Apr 29 07:04:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516111 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 35E7192A for ; Wed, 29 Apr 2020 07:05:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A6AE2076B for ; Wed, 29 Apr 2020 07:05:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726426AbgD2HFk (ORCPT ); Wed, 29 Apr 2020 03:05:40 -0400 Received: from mail-lf1-f46.google.com ([209.85.167.46]:43198 "EHLO mail-lf1-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726274AbgD2HFj (ORCPT ); Wed, 29 Apr 2020 03:05:39 -0400 Received: by mail-lf1-f46.google.com with SMTP id 188so714416lfa.10; Wed, 29 Apr 2020 00:05:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=v0AlrHVcMaN9YX/0YTzDZuf1gRmdxjs5BEYRWY3uGi0=; b=B5CaB0eZqCUaWRoeBywARlfKoGeikrghk4lm7mKt358X+0DmjwU4pcK/1D6bVAQYCi kdk5rx5SYH8W5MEDIEGvJHrl13dqrxOW27GIQPVzpOC5EUsmduQvCCJqmBGAlgWpEXWD KNkvo2czz+ZAVRrV1euqa35/xt0gkYx8+HwcMDP9ocjan6vUq8zs6R9hhgi6dJGPz85M 71v+fyRj5mNfBC1oyScDEql1swjnvZDidP2fh74mXpQNOWvSaasnbpvRDco4SxV7tiyp UAg30czoLhbAbpqz5nAyYaa7wgXcxyxA06eC/nP46C0DcvzfizjiAsGHk8KfcqTQzpt7 5sqw== X-Gm-Message-State: AGi0Pub5am8IlYOqKhmoo0VT5kKzYZQzVfuAV9oJbxZ+oFneRBjnV5XH 7F8RX0XR6TUpRzMjh5WeDw8= X-Google-Smtp-Source: APiQypKyCBIg4CBaPmPSTyY6kvUlAM1j66PX/YqQOu38JS1nucJBm8nSdK0pd+WJzMTT6fIrWAKS4g== X-Received: by 2002:a19:5f4e:: with SMTP id a14mr21972164lfj.57.1588143929109; Wed, 29 Apr 2020 00:05:29 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id 25sm1773574lft.68.2020.04.29.00.05.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2020 00:05:28 -0700 (PDT) Date: Wed, 29 Apr 2020 10:04:43 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 09/11] power: supply: Support ROHM bd99954 charger Message-ID: <276118646b6a406215dab098ec49290c77a2c162.1586925868.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The ROHM BD99954 is a Battery Management LSI for 1-4 cell Lithium-Ion secondary battery intended to be used in space-constraint equipment such as Low profile Notebook PC, Tablets and other applications. BD99954 provides a Dual-source Battery Charger, two port BC1.2 detection and a Battery Monitor. Support ROHM BD99954 Charger IC. Signed-off-by: Matti Vaittinen Reviewed-by: Andy Shevchenko --- No changes since v9 drivers/power/supply/Kconfig | 9 + drivers/power/supply/Makefile | 1 + drivers/power/supply/bd99954-charger.c | 1142 ++++++++++++++++++++++++ drivers/power/supply/bd99954-charger.h | 1075 ++++++++++++++++++++++ 4 files changed, 2227 insertions(+) create mode 100644 drivers/power/supply/bd99954-charger.c create mode 100644 drivers/power/supply/bd99954-charger.h diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 9f19636db922..436680ee8523 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -702,6 +702,15 @@ config CHARGER_BD70528 information and altering charger configurations from charger block of the ROHM BD70528 Power Management IC. +config CHARGER_BD99954 + tristate "ROHM bd99954 charger driver" + depends on I2C + select LINEAR_RANGES + help + Say Y here to enable support for getting battery and charger + information and altering charger configurations from the ROHM + BD99954 charger IC. + config CHARGER_WILCO tristate "Wilco EC based charger for ChromeOS" depends on WILCO_EC diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index 6c7da920ea83..eed11ca1bd7d 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -91,4 +91,5 @@ obj-$(CONFIG_CHARGER_SC2731) += sc2731_charger.o obj-$(CONFIG_FUEL_GAUGE_SC27XX) += sc27xx_fuel_gauge.o obj-$(CONFIG_CHARGER_UCS1002) += ucs1002_power.o obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o +obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o diff --git a/drivers/power/supply/bd99954-charger.c b/drivers/power/supply/bd99954-charger.c new file mode 100644 index 000000000000..3da39c7293e3 --- /dev/null +++ b/drivers/power/supply/bd99954-charger.c @@ -0,0 +1,1142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ROHM BD99954 charger driver + * + * Copyright (C) 2020 Rohm Semiconductors + * Originally written by: + * Mikko Mutanen + * Markus Laine + * Bugs added by: + * Matti Vaittinen + */ + +/* + * The battery charging profile of BD99954. + * + * Curve (1) represents charging current. + * Curve (2) represents battery voltage. + * + * The BD99954 data sheet divides charging to three phases. + * a) Trickle-charge with constant current (8). + * b) pre-charge with constant current (6) + * c) fast-charge, first with constant current (5) phase. After + * the battery voltage has reached target level (4) we have constant + * voltage phase until charging current has dropped to termination + * level (7) + * + * V ^ ^ I + * . . + * . . + *(4)` `.` ` ` ` ` ` ` ` ` ` ` ` ` ` ----------------------------. + * . :/ . + * . o----+/:/ ` ` ` ` ` ` ` ` ` ` ` ` `.` ` (5) + * . + :: + . + * . + /- -- . + * . +`/- + . + * . o/- -: . + * . .s. +` . + * . .--+ `/ . + * . ..`` + .: . + * . -` + -- . + * . (2) ...`` + :- . + * . ...`` + -: . + *(3)` `.`."" ` ` ` `+-------- ` ` ` ` ` ` `.:` ` ` ` ` ` ` ` ` .` ` (6) + * . + `:. . + * . + -: . + * . + -:. . + * . + .--. . + * . (1) + `.+` ` ` `.` ` (7) + * -..............` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` + ` ` ` .` ` (8) + * . + - + * -------------------------------------------------+++++++++--> + * | trickle | pre | fast | + * + * Details of DT properties for different limits can be found from BD99954 + * device tree binding documentation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bd99954-charger.h" + +struct battery_data { + u16 precharge_current; /* Trickle-charge Current */ + u16 fc_reg_voltage; /* Fast Charging Regulation Voltage */ + u16 voltage_min; + u16 voltage_max; +}; + +/* Initial field values, converted to initial register values */ +struct bd9995x_init_data { + u16 vsysreg_set; /* VSYS Regulation Setting */ + u16 ibus_lim_set; /* VBUS input current limitation */ + u16 icc_lim_set; /* VCC/VACP Input Current Limit Setting */ + u16 itrich_set; /* Trickle-charge Current Setting */ + u16 iprech_set; /* Pre-Charge Current Setting */ + u16 ichg_set; /* Fast-Charge constant current */ + u16 vfastchg_reg_set1; /* Fast Charging Regulation Voltage */ + u16 vprechg_th_set; /* Pre-charge Voltage Threshold Setting */ + u16 vrechg_set; /* Re-charge Battery Voltage Setting */ + u16 vbatovp_set; /* Battery Over Voltage Threshold Setting */ + u16 iterm_set; /* Charging termination current */ +}; + +struct bd9995x_state { + u8 online; + u16 chgstm_status; + u16 vbat_vsys_status; + u16 vbus_vcc_status; +}; + +struct bd9995x_device { + struct i2c_client *client; + struct device *dev; + struct power_supply *charger; + + struct regmap *rmap; + struct regmap_field *rmap_fields[F_MAX_FIELDS]; + + int chip_id; + int chip_rev; + struct bd9995x_init_data init_data; + struct bd9995x_state state; + + struct mutex lock; /* Protect state data */ +}; + +static const struct regmap_range bd9995x_readonly_reg_ranges[] = { + regmap_reg_range(CHGSTM_STATUS, SEL_ILIM_VAL), + regmap_reg_range(IOUT_DACIN_VAL, IOUT_DACIN_VAL), + regmap_reg_range(VCC_UCD_STATUS, VCC_IDD_STATUS), + regmap_reg_range(VBUS_UCD_STATUS, VBUS_IDD_STATUS), + regmap_reg_range(CHIP_ID, CHIP_REV), + regmap_reg_range(SYSTEM_STATUS, SYSTEM_STATUS), + regmap_reg_range(IBATP_VAL, VBAT_AVE_VAL), + regmap_reg_range(VTH_VAL, EXTIADP_AVE_VAL), +}; + +static const struct regmap_access_table bd9995x_writeable_regs = { + .no_ranges = bd9995x_readonly_reg_ranges, + .n_no_ranges = ARRAY_SIZE(bd9995x_readonly_reg_ranges), +}; + +static const struct regmap_range bd9995x_volatile_reg_ranges[] = { + regmap_reg_range(CHGSTM_STATUS, WDT_STATUS), + regmap_reg_range(VCC_UCD_STATUS, VCC_IDD_STATUS), + regmap_reg_range(VBUS_UCD_STATUS, VBUS_IDD_STATUS), + regmap_reg_range(INT0_STATUS, INT7_STATUS), + regmap_reg_range(SYSTEM_STATUS, SYSTEM_CTRL_SET), + regmap_reg_range(IBATP_VAL, EXTIADP_AVE_VAL), /* Measurement regs */ +}; + +static const struct regmap_access_table bd9995x_volatile_regs = { + .yes_ranges = bd9995x_volatile_reg_ranges, + .n_yes_ranges = ARRAY_SIZE(bd9995x_volatile_reg_ranges), +}; + +static const struct regmap_range_cfg regmap_range_cfg[] = { + { + .selector_reg = MAP_SET, + .selector_mask = 0xFFFF, + .selector_shift = 0, + .window_start = 0, + .window_len = 0x100, + .range_min = 0 * 0x100, + .range_max = 3 * 0x100, + }, +}; + +static const struct regmap_config bd9995x_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_stride = 1, + + .max_register = 3 * 0x100, + .cache_type = REGCACHE_RBTREE, + + .ranges = regmap_range_cfg, + .num_ranges = ARRAY_SIZE(regmap_range_cfg), + .val_format_endian = REGMAP_ENDIAN_LITTLE, + .wr_table = &bd9995x_writeable_regs, + .volatile_table = &bd9995x_volatile_regs, +}; + +enum bd9995x_chrg_fault { + CHRG_FAULT_NORMAL, + CHRG_FAULT_INPUT, + CHRG_FAULT_THERMAL_SHUTDOWN, + CHRG_FAULT_TIMER_EXPIRED, +}; + +static int bd9995x_get_prop_batt_health(struct bd9995x_device *bd) +{ + int ret, tmp; + + ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp); + if (ret) + return POWER_SUPPLY_HEALTH_UNKNOWN; + + /* TODO: Check these against datasheet page 34 */ + + switch (tmp) { + case ROOM: + return POWER_SUPPLY_HEALTH_GOOD; + case HOT1: + case HOT2: + case HOT3: + return POWER_SUPPLY_HEALTH_OVERHEAT; + case COLD1: + case COLD2: + return POWER_SUPPLY_HEALTH_COLD; + case TEMP_DIS: + case BATT_OPEN: + default: + return POWER_SUPPLY_HEALTH_UNKNOWN; + } +} + +static int bd9995x_get_prop_charge_type(struct bd9995x_device *bd) +{ + int ret, tmp; + + ret = regmap_field_read(bd->rmap_fields[F_CHGSTM_STATE], &tmp); + if (ret) + return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; + + switch (tmp) { + case CHGSTM_TRICKLE_CHARGE: + case CHGSTM_PRE_CHARGE: + return POWER_SUPPLY_CHARGE_TYPE_TRICKLE; + case CHGSTM_FAST_CHARGE: + return POWER_SUPPLY_CHARGE_TYPE_FAST; + case CHGSTM_TOP_OFF: + case CHGSTM_DONE: + case CHGSTM_SUSPEND: + return POWER_SUPPLY_CHARGE_TYPE_NONE; + default: /* Rest of the states are error related, no charging */ + return POWER_SUPPLY_CHARGE_TYPE_NONE; + } +} + +static bool bd9995x_get_prop_batt_present(struct bd9995x_device *bd) +{ + int ret, tmp; + + ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp); + if (ret) + return false; + + return tmp != BATT_OPEN; +} + +static int bd9995x_get_prop_batt_voltage(struct bd9995x_device *bd) +{ + int ret, tmp; + + ret = regmap_field_read(bd->rmap_fields[F_VBAT_VAL], &tmp); + if (ret) + return 0; + + tmp = min(tmp, 19200); + + return tmp * 1000; +} + +static int bd9995x_get_prop_batt_current(struct bd9995x_device *bd) +{ + int ret, tmp; + + ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp); + if (ret) + return 0; + + return tmp * 1000; +} + +#define DEFAULT_BATTERY_TEMPERATURE 250 + +static int bd9995x_get_prop_batt_temp(struct bd9995x_device *bd) +{ + int ret, tmp; + + ret = regmap_field_read(bd->rmap_fields[F_THERM_VAL], &tmp); + if (ret) + return DEFAULT_BATTERY_TEMPERATURE; + + return (200 - tmp) * 10; +} + +static int bd9995x_power_supply_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret, tmp; + struct bd9995x_device *bd = power_supply_get_drvdata(psy); + struct bd9995x_state state; + + mutex_lock(&bd->lock); + state = bd->state; + mutex_unlock(&bd->lock); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + switch (state.chgstm_status) { + case CHGSTM_TRICKLE_CHARGE: + case CHGSTM_PRE_CHARGE: + case CHGSTM_FAST_CHARGE: + case CHGSTM_TOP_OFF: + val->intval = POWER_SUPPLY_STATUS_CHARGING; + break; + + case CHGSTM_DONE: + val->intval = POWER_SUPPLY_STATUS_FULL; + break; + + case CHGSTM_SUSPEND: + case CHGSTM_TEMPERATURE_ERROR_1: + case CHGSTM_TEMPERATURE_ERROR_2: + case CHGSTM_TEMPERATURE_ERROR_3: + case CHGSTM_TEMPERATURE_ERROR_4: + case CHGSTM_TEMPERATURE_ERROR_5: + case CHGSTM_TEMPERATURE_ERROR_6: + case CHGSTM_TEMPERATURE_ERROR_7: + case CHGSTM_THERMAL_SHUT_DOWN_1: + case CHGSTM_THERMAL_SHUT_DOWN_2: + case CHGSTM_THERMAL_SHUT_DOWN_3: + case CHGSTM_THERMAL_SHUT_DOWN_4: + case CHGSTM_THERMAL_SHUT_DOWN_5: + case CHGSTM_THERMAL_SHUT_DOWN_6: + case CHGSTM_THERMAL_SHUT_DOWN_7: + case CHGSTM_BATTERY_ERROR: + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + break; + + default: + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + break; + } + break; + + case POWER_SUPPLY_PROP_MANUFACTURER: + val->strval = BD9995X_MANUFACTURER; + break; + + case POWER_SUPPLY_PROP_ONLINE: + val->intval = state.online; + break; + + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp); + if (ret) + return ret; + val->intval = tmp * 1000; + break; + + case POWER_SUPPLY_PROP_CHARGE_AVG: + ret = regmap_field_read(bd->rmap_fields[F_IBATP_AVE_VAL], &tmp); + if (ret) + return ret; + val->intval = tmp * 1000; + break; + + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + /* + * Currently the DT uses this property to give the + * target current for fast-charging constant current phase. + * I think it is correct in a sense. + * + * Yet, this prop we read and return here is the programmed + * safety limit for combined input currents. This feels + * also correct in a sense. + * + * However, this results a mismatch to DT value and value + * read from sysfs. + */ + ret = regmap_field_read(bd->rmap_fields[F_SEL_ILIM_VAL], &tmp); + if (ret) + return ret; + val->intval = tmp * 1000; + break; + + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + if (!state.online) { + val->intval = 0; + break; + } + + ret = regmap_field_read(bd->rmap_fields[F_VFASTCHG_REG_SET1], + &tmp); + if (ret) + return ret; + + /* + * The actual range : 2560 to 19200 mV. No matter what the + * register says + */ + val->intval = clamp_val(tmp << 4, 2560, 19200); + val->intval *= 1000; + break; + + case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: + ret = regmap_field_read(bd->rmap_fields[F_ITERM_SET], &tmp); + if (ret) + return ret; + /* Start step is 64 mA */ + val->intval = tmp << 6; + /* Maximum is 1024 mA - no matter what register says */ + val->intval = min(val->intval, 1024); + val->intval *= 1000; + break; + + /* Battery properties which we access through charger */ + case POWER_SUPPLY_PROP_PRESENT: + val->intval = bd9995x_get_prop_batt_present(bd); + break; + + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = bd9995x_get_prop_batt_voltage(bd); + break; + + case POWER_SUPPLY_PROP_CURRENT_NOW: + val->intval = bd9995x_get_prop_batt_current(bd); + break; + + case POWER_SUPPLY_PROP_CHARGE_TYPE: + val->intval = bd9995x_get_prop_charge_type(bd); + break; + + case POWER_SUPPLY_PROP_HEALTH: + val->intval = bd9995x_get_prop_batt_health(bd); + break; + + case POWER_SUPPLY_PROP_TEMP: + val->intval = bd9995x_get_prop_batt_temp(bd); + break; + + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = "bd99954"; + break; + + default: + return -EINVAL; + + } + + return 0; +} + +static int bd9995x_get_chip_state(struct bd9995x_device *bd, + struct bd9995x_state *state) +{ + int i, ret, tmp; + struct { + struct regmap_field *id; + u16 *data; + } state_fields[] = { + { + bd->rmap_fields[F_CHGSTM_STATE], &state->chgstm_status, + }, { + bd->rmap_fields[F_VBAT_VSYS_STATUS], + &state->vbat_vsys_status, + }, { + bd->rmap_fields[F_VBUS_VCC_STATUS], + &state->vbus_vcc_status, + }, + }; + + + for (i = 0; i < ARRAY_SIZE(state_fields); i++) { + ret = regmap_field_read(state_fields[i].id, &tmp); + if (ret) + return ret; + + *state_fields[i].data = tmp; + } + + if (state->vbus_vcc_status & STATUS_VCC_DET || + state->vbus_vcc_status & STATUS_VBUS_DET) + state->online = 1; + else + state->online = 0; + + return 0; +} + +static irqreturn_t bd9995x_irq_handler_thread(int irq, void *private) +{ + struct bd9995x_device *bd = private; + int ret, status, mask, i; + unsigned long tmp; + struct bd9995x_state state; + + /* + * The bd9995x does not seem to generate big amount of interrupts. + * The logic regarding which interrupts can cause relevant + * status changes seem to be pretty complex. + * + * So lets implement really simple and hopefully bullet-proof handler: + * It does not really matter which IRQ we handle, we just go and + * re-read all interesting statuses + give the framework a nudge. + * + * Other option would be building a _complex_ and error prone logic + * trying to decide what could have been changed (resulting this IRQ + * we are now handling). During the normal operation the BD99954 does + * not seem to be generating much of interrupts so benefit from such + * logic would probably be minimal. + */ + + ret = regmap_read(bd->rmap, INT0_STATUS, &status); + if (ret) { + dev_err(bd->dev, "Failed to read IRQ status\n"); + return IRQ_NONE; + } + + ret = regmap_field_read(bd->rmap_fields[F_INT0_SET], &mask); + if (ret) { + dev_err(bd->dev, "Failed to read IRQ mask\n"); + return IRQ_NONE; + } + + /* Handle only IRQs that are not masked */ + status &= mask; + tmp = status; + + /* Lowest bit does not represent any sub-registers */ + tmp >>= 1; + + /* + * Mask and ack IRQs we will handle (+ the idiot bit) + */ + ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], 0); + if (ret) { + dev_err(bd->dev, "Failed to mask F_INT0\n"); + return IRQ_NONE; + } + + ret = regmap_write(bd->rmap, INT0_STATUS, status); + if (ret) { + dev_err(bd->dev, "Failed to ack F_INT0\n"); + goto err_umask; + } + + for_each_set_bit(i, &tmp, 7) { + int sub_status, sub_mask; + int sub_status_reg[] = { + INT1_STATUS, INT2_STATUS, INT3_STATUS, INT4_STATUS, + INT5_STATUS, INT6_STATUS, INT7_STATUS, + }; + struct regmap_field *sub_mask_f[] = { + bd->rmap_fields[F_INT1_SET], + bd->rmap_fields[F_INT2_SET], + bd->rmap_fields[F_INT3_SET], + bd->rmap_fields[F_INT4_SET], + bd->rmap_fields[F_INT5_SET], + bd->rmap_fields[F_INT6_SET], + bd->rmap_fields[F_INT7_SET], + }; + + /* Clear sub IRQs */ + ret = regmap_read(bd->rmap, sub_status_reg[i], &sub_status); + if (ret) { + dev_err(bd->dev, "Failed to read IRQ sub-status\n"); + goto err_umask; + } + + ret = regmap_field_read(sub_mask_f[i], &sub_mask); + if (ret) { + dev_err(bd->dev, "Failed to read IRQ sub-mask\n"); + goto err_umask; + } + + /* Ack active sub-statuses */ + sub_status &= sub_mask; + + ret = regmap_write(bd->rmap, sub_status_reg[i], sub_status); + if (ret) { + dev_err(bd->dev, "Failed to ack sub-IRQ\n"); + goto err_umask; + } + } + + ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask); + if (ret) + /* May as well retry once */ + goto err_umask; + + /* Read whole chip state */ + ret = bd9995x_get_chip_state(bd, &state); + if (ret < 0) { + dev_err(bd->dev, "Failed to read chip state\n"); + } else { + mutex_lock(&bd->lock); + bd->state = state; + mutex_unlock(&bd->lock); + + power_supply_changed(bd->charger); + } + + return IRQ_HANDLED; + +err_umask: + ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask); + if (ret) + dev_err(bd->dev, + "Failed to un-mask F_INT0 - IRQ permanently disabled\n"); + + return IRQ_NONE; +} + +static int __bd9995x_chip_reset(struct bd9995x_device *bd) +{ + int ret, state; + int rst_check_counter = 10; + u16 tmp = ALLRST | OTPLD; + + ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2); + if (ret < 0) + return ret; + + do { + ret = regmap_field_read(bd->rmap_fields[F_OTPLD_STATE], &state); + if (ret) + return ret; + + msleep(10); + } while (state == 0 && --rst_check_counter); + + if (!rst_check_counter) { + dev_err(bd->dev, "chip reset not completed\n"); + return -ETIMEDOUT; + } + + tmp = 0; + ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2); + + return ret; +} + +static int bd9995x_hw_init(struct bd9995x_device *bd) +{ + int ret; + int i; + struct bd9995x_state state; + struct bd9995x_init_data *id = &bd->init_data; + + const struct { + enum bd9995x_fields id; + u16 value; + } init_data[] = { + /* Enable the charging trigger after SDP charger attached */ + {F_SDP_CHG_TRIG_EN, 1}, + /* Enable charging trigger after SDP charger attached */ + {F_SDP_CHG_TRIG, 1}, + /* Disable charging trigger by BC1.2 detection */ + {F_VBUS_BC_DISEN, 1}, + /* Disable charging trigger by BC1.2 detection */ + {F_VCC_BC_DISEN, 1}, + /* Disable automatic limitation of the input current */ + {F_ILIM_AUTO_DISEN, 1}, + /* Select current limitation when SDP charger attached*/ + {F_SDP_500_SEL, 1}, + /* Select current limitation when DCP charger attached */ + {F_DCP_2500_SEL, 1}, + {F_VSYSREG_SET, id->vsysreg_set}, + /* Activate USB charging and DC/DC converter */ + {F_USB_SUS, 0}, + /* DCDC clock: 1200 kHz*/ + {F_DCDC_CLK_SEL, 3}, + /* Enable charging */ + {F_CHG_EN, 1}, + /* Disable Input current Limit setting voltage measurement */ + {F_EXTIADPEN, 0}, + /* Disable input current limiting */ + {F_VSYS_PRIORITY, 1}, + {F_IBUS_LIM_SET, id->ibus_lim_set}, + {F_ICC_LIM_SET, id->icc_lim_set}, + /* Charge Termination Current Setting to 0*/ + {F_ITERM_SET, id->iterm_set}, + /* Trickle-charge Current Setting */ + {F_ITRICH_SET, id->itrich_set}, + /* Pre-charge Current setting */ + {F_IPRECH_SET, id->iprech_set}, + /* Fast Charge Current for constant current phase */ + {F_ICHG_SET, id->ichg_set}, + /* Fast Charge Voltage Regulation Setting */ + {F_VFASTCHG_REG_SET1, id->vfastchg_reg_set1}, + /* Set Pre-charge Voltage Threshold for trickle charging. */ + {F_VPRECHG_TH_SET, id->vprechg_th_set}, + {F_VRECHG_SET, id->vrechg_set}, + {F_VBATOVP_SET, id->vbatovp_set}, + /* Reverse buck boost voltage Setting */ + {F_VRBOOST_SET, 0}, + /* Disable fast-charging watchdog */ + {F_WDT_FST, 0}, + /* Disable pre-charging watchdog */ + {F_WDT_PRE, 0}, + /* Power save off */ + {F_POWER_SAVE_MODE, 0}, + {F_INT1_SET, INT1_ALL}, + {F_INT2_SET, INT2_ALL}, + {F_INT3_SET, INT3_ALL}, + {F_INT4_SET, INT4_ALL}, + {F_INT5_SET, INT5_ALL}, + {F_INT6_SET, INT6_ALL}, + {F_INT7_SET, INT7_ALL}, + }; + + /* + * Currently we initialize charger to a known state at startup. + * If we want to allow for example the boot code to initialize + * charger we should get rid of this. + */ + ret = __bd9995x_chip_reset(bd); + if (ret < 0) + return ret; + + /* Initialize currents/voltages and other parameters */ + for (i = 0; i < ARRAY_SIZE(init_data); i++) { + ret = regmap_field_write(bd->rmap_fields[init_data[i].id], + init_data[i].value); + if (ret) { + dev_err(bd->dev, "failed to initialize charger (%d)\n", + ret); + return ret; + } + } + + ret = bd9995x_get_chip_state(bd, &state); + if (ret < 0) + return ret; + + mutex_lock(&bd->lock); + bd->state = state; + mutex_unlock(&bd->lock); + + return 0; +} + +static enum power_supply_property bd9995x_power_supply_props[] = { + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, + POWER_SUPPLY_PROP_CHARGE_AVG, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, + POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, + /* Battery props we access through charger */ + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_TYPE, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_MODEL_NAME, +}; + +static const struct power_supply_desc bd9995x_power_supply_desc = { + .name = "bd9995x-charger", + .type = POWER_SUPPLY_TYPE_USB, + .properties = bd9995x_power_supply_props, + .num_properties = ARRAY_SIZE(bd9995x_power_supply_props), + .get_property = bd9995x_power_supply_get_property, +}; + +/* + * Limit configurations for vbus-input-current and vcc-vacp-input-current + * Minimum limit is 0 uA. Max is 511 * 32000 uA = 16352000 uA. This is + * configured by writing a register so that each increment in register + * value equals to 32000 uA limit increment. + * + * Eg, value 0x0 is limit 0, value 0x1 is limit 32000, ... + * Describe the setting in linear_range table. + */ +static const struct linear_range input_current_limit_ranges[] = { + { + .min = 0, + .step = 32000, + .min_sel = 0x0, + .max_sel = 0x1ff, + }, +}; + +/* Possible trickle, pre-charging and termination current values */ +static const struct linear_range charging_current_ranges[] = { + { + .min = 0, + .step = 64000, + .min_sel = 0x0, + .max_sel = 0x10, + }, { + .min = 1024000, + .step = 0, + .min_sel = 0x11, + .max_sel = 0x1f, + }, +}; + +/* + * Fast charging voltage regulation, starting re-charging limit + * and battery over voltage protection have same possible values + */ +static const struct linear_range charge_voltage_regulation_ranges[] = { + { + .min = 2560000, + .step = 0, + .min_sel = 0, + .max_sel = 0xA0, + }, { + .min = 2560000, + .step = 16000, + .min_sel = 0xA0, + .max_sel = 0x4B0, + }, { + .min = 19200000, + .step = 0, + .min_sel = 0x4B0, + .max_sel = 0x7FF, + }, +}; + +/* Possible VSYS voltage regulation values */ +static const struct linear_range vsys_voltage_regulation_ranges[] = { + { + .min = 2560000, + .step = 0, + .min_sel = 0, + .max_sel = 0x28, + }, { + .min = 2560000, + .step = 64000, + .min_sel = 0x28, + .max_sel = 0x12C, + }, { + .min = 19200000, + .step = 0, + .min_sel = 0x12C, + .max_sel = 0x1FF, + }, +}; + +/* Possible settings for switching from trickle to pre-charging limits */ +static const struct linear_range trickle_to_pre_threshold_ranges[] = { + { + .min = 2048000, + .step = 0, + .min_sel = 0, + .max_sel = 0x20, + }, { + .min = 2048000, + .step = 64000, + .min_sel = 0x20, + .max_sel = 0x12C, + }, { + .min = 19200000, + .step = 0, + .min_sel = 0x12C, + .max_sel = 0x1FF + } +}; + +/* Possible current values for fast-charging constant current phase */ +static const struct linear_range fast_charge_current_ranges[] = { + { + .min = 0, + .step = 64000, + .min_sel = 0, + .max_sel = 0xFF, + } +}; + +struct battery_init { + const char *name; + int *info_data; + const struct linear_range *range; + int ranges; + u16 *data; +}; + +struct dt_init { + char *prop; + const struct linear_range *range; + int ranges; + u16 *data; +}; + +static int bd9995x_fw_probe(struct bd9995x_device *bd) +{ + int ret; + struct power_supply_battery_info info; + u32 property; + int i; + int regval; + bool found; + struct bd9995x_init_data *init = &bd->init_data; + struct battery_init battery_inits[] = { + { + .name = "trickle-charging current", + .info_data = &info.tricklecharge_current_ua, + .range = &charging_current_ranges[0], + .ranges = 2, + .data = &init->itrich_set, + }, { + .name = "pre-charging current", + .info_data = &info.precharge_current_ua, + .range = &charging_current_ranges[0], + .ranges = 2, + .data = &init->iprech_set, + }, { + .name = "pre-to-trickle charge voltage threshold", + .info_data = &info.precharge_voltage_max_uv, + .range = &trickle_to_pre_threshold_ranges[0], + .ranges = 2, + .data = &init->vprechg_th_set, + }, { + .name = "charging termination current", + .info_data = &info.charge_term_current_ua, + .range = &charging_current_ranges[0], + .ranges = 2, + .data = &init->iterm_set, + }, { + .name = "charging re-start voltage", + .info_data = &info.charge_restart_voltage_uv, + .range = &charge_voltage_regulation_ranges[0], + .ranges = 2, + .data = &init->vrechg_set, + }, { + .name = "battery overvoltage limit", + .info_data = &info.overvoltage_limit_uv, + .range = &charge_voltage_regulation_ranges[0], + .ranges = 2, + .data = &init->vbatovp_set, + }, { + .name = "fast-charging max current", + .info_data = &info.constant_charge_current_max_ua, + .range = &fast_charge_current_ranges[0], + .ranges = 1, + .data = &init->ichg_set, + }, { + .name = "fast-charging voltage", + .info_data = &info.constant_charge_voltage_max_uv, + .range = &charge_voltage_regulation_ranges[0], + .ranges = 2, + .data = &init->vfastchg_reg_set1, + }, + }; + struct dt_init props[] = { + { + .prop = "rohm,vsys-regulation-microvolt", + .range = &vsys_voltage_regulation_ranges[0], + .ranges = 2, + .data = &init->vsysreg_set, + }, { + .prop = "rohm,vbus-input-current-limit-microamp", + .range = &input_current_limit_ranges[0], + .ranges = 1, + .data = &init->ibus_lim_set, + }, { + .prop = "rohm,vcc-input-current-limit-microamp", + .range = &input_current_limit_ranges[0], + .ranges = 1, + .data = &init->icc_lim_set, + }, + }; + + /* + * The power_supply_get_battery_info() does not support getting values + * from ACPI. Let's fix it if ACPI is required here. + */ + ret = power_supply_get_battery_info(bd->charger, &info); + if (ret < 0) + return ret; + + for (i = 0; i < ARRAY_SIZE(battery_inits); i++) { + int val = *battery_inits[i].info_data; + const struct linear_range *range = battery_inits[i].range; + int ranges = battery_inits[i].ranges; + + if (val == -EINVAL) + continue; + + ret = linear_range_get_selector_low_array(range, ranges, val, + ®val, &found); + if (ret) { + dev_err(bd->dev, "Unsupported value for %s\n", + battery_inits[i].name); + + power_supply_put_battery_info(bd->charger, &info); + return -EINVAL; + } + if (!found) { + dev_warn(bd->dev, + "Unsupported value for %s - using smaller\n", + battery_inits[i].name); + } + *(battery_inits[i].data) = regval; + } + + power_supply_put_battery_info(bd->charger, &info); + + for (i = 0; i < ARRAY_SIZE(props); i++) { + ret = device_property_read_u32(bd->dev, props[i].prop, + &property); + if (ret < 0) { + dev_err(bd->dev, "failed to read %s", props[i].prop); + + return ret; + } + + ret = linear_range_get_selector_low_array(props[i].range, + props[i].ranges, + property, ®val, + &found); + if (ret) { + dev_err(bd->dev, "Unsupported value for '%s'\n", + props[i].prop); + + return -EINVAL; + } + + if (!found) { + dev_warn(bd->dev, + "Unsupported value for '%s' - using smaller\n", + props[i].prop); + } + + *(props[i].data) = regval; + } + + return 0; +} + +void bd9995x_chip_reset(void *bd) +{ + __bd9995x_chip_reset(bd); +} + +static int bd9995x_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct bd9995x_device *bd; + struct power_supply_config psy_cfg = {}; + int ret; + int i; + + bd = devm_kzalloc(dev, sizeof(*bd), GFP_KERNEL); + if (!bd) + return -ENOMEM; + + bd->client = client; + bd->dev = dev; + psy_cfg.drv_data = bd; + psy_cfg.of_node = dev->of_node; + + mutex_init(&bd->lock); + + bd->rmap = devm_regmap_init_i2c(client, &bd9995x_regmap_config); + if (IS_ERR(bd->rmap)) { + dev_err(dev, "Failed to setup register access via i2c\n"); + return PTR_ERR(bd->rmap); + } + + for (i = 0; i < ARRAY_SIZE(bd9995x_reg_fields); i++) { + const struct reg_field *reg_fields = bd9995x_reg_fields; + + bd->rmap_fields[i] = devm_regmap_field_alloc(dev, bd->rmap, + reg_fields[i]); + if (IS_ERR(bd->rmap_fields[i])) { + dev_err(dev, "cannot allocate regmap field\n"); + return PTR_ERR(bd->rmap_fields[i]); + } + } + + i2c_set_clientdata(client, bd); + + ret = regmap_field_read(bd->rmap_fields[F_CHIP_ID], &bd->chip_id); + if (ret) { + dev_err(dev, "Cannot read chip ID.\n"); + return ret; + } + + if (bd->chip_id != BD99954_ID) { + dev_err(dev, "Chip with ID=0x%x, not supported!\n", + bd->chip_id); + return -ENODEV; + } + + ret = regmap_field_read(bd->rmap_fields[F_CHIP_REV], &bd->chip_rev); + if (ret) { + dev_err(dev, "Cannot read revision.\n"); + return ret; + } + + dev_info(bd->dev, "Found BD99954 chip rev %d\n", bd->chip_rev); + + /* + * We need to init the psy before we can call + * power_supply_get_battery_info() for it + */ + bd->charger = devm_power_supply_register(bd->dev, + &bd9995x_power_supply_desc, + &psy_cfg); + if (IS_ERR(bd->charger)) { + dev_err(dev, "Failed to register power supply\n"); + return PTR_ERR(bd->charger); + } + + ret = bd9995x_fw_probe(bd); + if (ret < 0) { + dev_err(dev, "Cannot read device properties.\n"); + return ret; + } + + ret = bd9995x_hw_init(bd); + if (ret < 0) { + dev_err(dev, "Cannot initialize the chip.\n"); + return ret; + } + + ret = devm_add_action_or_reset(dev, bd9995x_chip_reset, bd); + if (ret) + return ret; + + return devm_request_threaded_irq(dev, client->irq, NULL, + bd9995x_irq_handler_thread, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + BD9995X_IRQ_PIN, bd); +} + +static const struct of_device_id bd9995x_of_match[] = { + { .compatible = "rohm,bd99954", }, + { } +}; +MODULE_DEVICE_TABLE(of, bd9995x_of_match); + +static struct i2c_driver bd9995x_driver = { + .driver = { + .name = "bd9995x-charger", + .of_match_table = bd9995x_of_match, + }, + .probe_new = bd9995x_probe, +}; +module_i2c_driver(bd9995x_driver); + +MODULE_AUTHOR("Laine Markus "); +MODULE_DESCRIPTION("ROHM BD99954 charger driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/bd99954-charger.h b/drivers/power/supply/bd99954-charger.h new file mode 100644 index 000000000000..f58897925383 --- /dev/null +++ b/drivers/power/supply/bd99954-charger.h @@ -0,0 +1,1075 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 2020 ROHM Semiconductors */ +#ifndef BD99954_CHARGER_H +#define BD99954_CHARGER_H + +#include + +#define BD9995X_MANUFACTURER "Rohm Semiconductor" +#define BD9995X_IRQ_PIN "bd9995x_irq" + +#define BD9995X_VSYS_PRECHARGE_OFFSET_MV 200 + +#define BD99954_ID 0x346 +#define BD99955_ID 0x221 +#define BD99956_ID 0x331 + +/* Battery Charger Commands */ +#define CHARGING_CURRENT 0x14 +#define CHARGING_VOLTAGE 0x15 +#define PROTECT_SET 0x3E +#define MAP_SET 0x3F + +/* Extended commands */ +#define CHGSTM_STATUS 0x100 +#define VBAT_VSYS_STATUS 0x101 +#define VBUS_VCC_STATUS 0x102 +#define CHGOP_STATUS 0x103 +#define WDT_STATUS 0x104 +#define CUR_ILIM_VAL 0x105 +#define SEL_ILIM_VAL 0x106 +#define IBUS_LIM_SET 0x107 +#define ICC_LIM_SET 0x108 +#define IOTG_LIM_SET 0x109 +#define VIN_CTRL_SET 0x10A +#define CHGOP_SET1 0x10B +#define CHGOP_SET2 0x10C +#define VBUSCLPS_TH_SET 0x10D +#define VCCCLPS_TH_SET 0x10E +#define CHGWDT_SET 0x10F +#define BATTWDT_SET 0x110 +#define VSYSREG_SET 0x111 +#define VSYSVAL_THH_SET 0x112 +#define VSYSVAL_THL_SET 0x113 +#define ITRICH_SET 0x114 +#define IPRECH_SET 0x115 +#define ICHG_SET 0x116 +#define ITERM_SET 0x117 +#define VPRECHG_TH_SET 0x118 +#define VRBOOST_SET 0x119 +#define VFASTCHG_REG_SET1 0x11A +#define VFASTCHG_REG_SET2 0x11B +#define VFASTCHG_REG_SET3 0x11C +#define VRECHG_SET 0x11D +#define VBATOVP_SET 0x11E +#define IBATSHORT_SET 0x11F +#define PROCHOT_CTRL_SET 0x120 +#define PROCHOT_ICRIT_SET 0x121 +#define PROCHOT_INORM_SET 0x122 +#define PROCHOT_IDCHG_SET 0x123 +#define PROCHOT_VSYS_SET 0x124 +#define PMON_IOUT_CTRL_SET 0x125 +#define PMON_DACIN_VAL 0x126 +#define IOUT_DACIN_VAL 0x127 +#define VCC_UCD_SET 0x128 +#define VCC_UCD_STATUS 0x129 +#define VCC_IDD_STATUS 0x12A +#define VCC_UCD_FCTRL_SET 0x12B +#define VCC_UCD_FCTRL_EN 0x12C +#define VBUS_UCD_SET 0x130 +#define VBUS_UCD_STATUS 0x131 +#define VBUS_IDD_STATUS 0x132 +#define VBUS_UCD_FCTRL_SET 0x133 +#define VBUS_UCD_FCTRL_EN 0x134 +#define CHIP_ID 0x138 +#define CHIP_REV 0x139 +#define IC_SET1 0x13A +#define IC_SET2 0x13B +#define SYSTEM_STATUS 0x13C +#define SYSTEM_CTRL_SET 0x13D +#define VM_CTRL_SET 0x140 +#define THERM_WINDOW_SET1 0x141 +#define THERM_WINDOW_SET2 0x142 +#define THERM_WINDOW_SET3 0x143 +#define THERM_WINDOW_SET4 0x144 +#define THERM_WINDOW_SET5 0x145 +#define IBATP_TH_SET 0x146 +#define IBATM_TH_SET 0x147 +#define VBAT_TH_SET 0x148 +#define THERM_TH_SET 0x149 +#define IACP_TH_SET 0x14A +#define VACP_TH_SET 0x14B +#define VBUS_TH_SET 0x14C +#define VCC_TH_SET 0x14D +#define VSYS_TH_SET 0x14E +#define EXTIADP_TH_SET 0x14F +#define IBATP_VAL 0x150 +#define IBATP_AVE_VAL 0x151 +#define IBATM_VAL 0x152 +#define IBATM_AVE_VAL 0x153 +#define VBAT_VAL 0x154 +#define VBAT_AVE_VAL 0x155 +#define THERM_VAL 0x156 +#define VTH_VAL 0x157 +#define IACP_VAL 0x158 +#define IACP_AVE_VAL 0x159 +#define VACP_VAL 0x15A +#define VACP_AVE_VAL 0x15B +#define VBUS_VAL 0x15C +#define VBUS_AVE_VAL 0x15D +#define VCC_VAL 0x15E +#define VCC_AVE_VAL 0x15F +#define VSYS_VAL 0x160 +#define VSYS_AVE_VAL 0x161 +#define EXTIADP_VAL 0x162 +#define EXTIADP_AVE_VAL 0x163 +#define VACPCLPS_TH_SET 0x164 +#define INT0_SET 0x168 +#define INT1_SET 0x169 +#define INT2_SET 0x16A +#define INT3_SET 0x16B +#define INT4_SET 0x16C +#define INT5_SET 0x16D +#define INT6_SET 0x16E +#define INT7_SET 0x16F +#define INT0_STATUS 0x170 +#define INT1_STATUS 0x171 +#define INT2_STATUS 0x172 +#define INT3_STATUS 0x173 +#define INT4_STATUS 0x174 +#define INT5_STATUS 0x175 +#define INT6_STATUS 0x176 +#define INT7_STATUS 0x177 +#define OTPREG0 0x17A +#define OTPREG1 0x17B +#define SMBREG 0x17C +#define DEBUG_MODE_SET 0x17F +#define DEBUG0x14 0x214 +#define DEBUG0x1A 0x21A + +enum bd9995x_fields { + F_PREV_CHGSTM_STATE, F_CHGSTM_STATE, + F_VBAT_VSYS_STATUS, + F_VBUS_VCC_STATUS, + F_BATTEMP, F_VRECHG_DET, F_RBOOST_UV, F_RBOOSTS, + F_THERMWDT_VAL, F_CHGWDT_VAL, + F_CUR_ILIM_VAL, + F_SEL_ILIM_VAL, + F_IBUS_LIM_SET, + F_ICC_LIM_SET, + F_IOTG_LIM_SET, + F_OTG_BOTH_EN, + F_VRBOOST_TRIG, + F_VRBOOST_EN, + F_PP_BOTH_THRU, + F_VIN_ORD, + F_VBUS_EN, + F_VCC_EN, + F_VSYS_PRIORITY, + F_PPC_SUB_CAP, + F_PPC_CAP, + F_DCP_2500_SEL, + F_SDP_500_SEL, + F_ILIM_AUTO_DISEN, + F_VCC_BC_DISEN, + F_VBUS_BC_DISEN, + F_SDP_CHG_TRIG_EN, + F_SDP_CHG_TRIG, + F_AUTO_TOF, + F_AUTO_FST, + F_AUTO_RECH, + F_ILIM_RESET_EN, + F_DCDC_1MS_SEL, + F_SEL_ILIM_DIV, + F_BATT_LEARN, + F_CHG_EN, + F_USB_SUS, + F_CHOP_SS_INIT, + F_CHOP_ALL_INIT, + F_DCDC_CLK_SEL, + F_CHOP_SS, + F_CHOP_ALL, + F_VBUSCLPS_TH_SET, + F_VCCCLPS_TH_SET, + F_WDT_FST, + F_WDT_PRE, + F_WDT_IBAT_SHORT, + F_WDT_THERM, + F_VSYSREG_SET, + F_VSYSVAL_THH_SET, + F_VSYSVAL_THL_SET, + F_ITRICH_SET, + F_IPRECH_SET, + F_ICHG_SET, + F_ITERM_SET, + F_VPRECHG_TH_SET, + F_VRBOOST_SET, + F_VFASTCHG_REG_SET1, + F_VFASTCHG_REG_SET2, + F_VFASTCHG_REG_SET3, + F_VRECHG_SET, + F_VBATOVP_SET, + F_IBATM_SHORT_SET, + F_PROCHOT_DG_SET, + F_PROCHOT_ICRIT_DG_SET, + F_PROCHOT_IDCHG_DG_SET, + F_PROCHOT_EN, + F_PROCHOT_ICRIT_SET, + F_PROCHOT_INORM_SET, + F_PROCHOT_IDCHG_SET, + F_PROCHOT_VSYS_SET, + F_IMON_INSEL, + F_PMON_INSEL, + F_IOUT_OUT_EN, + F_IOUT_SOURCE_SEL, + F_IOUT_GAIN_SET, + F_PMON_OUT_EN, + F_PMON_GAIN_SET, + F_PMON_DACIN_VAL, + F_IOUT_DACIN_VAL, + F_VCC_BCSRETRY, + F_VCC_ADCRTRY, + F_VCC_USBDETEN, + F_VCC_IDRDETEN, + F_VCC_ENUMRDY, + F_VCC_ADCPOLEN, + F_VCC_DCDMODE, + F_VCC_USB_SW_EN, + F_VCC_USB_SW, + F_VCC_DCDFAIL, + F_VCC_CHGPORT, + F_VCC_PUPDET, + F_VCC_VBUS_VLD, + F_VCC_CHGDET, + F_VCC_OTGDET, + F_VCC_VBINOP, + F_VCC_EXTID, + F_VCC_IDRDET, + F_VCC_INDO, + F_VCC_UCDSWEN, + F_VCC_RREF_EN, + F_VCC_DPPU_EN, + F_VCC_DPREF_EN, + F_VCC_DMREF_EN, + F_VCC_DPDET_EN, + F_VCC_DMDET_EN, + F_VCC_DPSINK_EN, + F_VCC_DMSINK_EN, + F_VCC_DP_BUFF_EN, + F_VCC_DM_BUFF_EN, + F_VCC_EXTCLKENBL, + F_VCC_PLSTESTEN, + F_VCC_UCDSWEN_TSTENB, + F_VCC_RREF_EN_TSTENB, + F_VCC_DPPU_EN_TSTENB, + F_VCC_DPREF_EN_TSTENB, + F_VCC_DMREF_EN_TSTENB, + F_VCC_DPDET_EN_TSTENB, + F_VCC_DMDET_EN_TSTENB, + F_VCC_DPSINK_EN_TSTENB, + F_VCC_DMSINK_EN_TSTENB, + F_VCC_DP_BUFF_EN_TSTENB, + F_VCC_DM_BUFF_EN_TSTENB, + F_VBUS_BCSRETRY, + F_VBUS_ADCRTRY, + F_VBUS_USBDETEN, + F_VBUS_IDRDETEN, + F_VBUS_ENUMRDY, + F_VBUS_ADCPOLEN, + F_VBUS_DCDMODE, + F_VBUS_USB_SW_EN, + F_VBUS_USB_SW, + F_VBUS_DCDFAIL, + F_VBUS_CHGPORT, + F_VBUS_PUPDET, + F_VBUS_VBUS_VLD, + F_VBUS_CHGDET, + F_VBUS_OTGDET, + F_VBUS_VBINOP, + F_VBUS_EXTID, + F_VBUS_IDRDET, + F_VBUS_INDO, + F_VBUS_UCDSWEN, + F_VBUS_RREF_EN, + F_VBUS_DPPU_EN, + F_VBUS_DPREF_EN, + F_VBUS_DMREF_EN, + F_VBUS_DPDET_EN, + F_VBUS_DMDET_EN, + F_VBUS_DPSINK_EN, + F_VBUS_DMSINK_EN, + F_VBUS_DP_BUFF_EN, + F_VBUS_DM_BUFF_EN, + F_VBUS_EXTCLKENBL, + F_VBUS_PLSTESTEN, + F_VBUS_UCDSWEN_TSTENB, + F_VBUS_RREF_EN_TSTENB, + F_VBUS_DPPU_EN_TSTENB, + F_VBUS_DPREF_EN_TSTENB, + F_VBUS_DMREF_EN_TSTENB, + F_VBUS_DPDET_EN_TSTENB, + F_VBUS_DMDET_EN_TSTENB, + F_VBUS_DPSINK_EN_TSTENB, + F_VBUS_DMSINK_EN_TSTENB, + F_VBUS_DP_BUFF_EN_TSTENB, + F_VBUS_DM_BUFF_EN_TSTENB, + F_CHIP_ID, + F_CHIP_REV, + F_ONE_CELL_MODE, + F_cell, + F_VACP_AUTO_DISCHG, + F_VACP_LOAD, + F_ACOK_POL, + F_ACOK_DISEN, + F_DEBUG_SET1, + F_DEBUG_SET0, + F_MONRST_STATE, + F_ALMRST_STATE, + F_CHGRST_STATE, + F_OTPLD_STATE, + F_ALLRST_STATE, + F_PROTECT_SET, + F_MAP_SET, + F_ADCINTERVAL, + F_ADCMOD, + F_ADCTMOD, + F_EXTIADPEN, + F_VSYSENB, + F_VCCENB, + F_VBUSENB, + F_VACPENB, + F_IACPENB, + F_THERMENB, + F_VBATENB, + F_IBATMENB, + F_IBATPENB, + F_TMPTHR1B, + F_TMPTHR1A, + F_TMPTHR2B, + F_TMPTHR2A, + F_TMPTHR3B, + F_TMPTHR3A, + F_TMPTHR4B, + F_TMPTHR4A, + F_TMPTHR5B, + F_TMPTHR5A, + F_IBATP_TH_SET, + F_IBATM_TH_SET, + F_VBAT_TH_SET, + F_THERM_TH_SET, + F_IACP_TH_SET, + F_VACP_TH_SET, + F_VBUS_TH_SET, + F_VCC_TH_SET, + F_VSYS_TH_SET, + F_EXTIADP_TH_SET, + F_IBATP_VAL, + F_IBATP_AVE_VAL, + F_IBATM_VAL, + F_IBATM_AVE_VAL, + F_VBAT_VAL, + F_VBAT_AVE_VAL, + F_THERM_VAL, + F_VTH_VAL, + F_IACP_VAL, + F_IACP_AVE_VAL, + F_VACP_VAL, + F_VACP_AVE_VAL, + F_VBUS_VAL, + F_VBUS_AVE_VAL, + F_VCC_VAL, + F_VCC_AVE_VAL, + F_VSYS_VAL, + F_VSYS_AVE_VAL, + F_EXTIADP_VAL, + F_EXTIADP_AVE_VAL, + F_VACPCLPS_TH_SET, + F_INT7_SET, + F_INT6_SET, + F_INT5_SET, + F_INT4_SET, + F_INT3_SET, + F_INT2_SET, + F_INT1_SET, + F_INT0_SET, + F_VBUS_RBUV_DET, + F_VBUS_RBUV_RES, + F_VBUS_TH_DET, + F_VBUS_TH_RES, + F_VBUS_IIN_MOD, + F_VBUS_OV_DET, + F_VBUS_OV_RES, + F_VBUS_CLPS_DET, + F_VBUS_CLPS, + F_VBUS_DET, + F_VBUS_RES, + F_VCC_RBUV_DET, + F_VCC_RBUV_RES, + F_VCC_TH_DET, + F_VCC_TH_RES, + F_VCC_IIN_MOD, + F_VCC_OVP_DET, + F_VCC_OVP_RES, + F_VCC_CLPS_DET, + F_VCC_CLPS_RES, + F_VCC_DET, + F_VCC_RES, + F_TH_DET, + F_TH_RMV, + F_TMP_OUT_DET, + F_TMP_OUT_RES, + F_VBAT_TH_DET, + F_VBAT_TH_RES, + F_IBAT_SHORT_DET, + F_IBAT_SHORT_RES, + F_VBAT_OV_DET, + F_VBAT_OV_RES, + F_BAT_ASSIST_DET, + F_BAT_ASSIST_RES, + F_VSYS_TH_DET, + F_VSYS_TH_RES, + F_VSYS_OV_DET, + F_VSYS_OV_RES, + F_VSYS_SHT_DET, + F_VSYS_SHT_RES, + F_VSYS_UV_DET, + F_VSYS_UV_RES, + F_OTP_LOAD_DONE, + F_PWR_ON, + F_EXTIADP_TRNS, + F_EXTIADP_TH_DET, + F_EXIADP_TH_RES, + F_BAT_MNT_DET, + F_BAT_MNT_RES, + F_TSD_DET, + F_TSD_RES, + F_CHGWDT_EXP, + F_THERMWDT_EXP, + F_TMP_TRNS, + F_CHG_TRNS, + F_VBUS_UCD_PORT_DET, + F_VBUS_UCD_UCHG_DET, + F_VBUS_UCD_URID_RMV, + F_VBUS_UCD_OTG_DET, + F_VBUS_UCD_URID_MOD, + F_VCC_UCD_PORT_DET, + F_VCC_UCD_UCHG_DET, + F_VCC_UCD_URID_RMV, + F_VCC_UCD_OTG_DET, + F_VCC_UCD_URID_MOD, + F_PROCHOT_DET, + F_PROCHOT_RES, + F_VACP_DET, + F_VACP_RES, + F_VACP_TH_DET, + F_VACP_TH_RES, + F_IACP_TH_DET, + F_IACP_THE_RES, + F_THERM_TH_DET, + F_THERM_TH_RES, + F_IBATM_TH_DET, + F_IBATM_TH_RES, + F_IBATP_TH_DET, + F_IBATP_TH_RES, + F_INT7_STATUS, + F_INT6_STATUS, + F_INT5_STATUS, + F_INT4_STATUS, + F_INT3_STATUS, + F_INT2_STATUS, + F_INT1_STATUS, + F_INT0_STATUS, + F_ILIM_DECREASE, + F_RESERVE_OTPREG1, + F_POWER_SAVE_MODE, + F_DEBUG_MODE_SET, + F_DEBUG0x14, + F_DEBUG0x1A, + F_MAX_FIELDS +}; + +static const struct reg_field bd9995x_reg_fields[] = { + [F_PREV_CHGSTM_STATE] = REG_FIELD(CHGSTM_STATUS, 8, 14), + [F_CHGSTM_STATE] = REG_FIELD(CHGSTM_STATUS, 0, 6), + [F_VBAT_VSYS_STATUS] = REG_FIELD(VBAT_VSYS_STATUS, 0, 15), + [F_VBUS_VCC_STATUS] = REG_FIELD(VBUS_VCC_STATUS, 0, 12), + [F_BATTEMP] = REG_FIELD(CHGOP_STATUS, 8, 10), + [F_VRECHG_DET] = REG_FIELD(CHGOP_STATUS, 6, 6), + [F_RBOOST_UV] = REG_FIELD(CHGOP_STATUS, 1, 1), + [F_RBOOSTS] = REG_FIELD(CHGOP_STATUS, 0, 0), + [F_THERMWDT_VAL] = REG_FIELD(WDT_STATUS, 8, 15), + [F_CHGWDT_VAL] = REG_FIELD(WDT_STATUS, 0, 7), + [F_CUR_ILIM_VAL] = REG_FIELD(CUR_ILIM_VAL, 0, 13), + [F_SEL_ILIM_VAL] = REG_FIELD(SEL_ILIM_VAL, 0, 13), + [F_IBUS_LIM_SET] = REG_FIELD(IBUS_LIM_SET, 5, 13), + [F_ICC_LIM_SET] = REG_FIELD(ICC_LIM_SET, 5, 13), + [F_IOTG_LIM_SET] = REG_FIELD(IOTG_LIM_SET, 5, 13), + [F_OTG_BOTH_EN] = REG_FIELD(VIN_CTRL_SET, 15, 15), + [F_VRBOOST_TRIG] = REG_FIELD(VIN_CTRL_SET, 14, 14), + [F_VRBOOST_EN] = REG_FIELD(VIN_CTRL_SET, 12, 13), + [F_PP_BOTH_THRU] = REG_FIELD(VIN_CTRL_SET, 11, 11), + [F_VIN_ORD] = REG_FIELD(VIN_CTRL_SET, 7, 7), + [F_VBUS_EN] = REG_FIELD(VIN_CTRL_SET, 6, 6), + [F_VCC_EN] = REG_FIELD(VIN_CTRL_SET, 5, 5), + [F_VSYS_PRIORITY] = REG_FIELD(VIN_CTRL_SET, 4, 4), + [F_PPC_SUB_CAP] = REG_FIELD(VIN_CTRL_SET, 2, 3), + [F_PPC_CAP] = REG_FIELD(VIN_CTRL_SET, 0, 1), + [F_DCP_2500_SEL] = REG_FIELD(CHGOP_SET1, 15, 15), + [F_SDP_500_SEL] = REG_FIELD(CHGOP_SET1, 14, 14), + [F_ILIM_AUTO_DISEN] = REG_FIELD(CHGOP_SET1, 13, 13), + [F_VCC_BC_DISEN] = REG_FIELD(CHGOP_SET1, 11, 11), + [F_VBUS_BC_DISEN] = REG_FIELD(CHGOP_SET1, 10, 10), + [F_SDP_CHG_TRIG_EN] = REG_FIELD(CHGOP_SET1, 9, 9), + [F_SDP_CHG_TRIG] = REG_FIELD(CHGOP_SET1, 8, 8), + [F_AUTO_TOF] = REG_FIELD(CHGOP_SET1, 6, 6), + [F_AUTO_FST] = REG_FIELD(CHGOP_SET1, 5, 5), + [F_AUTO_RECH] = REG_FIELD(CHGOP_SET1, 3, 3), + [F_ILIM_RESET_EN] = REG_FIELD(CHGOP_SET2, 14, 14), + [F_DCDC_1MS_SEL] = REG_FIELD(CHGOP_SET2, 12, 13), + [F_SEL_ILIM_DIV] = REG_FIELD(CHGOP_SET2, 10, 10), + [F_BATT_LEARN] = REG_FIELD(CHGOP_SET2, 8, 8), + [F_CHG_EN] = REG_FIELD(CHGOP_SET2, 7, 7), + [F_USB_SUS] = REG_FIELD(CHGOP_SET2, 6, 6), + [F_CHOP_SS_INIT] = REG_FIELD(CHGOP_SET2, 5, 5), + [F_CHOP_ALL_INIT] = REG_FIELD(CHGOP_SET2, 4, 4), + [F_DCDC_CLK_SEL] = REG_FIELD(CHGOP_SET2, 2, 3), + [F_CHOP_SS] = REG_FIELD(CHGOP_SET2, 1, 1), + [F_CHOP_ALL] = REG_FIELD(CHGOP_SET2, 0, 0), + [F_VBUSCLPS_TH_SET] = REG_FIELD(VBUSCLPS_TH_SET, 7, 14), + [F_VCCCLPS_TH_SET] = REG_FIELD(VCCCLPS_TH_SET, 7, 14), + [F_WDT_FST] = REG_FIELD(CHGWDT_SET, 8, 15), + [F_WDT_PRE] = REG_FIELD(CHGWDT_SET, 0, 7), + [F_WDT_IBAT_SHORT] = REG_FIELD(BATTWDT_SET, 8, 15), + [F_WDT_THERM] = REG_FIELD(BATTWDT_SET, 0, 7), + [F_VSYSREG_SET] = REG_FIELD(VSYSREG_SET, 6, 14), + [F_VSYSVAL_THH_SET] = REG_FIELD(VSYSVAL_THH_SET, 6, 14), + [F_VSYSVAL_THL_SET] = REG_FIELD(VSYSVAL_THL_SET, 6, 14), + [F_ITRICH_SET] = REG_FIELD(ITRICH_SET, 6, 10), + [F_IPRECH_SET] = REG_FIELD(IPRECH_SET, 6, 10), + [F_ICHG_SET] = REG_FIELD(ICHG_SET, 6, 13), + [F_ITERM_SET] = REG_FIELD(ITERM_SET, 6, 10), + [F_VPRECHG_TH_SET] = REG_FIELD(VPRECHG_TH_SET, 6, 14), + [F_VRBOOST_SET] = REG_FIELD(VRBOOST_SET, 6, 14), + [F_VFASTCHG_REG_SET1] = REG_FIELD(VFASTCHG_REG_SET1, 4, 14), + [F_VFASTCHG_REG_SET2] = REG_FIELD(VFASTCHG_REG_SET2, 4, 14), + [F_VFASTCHG_REG_SET3] = REG_FIELD(VFASTCHG_REG_SET3, 4, 14), + [F_VRECHG_SET] = REG_FIELD(VRECHG_SET, 4, 14), + [F_VBATOVP_SET] = REG_FIELD(VBATOVP_SET, 4, 14), + [F_IBATM_SHORT_SET] = REG_FIELD(IBATSHORT_SET, 0, 14), + [F_PROCHOT_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 14, 15), + [F_PROCHOT_ICRIT_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 10, 11), + [F_PROCHOT_IDCHG_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 8, 9), + [F_PROCHOT_EN] = REG_FIELD(PROCHOT_CTRL_SET, 0, 4), + [F_PROCHOT_ICRIT_SET] = REG_FIELD(PROCHOT_ICRIT_SET, 0, 14), + [F_PROCHOT_INORM_SET] = REG_FIELD(PROCHOT_INORM_SET, 0, 14), + [F_PROCHOT_IDCHG_SET] = REG_FIELD(PROCHOT_IDCHG_SET, 0, 14), + [F_PROCHOT_VSYS_SET] = REG_FIELD(PROCHOT_VSYS_SET, 0, 14), + [F_IMON_INSEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 9, 9), + [F_PMON_INSEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 8, 8), + [F_IOUT_OUT_EN] = REG_FIELD(PMON_IOUT_CTRL_SET, 7, 7), + [F_IOUT_SOURCE_SEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 6, 6), + [F_IOUT_GAIN_SET] = REG_FIELD(PMON_IOUT_CTRL_SET, 4, 5), + [F_PMON_OUT_EN] = REG_FIELD(PMON_IOUT_CTRL_SET, 3, 3), + [F_PMON_GAIN_SET] = REG_FIELD(PMON_IOUT_CTRL_SET, 0, 2), + [F_PMON_DACIN_VAL] = REG_FIELD(PMON_DACIN_VAL, 0, 9), + [F_IOUT_DACIN_VAL] = REG_FIELD(IOUT_DACIN_VAL, 0, 11), + [F_VCC_BCSRETRY] = REG_FIELD(VCC_UCD_SET, 12, 12), + [F_VCC_ADCRTRY] = REG_FIELD(VCC_UCD_SET, 8, 8), + [F_VCC_USBDETEN] = REG_FIELD(VCC_UCD_SET, 7, 7), + [F_VCC_IDRDETEN] = REG_FIELD(VCC_UCD_SET, 6, 6), + [F_VCC_ENUMRDY] = REG_FIELD(VCC_UCD_SET, 5, 5), + [F_VCC_ADCPOLEN] = REG_FIELD(VCC_UCD_SET, 4, 4), + [F_VCC_DCDMODE] = REG_FIELD(VCC_UCD_SET, 3, 3), + [F_VCC_USB_SW_EN] = REG_FIELD(VCC_UCD_SET, 1, 1), + [F_VCC_USB_SW] = REG_FIELD(VCC_UCD_SET, 0, 0), + [F_VCC_DCDFAIL] = REG_FIELD(VCC_UCD_STATUS, 15, 15), + [F_VCC_CHGPORT] = REG_FIELD(VCC_UCD_STATUS, 12, 13), + [F_VCC_PUPDET] = REG_FIELD(VCC_UCD_STATUS, 11, 11), + [F_VCC_VBUS_VLD] = REG_FIELD(VCC_UCD_STATUS, 7, 7), + [F_VCC_CHGDET] = REG_FIELD(VCC_UCD_STATUS, 6, 6), + [F_VCC_OTGDET] = REG_FIELD(VCC_UCD_STATUS, 3, 3), + [F_VCC_VBINOP] = REG_FIELD(VCC_IDD_STATUS, 6, 6), + [F_VCC_EXTID] = REG_FIELD(VCC_IDD_STATUS, 5, 5), + [F_VCC_IDRDET] = REG_FIELD(VCC_IDD_STATUS, 4, 4), + [F_VCC_INDO] = REG_FIELD(VCC_IDD_STATUS, 0, 3), + [F_VCC_UCDSWEN] = REG_FIELD(VCC_UCD_FCTRL_SET, 10, 10), + [F_VCC_RREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 9, 9), + [F_VCC_DPPU_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 8, 8), + [F_VCC_DPREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 7, 7), + [F_VCC_DMREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 6, 6), + [F_VCC_DPDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 5, 5), + [F_VCC_DMDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 4, 4), + [F_VCC_DPSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 3, 3), + [F_VCC_DMSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 2, 2), + [F_VCC_DP_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 1, 1), + [F_VCC_DM_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 0, 0), + [F_VCC_EXTCLKENBL] = REG_FIELD(VCC_UCD_FCTRL_EN, 15, 15), + [F_VCC_PLSTESTEN] = REG_FIELD(VCC_UCD_FCTRL_EN, 14, 14), + [F_VCC_UCDSWEN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 10, 10), + [F_VCC_RREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 9, 9), + [F_VCC_DPPU_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 8, 8), + [F_VCC_DPREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 7, 7), + [F_VCC_DMREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 6, 6), + [F_VCC_DPDET_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 5, 5), + [F_VCC_DMDET_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 4, 4), + [F_VCC_DPSINK_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 3, 3), + [F_VCC_DMSINK_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 2, 2), + [F_VCC_DP_BUFF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 1, 1), + [F_VCC_DM_BUFF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 0, 0), + + [F_VBUS_BCSRETRY] = REG_FIELD(VBUS_UCD_SET, 12, 12), + [F_VBUS_ADCRTRY] = REG_FIELD(VBUS_UCD_SET, 8, 8), + [F_VBUS_USBDETEN] = REG_FIELD(VBUS_UCD_SET, 7, 7), + [F_VBUS_IDRDETEN] = REG_FIELD(VBUS_UCD_SET, 6, 6), + [F_VBUS_ENUMRDY] = REG_FIELD(VBUS_UCD_SET, 5, 5), + [F_VBUS_ADCPOLEN] = REG_FIELD(VBUS_UCD_SET, 4, 4), + [F_VBUS_DCDMODE] = REG_FIELD(VBUS_UCD_SET, 3, 3), + [F_VBUS_USB_SW_EN] = REG_FIELD(VBUS_UCD_SET, 1, 1), + [F_VBUS_USB_SW] = REG_FIELD(VBUS_UCD_SET, 0, 0), + [F_VBUS_DCDFAIL] = REG_FIELD(VBUS_UCD_STATUS, 15, 15), + [F_VBUS_CHGPORT] = REG_FIELD(VBUS_UCD_STATUS, 12, 13), + [F_VBUS_PUPDET] = REG_FIELD(VBUS_UCD_STATUS, 11, 11), + [F_VBUS_VBUS_VLD] = REG_FIELD(VBUS_UCD_STATUS, 7, 7), + [F_VBUS_CHGDET] = REG_FIELD(VBUS_UCD_STATUS, 6, 6), + [F_VBUS_OTGDET] = REG_FIELD(VBUS_UCD_STATUS, 3, 3), + [F_VBUS_VBINOP] = REG_FIELD(VBUS_IDD_STATUS, 6, 6), + [F_VBUS_EXTID] = REG_FIELD(VBUS_IDD_STATUS, 5, 5), + [F_VBUS_IDRDET] = REG_FIELD(VBUS_IDD_STATUS, 4, 4), + [F_VBUS_INDO] = REG_FIELD(VBUS_IDD_STATUS, 0, 3), + [F_VBUS_UCDSWEN] = REG_FIELD(VCC_UCD_FCTRL_SET, 10, 10), + [F_VBUS_RREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 9, 9), + [F_VBUS_DPPU_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 8, 8), + [F_VBUS_DPREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 7, 7), + [F_VBUS_DMREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 6, 6), + [F_VBUS_DPDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 5, 5), + [F_VBUS_DMDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 4, 4), + [F_VBUS_DPSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 3, 3), + [F_VBUS_DMSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 2, 2), + [F_VBUS_DP_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 1, 1), + [F_VBUS_DM_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 0, 0), + + [F_VBUS_EXTCLKENBL] = REG_FIELD(VBUS_UCD_FCTRL_EN, 15, 15), + [F_VBUS_PLSTESTEN] = REG_FIELD(VBUS_UCD_FCTRL_EN, 14, 14), + [F_VBUS_UCDSWEN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 10, 10), + [F_VBUS_RREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 9, 9), + [F_VBUS_DPPU_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 8, 8), + [F_VBUS_DPREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 7, 7), + [F_VBUS_DMREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 6, 6), + [F_VBUS_DPDET_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 5, 5), + [F_VBUS_DMDET_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 4, 4), + [F_VBUS_DPSINK_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 3, 3), + [F_VBUS_DMSINK_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 2, 2), + [F_VBUS_DP_BUFF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 1, 1), + [F_VBUS_DM_BUFF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 0, 0), + + [F_CHIP_ID] = REG_FIELD(CHIP_ID, 0, 15), + [F_CHIP_REV] = REG_FIELD(CHIP_REV, 0, 15), + [F_ONE_CELL_MODE] = REG_FIELD(IC_SET1, 11, 11), + [F_cell] = REG_FIELD(IC_SET1, 1, 1), + [F_VACP_AUTO_DISCHG] = REG_FIELD(IC_SET1, 9, 9), + [F_VACP_LOAD] = REG_FIELD(IC_SET1, 8, 8), + [F_ACOK_POL] = REG_FIELD(IC_SET1, 1, 1), + [F_ACOK_DISEN] = REG_FIELD(IC_SET1, 0, 0), + [F_DEBUG_SET1] = REG_FIELD(IC_SET2, 4, 8), + [F_DEBUG_SET0] = REG_FIELD(IC_SET2, 0, 0), + [F_MONRST_STATE] = REG_FIELD(SYSTEM_STATUS, 6, 6), + [F_ALMRST_STATE] = REG_FIELD(SYSTEM_STATUS, 5, 5), + [F_CHGRST_STATE] = REG_FIELD(SYSTEM_STATUS, 4, 4), + [F_OTPLD_STATE] = REG_FIELD(SYSTEM_STATUS, 1, 1), + [F_ALLRST_STATE] = REG_FIELD(SYSTEM_STATUS, 0, 0), + [F_PROTECT_SET] = REG_FIELD(PROTECT_SET, 0, 15), + [F_MAP_SET] = REG_FIELD(MAP_SET, 0, 15), + [F_ADCINTERVAL] = REG_FIELD(VM_CTRL_SET, 14, 15), + [F_ADCMOD] = REG_FIELD(VM_CTRL_SET, 12, 13), + [F_ADCTMOD] = REG_FIELD(VM_CTRL_SET, 10, 11), + [F_EXTIADPEN] = REG_FIELD(VM_CTRL_SET, 9, 9), + [F_VSYSENB] = REG_FIELD(VM_CTRL_SET, 8, 8), + [F_VCCENB] = REG_FIELD(VM_CTRL_SET, 7, 7), + [F_VBUSENB] = REG_FIELD(VM_CTRL_SET, 6, 6), + [F_VACPENB] = REG_FIELD(VM_CTRL_SET, 5, 5), + [F_IACPENB] = REG_FIELD(VM_CTRL_SET, 4, 4), + [F_THERMENB] = REG_FIELD(VM_CTRL_SET, 3, 3), + [F_VBATENB] = REG_FIELD(VM_CTRL_SET, 2, 2), + [F_IBATMENB] = REG_FIELD(VM_CTRL_SET, 1, 1), + [F_IBATPENB] = REG_FIELD(VM_CTRL_SET, 0, 0), + [F_TMPTHR1B] = REG_FIELD(THERM_WINDOW_SET1, 8, 15), + [F_TMPTHR1A] = REG_FIELD(THERM_WINDOW_SET1, 0, 7), + [F_TMPTHR2B] = REG_FIELD(THERM_WINDOW_SET2, 8, 15), + [F_TMPTHR2A] = REG_FIELD(THERM_WINDOW_SET2, 0, 7), + [F_TMPTHR3B] = REG_FIELD(THERM_WINDOW_SET3, 8, 15), + [F_TMPTHR3A] = REG_FIELD(THERM_WINDOW_SET3, 0, 7), + [F_TMPTHR4B] = REG_FIELD(THERM_WINDOW_SET4, 8, 15), + [F_TMPTHR4A] = REG_FIELD(THERM_WINDOW_SET4, 0, 7), + [F_TMPTHR5B] = REG_FIELD(THERM_WINDOW_SET5, 8, 15), + [F_TMPTHR5A] = REG_FIELD(THERM_WINDOW_SET5, 0, 7), + [F_IBATP_TH_SET] = REG_FIELD(IBATP_TH_SET, 0, 14), + [F_IBATM_TH_SET] = REG_FIELD(IBATM_TH_SET, 0, 14), + [F_VBAT_TH_SET] = REG_FIELD(VBAT_TH_SET, 0, 14), + [F_THERM_TH_SET] = REG_FIELD(THERM_TH_SET, 0, 7), + [F_IACP_TH_SET] = REG_FIELD(IACP_TH_SET, 0, 14), + [F_VACP_TH_SET] = REG_FIELD(VACP_TH_SET, 0, 14), + [F_VBUS_TH_SET] = REG_FIELD(VBUS_TH_SET, 0, 14), + [F_VCC_TH_SET] = REG_FIELD(VCC_TH_SET, 0, 14), + [F_VSYS_TH_SET] = REG_FIELD(VSYS_TH_SET, 0, 14), + [F_EXTIADP_TH_SET] = REG_FIELD(EXTIADP_TH_SET, 0, 11), + [F_IBATP_VAL] = REG_FIELD(IBATP_VAL, 0, 14), + [F_IBATP_AVE_VAL] = REG_FIELD(IBATP_AVE_VAL, 0, 14), + [F_IBATM_VAL] = REG_FIELD(IBATM_VAL, 0, 14), + [F_IBATM_AVE_VAL] = REG_FIELD(IBATM_AVE_VAL, 0, 14), + [F_VBAT_VAL] = REG_FIELD(VBAT_VAL, 0, 14), + [F_VBAT_AVE_VAL] = REG_FIELD(VBAT_AVE_VAL, 0, 14), + [F_THERM_VAL] = REG_FIELD(THERM_VAL, 0, 7), + [F_VTH_VAL] = REG_FIELD(VTH_VAL, 0, 11), + [F_IACP_VAL] = REG_FIELD(IACP_VAL, 0, 14), + [F_IACP_AVE_VAL] = REG_FIELD(IACP_AVE_VAL, 0, 14), + [F_VACP_VAL] = REG_FIELD(VACP_VAL, 0, 14), + [F_VACP_AVE_VAL] = REG_FIELD(VACP_AVE_VAL, 0, 14), + [F_VBUS_VAL] = REG_FIELD(VBUS_VAL, 0, 14), + [F_VBUS_AVE_VAL] = REG_FIELD(VBUS_AVE_VAL, 0, 14), + [F_VCC_VAL] = REG_FIELD(VCC_VAL, 0, 14), + [F_VCC_AVE_VAL] = REG_FIELD(VCC_AVE_VAL, 0, 14), + [F_VSYS_VAL] = REG_FIELD(VSYS_VAL, 0, 14), + [F_VSYS_AVE_VAL] = REG_FIELD(VSYS_AVE_VAL, 0, 14), + [F_EXTIADP_VAL] = REG_FIELD(EXTIADP_VAL, 0, 11), + [F_EXTIADP_AVE_VAL] = REG_FIELD(EXTIADP_AVE_VAL, 0, 11), + [F_VACPCLPS_TH_SET] = REG_FIELD(VACPCLPS_TH_SET, 7, 14), + [F_INT7_SET] = REG_FIELD(INT7_SET, 0, 15), + [F_INT6_SET] = REG_FIELD(INT6_SET, 0, 13), + [F_INT5_SET] = REG_FIELD(INT5_SET, 0, 13), + [F_INT4_SET] = REG_FIELD(INT4_SET, 0, 9), + [F_INT3_SET] = REG_FIELD(INT3_SET, 0, 15), + [F_INT2_SET] = REG_FIELD(INT2_SET, 0, 15), + [F_INT1_SET] = REG_FIELD(INT1_SET, 0, 15), + [F_INT0_SET] = REG_FIELD(INT0_SET, 0, 7), + [F_VBUS_RBUV_DET] = REG_FIELD(INT1_SET, 15, 15), + [F_VBUS_RBUV_RES] = REG_FIELD(INT1_SET, 14, 14), + [F_VBUS_TH_DET] = REG_FIELD(INT1_SET, 9, 9), + [F_VBUS_TH_RES] = REG_FIELD(INT1_SET, 8, 8), + [F_VBUS_IIN_MOD] = REG_FIELD(INT1_SET, 6, 6), + [F_VBUS_OV_DET] = REG_FIELD(INT1_SET, 5, 5), + [F_VBUS_OV_RES] = REG_FIELD(INT1_SET, 4, 4), + [F_VBUS_CLPS_DET] = REG_FIELD(INT1_SET, 3, 3), + [F_VBUS_CLPS] = REG_FIELD(INT1_SET, 2, 2), + [F_VBUS_DET] = REG_FIELD(INT1_SET, 1, 1), + [F_VBUS_RES] = REG_FIELD(INT1_SET, 0, 0), + [F_VCC_RBUV_DET] = REG_FIELD(INT2_SET, 15, 15), + [F_VCC_RBUV_RES] = REG_FIELD(INT2_SET, 14, 14), + [F_VCC_TH_DET] = REG_FIELD(INT2_SET, 9, 9), + [F_VCC_TH_RES] = REG_FIELD(INT2_SET, 8, 8), + [F_VCC_IIN_MOD] = REG_FIELD(INT2_SET, 6, 6), + [F_VCC_OVP_DET] = REG_FIELD(INT2_SET, 5, 5), + [F_VCC_OVP_RES] = REG_FIELD(INT2_SET, 4, 4), + [F_VCC_CLPS_DET] = REG_FIELD(INT2_SET, 3, 3), + [F_VCC_CLPS_RES] = REG_FIELD(INT2_SET, 2, 2), + [F_VCC_DET] = REG_FIELD(INT2_SET, 1, 1), + [F_VCC_RES] = REG_FIELD(INT2_SET, 0, 0), + [F_TH_DET] = REG_FIELD(INT3_SET, 15, 15), + [F_TH_RMV] = REG_FIELD(INT3_SET, 14, 14), + [F_TMP_OUT_DET] = REG_FIELD(INT3_SET, 11, 11), + [F_TMP_OUT_RES] = REG_FIELD(INT3_SET, 10, 10), + [F_VBAT_TH_DET] = REG_FIELD(INT3_SET, 9, 9), + [F_VBAT_TH_RES] = REG_FIELD(INT3_SET, 8, 8), + [F_IBAT_SHORT_DET] = REG_FIELD(INT3_SET, 7, 7), + [F_IBAT_SHORT_RES] = REG_FIELD(INT3_SET, 6, 6), + [F_VBAT_OV_DET] = REG_FIELD(INT3_SET, 5, 5), + [F_VBAT_OV_RES] = REG_FIELD(INT3_SET, 4, 4), + [F_BAT_ASSIST_DET] = REG_FIELD(INT3_SET, 3, 3), + [F_BAT_ASSIST_RES] = REG_FIELD(INT3_SET, 2, 2), + [F_VSYS_TH_DET] = REG_FIELD(INT4_SET, 9, 9), + [F_VSYS_TH_RES] = REG_FIELD(INT4_SET, 8, 8), + [F_VSYS_OV_DET] = REG_FIELD(INT4_SET, 5, 5), + [F_VSYS_OV_RES] = REG_FIELD(INT4_SET, 4, 4), + [F_VSYS_SHT_DET] = REG_FIELD(INT4_SET, 3, 3), + [F_VSYS_SHT_RES] = REG_FIELD(INT4_SET, 2, 2), + [F_VSYS_UV_DET] = REG_FIELD(INT4_SET, 1, 1), + [F_VSYS_UV_RES] = REG_FIELD(INT4_SET, 0, 0), + [F_OTP_LOAD_DONE] = REG_FIELD(INT5_SET, 13, 13), + [F_PWR_ON] = REG_FIELD(INT5_SET, 12, 12), + [F_EXTIADP_TRNS] = REG_FIELD(INT5_SET, 11, 11), + [F_EXTIADP_TH_DET] = REG_FIELD(INT5_SET, 9, 9), + [F_EXIADP_TH_RES] = REG_FIELD(INT5_SET, 8, 8), + [F_BAT_MNT_DET] = REG_FIELD(INT5_SET, 7, 7), + [F_BAT_MNT_RES] = REG_FIELD(INT5_SET, 6, 6), + [F_TSD_DET] = REG_FIELD(INT5_SET, 5, 5), + [F_TSD_RES] = REG_FIELD(INT5_SET, 4, 4), + [F_CHGWDT_EXP] = REG_FIELD(INT5_SET, 3, 3), + [F_THERMWDT_EXP] = REG_FIELD(INT5_SET, 2, 2), + [F_TMP_TRNS] = REG_FIELD(INT5_SET, 1, 1), + [F_CHG_TRNS] = REG_FIELD(INT5_SET, 0, 0), + [F_VBUS_UCD_PORT_DET] = REG_FIELD(INT6_SET, 13, 13), + [F_VBUS_UCD_UCHG_DET] = REG_FIELD(INT6_SET, 12, 12), + [F_VBUS_UCD_URID_RMV] = REG_FIELD(INT6_SET, 11, 11), + [F_VBUS_UCD_OTG_DET] = REG_FIELD(INT6_SET, 10, 10), + [F_VBUS_UCD_URID_MOD] = REG_FIELD(INT6_SET, 8, 8), + [F_VCC_UCD_PORT_DET] = REG_FIELD(INT6_SET, 5, 5), + [F_VCC_UCD_UCHG_DET] = REG_FIELD(INT6_SET, 4, 4), + [F_VCC_UCD_URID_RMV] = REG_FIELD(INT6_SET, 3, 3), + [F_VCC_UCD_OTG_DET] = REG_FIELD(INT6_SET, 2, 2), + [F_VCC_UCD_URID_MOD] = REG_FIELD(INT6_SET, 0, 0), + [F_PROCHOT_DET] = REG_FIELD(INT7_SET, 15, 15), + [F_PROCHOT_RES] = REG_FIELD(INT7_SET, 14, 14), + [F_VACP_DET] = REG_FIELD(INT7_SET, 11, 11), + [F_VACP_RES] = REG_FIELD(INT7_SET, 10, 10), + [F_VACP_TH_DET] = REG_FIELD(INT7_SET, 9, 9), + [F_VACP_TH_RES] = REG_FIELD(INT7_SET, 8, 8), + [F_IACP_TH_DET] = REG_FIELD(INT7_SET, 7, 7), + [F_IACP_THE_RES] = REG_FIELD(INT7_SET, 6, 6), + [F_THERM_TH_DET] = REG_FIELD(INT7_SET, 5, 5), + [F_THERM_TH_RES] = REG_FIELD(INT7_SET, 4, 4), + [F_IBATM_TH_DET] = REG_FIELD(INT7_SET, 3, 3), + [F_IBATM_TH_RES] = REG_FIELD(INT7_SET, 2, 2), + [F_IBATP_TH_DET] = REG_FIELD(INT7_SET, 1, 1), + [F_IBATP_TH_RES] = REG_FIELD(INT7_SET, 0, 0), + [F_INT7_STATUS] = REG_FIELD(INT7_STATUS, 0, 15), + [F_INT6_STATUS] = REG_FIELD(INT6_STATUS, 0, 13), + [F_INT5_STATUS] = REG_FIELD(INT5_STATUS, 0, 13), + [F_INT4_STATUS] = REG_FIELD(INT4_STATUS, 0, 9), + [F_INT3_STATUS] = REG_FIELD(INT3_STATUS, 0, 15), + [F_INT2_STATUS] = REG_FIELD(INT2_STATUS, 0, 15), + [F_INT1_STATUS] = REG_FIELD(INT1_STATUS, 0, 15), + [F_INT0_STATUS] = REG_FIELD(INT0_STATUS, 0, 7), + [F_ILIM_DECREASE] = REG_FIELD(OTPREG0, 0, 15), + [F_RESERVE_OTPREG1] = REG_FIELD(OTPREG1, 0, 15), + [F_POWER_SAVE_MODE] = REG_FIELD(SMBREG, 0, 15), + [F_DEBUG_MODE_SET] = REG_FIELD(DEBUG_MODE_SET, 0, 15), + [F_DEBUG0x14] = REG_FIELD(DEBUG0x14, 0, 15), + [F_DEBUG0x1A] = REG_FIELD(DEBUG0x1A, 0, 15), +}; + +/* CHGSTM_STATEs */ +#define CHGSTM_SUSPEND 0x00 +#define CHGSTM_TRICKLE_CHARGE 0x01 +#define CHGSTM_PRE_CHARGE 0x02 +#define CHGSTM_FAST_CHARGE 0x03 +#define CHGSTM_TOP_OFF 0x04 +#define CHGSTM_DONE 0x05 +#define CHGSTM_OTG 0x08 +#define CHGSTM_OTG_DONE 0x09 +#define CHGSTM_TEMPERATURE_ERROR_1 0x10 +#define CHGSTM_TEMPERATURE_ERROR_2 0x11 +#define CHGSTM_TEMPERATURE_ERROR_3 0x12 +#define CHGSTM_TEMPERATURE_ERROR_4 0x13 +#define CHGSTM_TEMPERATURE_ERROR_5 0x14 +#define CHGSTM_TEMPERATURE_ERROR_6 0x15 +#define CHGSTM_TEMPERATURE_ERROR_7 0x18 +#define CHGSTM_THERMAL_SHUT_DOWN_1 0x20 +#define CHGSTM_THERMAL_SHUT_DOWN_2 0x21 +#define CHGSTM_THERMAL_SHUT_DOWN_3 0x22 +#define CHGSTM_THERMAL_SHUT_DOWN_4 0x23 +#define CHGSTM_THERMAL_SHUT_DOWN_5 0x24 +#define CHGSTM_THERMAL_SHUT_DOWN_6 0x25 +#define CHGSTM_THERMAL_SHUT_DOWN_7 0x28 +#define CHGSTM_BATTERY_ERROR 0x40 + +/* VBAT_VSYS_STATUS */ +#define STATUS_VSYS_OV BIT(15) +#define STATUS_VSYS_SSD BIT(14) +#define STATUS_VSYS_SCP BIT(13) +#define STATUS_VSYS_UVN BIT(12) +#define STATUS_IBAT_SHORT BIT(6) +#define STATUS_VBAT_OV BIT(3) +#define STATUS_DEAD_BAT BIT(0) + +/* VBUS_VCC_STATUS */ +#define STATUS_VACP_DET BIT(12) +#define STATUS_VCC_OVP BIT(11) +#define STATUS_ILIM_VCC_MOD BIT(10) +#define STATUS_VCC_CLPS BIT(9) +#define STATUS_VCC_DET BIT(8) +#define STATUS_VBUS_OVP BIT(3) +#define STATUS_ILIM_VBUS_MOD BIT(2) +#define STATUS_VBUS_CLPS BIT(1) +#define STATUS_VBUS_DET BIT(0) + +/* Interrupt set/status definitions */ + +/* INT 0 */ +#define INT0_INT7_STATUS BIT(7) +#define INT0_INT6_STATUS BIT(6) +#define INT0_INT5_STATUS BIT(5) +#define INT0_INT4_STATUS BIT(4) +#define INT0_INT3_STATUS BIT(3) +#define INT0_INT2_STATUS BIT(2) +#define INT0_INT1_STATUS BIT(1) +#define INT0_INT0_STATUS BIT(0) +#define INT0_ALL 0xff + +/* INT 1 */ +#define VBUS_RBUV_DET BIT(15) +#define VBUS_RBUV_RES BIT(14) +#define VBUS_TH_DET BIT(9) +#define VBUS_TH_RES BIT(8) +#define VBUS_IIN_MOD BIT(6) +#define VBUS_OV_DET BIT(5) +#define VBUS_OV_RES BIT(4) +#define VBUS_CLPS_DET BIT(3) +#define VBUS_CLPS BIT(2) +#define VBUS_DET BIT(1) +#define VBUS_RES BIT(0) +#define INT1_ALL (VBUS_RBUV_DET|\ + VBUS_RBUV_RES|\ + VBUS_TH_DET |\ + VBUS_TH_RES |\ + VBUS_IIN_MOD|\ + VBUS_OV_DET |\ + VBUS_OV_RES |\ + VBUS_CLPS_DET |\ + VBUS_CLPS |\ + VBUS_DET |\ + VBUS_RES) + +/* INT 2 */ +#define VCC_RBUV_DET BIT(15) +#define VCC_RBUV_RES BIT(14) +#define VCC_TH_DET BIT(9) +#define VCC_TH_RES BIT(8) +#define VCC_IIN_MOD BIT(6) +#define VCC_OVP_DET BIT(5) +#define VCC_OVP_RES BIT(4) +#define VCC_CLPS_DET BIT(3) +#define VCC_CLPS_RES BIT(2) +#define VCC_DET BIT(1) +#define VCC_RES BIT(0) +#define INT2_ALL (VCC_RBUV_DET |\ + VCC_RBUV_RES |\ + VCC_TH_DET |\ + VCC_TH_RES |\ + VCC_IIN_MOD |\ + VCC_OVP_DET |\ + VCC_OVP_RES |\ + VCC_CLPS_DET |\ + VCC_CLPS_RES |\ + VCC_DET |\ + VCC_RES) +/* INT 3 */ +#define TH_DET BIT(15) +#define TH_RMV BIT(14) +#define TMP_OUT_DET BIT(11) +#define TMP_OUT_RES BIT(10) +#define VBAT_TH_DET BIT(9) +#define VBAT_TH_RES BIT(8) +#define IBAT_SHORT_DET BIT(7) +#define IBAT_SHORT_RES BIT(6) +#define VBAT_OV_DET BIT(5) +#define VBAT_OV_RES BIT(4) +#define BAT_ASSIST_DET BIT(3) +#define BAT_ASSIST_RES BIT(2) +#define INT3_ALL (TH_DET |\ + TH_RMV |\ + TMP_OUT_DET |\ + TMP_OUT_RES |\ + VBAT_TH_DET |\ + VBAT_TH_RES |\ + IBAT_SHORT_DET |\ + IBAT_SHORT_RES |\ + VBAT_OV_DET |\ + VBAT_OV_RES |\ + BAT_ASSIST_DET |\ + BAT_ASSIST_RES) + +/* INT 4 */ +#define VSYS_TH_DET BIT(9) +#define VSYS_TH_RES BIT(8) +#define VSYS_OV_DET BIT(5) +#define VSYS_OV_RES BIT(4) +#define VSYS_SHT_DET BIT(3) +#define VSYS_SHT_RES BIT(2) +#define VSYS_UV_DET BIT(1) +#define VSYS_UV_RES BIT(0) +#define INT4_ALL (VSYS_TH_DET |\ + VSYS_TH_RES |\ + VSYS_OV_DET |\ + VSYS_OV_RES |\ + VSYS_SHT_DET |\ + VSYS_SHT_RES |\ + VSYS_UV_DET |\ + VSYS_UV_RES) + +/* INT 5*/ +#define OTP_LOAD_DONE BIT(13) +#define PWR_ON BIT(12) +#define EXTIADP_TRNS BIT(11) +#define EXTIADP_TH_DET BIT(9) +#define EXIADP_TH_RES BIT(8) +#define BAT_MNT_DET BIT(7) +#define BAT_MNT_RES BIT(6) +#define TSD_DET BIT(5) +#define TSD_RES BIT(4) +#define CHGWDT_EXP BIT(3) +#define THERMWDT_EXP BIT(2) +#define TMP_TRNS BIT(1) +#define CHG_TRNS BIT(0) +#define INT5_ALL (OTP_LOAD_DONE |\ + PWR_ON |\ + EXTIADP_TRNS |\ + EXTIADP_TH_DET |\ + EXIADP_TH_RES |\ + BAT_MNT_DET |\ + BAT_MNT_RES |\ + TSD_DET |\ + TSD_RES |\ + CHGWDT_EXP |\ + THERMWDT_EXP |\ + TMP_TRNS |\ + CHG_TRNS) + +/* INT 6*/ +#define VBUS_UCD_PORT_DET BIT(13) +#define VBUS_UCD_UCHG_DET BIT(12) +#define VBUS_UCD_URID_RMV BIT(11) +#define VBUS_UCD_OTG_DET BIT(10) +#define VBUS_UCD_URID_MOD BIT(8) +#define VCC_UCD_PORT_DET BIT(5) +#define VCC_UCD_UCHG_DET BIT(4) +#define VCC_UCD_URID_RMV BIT(3) +#define VCC_UCD_OTG_DET BIT(2) +#define VCC_UCD_URID_MOD BIT(0) +#define INT6_ALL (VBUS_UCD_PORT_DET |\ + VBUS_UCD_UCHG_DET |\ + VBUS_UCD_URID_RMV |\ + VBUS_UCD_OTG_DET |\ + VBUS_UCD_URID_MOD |\ + VCC_UCD_PORT_DET |\ + VCC_UCD_UCHG_DET |\ + VCC_UCD_URID_RMV |\ + VCC_UCD_OTG_DET |\ + VCC_UCD_URID_MOD) + +/* INT 7 */ +#define PROCHOT_DET BIT(15) +#define PROCHOT_RES BIT(14) +#define VACP_DET BIT(11) +#define VACP_RES BIT(10) +#define VACP_TH_DET BIT(9) +#define VACP_TH_RES BIT(8) +#define IACP_TH_DET BIT(7) +#define IACP_THE_RES BIT(6) +#define THERM_TH_DET BIT(5) +#define THERM_TH_RES BIT(4) +#define IBATM_TH_DET BIT(3) +#define IBATM_TH_RES BIT(2) +#define IBATP_TH_DET BIT(1) +#define IBATP_TH_RES BIT(0) +#define INT7_ALL (PROCHOT_DET |\ + PROCHOT_RES |\ + VACP_DET |\ + VACP_RES |\ + VACP_TH_DET |\ + VACP_TH_RES |\ + IACP_TH_DET |\ + IACP_THE_RES |\ + THERM_TH_DET |\ + THERM_TH_RES |\ + IBATM_TH_DET |\ + IBATM_TH_RES |\ + IBATP_TH_DET |\ + IBATP_TH_RES) + +/* SYSTEM_CTRL_SET*/ +#define MONRST BIT(6) +#define ALMRST BIT(5) +#define CHGRST BIT(4) +#define OTPLD BIT(1) +#define ALLRST BIT(0) + +/* F_BATTEMP */ +#define ROOM 0x0 +#define HOT1 0x1 +#define HOT2 0x2 +#define HOT3 0x3 +#define COLD1 0x4 +#define COLD2 0x5 +#define TEMP_DIS 0x6 +#define BATT_OPEN 0x7 + +#endif From patchwork Wed Apr 29 07:05:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516113 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 31FC692A for ; Wed, 29 Apr 2020 07:07:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 23CD620784 for ; Wed, 29 Apr 2020 07:07:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726423AbgD2HHJ (ORCPT ); Wed, 29 Apr 2020 03:07:09 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:43706 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726274AbgD2HHJ (ORCPT ); Wed, 29 Apr 2020 03:07:09 -0400 Received: by mail-lj1-f196.google.com with SMTP id l19so1417164lje.10; Wed, 29 Apr 2020 00:07:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=Xn9Q8ChOHkxUVnDeeTwgLZBFu3TEywEF5Z2h0O3M1C0=; b=RPST9PX/HZtcg7kfmbO3e/NY91HzIDtbat/nsxTTjarRfg22PNe6R3+k6OsmoFp0TH 5uSOjdOtvtWTEQ/Y4f2yu6eWLm8eHSpyPkhzdGkzMQse2Gno8RwdqF3sjh1NJzwbqiBX h6nsUr4jUdiH6ypPlk/eC6WQ7oxaGWMm6gSpT0YQk9/g5sXBJeQcrKGWJVG8WQ+EXEFL EONOtPO+Tlp/yFErgA6zh7JQ6YqGjk+neFCAR0pm0gELqEBckiVpnEuakDUu5MAQ+glO gC72N1PvBNwZ8Pe4ejZpvpL4bonENIQb3N5uf5ulBZSmb3WaRD/+6UOlDoH9qRsYgB5u F5HQ== X-Gm-Message-State: AGi0PuZKoS55KvPqS2pGa6OYk3Gi+C/2s80pvAtIDwVsbPxeQJhkwrU0 sQlVUojFMhhZSwBYuM/dX5o= X-Google-Smtp-Source: APiQypIwKmaHB1MBNNzCboUFVG6tD7qPWyWyUzAUepoiz5TJHE7KQzdZAQH9OINeUDHOvEyFxYxbhw== X-Received: by 2002:a2e:1556:: with SMTP id 22mr10270424ljv.10.1588144026301; Wed, 29 Apr 2020 00:07:06 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id k18sm1997240lfg.81.2020.04.29.00.07.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2020 00:07:05 -0700 (PDT) Date: Wed, 29 Apr 2020 10:05:54 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 10/11] power: supply: Fix Kconfig help text indentiation Message-ID: <23314fb63b66f5f4816e052f0d7ff0e7927c0e78.1586925868.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Indent the help text as explained in Documentation/process/coding-style.rst Signed-off-by: Matti Vaittinen Reviewed-by: Sebastian Reichel --- No changes since v9 I just learned the help text in Kconfigs should be indented by two spaces. I fixed this for BD99954 as suggested by Randy and decided that I could do this for few other entries as well while I was at it anyways. drivers/power/supply/Kconfig | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 436680ee8523..ec028e47c3c2 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -415,7 +415,7 @@ config CHARGER_PCF50633 tristate "NXP PCF50633 MBC" depends on MFD_PCF50633 help - Say Y to include support for NXP PCF50633 Main Battery Charger. + Say Y to include support for NXP PCF50633 Main Battery Charger. config BATTERY_RX51 tristate "Nokia RX-51 (N900) battery driver" @@ -609,15 +609,15 @@ config CHARGER_TPS65090 tristate "TPS65090 battery charger driver" depends on MFD_TPS65090 help - Say Y here to enable support for battery charging with TPS65090 - PMIC chips. + Say Y here to enable support for battery charging with TPS65090 + PMIC chips. config CHARGER_TPS65217 tristate "TPS65217 battery charger driver" depends on MFD_TPS65217 help - Say Y here to enable support for battery charging with TPS65217 - PMIC chips. + Say Y here to enable support for battery charging with TPS65217 + PMIC chips. config BATTERY_GAUGE_LTC2941 tristate "LTC2941/LTC2943 Battery Gauge Driver" @@ -671,16 +671,16 @@ config CHARGER_SC2731 tristate "Spreadtrum SC2731 charger driver" depends on MFD_SC27XX_PMIC || COMPILE_TEST help - Say Y here to enable support for battery charging with SC2731 - PMIC chips. + Say Y here to enable support for battery charging with SC2731 + PMIC chips. config FUEL_GAUGE_SC27XX tristate "Spreadtrum SC27XX fuel gauge driver" depends on MFD_SC27XX_PMIC || COMPILE_TEST depends on IIO help - Say Y here to enable support for fuel gauge with SC27XX - PMIC chips. + Say Y here to enable support for fuel gauge with SC27XX + PMIC chips. config CHARGER_UCS1002 tristate "Microchip UCS1002 USB Port Power Controller" @@ -698,9 +698,9 @@ config CHARGER_BD70528 select LINEAR_RANGES default n help - Say Y here to enable support for getting battery status - information and altering charger configurations from charger - block of the ROHM BD70528 Power Management IC. + Say Y here to enable support for getting battery status + information and altering charger configurations from charger + block of the ROHM BD70528 Power Management IC. config CHARGER_BD99954 tristate "ROHM bd99954 charger driver" From patchwork Wed Apr 29 07:07:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 11516115 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8608292C for ; Wed, 29 Apr 2020 07:08:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77E242073E for ; Wed, 29 Apr 2020 07:08:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726436AbgD2HIt (ORCPT ); Wed, 29 Apr 2020 03:08:49 -0400 Received: from mail-lf1-f65.google.com ([209.85.167.65]:34493 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726401AbgD2HIt (ORCPT ); Wed, 29 Apr 2020 03:08:49 -0400 Received: by mail-lf1-f65.google.com with SMTP id y3so752510lfy.1; Wed, 29 Apr 2020 00:08:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=GPA/i1MeghluzvwK9kprDNBofjBWC5kulY4z+64/X/w=; b=ALmrVjUBSeYCZKVYKYkGiLlPxlOyj/C/tiNJKvHe/byLyqBEy41sy3tIofvBpVHDGr N7eC8z+LAXcJuXPafFTbA3TIu52B3kDpTu6HUSAH/GVRhLbpjwoH4ClMPrGYZhzpJvXE NPxDQmshGxk6AeeEKJn8KePX1pQOwdHWp7h8b32YDEAw/aKCEcvmckJVwGddsIyn/q+E u8Ge/bfHjFis+rvsYQgGQ8mN9qbfh8M/LG77Zc2d40Iq3G81XhJa0KM3eArYE2HBbmEv 2W3pIJuqvL62kMXvTv8kzCEzmBMat6WYiYBYG0lbu6uYCktrWlyLQjG7hAFpJl/Cj4pT zDWA== X-Gm-Message-State: AGi0PuZqP72TsVG2xVrRPUZaqnsVUAdCa/PT1CLYlyWB/dov53H+K7jb U2Ssb2gFlBVp9RC3hI4Qow/N+9Dc X-Google-Smtp-Source: APiQypKJUKHitCtd2hf4n0P6AtScizHXUhSATc+VpJMvAMKGH/LF9S4ySEx0M6VsRwpCPlQ/JRpLdA== X-Received: by 2002:a19:4a15:: with SMTP id x21mr3840498lfa.22.1588144127023; Wed, 29 Apr 2020 00:08:47 -0700 (PDT) Received: from localhost.localdomain (62-78-225-252.bb.dnainternet.fi. [62.78.225.252]) by smtp.gmail.com with ESMTPSA id z13sm1519205ljn.77.2020.04.29.00.08.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2020 00:08:46 -0700 (PDT) Date: Wed, 29 Apr 2020 10:07:54 +0300 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: sre@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lgirdwood@gmail.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v10 11/11] power: supply: KConfig cleanup default n Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The "default n" is not needed. Clean the KConfig by removing "default n". Signed-off-by: Matti Vaittinen --- This was pointed to me first by Randy Dunlap during v4 review. I cleaned the BD99954 back then. Also Andy Shevchenko mentioned this to me. So as I was changing the file anyways... Please just drop this patch out of the series if you're not Ok with this. drivers/power/supply/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index ec028e47c3c2..04821d8c9e43 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -660,7 +660,6 @@ config CHARGER_RT9455 config CHARGER_CROS_USBPD tristate "ChromeOS EC based USBPD charger" depends on CROS_USBPD_NOTIFY - default n help Say Y here to enable ChromeOS EC based USBPD charger driver. This driver gets various bits of information about @@ -696,7 +695,6 @@ config CHARGER_BD70528 tristate "ROHM bd70528 charger driver" depends on MFD_ROHM_BD70528 select LINEAR_RANGES - default n help Say Y here to enable support for getting battery status information and altering charger configurations from charger