#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
 #include <linux/pwm_backlight.h>
 #include <linux/dm9000.h>
 #include <linux/gpio_keys.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
 #include <linux/mfd/wm831x/gpio.h>
 
 #include <asm/mach/arch.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-modem.h>
 
-#include <mach/gpio-bank-o.h>
 #include <mach/regs-gpio-memport.h>
 
 #include <plat/regs-serial.h>
 #include <plat/iic.h>
 #include <plat/pm.h>
 
-#define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START
+#include <sound/wm8915.h>
+#include <sound/wm8962.h>
+#include <sound/wm9081.h>
 
-#define PCA935X_GPIO_BASE GPIO_BOARD_START
-#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8)
+#define BANFF_PMIC_IRQ_BASE            IRQ_BOARD_START
+#define GLENFARCLAS_PMIC_IRQ_BASE      (IRQ_BOARD_START + 64)
+
+#define PCA935X_GPIO_BASE              GPIO_BOARD_START
+#define CODEC_GPIO_BASE                (GPIO_BOARD_START + 8)
+#define GLENFARCLAS_PMIC_GPIO_BASE     (GPIO_BOARD_START + 16)
 
 /* serial port setup */
 
 
 static struct s3c2410_uartcfg crag6410_uartcfgs[] __initdata = {
        [0] = {
-               .hwport = 0,
-               .flags  = 0,
-               .ucon   = UCON,
-               .ulcon  = ULCON,
-               .ufcon  = UFCON,
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
        },
        [1] = {
-               .hwport = 1,
-               .flags  = 0,
-               .ucon   = UCON,
-               .ulcon  = ULCON,
-               .ufcon  = UFCON,
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
        },
        [2] = {
-               .hwport = 2,
-               .flags  = 0,
-               .ucon   = UCON,
-               .ulcon  = ULCON,
-               .ufcon  = UFCON,
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
        },
        [3] = {
-               .hwport = 3,
-               .flags  = 0,
-               .ucon   = UCON,
-               .ulcon  = ULCON,
-               .ufcon  = UFCON,
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
        },
 };
 
        [0] = {
                .code   = KEY_SUSPEND,
                .gpio   = S3C64XX_GPL(10),      /* EINT 18 */
-               .type   = EV_SW,
+               .type   = EV_KEY,
                .wakeup = 1,
                .active_low = 1,
        },
+       [1] = {
+               .code   = SW_FRONT_PROXIMITY,
+               .gpio   = S3C64XX_GPN(11),      /* EINT 11 */
+               .type   = EV_SW,
+       },
 };
 
 static struct gpio_keys_platform_data crag6410_gpio_keydata = {
        },
 };
 
+static struct platform_device speyside_device = {
+       .name           = "speyside",
+       .id             = -1,
+};
+
+static struct platform_device speyside_wm8962_device = {
+       .name           = "speyside-wm8962",
+       .id             = -1,
+};
+
+static struct regulator_consumer_supply wallvdd_consumers[] = {
+       REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+       REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_init_data wallvdd_data = {
+       .constraints = {
+               .always_on = 1,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(wallvdd_consumers),
+       .consumer_supplies = wallvdd_consumers,
+};
+
+static struct fixed_voltage_config wallvdd_pdata = {
+       .supply_name = "WALLVDD",
+       .microvolts = 5000000,
+       .init_data = &wallvdd_data,
+       .gpio = -EINVAL,
+};
+
+static struct platform_device wallvdd_device = {
+       .name           = "reg-fixed-voltage",
+       .id             = -1,
+       .dev = {
+               .platform_data = &wallvdd_pdata,
+       },
+};
+
 static struct platform_device *crag6410_devices[] __initdata = {
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc1,
        &crag6410_mmgpio,
        &crag6410_lcd_powerdev,
        &crag6410_backlight_device,
+       &speyside_device,
+       &speyside_wm8962_device,
+       &wallvdd_device,
 };
 
 static struct pca953x_platform_data crag6410_pca_data = {
 
 static struct wm831x_touch_pdata touch_pdata __initdata = {
        .data_irq = S3C_EINT(26),
+       .pd_irq = S3C_EINT(27),
 };
 
-static __init int crag_pmic_pre_init(struct wm831x *wm831x)
-{
-       /* Touchscreen data IRQ - CMOS, DBVDD, active high*/
-       wm831x_reg_write(wm831x, WM831X_GPIO11_CONTROL,
-                        WM831X_GPN_POL | WM831X_GPN_ENA | 0x6);
-
-       /* Touchscreen pen down IRQ - CMOS, DBVDD, active high*/
-       wm831x_reg_write(wm831x, WM831X_GPIO12_CONTROL,
-                        WM831X_GPN_POL | WM831X_GPN_ENA | 0x7);
-
-       return 0;
-}
-
 static struct wm831x_pdata crag_pmic_pdata __initdata = {
-       .pre_init = crag_pmic_pre_init,
-
+       .wm831x_num = 1,
        .irq_base = BANFF_PMIC_IRQ_BASE,
        .gpio_base = GPIO_BOARD_START + 8,
 
+       .gpio_defaults = {
+               /* GPIO11: Touchscreen data - CMOS, DBVDD, active high*/
+               [10] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x6,
+               /* GPIO12: Touchscreen pen down - CMOS, DBVDD, active high*/
+               [11] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x7,
+       },
+
        .dcdc = {
                &vddarm,  /* DCDC1 */
                &vddint,  /* DCDC2 */
        .frequency = 400000,
 };
 
+static struct regulator_init_data pvdd_1v2 __initdata = {
+       .constraints = {
+               .name = "PVDD_1V2",
+               .always_on = 1,
+       },
+};
+
+static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = {
+       REGULATOR_SUPPLY("PLLVDD", "1-001a"),
+       REGULATOR_SUPPLY("DBVDD", "1-001a"),
+       REGULATOR_SUPPLY("CPVDD", "1-001a"),
+       REGULATOR_SUPPLY("AVDD2", "1-001a"),
+       REGULATOR_SUPPLY("DCVDD", "1-001a"),
+       REGULATOR_SUPPLY("AVDD", "1-001a"),
+};
+
+static struct regulator_init_data pvdd_1v8 __initdata = {
+       .constraints = {
+               .name = "PVDD_1V8",
+               .always_on = 1,
+       },
+
+       .consumer_supplies = pvdd_1v8_consumers,
+       .num_consumer_supplies = ARRAY_SIZE(pvdd_1v8_consumers),
+};
+
+static struct regulator_consumer_supply pvdd_3v3_consumers[] __initdata = {
+       REGULATOR_SUPPLY("MICVDD", "1-001a"),
+       REGULATOR_SUPPLY("AVDD1", "1-001a"),
+};
+
+static struct regulator_init_data pvdd_3v3 __initdata = {
+       .constraints = {
+               .name = "PVDD_3V3",
+               .always_on = 1,
+       },
+
+       .consumer_supplies = pvdd_3v3_consumers,
+       .num_consumer_supplies = ARRAY_SIZE(pvdd_3v3_consumers),
+};
+
+static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = {
+       .wm831x_num = 2,
+       .irq_base = GLENFARCLAS_PMIC_IRQ_BASE,
+       .gpio_base = GLENFARCLAS_PMIC_GPIO_BASE,
+
+       .gpio_defaults = {
+               /* GPIO1-3: IRQ inputs, rising edge triggered, CMOS */
+               [0] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+               [1] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+               [2] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+       },
+
+       .dcdc = {
+               &pvdd_1v2,  /* DCDC1 */
+               &pvdd_1v8,  /* DCDC2 */
+               &pvdd_3v3,  /* DCDC3 */
+       },
+
+       .disable_touch = true,
+};
+
+static struct wm8915_retune_mobile_config wm8915_retune[] = {
+       {
+               .name = "Sub LPF",
+               .rate = 48000,
+               .regs = {
+                       0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+               },
+       },
+       {
+               .name = "Sub HPF",
+               .rate = 48000,
+               .regs = {
+                       0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+               },
+       },
+};
+
+static struct wm8915_pdata wm8915_pdata __initdata = {
+       .ldo_ena = S3C64XX_GPN(7),
+       .gpio_base = CODEC_GPIO_BASE,
+       .micdet_def = 1,
+       .inl_mode = WM8915_DIFFERRENTIAL_1,
+       .inr_mode = WM8915_DIFFERRENTIAL_1,
+
+       .irq_flags = IRQF_TRIGGER_FALLING,
+
+       .gpio_default = {
+               0x8001, /* GPIO1 == ADCLRCLK1 */
+               0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
+               0x0141, /* GPIO3 == HP_SEL */
+               0x0002, /* GPIO4 == IRQ */
+               0x020e, /* GPIO5 == CLKOUT */
+       },
+
+       .retune_mobile_cfgs = wm8915_retune,
+       .num_retune_mobile_cfgs = ARRAY_SIZE(wm8915_retune),
+};
+
+static struct wm8962_pdata wm8962_pdata __initdata = {
+       .gpio_init = {
+               0,
+               WM8962_GPIO_FN_OPCLK,
+               WM8962_GPIO_FN_DMICCLK,
+               0,
+               0x8000 | WM8962_GPIO_FN_DMICDAT,
+               WM8962_GPIO_FN_IRQ,    /* Open drain mode */
+       },
+       .irq_active_low = true,
+};
+
+static struct wm9081_pdata wm9081_pdata __initdata = {
+       .irq_high = false,
+       .irq_cmos = false,
+};
+
 static struct i2c_board_info i2c_devs1[] __initdata = {
        { I2C_BOARD_INFO("wm8311", 0x34),
-         .platform_data = &glenfarclas_pmic_pdata,
+         .irq = S3C_EINT(0),
+         .platform_data = &glenfarclas_pmic_pdata },
+
+       { I2C_BOARD_INFO("wm1250-ev1", 0x27) },
+       { I2C_BOARD_INFO("wm8915", 0x1a),
+         .platform_data = &wm8915_pdata,
+         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+       },
+       { I2C_BOARD_INFO("wm9081", 0x6c),
+         .platform_data = &wm9081_pdata, },
+       { I2C_BOARD_INFO("wm8962", 0x1a),
+         .platform_data = &wm8962_pdata,
+         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
        },
 };
 
 
        platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
 
+       regulator_has_full_constraints();
+
        s3c_pm_init();
 }