Messages in this thread | | | Date | Wed, 29 Feb 2012 18:50:57 +0100 | Subject | Re: [PATCH 2/4] power: ab8500-charger: AB8500 charger driver | From | Andi <> |
| |
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/
| |