lkml.org 
[lkml]   [2012]   [Feb]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: [PATCH 2/4] power: ab8500-charger: AB8500 charger driver
From
Hi,

On Wed, Feb 29, 2012 at 5:24 PM, Arun Murthy <arun.murthy@stericsson.com> wrote:
> This driver is responsible for detecting the ac/usb plugin and also includes
> function to enable ac/usb charging and re-kick the watchdog.
> It registers with the power supply class and provides information to the user
> space. The information include status of ac/usb charger device.
> This information in turn will be used by the abx500 charging algorithm driver
> to enable/disable and monitor charging.
>
> Signed-off-by: Arun Murthy <arun.murthy@stericsson.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/power/ab8500_charger.c       | 2789 ++++++++++++++++++++++++++++++++++
>  include/linux/mfd/abx500/ab8500-bm.h |  554 +++++++
>  2 files changed, 3343 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/power/ab8500_charger.c
>  create mode 100644 include/linux/mfd/abx500/ab8500-bm.h
>
> diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
> new file mode 100644
> index 0000000..bbc541a
> --- /dev/null
> +++ b/drivers/power/ab8500_charger.c
> @@ -0,0 +1,2789 @@
> +/**
> + * ab8500_charger_init_hw_registers() - Set up charger related registers
> + * @di:                pointer to the ab8500_charger structure
> + *
> + * Set up charger OVV, watchdog and maximum voltage registers as well as
> + * charging of the backup battery
> + */
> +static int ab8500_charger_init_hw_registers(struct ab8500_charger *di)
> +{
> +       int ret = 0;
> +
> +       /* Setup maximum charger current and voltage for ABB cut2.0 */
> +       if (!is_ab8500_1p1_or_earlier(di->parent)) {
> +               ret = abx500_set_register_interruptible(di->dev,
> +                       AB8500_CHARGER,
> +                       AB8500_CH_VOLT_LVL_MAX_REG, CH_VOL_LVL_4P6);
> +               if (ret) {
> +                       dev_err(di->dev,
> +                               "failed to set CH_VOLT_LVL_MAX_REG\n");
> +                       goto out;
> +               }
> +
> +               ret = abx500_set_register_interruptible(di->dev,
> +                       AB8500_CHARGER,
> +                       AB8500_CH_OPT_CRNTLVL_MAX_REG, CH_OP_CUR_LVL_1P6);
> +               if (ret) {
> +                       dev_err(di->dev,
> +                               "failed to set CH_OPT_CRNTLVL_MAX_REG\n");
> +                       goto out;
> +               }
> +       }
> +
> +       /* VBUS OVV set to 6.3V and enable automatic current limitiation */
> +       ret = abx500_set_register_interruptible(di->dev,
> +               AB8500_CHARGER,
> +               AB8500_USBCH_CTRL2_REG,
> +               VBUS_OVV_SELECT_6P3V | VBUS_AUTO_IN_CURR_LIM_ENA);
> +       if (ret) {
> +               dev_err(di->dev, "failed to set VBUS OVV\n");
> +               goto out;
> +       }
> +
> +       /* Enable main watchdog in OTP */
> +       ret = abx500_set_register_interruptible(di->dev,
> +               AB8500_OTP_EMUL, AB8500_OTP_CONF_15, OTP_ENABLE_WD);
> +       if (ret) {
> +               dev_err(di->dev, "failed to enable main WD in OTP\n");
> +               goto out;
> +       }
> +
> +       /* Enable main watchdog */
> +       ret = abx500_set_register_interruptible(di->dev,
> +               AB8500_SYS_CTRL2_BLOCK,
> +               AB8500_MAIN_WDOG_CTRL_REG, MAIN_WDOG_ENA);
> +       if (ret) {
> +               dev_err(di->dev, "faile to enable main watchdog\n");
> +               goto out;
> +       }
> +
> +       /*
> +        * Due to internal synchronisation, Enable and Kick watchdog bits
> +        * cannot be enabled in a single write.
> +        * A minimum delay of 2*32 kHz period (62.5µs) must be inserted
> +        * between writing Enable then Kick bits.
> +        */
> +       udelay(63);

Are you sure about this udelay?

> +
> +       /* Kick main watchdog */
> +       ret = abx500_set_register_interruptible(di->dev,
> +               AB8500_SYS_CTRL2_BLOCK,
> +               AB8500_MAIN_WDOG_CTRL_REG,
> +               (MAIN_WDOG_ENA | MAIN_WDOG_KICK));
> +       if (ret) {
> +               dev_err(di->dev, "failed to kick main watchdog\n");
> +               goto out;
> +       }
> +
> +       /* Disable main watchdog */
> +       ret = abx500_set_register_interruptible(di->dev,
> +               AB8500_SYS_CTRL2_BLOCK,
> +               AB8500_MAIN_WDOG_CTRL_REG, MAIN_WDOG_DIS);
> +       if (ret) {
> +               dev_err(di->dev, "failed to disable main watchdog\n");
> +               goto out;
> +       }
> +
> +       /* Set watchdog timeout */
> +       ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
> +               AB8500_CH_WD_TIMER_REG, WD_TIMER);
> +       if (ret) {
> +               dev_err(di->dev, "failed to set charger watchdog timeout\n");
> +               goto out;
> +       }
> +
> +       /* Backup battery voltage and current */
> +       ret = abx500_set_register_interruptible(di->dev,
> +               AB8500_RTC,
> +               AB8500_RTC_BACKUP_CHG_REG,
> +               di->bat->bkup_bat_v |
> +               di->bat->bkup_bat_i);
> +       if (ret) {
> +               dev_err(di->dev, "failed to setup backup battery charging\n");
> +               goto out;
> +       }
> +
> +       /* Enable backup battery charging */
> +       abx500_mask_and_set_register_interruptible(di->dev,
> +               AB8500_RTC, AB8500_RTC_CTRL_REG,
> +               RTC_BUP_CH_ENA, RTC_BUP_CH_ENA);
> +       if (ret < 0)
> +               dev_err(di->dev, "%s mask and set failed\n", __func__);
> +
> +out:
> +       return ret;
> +}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2012-02-29 18:53    [W:0.098 / U:0.516 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site