---
drivers/mfd/qcom-spmi-pmic.c | 108 +++++++++++++++++------------------
include/soc/qcom/qcom-pmic.h | 63 ++++++++++++++++++++
2 files changed, 114 insertions(+), 57 deletions(-)
create mode 100644 include/soc/qcom/qcom-pmic.h
diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c
index 1cacc00aa6c9..6b75c2f52b74 100644
--- a/drivers/mfd/qcom-spmi-pmic.c
+++ b/drivers/mfd/qcom-spmi-pmic.c
@@ -3,51 +3,24 @@
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*/
+#include <linux/device.h>
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/spmi.h>
#include <linux/regmap.h>
#include <linux/of_platform.h>
+#include <soc/qcom/qcom-pmic.h>
#define PMIC_REV2 0x101
#define PMIC_REV3 0x102
#define PMIC_REV4 0x103
#define PMIC_TYPE 0x104
#define PMIC_SUBTYPE 0x105
-
+#define PMIC_FAB_ID 0x1f2
#define PMIC_TYPE_VALUE 0x51
-#define COMMON_SUBTYPE 0x00
-#define PM8941_SUBTYPE 0x01
-#define PM8841_SUBTYPE 0x02
-#define PM8019_SUBTYPE 0x03
-#define PM8226_SUBTYPE 0x04
-#define PM8110_SUBTYPE 0x05
-#define PMA8084_SUBTYPE 0x06
-#define PMI8962_SUBTYPE 0x07
-#define PMD9635_SUBTYPE 0x08
-#define PM8994_SUBTYPE 0x09
-#define PMI8994_SUBTYPE 0x0a
-#define PM8916_SUBTYPE 0x0b
-#define PM8004_SUBTYPE 0x0c
-#define PM8909_SUBTYPE 0x0d
-#define PM8028_SUBTYPE 0x0e
-#define PM8901_SUBTYPE 0x0f
-#define PM8950_SUBTYPE 0x10
-#define PMI8950_SUBTYPE 0x11
-#define PM8998_SUBTYPE 0x14
-#define PMI8998_SUBTYPE 0x15
-#define PM8005_SUBTYPE 0x18
-#define PM660L_SUBTYPE 0x1A
-#define PM660_SUBTYPE 0x1B
-#define PM8150_SUBTYPE 0x1E
-#define PM8150L_SUBTYPE 0x1f
-#define PM8150B_SUBTYPE 0x20
-#define PMK8002_SUBTYPE 0x21
-#define PM8009_SUBTYPE 0x24
-#define PM8150C_SUBTYPE 0x26
-#define SMB2351_SUBTYPE 0x29
-
static const struct of_device_id pmic_spmi_id_table[] = {
{ .compatible = "qcom,pm660", .data = (void *)PM660_SUBTYPE },
{ .compatible = "qcom,pm660l", .data = (void *)PM660L_SUBTYPE },
@@ -81,42 +54,47 @@ static const struct of_device_id pmic_spmi_id_table[] = {
{ }
};
-static void pmic_spmi_show_revid(struct regmap *map, struct device *dev)
+static int pmic_spmi_load_revid(struct regmap *map, struct device *dev,
+ struct qcom_spmi_pmic *pmic)
{
- unsigned int rev2, minor, major, type, subtype;
- const char *name = "unknown";
int ret, i;
- ret = regmap_read(map, PMIC_TYPE, &type);
+ ret = regmap_read(map, PMIC_TYPE, &pmic->type);
if (ret < 0)
- return;
+ return ret;
- if (type != PMIC_TYPE_VALUE)
- return;
+ if (pmic->type != PMIC_TYPE_VALUE)
+ return ret;
- ret = regmap_read(map, PMIC_SUBTYPE, &subtype);
+ ret = regmap_read(map, PMIC_SUBTYPE, &pmic->subtype);
if (ret < 0)
- return;
+ return ret;
for (i = 0; i < ARRAY_SIZE(pmic_spmi_id_table); i++) {
- if (subtype == (unsigned long)pmic_spmi_id_table[i].data)
+ if (pmic->subtype == (unsigned long)pmic_spmi_id_table[i].data)
break;
}
if (i != ARRAY_SIZE(pmic_spmi_id_table))
- name = pmic_spmi_id_table[i].compatible;
+ pmic->name = devm_kstrdup_const(dev, pmic_spmi_id_table[i].compatible, GFP_KERNEL);
- ret = regmap_read(map, PMIC_REV2, &rev2);
+ ret = regmap_read(map, PMIC_REV2, &pmic->rev2);
if (ret < 0)
- return;
+ return ret;
- ret = regmap_read(map, PMIC_REV3, &minor);
+ ret = regmap_read(map, PMIC_REV3, &pmic->minor);
if (ret < 0)
- return;
+ return ret;
- ret = regmap_read(map, PMIC_REV4, &major);
+ ret = regmap_read(map, PMIC_REV4, &pmic->major);
if (ret < 0)
- return;
+ return ret;
+
+ if (pmic->subtype == PMI8998_SUBTYPE || pmic->subtype == PM660_SUBTYPE) {
+ ret = regmap_read(map, PMIC_FAB_ID, &pmic->fab_id);
+ if (ret < 0)
+ return ret;
+ }
/*
* In early versions of PM8941 and PM8226, the major revision number
@@ -124,14 +102,14 @@ static void pmic_spmi_show_revid(struct regmap *map, struct device *dev)
* Increment the major revision number here if the chip is an early
* version of PM8941 or PM8226.
*/
- if ((subtype == PM8941_SUBTYPE || subtype == PM8226_SUBTYPE) &&
- major < 0x02)
- major++;
+ if ((pmic->subtype == PM8941_SUBTYPE || pmic->subtype == PM8226_SUBTYPE) &&
+ pmic->major < 0x02)
+ pmic->major++;
- if (subtype == PM8110_SUBTYPE)
- minor = rev2;
+ if (pmic->subtype == PM8110_SUBTYPE)
+ pmic->minor = pmic->rev2;
- dev_dbg(dev, "%x: %s v%d.%d\n", subtype, name, major, minor);
+ return 0;
}
static const struct regmap_config spmi_regmap_config = {
@@ -144,22 +122,38 @@ static const struct regmap_config spmi_regmap_config = {
static int pmic_spmi_probe(struct spmi_device *sdev)
{
struct regmap *regmap;
+ struct qcom_spmi_pmic *pmic;
regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
+ pmic = devm_kzalloc(&sdev->dev, sizeof(*pmic), GFP_KERNEL);
+ if (!pmic)
+ return -ENOMEM;