help
          Common setup code for SPI GPIO configurations.
 
+config S5PV210_SETUP_USB_PHY
+       bool
+       help
+         Common setup code for USB PHY controller
+
 menu "S5PC110 Machines"
 
 config MACH_AQUILA
        select S5PV210_SETUP_KEYPAD
        select S5PV210_SETUP_SDHCI
        select S5PV210_SETUP_FIMC
+       select S5PV210_SETUP_USB_PHY
        help
          Machine support for Samsung GONI board
          S5PC110(MCP) is one of package option of S5PV210
 
--- /dev/null
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+#include <mach/regs-sys.h>
+#include <plat/cpu.h>
+#include <plat/regs-usb-hsotg-phy.h>
+#include <plat/usb-phy.h>
+
+static int s5pv210_usb_otgphy_init(struct platform_device *pdev)
+{
+       struct clk *xusbxti;
+       u32 phyclk;
+
+       writel(readl(S5PV210_USB_PHY_CON) | S5PV210_USB_PHY0_EN,
+                       S5PV210_USB_PHY_CON);
+
+       /* set clock frequency for PLL */
+       phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
+
+       xusbxti = clk_get(&pdev->dev, "xusbxti");
+       if (xusbxti && !IS_ERR(xusbxti)) {
+               switch (clk_get_rate(xusbxti)) {
+               case 12 * MHZ:
+                       phyclk |= S3C_PHYCLK_CLKSEL_12M;
+                       break;
+               case 24 * MHZ:
+                       phyclk |= S3C_PHYCLK_CLKSEL_24M;
+                       break;
+               default:
+               case 48 * MHZ:
+                       /* default reference clock */
+                       break;
+               }
+               clk_put(xusbxti);
+       }
+
+       /* TODO: select external clock/oscillator */
+       writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
+
+       /* set to normal OTG PHY */
+       writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
+       mdelay(1);
+
+       /* reset OTG PHY and Link */
+       writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
+                       S3C_RSTCON);
+       udelay(20);     /* at-least 10uS */
+       writel(0, S3C_RSTCON);
+
+       return 0;
+}
+
+static int s5pv210_usb_otgphy_exit(struct platform_device *pdev)
+{
+       writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
+                               S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
+
+       writel(readl(S5PV210_USB_PHY_CON) & ~S5PV210_USB_PHY0_EN,
+                       S5PV210_USB_PHY_CON);
+
+       return 0;
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_DEVICE)
+               return s5pv210_usb_otgphy_init(pdev);
+
+       return -EINVAL;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_DEVICE)
+               return s5pv210_usb_otgphy_exit(pdev);
+
+       return -EINVAL;
+}