linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] mfd: update on 88pm860x and max8925
@ 2012-09-17  4:19 Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 1/9] mfd: max8925: use register offset as REG in backlight Haojian Zhuang
                   ` (9 more replies)
  0 siblings, 10 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel

1. Updates the patch of max8925 of building issue.
2. Include Jett's PREG regulator patch.
3. Support DT in 88pm860x.


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

* [PATCH 1/9] mfd: max8925: use register offset as REG in backlight
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 2/9] mfd: max8925: remove array in regulator platform data Haojian Zhuang
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel
  Cc: Haojian Zhuang

Remove the register offset definition. All these register offset
are transfered as IORESOURCE_REG resources.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/mfd/max8925-core.c           |   31 ++++++-------
 drivers/video/backlight/max8925_bl.c |   79 ++++++++++++++++++----------------
 2 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index f2ff31f..b9f1d5c 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -18,20 +18,16 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/max8925.h>
 
-static struct resource backlight_resources[] = {
-	{
-		.name	= "max8925-backlight",
-		.start	= MAX8925_WLED_MODE_CNTL,
-		.end	= MAX8925_WLED_CNTL,
-		.flags	= IORESOURCE_REG,
-	},
+static struct resource bk_resources[] __devinitdata = {
+	{ 0x84, 0x84, "mode control", IORESOURCE_REG, },
+	{ 0x85, 0x85, "control",      IORESOURCE_REG, },
 };
 
-static struct mfd_cell backlight_devs[] = {
+static struct mfd_cell bk_devs[] __devinitdata = {
 	{
 		.name		= "max8925-backlight",
-		.num_resources	= 1,
-		.resources	= &backlight_resources[0],
+		.num_resources	= ARRAY_SIZE(bk_resources),
+		.resources	= &bk_resources[0],
 		.id		= -1,
 	},
 };
@@ -623,13 +619,14 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
 	}
 
 	if (pdata && pdata->backlight) {
-		ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
-				      ARRAY_SIZE(backlight_devs),
-				      &backlight_resources[0], 0, NULL);
-		if (ret < 0) {
-			dev_err(chip->dev, "Failed to add backlight subdev\n");
-			goto out_dev;
-		}
+		bk_devs[0].platform_data = &pdata->backlight;
+		bk_devs[0].pdata_size = sizeof(struct max8925_backlight_pdata);
+	}
+	ret = mfd_add_devices(chip->dev, 0, bk_devs, ARRAY_SIZE(bk_devs),
+			      NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add backlight subdev\n");
+		goto out_dev;
 	}
 
 	if (pdata && pdata->power) {
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index 996dadf..f72ba54 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -27,7 +27,9 @@
 struct max8925_backlight_data {
 	struct max8925_chip	*chip;
 
-	int		current_brightness;
+	int	current_brightness;
+	int	reg_mode_cntl;
+	int	reg_cntl;
 };
 
 static int max8925_backlight_set(struct backlight_device *bl, int brightness)
@@ -42,16 +44,16 @@ static int max8925_backlight_set(struct backlight_device *bl, int brightness)
 	else
 		value = brightness;
 
-	ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
+	ret = max8925_reg_write(chip->i2c, data->reg_cntl, value);
 	if (ret < 0)
 		goto out;
 
 	if (!data->current_brightness && brightness)
 		/* enable WLED output */
-		ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
+		ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 1);
 	else if (!brightness)
 		/* disable WLED output */
-		ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
+		ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 0);
 	if (ret < 0)
 		goto out;
 	dev_dbg(chip->dev, "set brightness %d\n", value);
@@ -85,7 +87,7 @@ static int max8925_backlight_get_brightness(struct backlight_device *bl)
 	struct max8925_chip *chip = data->chip;
 	int ret;
 
-	ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
+	ret = max8925_reg_read(chip->i2c, data->reg_cntl);
 	if (ret < 0)
 		return -EINVAL;
 	data->current_brightness = ret;
@@ -102,69 +104,70 @@ static const struct backlight_ops max8925_backlight_ops = {
 static int __devinit max8925_backlight_probe(struct platform_device *pdev)
 {
 	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct max8925_platform_data *max8925_pdata;
-	struct max8925_backlight_pdata *pdata = NULL;
+	struct max8925_backlight_pdata *pdata = pdev->dev.platform_data;
 	struct max8925_backlight_data *data;
 	struct backlight_device *bl;
 	struct backlight_properties props;
 	struct resource *res;
-	char name[MAX8925_NAME_SIZE];
 	unsigned char value;
-	int ret;
-
-	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource!\n");
-		return -EINVAL;
-	}
-
-	if (pdev->dev.parent->platform_data) {
-		max8925_pdata = pdev->dev.parent->platform_data;
-		pdata = max8925_pdata->backlight;
-	}
-
-	if (!pdata) {
-		dev_err(&pdev->dev, "platform data isn't assigned to "
-			"backlight\n");
-		return -EINVAL;
-	}
+	int ret = 0;
 
 	data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
 			    GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
-	strncpy(name, res->name, MAX8925_NAME_SIZE);
+
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource for mode control!\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_mode_cntl = res->start;
+	res = platform_get_resource(pdev, IORESOURCE_REG, 1);
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource for control!\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_cntl = res->start;
+
 	data->chip = chip;
 	data->current_brightness = 0;
 
 	memset(&props, 0, sizeof(struct backlight_properties));
 	props.type = BACKLIGHT_RAW;
 	props.max_brightness = MAX_BRIGHTNESS;
-	bl = backlight_device_register(name, &pdev->dev, data,
+	bl = backlight_device_register("max8925-backlight", &pdev->dev, data,
 					&max8925_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
-		return PTR_ERR(bl);
+		ret = PTR_ERR(bl);
+		goto out;
 	}
 	bl->props.brightness = MAX_BRIGHTNESS;
 
 	platform_set_drvdata(pdev, bl);
 
 	value = 0;
-	if (pdata->lxw_scl)
-		value |= (1 << 7);
-	if (pdata->lxw_freq)
-		value |= (LWX_FREQ(pdata->lxw_freq) << 4);
-	if (pdata->dual_string)
-		value |= (1 << 1);
-	ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
+	if (pdata) {
+		if (pdata->lxw_scl)
+			value |= (1 << 7);
+		if (pdata->lxw_freq)
+			value |= (LWX_FREQ(pdata->lxw_freq) << 4);
+		if (pdata->dual_string)
+			value |= (1 << 1);
+	}
+	ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 0xfe, value);
 	if (ret < 0)
-		goto out;
+		goto out_brt;
 
 	backlight_update_status(bl);
 	return 0;
-out:
+out_brt:
 	backlight_device_unregister(bl);
+out:
+	devm_kfree(&pdev->dev, data);
 	return ret;
 }
 
-- 
1.7.9.5


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

* [PATCH 2/9] mfd: max8925: remove array in regulator platform data
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 1/9] mfd: max8925: use register offset as REG in backlight Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator Haojian Zhuang
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel
  Cc: Haojian Zhuang

Remove array in parent's platform data. Use struct regulator_init_data
as regulator device's platform data directly. So a lot of pdata are
added into parent's platform data. And voltage out register offset
is used as IORESOURCE_REG to distinguish different regualtor devices.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/mfd/max8925-core.c            |  388 +++++++++++++++++++++++++++------
 drivers/regulator/max8925-regulator.c |   35 ++-
 include/linux/mfd/max8925.h           |   26 ++-
 3 files changed, 356 insertions(+), 93 deletions(-)

diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index b9f1d5c..1e0ab0a 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -15,6 +15,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/max8925.h>
 
@@ -109,71 +110,215 @@ static struct mfd_cell onkey_devs[] = {
 	},
 };
 
-#define MAX8925_REG_RESOURCE(_start, _end)	\
-{						\
-	.start	= MAX8925_##_start,		\
-	.end	= MAX8925_##_end,		\
-	.flags	= IORESOURCE_REG,		\
-}
+static struct resource sd1_resources[] __devinitdata = {
+	{0x06, 0x06, "sdv", IORESOURCE_REG, },
+};
 
-static struct resource regulator_resources[] = {
-	MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
-	MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
-	MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
-	MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
-	MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
-	MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
-	MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
-	MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
-	MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
-	MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
-	MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
-	MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
-	MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
-	MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
-	MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
-	MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
-	MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
-	MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
-	MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
-	MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
-	MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
-	MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
-	MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
-};
-
-#define MAX8925_REG_DEVS(_id)						\
-{									\
-	.name		= "max8925-regulator",				\
-	.num_resources	= 1,						\
-	.resources	= &regulator_resources[MAX8925_ID_##_id],	\
-	.id		= MAX8925_ID_##_id,				\
-}
+static struct resource sd2_resources[] __devinitdata = {
+	{0x09, 0x09, "sdv", IORESOURCE_REG, },
+};
+
+static struct resource sd3_resources[] __devinitdata = {
+	{0x0c, 0x0c, "sdv", IORESOURCE_REG, },
+};
+
+static struct resource ldo1_resources[] __devinitdata = {
+	{0x1a, 0x1a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo2_resources[] __devinitdata = {
+	{0x1e, 0x1e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo3_resources[] __devinitdata = {
+	{0x22, 0x22, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo4_resources[] __devinitdata = {
+	{0x26, 0x26, "ldov", IORESOURCE_REG, },
+};
 
-static struct mfd_cell regulator_devs[] = {
-	MAX8925_REG_DEVS(SD1),
-	MAX8925_REG_DEVS(SD2),
-	MAX8925_REG_DEVS(SD3),
-	MAX8925_REG_DEVS(LDO1),
-	MAX8925_REG_DEVS(LDO2),
-	MAX8925_REG_DEVS(LDO3),
-	MAX8925_REG_DEVS(LDO4),
-	MAX8925_REG_DEVS(LDO5),
-	MAX8925_REG_DEVS(LDO6),
-	MAX8925_REG_DEVS(LDO7),
-	MAX8925_REG_DEVS(LDO8),
-	MAX8925_REG_DEVS(LDO9),
-	MAX8925_REG_DEVS(LDO10),
-	MAX8925_REG_DEVS(LDO11),
-	MAX8925_REG_DEVS(LDO12),
-	MAX8925_REG_DEVS(LDO13),
-	MAX8925_REG_DEVS(LDO14),
-	MAX8925_REG_DEVS(LDO15),
-	MAX8925_REG_DEVS(LDO16),
-	MAX8925_REG_DEVS(LDO17),
-	MAX8925_REG_DEVS(LDO18),
-	MAX8925_REG_DEVS(LDO19),
-	MAX8925_REG_DEVS(LDO20),
+static struct resource ldo5_resources[] __devinitdata = {
+	{0x2a, 0x2a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo6_resources[] __devinitdata = {
+	{0x2e, 0x2e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo7_resources[] __devinitdata = {
+	{0x32, 0x32, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo8_resources[] __devinitdata = {
+	{0x36, 0x36, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo9_resources[] __devinitdata = {
+	{0x3a, 0x3a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo10_resources[] __devinitdata = {
+	{0x3e, 0x3e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo11_resources[] __devinitdata = {
+	{0x42, 0x42, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo12_resources[] __devinitdata = {
+	{0x46, 0x46, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo13_resources[] __devinitdata = {
+	{0x4a, 0x4a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo14_resources[] __devinitdata = {
+	{0x4e, 0x4e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo15_resources[] __devinitdata = {
+	{0x52, 0x52, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo16_resources[] __devinitdata = {
+	{0x12, 0x12, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo17_resources[] __devinitdata = {
+	{0x16, 0x16, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo18_resources[] __devinitdata = {
+	{0x74, 0x74, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo19_resources[] __devinitdata = {
+	{0x5e, 0x5e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo20_resources[] __devinitdata = {
+	{0x9e, 0x9e, "ldov", IORESOURCE_REG, },
+};
+
+static struct mfd_cell reg_devs[] __devinitdata = {
+	{
+		.name = "max8925-regulator",
+		.id = 0,
+		.num_resources = ARRAY_SIZE(sd1_resources),
+		.resources = sd1_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(sd2_resources),
+		.resources = sd2_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(sd3_resources),
+		.resources = sd3_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(ldo1_resources),
+		.resources = ldo1_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(ldo2_resources),
+		.resources = ldo2_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 5,
+		.num_resources = ARRAY_SIZE(ldo3_resources),
+		.resources = ldo3_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 6,
+		.num_resources = ARRAY_SIZE(ldo4_resources),
+		.resources = ldo4_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 7,
+		.num_resources = ARRAY_SIZE(ldo5_resources),
+		.resources = ldo5_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 8,
+		.num_resources = ARRAY_SIZE(ldo6_resources),
+		.resources = ldo6_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 9,
+		.num_resources = ARRAY_SIZE(ldo7_resources),
+		.resources = ldo7_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 10,
+		.num_resources = ARRAY_SIZE(ldo8_resources),
+		.resources = ldo8_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 11,
+		.num_resources = ARRAY_SIZE(ldo9_resources),
+		.resources = ldo9_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 12,
+		.num_resources = ARRAY_SIZE(ldo10_resources),
+		.resources = ldo10_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 13,
+		.num_resources = ARRAY_SIZE(ldo11_resources),
+		.resources = ldo11_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 14,
+		.num_resources = ARRAY_SIZE(ldo12_resources),
+		.resources = ldo12_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 15,
+		.num_resources = ARRAY_SIZE(ldo13_resources),
+		.resources = ldo13_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 16,
+		.num_resources = ARRAY_SIZE(ldo14_resources),
+		.resources = ldo14_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 17,
+		.num_resources = ARRAY_SIZE(ldo15_resources),
+		.resources = ldo15_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 18,
+		.num_resources = ARRAY_SIZE(ldo16_resources),
+		.resources = ldo16_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 19,
+		.num_resources = ARRAY_SIZE(ldo17_resources),
+		.resources = ldo17_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 20,
+		.num_resources = ARRAY_SIZE(ldo18_resources),
+		.resources = ldo18_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 21,
+		.num_resources = ARRAY_SIZE(ldo19_resources),
+		.resources = ldo19_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 22,
+		.num_resources = ARRAY_SIZE(ldo20_resources),
+		.resources = ldo20_resources,
+	},
 };
 
 enum {
@@ -569,6 +714,113 @@ tsc_irq:
 	return 0;
 }
 
+static void __devinit init_regulator(struct max8925_chip *chip,
+				     struct max8925_platform_data *pdata)
+{
+	int ret;
+
+	if (!pdata)
+		return;
+	if (pdata->sd1) {
+		reg_devs[0].platform_data = pdata->sd1;
+		reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->sd2) {
+		reg_devs[1].platform_data = pdata->sd2;
+		reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->sd3) {
+		reg_devs[2].platform_data = pdata->sd3;
+		reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo1) {
+		reg_devs[3].platform_data = pdata->ldo1;
+		reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo2) {
+		reg_devs[4].platform_data = pdata->ldo2;
+		reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo3) {
+		reg_devs[5].platform_data = pdata->ldo3;
+		reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo4) {
+		reg_devs[6].platform_data = pdata->ldo4;
+		reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo5) {
+		reg_devs[7].platform_data = pdata->ldo5;
+		reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo6) {
+		reg_devs[8].platform_data = pdata->ldo6;
+		reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo7) {
+		reg_devs[9].platform_data = pdata->ldo7;
+		reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo8) {
+		reg_devs[10].platform_data = pdata->ldo8;
+		reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo9) {
+		reg_devs[11].platform_data = pdata->ldo9;
+		reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo10) {
+		reg_devs[12].platform_data = pdata->ldo10;
+		reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo11) {
+		reg_devs[13].platform_data = pdata->ldo11;
+		reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo12) {
+		reg_devs[14].platform_data = pdata->ldo12;
+		reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo13) {
+		reg_devs[15].platform_data = pdata->ldo13;
+		reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo14) {
+		reg_devs[16].platform_data = pdata->ldo14;
+		reg_devs[16].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo15) {
+		reg_devs[17].platform_data = pdata->ldo15;
+		reg_devs[17].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo16) {
+		reg_devs[18].platform_data = pdata->ldo16;
+		reg_devs[18].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo17) {
+		reg_devs[19].platform_data = pdata->ldo17;
+		reg_devs[19].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo18) {
+		reg_devs[20].platform_data = pdata->ldo18;
+		reg_devs[20].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo19) {
+		reg_devs[21].platform_data = pdata->ldo19;
+		reg_devs[21].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo20) {
+		reg_devs[22].platform_data = pdata->ldo20;
+		reg_devs[22].pdata_size = sizeof(struct regulator_init_data);
+	}
+	ret = mfd_add_devices(chip->dev, 0, reg_devs, ARRAY_SIZE(reg_devs),
+			      NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add regulator subdev\n");
+		return;
+	}
+}
+
 int __devinit max8925_device_init(struct max8925_chip *chip,
 				  struct max8925_platform_data *pdata)
 {
@@ -608,15 +860,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
 		goto out_dev;
 	}
 
-	if (pdata) {
-		ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
-				      ARRAY_SIZE(regulator_devs),
-				      &regulator_resources[0], 0, NULL);
-		if (ret < 0) {
-			dev_err(chip->dev, "Failed to add regulator subdev\n");
-			goto out_dev;
-		}
-	}
+	init_regulator(chip, pdata);
 
 	if (pdata && pdata->backlight) {
 		bk_devs[0].platform_data = &pdata->backlight;
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
index 43dc97ec..9bb0be3 100644
--- a/drivers/regulator/max8925-regulator.c
+++ b/drivers/regulator/max8925-regulator.c
@@ -214,37 +214,36 @@ static struct max8925_regulator_info max8925_regulator_info[] = {
 	MAX8925_LDO(20, 750, 3900, 50),
 };
 
-static struct max8925_regulator_info * __devinit find_regulator_info(int id)
-{
-	struct max8925_regulator_info *ri;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
-		ri = &max8925_regulator_info[i];
-		if (ri->desc.id == id)
-			return ri;
-	}
-	return NULL;
-}
-
 static int __devinit max8925_regulator_probe(struct platform_device *pdev)
 {
 	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct max8925_platform_data *pdata = chip->dev->platform_data;
+	struct regulator_init_data *pdata = pdev->dev.platform_data;
 	struct regulator_config config = { };
 	struct max8925_regulator_info *ri;
+	struct resource *res;
 	struct regulator_dev *rdev;
+	int i;
 
-	ri = find_regulator_info(pdev->id);
-	if (ri == NULL) {
-		dev_err(&pdev->dev, "invalid regulator ID specified\n");
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource!\n");
+		return -EINVAL;
+	}
+	for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
+		ri = &max8925_regulator_info[i];
+		if (ri->vol_reg == res->start)
+			break;
+	}
+	if (i == ARRAY_SIZE(max8925_regulator_info)) {
+		dev_err(&pdev->dev, "Failed to find regulator %llu\n",
+			(unsigned long long)res->start);
 		return -EINVAL;
 	}
 	ri->i2c = chip->i2c;
 	ri->chip = chip;
 
 	config.dev = &pdev->dev;
-	config.init_data = pdata->regulator[pdev->id];
+	config.init_data = pdata;
 	config.driver_data = ri;
 
 	rdev = regulator_register(&ri->desc, &config);
diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h
index 15b2392..74d8e29 100644
--- a/include/linux/mfd/max8925.h
+++ b/include/linux/mfd/max8925.h
@@ -158,8 +158,6 @@ enum {
 #define TSC_IRQ_MASK			(0x03)
 #define RTC_IRQ_MASK			(0x0c)
 
-#define MAX8925_MAX_REGULATOR		(23)
-
 #define MAX8925_NAME_SIZE		(32)
 
 /* IRQ definitions */
@@ -236,7 +234,29 @@ struct max8925_platform_data {
 	struct max8925_backlight_pdata	*backlight;
 	struct max8925_touch_pdata	*touch;
 	struct max8925_power_pdata	*power;
-	struct regulator_init_data	*regulator[MAX8925_MAX_REGULATOR];
+	struct regulator_init_data	*sd1;
+	struct regulator_init_data	*sd2;
+	struct regulator_init_data	*sd3;
+	struct regulator_init_data	*ldo1;
+	struct regulator_init_data	*ldo2;
+	struct regulator_init_data	*ldo3;
+	struct regulator_init_data	*ldo4;
+	struct regulator_init_data	*ldo5;
+	struct regulator_init_data	*ldo6;
+	struct regulator_init_data	*ldo7;
+	struct regulator_init_data	*ldo8;
+	struct regulator_init_data	*ldo9;
+	struct regulator_init_data	*ldo10;
+	struct regulator_init_data	*ldo11;
+	struct regulator_init_data	*ldo12;
+	struct regulator_init_data	*ldo13;
+	struct regulator_init_data	*ldo14;
+	struct regulator_init_data	*ldo15;
+	struct regulator_init_data	*ldo16;
+	struct regulator_init_data	*ldo17;
+	struct regulator_init_data	*ldo18;
+	struct regulator_init_data	*ldo19;
+	struct regulator_init_data	*ldo20;
 
 	int		irq_base;
 	int		tsc_irq;
-- 
1.7.9.5


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

* [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 1/9] mfd: max8925: use register offset as REG in backlight Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 2/9] mfd: max8925: remove array in regulator platform data Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-17 10:19   ` Mark Brown
  2012-09-17  4:19 ` [PATCH 4/9] mfd: 88pm860x: avoid to check resource for preg regulator Haojian Zhuang
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel; +Cc: Jett.Zhou

From: "Jett.Zhou" <jtzhou@marvell.com>

Pre-regulator of 88pm8606 is mainly for support charging based on vbus,
it needs to be enabled for charging battery, and will be disabled in
some exception condition like over-temp.
Add the pre-regulator support for 88pm860x regulator driver.

Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/regulator/88pm8607.c |   66 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index 843c89a..d34bd8c 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -23,6 +23,7 @@ struct pm8607_regulator_info {
 	struct pm860x_chip	*chip;
 	struct regulator_dev	*regulator;
 	struct i2c_client	*i2c;
+	struct i2c_client	*i2c_8606;
 
 	unsigned int	*vol_table;
 	unsigned int	*vol_suspend;
@@ -242,6 +243,35 @@ static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
 	return ret;
 }
 
+static int pm8606_preg_enable(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+
+	return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
+			       1 << rdev->desc->enable_mask, 0);
+}
+
+static int pm8606_preg_disable(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+
+	return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
+			       1 << rdev->desc->enable_mask,
+			       1 << rdev->desc->enable_mask);
+}
+
+static int pm8606_preg_is_enabled(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = pm860x_reg_read(info->i2c, rdev->desc->enable_reg);
+	if (ret < 0)
+		return ret;
+
+	return !((unsigned char)ret & (1 << rdev->desc->enable_mask));
+}
+
 static struct regulator_ops pm8607_regulator_ops = {
 	.list_voltage	= pm8607_list_voltage,
 	.set_voltage_sel = pm8607_set_voltage_sel,
@@ -251,6 +281,25 @@ static struct regulator_ops pm8607_regulator_ops = {
 	.is_enabled = regulator_is_enabled_regmap,
 };
 
+static struct regulator_ops pm8606_preg_ops = {
+	.enable		= pm8606_preg_enable,
+	.disable	= pm8606_preg_disable,
+	.is_enabled	= pm8606_preg_is_enabled,
+};
+
+#define PM8606_PREG(ereg, ebit)						\
+{									\
+	.desc	= {							\
+		.name	= "PREG",					\
+		.ops	= &pm8606_preg_ops,				\
+		.type	= REGULATOR_CURRENT,				\
+		.id	= PM8606_ID_PREG,				\
+		.owner	= THIS_MODULE,					\
+		.enable_reg = PM8606_##ereg,				\
+		.enable_mask = (ebit),					\
+	},								\
+}
+
 #define PM8607_DVC(vreg, ureg, ubit, ereg, ebit)			\
 {									\
 	.desc	= {							\
@@ -309,6 +358,8 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = {
 	PM8607_LDO(12,        LDO12, 0, SUPPLIES_EN12, 5),
 	PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0),
 	PM8607_LDO(14,        LDO14, 0, SUPPLIES_EN12, 6),
+
+	PM8606_PREG(PREREGULATORB, 5),
 };
 
 static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
@@ -336,6 +387,8 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+	info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion :
+			chip->client;
 	info->chip = chip;
 
 	/* check DVC ramp slope double */
@@ -371,6 +424,18 @@ static int __devexit pm8607_regulator_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static struct platform_device_id pm8607_regulator_driver_ids[] = {
+	{
+		.name	= "88pm860x-regulator",
+		.driver_data	= 0,
+	}, {
+		.name	= "88pm860x-preg",
+		.driver_data	= 0,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids);
+
 static struct platform_driver pm8607_regulator_driver = {
 	.driver		= {
 		.name	= "88pm860x-regulator",
@@ -378,6 +443,7 @@ static struct platform_driver pm8607_regulator_driver = {
 	},
 	.probe		= pm8607_regulator_probe,
 	.remove		= __devexit_p(pm8607_regulator_remove),
+	.id_table	= pm8607_regulator_driver_ids,
 };
 
 static int __init pm8607_regulator_init(void)
-- 
1.7.9.5


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

* [PATCH 4/9] mfd: 88pm860x: avoid to check resource for preg regulator
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
                   ` (2 preceding siblings ...)
  2012-09-17  4:19 ` [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 5/9] mfd: 88pm860x: move initilization code Haojian Zhuang
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel
  Cc: Haojian Zhuang

From: Haojian Zhuang <haojian.zhuang@marvell.com>

Since PREG regulator is the only one regulator in 88PM8606, and other
regulators are in 88PM8607. Checking resource as identifying regulator
is not a good way. We can use NULL resource to indentify PREG regulator.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
---
 drivers/mfd/88pm860x-core.c  |    8 +-------
 drivers/regulator/88pm8607.c |   32 +++++++++++++++++++-------------
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 0c01d74..d2b0bf8 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -150,10 +150,6 @@ static struct resource charger_resources[] __devinitdata = {
 	{PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage",    IORESOURCE_IRQ,},
 };
 
-static struct resource preg_resources[] __devinitdata = {
-	{PM8606_ID_PREG,  PM8606_ID_PREG,  "preg",   IORESOURCE_REG,},
-};
-
 static struct resource rtc_resources[] __devinitdata = {
 	{PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
 };
@@ -960,10 +956,8 @@ static void __devinit device_power_init(struct pm860x_chip *chip,
 
 	power_devs[2].platform_data = &preg_init_data;
 	power_devs[2].pdata_size = sizeof(struct regulator_init_data);
-	power_devs[2].num_resources = ARRAY_SIZE(preg_resources);
-	power_devs[2].resources = &preg_resources[0],
 	ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1,
-			      &preg_resources[0], chip->irq_base, NULL);
+			      NULL, chip->irq_base, NULL);
 	if (ret < 0)
 		dev_err(chip->dev, "Failed to add preg subdev\n");
 }
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index d34bd8c..f96fbe3 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -358,7 +358,9 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = {
 	PM8607_LDO(12,        LDO12, 0, SUPPLIES_EN12, 5),
 	PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0),
 	PM8607_LDO(14,        LDO14, 0, SUPPLIES_EN12, 6),
+};
 
+static struct pm8607_regulator_info pm8606_regulator_info[] = {
 	PM8606_PREG(PREREGULATORB, 5),
 };
 
@@ -372,19 +374,23 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
 	int i;
 
 	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "No REG resource!\n");
-		return -EINVAL;
-	}
-	for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
-		info = &pm8607_regulator_info[i];
-		if (info->desc.vsel_reg == res->start)
-			break;
-	}
-	if (i == ARRAY_SIZE(pm8607_regulator_info)) {
-		dev_err(&pdev->dev, "Failed to find regulator %llu\n",
-			(unsigned long long)res->start);
-		return -EINVAL;
+	if (res) {
+		/* There're resources in 88PM8607 regulator driver */
+		for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
+			info = &pm8607_regulator_info[i];
+			if (info->desc.vsel_reg == res->start)
+				break;
+		}
+		if (i == ARRAY_SIZE(pm8607_regulator_info)) {
+			dev_err(&pdev->dev, "Failed to find regulator %llu\n",
+				(unsigned long long)res->start);
+			return -EINVAL;
+		}
+	} else {
+		/* There's no resource in 88PM8606 PREG regulator driver */
+		info = &pm8606_regulator_info[0];
+		/* i is used to check regulator ID */
+		i = -1;
 	}
 	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
 	info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion :
-- 
1.7.9.5


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

* [PATCH 5/9] mfd: 88pm860x: move initilization code
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
                   ` (3 preceding siblings ...)
  2012-09-17  4:19 ` [PATCH 4/9] mfd: 88pm860x: avoid to check resource for preg regulator Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 6/9] mfd: 88pm860x: use irqdomain Haojian Zhuang
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel
  Cc: Haojian Zhuang

Move probe() and other functions from 88pm860x-i2c.c to 88pm860x-core.c.
Since it could benefit to handle DT information.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/mfd/88pm860x-core.c  |  162 +++++++++++++++++++++++++++++++++++++++++-
 drivers/mfd/88pm860x-i2c.c   |  160 -----------------------------------------
 include/linux/mfd/88pm860x.h |    4 --
 3 files changed, 159 insertions(+), 167 deletions(-)

diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index d2b0bf8..797bdb3 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -11,10 +11,13 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/88pm860x.h>
 #include <linux/regulator/machine.h>
@@ -1064,8 +1067,8 @@ static void __devinit device_8606_init(struct pm860x_chip *chip,
 	device_led_init(chip, pdata);
 }
 
-int __devinit pm860x_device_init(struct pm860x_chip *chip,
-		       struct pm860x_platform_data *pdata)
+static int __devinit pm860x_device_init(struct pm860x_chip *chip,
+					struct pm860x_platform_data *pdata)
 {
 	chip->core_irq = 0;
 
@@ -1092,12 +1095,165 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
 	return 0;
 }
 
-void __devexit pm860x_device_exit(struct pm860x_chip *chip)
+static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
 {
 	device_irq_exit(chip);
 	mfd_remove_devices(chip->dev);
 }
 
+static const struct i2c_device_id pm860x_id_table[] = {
+	{ "88PM860x", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
+
+static int verify_addr(struct i2c_client *i2c)
+{
+	unsigned short addr_8607[] = {0x30, 0x34};
+	unsigned short addr_8606[] = {0x10, 0x11};
+	int size, i;
+
+	if (i2c == NULL)
+		return 0;
+	size = ARRAY_SIZE(addr_8606);
+	for (i = 0; i < size; i++) {
+		if (i2c->addr == *(addr_8606 + i))
+			return CHIP_PM8606;
+	}
+	size = ARRAY_SIZE(addr_8607);
+	for (i = 0; i < size; i++) {
+		if (i2c->addr == *(addr_8607 + i))
+			return CHIP_PM8607;
+	}
+	return 0;
+}
+
+static struct regmap_config pm860x_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
+static int __devinit pm860x_probe(struct i2c_client *client,
+				  const struct i2c_device_id *id)
+{
+	struct pm860x_platform_data *pdata = client->dev.platform_data;
+	struct pm860x_chip *chip;
+	int ret;
+
+	if (!pdata) {
+		pr_info("No platform data in %s!\n", __func__);
+		return -EINVAL;
+	}
+
+	chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->id = verify_addr(client);
+	chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
+	if (IS_ERR(chip->regmap)) {
+		ret = PTR_ERR(chip->regmap);
+		dev_err(&client->dev, "Failed to allocate register map: %d\n",
+				ret);
+		kfree(chip);
+		return ret;
+	}
+	chip->client = client;
+	i2c_set_clientdata(client, chip);
+	chip->dev = &client->dev;
+	dev_set_drvdata(chip->dev, chip);
+
+	/*
+	 * Both client and companion client shares same platform driver.
+	 * Driver distinguishes them by pdata->companion_addr.
+	 * pdata->companion_addr is only assigned if companion chip exists.
+	 * At the same time, the companion_addr shouldn't equal to client
+	 * address.
+	 */
+	if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
+		chip->companion_addr = pdata->companion_addr;
+		chip->companion = i2c_new_dummy(chip->client->adapter,
+						chip->companion_addr);
+		chip->regmap_companion = regmap_init_i2c(chip->companion,
+							&pm860x_regmap_config);
+		if (IS_ERR(chip->regmap_companion)) {
+			ret = PTR_ERR(chip->regmap_companion);
+			dev_err(&chip->companion->dev,
+				"Failed to allocate register map: %d\n", ret);
+			return ret;
+		}
+		i2c_set_clientdata(chip->companion, chip);
+	}
+
+	pm860x_device_init(chip, pdata);
+	return 0;
+}
+
+static int __devexit pm860x_remove(struct i2c_client *client)
+{
+	struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+	pm860x_device_exit(chip);
+	if (chip->companion) {
+		regmap_exit(chip->regmap_companion);
+		i2c_unregister_device(chip->companion);
+	}
+	regmap_exit(chip->regmap);
+	kfree(chip);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pm860x_suspend(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+	if (device_may_wakeup(dev) && chip->wakeup_flag)
+		enable_irq_wake(chip->core_irq);
+	return 0;
+}
+
+static int pm860x_resume(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+	if (device_may_wakeup(dev) && chip->wakeup_flag)
+		disable_irq_wake(chip->core_irq);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
+
+static struct i2c_driver pm860x_driver = {
+	.driver	= {
+		.name	= "88PM860x",
+		.owner	= THIS_MODULE,
+		.pm     = &pm860x_pm_ops,
+	},
+	.probe		= pm860x_probe,
+	.remove		= __devexit_p(pm860x_remove),
+	.id_table	= pm860x_id_table,
+};
+
+static int __init pm860x_i2c_init(void)
+{
+	int ret;
+	ret = i2c_add_driver(&pm860x_driver);
+	if (ret != 0)
+		pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
+	return ret;
+}
+subsys_initcall(pm860x_i2c_init);
+
+static void __exit pm860x_i2c_exit(void)
+{
+	i2c_del_driver(&pm860x_driver);
+}
+module_exit(pm860x_i2c_exit);
+
 MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index b2cfdc4..cd53a82 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -10,12 +10,9 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/platform_device.h>
 #include <linux/i2c.h>
-#include <linux/err.h>
 #include <linux/regmap.h>
 #include <linux/mfd/88pm860x.h>
-#include <linux/slab.h>
 
 int pm860x_reg_read(struct i2c_client *i2c, int reg)
 {
@@ -231,160 +228,3 @@ out:
 	return ret;
 }
 EXPORT_SYMBOL(pm860x_page_set_bits);
-
-static const struct i2c_device_id pm860x_id_table[] = {
-	{ "88PM860x", 0 },
-	{}
-};
-MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
-
-static int verify_addr(struct i2c_client *i2c)
-{
-	unsigned short addr_8607[] = {0x30, 0x34};
-	unsigned short addr_8606[] = {0x10, 0x11};
-	int size, i;
-
-	if (i2c == NULL)
-		return 0;
-	size = ARRAY_SIZE(addr_8606);
-	for (i = 0; i < size; i++) {
-		if (i2c->addr == *(addr_8606 + i))
-			return CHIP_PM8606;
-	}
-	size = ARRAY_SIZE(addr_8607);
-	for (i = 0; i < size; i++) {
-		if (i2c->addr == *(addr_8607 + i))
-			return CHIP_PM8607;
-	}
-	return 0;
-}
-
-static struct regmap_config pm860x_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-};
-
-static int __devinit pm860x_probe(struct i2c_client *client,
-				  const struct i2c_device_id *id)
-{
-	struct pm860x_platform_data *pdata = client->dev.platform_data;
-	struct pm860x_chip *chip;
-	int ret;
-
-	if (!pdata) {
-		pr_info("No platform data in %s!\n", __func__);
-		return -EINVAL;
-	}
-
-	chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
-	if (chip == NULL)
-		return -ENOMEM;
-
-	chip->id = verify_addr(client);
-	chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
-	if (IS_ERR(chip->regmap)) {
-		ret = PTR_ERR(chip->regmap);
-		dev_err(&client->dev, "Failed to allocate register map: %d\n",
-				ret);
-		kfree(chip);
-		return ret;
-	}
-	chip->client = client;
-	i2c_set_clientdata(client, chip);
-	chip->dev = &client->dev;
-	dev_set_drvdata(chip->dev, chip);
-
-	/*
-	 * Both client and companion client shares same platform driver.
-	 * Driver distinguishes them by pdata->companion_addr.
-	 * pdata->companion_addr is only assigned if companion chip exists.
-	 * At the same time, the companion_addr shouldn't equal to client
-	 * address.
-	 */
-	if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
-		chip->companion_addr = pdata->companion_addr;
-		chip->companion = i2c_new_dummy(chip->client->adapter,
-						chip->companion_addr);
-		chip->regmap_companion = regmap_init_i2c(chip->companion,
-							&pm860x_regmap_config);
-		if (IS_ERR(chip->regmap_companion)) {
-			ret = PTR_ERR(chip->regmap_companion);
-			dev_err(&chip->companion->dev,
-				"Failed to allocate register map: %d\n", ret);
-			return ret;
-		}
-		i2c_set_clientdata(chip->companion, chip);
-	}
-
-	pm860x_device_init(chip, pdata);
-	return 0;
-}
-
-static int __devexit pm860x_remove(struct i2c_client *client)
-{
-	struct pm860x_chip *chip = i2c_get_clientdata(client);
-
-	pm860x_device_exit(chip);
-	if (chip->companion) {
-		regmap_exit(chip->regmap_companion);
-		i2c_unregister_device(chip->companion);
-	}
-	regmap_exit(chip->regmap);
-	kfree(chip);
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int pm860x_suspend(struct device *dev)
-{
-	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-	struct pm860x_chip *chip = i2c_get_clientdata(client);
-
-	if (device_may_wakeup(dev) && chip->wakeup_flag)
-		enable_irq_wake(chip->core_irq);
-	return 0;
-}
-
-static int pm860x_resume(struct device *dev)
-{
-	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-	struct pm860x_chip *chip = i2c_get_clientdata(client);
-
-	if (device_may_wakeup(dev) && chip->wakeup_flag)
-		disable_irq_wake(chip->core_irq);
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
-
-static struct i2c_driver pm860x_driver = {
-	.driver	= {
-		.name	= "88PM860x",
-		.owner	= THIS_MODULE,
-		.pm     = &pm860x_pm_ops,
-	},
-	.probe		= pm860x_probe,
-	.remove		= __devexit_p(pm860x_remove),
-	.id_table	= pm860x_id_table,
-};
-
-static int __init pm860x_i2c_init(void)
-{
-	int ret;
-	ret = i2c_add_driver(&pm860x_driver);
-	if (ret != 0)
-		pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
-	return ret;
-}
-subsys_initcall(pm860x_i2c_init);
-
-static void __exit pm860x_i2c_exit(void)
-{
-	i2c_del_driver(&pm860x_driver);
-}
-module_exit(pm860x_i2c_exit);
-
-MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x");
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index 87c933d..d515e5c 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -402,8 +402,4 @@ extern int pm860x_page_bulk_write(struct i2c_client *, int, int,
 extern int pm860x_page_set_bits(struct i2c_client *, int, unsigned char,
 				unsigned char);
 
-extern int pm860x_device_init(struct pm860x_chip *chip,
-			      struct pm860x_platform_data *pdata) __devinit ;
-extern void pm860x_device_exit(struct pm860x_chip *chip) __devexit ;
-
 #endif /* __LINUX_MFD_88PM860X_H */
-- 
1.7.9.5


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

* [PATCH 6/9] mfd: 88pm860x: use irqdomain
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
                   ` (4 preceding siblings ...)
  2012-09-17  4:19 ` [PATCH 5/9] mfd: 88pm860x: move initilization code Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 7/9] mfd: 88pm860x: support dt Haojian Zhuang
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel
  Cc: Haojian Zhuang

Use irqdomain and allocating interrupts. It's necessary for supporting
DT mode.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/mfd/88pm860x-core.c |   65 +++++++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 27 deletions(-)

diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 797bdb3..a09d790 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -15,6 +15,7 @@
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
@@ -520,15 +521,12 @@ static void pm860x_irq_sync_unlock(struct irq_data *data)
 
 static void pm860x_irq_enable(struct irq_data *data)
 {
-	struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
-	pm860x_irqs[data->irq - chip->irq_base].enable
-		= pm860x_irqs[data->irq - chip->irq_base].offs;
+	pm860x_irqs[data->hwirq].enable = pm860x_irqs[data->hwirq].offs;
 }
 
 static void pm860x_irq_disable(struct irq_data *data)
 {
-	struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
-	pm860x_irqs[data->irq - chip->irq_base].enable = 0;
+	pm860x_irqs[data->hwirq].enable = 0;
 }
 
 static struct irq_chip pm860x_irq_chip = {
@@ -539,6 +537,25 @@ static struct irq_chip pm860x_irq_chip = {
 	.irq_disable	= pm860x_irq_disable,
 };
 
+static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
+				 irq_hw_number_t hw)
+{
+	irq_set_chip_data(virq, d->host_data);
+	irq_set_chip_and_handler(virq, &pm860x_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(virq, 1);
+#ifdef CONFIG_ARM
+	set_irq_flags(virq, IRQF_VALID);
+#else
+	irq_set_noprobe(virq);
+#endif
+	return 0;
+}
+
+static struct irq_domain_ops pm860x_irq_domain_ops = {
+	.map	= pm860x_irq_domain_map,
+	.xlate	= irq_domain_xlate_onetwocell,
+};
+
 static int __devinit device_gpadc_init(struct pm860x_chip *chip,
 				       struct pm860x_platform_data *pdata)
 {
@@ -593,13 +610,9 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
 				: chip->companion;
 	unsigned char status_buf[INT_STATUS_NUM];
 	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
-	int i, data, mask, ret = -EINVAL;
-	int __irq;
-
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(chip->dev, "No interrupt support on IRQ base\n");
-		return -EINVAL;
-	}
+	int data, mask, ret = -EINVAL;
+	int nr_irqs, irq_base = -1;
+	struct device_node *node = i2c->dev.of_node;
 
 	mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
 		| PM8607_B0_MISC1_INT_MASK;
@@ -639,25 +652,23 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
 		goto out;
 
 	mutex_init(&chip->irq_lock);
-	chip->irq_base = pdata->irq_base;
+
+	if (pdata && pdata->irq_base)
+		irq_base = pdata->irq_base;
+	nr_irqs = ARRAY_SIZE(pm860x_irqs);
+	chip->irq_base = irq_alloc_descs(irq_base, 0, nr_irqs, 0);
+	if (chip->irq_base < 0) {
+		dev_err(&i2c->dev, "Failed to allocate interrupts, ret:%d\n",
+			chip->irq_base);
+		ret = -EBUSY;
+		goto out;
+	}
+	irq_domain_add_legacy(node, nr_irqs, chip->irq_base, 0,
+			      &pm860x_irq_domain_ops, chip);
 	chip->core_irq = i2c->irq;
 	if (!chip->core_irq)
 		goto out;
 
-	/* register IRQ by genirq */
-	for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
-		__irq = i + chip->irq_base;
-		irq_set_chip_data(__irq, chip);
-		irq_set_chip_and_handler(__irq, &pm860x_irq_chip,
-					 handle_edge_irq);
-		irq_set_nested_thread(__irq, 1);
-#ifdef CONFIG_ARM
-		set_irq_flags(__irq, IRQF_VALID);
-#else
-		irq_set_noprobe(__irq);
-#endif
-	}
-
 	ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags,
 				   "88pm860x", chip);
 	if (ret) {
-- 
1.7.9.5


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

* [PATCH 7/9] mfd: 88pm860x: support dt
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
                   ` (5 preceding siblings ...)
  2012-09-17  4:19 ` [PATCH 6/9] mfd: 88pm860x: use irqdomain Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-17  9:59   ` Mark Brown
  2012-09-17  4:19 ` [PATCH 8/9] mfd: 88pm860x: move gpadc init into touch Haojian Zhuang
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel
  Cc: Haojian Zhuang

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/input/touchscreen/88pm860x-ts.c |   46 +++++++++++++++--------
 drivers/leds/leds-88pm860x.c            |   33 +++++++++++++++-
 drivers/mfd/88pm860x-core.c             |   62 ++++++++++++++++++++++++++-----
 drivers/regulator/88pm8607.c            |   35 ++++++++++++++++-
 drivers/rtc/rtc-88pm860x.c              |   43 ++++++++++++++++-----
 drivers/video/backlight/88pm860x_bl.c   |   39 +++++++++++++++++--
 include/linux/mfd/88pm860x.h            |    4 +-
 7 files changed, 221 insertions(+), 41 deletions(-)

diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
index 05f30b7..4f81e6e 100644
--- a/drivers/input/touchscreen/88pm860x-ts.c
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -10,6 +10,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
@@ -113,14 +114,31 @@ static void pm860x_touch_close(struct input_dev *dev)
 	pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
 }
 
+#ifdef CONFIG_OF
+static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
+					  int *res_x)
+{
+	struct device_node *np = pdev->dev.parent->of_node;
+	if (!np)
+		return -ENODEV;
+	np = of_find_node_by_name(np, "touch");
+	if (!np) {
+		dev_err(&pdev->dev, "Can't find touch node\n");
+		return -EINVAL;
+	}
+	of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
+	return 0;
+}
+#else
+#define pm860x_touch_dt_init(x, y)	(-1)
+#endif
+
 static int __devinit pm860x_touch_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct pm860x_platform_data *pm860x_pdata =		\
-				pdev->dev.parent->platform_data;
-	struct pm860x_touch_pdata *pdata = NULL;
+	struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
 	struct pm860x_touch *touch;
-	int irq, ret;
+	int irq, ret, res_x = 0;
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -128,15 +146,13 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	if (!pm860x_pdata) {
-		dev_err(&pdev->dev, "platform data is missing\n");
-		return -EINVAL;
-	}
-
-	pdata = pm860x_pdata->touch;
-	if (!pdata) {
-		dev_err(&pdev->dev, "touchscreen data is missing\n");
-		return -EINVAL;
+	if (pm860x_touch_dt_init(pdev, &res_x)) {
+		if (pdata)
+			res_x = pdata->res_x;
+		else {
+			dev_err(&pdev->dev, "failed to get platform data\n");
+			return -EINVAL;
+		}
 	}
 
 	touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
@@ -159,8 +175,8 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
 	touch->idev->close = pm860x_touch_close;
 	touch->chip = chip;
 	touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
-	touch->irq = irq + chip->irq_base;
-	touch->res_x = pdata->res_x;
+	touch->irq = irq;
+	touch->res_x = res_x;
 	input_set_drvdata(touch->idev, touch);
 
 	ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 70232b1..b7e8cc0 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/leds.h>
@@ -123,6 +124,33 @@ static void pm860x_led_set(struct led_classdev *cdev,
 	schedule_work(&data->work);
 }
 
+#ifdef CONFIG_OF
+static int pm860x_led_dt_init(struct platform_device *pdev,
+			      struct pm860x_led *data)
+{
+	struct device_node *nproot = pdev->dev.parent->of_node, *np;
+	int iset = 0;
+	if (!nproot)
+		return -ENODEV;
+	nproot = of_find_node_by_name(nproot, "leds");
+	if (!nproot) {
+		dev_err(&pdev->dev, "failed to find leds node\n");
+		return -ENODEV;
+	}
+	for_each_child_of_node(nproot, np) {
+		if (!of_node_cmp(np->name, data->name)) {
+			of_property_read_u32(np, "marvell,88pm860x-iset",
+					     &iset);
+			data->iset = PM8606_LED_CURRENT(iset);
+			break;
+		}
+	}
+	return 0;
+}
+#else
+#define pm860x_led_dt_init(x, y)	(-1)
+#endif
+
 static int pm860x_led_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -179,8 +207,9 @@ static int pm860x_led_probe(struct platform_device *pdev)
 	data->chip = chip;
 	data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
 	data->port = pdev->id;
-	if (pdata && pdata->iset)
-		data->iset = pdata->iset;
+	if (pm860x_led_dt_init(pdev, data))
+		if (pdata)
+			data->iset = pdata->iset;
 
 	data->current_brightness = 0;
 	data->cdev.name = data->name;
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index a09d790..15ded0b 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -16,6 +16,8 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
@@ -1112,12 +1114,6 @@ static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
 	mfd_remove_devices(chip->dev);
 }
 
-static const struct i2c_device_id pm860x_id_table[] = {
-	{ "88PM860x", 0 },
-	{}
-};
-MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
-
 static int verify_addr(struct i2c_client *i2c)
 {
 	unsigned short addr_8607[] = {0x30, 0x34};
@@ -1144,21 +1140,52 @@ static struct regmap_config pm860x_regmap_config = {
 	.val_bits = 8,
 };
 
+static int __devinit pm860x_dt_init(struct device_node *np,
+				    struct device *dev,
+				    struct pm860x_platform_data *pdata)
+{
+	int ret;
+
+	if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL))
+		pdata->irq_mode = 1;
+	ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
+				   &pdata->companion_addr);
+	if (ret) {
+		dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" "
+			"property\n");
+		pdata->companion_addr = 0;
+	}
+	return 0;
+}
+
 static int __devinit pm860x_probe(struct i2c_client *client,
 				  const struct i2c_device_id *id)
 {
 	struct pm860x_platform_data *pdata = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct pm860x_chip *chip;
 	int ret;
 
-	if (!pdata) {
+	if (node && !pdata) {
+		/* parse DT to get platform data */
+		pdata = devm_kzalloc(&client->dev,
+				     sizeof(struct pm860x_platform_data),
+				     GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+		ret = pm860x_dt_init(node, &client->dev, pdata);
+		if (ret)
+			goto err;
+	} else if (!pdata) {
 		pr_info("No platform data in %s!\n", __func__);
 		return -EINVAL;
 	}
 
 	chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
-	if (chip == NULL)
-		return -ENOMEM;
+	if (chip == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
 
 	chip->id = verify_addr(client);
 	chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
@@ -1198,6 +1225,10 @@ static int __devinit pm860x_probe(struct i2c_client *client,
 
 	pm860x_device_init(chip, pdata);
 	return 0;
+err:
+	if (node)
+		devm_kfree(&client->dev, pdata);
+	return ret;
 }
 
 static int __devexit pm860x_remove(struct i2c_client *client)
@@ -1238,11 +1269,24 @@ static int pm860x_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
 
+static const struct i2c_device_id pm860x_id_table[] = {
+	{ "88PM860x", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
+
+static const struct of_device_id pm860x_dt_ids[] = {
+	{ .compatible = "marvell,88pm860x", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, pm860x_dt_ids);
+
 static struct i2c_driver pm860x_driver = {
 	.driver	= {
 		.name	= "88PM860x",
 		.owner	= THIS_MODULE,
 		.pm     = &pm860x_pm_ops,
+		.of_match_table	= of_match_ptr(pm860x_dt_ids),
 	},
 	.probe		= pm860x_probe,
 	.remove		= __devexit_p(pm860x_remove),
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index f96fbe3..1c5ab01 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -12,6 +12,8 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
@@ -364,6 +366,34 @@ static struct pm8607_regulator_info pm8606_regulator_info[] = {
 	PM8606_PREG(PREREGULATORB, 5),
 };
 
+#ifdef CONFIG_OF
+static int pm8607_regulator_dt_init(struct platform_device *pdev,
+				    struct pm8607_regulator_info *info,
+				    struct regulator_config *config)
+{
+	struct device_node *nproot, *np;
+	nproot = pdev->dev.parent->of_node;
+	if (!nproot)
+		return -ENODEV;
+	nproot = of_find_node_by_name(nproot, "regulators");
+	if (!nproot) {
+		dev_err(&pdev->dev, "failed to find regulators node\n");
+		return -ENODEV;
+	}
+	for_each_child_of_node(nproot, np) {
+		if (!of_node_cmp(np->name, info->desc.name)) {
+			config->init_data =
+				of_get_regulator_init_data(&pdev->dev, np);
+			config->of_node = np;
+			break;
+		}
+	}
+	return 0;
+}
+#else
+#define pm8607_regulator_dt_init(x, y, z)	(-1)
+#endif
+
 static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -402,9 +432,12 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
 		info->slope_double = 1;
 
 	config.dev = &pdev->dev;
-	config.init_data = pdata;
 	config.driver_data = info;
 
+	if (pm8607_regulator_dt_init(pdev, info, &config))
+		if (pdata)
+			config.init_data = pdata;
+
 	if (chip->id == CHIP_PM8607)
 		config.regmap = chip->regmap;
 	else
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index feddefc..de9e854 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
@@ -284,6 +285,28 @@ out:
 }
 #endif
 
+#ifdef CONFIG_OF
+static int __devinit pm860x_rtc_dt_init(struct platform_device *pdev,
+					struct pm860x_rtc_info *info)
+{
+	struct device_node *np = pdev->dev.parent->of_node;
+	int ret;
+	if (!np)
+		return -ENODEV;
+	np = of_find_node_by_name(np, "rtc");
+	if (!np) {
+		dev_err(&pdev->dev, "failed to find rtc node\n");
+		return -ENODEV;
+	}
+	ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc);
+	if (ret)
+		info->vrtc = 0;
+	return 0;
+}
+#else
+#define pm860x_rtc_dt_init(x, y)	(-1)
+#endif
+
 static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -294,8 +317,6 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
 	int ret;
 
 	pdata = pdev->dev.platform_data;
-	if (pdata == NULL)
-		dev_warn(&pdev->dev, "No platform data!\n");
 
 	info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL);
 	if (!info)
@@ -345,9 +366,11 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
 		}
 	}
 	rtc_tm_to_time(&tm, &ticks);
-	if (pdata && pdata->sync) {
-		pdata->sync(ticks);
-		info->sync = pdata->sync;
+	if (pm860x_rtc_dt_init(pdev, info)) {
+		if (pdata && pdata->sync) {
+			pdata->sync(ticks);
+			info->sync = pdata->sync;
+		}
 	}
 
 	info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev,
@@ -366,10 +389,12 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
 
 #ifdef VRTC_CALIBRATION
 	/* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */
-	if (pdata && pdata->vrtc)
-		info->vrtc = pdata->vrtc & 0x3;
-	else
-		info->vrtc = 1;
+	if (pm860x_rtc_dt_init(pdev, info)) {
+		if (pdata && pdata->vrtc)
+			info->vrtc = pdata->vrtc & 0x3;
+		else
+			info->vrtc = 1;
+	}
 	pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC);
 
 	/* calibrate VRTC */
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index 965161c..b7ec34c 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -11,6 +11,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/fb.h>
@@ -159,6 +160,36 @@ static const struct backlight_ops pm860x_backlight_ops = {
 	.get_brightness	= pm860x_backlight_get_brightness,
 };
 
+#ifdef CONFIG_OF
+static int pm860x_backlight_dt_init(struct platform_device *pdev,
+				    struct pm860x_backlight_data *data,
+				    char *name)
+{
+	struct device_node *nproot = pdev->dev.parent->of_node, *np;
+	int iset = 0;
+	if (!nproot)
+		return -ENODEV;
+	nproot = of_find_node_by_name(nproot, "backlights");
+	if (!nproot) {
+		dev_err(&pdev->dev, "failed to find backlights node\n");
+		return -ENODEV;
+	}
+	for_each_child_of_node(nproot, np) {
+		if (!of_node_cmp(np->name, name)) {
+			of_property_read_u32(np, "marvell,88pm860x-iset",
+					     &iset);
+			data->iset = PM8606_WLED_CURRENT(iset);
+			of_property_read_u32(np, "marvell,88pm860x-pwm",
+					     &data->pwm);
+			break;
+		}
+	}
+	return 0;
+}
+#else
+#define pm860x_backlight_dt_init(x, y, z)	(-1)
+#endif
+
 static int pm860x_backlight_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -203,9 +234,11 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
 	data->i2c = (chip->id == CHIP_PM8606) ? chip->client	\
 			: chip->companion;
 	data->current_brightness = MAX_BRIGHTNESS;
-	if (pdata) {
-		data->pwm = pdata->pwm;
-		data->iset = pdata->iset;
+	if (pm860x_backlight_dt_init(pdev, data, name)) {
+		if (pdata) {
+			data->pwm = pdata->pwm;
+			data->iset = pdata->iset;
+		}
 	}
 
 	memset(&props, 0, sizeof(struct backlight_properties));
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index d515e5c..ef3e6b7 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -306,7 +306,7 @@ struct pm860x_chip {
 	struct regmap           *regmap_companion;
 
 	int			buck3_double;	/* DVC ramp slope double */
-	unsigned short		companion_addr;
+	int			companion_addr;
 	unsigned short		osc_vote;
 	int			id;
 	int			irq_mode;
@@ -376,7 +376,7 @@ struct pm860x_platform_data {
 	struct regulator_init_data	*ldo_vibrator;
 	struct regulator_init_data	*ldo14;
 
-	unsigned short	companion_addr;	/* I2C address of companion chip */
+	int 		companion_addr;	/* I2C address of companion chip */
 	int		i2c_port;	/* Controlled by GI2C or PI2C */
 	int		irq_mode;	/* Clear interrupt by read/write(0/1) */
 	int		irq_base;	/* IRQ base number of 88pm860x */
-- 
1.7.9.5


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

* [PATCH 8/9] mfd: 88pm860x: move gpadc init into touch
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
                   ` (6 preceding siblings ...)
  2012-09-17  4:19 ` [PATCH 7/9] mfd: 88pm860x: support dt Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-17  4:19 ` [PATCH 9/9] ARM: dts: enable 88pm860x pmic Haojian Zhuang
  2012-09-19 11:26 ` [PATCH 0/9] mfd: update on 88pm860x and max8925 Samuel Ortiz
  9 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel
  Cc: Haojian Zhuang

The initilization of GPADC is moved from core driver to touch driver
with DT support.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/input/touchscreen/88pm860x-ts.c |   91 +++++++++++++++++++++++++++++--
 drivers/mfd/88pm860x-core.c             |   51 -----------------
 2 files changed, 85 insertions(+), 57 deletions(-)

diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
index 4f81e6e..326218d 100644
--- a/drivers/input/touchscreen/88pm860x-ts.c
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -116,9 +116,13 @@ static void pm860x_touch_close(struct input_dev *dev)
 
 #ifdef CONFIG_OF
 static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
+					  struct pm860x_chip *chip,
 					  int *res_x)
 {
 	struct device_node *np = pdev->dev.parent->of_node;
+	struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+				 : chip->companion;
+	int data, n, ret;
 	if (!np)
 		return -ENODEV;
 	np = of_find_node_by_name(np, "touch");
@@ -126,11 +130,43 @@ static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
 		dev_err(&pdev->dev, "Can't find touch node\n");
 		return -EINVAL;
 	}
+	/* set GPADC MISC1 register */
+	data = 0;
+	if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-prebias", &n))
+		data |= (n << 1) & PM8607_GPADC_PREBIAS_MASK;
+	if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-slot-cycle", &n))
+		data |= (n << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
+	if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-off-scale", &n))
+		data |= (n << 5) & PM8607_GPADC_OFF_SCALE_MASK;
+	if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-sw-cal", &n))
+		data |= (n << 7) & PM8607_GPADC_SW_CAL_MASK;
+	if (data) {
+		ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
+		if (ret < 0)
+			return -EINVAL;
+	}
+	/* set tsi prebias time */
+	if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
+		ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
+		if (ret < 0)
+			return -EINVAL;
+	}
+	/* set prebias & prechg time of pen detect */
+	data = 0;
+	if (!of_property_read_u32(np, "marvell,88pm860x-pen-prebias", &n))
+		data |= n & PM8607_PD_PREBIAS_MASK;
+	if (!of_property_read_u32(np, "marvell,88pm860x-pen-prechg", &n))
+		data |= n & PM8607_PD_PRECHG_MASK;
+	if (data) {
+		ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
+		if (ret < 0)
+			return -EINVAL;
+	}
 	of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
 	return 0;
 }
 #else
-#define pm860x_touch_dt_init(x, y)	(-1)
+#define pm860x_touch_dt_init(x, y, z)	(-1)
 #endif
 
 static int __devinit pm860x_touch_probe(struct platform_device *pdev)
@@ -138,7 +174,9 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
 	struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
 	struct pm860x_touch *touch;
-	int irq, ret, res_x = 0;
+	struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+				 : chip->companion;
+	int irq, ret, res_x = 0, data = 0;
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -146,14 +184,55 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	if (pm860x_touch_dt_init(pdev, &res_x)) {
-		if (pdata)
+	if (pm860x_touch_dt_init(pdev, chip, &res_x)) {
+		if (pdata) {
+			/* set GPADC MISC1 register */
+			data = 0;
+			data |= (pdata->gpadc_prebias << 1)
+				& PM8607_GPADC_PREBIAS_MASK;
+			data |= (pdata->slot_cycle << 3)
+				& PM8607_GPADC_SLOT_CYCLE_MASK;
+			data |= (pdata->off_scale << 5)
+				& PM8607_GPADC_OFF_SCALE_MASK;
+			data |= (pdata->sw_cal << 7)
+				& PM8607_GPADC_SW_CAL_MASK;
+			if (data) {
+				ret = pm860x_reg_write(i2c,
+					PM8607_GPADC_MISC1, data);
+				if (ret < 0)
+					return -EINVAL;
+			}
+			/* set tsi prebias time */
+			if (pdata->tsi_prebias) {
+				data = pdata->tsi_prebias;
+				ret = pm860x_reg_write(i2c,
+					PM8607_TSI_PREBIAS, data);
+				if (ret < 0)
+					return -EINVAL;
+			}
+			/* set prebias & prechg time of pen detect */
+			data = 0;
+			data |= pdata->pen_prebias
+				& PM8607_PD_PREBIAS_MASK;
+			data |= (pdata->pen_prechg << 5)
+				& PM8607_PD_PRECHG_MASK;
+			if (data) {
+				ret = pm860x_reg_write(i2c,
+					PM8607_PD_PREBIAS, data);
+				if (ret < 0)
+					return -EINVAL;
+			}
 			res_x = pdata->res_x;
-		else {
+		} else {
 			dev_err(&pdev->dev, "failed to get platform data\n");
 			return -EINVAL;
 		}
 	}
+	/* enable GPADC */
+	ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, PM8607_GPADC_EN,
+			      PM8607_GPADC_EN);
+	if (ret)
+		return ret;
 
 	touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
 	if (touch == NULL)
@@ -174,7 +253,7 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
 	touch->idev->open = pm860x_touch_open;
 	touch->idev->close = pm860x_touch_close;
 	touch->chip = chip;
-	touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+	touch->i2c = i2c;
 	touch->irq = irq;
 	touch->res_x = res_x;
 	input_set_drvdata(touch->idev, touch);
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 15ded0b..90d8ca6 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -558,53 +558,6 @@ static struct irq_domain_ops pm860x_irq_domain_ops = {
 	.xlate	= irq_domain_xlate_onetwocell,
 };
 
-static int __devinit device_gpadc_init(struct pm860x_chip *chip,
-				       struct pm860x_platform_data *pdata)
-{
-	struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
-				: chip->companion;
-	int data;
-	int ret;
-
-	/* initialize GPADC without activating it */
-
-	if (!pdata || !pdata->touch)
-		return -EINVAL;
-
-	/* set GPADC MISC1 register */
-	data = 0;
-	data |= (pdata->touch->gpadc_prebias << 1) & PM8607_GPADC_PREBIAS_MASK;
-	data |= (pdata->touch->slot_cycle << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
-	data |= (pdata->touch->off_scale << 5) & PM8607_GPADC_OFF_SCALE_MASK;
-	data |= (pdata->touch->sw_cal << 7) & PM8607_GPADC_SW_CAL_MASK;
-	if (data) {
-		ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
-		if (ret < 0)
-			goto out;
-	}
-	/* set tsi prebias time */
-	if (pdata->touch->tsi_prebias) {
-		data = pdata->touch->tsi_prebias;
-		ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
-		if (ret < 0)
-			goto out;
-	}
-	/* set prebias & prechg time of pen detect */
-	data = 0;
-	data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK;
-	data |= (pdata->touch->pen_prechg << 5) & PM8607_PD_PRECHG_MASK;
-	if (data) {
-		ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
-		if (ret < 0)
-			goto out;
-	}
-
-	ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1,
-			      PM8607_GPADC_EN, PM8607_GPADC_EN);
-out:
-	return ret;
-}
-
 static int __devinit device_irq_init(struct pm860x_chip *chip,
 				     struct pm860x_platform_data *pdata)
 {
@@ -1053,10 +1006,6 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
 		goto out;
 	}
 
-	ret = device_gpadc_init(chip, pdata);
-	if (ret < 0)
-		goto out;
-
 	ret = device_irq_init(chip, pdata);
 	if (ret < 0)
 		goto out;
-- 
1.7.9.5


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

* [PATCH 9/9] ARM: dts: enable 88pm860x pmic
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
                   ` (7 preceding siblings ...)
  2012-09-17  4:19 ` [PATCH 8/9] mfd: 88pm860x: move gpadc init into touch Haojian Zhuang
@ 2012-09-17  4:19 ` Haojian Zhuang
  2012-09-19 11:26 ` [PATCH 0/9] mfd: update on 88pm860x and max8925 Samuel Ortiz
  9 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17  4:19 UTC (permalink / raw)
  To: sameo, lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel
  Cc: Haojian Zhuang

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 arch/arm/boot/dts/pxa910-dkb.dts |  137 ++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/pxa910.dtsi    |    4 ++
 2 files changed, 141 insertions(+)

diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index e92be5a..595492a 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -29,6 +29,143 @@
 			};
 			twsi1: i2c@d4011000 {
 				status = "okay";
+
+				pmic: 88pm860x@34 {
+					compatible = "marvell,88pm860x";
+					reg = <0x34>;
+					interrupts = <4>;
+					interrupt-parent = <&intc>;
+					interrupt-controller;
+					#interrupt-cells = <1>;
+
+					marvell,88pm860x-irq-read-clr;
+					marvell,88pm860x-slave-addr = <0x11>;
+
+					regulators {
+						BUCK1 {
+							regulator-min-microvolt = <1000000>;
+							regulator-max-microvolt = <1500000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						BUCK2 {
+							regulator-min-microvolt = <1000000>;
+							regulator-max-microvolt = <1500000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						BUCK3 {
+							regulator-min-microvolt = <1000000>;
+							regulator-max-microvolt = <3000000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO1 {
+							regulator-min-microvolt = <1200000>;
+							regulator-max-microvolt = <2800000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO2 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO3 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO4 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-always-on;
+						};
+						LDO5 {
+							regulator-min-microvolt = <2900000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO6 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO7 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <2900000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO8 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <2900000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO9 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO10 {
+							regulator-min-microvolt = <1200000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO12 {
+							regulator-min-microvolt = <1200000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-always-on;
+						};
+						LDO13 {
+							regulator-min-microvolt = <1200000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-always-on;
+						};
+						LDO14 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-always-on;
+						};
+					};
+					rtc {
+						marvell,88pm860x-vrtc = <1>;
+					};
+					touch {
+						marvell,88pm860x-gpadc-prebias = <1>;
+						marvell,88pm860x-gpadc-slot-cycle = <1>;
+						marvell,88pm860x-tsi-prebias = <6>;
+						marvell,88pm860x-pen-prebias = <16>;
+						marvell,88pm860x-pen-prechg = <2>;
+						marvell,88pm860x-resistor-X = <300>;
+					};
+					backlights {
+						backlight-0 {
+							marvell,88pm860x-iset = <4>;
+							marvell,88pm860x-pwm = <3>;
+						};
+						backlight-2 {
+						};
+					};
+					leds {
+						led0-red {
+							marvell,88pm860x-iset = <12>;
+						};
+						led0-green {
+							marvell,88pm860x-iset = <12>;
+						};
+						led0-blue {
+							marvell,88pm860x-iset = <12>;
+						};
+					};
+				};
 			};
 			rtc: rtc@d4010000 {
 				status = "okay";
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index aebf32d..1942e54 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -115,6 +115,8 @@
 
 			twsi1: i2c@d4011000 {
 				compatible = "mrvl,mmp-twsi";
+				#address-cells = <1>;
+				#size-cells = <0>;
 				reg = <0xd4011000 0x1000>;
 				interrupts = <7>;
 				mrvl,i2c-fast-mode;
@@ -123,6 +125,8 @@
 
 			twsi2: i2c@d4037000 {
 				compatible = "mrvl,mmp-twsi";
+				#address-cells = <1>;
+				#size-cells = <0>;
 				reg = <0xd4037000 0x1000>;
 				interrupts = <54>;
 				status = "disabled";
-- 
1.7.9.5


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

* Re: [PATCH 7/9] mfd: 88pm860x: support dt
  2012-09-17  4:19 ` [PATCH 7/9] mfd: 88pm860x: support dt Haojian Zhuang
@ 2012-09-17  9:59   ` Mark Brown
  0 siblings, 0 replies; 19+ messages in thread
From: Mark Brown @ 2012-09-17  9:59 UTC (permalink / raw)
  To: Haojian Zhuang; +Cc: sameo, lrg, rpurdie, dmitry.torokhov, linux-kernel

On Mon, Sep 17, 2012 at 12:19:10PM +0800, Haojian Zhuang wrote:
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
>  drivers/input/touchscreen/88pm860x-ts.c |   46 +++++++++++++++--------
>  drivers/leds/leds-88pm860x.c            |   33 +++++++++++++++-
>  drivers/mfd/88pm860x-core.c             |   62 ++++++++++++++++++++++++++-----
>  drivers/regulator/88pm8607.c            |   35 ++++++++++++++++-
>  drivers/rtc/rtc-88pm860x.c              |   43 ++++++++++++++++-----
>  drivers/video/backlight/88pm860x_bl.c   |   39 +++++++++++++++++--
>  include/linux/mfd/88pm860x.h            |    4 +-
>  7 files changed, 221 insertions(+), 41 deletions(-)

Any new DT bindings should come with documentation in the appropriate
places under Documentation/devicetree.

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

* Re: [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator
  2012-09-17  4:19 ` [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator Haojian Zhuang
@ 2012-09-17 10:19   ` Mark Brown
  2012-09-17 10:28     ` Haojian Zhuang
  0 siblings, 1 reply; 19+ messages in thread
From: Mark Brown @ 2012-09-17 10:19 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: sameo, lrg, rpurdie, dmitry.torokhov, linux-kernel, Jett.Zhou

On Mon, Sep 17, 2012 at 12:19:06PM +0800, Haojian Zhuang wrote:
> From: "Jett.Zhou" <jtzhou@marvell.com>
> 
> Pre-regulator of 88pm8606 is mainly for support charging based on vbus,
> it needs to be enabled for charging battery, and will be disabled in
> some exception condition like over-temp.
> Add the pre-regulator support for 88pm860x regulator driver.
> 
> Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
> Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>

If you can sign this patch off I can apply it.

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

* Re: [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator
  2012-09-17 10:19   ` Mark Brown
@ 2012-09-17 10:28     ` Haojian Zhuang
  2012-09-17 10:40       ` Mark Brown
  0 siblings, 1 reply; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17 10:28 UTC (permalink / raw)
  To: Mark Brown; +Cc: sameo, lrg, rpurdie, dmitry.torokhov, linux-kernel, Jett.Zhou

On Mon, Sep 17, 2012 at 6:19 PM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Mon, Sep 17, 2012 at 12:19:06PM +0800, Haojian Zhuang wrote:
>> From: "Jett.Zhou" <jtzhou@marvell.com>
>>
>> Pre-regulator of 88pm8606 is mainly for support charging based on vbus,
>> it needs to be enabled for charging battery, and will be disabled in
>> some exception condition like over-temp.
>> Add the pre-regulator support for 88pm860x regulator driver.
>>
>> Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
>> Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
>
> If you can sign this patch off I can apply it.

Could this patch be merged into MFD tree? Since the fourth patch in this
patch series is depend on this one.

Best Regards
Haojian

From: Haojian Zhuang <haojian.zhuang@marvell.com>

Since PREG regulator is the only one regulator in 88PM8606, and other
regulators are in 88PM8607. Checking resource as identifying regulator
is not a good way. We can use NULL resource to indentify PREG regulator.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
---
 drivers/mfd/88pm860x-core.c  |    8 +-------
 drivers/regulator/88pm8607.c |   32 +++++++++++++++++++-------------
 2 files changed, 20 insertions(+), 20 deletions(-)

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

* Re: [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator
  2012-09-17 10:28     ` Haojian Zhuang
@ 2012-09-17 10:40       ` Mark Brown
  2012-09-17 13:42         ` Haojian Zhuang
  0 siblings, 1 reply; 19+ messages in thread
From: Mark Brown @ 2012-09-17 10:40 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: sameo, lrg, rpurdie, dmitry.torokhov, linux-kernel, Jett.Zhou

On Mon, Sep 17, 2012 at 06:28:18PM +0800, Haojian Zhuang wrote:

> Could this patch be merged into MFD tree? Since the fourth patch in this
> patch series is depend on this one.

Why is there a dependency?

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

* Re: [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator
  2012-09-17 10:40       ` Mark Brown
@ 2012-09-17 13:42         ` Haojian Zhuang
  0 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-17 13:42 UTC (permalink / raw)
  To: Mark Brown; +Cc: sameo, lrg, rpurdie, dmitry.torokhov, linux-kernel, Jett.Zhou

On Mon, Sep 17, 2012 at 6:40 PM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Mon, Sep 17, 2012 at 06:28:18PM +0800, Haojian Zhuang wrote:
>
>> Could this patch be merged into MFD tree? Since the fourth patch in this
>> patch series is depend on this one.
>
> Why is there a dependency?
> --
This patch is picked from Jett's patch on power device of 88pm860x.
His patch addes the support
of PREG regulator in 88pm8607 regulator driver. Although this patch
was submitted for a long time,
it wasn't merged yet.

And I have a patch series on updating 88pm860x driver with
IORESOURCE_REG. One patch in that
series is used to split regulator subdevs into an array of regulator
subdevs. It results in 88pm860x
regulator driver updated and merged into MFD for-next branch.

Since both Jett's patch and my patch updates code in probe() function
of 88pm860x regulator driver,
some code between these two patches conflicts. So I make the fourth
patch in current series to resolve
this conflict on MFD for-next branch.

If you agree on merging this patch series into MFD tree without your
Ack, it would be simple way. Or I
could rebase it and split them into two different patch series for MFD
and regulator tree. Which way do
you like?

Best Regards
Haojian

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

* Re: [PATCH 0/9] mfd: update on 88pm860x and max8925
  2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
                   ` (8 preceding siblings ...)
  2012-09-17  4:19 ` [PATCH 9/9] ARM: dts: enable 88pm860x pmic Haojian Zhuang
@ 2012-09-19 11:26 ` Samuel Ortiz
  2012-09-19 11:49   ` Mark Brown
  2012-09-21 10:10   ` Haojian Zhuang
  9 siblings, 2 replies; 19+ messages in thread
From: Samuel Ortiz @ 2012-09-19 11:26 UTC (permalink / raw)
  To: Haojian Zhuang; +Cc: lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel

Hi Haojian,

On Mon, Sep 17, 2012 at 12:19:03PM +0800, Haojian Zhuang wrote:
> 1. Updates the patch of max8925 of building issue.
> 2. Include Jett's PREG regulator patch.
> 3. Support DT in 88pm860x.

I applied the 5 first patches.
For the regulator one, I'd like to get Mark's ACK as well.

Patch #6 did not apply cleanly.
Patch #7 needs some fixes and documentation addition.
Patch #8 needs Dmitry's ACK

And I can take patch #9 once #7 is in.

Cheers,
Samuel.

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

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

* Re: [PATCH 0/9] mfd: update on 88pm860x and max8925
  2012-09-19 11:26 ` [PATCH 0/9] mfd: update on 88pm860x and max8925 Samuel Ortiz
@ 2012-09-19 11:49   ` Mark Brown
  2012-09-21 10:16     ` Haojian Zhuang
  2012-09-21 10:10   ` Haojian Zhuang
  1 sibling, 1 reply; 19+ messages in thread
From: Mark Brown @ 2012-09-19 11:49 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: Haojian Zhuang, lrg, rpurdie, dmitry.torokhov, linux-kernel

On Wed, Sep 19, 2012 at 01:26:14PM +0200, Samuel Ortiz wrote:

> I applied the 5 first patches.
> For the regulator one, I'd like to get Mark's ACK as well.

I'm still waiting for an update on what the depdencies in the rest of
the series are.

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

* Re: [PATCH 0/9] mfd: update on 88pm860x and max8925
  2012-09-19 11:26 ` [PATCH 0/9] mfd: update on 88pm860x and max8925 Samuel Ortiz
  2012-09-19 11:49   ` Mark Brown
@ 2012-09-21 10:10   ` Haojian Zhuang
  1 sibling, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-21 10:10 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: lrg, broonie, rpurdie, dmitry.torokhov, linux-kernel

On Wed, Sep 19, 2012 at 7:26 PM, Samuel Ortiz <sameo@linux.intel.com> wrote:
> Hi Haojian,
>
> On Mon, Sep 17, 2012 at 12:19:03PM +0800, Haojian Zhuang wrote:
>> 1. Updates the patch of max8925 of building issue.
>> 2. Include Jett's PREG regulator patch.
>> 3. Support DT in 88pm860x.
>
> I applied the 5 first patches.
> For the regulator one, I'd like to get Mark's ACK as well.
>
> Patch #6 did not apply cleanly.
> Patch #7 needs some fixes and documentation addition.
> Patch #8 needs Dmitry's ACK
>
> And I can take patch #9 once #7 is in.
>

I updated those patches.

Thanks
Haojian

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

* Re: [PATCH 0/9] mfd: update on 88pm860x and max8925
  2012-09-19 11:49   ` Mark Brown
@ 2012-09-21 10:16     ` Haojian Zhuang
  0 siblings, 0 replies; 19+ messages in thread
From: Haojian Zhuang @ 2012-09-21 10:16 UTC (permalink / raw)
  To: Mark Brown; +Cc: Samuel Ortiz, lrg, rpurdie, dmitry.torokhov, linux-kernel

On Wed, Sep 19, 2012 at 7:49 PM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Wed, Sep 19, 2012 at 01:26:14PM +0200, Samuel Ortiz wrote:
>
>> I applied the 5 first patches.
>> For the regulator one, I'd like to get Mark's ACK as well.
>
> I'm still waiting for an update on what the depdencies in the rest of
> the series are.

Jett's PREG patch is used to append PREG regulator. My patch is used
to avoid checking
resource of PREG regulator. Without Jett's patch, my patch doesn't
make sense. So I prefer
both of these two patches could go through into same git tree.

Best Regards
Haojian

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

end of thread, other threads:[~2012-09-21 10:16 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-17  4:19 [PATCH 0/9] mfd: update on 88pm860x and max8925 Haojian Zhuang
2012-09-17  4:19 ` [PATCH 1/9] mfd: max8925: use register offset as REG in backlight Haojian Zhuang
2012-09-17  4:19 ` [PATCH 2/9] mfd: max8925: remove array in regulator platform data Haojian Zhuang
2012-09-17  4:19 ` [PATCH 3/9] regulator: 88pm860x: add pre-regulator support for 88pm860x regulator Haojian Zhuang
2012-09-17 10:19   ` Mark Brown
2012-09-17 10:28     ` Haojian Zhuang
2012-09-17 10:40       ` Mark Brown
2012-09-17 13:42         ` Haojian Zhuang
2012-09-17  4:19 ` [PATCH 4/9] mfd: 88pm860x: avoid to check resource for preg regulator Haojian Zhuang
2012-09-17  4:19 ` [PATCH 5/9] mfd: 88pm860x: move initilization code Haojian Zhuang
2012-09-17  4:19 ` [PATCH 6/9] mfd: 88pm860x: use irqdomain Haojian Zhuang
2012-09-17  4:19 ` [PATCH 7/9] mfd: 88pm860x: support dt Haojian Zhuang
2012-09-17  9:59   ` Mark Brown
2012-09-17  4:19 ` [PATCH 8/9] mfd: 88pm860x: move gpadc init into touch Haojian Zhuang
2012-09-17  4:19 ` [PATCH 9/9] ARM: dts: enable 88pm860x pmic Haojian Zhuang
2012-09-19 11:26 ` [PATCH 0/9] mfd: update on 88pm860x and max8925 Samuel Ortiz
2012-09-19 11:49   ` Mark Brown
2012-09-21 10:16     ` Haojian Zhuang
2012-09-21 10:10   ` Haojian Zhuang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).