From: Anton Vorontsov <anton.vorontsov@linaro.org>
To: mathieu.poirier@linaro.org
Cc: linux-kernel@vger.kernel.org, dwmw2@infradead.org
Subject: Re: [PATCH 01/57] power: ab8500_bm: Charger current step-up/down
Date: Thu, 27 Sep 2012 20:41:21 -0700 [thread overview]
Message-ID: <20120928034120.GP5040@lizard> (raw)
In-Reply-To: <1348589574-25655-2-git-send-email-mathieu.poirier@linaro.org>
On Tue, Sep 25, 2012 at 10:11:58AM -0600, mathieu.poirier@linaro.org wrote:
> From: Johan Bjornstedt <johan.bjornstedt@stericsson.com>
>
> There is no state machine in the AB to step up/down
> the charger current to avoid dips and spikes on VBUS
> and VBAT when charging is started.
> Instead this is implemented in SW
Some general comment: the commit messages use random line wrapping length.
It's usually a good idea to make lines no longer than 74 columns (since
'git log' adds some spaces before the message) , but too short or random
is also not pretty.
> Signed-off-by: Johan Bjornstedt <johan.bjornstedt@stericsson.com>
> Signed-off-by: Mattias Wallin <mattias.wallin@stericsson.com>
> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> Reviewed-by: Karl KOMIEROWSKI <karl.komierowski@stericsson.com>
> ---
> drivers/power/ab8500_charger.c | 172 +++++++++++++++++++++++++++++++---------
> 1 files changed, 133 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
> index d4f0c98..3ceb788 100644
> --- a/drivers/power/ab8500_charger.c
> +++ b/drivers/power/ab8500_charger.c
> @@ -77,6 +77,9 @@
> /* Lowest charger voltage is 3.39V -> 0x4E */
> #define LOW_VOLT_REG 0x4E
>
> +/* Step up/down delay in us */
> +#define STEP_UDELAY 1000
> +
> /* UsbLineStatus register - usb types */
> enum ab8500_charger_link_status {
> USB_STAT_NOT_CONFIGURED,
> @@ -934,6 +937,88 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
> }
>
> /**
> + * ab8500_charger_set_current() - set charger current
> + * @di: pointer to the ab8500_charger structure
> + * @ich: charger current, in mA
> + * @reg: select what charger register to set
> + *
> + * Set charger current.
> + * There is no state machine in the AB to step up/down the charger
> + * current to avoid dips and spikes on MAIN, VBUS and VBAT when
> + * charging is started. Instead we need to implement
> + * this charger current step-up/down here.
> + * Returns error code in case of failure else 0(on success)
Random line wrapping...
Sophisticated editors (like vim :-), can format text for you. i.e. 'gqip'
command. I'm sure emacs can do this too.
> + */
> +static int ab8500_charger_set_current(struct ab8500_charger *di,
> + int ich, int reg)
> +{
> + int ret, i;
> + int curr_index, prev_curr_index, shift_value;
One variable per line, please.
> + u8 reg_value;
> +
> + switch (reg) {
> + case AB8500_MCH_IPT_CURLVL_REG:
> + shift_value = MAIN_CH_INPUT_CURR_SHIFT;
> + curr_index = ab8500_current_to_regval(ich);
> + break;
> + case AB8500_USBCH_IPT_CRNTLVL_REG:
> + shift_value = VBUS_IN_CURR_LIM_SHIFT;
> + curr_index = ab8500_vbus_in_curr_to_regval(ich);
> + break;
> + case AB8500_CH_OPT_CRNTLVL_REG:
> + shift_value = 0;
> + curr_index = ab8500_current_to_regval(ich);
> + break;
> + default:
> + dev_err(di->dev, "%s current register not valid\n", __func__);
> + return -ENXIO;
> + }
> +
> + if (curr_index < 0) {
> + dev_err(di->dev, "requested current limit out-of-range\n");
> + return -ENXIO;
> + }
> +
> + ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
> + reg, ®_value);
> + if (ret < 0) {
> + dev_err(di->dev, "%s read failed\n", __func__);
> + return ret;
> + }
> + prev_curr_index = (reg_value >> shift_value);
No need for parenthesis.
> + /* only update current if it's been changed */
> + if (prev_curr_index == curr_index)
> + return 0;
> +
> + dev_dbg(di->dev, "%s set charger current: %d mA for reg: 0x%02x\n",
> + __func__, ich, reg);
> +
> + if (prev_curr_index > curr_index) {
> + for (i = prev_curr_index - 1; i >= curr_index; i--) {
> + ret = abx500_set_register_interruptible(di->dev,
> + AB8500_CHARGER, reg, (u8) i << shift_value);
> + if (ret) {
> + dev_err(di->dev, "%s write failed\n", __func__);
> + return ret;
> + }
> + usleep_range(STEP_UDELAY, STEP_UDELAY * 2);
> + }
> + } else {
> + for (i = prev_curr_index + 1; i <= curr_index; i++) {
> + ret = abx500_set_register_interruptible(di->dev,
> + AB8500_CHARGER, reg, (u8) i << shift_value);
> + if (ret) {
> + dev_err(di->dev, "%s write failed\n", __func__);
> + return ret;
> + }
> + usleep_range(STEP_UDELAY, STEP_UDELAY * 2);
> + }
> + }
Too much duplication.
Assuming that you need to preserve the order of the writes, i.e. if it
matters to the hw, I guess this (or something alike) will work:
write_current()
{
uint start = prev_curr_index + 1;
uint stop = curr_index + 1;
int direction = 1;
if (prev_curr_index > curr_index) {
start = prev_curr_index - 1;
stop = curr_index - 1;
direction = -1;
}
for (i = start; i != stop; i += direction) {
ret = abx500_set_register_interruptible(di->dev,
AB8500_CHARGER, reg, (u8)i << shift_value);
if (ret) {
dev_err(di->dev, "%s write failed\n", __func__);
return ret;
}
usleep_range(STEP_UDELAY, STEP_UDELAY * 2);
}
}
If the order doesn't matter, it could be even simpler.
> + return ret;
> +}
> +
> +/**
> * ab8500_charger_set_vbus_in_curr() - set VBUS input current limit
> * @di: pointer to the ab8500_charger structure
> * @ich_in: charger input current limit
> @@ -944,8 +1029,6 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
> static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di,
> int ich_in)
> {
> - int ret;
> - int input_curr_index;
> int min_value;
>
> /* We should always use to lowest current limit */
> @@ -964,19 +1047,38 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di,
> break;
> }
>
> - input_curr_index = ab8500_vbus_in_curr_to_regval(min_value);
> - if (input_curr_index < 0) {
> - dev_err(di->dev, "VBUS input current limit too high\n");
> - return -ENXIO;
> - }
> + return ab8500_charger_set_current(di, min_value,
> + AB8500_USBCH_IPT_CRNTLVL_REG);
> +}
>
> - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
> - AB8500_USBCH_IPT_CRNTLVL_REG,
> - input_curr_index << VBUS_IN_CURR_LIM_SHIFT);
> - if (ret)
> - dev_err(di->dev, "%s write failed\n", __func__);
> +/**
> + * ab8500_charger_set_main_in_curr() - set main charger input current
> + * @di: pointer to the ab8500_charger structure
> + * @ich_in: input charger current, in mA
> + *
> + * Set main charger input current.
> + * Returns error code in case of failure else 0(on success)
> + */
> +static int ab8500_charger_set_main_in_curr(struct ab8500_charger *di,
> + int ich_in)
> +{
> + return ab8500_charger_set_current(di, ich_in,
> + AB8500_MCH_IPT_CURLVL_REG);
> +}
>
> - return ret;
> +/**
> + * ab8500_charger_set_output_curr() - set charger output current
> + * @di: pointer to the ab8500_charger structure
> + * @ich_out: output charger current, in mA
> + *
> + * Set charger output current.
> + * Returns error code in case of failure else 0(on success)
> + */
> +static int ab8500_charger_set_output_curr(struct ab8500_charger *di,
> + int ich_out)
Wrong indentation.
> +{
> + return ab8500_charger_set_current(di, ich_out,
> + AB8500_CH_OPT_CRNTLVL_REG);
> }
>
> /**
> @@ -1088,18 +1190,18 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
> return ret;
> }
> /* MainChInputCurr: current that can be drawn from the charger*/
> - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
> - AB8500_MCH_IPT_CURLVL_REG,
> - input_curr_index << MAIN_CH_INPUT_CURR_SHIFT);
> + ret = ab8500_charger_set_main_in_curr(di,
> + di->bat->chg_params->ac_curr_max);
> if (ret) {
> - dev_err(di->dev, "%s write failed\n", __func__);
> + dev_err(di->dev, "%s Failed to set MainChInputCurr\n",
> + __func__);
> return ret;
> }
> /* ChOutputCurentLevel: protected output current */
> - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
> - AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index);
> + ret = ab8500_charger_set_output_curr(di, iset);
> if (ret) {
> - dev_err(di->dev, "%s write failed\n", __func__);
> + dev_err(di->dev,
> + "%s Failed to set ChOutputCurentLevel\n", __func__);
> return ret;
> }
>
> @@ -1156,12 +1258,11 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
> return ret;
> }
>
> - ret = abx500_set_register_interruptible(di->dev,
> - AB8500_CHARGER,
> - AB8500_CH_OPT_CRNTLVL_REG, CH_OP_CUR_LVL_0P1);
> + ret = ab8500_charger_set_output_curr(di, 0);
> if (ret) {
> dev_err(di->dev,
> - "%s write failed\n", __func__);
> + "%s Failed to set ChOutputCurentLevel\n",
> + __func__);
Weird, inconsistent indentation.
> return ret;
> }
> } else {
> @@ -1264,10 +1365,11 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger,
> return ret;
> }
> /* ChOutputCurentLevel: protected output current */
> - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
> - AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index);
> + ret = ab8500_charger_set_output_curr(di, ich_out);
> if (ret) {
> - dev_err(di->dev, "%s write failed\n", __func__);
> + dev_err(di->dev,
> + "%s Failed to set ChOutputCurentLevel\n",
> + __func__);
Weird indentation.
> return ret;
> }
> /* Check if VBAT overshoot control should be enabled */
> @@ -1364,7 +1466,6 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
> int ich_out)
> {
> int ret;
> - int curr_index;
> struct ab8500_charger *di;
>
> if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS)
> @@ -1374,18 +1475,11 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
> else
> return -ENXIO;
>
> - curr_index = ab8500_current_to_regval(ich_out);
> - if (curr_index < 0) {
> - dev_err(di->dev,
> - "Charger current too high, "
> - "charging not started\n");
> - return -ENXIO;
> - }
> -
> - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
> - AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index);
> + ret = ab8500_charger_set_output_curr(di, ich_out);
> if (ret) {
> - dev_err(di->dev, "%s write failed\n", __func__);
> + dev_err(di->dev,
> + "%s Failed to set ChOutputCurentLevel\n",
> + __func__);
Weird indentation. No need for the first line wrap.
> return ret;
> }
>
> --
> 1.7.5.4
next prev parent reply other threads:[~2012-09-28 3:44 UTC|newest]
Thread overview: 108+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-25 16:11 [PATCH 00/57] power: Upgrade to ux500 battery management driver mathieu.poirier
2012-09-25 16:11 ` [PATCH 01/57] power: ab8500_bm: Charger current step-up/down mathieu.poirier
2012-09-28 3:41 ` Anton Vorontsov [this message]
2012-09-25 16:11 ` [PATCH 02/57] power: ab8500_bm: Don't clear the CCMuxOffset bit mathieu.poirier
2012-09-28 3:42 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 03/57] power: ab8500_btemp: Detect battery type in workqueue mathieu.poirier
2012-09-25 16:12 ` [PATCH 04/57] power: ab8500: bm: movimg back to ab8500 platform data managment mathieu.poirier
2012-09-27 2:42 ` Anton Vorontsov
2012-09-27 2:53 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 05/57] power: ab8500_bm: Rename the power_loss function mathieu.poirier
2012-09-25 16:12 ` [PATCH 06/57] power: ab8500_bm: Skip first CCEOC irq for instant current mathieu.poirier
2012-09-25 16:12 ` [PATCH 07/57] power: ab8500_bm: Detect removed charger mathieu.poirier
2012-09-27 3:09 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 08/57] power: ab8500_fg: flush sync on suspend mathieu.poirier
2012-09-27 3:11 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 09/57] power: ab8500_fg: usleep_range instead of short msleep mathieu.poirier
2012-09-27 2:36 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 10/57] power: ab8500_charger: Handle gpadc errors mathieu.poirier
2012-09-25 16:12 ` [PATCH 11/57] power: Recharge condition not optimal for battery mathieu.poirier
2012-09-27 3:29 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 12/57] power: ab8500_fg: balance IRQ enable mathieu.poirier
2012-09-25 16:12 ` [PATCH 13/57] power: ab8500_bm: Ignore false btemp low interrupt mathieu.poirier
2012-09-27 3:32 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 14/57] power: Adds support for Car/Travel Adapters mathieu.poirier
2012-09-25 16:12 ` [PATCH 15/57] power: ab8500_fg: Round capacity output mathieu.poirier
2012-09-25 16:12 ` [PATCH 16/57] power: bm remove superfluous BTEMP thermal comp mathieu.poirier
2012-09-25 16:12 ` [PATCH 17/57] power: ab8500_bm: Added support for BATT_OVV mathieu.poirier
2012-09-27 3:36 ` Anton Vorontsov
2012-09-28 18:24 ` Mathieu Poirier
2012-09-28 18:26 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 18/57] power: Add sysfs interfaces for capacity mathieu.poirier
2012-09-27 7:08 ` Anton Vorontsov
2012-09-28 18:26 ` Mathieu Poirier
2012-09-28 19:11 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 19/57] power: remove unused defines mathieu.poirier
2012-09-25 16:12 ` [PATCH 20/57] power: Adds support for legacy USB chargers mathieu.poirier
2012-09-27 7:15 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 21/57] power: Overflow in current calculation mathieu.poirier
2012-09-25 16:12 ` [PATCH 22/57] power: AB workaround for invalid charger mathieu.poirier
2012-09-25 16:12 ` [PATCH 23/57] power: Add plaform data charger configurables mathieu.poirier
2012-09-25 16:12 ` [PATCH 24/57] power: ab8500_fg: Adjust for RF bursts voltage drops mathieu.poirier
2012-09-25 16:12 ` [PATCH 25/57] power: ab8500: adaptation to ab version mathieu.poirier
2012-09-25 16:12 ` [PATCH 26/57] power: charge: update watchdog for pm2xxx support mathieu.poirier
2012-09-25 16:12 ` [PATCH 27/57] power: sysfs interface update mathieu.poirier
2012-09-27 7:20 ` Anton Vorontsov
2012-09-28 18:26 ` Mathieu Poirier
2012-09-25 16:12 ` [PATCH 28/57] power: ab8500 - Accessing Autopower register fails mathieu.poirier
2012-09-25 16:12 ` [PATCH 29/57] power: ab8500_fg: Goto INIT_RECOVERY when charger removed mathieu.poirier
2012-09-25 16:12 ` [PATCH 30/57] power: ab8500: Flush & sync all works mathieu.poirier
2012-09-27 7:23 ` Anton Vorontsov
2012-09-28 18:28 ` Mathieu Poirier
2012-09-28 19:54 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 31/57] power: ab8500_fg: fix to use correct battery charge full design mathieu.poirier
2012-09-27 7:27 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 32/57] power: ab8500_charger: Do not touch VBUSOVV bits mathieu.poirier
2012-09-25 16:12 ` [PATCH 33/57] power: u8500_charger: Delay for USB enumeration mathieu.poirier
2012-09-27 7:42 ` Anton Vorontsov
2012-09-28 16:56 ` Mathieu Poirier
2012-09-28 17:09 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 34/57] power: ab8500_fg: add power cut feature for ab8505 mathieu.poirier
2012-09-28 0:01 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 35/57] power: ab8500_fg: Report unscaled capacity mathieu.poirier
2012-09-25 16:12 ` [PATCH 36/57] power: add backup battery charge voltages mathieu.poirier
2012-09-25 16:12 ` [PATCH 37/57] power: ab8500_bm: Quick re-attach charging behaviour mathieu.poirier
2012-09-28 0:13 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 38/57] power: l9540: Charge only mode fixes mathieu.poirier
2012-09-28 0:27 ` Anton Vorontsov
2012-09-28 18:32 ` Mathieu Poirier
2012-09-25 16:12 ` [PATCH 39/57] power: ab8500_charger: Prevent auto drop of VBUS mathieu.poirier
2012-09-28 0:52 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 40/57] power: ab8500: ADC for battery thermistor mathieu.poirier
2012-09-28 0:57 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 41/57] power: ab8500_btemp: Filter btemp readings mathieu.poirier
2012-09-25 16:12 ` [PATCH 42/57] power: charging: Allow capacity to raise from 1% mathieu.poirier
2012-09-25 16:12 ` [PATCH 43/57] power: charging: Add AB8505_USB_LINK_STATUS mathieu.poirier
2012-09-25 16:12 ` [PATCH 44/57] power: ab8500: remove unecesary define flag mathieu.poirier
2012-09-28 1:05 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 45/57] power: ab8500: defer btemp filtering while init mathieu.poirier
2012-09-28 1:08 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 46/57] power: chargealg: Realign with upstream version mathieu.poirier
2012-09-28 1:17 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 47/57] power: Harmonising platform data declaration/handling mathieu.poirier
2012-09-28 1:11 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 48/57] power: ab8500 : quick re-attach for ext charger mathieu.poirier
2012-09-28 1:19 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 49/57] power: Cancelling status charging notification mathieu.poirier
2012-09-28 2:16 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 50/57] power: ab8500-chargalg: update battery health on safety timer exp mathieu.poirier
2012-09-28 2:21 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 51/57] power: ab8500: Re-alignment with internal developement mathieu.poirier
2012-09-28 2:35 ` Anton Vorontsov
2012-09-28 2:45 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 52/57] power: abx500_chargalg: Use hrtimer mathieu.poirier
2012-09-28 2:47 ` Anton Vorontsov
2012-09-28 18:33 ` Mathieu Poirier
2012-09-28 19:41 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 53/57] power: ab8500_fg: Moving structure definitions to header file mathieu.poirier
2012-09-28 2:51 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 54/57] power: ab8500_charger: Use USBLink1Status Register mathieu.poirier
2012-09-28 2:56 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 55/57] power: ab8500_charger: Add UsbLineCtrl2 reference mathieu.poirier
2012-09-28 2:58 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 56/57] power: abx500_chargalg: Fix quick re-attach charger issue mathieu.poirier
2012-09-28 3:00 ` Anton Vorontsov
2012-09-25 16:12 ` [PATCH 57/57] power: ab8500_charger: Limit USB charger current mathieu.poirier
2012-09-27 3:38 ` [PATCH 00/57] power: Upgrade to ux500 battery management driver Anton Vorontsov
2012-09-27 22:08 ` Mathieu Poirier
2012-09-28 0:36 ` Anton Vorontsov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120928034120.GP5040@lizard \
--to=anton.vorontsov@linaro.org \
--cc=dwmw2@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.poirier@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.