All of lore.kernel.org
 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 related	[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 related	[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 related	[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 related	[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 related	[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 related	[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 related	[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 related	[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 related	[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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.