hidg: support boot protocol
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg / dwc_otg_attr.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_attr.c $
3  * $Revision: #5 $
4  * $Date: 2005/09/15 $
5  * $Change: 537387 $
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
50  The following table shows the attributes.
51  <table>
52  <tr>
53  <td><b> Name</b></td>
54  <td><b> Description</b></td>
55  <td><b> Access</b></td>
56  </tr>
57  
58  <tr>
59  <td> mode </td>
60  <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
61  <td> Read</td>
62  </tr>
63  
64  <tr>
65  <td> hnpcapable </td>
66  <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
67  Read returns the current value.</td>
68  <td> Read/Write</td>
69  </tr>
70  
71  <tr>
72  <td> srpcapable </td>
73  <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
74  Read returns the current value.</td>
75  <td> Read/Write</td>
76  </tr>
77  
78  <tr>
79  <td> hnp </td>
80  <td> Initiates the Host Negotiation Protocol.  Read returns the status.</td>
81  <td> Read/Write</td>
82  </tr>
83  
84  <tr>
85  <td> srp </td>
86  <td> Initiates the Session Request Protocol.  Read returns the status.</td>
87  <td> Read/Write</td>
88  </tr>
89  
90  <tr>
91  <td> buspower </td>
92  <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
93  <td> Read/Write</td>
94  </tr>
95  
96  <tr>
97  <td> bussuspend </td>
98  <td> Suspends the USB bus.</td>
99  <td> Read/Write</td>
100  </tr>
101  
102  <tr>
103  <td> busconnected </td>
104  <td> Gets the connection status of the bus</td>
105  <td> Read</td>
106  </tr>
107  
108  <tr>
109  <td> gotgctl </td>
110  <td> Gets or sets the Core Control Status Register.</td>
111  <td> Read/Write</td>
112  </tr>
113  
114  <tr>
115  <td> gusbcfg </td>
116  <td> Gets or sets the Core USB Configuration Register</td>
117  <td> Read/Write</td>
118  </tr>
119  
120  <tr>
121  <td> grxfsiz </td>
122  <td> Gets or sets the Receive FIFO Size Register</td>
123  <td> Read/Write</td>
124  </tr>
125  
126  <tr>
127  <td> gnptxfsiz </td>
128  <td> Gets or sets the non-periodic Transmit Size Register</td>
129  <td> Read/Write</td>
130  </tr>
131  
132  <tr>
133  <td> gpvndctl </td>
134  <td> Gets or sets the PHY Vendor Control Register</td>
135  <td> Read/Write</td>
136  </tr>
137  
138  <tr>
139  <td> ggpio </td>
140  <td> Gets the value in the lower 16-bits of the General Purpose IO Register
141  or sets the upper 16 bits.</td>
142  <td> Read/Write</td>
143  </tr>
144  
145  <tr>
146  <td> guid </td>
147  <td> Gets or sets the value of the User ID Register</td>
148  <td> Read/Write</td>
149  </tr>
150  
151  <tr>
152  <td> gsnpsid </td>
153  <td> Gets the value of the Synopsys ID Regester</td>
154  <td> Read</td>
155  </tr>
156  
157  <tr>
158  <td> devspeed </td>
159  <td> Gets or sets the device speed setting in the DCFG register</td>
160  <td> Read/Write</td>
161  </tr>
162  
163  <tr>
164  <td> enumspeed </td>
165  <td> Gets the device enumeration Speed.</td>
166  <td> Read</td>
167  </tr>
168  
169  <tr>
170  <td> hptxfsiz </td>
171  <td> Gets the value of the Host Periodic Transmit FIFO</td>
172  <td> Read</td>
173  </tr>
174  
175  <tr>
176  <td> hprt0 </td>
177  <td> Gets or sets the value in the Host Port Control and Status Register</td>
178  <td> Read/Write</td>
179  </tr>
180  
181  <tr>
182  <td> regoffset </td>
183  <td> Sets the register offset for the next Register Access</td>
184  <td> Read/Write</td>
185  </tr>
186  
187  <tr>
188  <td> regvalue </td>
189  <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
190  <td> Read/Write</td>
191  </tr>
192  
193  <tr>
194  <td> remote_wakeup </td>
195  <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
196  wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
197  Wakeup signalling bit in the Device Control Register is set for 1
198  milli-second.</td>
199  <td> Read/Write</td>
200  </tr>
201  
202  <tr>
203  <td> regdump </td>
204  <td> Dumps the contents of core registers.</td>
205  <td> Read</td>
206  </tr>
207  
208  <tr>
209  <td> hcddump </td>
210  <td> Dumps the current HCD state.</td>
211  <td> Read</td>
212  </tr>
213  
214  <tr>
215  <td> hcd_frrem </td>
216  <td> Shows the average value of the Frame Remaining
217  field in the Host Frame Number/Frame Remaining register when an SOF interrupt
218  occurs. This can be used to determine the average interrupt latency. Also
219  shows the average Frame Remaining value for start_transfer and the "a" and
220  "b" sample points. The "a" and "b" sample points may be used during debugging
221  bto determine how long it takes to execute a section of the HCD code.</td>
222  <td> Read</td>
223  </tr>
224  
225  <tr>
226  <td> rd_reg_test </td>
227  <td> Displays the time required to read the GNPTXFSIZ register many times
228  (the output shows the number of times the register is read).
229  <td> Read</td>
230  </tr>
231  
232  <tr>
233  <td> wr_reg_test </td>
234  <td> Displays the time required to write the GNPTXFSIZ register many times
235  (the output shows the number of times the register is written).
236  <td> Read</td>
237  </tr>
238  
239  </table>
240  
241  Example usage:
242  To get the current mode:
243  cat /sys/devices/lm0/mode
244  
245  To power down the USB:
246  echo 0 > /sys/devices/lm0/buspower
247  */
248
249 #include <linux/kernel.h>
250 #include <linux/module.h>
251 #include <linux/moduleparam.h>
252 #include <linux/init.h>
253 #include <linux/device.h>
254 #include <linux/errno.h>
255 #include <linux/types.h>
256 #include <linux/stat.h>  /* permission constants */
257
258 #include <asm/sizes.h>
259 #include <asm/io.h>
260
261 #include "linux/dwc_otg_plat.h"
262 #include "dwc_otg_attr.h"
263 #include "dwc_otg_driver.h"
264 #include "dwc_otg_pcd.h"
265 #include "dwc_otg_hcd.h"
266
267 /*
268  * MACROs for defining sysfs attribute
269  */
270 #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
271 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
272 { \
273     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));\
274         uint32_t val; \
275         val = dwc_read_reg32 (_addr_); \
276         val = (val & (_mask_)) >> _shift_; \
277         return sprintf (buf, "%s = 0x%x\n", _string_, val); \
278 }
279 #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
280 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \
281 { \
282     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));\
283         uint32_t set = simple_strtoul(buf, NULL, 16); \
284         uint32_t clear = set; \
285         clear = ((~clear) << _shift_) & _mask_; \
286         set = (set << _shift_) & _mask_; \
287         dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
288         dwc_modify_reg32(_addr_, clear, set); \
289         return count; \
290 }
291
292 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
293 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
294 DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
295 DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
296
297 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
298 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
299 DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
300
301 /*
302  * MACROs for defining sysfs attribute for 32-bit registers
303  */
304 #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
305 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
306 { \
307     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));\
308         uint32_t val; \
309         val = dwc_read_reg32 (_addr_); \
310         return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
311 }
312 #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
313 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \
314 { \
315     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));\
316         uint32_t val = simple_strtoul(buf, NULL, 16); \
317         dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \
318         dwc_write_reg32(_addr_, val); \
319         return count; \
320 }
321
322 #define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
323 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
324 DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
325 DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
326
327 #define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
328 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
329 DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
330
331
332 /** @name Functions for Show/Store of Attributes */
333 /**@{*/
334
335 /**
336  * Show the register offset of the Register Access.
337  */
338 static ssize_t regoffset_show( struct device *_dev,
339                                                         struct device_attribute *attr, char *buf) 
340 {
341     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
342         
343         return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset);
344 }
345
346 /**
347  * Set the register offset for the next Register Access         Read/Write
348  */
349 static ssize_t regoffset_store( struct device *_dev, struct device_attribute *attr,
350                                                         const char *buf, size_t count ) 
351 {
352     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
353         uint32_t offset = simple_strtoul(buf, NULL, 16);
354         //dev_dbg(_dev, "Offset=0x%08x\n", offset);
355         if (offset < SZ_256K ) {
356                 otg_dev->reg_offset = offset;
357         }
358         else {
359                 dev_err( _dev, "invalid offset\n" );
360         }
361
362         return count;
363 }
364 DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, regoffset_show, regoffset_store);
365
366
367 /**
368  * Show the value of the register at the offset in the reg_offset
369  * attribute.
370  */
371 static ssize_t regvalue_show( struct device *_dev,
372                                                                 struct device_attribute *attr, char *buf) 
373 {
374         dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
375         uint32_t val;
376         volatile uint32_t *addr;
377         
378         if (otg_dev->reg_offset != 0xFFFFFFFF && 
379             0 != otg_dev->base) {
380                 /* Calculate the address */
381                 addr = (uint32_t*)(otg_dev->reg_offset + 
382                                    (uint8_t*)otg_dev->base);
383                 //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr); 
384                 val = dwc_read_reg32( addr );             
385                 return snprintf(buf, sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n")+1,
386                                 "Reg@0x%06x = 0x%08x\n", 
387                                 otg_dev->reg_offset, val);
388         }
389         else {
390                 dev_err(_dev, "Invalid offset (0x%0x)\n", 
391                         otg_dev->reg_offset);
392                 return sprintf(buf, "invalid offset\n" );
393         }
394 }
395
396 /**
397  * Store the value in the register at the offset in the reg_offset
398  * attribute.
399  * 
400  */
401 static ssize_t regvalue_store( struct device *_dev,
402                                                                 struct device_attribute *attr, 
403                                                                 const char *buf,  size_t count ) 
404 {
405     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
406         volatile uint32_t * addr;
407         uint32_t val = simple_strtoul(buf, NULL, 16);
408         //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
409         if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
410                 /* Calculate the address */
411                 addr = (uint32_t*)(otg_dev->reg_offset + 
412                                    (uint8_t*)otg_dev->base);
413                 //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr); 
414                 dwc_write_reg32( addr, val );
415         }
416         else {
417                 dev_err(_dev, "Invalid Register Offset (0x%08x)\n", 
418                         otg_dev->reg_offset);
419         }
420         return count;
421 }
422 DEVICE_ATTR(regvalue,  S_IRUGO|S_IWUSR, regvalue_show, regvalue_store);
423
424 /*
425  * Attributes
426  */
427 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<20),20,"Mode");
428 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<9),9,"Mode");
429 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<8),8,"Mode");
430
431 //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
432 //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
433 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected,otg_dev->core_if->host_if->hprt0,0x01,0,"Bus Connected");
434
435 DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,&(otg_dev->core_if->core_global_regs->gotgctl),"GOTGCTL");
436 DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,&(otg_dev->core_if->core_global_regs->gusbcfg),"GUSBCFG");
437 DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,&(otg_dev->core_if->core_global_regs->grxfsiz),"GRXFSIZ");
438 DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,&(otg_dev->core_if->core_global_regs->gnptxfsiz),"GNPTXFSIZ");
439 DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,&(otg_dev->core_if->core_global_regs->gpvndctl),"GPVNDCTL");
440 DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,&(otg_dev->core_if->core_global_regs->ggpio),"GGPIO");
441 DWC_OTG_DEVICE_ATTR_REG32_RW(guid,&(otg_dev->core_if->core_global_regs->guid),"GUID");
442 DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,&(otg_dev->core_if->core_global_regs->gsnpsid),"GSNPSID");
443 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dcfg),0x3,0,"Device Speed");
444 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dsts),0x6,1,"Device Enumeration Speed");
445
446 DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,&(otg_dev->core_if->core_global_regs->hptxfsiz),"HPTXFSIZ");
447 DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0");
448
449
450 /**
451  * @todo Add code to initiate the HNP.
452  */
453 /**
454  * Show the HNP status bit
455  */
456 static ssize_t hnp_show( struct device *_dev,
457                                                                 struct device_attribute *attr,  char *buf) 
458 {
459     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
460         gotgctl_data_t val;
461         val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
462         return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
463 }
464
465 /**
466  * Set the HNP Request bit
467  */
468 static ssize_t hnp_store( struct device *_dev,
469                                                                 struct device_attribute *attr, 
470                                                                 const char *buf, size_t count ) 
471 {
472     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
473         uint32_t in = simple_strtoul(buf, NULL, 16);
474         uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl);
475         gotgctl_data_t mem;
476         mem.d32 = dwc_read_reg32(addr);
477         mem.b.hnpreq = in;
478         dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
479         dwc_write_reg32(addr, mem.d32);
480         return count;
481 }
482 DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
483
484 /**
485  * @todo Add code to initiate the SRP.
486  */
487 /**
488  * Show the SRP status bit
489  */
490 static ssize_t srp_show( struct device *_dev,
491                                                                 struct device_attribute *attr,  char *buf) 
492 {
493 #ifndef DWC_HOST_ONLY
494     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
495         gotgctl_data_t val;
496         val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
497         return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
498 #else
499         return sprintf(buf, "Host Only Mode!\n");
500 #endif
501 }
502
503
504
505 /**
506  * Set the SRP Request bit
507  */
508 static ssize_t srp_store( struct device *_dev,
509                                                                 struct device_attribute *attr, 
510                                                                 const char *buf, size_t count ) 
511 {
512 #ifndef DWC_HOST_ONLY
513     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
514         dwc_otg_pcd_initiate_srp(otg_dev->pcd);
515 #endif
516         return count;
517 }
518 DEVICE_ATTR(srp, 0644, srp_show, srp_store);
519
520 /**
521  * @todo Need to do more for power on/off?
522  */
523 /**
524  * Show the Bus Power status
525  */
526 static ssize_t buspower_show( struct device *_dev,
527                                                                 struct device_attribute *attr,  char *buf) 
528 {
529     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
530         hprt0_data_t val;
531         val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
532         return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr);
533 }
534
535
536 /**
537  * Set the Bus Power status
538  */
539 static ssize_t buspower_store( struct device *_dev,
540                                                                 struct device_attribute *attr, 
541                                                                 const char *buf, size_t count ) 
542 {
543     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
544         uint32_t on = simple_strtoul(buf, NULL, 16);
545         uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
546         hprt0_data_t mem;
547
548         mem.d32 = dwc_read_reg32(addr);
549         mem.b.prtpwr = on;
550
551         //dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
552         dwc_write_reg32(addr, mem.d32);
553
554         return count;
555 }
556 DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
557
558 /**
559  * @todo Need to do more for suspend?
560  */
561 /**
562  * Show the Bus Suspend status
563  */
564 static ssize_t bussuspend_show( struct device *_dev,
565                                                                 struct device_attribute *attr,  char *buf) 
566 {
567     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
568         hprt0_data_t val;
569         val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
570         return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
571 }
572
573 /**
574  * Set the Bus Suspend status
575  */
576 static ssize_t bussuspend_store( struct device *_dev,
577                                                                 struct device_attribute *attr, 
578                                                                 const char *buf, size_t count ) 
579 {
580     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
581         uint32_t in = simple_strtoul(buf, NULL, 16);
582         uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
583         hprt0_data_t mem;
584         mem.d32 = dwc_read_reg32(addr);
585         mem.b.prtsusp = in;
586         dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
587         dwc_write_reg32(addr, mem.d32);
588         return count;
589 }
590 DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
591
592 /**
593  * Show the status of Remote Wakeup.
594  */
595 static ssize_t remote_wakeup_show( struct device *_dev, 
596                                                                                 struct device_attribute *attr,char *buf) 
597 {
598 #ifndef DWC_HOST_ONLY
599         dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
600         dctl_data_t val;
601         val.d32 = 
602                 dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl);
603         return sprintf( buf, "Remote Wakeup = %d Enabled = %d\n", 
604                         val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable);
605 #else
606         return sprintf(buf, "Host Only Mode!\n");
607 #endif
608 }
609 /**
610  * Initiate a remote wakeup of the host.  The Device control register
611  * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
612  * flag is set.
613  * 
614  */
615 static ssize_t remote_wakeup_store( struct device *_dev, 
616                                                 struct device_attribute *attr,
617                                                 const char *buf,  size_t count ) 
618 {
619 #ifndef DWC_HOST_ONLY
620     uint32_t val = simple_strtoul(buf, NULL, 16);        
621         dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
622         if (val&1) {
623                 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
624         }
625         else {
626                 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
627         }
628 #endif
629         return count;
630 }
631 static DEVICE_ATTR(remote_wakeup,  S_IRUGO|S_IWUSR, remote_wakeup_show, 
632             remote_wakeup_store);
633
634 /**
635  * Dump global registers and either host or device registers (depending on the
636  * current mode of the core).
637  */
638 static ssize_t regdump_show( struct device *_dev, 
639                                                                 struct device_attribute *attr, char *buf) 
640 {
641         dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
642         dwc_otg_dump_global_registers( otg_dev->core_if);
643         if (dwc_otg_is_host_mode(otg_dev->core_if)) {
644                 dwc_otg_dump_host_registers( otg_dev->core_if);
645         } else {
646                 dwc_otg_dump_dev_registers( otg_dev->core_if);
647         }
648         return sprintf( buf, "Register Dump\n" );
649 }
650
651 DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0);
652
653 /**
654  * Dump the current hcd state.
655  */
656 static ssize_t hcddump_show( struct device *_dev, 
657                                                                 struct device_attribute *attr, char *buf) 
658 {
659 #ifndef DWC_DEVICE_ONLY
660         dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
661         dwc_otg_hcd_dump_state(otg_dev->hcd);
662 #endif
663         return sprintf( buf, "HCD Dump\n" );
664 }
665
666 DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0);
667
668 /**
669  * Dump the average frame remaining at SOF. This can be used to
670  * determine average interrupt latency. Frame remaining is also shown for
671  * start transfer and two additional sample points.
672  */
673 static ssize_t hcd_frrem_show( struct device *_dev,
674                                                                 struct device_attribute *attr,  char *buf) 
675 {
676 #ifndef DWC_DEVICE_ONLY
677         dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
678         dwc_otg_hcd_dump_frrem(otg_dev->hcd);
679 #endif
680         return sprintf( buf, "HCD Dump Frame Remaining\n" );
681 }
682
683 DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0);
684
685 /**
686  * Displays the time required to read the GNPTXFSIZ register many times (the
687  * output shows the number of times the register is read).
688  */
689 #define RW_REG_COUNT 10000000
690 #define MSEC_PER_JIFFIE 1000/HZ 
691 static ssize_t rd_reg_test_show( struct device *_dev, 
692                                                                 struct device_attribute *attr, char *buf) 
693 {
694         int i;
695         int time;
696         int start_jiffies;
697     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
698
699         DWC_PRINT("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
700                HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
701         start_jiffies = jiffies;
702         for (i = 0; i < RW_REG_COUNT; i++) {
703                 dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
704         }
705         time = jiffies - start_jiffies;
706         return sprintf( buf, "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
707                         RW_REG_COUNT, time * MSEC_PER_JIFFIE, time );
708 }
709
710 DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0);
711
712 /**
713  * Displays the time required to write the GNPTXFSIZ register many times (the
714  * output shows the number of times the register is written).
715  */
716 static ssize_t wr_reg_test_show( struct device *_dev, 
717                                                                 struct device_attribute *attr, char *buf) 
718 {
719         int i;
720         int time;
721         int start_jiffies;
722     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
723         uint32_t reg_val;
724
725         DWC_PRINT("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
726                HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
727         reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
728         start_jiffies = jiffies;
729         for (i = 0; i < RW_REG_COUNT; i++) {
730                 dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz, reg_val);
731         }
732         time = jiffies - start_jiffies;
733         return sprintf( buf, "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
734                         RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
735 }
736
737 DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
738 extern int dwc_debug(dwc_otg_core_if_t *core_if, int flag);
739
740 static ssize_t debug_show( struct device *_dev, 
741                                                                 struct device_attribute *attr, char *buf) 
742 {
743     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
744     dwc_otg_dump_global_registers( otg_dev->core_if);
745     if (dwc_otg_is_host_mode(otg_dev->core_if)) {
746             dwc_otg_dump_host_registers( otg_dev->core_if);
747     } else {
748             dwc_otg_dump_dev_registers( otg_dev->core_if);
749     }
750         return sprintf( buf, "Register Dump\n" );
751 }
752 static ssize_t debug_store( struct device *_dev,
753                                                                 struct device_attribute *attr, 
754                                                                 const char *buf, size_t count ) 
755 {
756         uint32_t val = simple_strtoul(buf, NULL, 16);
757     dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));
758     dwc_otg_dump_global_registers( otg_dev->core_if);
759     dwc_debug(otg_dev->core_if,val);
760         return count;
761 }
762
763 DEVICE_ATTR(debug, S_IRUGO|S_IWUSR, debug_show, debug_store);
764
765
766 /**@}*/
767
768 /**
769  * Create the device files
770  */
771 void dwc_otg_attr_create (struct device *dev)
772 {
773         int error;
774         error = device_create_file(dev, &dev_attr_regoffset);
775         error |= device_create_file(dev, &dev_attr_regvalue);
776         error |= device_create_file(dev, &dev_attr_mode);
777         error |= device_create_file(dev, &dev_attr_hnpcapable);
778         error |= device_create_file(dev, &dev_attr_srpcapable);
779         error |= device_create_file(dev, &dev_attr_hnp);
780         error |= device_create_file(dev, &dev_attr_srp);
781         error |= device_create_file(dev, &dev_attr_buspower);
782         error |= device_create_file(dev, &dev_attr_bussuspend);
783         error |= device_create_file(dev, &dev_attr_busconnected);
784         error |= device_create_file(dev, &dev_attr_gotgctl);
785         error |= device_create_file(dev, &dev_attr_gusbcfg);
786         error |= device_create_file(dev, &dev_attr_grxfsiz);
787         error |= device_create_file(dev, &dev_attr_gnptxfsiz);
788         error |= device_create_file(dev, &dev_attr_gpvndctl);
789         error |= device_create_file(dev, &dev_attr_ggpio);
790         error |= device_create_file(dev, &dev_attr_guid);
791         error |= device_create_file(dev, &dev_attr_gsnpsid);
792         error |= device_create_file(dev, &dev_attr_devspeed);
793         error |= device_create_file(dev, &dev_attr_enumspeed);
794         error |= device_create_file(dev, &dev_attr_hptxfsiz);
795         error |= device_create_file(dev, &dev_attr_hprt0);
796         error |= device_create_file(dev, &dev_attr_remote_wakeup);
797         error |= device_create_file(dev, &dev_attr_regdump);
798         error |= device_create_file(dev, &dev_attr_hcddump);
799         error |= device_create_file(dev, &dev_attr_hcd_frrem);
800         error |= device_create_file(dev, &dev_attr_rd_reg_test);
801         error |= device_create_file(dev, &dev_attr_wr_reg_test);
802         error |= device_create_file(dev, &dev_attr_debug);
803         if (error)
804                 pr_err("DWC_OTG: Creating some device files failed\n");
805 }
806
807 /**
808  * Remove the device files
809  */
810 void dwc_otg_attr_remove (struct device *dev)
811 {
812         device_remove_file(dev, &dev_attr_regoffset);
813         device_remove_file(dev, &dev_attr_regvalue);
814         device_remove_file(dev, &dev_attr_mode);
815         device_remove_file(dev, &dev_attr_hnpcapable);
816         device_remove_file(dev, &dev_attr_srpcapable);
817         device_remove_file(dev, &dev_attr_hnp);
818         device_remove_file(dev, &dev_attr_srp);
819         device_remove_file(dev, &dev_attr_buspower);
820         device_remove_file(dev, &dev_attr_bussuspend);
821         device_remove_file(dev, &dev_attr_busconnected);
822         device_remove_file(dev, &dev_attr_gotgctl);
823         device_remove_file(dev, &dev_attr_gusbcfg);
824         device_remove_file(dev, &dev_attr_grxfsiz);
825         device_remove_file(dev, &dev_attr_gnptxfsiz);
826         device_remove_file(dev, &dev_attr_gpvndctl);
827         device_remove_file(dev, &dev_attr_ggpio);
828         device_remove_file(dev, &dev_attr_guid);
829         device_remove_file(dev, &dev_attr_gsnpsid);
830         device_remove_file(dev, &dev_attr_devspeed);
831         device_remove_file(dev, &dev_attr_enumspeed);
832         device_remove_file(dev, &dev_attr_hptxfsiz);
833         device_remove_file(dev, &dev_attr_hprt0);
834         device_remove_file(dev, &dev_attr_remote_wakeup);
835         device_remove_file(dev, &dev_attr_regdump);
836         device_remove_file(dev, &dev_attr_hcddump);
837         device_remove_file(dev, &dev_attr_hcd_frrem);
838         device_remove_file(dev, &dev_attr_rd_reg_test);
839         device_remove_file(dev, &dev_attr_wr_reg_test);
840         device_remove_file(dev, &dev_attr_debug);
841 }