linux/arch/arm/mach-s3c64xx/setup-usb-phy.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
   3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
   4 *
   5 *  This program is free software; you can redistribute  it and/or modify it
   6 *  under  the terms of  the GNU General  Public License as published by the
   7 *  Free Software Foundation;  either version 2 of the  License, or (at your
   8 *  option) any later version.
   9 *
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/delay.h>
  14#include <linux/err.h>
  15#include <linux/io.h>
  16#include <linux/platform_device.h>
  17#include <mach/map.h>
  18#include <plat/cpu.h>
  19#include <plat/usb-phy.h>
  20
  21#include "regs-sys.h"
  22#include "regs-usb-hsotg-phy.h"
  23
  24static int s3c_usb_otgphy_init(struct platform_device *pdev)
  25{
  26        struct clk *xusbxti;
  27        u32 phyclk;
  28
  29        writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
  30
  31        /* set clock frequency for PLL */
  32        phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
  33
  34        xusbxti = clk_get(&pdev->dev, "xusbxti");
  35        if (xusbxti && !IS_ERR(xusbxti)) {
  36                switch (clk_get_rate(xusbxti)) {
  37                case 12 * MHZ:
  38                        phyclk |= S3C_PHYCLK_CLKSEL_12M;
  39                        break;
  40                case 24 * MHZ:
  41                        phyclk |= S3C_PHYCLK_CLKSEL_24M;
  42                        break;
  43                default:
  44                case 48 * MHZ:
  45                        /* default reference clock */
  46                        break;
  47                }
  48                clk_put(xusbxti);
  49        }
  50
  51        /* TODO: select external clock/oscillator */
  52        writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
  53
  54        /* set to normal OTG PHY */
  55        writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
  56        mdelay(1);
  57
  58        /* reset OTG PHY and Link */
  59        writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
  60                        S3C_RSTCON);
  61        udelay(20);     /* at-least 10uS */
  62        writel(0, S3C_RSTCON);
  63
  64        return 0;
  65}
  66
  67static int s3c_usb_otgphy_exit(struct platform_device *pdev)
  68{
  69        writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
  70                                S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
  71
  72        writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
  73
  74        return 0;
  75}
  76
  77int s5p_usb_phy_init(struct platform_device *pdev, int type)
  78{
  79        if (type == USB_PHY_TYPE_DEVICE)
  80                return s3c_usb_otgphy_init(pdev);
  81
  82        return -EINVAL;
  83}
  84
  85int s5p_usb_phy_exit(struct platform_device *pdev, int type)
  86{
  87        if (type == USB_PHY_TYPE_DEVICE)
  88                return s3c_usb_otgphy_exit(pdev);
  89
  90        return -EINVAL;
  91}
  92