mfd: pm8921: Add charger cell

The 8921 pmic is equipped with a charger block that can trickle charge
and fast charge a battery. The charger block has 32 interrupts for
notifying various charging events. It needs some parameters such as max
and min voltage of the system, charging resume voltage.

Add code to support the charger module in the core file.

Change-Id: I082b3009dd070af4120b1cd170972e7bf88ce810
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
Abhijeet Dharmapurikar
2011-04-01 15:12:40 -07:00
committed by Stephen Boyd
parent 982fe07ec4
commit bee2afbfda
3 changed files with 149 additions and 0 deletions

View File

@@ -27,6 +27,14 @@
#define REG_MPP_BASE 0x050
#define SINGLE_IRQ_RESOURCE(_name, _irq) \
{ \
.name = _name, \
.start = _irq, \
.end = _irq, \
.flags = IORESOURCE_IRQ, \
}
struct pm8921 {
struct device *dev;
struct pm_irq_chip *irq_chip;
@@ -188,6 +196,48 @@ static struct mfd_cell pwm_cell __devinitdata = {
.id = -1,
};
static const struct resource charger_cell_resources[] __devinitconst = {
SINGLE_IRQ_RESOURCE("USBIN_VALID_IRQ", PM8921_USBIN_VALID_IRQ),
SINGLE_IRQ_RESOURCE("USBIN_OV_IRQ", PM8921_USBIN_OV_IRQ),
SINGLE_IRQ_RESOURCE("BATT_INSERTED_IRQ", PM8921_BATT_INSERTED_IRQ),
SINGLE_IRQ_RESOURCE("VBATDET_LOW_IRQ", PM8921_VBATDET_LOW_IRQ),
SINGLE_IRQ_RESOURCE("USBIN_UV_IRQ", PM8921_USBIN_UV_IRQ),
SINGLE_IRQ_RESOURCE("VBAT_OV_IRQ", PM8921_VBAT_OV_IRQ),
SINGLE_IRQ_RESOURCE("CHGWDOG_IRQ", PM8921_CHGWDOG_IRQ),
SINGLE_IRQ_RESOURCE("VCP_IRQ", PM8921_VCP_IRQ),
SINGLE_IRQ_RESOURCE("ATCDONE_IRQ", PM8921_ATCDONE_IRQ),
SINGLE_IRQ_RESOURCE("ATCFAIL_IRQ", PM8921_ATCFAIL_IRQ),
SINGLE_IRQ_RESOURCE("CHGDONE_IRQ", PM8921_CHGDONE_IRQ),
SINGLE_IRQ_RESOURCE("CHGFAIL_IRQ", PM8921_CHGFAIL_IRQ),
SINGLE_IRQ_RESOURCE("CHGSTATE_IRQ", PM8921_CHGSTATE_IRQ),
SINGLE_IRQ_RESOURCE("LOOP_CHANGE_IRQ", PM8921_LOOP_CHANGE_IRQ),
SINGLE_IRQ_RESOURCE("FASTCHG_IRQ", PM8921_FASTCHG_IRQ),
SINGLE_IRQ_RESOURCE("TRKLCHG_IRQ", PM8921_TRKLCHG_IRQ),
SINGLE_IRQ_RESOURCE("BATT_REMOVED_IRQ", PM8921_BATT_REMOVED_IRQ),
SINGLE_IRQ_RESOURCE("BATTTEMP_HOT_IRQ", PM8921_BATTTEMP_HOT_IRQ),
SINGLE_IRQ_RESOURCE("CHGHOT_IRQ", PM8921_CHGHOT_IRQ),
SINGLE_IRQ_RESOURCE("BATTTEMP_COLD_IRQ", PM8921_BATTTEMP_COLD_IRQ),
SINGLE_IRQ_RESOURCE("CHG_GONE_IRQ", PM8921_CHG_GONE_IRQ),
SINGLE_IRQ_RESOURCE("BAT_TEMP_OK_IRQ", PM8921_BAT_TEMP_OK_IRQ),
SINGLE_IRQ_RESOURCE("COARSE_DET_LOW_IRQ", PM8921_COARSE_DET_LOW_IRQ),
SINGLE_IRQ_RESOURCE("VDD_LOOP_IRQ", PM8921_VDD_LOOP_IRQ),
SINGLE_IRQ_RESOURCE("VREG_OV_IRQ", PM8921_VREG_OV_IRQ),
SINGLE_IRQ_RESOURCE("VBAT_IRQ", PM8921_VBAT_IRQ),
SINGLE_IRQ_RESOURCE("VBATDET_IRQ", PM8921_VBATDET_IRQ),
SINGLE_IRQ_RESOURCE("BATFET_IRQ", PM8921_BATFET_IRQ),
SINGLE_IRQ_RESOURCE("PSI_IRQ", PM8921_PSI_IRQ),
SINGLE_IRQ_RESOURCE("DCIN_VALID_IRQ", PM8921_DCIN_VALID_IRQ),
SINGLE_IRQ_RESOURCE("DCIN_OV_IRQ", PM8921_DCIN_OV_IRQ),
SINGLE_IRQ_RESOURCE("DCIN_UV_IRQ", PM8921_DCIN_UV_IRQ),
};
static struct mfd_cell charger_cell __devinitdata = {
.name = PM8921_CHARGER_DEV_NAME,
.id = -1,
.resources = charger_cell_resources,
.num_resources = ARRAY_SIZE(charger_cell_resources),
};
static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
*pdata,
struct pm8921 *pmic,
@@ -273,6 +323,19 @@ static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
}
}
if (pdata->charger_pdata) {
pdata->charger_pdata->charger_cdata.rev = rev;
charger_cell.platform_data = pdata->charger_pdata;
charger_cell.pdata_size =
sizeof(struct pm8921_charger_platform_data);
ret = mfd_add_devices(pmic->dev, 0, &charger_cell, 1, NULL,
irq_base);
if (ret) {
pr_err("Failed to add charger subdevice ret=%d\n", ret);
goto bail;
}
}
/* Add one device for each regulator used by the board. */
if (pdata->num_regulators > 0 && pdata->regulator_pdatas) {
mfd_regulators = kzalloc(sizeof(struct mfd_cell)

View File

@@ -0,0 +1,51 @@
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __PM8XXX_CHARGER_H
#define __PM8XXX_CHARGER_H
#include <linux/errno.h>
#define PM8921_CHARGER_DEV_NAME "pm8921-charger"
struct pm8xxx_charger_core_data {
u32 rev;
};
/**
* struct pm8921_charger_platform_data -
* @safety_time: max charging time in minutes
* @update_time: how often the userland be updated of the charging
* @max_voltage: the max voltage the battery should be charged up to
* @min_voltage: the voltage where charging method switches from trickle
* to fast. This is also the minimum voltage the system
* operates at
* @resume_voltage: the voltage to wait for before resume charging after the
* battery has been fully charged
* @term_current: the charger current at which EOC happens
* @get_batt_capacity_percent:
* a board specific function to return battery
* capacity. If null - a default one will be used
*
*/
struct pm8921_charger_platform_data {
struct pm8xxx_charger_core_data charger_cdata;
unsigned int safety_time;
unsigned int update_time;
unsigned int max_voltage;
unsigned int min_voltage;
unsigned int resume_voltage;
unsigned int term_current;
unsigned int (*get_batt_capacity_percent) (void);
};
#endif

View File

@@ -26,6 +26,7 @@
#include <linux/input/pmic8xxx-pwrkey.h>
#include <linux/input/pmic8xxx-keypad.h>
#include <linux/regulator/pm8921-regulator.h>
#include <linux/mfd/pm8xxx/pm8921-charger.h>
#define PM8921_NR_IRQS 256
@@ -50,6 +51,39 @@
#define PM8921_KEYPAD_IRQ PM8921_IRQ_BLOCK_BIT(9, 2)
#define PM8921_KEYSTUCK_IRQ PM8921_IRQ_BLOCK_BIT(9, 3)
#define PM8921_USBIN_VALID_IRQ PM8921_IRQ_BLOCK_BIT(1, 7)
#define PM8921_USBIN_OV_IRQ PM8921_IRQ_BLOCK_BIT(1, 6)
#define PM8921_BATT_INSERTED_IRQ PM8921_IRQ_BLOCK_BIT(1, 5)
#define PM8921_VBATDET_LOW_IRQ PM8921_IRQ_BLOCK_BIT(1, 4)
#define PM8921_USBIN_UV_IRQ PM8921_IRQ_BLOCK_BIT(1, 3)
#define PM8921_VBAT_OV_IRQ PM8921_IRQ_BLOCK_BIT(1, 2)
#define PM8921_CHGWDOG_IRQ PM8921_IRQ_BLOCK_BIT(1, 1)
#define PM8921_VCP_IRQ PM8921_IRQ_BLOCK_BIT(1, 0)
#define PM8921_ATCDONE_IRQ PM8921_IRQ_BLOCK_BIT(2, 7)
#define PM8921_ATCFAIL_IRQ PM8921_IRQ_BLOCK_BIT(2, 6)
#define PM8921_CHGDONE_IRQ PM8921_IRQ_BLOCK_BIT(2, 5)
#define PM8921_CHGFAIL_IRQ PM8921_IRQ_BLOCK_BIT(2, 4)
#define PM8921_CHGSTATE_IRQ PM8921_IRQ_BLOCK_BIT(2, 3)
#define PM8921_LOOP_CHANGE_IRQ PM8921_IRQ_BLOCK_BIT(2, 2)
#define PM8921_FASTCHG_IRQ PM8921_IRQ_BLOCK_BIT(2, 1)
#define PM8921_TRKLCHG_IRQ PM8921_IRQ_BLOCK_BIT(2, 0)
#define PM8921_BATT_REMOVED_IRQ PM8921_IRQ_BLOCK_BIT(3, 7)
#define PM8921_BATTTEMP_HOT_IRQ PM8921_IRQ_BLOCK_BIT(3, 6)
#define PM8921_CHGHOT_IRQ PM8921_IRQ_BLOCK_BIT(3, 5)
#define PM8921_BATTTEMP_COLD_IRQ PM8921_IRQ_BLOCK_BIT(3, 4)
#define PM8921_CHG_GONE_IRQ PM8921_IRQ_BLOCK_BIT(3, 3)
#define PM8921_BAT_TEMP_OK_IRQ PM8921_IRQ_BLOCK_BIT(3, 2)
#define PM8921_COARSE_DET_LOW_IRQ PM8921_IRQ_BLOCK_BIT(3, 1)
#define PM8921_VDD_LOOP_IRQ PM8921_IRQ_BLOCK_BIT(3, 0)
#define PM8921_VREG_OV_IRQ PM8921_IRQ_BLOCK_BIT(5, 7)
#define PM8921_VBAT_IRQ PM8921_IRQ_BLOCK_BIT(5, 6)
#define PM8921_VBATDET_IRQ PM8921_IRQ_BLOCK_BIT(5, 5)
#define PM8921_BATFET_IRQ PM8921_IRQ_BLOCK_BIT(5, 4)
#define PM8921_PSI_IRQ PM8921_IRQ_BLOCK_BIT(5, 3)
#define PM8921_DCIN_VALID_IRQ PM8921_IRQ_BLOCK_BIT(5, 2)
#define PM8921_DCIN_OV_IRQ PM8921_IRQ_BLOCK_BIT(5, 1)
#define PM8921_DCIN_UV_IRQ PM8921_IRQ_BLOCK_BIT(5, 0)
/* PMIC I/O Resources */
#define PM8921_RTC_BASE 0x11D
@@ -61,6 +95,7 @@ struct pm8921_platform_data {
struct pm8xxx_rtc_platform_data *rtc_pdata;
struct pm8xxx_pwrkey_platform_data *pwrkey_pdata;
struct pm8xxx_keypad_platform_data *keypad_pdata;
struct pm8921_charger_platform_data *charger_pdata;
struct pm8921_regulator_platform_data *regulator_pdatas;
int num_regulators;
};