mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement
@ 2013-06-14  5:21 Chao Xie
  2013-06-14  5:21 ` [PATCH V2 1/9] mfd: 88pm800: fix NULL pointer error Chao Xie
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

The patch set fixes some bugs in the 88pm800/88pm805 driver, and it add
regulator device into 88pm800.

The patches are tested based on Marvell pxa988 platform.

V2->V1:
  add more fixes patches.
  Below patches are same almost same as V1
     mfd: 88pm800: fix NULL pointer errorm
     mfd: 88pm800/88pm805: remove "IRQF_TRIGGER_FALLING" flag
  Other patches are new.

Chao Xie (7):
  mfd: 88pm80x: fix driver name for 88pm800 and 88pm805
  mfd: 88pm800: fix for mask_invert
  mfd: 88pm800: remove the power and gpadc page addr from platform data
  mfd: 88pm800: fixes error handling for sub pages probe/remove
  mfd: 88pm80x: Changes chip id definition and detection
  mfd: 88pm800: enhance sub devices initialization
  mfd: 88pm800: add regulator sub device

Yi Zhang (2):
  mfd: 88pm800: fix NULL pointer error
  mfd: 88pm800/88pm805: remove "IRQF_TRIGGER_FALLING" flag

 drivers/mfd/88pm800.c       |  237 +++++++++++++++++++++++++------------------
 drivers/mfd/88pm805.c       |   20 +---
 drivers/mfd/88pm80x.c       |   47 +++++++--
 include/linux/mfd/88pm80x.h |   17 ++--
 4 files changed, 193 insertions(+), 128 deletions(-)

-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 1/9] mfd: 88pm800: fix NULL pointer error
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-14  5:21 ` [PATCH V2 2/9] mfd: 88pm80x: fix driver name for 88pm800 and 88pm805 Chao Xie
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

From: Yi Zhang <yizhang@marvell.com>

move "device_800_init" to fix NULL pointer error when
calling "device_gpadc_init"

for "device_gpadc_init" needs "subchip->regmap_gpadc"
to set registers via regmap interface

Signed-off-by: Yi Zhang <yizhang@marvell.com>
Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index 582bda5..b2f9f0f 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -528,24 +528,26 @@ static int pm800_probe(struct i2c_client *client,
 	subchip->gpadc_page_addr = pdata->gpadc_page_addr;
 	chip->subchip = subchip;
 
-	ret = device_800_init(chip, pdata);
-	if (ret) {
-		dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id);
-		goto err_subchip_alloc;
-	}
-
 	ret = pm800_pages_init(chip);
 	if (ret) {
 		dev_err(&client->dev, "pm800_pages_init failed!\n");
 		goto err_page_init;
 	}
 
+	ret = device_800_init(chip, pdata);
+	if (ret) {
+		dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id);
+		goto err_device_init;
+	}
+
 	if (pdata->plat_config)
 		pdata->plat_config(chip, pdata);
 
+	return 0;
+
+err_device_init:
+	pm800_pages_exit(chip);
 err_page_init:
-	mfd_remove_devices(chip->dev);
-	device_irq_exit_800(chip);
 err_subchip_alloc:
 	pm80x_deinit();
 out_init:
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 2/9] mfd: 88pm80x: fix driver name for 88pm800 and 88pm805
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
  2013-06-14  5:21 ` [PATCH V2 1/9] mfd: 88pm800: fix NULL pointer error Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-14  5:21 ` [PATCH V2 3/9] mfd: 88pm800: fix for mask_invert Chao Xie
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

88pm800 has same driver name as 88pm805. Fix it.

Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c |    2 +-
 drivers/mfd/88pm805.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index b2f9f0f..0801049 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -569,7 +569,7 @@ static int pm800_remove(struct i2c_client *client)
 
 static struct i2c_driver pm800_driver = {
 	.driver = {
-		.name = "88PM80X",
+		.name = "88PM800",
 		.owner = THIS_MODULE,
 		.pm = &pm80x_pm_ops,
 		},
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
index 65d7ac09..d32b544 100644
--- a/drivers/mfd/88pm805.c
+++ b/drivers/mfd/88pm805.c
@@ -276,7 +276,7 @@ static int pm805_remove(struct i2c_client *client)
 
 static struct i2c_driver pm805_driver = {
 	.driver = {
-		.name = "88PM80X",
+		.name = "88PM805",
 		.owner = THIS_MODULE,
 		.pm = &pm80x_pm_ops,
 		},
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 3/9] mfd: 88pm800: fix for mask_invert
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
  2013-06-14  5:21 ` [PATCH V2 1/9] mfd: 88pm800: fix NULL pointer error Chao Xie
  2013-06-14  5:21 ` [PATCH V2 2/9] mfd: 88pm80x: fix driver name for 88pm800 and 88pm805 Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-14  5:21 ` [PATCH V2 4/9] mfd: 88pm800/88pm805: remove "IRQF_TRIGGER_FALLING" flag Chao Xie
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

mask_invert must be set. Or interrupt cannot be cleared.

Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index 0801049..cca63f2 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -362,6 +362,7 @@ static struct regmap_irq_chip pm800_irq_chip = {
 	.status_base = PM800_INT_STATUS1,
 	.mask_base = PM800_INT_ENA_1,
 	.ack_base = PM800_INT_STATUS1,
+	.mask_invert = 1,
 };
 
 static int pm800_pages_init(struct pm80x_chip *chip)
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 4/9] mfd: 88pm800/88pm805: remove "IRQF_TRIGGER_FALLING" flag
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
                   ` (2 preceding siblings ...)
  2013-06-14  5:21 ` [PATCH V2 3/9] mfd: 88pm800: fix for mask_invert Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-14  5:21 ` [PATCH V2 5/9] mfd: 88pm800: remove the power and gpadc page addr from platform data Chao Xie
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

From: Yi Zhang <yizhang@marvell.com>

88pm800/88pm805 interrupt is asserted low if the events happened.
So remove IRQF_TRIGGER_FALLING for irq request.
How the interrupt is connected to SOC chip depends on the board design.
So do not set IRQF_TRIGGER flags.

Signed-off-by: Yi Zhang <yizhang@marvell.com>
Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c |    2 +-
 drivers/mfd/88pm805.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index cca63f2..d2951d7 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -318,7 +318,7 @@ out:
 static int device_irq_init_800(struct pm80x_chip *chip)
 {
 	struct regmap *map = chip->regmap;
-	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+	unsigned long flags = IRQF_ONESHOT;
 	int data, mask, ret = -EINVAL;
 
 	if (!map || !chip->irq) {
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
index d32b544..0e82c2a 100644
--- a/drivers/mfd/88pm805.c
+++ b/drivers/mfd/88pm805.c
@@ -138,7 +138,7 @@ static struct regmap_irq pm805_irqs[] = {
 static int device_irq_init_805(struct pm80x_chip *chip)
 {
 	struct regmap *map = chip->regmap;
-	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+	unsigned long flags = IRQF_ONESHOT;
 	int data, mask, ret = -EINVAL;
 
 	if (!map || !chip->irq) {
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 5/9] mfd: 88pm800: remove the power and gpadc page addr from platform data
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
                   ` (3 preceding siblings ...)
  2013-06-14  5:21 ` [PATCH V2 4/9] mfd: 88pm800/88pm805: remove "IRQF_TRIGGER_FALLING" flag Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-14  5:21 ` [PATCH V2 6/9] mfd: 88pm800: fixes error handling for sub pages probe/remove Chao Xie
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

88pm800 has two addtional pages - power and gpadc.
The address of the pages depends on the address of 88pm800.
So do not need pass the address of the power and gpadc in
platform data.

Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c       |    5 +++--
 include/linux/mfd/88pm80x.h |    2 --
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index d2951d7..6b607ad 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -525,8 +525,9 @@ static int pm800_probe(struct i2c_client *client,
 		goto err_subchip_alloc;
 	}
 
-	subchip->power_page_addr = pdata->power_page_addr;
-	subchip->gpadc_page_addr = pdata->gpadc_page_addr;
+	/* pm800 has 2 addtional pages to support power and gpadc. */
+	subchip->power_page_addr = client->addr + 1;
+	subchip->gpadc_page_addr = client->addr + 2;
 	chip->subchip = subchip;
 
 	ret = pm800_pages_init(chip);
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index e94537b..023e639 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -309,8 +309,6 @@ struct pm80x_chip {
 
 struct pm80x_platform_data {
 	struct pm80x_rtc_pdata *rtc;
-	unsigned short power_page_addr;	/* power page I2C address */
-	unsigned short gpadc_page_addr;	/* gpadc page I2C address */
 	int irq_mode;		/* Clear interrupt by read/write(0/1) */
 	int batt_det;		/* enable/disable */
 	int (*plat_config)(struct pm80x_chip *chip,
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 6/9] mfd: 88pm800: fixes error handling for sub pages probe/remove
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
                   ` (4 preceding siblings ...)
  2013-06-14  5:21 ` [PATCH V2 5/9] mfd: 88pm800: remove the power and gpadc page addr from platform data Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-14  5:21 ` [PATCH V2 7/9] mfd: 88pm80x: Changes chip id definition and detection Chao Xie
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

pm800_pages_init and pm800_pages_exit are called by pm800_probe.
Change the code to enhance error handling and remove unused code at
pm800_pages_init/exit and pm800_probe.

Signed-off-by: Yi Zhang <yizhang@marvell.com>
Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c |   80 ++++++++++++++++++++++++++++--------------------
 1 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index 6b607ad..932ebe8 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -370,50 +370,64 @@ static int pm800_pages_init(struct pm80x_chip *chip)
 	struct pm80x_subchip *subchip;
 	struct i2c_client *client = chip->client;
 
+	int ret = 0;
+
 	subchip = chip->subchip;
-	/* PM800 block power: i2c addr 0x31 */
-	if (subchip->power_page_addr) {
-		subchip->power_page =
-		    i2c_new_dummy(client->adapter, subchip->power_page_addr);
-		subchip->regmap_power =
-		    devm_regmap_init_i2c(subchip->power_page,
-					 &pm80x_regmap_config);
-		i2c_set_clientdata(subchip->power_page, chip);
-	} else
-		dev_info(chip->dev,
-			 "PM800 block power 0x31: No power_page_addr\n");
-
-	/* PM800 block GPADC: i2c addr 0x32 */
-	if (subchip->gpadc_page_addr) {
-		subchip->gpadc_page = i2c_new_dummy(client->adapter,
-						    subchip->gpadc_page_addr);
-		subchip->regmap_gpadc =
-		    devm_regmap_init_i2c(subchip->gpadc_page,
-					 &pm80x_regmap_config);
-		i2c_set_clientdata(subchip->gpadc_page, chip);
-	} else
-		dev_info(chip->dev,
-			 "PM800 block GPADC 0x32: No gpadc_page_addr\n");
+	if (!subchip || !subchip->power_page_addr || !subchip->gpadc_page_addr)
+		return -ENODEV;
+
+	/* PM800 block power page */
+	subchip->power_page = i2c_new_dummy(client->adapter,
+					    subchip->power_page_addr);
+	if (subchip->power_page == NULL) {
+		ret = -ENODEV;
+		goto out;
+	}
 
-	return 0;
+	subchip->regmap_power = devm_regmap_init_i2c(subchip->power_page,
+						     &pm80x_regmap_config);
+	if (IS_ERR(subchip->regmap_power)) {
+		ret = PTR_ERR(subchip->regmap_power);
+		dev_err(chip->dev,
+			"Failed to allocate regmap_power: %d\n", ret);
+		goto out;
+	}
+
+	i2c_set_clientdata(subchip->power_page, chip);
+
+	/* PM800 block GPADC */
+	subchip->gpadc_page = i2c_new_dummy(client->adapter,
+					    subchip->gpadc_page_addr);
+	if (subchip->gpadc_page == NULL) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	subchip->regmap_gpadc = devm_regmap_init_i2c(subchip->gpadc_page,
+						     &pm80x_regmap_config);
+	if (IS_ERR(subchip->regmap_gpadc)) {
+		ret = PTR_ERR(subchip->regmap_gpadc);
+		dev_err(chip->dev,
+			"Failed to allocate regmap_gpadc: %d\n", ret);
+		goto out;
+	}
+	i2c_set_clientdata(subchip->gpadc_page, chip);
+
+out:
+	return ret;
 }
 
 static void pm800_pages_exit(struct pm80x_chip *chip)
 {
 	struct pm80x_subchip *subchip;
 
-	regmap_exit(chip->regmap);
-	i2c_unregister_device(chip->client);
-
 	subchip = chip->subchip;
-	if (subchip->power_page) {
-		regmap_exit(subchip->regmap_power);
+
+	if (subchip && subchip->power_page)
 		i2c_unregister_device(subchip->power_page);
-	}
-	if (subchip->gpadc_page) {
-		regmap_exit(subchip->regmap_gpadc);
+
+	if (subchip && subchip->gpadc_page)
 		i2c_unregister_device(subchip->gpadc_page);
-	}
 }
 
 static int device_800_init(struct pm80x_chip *chip,
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 7/9] mfd: 88pm80x: Changes chip id definition and detection
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
                   ` (5 preceding siblings ...)
  2013-06-14  5:21 ` [PATCH V2 6/9] mfd: 88pm800: fixes error handling for sub pages probe/remove Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-14  5:21 ` [PATCH V2 8/9] mfd: 88pm800: enhance sub devices initialization Chao Xie
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

Change the chip id definition and detection.
It brings the benefits
1. do not need add PM800_CHIP_XXX for the coming revision.
2. do not need pass driver_data in i2c_device_id because we
   can distinguish the chips by CHIP_ID register.

Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c       |   42 +++++--------------------------------
 drivers/mfd/88pm805.c       |   16 ++-----------
 drivers/mfd/88pm80x.c       |   47 ++++++++++++++++++++++++++++++++++++------
 include/linux/mfd/88pm80x.h |    7 +----
 4 files changed, 51 insertions(+), 61 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index 932ebe8..16faad6 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -27,8 +27,6 @@
 #include <linux/mfd/88pm80x.h>
 #include <linux/slab.h>
 
-#define PM800_CHIP_ID			(0x00)
-
 /* Interrupt Registers */
 #define PM800_INT_STATUS1		(0x05)
 #define PM800_ONKEY_INT_STS1		(1 << 0)
@@ -113,20 +111,11 @@ enum {
 	PM800_MAX_IRQ,
 };
 
-enum {
-	/* Procida */
-	PM800_CHIP_A0  = 0x60,
-	PM800_CHIP_A1  = 0x61,
-	PM800_CHIP_B0  = 0x62,
-	PM800_CHIP_C0  = 0x63,
-	PM800_CHIP_END = PM800_CHIP_C0,
-
-	/* Make sure to update this to the last stepping */
-	PM8XXX_CHIP_END = PM800_CHIP_END
-};
+/* PM800: generation identification number */
+#define PM800_CHIP_GEN_ID_NUM	0x3
 
 static const struct i2c_device_id pm80x_id_table[] = {
-	{"88PM800", CHIP_PM800},
+	{"88PM800", 0},
 	{} /* NULL terminated */
 };
 MODULE_DEVICE_TABLE(i2c, pm80x_id_table);
@@ -433,28 +422,9 @@ static void pm800_pages_exit(struct pm80x_chip *chip)
 static int device_800_init(struct pm80x_chip *chip,
 				     struct pm80x_platform_data *pdata)
 {
-	int ret, pmic_id;
+	int ret;
 	unsigned int val;
 
-	ret = regmap_read(chip->regmap, PM800_CHIP_ID, &val);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
-		goto out;
-	}
-
-	pmic_id = val & PM80X_VERSION_MASK;
-
-	if ((pmic_id >= PM800_CHIP_A0) && (pmic_id <= PM800_CHIP_END)) {
-		chip->version = val;
-		dev_info(chip->dev,
-			 "88PM80x:Marvell 88PM800 (ID:0x%x) detected\n", val);
-	} else {
-		dev_err(chip->dev,
-			"Failed to detect Marvell 88PM800:ChipID[0x%x]\n", val);
-		ret = -EINVAL;
-		goto out;
-	}
-
 	/*
 	 * alarm wake up bit will be clear in device_irq_init(),
 	 * read before that
@@ -522,7 +492,7 @@ static int pm800_probe(struct i2c_client *client,
 	struct pm80x_platform_data *pdata = client->dev.platform_data;
 	struct pm80x_subchip *subchip;
 
-	ret = pm80x_init(client, id);
+	ret = pm80x_init(client);
 	if (ret) {
 		dev_err(&client->dev, "pm800_init fail\n");
 		goto out_init;
@@ -552,7 +522,7 @@ static int pm800_probe(struct i2c_client *client,
 
 	ret = device_800_init(chip, pdata);
 	if (ret) {
-		dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id);
+		dev_err(chip->dev, "Failed to initialize 88pm800 devices\n");
 		goto err_device_init;
 	}
 
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
index 0e82c2a..5216022 100644
--- a/drivers/mfd/88pm805.c
+++ b/drivers/mfd/88pm805.c
@@ -29,10 +29,8 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
-#define PM805_CHIP_ID			(0x00)
-
 static const struct i2c_device_id pm80x_id_table[] = {
-	{"88PM805", CHIP_PM805},
+	{"88PM805", 0},
 	{} /* NULL terminated */
 };
 MODULE_DEVICE_TABLE(i2c, pm80x_id_table);
@@ -192,7 +190,6 @@ static struct regmap_irq_chip pm805_irq_chip = {
 static int device_805_init(struct pm80x_chip *chip)
 {
 	int ret = 0;
-	unsigned int val;
 	struct regmap *map = chip->regmap;
 
 	if (!map) {
@@ -200,13 +197,6 @@ static int device_805_init(struct pm80x_chip *chip)
 		return -EINVAL;
 	}
 
-	ret = regmap_read(map, PM805_CHIP_ID, &val);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
-		goto out_irq_init;
-	}
-	chip->version = val;
-
 	chip->regmap_irq_chip = &pm805_irq_chip;
 
 	ret = device_irq_init_805(chip);
@@ -239,7 +229,7 @@ static int pm805_probe(struct i2c_client *client,
 	struct pm80x_chip *chip;
 	struct pm80x_platform_data *pdata = client->dev.platform_data;
 
-	ret = pm80x_init(client, id);
+	ret = pm80x_init(client);
 	if (ret) {
 		dev_err(&client->dev, "pm805_init fail!\n");
 		goto out_init;
@@ -249,7 +239,7 @@ static int pm805_probe(struct i2c_client *client,
 
 	ret = device_805_init(chip);
 	if (ret) {
-		dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id);
+		dev_err(chip->dev, "Failed to initialize 88pm805 devices\n");
 		goto err_805_init;
 	}
 
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
index f736a46..5e72f65 100644
--- a/drivers/mfd/88pm80x.c
+++ b/drivers/mfd/88pm80x.c
@@ -18,6 +18,23 @@
 #include <linux/uaccess.h>
 #include <linux/err.h>
 
+/* 88pm80x chips have same definition for chip id register. */
+#define PM80X_CHIP_ID			(0x00)
+#define PM80X_CHIP_ID_NUM(x)		(((x) >> 5) & 0x7)
+#define PM80X_CHIP_ID_REVISION(x)	((x) & 0x1F)
+
+struct pm80x_chip_mapping {
+	unsigned int	id;
+	int		type;
+};
+
+static struct pm80x_chip_mapping chip_mapping[] = {
+	/* 88PM800 chip id number */
+	{0x3,	CHIP_PM800},
+	/* 88PM805 chip id number */
+	{0x0,	CHIP_PM805},
+};
+
 /*
  * workaround: some registers needed by pm805 are defined in pm800, so
  * need to use this global variable to maintain the relation between
@@ -31,12 +48,13 @@ const struct regmap_config pm80x_regmap_config = {
 };
 EXPORT_SYMBOL_GPL(pm80x_regmap_config);
 
-int pm80x_init(struct i2c_client *client,
-				 const struct i2c_device_id *id)
+
+int pm80x_init(struct i2c_client *client)
 {
 	struct pm80x_chip *chip;
 	struct regmap *map;
-	int ret = 0;
+	unsigned int val;
+	int i, ret = 0;
 
 	chip =
 	    devm_kzalloc(&client->dev, sizeof(struct pm80x_chip), GFP_KERNEL);
@@ -51,10 +69,6 @@ int pm80x_init(struct i2c_client *client,
 		return ret;
 	}
 
-	chip->id = id->driver_data;
-	if (chip->id < CHIP_PM800 || chip->id > CHIP_PM805)
-		return -EINVAL;
-
 	chip->client = client;
 	chip->regmap = map;
 
@@ -64,6 +78,25 @@ int pm80x_init(struct i2c_client *client,
 	dev_set_drvdata(chip->dev, chip);
 	i2c_set_clientdata(chip->client, chip);
 
+	ret = regmap_read(chip->regmap, PM80X_CHIP_ID, &val);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(chip_mapping); i++) {
+		if (chip_mapping[i].id == PM80X_CHIP_ID_NUM(val)) {
+			chip->type = chip_mapping[i].type;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(chip_mapping)) {
+		dev_err(chip->dev,
+			"Failed to detect Marvell 88PM800:ChipID[0x%x]\n", val);
+		return -EINVAL;
+	}
+
 	device_init_wakeup(&client->dev, 1);
 
 	/*
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index 023e639..4a66a56 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -17,7 +17,6 @@
 #include <linux/regmap.h>
 #include <linux/atomic.h>
 
-#define PM80X_VERSION_MASK		(0xFF)	/* 80X chip ID mask */
 enum {
 	CHIP_INVALID = 0,
 	CHIP_PM800,
@@ -299,8 +298,7 @@ struct pm80x_chip {
 	struct regmap *regmap;
 	struct regmap_irq_chip *regmap_irq_chip;
 	struct regmap_irq_chip_data *irq_data;
-	unsigned char version;
-	int id;
+	int type;
 	int irq;
 	int irq_mode;
 	unsigned long wu_flag;
@@ -361,7 +359,6 @@ static inline int pm80x_dev_resume(struct device *dev)
 }
 #endif
 
-extern int pm80x_init(struct i2c_client *client,
-		      const struct i2c_device_id *id);
+extern int pm80x_init(struct i2c_client *client);
 extern int pm80x_deinit(void);
 #endif /* __LINUX_MFD_88PM80X_H */
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 8/9] mfd: 88pm800: enhance sub devices initialization
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
                   ` (6 preceding siblings ...)
  2013-06-14  5:21 ` [PATCH V2 7/9] mfd: 88pm80x: Changes chip id definition and detection Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-14  5:21 ` [PATCH V2 9/9] mfd: 88pm800: add regulator sub device Chao Xie
  2013-06-17 23:07 ` [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Samuel Ortiz
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

Separate the devices initialization into different functions.
It makes the probe function clearly.

Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c |   61 +++++++++++++++++++++++++++++++++---------------
 1 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index 16faad6..35c7fe8 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -304,6 +304,40 @@ out:
 	return ret;
 }
 
+static int device_onkey_init(struct pm80x_chip *chip,
+				struct pm80x_platform_data *pdata)
+{
+	int ret;
+
+	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
+			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
+			      NULL);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add onkey subdev\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int device_rtc_init(struct pm80x_chip *chip,
+				struct pm80x_platform_data *pdata)
+{
+	int ret;
+
+	rtc_devs[0].platform_data = pdata->rtc;
+	rtc_devs[0].pdata_size =
+			pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
+	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
+			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add rtc subdev\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int device_irq_init_800(struct pm80x_chip *chip)
 {
 	struct regmap *map = chip->regmap;
@@ -453,27 +487,16 @@ static int device_800_init(struct pm80x_chip *chip,
 		goto out;
 	}
 
-	ret =
-	    mfd_add_devices(chip->dev, 0, &onkey_devs[0],
-			    ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
-			    NULL);
-	if (ret < 0) {
+	ret = device_onkey_init(chip, pdata);
+	if (ret) {
 		dev_err(chip->dev, "Failed to add onkey subdev\n");
 		goto out_dev;
-	} else
-		dev_info(chip->dev, "[%s]:Added mfd onkey_devs\n", __func__);
-
-	if (pdata && pdata->rtc) {
-		rtc_devs[0].platform_data = pdata->rtc;
-		rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata);
-		ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
-				      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
-		if (ret < 0) {
-			dev_err(chip->dev, "Failed to add rtc subdev\n");
-			goto out_dev;
-		} else
-			dev_info(chip->dev,
-				 "[%s]:Added mfd rtc_devs\n", __func__);
+	}
+
+	ret = device_rtc_init(chip, pdata);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add rtc subdev\n");
+		goto out;
 	}
 
 	return 0;
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V2 9/9] mfd: 88pm800: add regulator sub device
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
                   ` (7 preceding siblings ...)
  2013-06-14  5:21 ` [PATCH V2 8/9] mfd: 88pm800: enhance sub devices initialization Chao Xie
@ 2013-06-14  5:21 ` Chao Xie
  2013-06-17 23:07 ` [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Samuel Ortiz
  9 siblings, 0 replies; 11+ messages in thread
From: Chao Xie @ 2013-06-14  5:21 UTC (permalink / raw)
  To: linux-kernel, sameo, yizhang; +Cc: Chao Xie

Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/mfd/88pm800.c       |   28 ++++++++++++++++++++++++++++
 include/linux/mfd/88pm80x.h |    8 ++++++++
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index 35c7fe8..ec9d815 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -156,6 +156,13 @@ static struct mfd_cell onkey_devs[] = {
 	 },
 };
 
+static struct mfd_cell regulator_devs[] = {
+	{
+	 .name = "88pm80x-regulator",
+	 .id = -1,
+	},
+};
+
 static const struct regmap_irq pm800_irqs[] = {
 	/* INT0 */
 	[PM800_IRQ_ONKEY] = {
@@ -338,6 +345,21 @@ static int device_rtc_init(struct pm80x_chip *chip,
 	return 0;
 }
 
+static int device_regulator_init(struct pm80x_chip *chip,
+					   struct pm80x_platform_data *pdata)
+{
+	int ret;
+
+	ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
+			      ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add regulator subdev\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int device_irq_init_800(struct pm80x_chip *chip)
 {
 	struct regmap *map = chip->regmap;
@@ -499,6 +521,12 @@ static int device_800_init(struct pm80x_chip *chip,
 		goto out;
 	}
 
+	ret = device_regulator_init(chip, pdata);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add regulators subdev\n");
+		goto out;
+	}
+
 	return 0;
 out_dev:
 	mfd_remove_devices(chip->dev);
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index 4a66a56..97cb283 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -307,6 +307,14 @@ struct pm80x_chip {
 
 struct pm80x_platform_data {
 	struct pm80x_rtc_pdata *rtc;
+	/*
+	 * For the regulator not defined, set regulators[not_defined] to be
+	 * NULL. num_regulators are the number of regulators supposed to be
+	 * initialized. If all regulators are not defined, set num_regulators
+	 * to be 0.
+	 */
+	struct regulator_init_data *regulators[PM800_ID_RG_MAX];
+	unsigned int num_regulators;
 	int irq_mode;		/* Clear interrupt by read/write(0/1) */
 	int batt_det;		/* enable/disable */
 	int (*plat_config)(struct pm80x_chip *chip,
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement
  2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
                   ` (8 preceding siblings ...)
  2013-06-14  5:21 ` [PATCH V2 9/9] mfd: 88pm800: add regulator sub device Chao Xie
@ 2013-06-17 23:07 ` Samuel Ortiz
  9 siblings, 0 replies; 11+ messages in thread
From: Samuel Ortiz @ 2013-06-17 23:07 UTC (permalink / raw)
  To: Chao Xie; +Cc: linux-kernel, yizhang

Hi Chao,

On Fri, Jun 14, 2013 at 01:21:44AM -0400, Chao Xie wrote:
> The patch set fixes some bugs in the 88pm800/88pm805 driver, and it add
> regulator device into 88pm800.
> 
> The patches are tested based on Marvell pxa988 platform.
> 
> V2->V1:
>   add more fixes patches.
>   Below patches are same almost same as V1
>      mfd: 88pm800: fix NULL pointer errorm
>      mfd: 88pm800/88pm805: remove "IRQF_TRIGGER_FALLING" flag
>   Other patches are new.
> 
> Chao Xie (7):
>   mfd: 88pm80x: fix driver name for 88pm800 and 88pm805
>   mfd: 88pm800: fix for mask_invert
>   mfd: 88pm800: remove the power and gpadc page addr from platform data
>   mfd: 88pm800: fixes error handling for sub pages probe/remove
>   mfd: 88pm80x: Changes chip id definition and detection
>   mfd: 88pm800: enhance sub devices initialization
>   mfd: 88pm800: add regulator sub device
> 
> Yi Zhang (2):
>   mfd: 88pm800: fix NULL pointer error
>   mfd: 88pm800/88pm805: remove "IRQF_TRIGGER_FALLING" flag
> 
>  drivers/mfd/88pm800.c       |  237 +++++++++++++++++++++++++------------------
>  drivers/mfd/88pm805.c       |   20 +---
>  drivers/mfd/88pm80x.c       |   47 +++++++--
>  include/linux/mfd/88pm80x.h |   17 ++--
>  4 files changed, 193 insertions(+), 128 deletions(-)
All 9 patches applied, thanks.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-06-17 23:08 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-14  5:21 [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Chao Xie
2013-06-14  5:21 ` [PATCH V2 1/9] mfd: 88pm800: fix NULL pointer error Chao Xie
2013-06-14  5:21 ` [PATCH V2 2/9] mfd: 88pm80x: fix driver name for 88pm800 and 88pm805 Chao Xie
2013-06-14  5:21 ` [PATCH V2 3/9] mfd: 88pm800: fix for mask_invert Chao Xie
2013-06-14  5:21 ` [PATCH V2 4/9] mfd: 88pm800/88pm805: remove "IRQF_TRIGGER_FALLING" flag Chao Xie
2013-06-14  5:21 ` [PATCH V2 5/9] mfd: 88pm800: remove the power and gpadc page addr from platform data Chao Xie
2013-06-14  5:21 ` [PATCH V2 6/9] mfd: 88pm800: fixes error handling for sub pages probe/remove Chao Xie
2013-06-14  5:21 ` [PATCH V2 7/9] mfd: 88pm80x: Changes chip id definition and detection Chao Xie
2013-06-14  5:21 ` [PATCH V2 8/9] mfd: 88pm800: enhance sub devices initialization Chao Xie
2013-06-14  5:21 ` [PATCH V2 9/9] mfd: 88pm800: add regulator sub device Chao Xie
2013-06-17 23:07 ` [PATCH V2 0/9] mfd: 88pm80x: bug fixes and enhancement Samuel Ortiz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®