mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
regulator: pm8921-regulator: Add regulator driver for PM8921
Create a regulator driver to control all regulators on the Qualcomm PM8921 PMIC chip. This chip contains many different types of regulators with a wide range of abilities and voltage ranges. Eight different regulator types are available on the PM8921. These are managed via 7 different type values in the driver: LDO - low drop out regulator (supports both NMOS and PMOS LDOs) NLDO1200 - 1.2A NMOS LDO (different control structure than other LDOs) SMPS - switched-mode power supply FTSMPS - fast transient SMPS VS - voltage switch VS300 - 300mA voltage switch (different control structure than other switches) NCP - negative charge pump The driver interfaces with the PMIC using Qualcomm's SSBI bus. Calls to this bus are abtracted through the pm8xxx_readb/writeb API. Change-Id: I01fb755c6be8e3f32c86fef079b5740edfc39f14 Signed-off-by: David Collins <collinsd@codeaurora.org> [sboyd: Take only pm8921-core bits]
This commit is contained in:
parent
28d08f40ce
commit
9c38a8d17d
2 changed files with 37 additions and 0 deletions
|
@ -30,6 +30,7 @@
|
|||
struct pm8921 {
|
||||
struct device *dev;
|
||||
struct pm_irq_chip *irq_chip;
|
||||
struct mfd_cell *mfd_regulators;
|
||||
};
|
||||
|
||||
static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
|
||||
|
@ -182,6 +183,8 @@ static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
|
|||
{
|
||||
int ret = 0, irq_base = 0;
|
||||
struct pm_irq_chip *irq_chip;
|
||||
static struct mfd_cell *mfd_regulators;
|
||||
int i;
|
||||
|
||||
if (pdata->irq_pdata) {
|
||||
pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS;
|
||||
|
@ -258,6 +261,36 @@ static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
|
|||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
* (pdata->num_regulators), GFP_KERNEL);
|
||||
if (!mfd_regulators) {
|
||||
pr_err("Cannot allocate %d bytes for pm8921 regulator "
|
||||
"mfd cells\n", sizeof(struct mfd_cell)
|
||||
* (pdata->num_regulators));
|
||||
ret = -ENOMEM;
|
||||
goto bail;
|
||||
}
|
||||
for (i = 0; i < pdata->num_regulators; i++) {
|
||||
mfd_regulators[i].name = PM8921_REGULATOR_DEV_NAME;
|
||||
mfd_regulators[i].id = pdata->regulator_pdatas[i].id;
|
||||
mfd_regulators[i].platform_data =
|
||||
&(pdata->regulator_pdatas[i]);
|
||||
mfd_regulators[i].pdata_size =
|
||||
sizeof(struct pm8921_regulator_platform_data);
|
||||
}
|
||||
ret = mfd_add_devices(pmic->dev, 0, mfd_regulators,
|
||||
pdata->num_regulators, NULL, irq_base);
|
||||
if (ret) {
|
||||
pr_err("Failed to add regulator subdevices ret=%d\n",
|
||||
ret);
|
||||
kfree(mfd_regulators);
|
||||
goto bail;
|
||||
}
|
||||
pmic->mfd_regulators = mfd_regulators;
|
||||
}
|
||||
|
||||
return 0;
|
||||
bail:
|
||||
if (pmic->irq_chip) {
|
||||
|
@ -343,6 +376,7 @@ static int __devexit pm8921_remove(struct platform_device *pdev)
|
|||
pmic->irq_chip = NULL;
|
||||
}
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(pmic->mfd_regulators);
|
||||
kfree(pmic);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/mfd/pm8xxx/rtc.h>
|
||||
#include <linux/input/pmic8xxx-pwrkey.h>
|
||||
#include <linux/input/pmic8xxx-keypad.h>
|
||||
#include <linux/regulator/pm8921-regulator.h>
|
||||
|
||||
#define PM8921_NR_IRQS 256
|
||||
|
||||
|
@ -59,6 +60,8 @@ 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_regulator_platform_data *regulator_pdatas;
|
||||
int num_regulators;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue