root/drivers/usb/chipidea/ulpi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ci_ulpi_wait
  2. ci_ulpi_read
  3. ci_ulpi_write
  4. ci_ulpi_init
  5. ci_ulpi_exit
  6. ci_ulpi_resume

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (c) 2016 Linaro Ltd.
   4  */
   5 
   6 #include <linux/device.h>
   7 #include <linux/usb/chipidea.h>
   8 #include <linux/ulpi/interface.h>
   9 
  10 #include "ci.h"
  11 
  12 #define ULPI_WAKEUP             BIT(31)
  13 #define ULPI_RUN                BIT(30)
  14 #define ULPI_WRITE              BIT(29)
  15 #define ULPI_SYNC_STATE         BIT(27)
  16 #define ULPI_ADDR(n)            ((n) << 16)
  17 #define ULPI_DATA(n)            (n)
  18 
  19 static int ci_ulpi_wait(struct ci_hdrc *ci, u32 mask)
  20 {
  21         unsigned long usec = 10000;
  22 
  23         while (usec--) {
  24                 if (!hw_read(ci, OP_ULPI_VIEWPORT, mask))
  25                         return 0;
  26 
  27                 udelay(1);
  28         }
  29 
  30         return -ETIMEDOUT;
  31 }
  32 
  33 static int ci_ulpi_read(struct device *dev, u8 addr)
  34 {
  35         struct ci_hdrc *ci = dev_get_drvdata(dev);
  36         int ret;
  37 
  38         hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
  39         ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
  40         if (ret)
  41                 return ret;
  42 
  43         hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_RUN | ULPI_ADDR(addr));
  44         ret = ci_ulpi_wait(ci, ULPI_RUN);
  45         if (ret)
  46                 return ret;
  47 
  48         return hw_read(ci, OP_ULPI_VIEWPORT, GENMASK(15, 8)) >> 8;
  49 }
  50 
  51 static int ci_ulpi_write(struct device *dev, u8 addr, u8 val)
  52 {
  53         struct ci_hdrc *ci = dev_get_drvdata(dev);
  54         int ret;
  55 
  56         hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
  57         ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
  58         if (ret)
  59                 return ret;
  60 
  61         hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff,
  62                  ULPI_RUN | ULPI_WRITE | ULPI_ADDR(addr) | val);
  63         return ci_ulpi_wait(ci, ULPI_RUN);
  64 }
  65 
  66 int ci_ulpi_init(struct ci_hdrc *ci)
  67 {
  68         if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
  69                 return 0;
  70 
  71         /*
  72          * Set PORTSC correctly so we can read/write ULPI registers for
  73          * identification purposes
  74          */
  75         hw_phymode_configure(ci);
  76 
  77         ci->ulpi_ops.read = ci_ulpi_read;
  78         ci->ulpi_ops.write = ci_ulpi_write;
  79         ci->ulpi = ulpi_register_interface(ci->dev, &ci->ulpi_ops);
  80         if (IS_ERR(ci->ulpi))
  81                 dev_err(ci->dev, "failed to register ULPI interface");
  82 
  83         return PTR_ERR_OR_ZERO(ci->ulpi);
  84 }
  85 
  86 void ci_ulpi_exit(struct ci_hdrc *ci)
  87 {
  88         if (ci->ulpi) {
  89                 ulpi_unregister_interface(ci->ulpi);
  90                 ci->ulpi = NULL;
  91         }
  92 }
  93 
  94 int ci_ulpi_resume(struct ci_hdrc *ci)
  95 {
  96         int cnt = 100000;
  97 
  98         if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
  99                 return 0;
 100 
 101         while (cnt-- > 0) {
 102                 if (hw_read(ci, OP_ULPI_VIEWPORT, ULPI_SYNC_STATE))
 103                         return 0;
 104                 udelay(1);
 105         }
 106 
 107         return -ETIMEDOUT;
 108 }

/* [<][>][^][v][top][bottom][index][help] */