Merge "msm: qpnp-revid: Add api to return pmic revision id"
diff --git a/drivers/platform/msm/qpnp-revid.c b/drivers/platform/msm/qpnp-revid.c
index 9471188..a2876e0 100644
--- a/drivers/platform/msm/qpnp-revid.c
+++ b/drivers/platform/msm/qpnp-revid.c
@@ -13,6 +13,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spmi.h>
+#include <linux/err.h>
+#include <linux/qpnp-revid.h>
#define REVID_REVISION1 0x0
#define REVID_REVISION2 0x1
@@ -36,6 +38,15 @@
"PMD9635",
};
+struct revid_chip {
+ struct list_head link;
+ struct device_node *dev_node;
+ struct pmic_revid_data data;
+};
+
+static LIST_HEAD(revid_chips);
+static DEFINE_MUTEX(revid_chips_lock);
+
static struct of_device_id qpnp_revid_match_table[] = {
{ .compatible = QPNP_REVID_DEV_NAME },
{}
@@ -54,6 +65,35 @@
return val;
}
+/**
+ * get_revid_data - Return the revision information of PMIC
+ * @dev_node: Pointer to the revid peripheral of the PMIC for which
+ * revision information is seeked
+ *
+ * CONTEXT: Should be called in non atomic context
+ *
+ * RETURNS: pointer to struct pmic_revid_data filled with the information
+ * about the PMIC revision
+ */
+struct pmic_revid_data *get_revid_data(struct device_node *dev_node)
+{
+ struct revid_chip *revid_chip;
+
+ if (!dev_node)
+ return ERR_PTR(-EINVAL);
+
+ mutex_lock(&revid_chips_lock);
+ list_for_each_entry(revid_chip, &revid_chips, link) {
+ if (dev_node == revid_chip->dev_node) {
+ mutex_unlock(&revid_chips_lock);
+ return &revid_chip->data;
+ }
+ }
+ mutex_unlock(&revid_chips_lock);
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL(get_revid_data);
+
#define PM8941_PERIPHERAL_SUBTYPE 0x01
#define PM8226_PERIPHERAL_SUBTYPE 0x04
static size_t build_pmic_string(char *buf, size_t n, int sid,
@@ -94,6 +134,7 @@
u8 option1, option2, option3, option4;
struct resource *resource;
char pmic_string[PMIC_STRING_MAXLENGTH] = {'\0'};
+ struct revid_chip *revid_chip;
resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
if (!resource) {
@@ -114,6 +155,23 @@
pmic_subtype = qpnp_read_byte(spmi, resource->start + REVID_SUBTYPE);
pmic_status = qpnp_read_byte(spmi, resource->start + REVID_STATUS1);
+ revid_chip = devm_kzalloc(&spmi->dev, sizeof(struct revid_chip),
+ GFP_KERNEL);
+ if (!revid_chip)
+ return -ENOMEM;
+
+ revid_chip->dev_node = spmi->dev.of_node;
+ revid_chip->data.rev1 = rev1;
+ revid_chip->data.rev2 = rev2;
+ revid_chip->data.rev3 = rev3;
+ revid_chip->data.rev4 = rev4;
+ revid_chip->data.pmic_subtype = pmic_subtype;
+ revid_chip->data.pmic_type = pmic_type;
+
+ mutex_lock(&revid_chips_lock);
+ list_add(&revid_chip->link, &revid_chips);
+ mutex_unlock(&revid_chips_lock);
+
option1 = pmic_status & 0x3;
option2 = (pmic_status >> 2) & 0x3;
option3 = (pmic_status >> 4) & 0x3;
diff --git a/include/linux/qpnp-revid.h b/include/linux/qpnp-revid.h
new file mode 100644
index 0000000..3cf9f1c
--- /dev/null
+++ b/include/linux/qpnp-revid.h
@@ -0,0 +1,111 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 __QPNP_REVID
+#define __QPNP_REVID
+
+#define PM8226_V2P1_REV1 0x00
+#define PM8226_V2P1_REV2 0x00
+#define PM8226_V2P1_REV3 0x01
+#define PM8226_V2P1_REV4 0x02
+#define PM8226_V2P1_TYPE 0x51
+#define PM8226_V2P1_SUBTYPE 0x04
+
+#define PM8226_V2P0_REV1 0x00
+#define PM8226_V2P0_REV2 0x00
+#define PM8226_V2P0_REV3 0x00
+#define PM8226_V2P0_REV4 0x02
+#define PM8226_V2P0_TYPE 0x51
+#define PM8226_V2P0_SUBTYPE 0x04
+
+#define PM8226_V1P0_REV1 0x00
+#define PM8226_V1P0_REV2 0x00
+#define PM8226_V1P0_REV3 0x00
+#define PM8226_V1P0_REV4 0x00
+#define PM8226_V1P0_TYPE 0x51
+#define PM8226_V1P0_SUBTYPE 0x04
+
+#define PM8941_V1P0_REV1 0x00
+#define PM8941_V1P0_REV2 0x00
+#define PM8941_V1P0_REV3 0x00
+#define PM8941_V1P0_REV4 0x01
+#define PM8941_V1P0_TYPE 0x51
+#define PM8941_V1P0_SUBTYPE 0x01
+
+#define PM8941_V2P0_REV1 0x00
+#define PM8941_V2P0_REV2 0x00
+#define PM8941_V2P0_REV3 0x00
+#define PM8941_V2P0_REV4 0x01
+#define PM8941_V2P0_TYPE 0x51
+#define PM8941_V2P0_SUBTYPE 0x01
+
+#define PM8941_V3P0_REV1 0x00
+#define PM8941_V3P0_REV2 0x00
+#define PM8941_V3P0_REV3 0x00
+#define PM8941_V3P0_REV4 0x03
+#define PM8941_V3P0_TYPE 0x51
+#define PM8941_V3P0_SUBTYPE 0x01
+
+#define PM8941_V3P1_REV1 0x00
+#define PM8941_V3P1_REV2 0x00
+#define PM8941_V3P1_REV3 0x01
+#define PM8941_V3P1_REV4 0x03
+#define PM8941_V3P1_TYPE 0x51
+#define PM8941_V3P1_SUBTYPE 0x01
+
+#define PM8110_V1P0_REV1 0x00
+#define PM8110_V1P0_REV2 0x00
+#define PM8110_V1P0_REV3 0x00
+#define PM8110_V1P0_REV4 0x01
+#define PM8110_V1P0_TYPE 0x51
+#define PM8110_V1P0_SUBTYPE 0x05
+
+#define PM8110_V1P1_REV1 0x00
+#define PM8110_V1P1_REV2 0x01
+#define PM8110_V1P1_REV3 0x00
+#define PM8110_V1P1_REV4 0x01
+#define PM8110_V1P1_TYPE 0x51
+#define PM8110_V1P1_SUBTYPE 0x05
+
+#define PM8110_V1P3_REV1 0x00
+#define PM8110_V1P3_REV2 0x03
+#define PM8110_V1P3_REV3 0x00
+#define PM8110_V1P3_REV4 0x01
+#define PM8110_V1P3_TYPE 0x51
+#define PM8110_V1P3_SUBTYPE 0x05
+
+#define PM8110_V2P0_REV1 0x00
+#define PM8110_V2P0_REV2 0x00
+#define PM8110_V2P0_REV3 0x00
+#define PM8110_V2P0_REV4 0x02
+#define PM8110_V2P0_TYPE 0x51
+#define PM8110_V2P0_SUBTYPE 0x05
+
+struct pmic_revid_data {
+ u8 rev1;
+ u8 rev2;
+ u8 rev3;
+ u8 rev4;
+ u8 pmic_type;
+ u8 pmic_subtype;
+};
+
+#ifdef CONFIG_QPNP_REVID
+struct pmic_revid_data *get_revid_data(struct device_node *dev_node);
+#else
+static inline
+struct pmic_revid_data *get_revid_data(struct device_node *dev_node)
+{
+ return NULL;
+}
+#endif
+#endif