diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c index 93b68b41937..5078803d1b6 100644 --- a/drivers/mfd/pm8921-core.c +++ b/drivers/mfd/pm8921-core.c @@ -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) diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h new file mode 100644 index 00000000000..734661c97de --- /dev/null +++ b/include/linux/mfd/pm8xxx/pm8921-charger.h @@ -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 + +#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 diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h index d00a3c9a482..ddf152f870a 100644 --- a/include/linux/mfd/pm8xxx/pm8921.h +++ b/include/linux/mfd/pm8xxx/pm8921.h @@ -26,6 +26,7 @@ #include #include #include +#include #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; };