LCOV - code coverage report
Current view: top level - drivers/usb/host/dwc_otg - dwc_otg_attr.c (source / functions) Hit Total Coverage
Test: Real Lines: 37 202 18.3 %
Date: 2020-10-17 15:46:43 Functions: 0 60 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* ==========================================================================
       2                 :            :  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
       3                 :            :  * $Revision: #44 $
       4                 :            :  * $Date: 2010/11/29 $
       5                 :            :  * $Change: 1636033 $
       6                 :            :  *
       7                 :            :  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
       8                 :            :  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
       9                 :            :  * otherwise expressly agreed to in writing between Synopsys and you.
      10                 :            :  *
      11                 :            :  * The Software IS NOT an item of Licensed Software or Licensed Product under
      12                 :            :  * any End User Software License Agreement or Agreement for Licensed Product
      13                 :            :  * with Synopsys or any supplement thereto. You are permitted to use and
      14                 :            :  * redistribute this Software in source and binary forms, with or without
      15                 :            :  * modification, provided that redistributions of source code must retain this
      16                 :            :  * notice. You may not view, use, disclose, copy or distribute this file or
      17                 :            :  * any information contained herein except pursuant to this license grant from
      18                 :            :  * Synopsys. If you do not agree with this notice, including the disclaimer
      19                 :            :  * below, then you are not authorized to use the Software.
      20                 :            :  *
      21                 :            :  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
      22                 :            :  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24                 :            :  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
      25                 :            :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      26                 :            :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      27                 :            :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
      28                 :            :  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
      31                 :            :  * DAMAGE.
      32                 :            :  * ========================================================================== */
      33                 :            : 
      34                 :            : /** @file
      35                 :            :  *
      36                 :            :  * The diagnostic interface will provide access to the controller for
      37                 :            :  * bringing up the hardware and testing.  The Linux driver attributes
      38                 :            :  * feature will be used to provide the Linux Diagnostic
      39                 :            :  * Interface. These attributes are accessed through sysfs.
      40                 :            :  */
      41                 :            : 
      42                 :            : /** @page "Linux Module Attributes"
      43                 :            :  *
      44                 :            :  * The Linux module attributes feature is used to provide the Linux
      45                 :            :  * Diagnostic Interface.  These attributes are accessed through sysfs.
      46                 :            :  * The diagnostic interface will provide access to the controller for
      47                 :            :  * bringing up the hardware and testing.
      48                 :            : 
      49                 :            :  The following table shows the attributes.
      50                 :            :  <table>
      51                 :            :  <tr>
      52                 :            :  <td><b> Name</b></td>
      53                 :            :  <td><b> Description</b></td>
      54                 :            :  <td><b> Access</b></td>
      55                 :            :  </tr>
      56                 :            : 
      57                 :            :  <tr>
      58                 :            :  <td> mode </td>
      59                 :            :  <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
      60                 :            :  <td> Read</td>
      61                 :            :  </tr>
      62                 :            : 
      63                 :            :  <tr>
      64                 :            :  <td> hnpcapable </td>
      65                 :            :  <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
      66                 :            :  Read returns the current value.</td>
      67                 :            :  <td> Read/Write</td>
      68                 :            :  </tr>
      69                 :            : 
      70                 :            :  <tr>
      71                 :            :  <td> srpcapable </td>
      72                 :            :  <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
      73                 :            :  Read returns the current value.</td>
      74                 :            :  <td> Read/Write</td>
      75                 :            :  </tr>
      76                 :            : 
      77                 :            :  <tr>
      78                 :            :  <td> hsic_connect </td>
      79                 :            :  <td> Gets or sets the "HSIC-Connect" bit in the GLPMCFG Register.
      80                 :            :  Read returns the current value.</td>
      81                 :            :  <td> Read/Write</td>
      82                 :            :  </tr>
      83                 :            : 
      84                 :            :  <tr>
      85                 :            :  <td> inv_sel_hsic </td>
      86                 :            :  <td> Gets or sets the "Invert Select HSIC" bit in the GLPMFG Register.
      87                 :            :  Read returns the current value.</td>
      88                 :            :  <td> Read/Write</td>
      89                 :            :  </tr>
      90                 :            : 
      91                 :            :  <tr>
      92                 :            :  <td> hnp </td>
      93                 :            :  <td> Initiates the Host Negotiation Protocol.  Read returns the status.</td>
      94                 :            :  <td> Read/Write</td>
      95                 :            :  </tr>
      96                 :            : 
      97                 :            :  <tr>
      98                 :            :  <td> srp </td>
      99                 :            :  <td> Initiates the Session Request Protocol.  Read returns the status.</td>
     100                 :            :  <td> Read/Write</td>
     101                 :            :  </tr>
     102                 :            : 
     103                 :            :  <tr>
     104                 :            :  <td> buspower </td>
     105                 :            :  <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
     106                 :            :  <td> Read/Write</td>
     107                 :            :  </tr>
     108                 :            : 
     109                 :            :  <tr>
     110                 :            :  <td> bussuspend </td>
     111                 :            :  <td> Suspends the USB bus.</td>
     112                 :            :  <td> Read/Write</td>
     113                 :            :  </tr>
     114                 :            : 
     115                 :            :  <tr>
     116                 :            :  <td> busconnected </td>
     117                 :            :  <td> Gets the connection status of the bus</td>
     118                 :            :  <td> Read</td>
     119                 :            :  </tr>
     120                 :            : 
     121                 :            :  <tr>
     122                 :            :  <td> gotgctl </td>
     123                 :            :  <td> Gets or sets the Core Control Status Register.</td>
     124                 :            :  <td> Read/Write</td>
     125                 :            :  </tr>
     126                 :            : 
     127                 :            :  <tr>
     128                 :            :  <td> gusbcfg </td>
     129                 :            :  <td> Gets or sets the Core USB Configuration Register</td>
     130                 :            :  <td> Read/Write</td>
     131                 :            :  </tr>
     132                 :            : 
     133                 :            :  <tr>
     134                 :            :  <td> grxfsiz </td>
     135                 :            :  <td> Gets or sets the Receive FIFO Size Register</td>
     136                 :            :  <td> Read/Write</td>
     137                 :            :  </tr>
     138                 :            : 
     139                 :            :  <tr>
     140                 :            :  <td> gnptxfsiz </td>
     141                 :            :  <td> Gets or sets the non-periodic Transmit Size Register</td>
     142                 :            :  <td> Read/Write</td>
     143                 :            :  </tr>
     144                 :            : 
     145                 :            :  <tr>
     146                 :            :  <td> gpvndctl </td>
     147                 :            :  <td> Gets or sets the PHY Vendor Control Register</td>
     148                 :            :  <td> Read/Write</td>
     149                 :            :  </tr>
     150                 :            : 
     151                 :            :  <tr>
     152                 :            :  <td> ggpio </td>
     153                 :            :  <td> Gets the value in the lower 16-bits of the General Purpose IO Register
     154                 :            :  or sets the upper 16 bits.</td>
     155                 :            :  <td> Read/Write</td>
     156                 :            :  </tr>
     157                 :            : 
     158                 :            :  <tr>
     159                 :            :  <td> guid </td>
     160                 :            :  <td> Gets or sets the value of the User ID Register</td>
     161                 :            :  <td> Read/Write</td>
     162                 :            :  </tr>
     163                 :            : 
     164                 :            :  <tr>
     165                 :            :  <td> gsnpsid </td>
     166                 :            :  <td> Gets the value of the Synopsys ID Regester</td>
     167                 :            :  <td> Read</td>
     168                 :            :  </tr>
     169                 :            : 
     170                 :            :  <tr>
     171                 :            :  <td> devspeed </td>
     172                 :            :  <td> Gets or sets the device speed setting in the DCFG register</td>
     173                 :            :  <td> Read/Write</td>
     174                 :            :  </tr>
     175                 :            : 
     176                 :            :  <tr>
     177                 :            :  <td> enumspeed </td>
     178                 :            :  <td> Gets the device enumeration Speed.</td>
     179                 :            :  <td> Read</td>
     180                 :            :  </tr>
     181                 :            : 
     182                 :            :  <tr>
     183                 :            :  <td> hptxfsiz </td>
     184                 :            :  <td> Gets the value of the Host Periodic Transmit FIFO</td>
     185                 :            :  <td> Read</td>
     186                 :            :  </tr>
     187                 :            : 
     188                 :            :  <tr>
     189                 :            :  <td> hprt0 </td>
     190                 :            :  <td> Gets or sets the value in the Host Port Control and Status Register</td>
     191                 :            :  <td> Read/Write</td>
     192                 :            :  </tr>
     193                 :            : 
     194                 :            :  <tr>
     195                 :            :  <td> regoffset </td>
     196                 :            :  <td> Sets the register offset for the next Register Access</td>
     197                 :            :  <td> Read/Write</td>
     198                 :            :  </tr>
     199                 :            : 
     200                 :            :  <tr>
     201                 :            :  <td> regvalue </td>
     202                 :            :  <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
     203                 :            :  <td> Read/Write</td>
     204                 :            :  </tr>
     205                 :            : 
     206                 :            :  <tr>
     207                 :            :  <td> remote_wakeup </td>
     208                 :            :  <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
     209                 :            :  wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
     210                 :            :  Wakeup signalling bit in the Device Control Register is set for 1
     211                 :            :  milli-second.</td>
     212                 :            :  <td> Read/Write</td>
     213                 :            :  </tr>
     214                 :            : 
     215                 :            :  <tr>
     216                 :            :  <td> rem_wakeup_pwrdn </td>
     217                 :            :  <td> On read, shows the status core - hibernated or not. On write, initiates
     218                 :            :  a remote wakeup of the device from Hibernation. </td>
     219                 :            :  <td> Read/Write</td>
     220                 :            :  </tr>
     221                 :            : 
     222                 :            :  <tr>
     223                 :            :  <td> mode_ch_tim_en </td>
     224                 :            :  <td> This bit is used to enable or disable the host core to wait for 200 PHY
     225                 :            :  clock cycles at the end of Resume to change the opmode signal to the PHY to 00
     226                 :            :  after Suspend or LPM. </td>
     227                 :            :  <td> Read/Write</td>
     228                 :            :  </tr>
     229                 :            : 
     230                 :            :  <tr>
     231                 :            :  <td> fr_interval </td>
     232                 :            :  <td> On read, shows the value of HFIR Frame Interval. On write, dynamically
     233                 :            :  reload HFIR register during runtime. The application can write a value to this
     234                 :            :  register only after the Port Enable bit of the Host Port Control and Status
     235                 :            :  register (HPRT.PrtEnaPort) has been set </td>
     236                 :            :  <td> Read/Write</td>
     237                 :            :  </tr>
     238                 :            : 
     239                 :            :  <tr>
     240                 :            :  <td> disconnect_us </td>
     241                 :            :  <td> On read, shows the status of disconnect_device_us. On write, sets disconnect_us
     242                 :            :  which causes soft disconnect for 100us. Applicable only for device mode of operation.</td>
     243                 :            :  <td> Read/Write</td>
     244                 :            :  </tr>
     245                 :            : 
     246                 :            :  <tr>
     247                 :            :  <td> regdump </td>
     248                 :            :  <td> Dumps the contents of core registers.</td>
     249                 :            :  <td> Read</td>
     250                 :            :  </tr>
     251                 :            : 
     252                 :            :  <tr>
     253                 :            :  <td> spramdump </td>
     254                 :            :  <td> Dumps the contents of core registers.</td>
     255                 :            :  <td> Read</td>
     256                 :            :  </tr>
     257                 :            : 
     258                 :            :  <tr>
     259                 :            :  <td> hcddump </td>
     260                 :            :  <td> Dumps the current HCD state.</td>
     261                 :            :  <td> Read</td>
     262                 :            :  </tr>
     263                 :            : 
     264                 :            :  <tr>
     265                 :            :  <td> hcd_frrem </td>
     266                 :            :  <td> Shows the average value of the Frame Remaining
     267                 :            :  field in the Host Frame Number/Frame Remaining register when an SOF interrupt
     268                 :            :  occurs. This can be used to determine the average interrupt latency. Also
     269                 :            :  shows the average Frame Remaining value for start_transfer and the "a" and
     270                 :            :  "b" sample points. The "a" and "b" sample points may be used during debugging
     271                 :            :  bto determine how long it takes to execute a section of the HCD code.</td>
     272                 :            :  <td> Read</td>
     273                 :            :  </tr>
     274                 :            : 
     275                 :            :  <tr>
     276                 :            :  <td> rd_reg_test </td>
     277                 :            :  <td> Displays the time required to read the GNPTXFSIZ register many times
     278                 :            :  (the output shows the number of times the register is read).
     279                 :            :  <td> Read</td>
     280                 :            :  </tr>
     281                 :            : 
     282                 :            :  <tr>
     283                 :            :  <td> wr_reg_test </td>
     284                 :            :  <td> Displays the time required to write the GNPTXFSIZ register many times
     285                 :            :  (the output shows the number of times the register is written).
     286                 :            :  <td> Read</td>
     287                 :            :  </tr>
     288                 :            : 
     289                 :            :  <tr>
     290                 :            :  <td> lpm_response </td>
     291                 :            :  <td> Gets or sets lpm_response mode. Applicable only in device mode.
     292                 :            :  <td> Write</td>
     293                 :            :  </tr>
     294                 :            : 
     295                 :            :  <tr>
     296                 :            :  <td> sleep_status </td>
     297                 :            :  <td> Shows sleep status of device.
     298                 :            :  <td> Read</td>
     299                 :            :  </tr>
     300                 :            : 
     301                 :            :  </table>
     302                 :            : 
     303                 :            :  Example usage:
     304                 :            :  To get the current mode:
     305                 :            :  cat /sys/devices/lm0/mode
     306                 :            : 
     307                 :            :  To power down the USB:
     308                 :            :  echo 0 > /sys/devices/lm0/buspower
     309                 :            :  */
     310                 :            : 
     311                 :            : #include "dwc_otg_os_dep.h"
     312                 :            : #include "dwc_os.h"
     313                 :            : #include "dwc_otg_driver.h"
     314                 :            : #include "dwc_otg_attr.h"
     315                 :            : #include "dwc_otg_core_if.h"
     316                 :            : #include "dwc_otg_pcd_if.h"
     317                 :            : #include "dwc_otg_hcd_if.h"
     318                 :            : 
     319                 :            : /*
     320                 :            :  * MACROs for defining sysfs attribute
     321                 :            :  */
     322                 :            : #ifdef LM_INTERFACE
     323                 :            : 
     324                 :            : #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
     325                 :            : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
     326                 :            : { \
     327                 :            :         struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
     328                 :            :         dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);             \
     329                 :            :         uint32_t val; \
     330                 :            :         val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
     331                 :            :         return sprintf (buf, "%s = 0x%x\n", _string_, val); \
     332                 :            : }
     333                 :            : #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
     334                 :            : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
     335                 :            :                                         const char *buf, size_t count) \
     336                 :            : { \
     337                 :            :         struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
     338                 :            :         dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
     339                 :            :         uint32_t set = simple_strtoul(buf, NULL, 16); \
     340                 :            :         dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
     341                 :            :         return count; \
     342                 :            : }
     343                 :            : 
     344                 :            : #elif defined(PCI_INTERFACE)
     345                 :            : 
     346                 :            : #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
     347                 :            : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
     348                 :            : { \
     349                 :            :         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);      \
     350                 :            :         uint32_t val; \
     351                 :            :         val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
     352                 :            :         return sprintf (buf, "%s = 0x%x\n", _string_, val); \
     353                 :            : }
     354                 :            : #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
     355                 :            : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
     356                 :            :                                         const char *buf, size_t count) \
     357                 :            : { \
     358                 :            :         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);  \
     359                 :            :         uint32_t set = simple_strtoul(buf, NULL, 16); \
     360                 :            :         dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
     361                 :            :         return count; \
     362                 :            : }
     363                 :            : 
     364                 :            : #elif defined(PLATFORM_INTERFACE)
     365                 :            : 
     366                 :            : #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
     367                 :            : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
     368                 :            : { \
     369                 :            :         struct platform_device *platform_dev = \
     370                 :            :                 container_of(_dev, struct platform_device, dev); \
     371                 :            :         dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev);  \
     372                 :            :         uint32_t val; \
     373                 :            :         DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \
     374                 :            :                     __func__, _dev, platform_dev, otg_dev); \
     375                 :            :         val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
     376                 :            :         return sprintf (buf, "%s = 0x%x\n", _string_, val); \
     377                 :            : }
     378                 :            : #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
     379                 :            : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
     380                 :            :                                         const char *buf, size_t count) \
     381                 :            : { \
     382                 :            :         struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
     383                 :            :         dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
     384                 :            :         uint32_t set = simple_strtoul(buf, NULL, 16); \
     385                 :            :         dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
     386                 :            :         return count; \
     387                 :            : }
     388                 :            : #endif
     389                 :            : 
     390                 :            : /*
     391                 :            :  * MACROs for defining sysfs attribute for 32-bit registers
     392                 :            :  */
     393                 :            : #ifdef LM_INTERFACE
     394                 :            : #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
     395                 :            : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
     396                 :            : { \
     397                 :            :         struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
     398                 :            :         dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
     399                 :            :         uint32_t val; \
     400                 :            :         val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
     401                 :            :         return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
     402                 :            : }
     403                 :            : #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
     404                 :            : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
     405                 :            :                                         const char *buf, size_t count) \
     406                 :            : { \
     407                 :            :         struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
     408                 :            :         dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
     409                 :            :         uint32_t val = simple_strtoul(buf, NULL, 16); \
     410                 :            :         dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
     411                 :            :         return count; \
     412                 :            : }
     413                 :            : #elif defined(PCI_INTERFACE)
     414                 :            : #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
     415                 :            : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
     416                 :            : { \
     417                 :            :         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);  \
     418                 :            :         uint32_t val; \
     419                 :            :         val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
     420                 :            :         return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
     421                 :            : }
     422                 :            : #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
     423                 :            : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
     424                 :            :                                         const char *buf, size_t count) \
     425                 :            : { \
     426                 :            :         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);  \
     427                 :            :         uint32_t val = simple_strtoul(buf, NULL, 16); \
     428                 :            :         dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
     429                 :            :         return count; \
     430                 :            : }
     431                 :            : 
     432                 :            : #elif defined(PLATFORM_INTERFACE)
     433                 :            : #include "dwc_otg_dbg.h"
     434                 :            : #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
     435                 :            : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
     436                 :            : { \
     437                 :            :         struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
     438                 :            :         dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
     439                 :            :         uint32_t val; \
     440                 :            :         DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \
     441                 :            :                     __func__, _dev, platform_dev, otg_dev); \
     442                 :            :         val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
     443                 :            :         return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
     444                 :            : }
     445                 :            : #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
     446                 :            : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
     447                 :            :                                         const char *buf, size_t count) \
     448                 :            : { \
     449                 :            :         struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
     450                 :            :         dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
     451                 :            :         uint32_t val = simple_strtoul(buf, NULL, 16); \
     452                 :            :         dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
     453                 :            :         return count; \
     454                 :            : }
     455                 :            : 
     456                 :            : #endif
     457                 :            : 
     458                 :            : #define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_string_) \
     459                 :            : DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
     460                 :            : DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
     461                 :            : DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
     462                 :            : 
     463                 :            : #define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_string_) \
     464                 :            : DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
     465                 :            : DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
     466                 :            : 
     467                 :            : #define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
     468                 :            : DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
     469                 :            : DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
     470                 :            : DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
     471                 :            : 
     472                 :            : #define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
     473                 :            : DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
     474                 :            : DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
     475                 :            : 
     476                 :            : /** @name Functions for Show/Store of Attributes */
     477                 :            : /**@{*/
     478                 :            : 
     479                 :            : /**
     480                 :            :  * Helper function returning the otg_device structure of the given device
     481                 :            :  */
     482                 :            : static dwc_otg_device_t *dwc_otg_drvdev(struct device *_dev)
     483                 :            : {
     484                 :            :         dwc_otg_device_t *otg_dev;
     485                 :            :         DWC_OTG_GETDRVDEV(otg_dev, _dev);
     486                 :            :         return otg_dev;
     487                 :            : }
     488                 :            : 
     489                 :            : /**
     490                 :            :  * Show the register offset of the Register Access.
     491                 :            :  */
     492                 :          0 : static ssize_t regoffset_show(struct device *_dev,
     493                 :            :                               struct device_attribute *attr, char *buf)
     494                 :            : {
     495                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     496                 :          0 :         return snprintf(buf, sizeof("0xFFFFFFFF\n") + 1, "0x%08x\n",
     497                 :            :                         otg_dev->os_dep.reg_offset);
     498                 :            : }
     499                 :            : 
     500                 :            : /**
     501                 :            :  * Set the register offset for the next Register Access         Read/Write
     502                 :            :  */
     503                 :          0 : static ssize_t regoffset_store(struct device *_dev,
     504                 :            :                                struct device_attribute *attr,
     505                 :            :                                const char *buf, size_t count)
     506                 :            : {
     507                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     508                 :          0 :         uint32_t offset = simple_strtoul(buf, NULL, 16);
     509                 :            : #if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE)
     510                 :          0 :         if (offset < SZ_256K) {
     511                 :            : #elif  defined(PCI_INTERFACE)
     512                 :            :         if (offset < 0x00040000) {
     513                 :            : #endif
     514                 :          0 :                 otg_dev->os_dep.reg_offset = offset;
     515                 :            :         } else {
     516                 :          0 :                 dev_err(_dev, "invalid offset\n");
     517                 :            :         }
     518                 :            : 
     519                 :          0 :         return count;
     520                 :            : }
     521                 :            : 
     522                 :            : DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store);
     523                 :            : 
     524                 :            : /**
     525                 :            :  * Show the value of the register at the offset in the reg_offset
     526                 :            :  * attribute.
     527                 :            :  */
     528                 :          0 : static ssize_t regvalue_show(struct device *_dev,
     529                 :            :                              struct device_attribute *attr, char *buf)
     530                 :            : {
     531                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     532                 :            :         uint32_t val;
     533                 :            :         volatile uint32_t *addr;
     534                 :            : 
     535                 :          0 :         if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) {
     536                 :            :                 /* Calculate the address */
     537                 :          0 :                 addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
     538                 :            :                                      (uint8_t *) otg_dev->os_dep.base);
     539                 :          0 :                 val = DWC_READ_REG32(addr);
     540                 :          0 :                 return snprintf(buf,
     541                 :            :                                 sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n") + 1,
     542                 :            :                                 "Reg@0x%06x = 0x%08x\n", otg_dev->os_dep.reg_offset,
     543                 :            :                                 val);
     544                 :            :         } else {
     545                 :          0 :                 dev_err(_dev, "Invalid offset (0x%0x)\n", otg_dev->os_dep.reg_offset);
     546                 :          0 :                 return sprintf(buf, "invalid offset\n");
     547                 :            :         }
     548                 :            : }
     549                 :            : 
     550                 :            : /**
     551                 :            :  * Store the value in the register at the offset in the reg_offset
     552                 :            :  * attribute.
     553                 :            :  *
     554                 :            :  */
     555                 :          0 : static ssize_t regvalue_store(struct device *_dev,
     556                 :            :                               struct device_attribute *attr,
     557                 :            :                               const char *buf, size_t count)
     558                 :            : {
     559                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     560                 :            :         volatile uint32_t *addr;
     561                 :          0 :         uint32_t val = simple_strtoul(buf, NULL, 16);
     562                 :            :         //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
     563                 :          0 :         if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) {
     564                 :            :                 /* Calculate the address */
     565                 :          0 :                 addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
     566                 :            :                                      (uint8_t *) otg_dev->os_dep.base);
     567                 :          0 :                 DWC_WRITE_REG32(addr, val);
     568                 :            :         } else {
     569                 :          0 :                 dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
     570                 :            :                         otg_dev->os_dep.reg_offset);
     571                 :            :         }
     572                 :          0 :         return count;
     573                 :            : }
     574                 :            : 
     575                 :            : DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store);
     576                 :            : 
     577                 :            : /*
     578                 :            :  * Attributes
     579                 :            :  */
     580                 :          0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode, "Mode");
     581                 :          0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable, "HNPCapable");
     582                 :          0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable, "SRPCapable");
     583                 :          0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hsic_connect, "HSIC Connect");
     584                 :          0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(inv_sel_hsic, "Invert Select HSIC");
     585                 :            : 
     586                 :            : //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
     587                 :            : //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
     588                 :          0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, "Bus Connected");
     589                 :            : 
     590                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl, 0, "GOTGCTL");
     591                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,
     592                 :            :                              &(otg_dev->core_if->core_global_regs->gusbcfg),
     593                 :            :                              "GUSBCFG");
     594                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,
     595                 :            :                              &(otg_dev->core_if->core_global_regs->grxfsiz),
     596                 :            :                              "GRXFSIZ");
     597                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,
     598                 :            :                              &(otg_dev->core_if->core_global_regs->gnptxfsiz),
     599                 :            :                              "GNPTXFSIZ");
     600                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,
     601                 :            :                              &(otg_dev->core_if->core_global_regs->gpvndctl),
     602                 :            :                              "GPVNDCTL");
     603                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,
     604                 :            :                              &(otg_dev->core_if->core_global_regs->ggpio),
     605                 :            :                              "GGPIO");
     606                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid),
     607                 :            :                              "GUID");
     608                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,
     609                 :            :                              &(otg_dev->core_if->core_global_regs->gsnpsid),
     610                 :            :                              "GSNPSID");
     611                 :          0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed, "Device Speed");
     612                 :          0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed, "Device Enumeration Speed");
     613                 :            : 
     614                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,
     615                 :            :                              &(otg_dev->core_if->core_global_regs->hptxfsiz),
     616                 :            :                              "HPTXFSIZ");
     617                 :          0 : DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0");
     618                 :            : 
     619                 :            : /**
     620                 :            :  * @todo Add code to initiate the HNP.
     621                 :            :  */
     622                 :            : /**
     623                 :            :  * Show the HNP status bit
     624                 :            :  */
     625                 :          0 : static ssize_t hnp_show(struct device *_dev,
     626                 :            :                         struct device_attribute *attr, char *buf)
     627                 :            : {
     628                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     629                 :          0 :         return sprintf(buf, "HstNegScs = 0x%x\n",
     630                 :            :                        dwc_otg_get_hnpstatus(otg_dev->core_if));
     631                 :            : }
     632                 :            : 
     633                 :            : /**
     634                 :            :  * Set the HNP Request bit
     635                 :            :  */
     636                 :          0 : static ssize_t hnp_store(struct device *_dev,
     637                 :            :                          struct device_attribute *attr,
     638                 :            :                          const char *buf, size_t count)
     639                 :            : {
     640                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     641                 :          0 :         uint32_t in = simple_strtoul(buf, NULL, 16);
     642                 :          0 :         dwc_otg_set_hnpreq(otg_dev->core_if, in);
     643                 :          0 :         return count;
     644                 :            : }
     645                 :            : 
     646                 :            : DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
     647                 :            : 
     648                 :            : /**
     649                 :            :  * @todo Add code to initiate the SRP.
     650                 :            :  */
     651                 :            : /**
     652                 :            :  * Show the SRP status bit
     653                 :            :  */
     654                 :          0 : static ssize_t srp_show(struct device *_dev,
     655                 :            :                         struct device_attribute *attr, char *buf)
     656                 :            : {
     657                 :            : #ifndef DWC_HOST_ONLY
     658                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     659                 :          0 :         return sprintf(buf, "SesReqScs = 0x%x\n",
     660                 :            :                        dwc_otg_get_srpstatus(otg_dev->core_if));
     661                 :            : #else
     662                 :            :         return sprintf(buf, "Host Only Mode!\n");
     663                 :            : #endif
     664                 :            : }
     665                 :            : 
     666                 :            : /**
     667                 :            :  * Set the SRP Request bit
     668                 :            :  */
     669                 :          0 : static ssize_t srp_store(struct device *_dev,
     670                 :            :                          struct device_attribute *attr,
     671                 :            :                          const char *buf, size_t count)
     672                 :            : {
     673                 :            : #ifndef DWC_HOST_ONLY
     674                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     675                 :          0 :         dwc_otg_pcd_initiate_srp(otg_dev->pcd);
     676                 :            : #endif
     677                 :          0 :         return count;
     678                 :            : }
     679                 :            : 
     680                 :            : DEVICE_ATTR(srp, 0644, srp_show, srp_store);
     681                 :            : 
     682                 :            : /**
     683                 :            :  * @todo Need to do more for power on/off?
     684                 :            :  */
     685                 :            : /**
     686                 :            :  * Show the Bus Power status
     687                 :            :  */
     688                 :          0 : static ssize_t buspower_show(struct device *_dev,
     689                 :            :                              struct device_attribute *attr, char *buf)
     690                 :            : {
     691                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     692                 :          0 :         return sprintf(buf, "Bus Power = 0x%x\n",
     693                 :            :                        dwc_otg_get_prtpower(otg_dev->core_if));
     694                 :            : }
     695                 :            : 
     696                 :            : /**
     697                 :            :  * Set the Bus Power status
     698                 :            :  */
     699                 :          0 : static ssize_t buspower_store(struct device *_dev,
     700                 :            :                               struct device_attribute *attr,
     701                 :            :                               const char *buf, size_t count)
     702                 :            : {
     703                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     704                 :          0 :         uint32_t on = simple_strtoul(buf, NULL, 16);
     705                 :          0 :         dwc_otg_set_prtpower(otg_dev->core_if, on);
     706                 :          0 :         return count;
     707                 :            : }
     708                 :            : 
     709                 :            : DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
     710                 :            : 
     711                 :            : /**
     712                 :            :  * @todo Need to do more for suspend?
     713                 :            :  */
     714                 :            : /**
     715                 :            :  * Show the Bus Suspend status
     716                 :            :  */
     717                 :          0 : static ssize_t bussuspend_show(struct device *_dev,
     718                 :            :                                struct device_attribute *attr, char *buf)
     719                 :            : {
     720                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     721                 :          0 :         return sprintf(buf, "Bus Suspend = 0x%x\n",
     722                 :            :                        dwc_otg_get_prtsuspend(otg_dev->core_if));
     723                 :            : }
     724                 :            : 
     725                 :            : /**
     726                 :            :  * Set the Bus Suspend status
     727                 :            :  */
     728                 :          0 : static ssize_t bussuspend_store(struct device *_dev,
     729                 :            :                                 struct device_attribute *attr,
     730                 :            :                                 const char *buf, size_t count)
     731                 :            : {
     732                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     733                 :          0 :         uint32_t in = simple_strtoul(buf, NULL, 16);
     734                 :          0 :         dwc_otg_set_prtsuspend(otg_dev->core_if, in);
     735                 :          0 :         return count;
     736                 :            : }
     737                 :            : 
     738                 :            : DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
     739                 :            : 
     740                 :            : /**
     741                 :            :  * Show the Mode Change Ready Timer status
     742                 :            :  */
     743                 :          0 : static ssize_t mode_ch_tim_en_show(struct device *_dev,
     744                 :            :                                    struct device_attribute *attr, char *buf)
     745                 :            : {
     746                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     747                 :          0 :         return sprintf(buf, "Mode Change Ready Timer Enable = 0x%x\n",
     748                 :            :                        dwc_otg_get_mode_ch_tim(otg_dev->core_if));
     749                 :            : }
     750                 :            : 
     751                 :            : /**
     752                 :            :  * Set the Mode Change Ready Timer status
     753                 :            :  */
     754                 :          0 : static ssize_t mode_ch_tim_en_store(struct device *_dev,
     755                 :            :                                     struct device_attribute *attr,
     756                 :            :                                     const char *buf, size_t count)
     757                 :            : {
     758                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     759                 :          0 :         uint32_t in = simple_strtoul(buf, NULL, 16);
     760                 :          0 :         dwc_otg_set_mode_ch_tim(otg_dev->core_if, in);
     761                 :          0 :         return count;
     762                 :            : }
     763                 :            : 
     764                 :            : DEVICE_ATTR(mode_ch_tim_en, 0644, mode_ch_tim_en_show, mode_ch_tim_en_store);
     765                 :            : 
     766                 :            : /**
     767                 :            :  * Show the value of HFIR Frame Interval bitfield
     768                 :            :  */
     769                 :          0 : static ssize_t fr_interval_show(struct device *_dev,
     770                 :            :                                 struct device_attribute *attr, char *buf)
     771                 :            : {
     772                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     773                 :          0 :         return sprintf(buf, "Frame Interval = 0x%x\n",
     774                 :            :                        dwc_otg_get_fr_interval(otg_dev->core_if));
     775                 :            : }
     776                 :            : 
     777                 :            : /**
     778                 :            :  * Set the HFIR Frame Interval value
     779                 :            :  */
     780                 :          0 : static ssize_t fr_interval_store(struct device *_dev,
     781                 :            :                                  struct device_attribute *attr,
     782                 :            :                                  const char *buf, size_t count)
     783                 :            : {
     784                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     785                 :          0 :         uint32_t in = simple_strtoul(buf, NULL, 10);
     786                 :          0 :         dwc_otg_set_fr_interval(otg_dev->core_if, in);
     787                 :          0 :         return count;
     788                 :            : }
     789                 :            : 
     790                 :            : DEVICE_ATTR(fr_interval, 0644, fr_interval_show, fr_interval_store);
     791                 :            : 
     792                 :            : /**
     793                 :            :  * Show the status of Remote Wakeup.
     794                 :            :  */
     795                 :          0 : static ssize_t remote_wakeup_show(struct device *_dev,
     796                 :            :                                   struct device_attribute *attr, char *buf)
     797                 :            : {
     798                 :            : #ifndef DWC_HOST_ONLY
     799                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     800                 :            : 
     801                 :          0 :         return sprintf(buf,
     802                 :            :                        "Remote Wakeup Sig = %d Enabled = %d LPM Remote Wakeup = %d\n",
     803                 :            :                        dwc_otg_get_remotewakesig(otg_dev->core_if),
     804                 :          0 :                        dwc_otg_pcd_get_rmwkup_enable(otg_dev->pcd),
     805                 :            :                        dwc_otg_get_lpm_remotewakeenabled(otg_dev->core_if));
     806                 :            : #else
     807                 :            :         return sprintf(buf, "Host Only Mode!\n");
     808                 :            : #endif /* DWC_HOST_ONLY */
     809                 :            : }
     810                 :            : 
     811                 :            : /**
     812                 :            :  * Initiate a remote wakeup of the host.  The Device control register
     813                 :            :  * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
     814                 :            :  * flag is set.
     815                 :            :  *
     816                 :            :  */
     817                 :          0 : static ssize_t remote_wakeup_store(struct device *_dev,
     818                 :            :                                    struct device_attribute *attr,
     819                 :            :                                    const char *buf, size_t count)
     820                 :            : {
     821                 :            : #ifndef DWC_HOST_ONLY
     822                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     823                 :          0 :         uint32_t val = simple_strtoul(buf, NULL, 16);
     824                 :            : 
     825                 :          0 :         if (val & 1) {
     826                 :          0 :                 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
     827                 :            :         } else {
     828                 :          0 :                 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
     829                 :            :         }
     830                 :            : #endif /* DWC_HOST_ONLY */
     831                 :          0 :         return count;
     832                 :            : }
     833                 :            : 
     834                 :            : DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show,
     835                 :            :             remote_wakeup_store);
     836                 :            : 
     837                 :            : /**
     838                 :            :  * Show the whether core is hibernated or not.
     839                 :            :  */
     840                 :          0 : static ssize_t rem_wakeup_pwrdn_show(struct device *_dev,
     841                 :            :                                      struct device_attribute *attr, char *buf)
     842                 :            : {
     843                 :            : #ifndef DWC_HOST_ONLY
     844                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     845                 :            : 
     846                 :          0 :         if (dwc_otg_get_core_state(otg_dev->core_if)) {
     847                 :          0 :                 DWC_PRINTF("Core is in hibernation\n");
     848                 :            :         } else {
     849                 :          0 :                 DWC_PRINTF("Core is not in hibernation\n");
     850                 :            :         }
     851                 :            : #endif /* DWC_HOST_ONLY */
     852                 :          0 :         return 0;
     853                 :            : }
     854                 :            : 
     855                 :            : extern int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
     856                 :            :                                               int rem_wakeup, int reset);
     857                 :            : 
     858                 :            : /**
     859                 :            :  * Initiate a remote wakeup of the device to exit from hibernation.
     860                 :            :  */
     861                 :          0 : static ssize_t rem_wakeup_pwrdn_store(struct device *_dev,
     862                 :            :                                       struct device_attribute *attr,
     863                 :            :                                       const char *buf, size_t count)
     864                 :            : {
     865                 :            : #ifndef DWC_HOST_ONLY
     866                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     867                 :          0 :         dwc_otg_device_hibernation_restore(otg_dev->core_if, 1, 0);
     868                 :            : #endif
     869                 :          0 :         return count;
     870                 :            : }
     871                 :            : 
     872                 :            : DEVICE_ATTR(rem_wakeup_pwrdn, S_IRUGO | S_IWUSR, rem_wakeup_pwrdn_show,
     873                 :            :             rem_wakeup_pwrdn_store);
     874                 :            : 
     875                 :          0 : static ssize_t disconnect_us(struct device *_dev,
     876                 :            :                              struct device_attribute *attr,
     877                 :            :                              const char *buf, size_t count)
     878                 :            : {
     879                 :            : 
     880                 :            : #ifndef DWC_HOST_ONLY
     881                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     882                 :          0 :         uint32_t val = simple_strtoul(buf, NULL, 16);
     883                 :          0 :         DWC_PRINTF("The Passed value is %04x\n", val);
     884                 :            : 
     885                 :          0 :         dwc_otg_pcd_disconnect_us(otg_dev->pcd, 50);
     886                 :            : 
     887                 :            : #endif /* DWC_HOST_ONLY */
     888                 :          0 :         return count;
     889                 :            : }
     890                 :            : 
     891                 :            : DEVICE_ATTR(disconnect_us, S_IWUSR, 0, disconnect_us);
     892                 :            : 
     893                 :            : /**
     894                 :            :  * Dump global registers and either host or device registers (depending on the
     895                 :            :  * current mode of the core).
     896                 :            :  */
     897                 :          0 : static ssize_t regdump_show(struct device *_dev,
     898                 :            :                             struct device_attribute *attr, char *buf)
     899                 :            : {
     900                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     901                 :            : 
     902                 :          0 :         dwc_otg_dump_global_registers(otg_dev->core_if);
     903                 :          0 :         if (dwc_otg_is_host_mode(otg_dev->core_if)) {
     904                 :          0 :                 dwc_otg_dump_host_registers(otg_dev->core_if);
     905                 :            :         } else {
     906                 :          0 :                 dwc_otg_dump_dev_registers(otg_dev->core_if);
     907                 :            : 
     908                 :            :         }
     909                 :          0 :         return sprintf(buf, "Register Dump\n");
     910                 :            : }
     911                 :            : 
     912                 :            : DEVICE_ATTR(regdump, S_IRUGO, regdump_show, 0);
     913                 :            : 
     914                 :            : /**
     915                 :            :  * Dump global registers and either host or device registers (depending on the
     916                 :            :  * current mode of the core).
     917                 :            :  */
     918                 :          0 : static ssize_t spramdump_show(struct device *_dev,
     919                 :            :                               struct device_attribute *attr, char *buf)
     920                 :            : {
     921                 :            : #if 0
     922                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     923                 :            : 
     924                 :            :         dwc_otg_dump_spram(otg_dev->core_if);
     925                 :            : #endif
     926                 :            : 
     927                 :          0 :         return sprintf(buf, "SPRAM Dump\n");
     928                 :            : }
     929                 :            : 
     930                 :            : DEVICE_ATTR(spramdump, S_IRUGO, spramdump_show, 0);
     931                 :            : 
     932                 :            : /**
     933                 :            :  * Dump the current hcd state.
     934                 :            :  */
     935                 :          0 : static ssize_t hcddump_show(struct device *_dev,
     936                 :            :                             struct device_attribute *attr, char *buf)
     937                 :            : {
     938                 :            : #ifndef DWC_DEVICE_ONLY
     939                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     940                 :          0 :         dwc_otg_hcd_dump_state(otg_dev->hcd);
     941                 :            : #endif /* DWC_DEVICE_ONLY */
     942                 :          0 :         return sprintf(buf, "HCD Dump\n");
     943                 :            : }
     944                 :            : 
     945                 :            : DEVICE_ATTR(hcddump, S_IRUGO, hcddump_show, 0);
     946                 :            : 
     947                 :            : /**
     948                 :            :  * Dump the average frame remaining at SOF. This can be used to
     949                 :            :  * determine average interrupt latency. Frame remaining is also shown for
     950                 :            :  * start transfer and two additional sample points.
     951                 :            :  */
     952                 :          0 : static ssize_t hcd_frrem_show(struct device *_dev,
     953                 :            :                               struct device_attribute *attr, char *buf)
     954                 :            : {
     955                 :            : #ifndef DWC_DEVICE_ONLY
     956                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     957                 :            : 
     958                 :          0 :         dwc_otg_hcd_dump_frrem(otg_dev->hcd);
     959                 :            : #endif /* DWC_DEVICE_ONLY */
     960                 :          0 :         return sprintf(buf, "HCD Dump Frame Remaining\n");
     961                 :            : }
     962                 :            : 
     963                 :            : DEVICE_ATTR(hcd_frrem, S_IRUGO, hcd_frrem_show, 0);
     964                 :            : 
     965                 :            : /**
     966                 :            :  * Displays the time required to read the GNPTXFSIZ register many times (the
     967                 :            :  * output shows the number of times the register is read).
     968                 :            :  */
     969                 :            : #define RW_REG_COUNT 10000000
     970                 :            : #define MSEC_PER_JIFFIE 1000/HZ
     971                 :          0 : static ssize_t rd_reg_test_show(struct device *_dev,
     972                 :            :                                 struct device_attribute *attr, char *buf)
     973                 :            : {
     974                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
     975                 :            :         int i;
     976                 :            :         int time;
     977                 :            :         int start_jiffies;
     978                 :            : 
     979                 :          0 :         printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
     980                 :            :                HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
     981                 :          0 :         start_jiffies = jiffies;
     982                 :          0 :         for (i = 0; i < RW_REG_COUNT; i++) {
     983                 :          0 :                 dwc_otg_get_gnptxfsiz(otg_dev->core_if);
     984                 :            :         }
     985                 :          0 :         time = jiffies - start_jiffies;
     986                 :          0 :         return sprintf(buf,
     987                 :            :                        "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
     988                 :          0 :                        RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
     989                 :            : }
     990                 :            : 
     991                 :            : DEVICE_ATTR(rd_reg_test, S_IRUGO, rd_reg_test_show, 0);
     992                 :            : 
     993                 :            : /**
     994                 :            :  * Displays the time required to write the GNPTXFSIZ register many times (the
     995                 :            :  * output shows the number of times the register is written).
     996                 :            :  */
     997                 :          0 : static ssize_t wr_reg_test_show(struct device *_dev,
     998                 :            :                                 struct device_attribute *attr, char *buf)
     999                 :            : {
    1000                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
    1001                 :            :         uint32_t reg_val;
    1002                 :            :         int i;
    1003                 :            :         int time;
    1004                 :            :         int start_jiffies;
    1005                 :            : 
    1006                 :          0 :         printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
    1007                 :            :                HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
    1008                 :          0 :         reg_val = dwc_otg_get_gnptxfsiz(otg_dev->core_if);
    1009                 :          0 :         start_jiffies = jiffies;
    1010                 :          0 :         for (i = 0; i < RW_REG_COUNT; i++) {
    1011                 :          0 :                 dwc_otg_set_gnptxfsiz(otg_dev->core_if, reg_val);
    1012                 :            :         }
    1013                 :          0 :         time = jiffies - start_jiffies;
    1014                 :          0 :         return sprintf(buf,
    1015                 :            :                        "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
    1016                 :          0 :                        RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
    1017                 :            : }
    1018                 :            : 
    1019                 :            : DEVICE_ATTR(wr_reg_test, S_IRUGO, wr_reg_test_show, 0);
    1020                 :            : 
    1021                 :            : #ifdef CONFIG_USB_DWC_OTG_LPM
    1022                 :            : 
    1023                 :            : /**
    1024                 :            : * Show the lpm_response attribute.
    1025                 :            : */
    1026                 :            : static ssize_t lpmresp_show(struct device *_dev,
    1027                 :            :                             struct device_attribute *attr, char *buf)
    1028                 :            : {
    1029                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
    1030                 :            : 
    1031                 :            :         if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
    1032                 :            :                 return sprintf(buf, "** LPM is DISABLED **\n");
    1033                 :            : 
    1034                 :            :         if (!dwc_otg_is_device_mode(otg_dev->core_if)) {
    1035                 :            :                 return sprintf(buf, "** Current mode is not device mode\n");
    1036                 :            :         }
    1037                 :            :         return sprintf(buf, "lpm_response = %d\n",
    1038                 :            :                        dwc_otg_get_lpmresponse(otg_dev->core_if));
    1039                 :            : }
    1040                 :            : 
    1041                 :            : /**
    1042                 :            : * Store the lpm_response attribute.
    1043                 :            : */
    1044                 :            : static ssize_t lpmresp_store(struct device *_dev,
    1045                 :            :                              struct device_attribute *attr,
    1046                 :            :                              const char *buf, size_t count)
    1047                 :            : {
    1048                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
    1049                 :            :         uint32_t val = simple_strtoul(buf, NULL, 16);
    1050                 :            : 
    1051                 :            :         if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if)) {
    1052                 :            :                 return 0;
    1053                 :            :         }
    1054                 :            : 
    1055                 :            :         if (!dwc_otg_is_device_mode(otg_dev->core_if)) {
    1056                 :            :                 return 0;
    1057                 :            :         }
    1058                 :            : 
    1059                 :            :         dwc_otg_set_lpmresponse(otg_dev->core_if, val);
    1060                 :            :         return count;
    1061                 :            : }
    1062                 :            : 
    1063                 :            : DEVICE_ATTR(lpm_response, S_IRUGO | S_IWUSR, lpmresp_show, lpmresp_store);
    1064                 :            : 
    1065                 :            : /**
    1066                 :            : * Show the sleep_status attribute.
    1067                 :            : */
    1068                 :            : static ssize_t sleepstatus_show(struct device *_dev,
    1069                 :            :                                 struct device_attribute *attr, char *buf)
    1070                 :            : {
    1071                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
    1072                 :            :         return sprintf(buf, "Sleep Status = %d\n",
    1073                 :            :                        dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if));
    1074                 :            : }
    1075                 :            : 
    1076                 :            : /**
    1077                 :            :  * Store the sleep_status attribure.
    1078                 :            :  */
    1079                 :            : static ssize_t sleepstatus_store(struct device *_dev,
    1080                 :            :                                  struct device_attribute *attr,
    1081                 :            :                                  const char *buf, size_t count)
    1082                 :            : {
    1083                 :            :         dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
    1084                 :            :         dwc_otg_core_if_t *core_if = otg_dev->core_if;
    1085                 :            : 
    1086                 :            :         if (dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if)) {
    1087                 :            :                 if (dwc_otg_is_host_mode(core_if)) {
    1088                 :            : 
    1089                 :            :                         DWC_PRINTF("Host initiated resume\n");
    1090                 :            :                         dwc_otg_set_prtresume(otg_dev->core_if, 1);
    1091                 :            :                 }
    1092                 :            :         }
    1093                 :            : 
    1094                 :            :         return count;
    1095                 :            : }
    1096                 :            : 
    1097                 :            : DEVICE_ATTR(sleep_status, S_IRUGO | S_IWUSR, sleepstatus_show,
    1098                 :            :             sleepstatus_store);
    1099                 :            : 
    1100                 :            : #endif /* CONFIG_USB_DWC_OTG_LPM_ENABLE */
    1101                 :            : 
    1102                 :            : /**@}*/
    1103                 :            : 
    1104                 :            : /**
    1105                 :            :  * Create the device files
    1106                 :            :  */
    1107                 :          3 : void dwc_otg_attr_create(
    1108                 :            : #ifdef LM_INTERFACE
    1109                 :            :         struct lm_device *dev
    1110                 :            : #elif  defined(PCI_INTERFACE)
    1111                 :            :         struct pci_dev *dev
    1112                 :            : #elif  defined(PLATFORM_INTERFACE)
    1113                 :            :         struct platform_device *dev
    1114                 :            : #endif
    1115                 :            :     )
    1116                 :            : {
    1117                 :            :         int error;
    1118                 :            : 
    1119                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_regoffset);
    1120                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_regvalue);
    1121                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_mode);
    1122                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_hnpcapable);
    1123                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_srpcapable);
    1124                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_hsic_connect);
    1125                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_inv_sel_hsic);
    1126                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_hnp);
    1127                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_srp);
    1128                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_buspower);
    1129                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_bussuspend);
    1130                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_mode_ch_tim_en);
    1131                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_fr_interval);
    1132                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_busconnected);
    1133                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_gotgctl);
    1134                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_gusbcfg);
    1135                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_grxfsiz);
    1136                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_gnptxfsiz);
    1137                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_gpvndctl);
    1138                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_ggpio);
    1139                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_guid);
    1140                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_gsnpsid);
    1141                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_devspeed);
    1142                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_enumspeed);
    1143                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_hptxfsiz);
    1144                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_hprt0);
    1145                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_remote_wakeup);
    1146                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn);
    1147                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_disconnect_us);
    1148                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_regdump);
    1149                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_spramdump);
    1150                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_hcddump);
    1151                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_hcd_frrem);
    1152                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_rd_reg_test);
    1153                 :          3 :         error = device_create_file(&dev->dev, &dev_attr_wr_reg_test);
    1154                 :            : #ifdef CONFIG_USB_DWC_OTG_LPM
    1155                 :            :         error = device_create_file(&dev->dev, &dev_attr_lpm_response);
    1156                 :            :         error = device_create_file(&dev->dev, &dev_attr_sleep_status);
    1157                 :            : #endif
    1158                 :          3 : }
    1159                 :            : 
    1160                 :            : /**
    1161                 :            :  * Remove the device files
    1162                 :            :  */
    1163                 :          0 : void dwc_otg_attr_remove(
    1164                 :            : #ifdef LM_INTERFACE
    1165                 :            :         struct lm_device *dev
    1166                 :            : #elif  defined(PCI_INTERFACE)
    1167                 :            :         struct pci_dev *dev
    1168                 :            : #elif  defined(PLATFORM_INTERFACE)
    1169                 :            :         struct platform_device *dev
    1170                 :            : #endif
    1171                 :            :     )
    1172                 :            : {
    1173                 :          0 :         device_remove_file(&dev->dev, &dev_attr_regoffset);
    1174                 :          0 :         device_remove_file(&dev->dev, &dev_attr_regvalue);
    1175                 :          0 :         device_remove_file(&dev->dev, &dev_attr_mode);
    1176                 :          0 :         device_remove_file(&dev->dev, &dev_attr_hnpcapable);
    1177                 :          0 :         device_remove_file(&dev->dev, &dev_attr_srpcapable);
    1178                 :          0 :         device_remove_file(&dev->dev, &dev_attr_hsic_connect);
    1179                 :          0 :         device_remove_file(&dev->dev, &dev_attr_inv_sel_hsic);
    1180                 :          0 :         device_remove_file(&dev->dev, &dev_attr_hnp);
    1181                 :          0 :         device_remove_file(&dev->dev, &dev_attr_srp);
    1182                 :          0 :         device_remove_file(&dev->dev, &dev_attr_buspower);
    1183                 :          0 :         device_remove_file(&dev->dev, &dev_attr_bussuspend);
    1184                 :          0 :         device_remove_file(&dev->dev, &dev_attr_mode_ch_tim_en);
    1185                 :          0 :         device_remove_file(&dev->dev, &dev_attr_fr_interval);
    1186                 :          0 :         device_remove_file(&dev->dev, &dev_attr_busconnected);
    1187                 :          0 :         device_remove_file(&dev->dev, &dev_attr_gotgctl);
    1188                 :          0 :         device_remove_file(&dev->dev, &dev_attr_gusbcfg);
    1189                 :          0 :         device_remove_file(&dev->dev, &dev_attr_grxfsiz);
    1190                 :          0 :         device_remove_file(&dev->dev, &dev_attr_gnptxfsiz);
    1191                 :          0 :         device_remove_file(&dev->dev, &dev_attr_gpvndctl);
    1192                 :          0 :         device_remove_file(&dev->dev, &dev_attr_ggpio);
    1193                 :          0 :         device_remove_file(&dev->dev, &dev_attr_guid);
    1194                 :          0 :         device_remove_file(&dev->dev, &dev_attr_gsnpsid);
    1195                 :          0 :         device_remove_file(&dev->dev, &dev_attr_devspeed);
    1196                 :          0 :         device_remove_file(&dev->dev, &dev_attr_enumspeed);
    1197                 :          0 :         device_remove_file(&dev->dev, &dev_attr_hptxfsiz);
    1198                 :          0 :         device_remove_file(&dev->dev, &dev_attr_hprt0);
    1199                 :          0 :         device_remove_file(&dev->dev, &dev_attr_remote_wakeup);
    1200                 :          0 :         device_remove_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn);
    1201                 :          0 :         device_remove_file(&dev->dev, &dev_attr_disconnect_us);
    1202                 :          0 :         device_remove_file(&dev->dev, &dev_attr_regdump);
    1203                 :          0 :         device_remove_file(&dev->dev, &dev_attr_spramdump);
    1204                 :          0 :         device_remove_file(&dev->dev, &dev_attr_hcddump);
    1205                 :          0 :         device_remove_file(&dev->dev, &dev_attr_hcd_frrem);
    1206                 :          0 :         device_remove_file(&dev->dev, &dev_attr_rd_reg_test);
    1207                 :          0 :         device_remove_file(&dev->dev, &dev_attr_wr_reg_test);
    1208                 :            : #ifdef CONFIG_USB_DWC_OTG_LPM
    1209                 :            :         device_remove_file(&dev->dev, &dev_attr_lpm_response);
    1210                 :            :         device_remove_file(&dev->dev, &dev_attr_sleep_status);
    1211                 :            : #endif
    1212                 :          0 : }
    

Generated by: LCOV version 1.14