linux/drivers/usb/phy/phy-ulpi-viewport.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Google, Inc.
   3 *
   4 * This software is licensed under the terms of the GNU General Public
   5 * License version 2, as published by the Free Software Foundation, and
   6 * may be copied, distributed, and modified under those terms.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 */
  14
  15#include <linux/export.h>
  16#include <linux/kernel.h>
  17#include <linux/usb.h>
  18#include <linux/io.h>
  19#include <linux/usb/otg.h>
  20#include <linux/usb/ulpi.h>
  21
  22#define ULPI_VIEW_WAKEUP        (1 << 31)
  23#define ULPI_VIEW_RUN           (1 << 30)
  24#define ULPI_VIEW_WRITE         (1 << 29)
  25#define ULPI_VIEW_READ          (0 << 29)
  26#define ULPI_VIEW_ADDR(x)       (((x) & 0xff) << 16)
  27#define ULPI_VIEW_DATA_READ(x)  (((x) >> 8) & 0xff)
  28#define ULPI_VIEW_DATA_WRITE(x) ((x) & 0xff)
  29
  30static int ulpi_viewport_wait(void __iomem *view, u32 mask)
  31{
  32        unsigned long usec = 2000;
  33
  34        while (usec--) {
  35                if (!(readl(view) & mask))
  36                        return 0;
  37
  38                udelay(1);
  39        }
  40
  41        return -ETIMEDOUT;
  42}
  43
  44static int ulpi_viewport_read(struct usb_phy *otg, u32 reg)
  45{
  46        int ret;
  47        void __iomem *view = otg->io_priv;
  48
  49        writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view);
  50        ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP);
  51        if (ret)
  52                return ret;
  53
  54        writel(ULPI_VIEW_RUN | ULPI_VIEW_READ | ULPI_VIEW_ADDR(reg), view);
  55        ret = ulpi_viewport_wait(view, ULPI_VIEW_RUN);
  56        if (ret)
  57                return ret;
  58
  59        return ULPI_VIEW_DATA_READ(readl(view));
  60}
  61
  62static int ulpi_viewport_write(struct usb_phy *otg, u32 val, u32 reg)
  63{
  64        int ret;
  65        void __iomem *view = otg->io_priv;
  66
  67        writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view);
  68        ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP);
  69        if (ret)
  70                return ret;
  71
  72        writel(ULPI_VIEW_RUN | ULPI_VIEW_WRITE | ULPI_VIEW_DATA_WRITE(val) |
  73                                                 ULPI_VIEW_ADDR(reg), view);
  74
  75        return ulpi_viewport_wait(view, ULPI_VIEW_RUN);
  76}
  77
  78struct usb_phy_io_ops ulpi_viewport_access_ops = {
  79        .read   = ulpi_viewport_read,
  80        .write  = ulpi_viewport_write,
  81};
  82EXPORT_SYMBOL_GPL(ulpi_viewport_access_ops);
  83