diff mbox

[1/2] Exynos4 NURI: configure regulators and PMIC

Message ID 1308215372-17420-1-git-send-email-myungjoo.ham@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

MyungJoo Ham June 16, 2011, 9:09 a.m. UTC
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-exynos4/mach-nuri.c |  660 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 659 insertions(+), 1 deletions(-)

Comments

Mark Brown June 18, 2011, 3:12 p.m. UTC | #1
On Thu, Jun 16, 2011 at 06:09:31PM +0900, MyungJoo Ham wrote:

>  static struct regulator_init_data emmc_fixed_voltage_init_data = {
>  	.constraints		= {
> +		.min_uV		= 2800000,
> +		.max_uV		= 2800000,
>  		.name		= "VMEM_VDD_2.8V",
>  		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,

Since the regualtor can't change voltage specifying the voltage here
isn't going to achieve anything - to get the voltage reported through
get_voltage() you need to put the voltage in the platform data for the
fixed regulator.

> +static struct regulator_consumer_supply nuri_max8997_ldo1_consumer[] = {
> +	REGULATOR_SUPPLY("vadc", NULL), /* Used by CPU's ADC drv */
> +};

In the ADC regulator patch you called the supply vdd (though the chip
normally calls it vadc so that's the better name)...

Extra ' too.

> +static struct regulator_consumer_supply nuri_max8997_ldo8_consumer[] = {
> +	REGULATOR_SUPPLY("vusb_d", NULL), /* Used by CPU */
> +	REGULATOR_SUPPLY("vdac", NULL), /* Used by CPU */
> +};

Another VADC?  For a different supply?

> +		.state_mem	= {
> +			.enabled	= 0,

No need to initialize to zero.

> +static struct regulator_init_data nuri_max8997_ldo10_data = {
> +	.constraints	= {

You should be able to use __initdata for a lot of this by the way.

> +#define NURI_PMIC_GPIO		EXYNOS4_GPX0(7)
> +static void __init nuri_pmic_init(void)
> +{
> +	int gpio;
> +
> +	nuri_max8997_pdata.irq_base = irq_get_next_irq(IRQ_GPIO_END);
> +	gpio = NURI_PMIC_GPIO;
> +	gpio_request(gpio, "AP_PMIC_IRQ");
> +	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
> +	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +}

I'm not sure both the #define and the variable make sense here...
MyungJoo Ham June 20, 2011, 6:26 a.m. UTC | #2
On Sun, Jun 19, 2011 at 12:12 AM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Thu, Jun 16, 2011 at 06:09:31PM +0900, MyungJoo Ham wrote:
>
>>  static struct regulator_init_data emmc_fixed_voltage_init_data = {
>>       .constraints            = {
>> +             .min_uV         = 2800000,
>> +             .max_uV         = 2800000,
>>               .name           = "VMEM_VDD_2.8V",
>>               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
>
> Since the regualtor can't change voltage specifying the voltage here
> isn't going to achieve anything - to get the voltage reported through
> get_voltage() you need to put the voltage in the platform data for the
> fixed regulator.

Ah.. they are useless. I'll remove them.

>
>> +static struct regulator_consumer_supply nuri_max8997_ldo1_consumer[] = {
>> +     REGULATOR_SUPPLY("vadc", NULL), /* Used by CPU's ADC drv */
>> +};
>
> In the ADC regulator patch you called the supply vdd (though the chip
> normally calls it vadc so that's the better name)...

Um.. this happened as I have seperated NURI-board platform patch for
ADC and PMIC.
After ADC patch, that name became ("vdd", "s5p-adc").
I'll let them either be merged or be disjoint completely.

Anyway, do you think "vadc" is better than "vdd" for ADC drivers? The
circuit schematics says the pin on the consumer side is "VDD33_ADC"
(VDD 3.3V for ADC).


>
> Extra ' too.
>
>> +static struct regulator_consumer_supply nuri_max8997_ldo8_consumer[] = {
>> +     REGULATOR_SUPPLY("vusb_d", NULL), /* Used by CPU */
>> +     REGULATOR_SUPPLY("vdac", NULL), /* Used by CPU */
>> +};
>
> Another VADC?  For a different supply?

That's DAC (opposite to ADC).

>
>> +             .state_mem      = {
>> +                     .enabled        = 0,
>
> No need to initialize to zero.

Ok, I'll remove every zero-initialization from the patch.

>
>> +static struct regulator_init_data nuri_max8997_ldo10_data = {
>> +     .constraints    = {
>
> You should be able to use __initdata for a lot of this by the way.

Ah.. way to reduce some weight. Fine.

>
>> +#define NURI_PMIC_GPIO               EXYNOS4_GPX0(7)
>> +static void __init nuri_pmic_init(void)
>> +{
>> +     int gpio;
>> +
>> +     nuri_max8997_pdata.irq_base = irq_get_next_irq(IRQ_GPIO_END);
>> +     gpio = NURI_PMIC_GPIO;
>> +     gpio_request(gpio, "AP_PMIC_IRQ");
>> +     s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
>> +     s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
>> +}
>
> I'm not sure both the #define and the variable make sense here...
>

I've defined them because two statements are using the gpio address of
NURI_PMIC.



Thanks you very much!

- MyungJoo
MyungJoo Ham June 20, 2011, 7:58 a.m. UTC | #3
Hello.

On Sun, Jun 19, 2011 at 12:12 AM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Thu, Jun 16, 2011 at 06:09:31PM +0900, MyungJoo Ham wrote:
>
[]
>
>> +static struct regulator_init_data nuri_max8997_ldo10_data = {
>> +     .constraints    = {
>
> You should be able to use __initdata for a lot of this by the way.
>


Anyway, I've got a question about using __initdata for platform_data entries.

Using __initdata on this entry and other max8997's platform_data did
not create any SECTION MISMATCH warnings.

"Documentation/DocBook/kernel-hacking.tmpl" says, __initdata means
that the content of it may be free'd after boot.


However, the MAX8997 driver uses platform_data's entry (variables
defined in "static struct max8997_platform_data __initdata
nuri_max8997_pdata)
in its normal functions other than its probe function, which are often
called after boot.

Probably, I'm thinking wrong in some place; however, it seems that
there should be SECTION MISMATCH warnings as the MAX8997 driver uses
the pdata, which is declared to be __initdata, in non-_init function.
Or, is it safe to use platform_data (by dev_get_platdata) out of probe
in drivers even if the platdata is declared to be __initdata in the
platform files?

I just can't sure whether I should let probe function copy
platform-data used by non-probe functions to its own local data
assuming that the content may be freed (assuming that the SECTION
MISMATCH warning is not "complete".) or just believe the completeness
of gcc's SECTION MISMATCH warning.


Cheers!

- MyungJoo
Mark Brown June 20, 2011, 10:27 a.m. UTC | #4
On Mon, Jun 20, 2011 at 03:26:08PM +0900, MyungJoo Ham wrote:
> On Sun, Jun 19, 2011 at 12:12 AM, Mark Brown

> >> +static struct regulator_consumer_supply nuri_max8997_ldo1_consumer[] = {
> >> +     REGULATOR_SUPPLY("vadc", NULL), /* Used by CPU's ADC drv */
> >> +};

> > In the ADC regulator patch you called the supply vdd (though the chip
> > normally calls it vadc so that's the better name)...

> Um.. this happened as I have seperated NURI-board platform patch for
> ADC and PMIC.
> After ADC patch, that name became ("vdd", "s5p-adc").
> I'll let them either be merged or be disjoint completely.

You may as well get it right to start off with, there's no harm 
defining a supply that doesn't get used.

> Anyway, do you think "vadc" is better than "vdd" for ADC drivers? The
> circuit schematics says the pin on the consumer side is "VDD33_ADC"
> (VDD 3.3V for ADC).

If that's what the pin is called on the package that is the best name
to use.

> >> +static void __init nuri_pmic_init(void)
> >> +{
> >> +     int gpio;
> >> +
> >> +     nuri_max8997_pdata.irq_base = irq_get_next_irq(IRQ_GPIO_END);
> >> +     gpio = NURI_PMIC_GPIO;
> >> +     gpio_request(gpio, "AP_PMIC_IRQ");
> >> +     s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
> >> +     s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> >> +}

> > I'm not sure both the #define and the variable make sense here...

> I've defined them because two statements are using the gpio address of
> NURI_PMIC.

Right, but there's no point in doing both - either use the #define
everywhere or use the variable everywhere but having both seems
excessive.
Mark Brown June 20, 2011, 10:31 a.m. UTC | #5
On Mon, Jun 20, 2011 at 04:58:09PM +0900, MyungJoo Ham wrote:

> However, the MAX8997 driver uses platform_data's entry (variables
> defined in "static struct max8997_platform_data __initdata
> nuri_max8997_pdata)
> in its normal functions other than its probe function, which are often
> called after boot.

That's bad practice on its part.

> I just can't sure whether I should let probe function copy
> platform-data used by non-probe functions to its own local data

This is the best fix.
MyungJoo Ham June 21, 2011, 2:07 a.m. UTC | #6
1/4: Add configuration for MAX8997 PMIC and regulators
2/4: Add configuration for MAX17042 fuel gauge.
3/4: Add configuration for ADC
	depends on the recently submitted ADC for Samsung SoC patch series:
	[PATCH v2 0/5] Update Samsung-SoC ADC (regulator / recent CPU support)
4/4: Add configuration for NTC themistor.
	depends on the recently submitted NTC-thermistor patch:
	[PATCH v10] drivers/hwmon NTC Thermistor Initial Support v10 (applied to next)

MyungJoo Ham (4):
  Exynos4 NURI: configure regulators and PMIC
  Exynos4 NURI: configure MAX17042 fuel gauge
  Exynos4 NURI: configure ADC.
  Exynos4 NURI: support for NTC thermistor

 arch/arm/mach-exynos4/mach-nuri.c |  703 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 702 insertions(+), 1 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c
index 642702b..c8c2431 100644
--- a/arch/arm/mach-exynos4/mach-nuri.c
+++ b/arch/arm/mach-exynos4/mach-nuri.c
@@ -17,6 +17,7 @@ 
 #include <linux/gpio.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
+#include <linux/mfd/max8997.h>
 #include <linux/mmc/host.h>
 #include <linux/fb.h>
 #include <linux/pwm_backlight.h>
@@ -100,6 +101,8 @@  static struct regulator_consumer_supply emmc_supplies[] = {
 
 static struct regulator_init_data emmc_fixed_voltage_init_data = {
 	.constraints		= {
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
 		.name		= "VMEM_VDD_2.8V",
 		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
 	},
@@ -344,9 +347,660 @@  static void __init nuri_tsp_init(void)
 	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
 }
 
+static struct regulator_consumer_supply nuri_max8997_ldo1_consumer[] = {
+	REGULATOR_SUPPLY("vadc", NULL), /* Used by CPU's ADC drv */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo3_consumer[] = {
+	REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"), /* MIPI */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo4_consumer[] = {
+	REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"), /* MIPI */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo5_consumer[] = {
+	REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo7_consumer[] = {
+	REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo8_consumer[] = {
+	REGULATOR_SUPPLY("vusb_d", NULL), /* Used by CPU */
+	REGULATOR_SUPPLY("vdac", NULL), /* Used by CPU */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo11_consumer[] = {
+	REGULATOR_SUPPLY("vcc", "platform-lcd"), /* U804 LVDS */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo12_consumer[] = {
+	REGULATOR_SUPPLY("vddio", "6-003c"), /* HDC802 */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo13_consumer[] = {
+	REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), /* TFLASH */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo14_consumer[] = {
+	REGULATOR_SUPPLY("inmotor", "max8997-haptic"),
+};
+static struct regulator_consumer_supply nuri_max8997_ldo15_consumer[] = {
+	REGULATOR_SUPPLY("avdd", "3-004a"), /* Touch Screen */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo16_consumer[] = {
+	REGULATOR_SUPPLY("d_sensor", "0-001f"), /* HDC803 */
+};
+static struct regulator_consumer_supply nuri_max8997_ldo18_consumer[] = {
+	REGULATOR_SUPPLY("vdd", "3-004a"), /* Touch Screen */
+};
+static struct regulator_consumer_supply nuri_max8997_buck1_consumer[] = {
+	REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
+};
+static struct regulator_consumer_supply nuri_max8997_buck2_consumer[] = {
+	REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */
+};
+static struct regulator_consumer_supply nuri_max8997_buck3_consumer[] = {
+	REGULATOR_SUPPLY("vdd", "mali_dev.0"), /* G3D of Exynos 4 */
+};
+static struct regulator_consumer_supply nuri_max8997_buck4_consumer[] = {
+	REGULATOR_SUPPLY("core", "0-001f"), /* HDC803 */
+};
+static struct regulator_consumer_supply nuri_max8997_buck6_consumer[] = {
+	REGULATOR_SUPPLY("dig_28", "0-001f"), /* pin "7" of HDC803 */
+};
+static struct regulator_consumer_supply nuri_max8997_esafeout1_consumer[] = {
+	REGULATOR_SUPPLY("usb_vbus", NULL), /* CPU's USB OTG */
+};
+static struct regulator_consumer_supply nuri_max8997_esafeout2_consumer[] = {
+	REGULATOR_SUPPLY("usb_vbus", "modemctl"), /* VBUS of Modem */
+};
+
+static struct regulator_consumer_supply nuri_max8997_charger_consumer[] = {
+	REGULATOR_SUPPLY("vinchg1", "charger-manager.0"),
+};
+static struct regulator_consumer_supply nuri_max8997_chg_toff_consumer[] = {
+	REGULATOR_SUPPLY("vinchg_stop", NULL), /* for jack interrupt handlers */
+};
+
+static struct regulator_consumer_supply nuri_max8997_32khz_ap_consumer[] = {
+	REGULATOR_SUPPLY("gps_clk", "bcm4751"),
+	REGULATOR_SUPPLY("bt_clk", "bcm4330-b1"),
+	REGULATOR_SUPPLY("wifi_clk", "bcm433-b1"),
+};
+
+static struct regulator_init_data nuri_max8997_ldo1_data = {
+	.constraints	= {
+		.name		= "VADC_3.3V_C210",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo1_consumer),
+	.consumer_supplies	= nuri_max8997_ldo1_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo2_data = {
+	.constraints	= {
+		.name		= "VALIVE_1.1V_C210",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled	= 1,
+			.disabled	= 0,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_ldo3_data = {
+	.constraints	= {
+		.name		= "VUSB_1.1V_C210",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo3_consumer),
+	.consumer_supplies	= nuri_max8997_ldo3_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo4_data = {
+	.constraints	= {
+		.name		= "VMIPI_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo4_consumer),
+	.consumer_supplies	= nuri_max8997_ldo4_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo5_data = {
+	.constraints	= {
+		.name		= "VHSIC_1.2V_C210",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo5_consumer),
+	.consumer_supplies	= nuri_max8997_ldo5_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo6_data = {
+	.constraints	= {
+		.name		= "VCC_1.8V_PDA",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled	= 1,
+			.disabled	= 0,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_ldo7_data = {
+	.constraints	= {
+		.name		= "CAM_ISP_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo7_consumer),
+	.consumer_supplies	= nuri_max8997_ldo7_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo8_data = {
+	.constraints	= {
+		.name		= "VUSB/VDAC_3.3V_C210",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo8_consumer),
+	.consumer_supplies	= nuri_max8997_ldo8_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo9_data = {
+	.constraints	= {
+		.name		= "VCC_2.8V_PDA",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled	= 1,
+			.disabled	= 0,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_ldo10_data = {
+	.constraints	= {
+		.name		= "VPLL_1.1V_C210",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_ldo11_data = {
+	.constraints	= {
+		.name		= "LVDS_VDD3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.boot_on	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo11_consumer),
+	.consumer_supplies	= nuri_max8997_ldo11_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo12_data = {
+	.constraints	= {
+		.name		= "VT_CAM_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo12_consumer),
+	.consumer_supplies	= nuri_max8997_ldo12_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo13_data = {
+	.constraints	= {
+		.name		= "VTF_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo13_consumer),
+	.consumer_supplies	= nuri_max8997_ldo13_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo14_data = {
+	.constraints	= {
+		.name		= "VCC_3.0V_MOTOR",
+		.min_uV		= 3000000,
+		.max_uV		= 3000000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo14_consumer),
+	.consumer_supplies	= nuri_max8997_ldo14_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo15_data = {
+	.constraints	= {
+		.name		= "VTOUCH_ADVV2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo15_consumer),
+	.consumer_supplies	= nuri_max8997_ldo15_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo16_data = {
+	.constraints	= {
+		.name		= "CAM_SENSOR_IO_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo16_consumer),
+	.consumer_supplies	= nuri_max8997_ldo16_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo18_data = {
+	.constraints	= {
+		.name		= "VTOUCH_VDD2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo18_consumer),
+	.consumer_supplies	= nuri_max8997_ldo18_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_ldo21_data = {
+	.constraints	= {
+		.name		= "VDDQ_M1M2_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled	= 0,
+			.disabled	= 1,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_buck1_data = {
+	.constraints	= {
+		.name		= "VARM_1.2V_C210",
+		.min_uV		= 900000,
+		.max_uV		= 1350000,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies = ARRAY_SIZE(nuri_max8997_buck1_consumer),
+	.consumer_supplies = nuri_max8997_buck1_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_buck2_data = {
+	.constraints	= {
+		.name		= "VINT_1.1V_C210",
+		.min_uV		= 900000,
+		.max_uV		= 1100000,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies = ARRAY_SIZE(nuri_max8997_buck2_consumer),
+	.consumer_supplies = nuri_max8997_buck2_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_buck3_data = {
+	.constraints	= {
+		.name		= "VG3D_1.1V_C210",
+		.min_uV		= 900000,
+		.max_uV		= 1100000,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies = ARRAY_SIZE(nuri_max8997_buck3_consumer),
+	.consumer_supplies = nuri_max8997_buck3_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_buck4_data = {
+	.constraints	= {
+		.name		= "CAM_ISP_CORE_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies = ARRAY_SIZE(nuri_max8997_buck4_consumer),
+	.consumer_supplies = nuri_max8997_buck4_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_buck5_data = {
+	.constraints	= {
+		.name		= "VMEM_1.2V_C210",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled = 1,
+			.disabled = 0,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_buck6_data = {
+	.constraints	= {
+		.name		= "CAM_AF_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies = ARRAY_SIZE(nuri_max8997_buck6_consumer),
+	.consumer_supplies = nuri_max8997_buck6_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_buck7_data = {
+	.constraints	= {
+		.name		= "VCC_SUB_2.0V",
+		.min_uV		= 2000000,
+		.max_uV		= 2000000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled = 1,
+			.disabled = 0,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_32khz_ap_data = {
+	.constraints	= {
+		.name		= "32KHz AP",
+		.always_on	= 1,
+		.state_mem	= {
+			.enabled = 1,
+			.disabled = 0,
+		},
+	},
+	.num_consumer_supplies = ARRAY_SIZE(nuri_max8997_32khz_ap_consumer),
+	.consumer_supplies = nuri_max8997_32khz_ap_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_32khz_cp_data = {
+	.constraints	= {
+		.name		= "32KHz CP",
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_vichg_data = {
+	.constraints	= {
+		.name		= "VICHG",
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+};
+
+static struct regulator_init_data nuri_max8997_esafeout1_data = {
+	.constraints	= {
+		.name		= "SAFEOUT1",
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_esafeout1_consumer),
+	.consumer_supplies	= nuri_max8997_esafeout1_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_esafeout2_data = {
+	.constraints	= {
+		.name		= "SAFEOUT2",
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+		.state_mem	= {
+			.enabled = 0,
+			.disabled = 1,
+		},
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_esafeout2_consumer),
+	.consumer_supplies	= nuri_max8997_esafeout2_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_charger_cv_data = {
+	.constraints	= {
+		.name		= "CHARGER_CV",
+		.min_uV		= 4200000,
+		.max_uV		= 4200000,
+		.apply_uV	= 1,
+	},
+};
+
+static struct regulator_init_data nuri_max8997_charger_data = {
+	.constraints	= {
+		.name		= "CHARGER",
+		.min_uA		= 200000,
+		.max_uA		= 950000,
+		.boot_on	= 1,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS |
+				REGULATOR_CHANGE_CURRENT,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_charger_consumer),
+	.consumer_supplies	= nuri_max8997_charger_consumer,
+};
+
+static struct regulator_init_data nuri_max8997_charger_topoff_data = {
+	.constraints	= {
+		.name		= "CHARGER TOPOFF",
+		.min_uA		= 50000,
+		.max_uA		= 200000,
+		.valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_chg_toff_consumer),
+	.consumer_supplies	= nuri_max8997_charger_topoff_consumer,
+};
+
+static struct max8997_regulator_data nuri_max8997_regulators[] = {
+	{ MAX8997_LDO1, &nuri_max8997_ldo1_data },
+	{ MAX8997_LDO2, &nuri_max8997_ldo2_data },
+	{ MAX8997_LDO3, &nuri_max8997_ldo3_data },
+	{ MAX8997_LDO4, &nuri_max8997_ldo4_data },
+	{ MAX8997_LDO5, &nuri_max8997_ldo5_data },
+	{ MAX8997_LDO6, &nuri_max8997_ldo6_data },
+	{ MAX8997_LDO7, &nuri_max8997_ldo7_data },
+	{ MAX8997_LDO8, &nuri_max8997_ldo8_data },
+	{ MAX8997_LDO9, &nuri_max8997_ldo9_data },
+	{ MAX8997_LDO10, &nuri_max8997_ldo10_data },
+	{ MAX8997_LDO11, &nuri_max8997_ldo11_data },
+	{ MAX8997_LDO12, &nuri_max8997_ldo12_data },
+	{ MAX8997_LDO13, &nuri_max8997_ldo13_data },
+	{ MAX8997_LDO14, &nuri_max8997_ldo14_data },
+	{ MAX8997_LDO15, &nuri_max8997_ldo15_data },
+	{ MAX8997_LDO16, &nuri_max8997_ldo16_data },
+
+	{ MAX8997_LDO18, &nuri_max8997_ldo18_data },
+	{ MAX8997_LDO21, &nuri_max8997_ldo21_data },
+
+	{ MAX8997_BUCK1, &nuri_max8997_buck1_data },
+	{ MAX8997_BUCK2, &nuri_max8997_buck2_data },
+	{ MAX8997_BUCK3, &nuri_max8997_buck3_data },
+	{ MAX8997_BUCK4, &nuri_max8997_buck4_data },
+	{ MAX8997_BUCK5, &nuri_max8997_buck5_data },
+	{ MAX8997_BUCK6, &nuri_max8997_buck6_data },
+	{ MAX8997_BUCK7, &nuri_max8997_buck7_data },
+
+	{ MAX8997_EN32KHZ_AP, &nuri_max8997_32khz_ap_data },
+	{ MAX8997_EN32KHZ_CP, &nuri_max8997_32khz_cp_data },
+
+	{ MAX8997_ENVICHG, &nuri_max8997_vichg_data },
+	{ MAX8997_ESAFEOUT1, &nuri_max8997_esafeout1_data },
+	{ MAX8997_ESAFEOUT2, &nuri_max8997_esafeout2_data },
+	{ MAX8997_CHARGER_CV, &nuri_max8997_charger_cv_data },
+	{ MAX8997_CHARGER, &nuri_max8997_charger_data },
+	{ MAX8997_CHARGER_TOPOFF, &nuri_max8997_charger_topoff_data },
+};
+
+static struct max8997_platform_data nuri_max8997_pdata = {
+	.irq_base		= 0,
+	.ono			= 0,
+	.wakeup			= 1,
+
+	.num_regulators		= ARRAY_SIZE(nuri_max8997_regulators),
+	.regulators		= nuri_max8997_regulators,
+
+	.buck125_gpios = { EXYNOS4_GPX0(5), EXYNOS4_GPX0(6), EXYNOS4_GPL0(0) },
+	.buck125_default_idx = 0,
+	.buck1_gpiodvs = false,
+	.buck2_gpiodvs = true,
+	.buck5_gpiodvs = false,
+
+	.buck1_voltage[0] = 1350000, /* 1.35V */
+	.buck1_voltage[1] = 1300000, /* 1.3V */
+	.buck1_voltage[2] = 1250000, /* 1.25V */
+	.buck1_voltage[3] = 1200000, /* 1.2V */
+	.buck1_voltage[4] = 1150000, /* 1.15V */
+	.buck1_voltage[5] = 1100000, /* 1.1V */
+	.buck1_voltage[6] = 1000000, /* 1.0V */
+	.buck1_voltage[7] = 950000, /* 0.95V */
+
+	.buck2_voltage[0] = 1100000, /* 1.1V */
+	.buck2_voltage[1] = 1000000, /* 1.0V */
+	.buck2_voltage[2] = 950000, /* 0.95V */
+	.buck2_voltage[3] = 900000, /* 0.9V */
+	.buck2_voltage[4] = 1100000, /* 1.1V */
+	.buck2_voltage[5] = 1000000, /* 1.0V */
+	.buck2_voltage[6] = 950000, /* 0.95V */
+	.buck2_voltage[7] = 900000, /* 0.9V */
+
+	.buck5_voltage[0] = 1200000, /* 1.2V */
+	.buck5_voltage[1] = 1200000, /* 1.2V */
+	.buck5_voltage[2] = 1200000, /* 1.2V */
+	.buck5_voltage[3] = 1200000, /* 1.2V */
+	.buck5_voltage[4] = 1200000, /* 1.2V */
+	.buck5_voltage[5] = 1200000, /* 1.2V */
+	.buck5_voltage[6] = 1200000, /* 1.2V */
+	.buck5_voltage[7] = 1200000, /* 1.2V */
+};
+
+#define NURI_PMIC_GPIO		EXYNOS4_GPX0(7)
+static void __init nuri_pmic_init(void)
+{
+	int gpio;
+
+	nuri_max8997_pdata.irq_base = irq_get_next_irq(IRQ_GPIO_END);
+	gpio = NURI_PMIC_GPIO;
+	gpio_request(gpio, "AP_PMIC_IRQ");
+	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+}
+
 /* GPIO I2C 5 (PMIC) */
+enum { I2C5_MAX8997 };
 static struct i2c_board_info i2c5_devs[] __initdata = {
-	/* max8997, To be updated */
+	[I2C5_MAX8997] = {
+		I2C_BOARD_INFO("max8997", 0xCC >> 1),
+		.platform_data	= &nuri_max8997_pdata,
+	},
 };
 
 /* USB EHCI */
@@ -369,6 +1023,7 @@  static struct platform_device *nuri_devices[] __initdata = {
 	&s3c_device_timer[0],
 	&s5p_device_ehci,
 	&s3c_device_i2c3,
+	&s3c_device_i2c5,
 
 	/* NURI Devices */
 	&nuri_gpio_keys,
@@ -387,10 +1042,13 @@  static void __init nuri_machine_init(void)
 {
 	nuri_sdhci_init();
 	nuri_tsp_init();
+	nuri_pmic_init();
 
 	i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
 	s3c_i2c3_set_platdata(&i2c3_data);
 	i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
+	s3c_i2c5_set_platdata(NULL);
+	i2c5_devs[I2C5_MAX8997].irq = gpio_to_irq(NURI_PMIC_GPIO);
 	i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
 
 	nuri_ehci_init();