[PATCH V10 5/9] mfd: pm8008: Use i2c_new_dummy_device() API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use i2c_new_dummy_device() to register clients along with
the main mfd device.

Signed-off-by: Satya Priya <quic_c_skakit@xxxxxxxxxxx>
---
Changes in V10:
 - Implement i2c_new_dummy_device to register extra clients.

 drivers/mfd/qcom-pm8008.c       | 54 +++++++++++++++++++++++++++++++++--------
 include/linux/mfd/qcom_pm8008.h | 13 ++++++++++
 2 files changed, 57 insertions(+), 10 deletions(-)
 create mode 100644 include/linux/mfd/qcom_pm8008.h

diff --git a/drivers/mfd/qcom-pm8008.c b/drivers/mfd/qcom-pm8008.c
index 97a72da..ca5240d 100644
--- a/drivers/mfd/qcom-pm8008.c
+++ b/drivers/mfd/qcom-pm8008.c
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
+#include <linux/mfd/qcom_pm8008.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
@@ -56,8 +57,10 @@ enum {
 #define PM8008_PERIPH_OFFSET(paddr)	(paddr - PM8008_PERIPH_0_BASE)
 
 struct pm8008_data {
+	bool ready;
 	struct device *dev;
-	struct regmap *regmap;
+	struct i2c_client *clients[PM8008_NUM_CLIENTS];
+	struct regmap *regmap[PM8008_NUM_CLIENTS];
 	struct gpio_desc *reset_gpio;
 	int irq;
 	struct regmap_irq_chip_data *irq_data;
@@ -152,9 +155,20 @@ static struct regmap_config qcom_mfd_regmap_cfg = {
 	.max_register	= 0xFFFF,
 };
 
+struct regmap *pm8008_get_regmap(struct pm8008_data *chip, u8 sid)
+{
+	if (!chip || !chip->ready) {
+		pr_err("pm8008 chip not initialized\n");
+		return NULL;
+	}
+
+	return chip->regmap[sid];
+}
+
 static int pm8008_init(struct pm8008_data *chip)
 {
 	int rc;
+	struct regmap *regmap = pm8008_get_regmap(chip, PM8008_INFRA_SID);
 
 	/*
 	 * Set TEMP_ALARM peripheral's TYPE so that the regmap-irq framework
@@ -162,19 +176,19 @@ static int pm8008_init(struct pm8008_data *chip)
 	 * This is required to enable the writing of TYPE registers in
 	 * regmap_irq_sync_unlock().
 	 */
-	rc = regmap_write(chip->regmap,
+	rc = regmap_write(regmap,
 			 (PM8008_TEMP_ALARM_ADDR | INT_SET_TYPE_OFFSET),
 			 BIT(0));
 	if (rc)
 		return rc;
 
 	/* Do the same for GPIO1 and GPIO2 peripherals */
-	rc = regmap_write(chip->regmap,
+	rc = regmap_write(regmap,
 			 (PM8008_GPIO1_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
 	if (rc)
 		return rc;
 
-	rc = regmap_write(chip->regmap,
+	rc = regmap_write(regmap,
 			 (PM8008_GPIO2_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
 
 	return rc;
@@ -186,6 +200,7 @@ static int pm8008_probe_irq_peripherals(struct pm8008_data *chip,
 	int rc, i;
 	struct regmap_irq_type *type;
 	struct regmap_irq_chip_data *irq_data;
+	struct regmap *regmap = pm8008_get_regmap(chip, PM8008_INFRA_SID);
 
 	rc = pm8008_init(chip);
 	if (rc) {
@@ -209,7 +224,7 @@ static int pm8008_probe_irq_peripherals(struct pm8008_data *chip,
 				IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW);
 	}
 
-	rc = devm_regmap_add_irq_chip(chip->dev, chip->regmap, client_irq,
+	rc = devm_regmap_add_irq_chip(chip->dev, regmap, client_irq,
 			IRQF_SHARED, 0, &pm8008_irq_chip, &irq_data);
 	if (rc) {
 		dev_err(chip->dev, "Failed to add IRQ chip: %d\n", rc);
@@ -221,19 +236,38 @@ static int pm8008_probe_irq_peripherals(struct pm8008_data *chip,
 
 static int pm8008_probe(struct i2c_client *client)
 {
-	int rc;
+	int rc, i;
 	struct pm8008_data *chip;
+	struct device_node *node = client->dev.of_node;
 
 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 
 	chip->dev = &client->dev;
-	chip->regmap = devm_regmap_init_i2c(client, &qcom_mfd_regmap_cfg);
-	if (!chip->regmap)
-		return -ENODEV;
 
-	i2c_set_clientdata(client, chip);
+	for (i = 0; i < PM8008_NUM_CLIENTS; i++) {
+		if (i == 0) {
+			chip->clients[i] = client;
+		} else {
+			chip->clients[i] = i2c_new_dummy_device(client->adapter,
+								client->addr + i);
+			if (IS_ERR(chip->clients[i])) {
+				dev_err(&client->dev, "can't attach client %d\n", i);
+				return PTR_ERR(chip->clients[i]);
+			}
+			chip->clients[i]->dev.of_node = of_node_get(node);
+		}
+
+		chip->regmap[i] = devm_regmap_init_i2c(chip->clients[i],
+							&qcom_mfd_regmap_cfg);
+		if (!chip->regmap[i])
+			return -ENODEV;
+
+		i2c_set_clientdata(chip->clients[i], chip);
+	}
+
+	chip->ready = true;
 
 	if (of_property_read_bool(chip->dev->of_node, "interrupt-controller")) {
 		rc = pm8008_probe_irq_peripherals(chip, client->irq);
diff --git a/include/linux/mfd/qcom_pm8008.h b/include/linux/mfd/qcom_pm8008.h
new file mode 100644
index 0000000..bc64f01
--- /dev/null
+++ b/include/linux/mfd/qcom_pm8008.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __QCOM_PM8008_H__
+#define __QCOM_PM8008_H__
+
+#define PM8008_INFRA_SID	0
+#define PM8008_REGULATORS_SID	1
+
+#define PM8008_NUM_CLIENTS	2
+
+struct pm8008_data;
+struct regmap *pm8008_get_regmap(struct pm8008_data *chip, u8 sid);
+
+#endif
-- 
2.7.4




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux