[PATCH v2] regulators: add support max8952 regulator

Kukjin Kim kgene.kim at samsung.com
Tue Sep 7 03:23:22 EDT 2010


From: Changhwan Youn <chaos.youn at samsung.com>

The operation of max8952 is almost similar to max8649 except
the output voltage range. This patch adds support the max8952
regulator using current max8649 implementation.

Signed-off-by: Changhwan Youn <chaos.youn at samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim at samsung.com>
Cc: Mark Brown <broonie at opensource.wolfsonmicro.com>
---
Changes since v1:
Following is as per Mark Brown's suggestion.
- Added returning fail when detected wrong ID
- Added matching the ID from the chip in case the user got things wrong
- Added enum chip ID instead of 0, 1

Mark Brown, Thanks

NOTE: Following is test log

1) In the case of success
s3c-i2c s3c2410-i2c.0: slave address 0x10
s3c-i2c s3c2410-i2c.0: bus frequency set to 97 KHz
max8649 0-0060: Detected max8952 (ID: 0x201a)
regulator: vdd_arm range: 770 <--> 1400 mV at 1100 mV
max8649 0-0060: max8952 regulator device is detected.
max8649 0-0062: Detected max8649 (ID: 0x200a)
regulator: vdd_g3d range: 750 <--> 1380 mV at 1230 mV
max8649 0-0062: max8649 regulator device is detected.
s3c-i2c s3c2410-i2c.0: i2c-0: S3C I2C adapter
s3c-i2c s3c2410-i2c.1: slave address 0x10
s3c-i2c s3c2410-i2c.1: bus frequency set to 97 KHz
max8649 1-0060: Detected max8649 (ID: 0x200a)
regulator: vdd_int range: 750 <--> 1380 mV at 1230 mV
max8649 1-0060: max8649 regulator device is detected.
s3c-i2c s3c2410-i2c.1: i2c-1: S3C I2C adapter

2) In the case of fail
s3c-i2c s3c2410-i2c.0: slave address 0x10
s3c-i2c s3c2410-i2c.0: bus frequency set to 97 KHz
max8649 0-0060: Failed to detect the device
requested : 0x200a, detected 0x201a
max8649 0-0062: Detected max8649 (ID: 0x200a)
regulator: vdd_g3d range: 750 <--> 1380 mV at 1230 mV
max8649 0-0062: max8649 regulator device is detected.
s3c-i2c s3c2410-i2c.0: i2c-0: S3C I2C adapter
s3c-i2c s3c2410-i2c.1: slave address 0x10
s3c-i2c s3c2410-i2c.1: bus frequency set to 97 KHz
max8649 1-0060: Failed to detect the device
requested : 0x201a, detected 0x200a
s3c-i2c s3c2410-i2c.1: i2c-1: S3C I2C adapter


 drivers/regulator/Kconfig   |    4 +-
 drivers/regulator/max8649.c |   55 +++++++++++++++++++++++++++++++++++++-----
 2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 172951b..fab9a90 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -81,10 +81,10 @@ config REGULATOR_MAX1586
 	  for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
 
 config REGULATOR_MAX8649
-	tristate "Maxim 8649 voltage regulator"
+	tristate "Maxim 8649/8952 voltage regulator"
 	depends on I2C
 	help
-	  This driver controls a Maxim 8649 voltage output regulator via
+	  This driver controls a Maxim 8649/8952 voltage output regulator via
 	  I2C bus.
 
 config REGULATOR_MAX8660
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index 4520ace..7f61a3a 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -22,6 +22,9 @@
 #define MAX8649_DCDC_STEP	10000		/* uV */
 #define MAX8649_VOL_MASK	0x3f
 
+/* difference between voltages of max8649 and max8952 */
+#define DIFF_MAX8952_DCDC_VOL	20000		/* uV */
+
 /* Registers */
 #define MAX8649_MODE0		0x00
 #define MAX8649_MODE1		0x01
@@ -47,6 +50,11 @@
 #define MAX8649_RAMP_MASK	(7 << 5)
 #define MAX8649_RAMP_DOWN	(1 << 1)
 
+enum chips {
+	MAX8649 = 0x200a,
+	MAX8952 = 0x201a,
+};
+
 struct max8649_regulator_info {
 	struct regulator_dev	*regulator;
 	struct i2c_client	*i2c;
@@ -54,6 +62,7 @@ struct max8649_regulator_info {
 	struct mutex		io_lock;
 
 	int		vol_reg;
+	int		type;
 	unsigned	mode:2;	/* bit[1:0] = VID1, VID0 */
 	unsigned	extclk_freq:2;
 	unsigned	extclk:1;
@@ -138,7 +147,12 @@ static inline int check_range(int min_uV, int max_uV)
 
 static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index)
 {
-	return (MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP);
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret = MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP;
+
+	if (info->type == MAX8952)
+		ret += DIFF_MAX8952_DCDC_VOL;
+	return ret;
 }
 
 static int max8649_get_voltage(struct regulator_dev *rdev)
@@ -160,6 +174,11 @@ static int max8649_set_voltage(struct regulator_dev *rdev,
 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
 	unsigned char data, mask;
 
+	if (info->type == MAX8952) {
+		min_uV -= DIFF_MAX8952_DCDC_VOL;
+		max_uV -= DIFF_MAX8952_DCDC_VOL;
+	}
+
 	if (check_range(min_uV, max_uV)) {
 		dev_err(info->dev, "invalid voltage range (%d, %d) uV\n",
 			min_uV, max_uV);
@@ -263,7 +282,6 @@ static struct regulator_ops max8649_dcdc_ops = {
 	.enable_time	= max8649_enable_time,
 	.set_mode	= max8649_set_mode,
 	.get_mode	= max8649_get_mode,
-
 };
 
 static struct regulator_desc dcdc_desc = {
@@ -281,6 +299,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
 	struct max8649_regulator_info *info = NULL;
 	unsigned char data;
 	int ret;
+	int chip_id;
 
 	info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL);
 	if (!info) {
@@ -313,11 +332,32 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
 
 	ret = max8649_reg_read(info->i2c, MAX8649_CHIP_ID1);
 	if (ret < 0) {
-		dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
-			ret);
+		dev_err(info->dev, "Failed to detect ID1 of %s:%d\n",
+			id->name, ret);
 		goto out;
 	}
-	dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret);
+	chip_id = ret;
+
+	ret = max8649_reg_read(info->i2c, MAX8649_CHIP_ID2);
+	if (ret < 0) {
+		dev_err(info->dev, "Failed to detect ID2 of %s:%d\n",
+			id->name, ret);
+		goto out;
+	}
+
+	chip_id = (chip_id << 8) | ret;
+
+	if (id->driver_data != chip_id) {
+		dev_err(info->dev, "Failed to detect the device\n"
+				   "requested : 0x%x, detected 0x%x\n",
+				   id->driver_data, chip_id);
+		ret = -ENODEV;
+		goto out;
+	}
+
+	dev_info(info->dev, "Detected %s (ID: 0x%x)\n", id->name, chip_id);
+
+	info->type = id->driver_data;
 
 	/* enable VID0 & VID1 */
 	max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_VID_MASK, 0);
@@ -354,7 +394,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
 		goto out;
 	}
 
-	dev_info(info->dev, "Max8649 regulator device is detected.\n");
+	dev_info(info->dev, "%s regulator device is detected.\n", id->name);
 	return 0;
 out:
 	kfree(info);
@@ -375,7 +415,8 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id max8649_id[] = {
-	{ "max8649", 0 },
+	{ "max8649", MAX8649 },
+	{ "max8952", MAX8952 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, max8649_id);
-- 
1.6.2.5




More information about the linux-arm-kernel mailing list