Skip to contentSkip to conversation

Samsung Aquila & GONI update

PATCH Superseded Marek Szyprowski 2 participants 8 messages Jul 1, 2010

Subsystems (3)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Samsung Aquila & GONI update

Hello,

This short patch series adds basic framebuffer defintion to Samsung GONI board as well as PMIC8998 support for both Samsung Aquila and GONI boards. MAX8998 PMIC driver has been accepted by regulator subsystem maintainers and is already available in the 'next' kernel tree (see commit 8d017ab9f81089cb5ffde0e354d13130c1c19999).

The series contains the following patches:

[PATCH 1/3] arm: s5pv210: GONI: add support for framebuffer [PATCH 2/3] arm: s5pv210: Aquila: add support for MAX8998 PMIC [PATCH 3/3] arm: s5pv210: GONI: add support for MAX8998 PMIC

Best regards

Signature · 2 lines
Marek Szyprowski
Samsung Poland R&D Center
#1 lore raw

PATCH 1/3 arm: s5pv210: GONI: add support for framebuffer

This patch adds required platform definitions to enable s3c-fb driver on GONI board. One framebuffer window in 480x800x16bpp mode is defined.

---
 arch/arm/mach-s5pv210/Kconfig     |    2 +
 arch/arm/mach-s5pv210/mach-goni.c |   39 +++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 0 deletions(-)
arch/arm/mach-s5pv210/Kconfig +2 -0
index 5e88941..8ab4bb0 100644
@@ -59,6 +59,8 @@ config MACH_GONI
 	bool "GONI"
 	select CPU_S5PV210
 	select ARCH_SPARSEMEM_ENABLE
+	select S5PV210_SETUP_FB_24BPP
+	select S3C_DEV_FB
 	select S5PC110_DEV_ONENAND
 	help
 	  Machine support for Samsung GONI board
arch/arm/mach-s5pv210/mach-goni.c +39 -0
index 88c38e3..05b4a1a 100644
@@ -12,6 +12,9 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -20,11 +23,15 @@
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+#include <mach/gpio.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/regs-serial.h>
 #include <plat/s5pv210.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define S5PV210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -73,7 +80,35 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
 	},
 };
 
+/* Frame Buffer */
+static struct s3c_fb_pd_win goni_fb_win0 = {
+	.win_mode = {
+		.pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55),
+		.left_margin = 16,
+		.right_margin = 16,
+		.upper_margin = 3,
+		.lower_margin = 28,
+		.hsync_len = 2,
+		.vsync_len = 2,
+		.xres = 480,
+		.yres = 800,
+		.refresh = 55,
+	},
+	.max_bpp = 32,
+	.default_bpp = 16,
+};
+
+static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
+	.win[0]	= &goni_fb_win0,
+	.vidcon0		= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
+					VIDCON0_CLKSEL_LCD,
+	.vidcon1		= VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
+				| VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio		= s5pv210_fb_gpio_setup_24bpp,
+};
+
 static struct platform_device *goni_devices[] __initdata = {
+	&s3c_device_fb,
 	&s5pc110_device_onenand,
 };
 
@@ -86,6 +121,10 @@ static void __init goni_map_io(void)
 
 static void __init goni_machine_init(void)
 {
+
+	/* FB */
+	s3c_fb_set_platdata(&goni_lcd_pdata);
+
 	platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
 }
 
Signature · 1 line
1.7.1.569.g6f426
#2 lore raw

PATCH 2/3 arm: s5pv210: Aquila: add support for MAX8998 PMIC

In reply to Marek Szyprowski

This patch adds required platform definitions for MAX8998 PMIC driver. Power regulators for LDO and BUCK outputs has been defined as well as a simple gpio-keys button for power key (to enable wakeup functionality with external interrupt).

---
 arch/arm/mach-s5pv210/mach-aquila.c |  388 +++++++++++++++++++++++++++++++++++
 1 files changed, 388 insertions(+), 0 deletions(-)
arch/arm/mach-s5pv210/mach-aquila.c +388 -0
index 44db0fc..46e0a23 100644
@@ -13,6 +13,11 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/mfd/max8998.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -22,7 +27,9 @@
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-fb.h>
+#include <mach/gpio.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/regs-serial.h>
 #include <plat/s5pv210.h>
 #include <plat/devs.h>
@@ -122,7 +129,383 @@ static struct s3c_fb_platdata aquila_lcd_pdata __initdata = {
 	.setup_gpio	= s5pv210_fb_gpio_setup_24bpp,
 };
 
+/* MAX8998 regulators */
+#if defined(CONFIG_REGULATOR_MAX8998) || \
+				defined(CONFIG_REGULATOR_MAX8998_MODULE)
+
+static struct regulator_consumer_supply aquila_ldo3_consumers[] = {
+	{	.supply	= "VMIPI_1.1V",	},
+};
+
+static struct regulator_consumer_supply aquila_ldo8_consumers[] = {
+	{	.supply	= "VADC_3.3V", },
+};
+
+static struct regulator_consumer_supply aquila_ldo11_consumers[] = {
+	{	.supply	= "CAM_IO_2.8V", },
+};
+
+static struct regulator_consumer_supply aquila_ldo12_consumers[] = {
+	{	.supply	= "CAM_ISP_1.2V", },
+};
+
+static struct regulator_consumer_supply aquila_ldo13_consumers[] = {
+	{	.supply	= "CAM_A_2.8V", },
+};
+
+static struct regulator_consumer_supply aquila_ldo14_consumers[] = {
+	{	.supply	= "CAM_CIF_1.8V", },
+};
+
+static struct regulator_consumer_supply aquila_ldo15_consumers[] = {
+	{	.supply	= "CAM_AF_3.3V", },
+};
+
+static struct regulator_consumer_supply aquila_ldo16_consumers[] = {
+	{	.supply	= "VMIPI_1.8V", },
+};
+
+static struct regulator_consumer_supply aquila_ldo17_consumers[] = {
+	{	.supply	= "CAM_8M_1.8V", },
+};
+
+static struct regulator_init_data aquila_ldo2_data = {
+	.constraints	= {
+		.name		= "VALIVE_1.1V",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.boot_on	= 0,
+		.state_mem	= {
+			.enabled = 1,
+		},
+	},
+};
+
+static struct regulator_init_data aquila_ldo3_data = {
+	.constraints	= {
+		.name		= "VUSB/MIPI_1.1V",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo3_consumers),
+	.consumer_supplies	= aquila_ldo3_consumers,
+};
+
+static struct regulator_init_data aquila_ldo4_data = {
+	.constraints	= {
+		.name		= "VDAC_3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.apply_uV	= 1,
+	},
+};
+
+static struct regulator_init_data aquila_ldo5_data = {
+	.constraints	= {
+		.name		= "VTF_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+	},
+};
+
+static struct regulator_init_data aquila_ldo6_data = {
+	.constraints	= {
+		.name		= "VCC_3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.apply_uV	= 1,
+	},
+};
+
+static struct regulator_init_data aquila_ldo7_data = {
+	.constraints	= {
+		.name		= "VCC_3.0V",
+		.min_uV		= 3000000,
+		.max_uV		= 3000000,
+		.apply_uV	= 1,
+		.boot_on	= 1,
+		.always_on	= 1,
+	},
+};
+
+static struct regulator_init_data aquila_ldo8_data = {
+	.constraints	= {
+		.name		= "VUSB/VADC_3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo8_consumers),
+	.consumer_supplies	= aquila_ldo8_consumers,
+};
+
+static struct regulator_init_data aquila_ldo9_data = {
+	.constraints	= {
+		.name		= "VCC/VCAM_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+};
+
+static struct regulator_init_data aquila_ldo10_data = {
+	.constraints	= {
+		.name		= "VPLL_1.1V",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.boot_on	= 1,
+	},
+};
+
+static struct regulator_init_data aquila_ldo11_data = {
+	.constraints	= {
+		.name		= "CAM_IO_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo11_consumers),
+	.consumer_supplies	= aquila_ldo11_consumers,
+};
+
+static struct regulator_init_data aquila_ldo12_data = {
+	.constraints	= {
+		.name		= "CAM_ISP_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo12_consumers),
+	.consumer_supplies	= aquila_ldo12_consumers,
+};
+
+static struct regulator_init_data aquila_ldo13_data = {
+	.constraints	= {
+		.name		= "CAM_A_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo13_consumers),
+	.consumer_supplies	= aquila_ldo13_consumers,
+};
+
+static struct regulator_init_data aquila_ldo14_data = {
+	.constraints	= {
+		.name		= "CAM_CIF_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo14_consumers),
+	.consumer_supplies	= aquila_ldo14_consumers,
+};
+
+static struct regulator_init_data aquila_ldo15_data = {
+	.constraints	= {
+		.name		= "CAM_AF_3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.apply_uV	= 1,
+		.boot_on	= 0,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo15_consumers),
+	.consumer_supplies	= aquila_ldo15_consumers,
+};
+
+static struct regulator_init_data aquila_ldo16_data = {
+	.constraints	= {
+		.name		= "VMIPI_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo16_consumers),
+	.consumer_supplies	= aquila_ldo16_consumers,
+};
+
+static struct regulator_init_data aquila_ldo17_data = {
+	.constraints	= {
+		.name		= "CAM_8M_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_ldo17_consumers),
+	.consumer_supplies	= aquila_ldo17_consumers,
+};
+
+/* BUCK */
+static struct regulator_consumer_supply buck1_consumer[] = {
+	{	.supply	= "vddarm", },
+};
+
+static struct regulator_consumer_supply aquila_buck4_consumers[] = {
+	{	.supply	= "CAM_CORE_1.2V", },
+};
+
+static struct regulator_init_data aquila_buck1_data = {
+	.constraints	= {
+		.name		= "VARM_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(buck1_consumer),
+	.consumer_supplies	= buck1_consumer,
+};
+
+static struct regulator_consumer_supply buck2_consumer[] = {
+	{	.supply	= "vddint", },
+};
+
+static struct regulator_init_data aquila_buck2_data = {
+	.constraints	= {
+		.name		= "VINT_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(buck2_consumer),
+	.consumer_supplies	= buck2_consumer,
+};
+
+static struct regulator_init_data aquila_buck3_data = {
+	.constraints	= {
+		.name		= "VCC_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled = 1,
+		},
+	},
+};
+
+static struct regulator_init_data aquila_buck4_data = {
+	.constraints	= {
+		.name		= "CAM_CORE_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(aquila_buck4_consumers),
+	.consumer_supplies	= aquila_buck4_consumers,
+};
+
+static struct max8998_regulator_data aquila_regulators[] = {
+	{ MAX8998_LDO2,  &aquila_ldo2_data },
+	{ MAX8998_LDO3,  &aquila_ldo3_data },
+	{ MAX8998_LDO4,  &aquila_ldo4_data },
+	{ MAX8998_LDO5,  &aquila_ldo5_data },
+	{ MAX8998_LDO6,  &aquila_ldo6_data },
+	{ MAX8998_LDO7,  &aquila_ldo7_data },
+	{ MAX8998_LDO8,  &aquila_ldo8_data },
+	{ MAX8998_LDO9,  &aquila_ldo9_data },
+	{ MAX8998_LDO10, &aquila_ldo10_data },
+	{ MAX8998_LDO11, &aquila_ldo11_data },
+	{ MAX8998_LDO12, &aquila_ldo12_data },
+	{ MAX8998_LDO13, &aquila_ldo13_data },
+	{ MAX8998_LDO14, &aquila_ldo14_data },
+	{ MAX8998_LDO15, &aquila_ldo15_data },
+	{ MAX8998_LDO16, &aquila_ldo16_data },
+	{ MAX8998_LDO17, &aquila_ldo17_data },
+	{ MAX8998_BUCK1, &aquila_buck1_data },
+	{ MAX8998_BUCK2, &aquila_buck2_data },
+	{ MAX8998_BUCK3, &aquila_buck3_data },
+	{ MAX8998_BUCK4, &aquila_buck4_data },
+};
+
+static struct max8998_platform_data max8998_platform_data = {
+	.num_regulators		= ARRAY_SIZE(aquila_regulators),
+	.regulators		= aquila_regulators,
+};
+#endif
+
+/* GPIO I2C PMIC */
+#define AP_I2C_GPIO_PMIC_BUS_4	4
+static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = {
+	.sda_pin	= S5PV210_GPJ4(0),	/* XMSMCSN */
+	.scl_pin	= S5PV210_GPJ4(3),	/* XMSMIRQN */
+};
+
+static struct platform_device aquila_i2c_gpio_pmic = {
+	.name		= "i2c-gpio",
+	.id		= AP_I2C_GPIO_PMIC_BUS_4,
+	.dev		= {
+		.platform_data	= &aquila_i2c_gpio_pmic_data,
+	},
+};
+
+static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+	{
+		/* 0xCC when SRAD = 0 */
+		I2C_BOARD_INFO("max8998", 0xCC >> 1),
+		.platform_data		= &max8998_platform_data,
+	},
+#endif
+};
+
+/* PMIC Power button */
+static struct gpio_keys_button aquila_gpio_keys_table[] = {
+	{
+		.code 		= KEY_POWER,
+		.gpio		= S5PV210_GPH2(6),
+		.desc		= "gpio-keys: KEY_POWER",
+		.type		= EV_KEY,
+		.active_low	= 1,
+		.wakeup		= 1,
+		.debounce_interval = 1,
+	},
+};
+
+static struct gpio_keys_platform_data aquila_gpio_keys_data = {
+	.buttons        = aquila_gpio_keys_table,
+	.nbuttons       = ARRAY_SIZE(aquila_gpio_keys_table),
+};
+
+static struct platform_device aquila_device_gpiokeys = {
+	.name      = "gpio-keys",
+	.dev = {
+		.platform_data = &aquila_gpio_keys_data,
+	},
+};
+
+static void __init aquila_pmic_init(void)
+{
+	/* AP_PMIC_IRQ: EINT7 */
+	s3c_gpio_cfgpin(S5PV210_GPH0(7), S3C_GPIO_SFN(0xf));
+	s3c_gpio_setpull(S5PV210_GPH0(7), S3C_GPIO_PULL_UP);
+
+	/* nPower: EINT22 */
+	s3c_gpio_cfgpin(S5PV210_GPH2(6), S3C_GPIO_SFN(0xf));
+	s3c_gpio_setpull(S5PV210_GPH2(6), S3C_GPIO_PULL_UP);
+}
+
 static struct platform_device *aquila_devices[] __initdata = {
+	&aquila_i2c_gpio_pmic,
+	&aquila_device_gpiokeys,
 	&s3c_device_fb,
 	&s5pc110_device_onenand,
 };
@@ -136,6 +519,11 @@ static void __init aquila_map_io(void)
 
 static void __init aquila_machine_init(void)
 {
+	/* PMIC */
+	aquila_pmic_init();
+	i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
+			ARRAY_SIZE(i2c_gpio_pmic_devs));
+
 	/* FB */
 	s3c_fb_set_platdata(&aquila_lcd_pdata);
 
Signature · 1 line
1.7.1.569.g6f426
#3 lore raw

PATCH 2/3 arm: s5pv210: Aquila: add support for MAX8998 PMIC

arch/arm/mach-s5pv210/mach-aquila.c static struct s3c_fb_platdata aquila_lcd_pdata __initdata = { · line 142

Quoted 7 lines · Marek Szyprowski
arch/arm/mach-s5pv210/mach-aquila.c +6 -0
+static struct regulator_consumer_supply aquila_ldo3_consumers[] = {
+	{	.supply	= "VMIPI_1.1V",	},
+};
 
+static struct regulator_consumer_supply aquila_ldo8_consumers[] = {
+	{	.supply	= "VADC_3.3V", },
+};

Almost all of these regulator supplies should be removed. Except in some exceptional cases all supplies should specify a struct device (the only one that really exists at the minute is CPU core due to lack of devices for CPUfreq). In general if you're defining a supply name that is the same as the rail on the board rather than a pin on a chip you're not using the API correctly.

If you want to label the supply for userspace do so in the constraints.

arch/arm/mach-s5pv210/mach-aquila.c static struct s3c_fb_platdata aquila_lcd_pdata __initdata = { · line 179

Quoted 7 lines
arch/arm/mach-s5pv210/mach-aquila.c +7 -0
+	.constraints	= {
+		.name		= "VALIVE_1.1V",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.boot_on	= 0,

No need to explicitly set stuff to zero.

#4 lore raw

PATCH 2/3 arm: s5pv210: Aquila: add support for MAX8998 PMIC

Hello,

Quoted 6 lines · Mark Brown
Quoted 3 lines · Marek Szyprowski
arch/arm/mach-s5pv210/mach-aquila.c +3 -0
+static struct regulator_consumer_supply aquila_ldo3_consumers[] = {
+	{	.supply	= "VMIPI_1.1V",	},
+};
Quoted 10 lines

arch/arm/mach-s5pv210/mach-aquila.c static struct s3c_fb_platdata aquila_lcd_pdata __initdata = { · line 142

Quoted 3 lines
arch/arm/mach-s5pv210/mach-aquila.c +3 -0
+static struct regulator_consumer_supply aquila_ldo8_consumers[] = {
+	{	.supply	= "VADC_3.3V", },
+};

Almost all of these regulator supplies should be removed. Except in some exceptional cases all supplies should specify a struct device (the only one that really exists at the minute is CPU core due to lack of devices for CPUfreq). In general if you're defining a supply name that is the same as the rail on the board rather than a pin on a chip you're not using the API correctly.

Ok. I will remove them now and add later with the appropriate devices.

One more question - should I enable the regulators in the driver itself or in the platform callback (like a "poweron()" callback)?

If I put regulator enabling into the driver how can one make it working on a board without regulators (chip powered all the time)? Should the driver ignore errors from regulator_get()?

What if one regulator needs enabling other to operate properly (parent-child hierarchy)?

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

#5 lore raw

PATCH 2/3 arm: s5pv210: Aquila: add support for MAX8998 PMIC

Quoted 2 lines · Marek Szyprowski

One more question - should I enable the regulators in the driver itself or in the platform callback (like a "poweron()" callback)?

I don't understand what you mean by "platform callback". Normally the driver would unconditionally use the regulators.

Quoted 3 lines

If I put regulator enabling into the driver how can one make it working on a board without regulators (chip powered all the time)? Should the driver ignore errors from regulator_get()?

No, check the errors. The regulator API will stub itself out if it's not enabled in Kconfig (which will happen on boards where it's not being used at all), boards using a mixed configuration can use fixed voltage regulators for static supplies and REGULATOR_DUMMY can also be used.

Quoted 2 lines

What if one regulator needs enabling other to operate properly (parent-child hierarchy)?

Set up supplies for the child regulators in their constraints. This isn't heavily tested at the minute but it should do the right thing for you automatically in the core; if it doesn't work we can fix it up.

#6 lore raw

PATCH 3/3 arm: s5pv210: GONI: add support for MAX8998 PMIC

In reply to Marek Szyprowski

This patch adds required platform definitions for MAX8998 PMIC driver. Power regulators for LDO and BUCK outputs has been defined as well as a simple gpio-keys button for power key (to enable wakeup functionality with external interrupt).

---
 arch/arm/mach-s5pv210/mach-goni.c |  391 +++++++++++++++++++++++++++++++++++++
 1 files changed, 391 insertions(+), 0 deletions(-)
arch/arm/mach-s5pv210/mach-goni.c +391 -0
index 05b4a1a..683d2b9 100644
@@ -13,8 +13,13 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/mfd/max8998.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -107,9 +112,391 @@ static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
 	.setup_gpio		= s5pv210_fb_gpio_setup_24bpp,
 };
 
+/* MAX8998 regulators */
+#if defined(CONFIG_REGULATOR_MAX8998) || \
+				defined(CONFIG_REGULATOR_MAX8998_MODULE)
+
+static struct regulator_consumer_supply goni_ldo3_consumers[] = {
+	{	.supply	= "VMIPI_1.1V",	},
+};
+
+static struct regulator_consumer_supply sdk_ldo7_consumers[] = {
+	{	.supply	= "VLCD_1.8V", },
+};
+
+static struct regulator_consumer_supply goni_ldo8_consumers[] = {
+	{	.supply	= "VADC_3.3V", },
+};
+
+static struct regulator_consumer_supply goni_ldo11_consumers[] = {
+	{	.supply	= "CAM_IO_2.8V", },
+};
+
+static struct regulator_consumer_supply goni_ldo12_consumers[] = {
+	{	.supply	= "CAM_ISP_1.2V", },
+};
+
+static struct regulator_consumer_supply goni_ldo13_consumers[] = {
+	{	.supply	= "CAM_A_2.8V", },
+};
+
+static struct regulator_consumer_supply goni_ldo14_consumers[] = {
+	{	.supply	= "CAM_CIF_1.8V", },
+};
+
+static struct regulator_consumer_supply goni_ldo15_consumers[] = {
+	{	.supply	= "CAM_AF_3.3V", },
+};
+
+static struct regulator_consumer_supply goni_ldo16_consumers[] = {
+	{	.supply	= "VMIPI_1.8V", },
+};
+
+static struct regulator_consumer_supply goni_ldo17_consumers[] = {
+	{	.supply	= "VCC_3.0V_LCD", },
+};
+
+static struct regulator_init_data goni_ldo2_data = {
+	.constraints	= {
+		.name		= "VALIVE_1.1V",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+		.boot_on	= 0,
+		.state_mem	= {
+			.enabled = 1,
+		},
+	},
+};
+
+static struct regulator_init_data goni_ldo3_data = {
+	.constraints	= {
+		.name		= "VUSB/MIPI_1.1V",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo3_consumers),
+	.consumer_supplies	= goni_ldo3_consumers,
+};
+
+static struct regulator_init_data goni_ldo4_data = {
+	.constraints	= {
+		.name		= "VDAC_3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.apply_uV	= 1,
+	},
+};
+
+static struct regulator_init_data goni_ldo5_data = {
+	.constraints	= {
+		.name		= "VTF_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+	},
+};
+
+static struct regulator_init_data goni_ldo6_data = {
+	.constraints	= {
+		.name		= "VCC_3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.apply_uV	= 1,
+	},
+};
+
+static struct regulator_init_data goni_ldo7_data = {
+	.constraints	= {
+		.name		= "VLCD_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(sdk_ldo7_consumers),
+	.consumer_supplies	= sdk_ldo7_consumers,
+};
+
+static struct regulator_init_data goni_ldo8_data = {
+	.constraints	= {
+		.name		= "VUSB/VADC_3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo8_consumers),
+	.consumer_supplies	= goni_ldo8_consumers,
+};
+
+static struct regulator_init_data goni_ldo9_data = {
+	.constraints	= {
+		.name		= "VCC/VCAM_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+};
+
+static struct regulator_init_data goni_ldo10_data = {
+	.constraints	= {
+		.name		= "VPLL_1.1V",
+		.min_uV		= 1100000,
+		.max_uV		= 1100000,
+		.apply_uV	= 1,
+		.boot_on	= 1,
+	},
+};
+
+static struct regulator_init_data goni_ldo11_data = {
+	.constraints	= {
+		.name		= "CAM_IO_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo11_consumers),
+	.consumer_supplies	= goni_ldo11_consumers,
+};
+
+static struct regulator_init_data goni_ldo12_data = {
+	.constraints	= {
+		.name		= "CAM_ISP_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo12_consumers),
+	.consumer_supplies	= goni_ldo12_consumers,
+};
+
+static struct regulator_init_data goni_ldo13_data = {
+	.constraints	= {
+		.name		= "CAM_A_2.8V",
+		.min_uV		= 2800000,
+		.max_uV		= 2800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo13_consumers),
+	.consumer_supplies	= goni_ldo13_consumers,
+};
+
+static struct regulator_init_data goni_ldo14_data = {
+	.constraints	= {
+		.name		= "CAM_CIF_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo14_consumers),
+	.consumer_supplies	= goni_ldo14_consumers,
+};
+
+static struct regulator_init_data goni_ldo15_data = {
+	.constraints	= {
+		.name		= "CAM_AF_3.3V",
+		.min_uV		= 3300000,
+		.max_uV		= 3300000,
+		.apply_uV	= 1,
+		.boot_on	= 0,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo15_consumers),
+	.consumer_supplies	= goni_ldo15_consumers,
+};
+
+static struct regulator_init_data goni_ldo16_data = {
+	.constraints	= {
+		.name		= "VMIPI_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo16_consumers),
+	.consumer_supplies	= goni_ldo16_consumers,
+};
+
+static struct regulator_init_data goni_ldo17_data = {
+	.constraints	= {
+		.name		= "VCC_3.0V_LCD",
+		.min_uV		= 3000000,
+		.max_uV		= 3000000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_ldo17_consumers),
+	.consumer_supplies	= goni_ldo17_consumers,
+};
+
+/* BUCK */
+static struct regulator_consumer_supply buck1_consumer[] = {
+	{	.supply	= "vddarm", },
+};
+
+static struct regulator_consumer_supply goni_buck4_consumers[] = {
+	{	.supply	= "CAM_CORE_1.2V", },
+};
+
+static struct regulator_init_data goni_buck1_data = {
+	.constraints	= {
+		.name		= "VARM_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(buck1_consumer),
+	.consumer_supplies	= buck1_consumer,
+};
+
+static struct regulator_consumer_supply buck2_consumer[] = {
+	{	.supply	= "vddint", },
+};
+
+static struct regulator_init_data goni_buck2_data = {
+	.constraints	= {
+		.name		= "VINT_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(buck2_consumer),
+	.consumer_supplies	= buck2_consumer,
+};
+
+static struct regulator_init_data goni_buck3_data = {
+	.constraints	= {
+		.name		= "VCC_1.8V",
+		.min_uV		= 1800000,
+		.max_uV		= 1800000,
+		.apply_uV	= 1,
+		.state_mem	= {
+			.enabled = 1,
+		},
+	},
+};
+
+static struct regulator_init_data goni_buck4_data = {
+	.constraints	= {
+		.name		= "CAM_CORE_1.2V",
+		.min_uV		= 1200000,
+		.max_uV		= 1200000,
+		.apply_uV	= 1,
+		.always_on	= 1,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(goni_buck4_consumers),
+	.consumer_supplies	= goni_buck4_consumers,
+};
+
+static struct max8998_regulator_data goni_regulators[] = {
+	{ MAX8998_LDO2,  &goni_ldo2_data },
+	{ MAX8998_LDO3,  &goni_ldo3_data },
+	{ MAX8998_LDO4,  &goni_ldo4_data },
+	{ MAX8998_LDO5,  &goni_ldo5_data },
+	{ MAX8998_LDO6,  &goni_ldo6_data },
+	{ MAX8998_LDO7,  &goni_ldo7_data },
+	{ MAX8998_LDO8,  &goni_ldo8_data },
+	{ MAX8998_LDO9,  &goni_ldo9_data },
+	{ MAX8998_LDO10, &goni_ldo10_data },
+	{ MAX8998_LDO11, &goni_ldo11_data },
+	{ MAX8998_LDO12, &goni_ldo12_data },
+	{ MAX8998_LDO13, &goni_ldo13_data },
+	{ MAX8998_LDO14, &goni_ldo14_data },
+	{ MAX8998_LDO15, &goni_ldo15_data },
+	{ MAX8998_LDO16, &goni_ldo16_data },
+	{ MAX8998_LDO17, &goni_ldo17_data },
+	{ MAX8998_BUCK1, &goni_buck1_data },
+	{ MAX8998_BUCK2, &goni_buck2_data },
+	{ MAX8998_BUCK3, &goni_buck3_data },
+	{ MAX8998_BUCK4, &goni_buck4_data },
+};
+
+static struct max8998_platform_data max8998_platform_data = {
+	.num_regulators		= ARRAY_SIZE(goni_regulators),
+	.regulators		= goni_regulators,
+};
+#endif
+
+/* GPIO I2C PMIC */
+#define AP_I2C_GPIO_PMIC_BUS_4	4
+static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = {
+	.sda_pin	= S5PV210_GPJ4(0),	/* XMSMCSN */
+	.scl_pin	= S5PV210_GPJ4(3),	/* XMSMIRQN */
+};
+
+static struct platform_device goni_i2c_gpio_pmic = {
+	.name		= "i2c-gpio",
+	.id		= AP_I2C_GPIO_PMIC_BUS_4,
+	.dev		= {
+		.platform_data	= &goni_i2c_gpio_pmic_data,
+	},
+};
+
+static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+	{
+		/* 0xCC when SRAD = 0 */
+		I2C_BOARD_INFO("max8998", 0xCC >> 1),
+		.platform_data		= &max8998_platform_data,
+	},
+#endif
+};
+
+/* PMIC Power button */
+static struct gpio_keys_button goni_gpio_keys_table[] = {
+	{
+		.code 		= KEY_POWER,
+		.gpio		= S5PV210_GPH2(6),
+		.desc		= "gpio-keys: KEY_POWER",
+		.type		= EV_KEY,
+		.active_low	= 1,
+		.wakeup		= 1,
+		.debounce_interval = 1,
+	},
+};
+
+static struct gpio_keys_platform_data goni_gpio_keys_data = {
+	.buttons        = goni_gpio_keys_table,
+	.nbuttons       = ARRAY_SIZE(goni_gpio_keys_table),
+};
+
+static struct platform_device goni_device_gpiokeys = {
+	.name      = "gpio-keys",
+	.dev = {
+		.platform_data = &goni_gpio_keys_data,
+	},
+};
+
+static void __init goni_pmic_init(void)
+{
+	/* AP_PMIC_IRQ: EINT7 */
+	s3c_gpio_cfgpin(S5PV210_GPH0(7), S3C_GPIO_SFN(0xf));
+	s3c_gpio_setpull(S5PV210_GPH0(7), S3C_GPIO_PULL_UP);
+
+	/* nPower: EINT22 */
+	s3c_gpio_cfgpin(S5PV210_GPH2(6), S3C_GPIO_SFN(0xf));
+	s3c_gpio_setpull(S5PV210_GPH2(6), S3C_GPIO_PULL_UP);
+}
+
+
 static struct platform_device *goni_devices[] __initdata = {
 	&s3c_device_fb,
 	&s5pc110_device_onenand,
+	&goni_i2c_gpio_pmic,
+	&goni_device_gpiokeys,
 };
 
 static void __init goni_map_io(void)
@@ -121,6 +508,10 @@ static void __init goni_map_io(void)
 
 static void __init goni_machine_init(void)
 {
+	/* PMIC */
+	goni_pmic_init();
+	i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
+			ARRAY_SIZE(i2c_gpio_pmic_devs));
 
 	/* FB */
 	s3c_fb_set_platdata(&goni_lcd_pdata);
Signature · 1 line
1.7.1.569.g6f426
#7 lore raw

PATCH 3/3 arm: s5pv210: GONI: add support for MAX8998 PMIC

arch/arm/mach-s5pv210/mach-goni.c static struct s3c_fb_platdata goni_lcd_pdata __initdata = { · line 121

Quoted 3 lines · Marek Szyprowski
arch/arm/mach-s5pv210/mach-goni.c +3 -0
+static struct regulator_consumer_supply goni_ldo3_consumers[] = {
+	{	.supply	= "VMIPI_1.1V",	},
+};

A similar issue to the previous patch applies here - you should be defining consumers using struct device based lookups only.