[ramips] add feature gpio
[15.05/openwrt.git] / target / linux / ramips / files / drivers / usb / dwc_otg / dwc_otg_attr.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
3  * $Revision: 1.2 $
4  * $Date: 2008-11-21 05:39:15 $
5  * $Change: 1064918 $
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> spramdump </td>
210  <td> Dumps the contents of core registers.</td>
211  <td> Read</td>
212  </tr>
213
214  <tr>
215  <td> hcddump </td>
216  <td> Dumps the current HCD state.</td>
217  <td> Read</td>
218  </tr>
219
220  <tr>
221  <td> hcd_frrem </td>
222  <td> Shows the average value of the Frame Remaining
223  field in the Host Frame Number/Frame Remaining register when an SOF interrupt
224  occurs. This can be used to determine the average interrupt latency. Also
225  shows the average Frame Remaining value for start_transfer and the "a" and
226  "b" sample points. The "a" and "b" sample points may be used during debugging
227  bto determine how long it takes to execute a section of the HCD code.</td>
228  <td> Read</td>
229  </tr>
230
231  <tr>
232  <td> rd_reg_test </td>
233  <td> Displays the time required to read the GNPTXFSIZ register many times
234  (the output shows the number of times the register is read).
235  <td> Read</td>
236  </tr>
237
238  <tr>
239  <td> wr_reg_test </td>
240  <td> Displays the time required to write the GNPTXFSIZ register many times
241  (the output shows the number of times the register is written).
242  <td> Read</td>
243  </tr>
244
245  </table>
246
247  Example usage:
248  To get the current mode:
249  cat /sys/devices/lm0/mode
250
251  To power down the USB:
252  echo 0 > /sys/devices/lm0/buspower
253  */
254
255 #include <linux/kernel.h>
256 #include <linux/module.h>
257 #include <linux/moduleparam.h>
258 #include <linux/init.h>
259 #include <linux/device.h>
260 #include <linux/errno.h>
261 #include <linux/types.h>
262 #include <linux/stat.h>  /* permission constants */
263 #include <linux/version.h>
264
265 #include <asm/io.h>
266
267 #include "linux/dwc_otg_plat.h"
268 #include "dwc_otg_attr.h"
269 #include "dwc_otg_driver.h"
270 #include "dwc_otg_pcd.h"
271 #include "dwc_otg_hcd.h"
272
273 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
274 /*
275  * MACROs for defining sysfs attribute
276  */
277 #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
278 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
279 { \
280         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);              \
281         uint32_t val; \
282         val = dwc_read_reg32 (_addr_); \
283         val = (val & (_mask_)) >> _shift_; \
284         return sprintf (buf, "%s = 0x%x\n", _string_, val); \
285 }
286 #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
287 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
288                                         const char *buf, size_t count) \
289 { \
290         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
291         uint32_t set = simple_strtoul(buf, NULL, 16); \
292         uint32_t clear = set; \
293         clear = ((~clear) << _shift_) & _mask_; \
294         set = (set << _shift_) & _mask_; \
295         dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
296         dwc_modify_reg32(_addr_, clear, set); \
297         return count; \
298 }
299
300 /*
301  * MACROs for defining sysfs attribute for 32-bit registers
302  */
303 #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
304 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
305 { \
306         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
307         uint32_t val; \
308         val = dwc_read_reg32 (_addr_); \
309         return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
310 }
311 #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
312 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
313                                         const char *buf, size_t count) \
314 { \
315         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
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 #else
323
324 /*
325  * MACROs for defining sysfs attribute
326  */
327 #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
328 static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \
329 { \
330         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
331         uint32_t val; \
332         val = dwc_read_reg32 (_addr_); \
333         val = (val & (_mask_)) >> _shift_; \
334         return sprintf (buf, "%s = 0x%x\n", _string_, val); \
335 }
336 #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
337 static ssize_t _otg_attr_name_##_store (struct device *_dev, const char *buf, size_t count) \
338 { \
339         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
340         uint32_t set = simple_strtoul(buf, NULL, 16); \
341         uint32_t clear = set; \
342         clear = ((~clear) << _shift_) & _mask_; \
343         set = (set << _shift_) & _mask_; \
344         dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
345         dwc_modify_reg32(_addr_, clear, set); \
346         return count; \
347 }
348
349 /*
350  * MACROs for defining sysfs attribute for 32-bit registers
351  */
352 #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
353 static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \
354 { \
355         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
356         uint32_t val; \
357         val = dwc_read_reg32 (_addr_); \
358         return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
359 }
360 #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
361 static ssize_t _otg_attr_name_##_store (struct device *_dev, const char *buf, size_t count) \
362 { \
363         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
364         uint32_t val = simple_strtoul(buf, NULL, 16); \
365         dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \
366         dwc_write_reg32(_addr_, val); \
367         return count; \
368 }
369
370 #endif
371
372 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
373 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
374 DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
375 DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
376
377 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
378 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
379 DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
380
381 #define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
382 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
383 DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
384 DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
385
386 #define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
387 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
388 DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
389
390
391 /** @name Functions for Show/Store of Attributes */
392 /**@{*/
393
394 /**
395  * Show the register offset of the Register Access.
396  */
397 static ssize_t regoffset_show( struct device *_dev,
398 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
399                                struct device_attribute *attr,
400 #endif
401                                char *buf)
402 {
403         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
404         return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset);
405 }
406
407 /**
408  * Set the register offset for the next Register Access         Read/Write
409  */
410 static ssize_t regoffset_store( struct device *_dev,
411 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
412                                 struct device_attribute *attr,
413 #endif
414                                 const char *buf,
415                                 size_t count )
416 {
417         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
418
419         uint32_t offset = simple_strtoul(buf, NULL, 16);
420         //dev_dbg(_dev, "Offset=0x%08x\n", offset);
421         if (offset < 0x00040000 ) {
422                 otg_dev->reg_offset = offset;
423         }
424         else {
425                 dev_err( _dev, "invalid offset\n" );
426         }
427
428         return count;
429 }
430 DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, (void *)regoffset_show, regoffset_store);
431
432
433 /**
434  * Show the value of the register at the offset in the reg_offset
435  * attribute.
436  */
437 static ssize_t regvalue_show( struct device *_dev,
438 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
439                               struct device_attribute *attr,
440 #endif
441                               char *buf)
442 {
443         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
444
445         uint32_t val;
446         volatile uint32_t *addr;
447
448         if (otg_dev->reg_offset != 0xFFFFFFFF &&
449             0 != otg_dev->base) {
450                 /* Calculate the address */
451                 addr = (uint32_t*)(otg_dev->reg_offset +
452                                    (uint8_t*)otg_dev->base);
453                 //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
454                 val = dwc_read_reg32( addr );
455                 return snprintf(buf, sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n")+1,
456                                 "Reg@0x%06x = 0x%08x\n",
457                                 otg_dev->reg_offset, val);
458         }
459         else {
460                 dev_err(_dev, "Invalid offset (0x%0x)\n",
461                         otg_dev->reg_offset);
462                 return sprintf(buf, "invalid offset\n" );
463         }
464 }
465
466 /**
467  * Store the value in the register at the offset in the reg_offset
468  * attribute.
469  *
470  */
471 static ssize_t regvalue_store( struct device *_dev,
472 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
473                                struct device_attribute *attr,
474 #endif
475                                const char *buf,
476                                size_t count )
477 {
478         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
479
480         volatile uint32_t * addr;
481         uint32_t val = simple_strtoul(buf, NULL, 16);
482         //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
483         if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
484                 /* Calculate the address */
485                 addr = (uint32_t*)(otg_dev->reg_offset +
486                                    (uint8_t*)otg_dev->base);
487                 //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
488                 dwc_write_reg32( addr, val );
489         }
490         else {
491                 dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
492                         otg_dev->reg_offset);
493         }
494         return count;
495 }
496 DEVICE_ATTR(regvalue,  S_IRUGO|S_IWUSR, regvalue_show, regvalue_store);
497
498 /*
499  * Attributes
500  */
501 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<20),20,"Mode");
502 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<9),9,"Mode");
503 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<8),8,"Mode");
504
505 //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
506 //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
507 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected,otg_dev->core_if->host_if->hprt0,0x01,0,"Bus Connected");
508
509 DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,&(otg_dev->core_if->core_global_regs->gotgctl),"GOTGCTL");
510 DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,&(otg_dev->core_if->core_global_regs->gusbcfg),"GUSBCFG");
511 DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,&(otg_dev->core_if->core_global_regs->grxfsiz),"GRXFSIZ");
512 DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,&(otg_dev->core_if->core_global_regs->gnptxfsiz),"GNPTXFSIZ");
513 DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,&(otg_dev->core_if->core_global_regs->gpvndctl),"GPVNDCTL");
514 DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,&(otg_dev->core_if->core_global_regs->ggpio),"GGPIO");
515 DWC_OTG_DEVICE_ATTR_REG32_RW(guid,&(otg_dev->core_if->core_global_regs->guid),"GUID");
516 DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,&(otg_dev->core_if->core_global_regs->gsnpsid),"GSNPSID");
517 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dcfg),0x3,0,"Device Speed");
518 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dsts),0x6,1,"Device Enumeration Speed");
519
520 DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,&(otg_dev->core_if->core_global_regs->hptxfsiz),"HPTXFSIZ");
521 DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0");
522
523
524 /**
525  * @todo Add code to initiate the HNP.
526  */
527 /**
528  * Show the HNP status bit
529  */
530 static ssize_t hnp_show( struct device *_dev,
531 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
532                          struct device_attribute *attr,
533 #endif
534                          char *buf)
535 {
536         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
537
538         gotgctl_data_t val;
539         val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
540         return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
541 }
542
543 /**
544  * Set the HNP Request bit
545  */
546 static ssize_t hnp_store( struct device *_dev,
547 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
548                           struct device_attribute *attr,
549 #endif
550                           const char *buf,
551                           size_t count )
552 {
553         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
554
555         uint32_t in = simple_strtoul(buf, NULL, 16);
556         uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl);
557         gotgctl_data_t mem;
558         mem.d32 = dwc_read_reg32(addr);
559         mem.b.hnpreq = in;
560         dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
561         dwc_write_reg32(addr, mem.d32);
562         return count;
563 }
564 DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
565
566 /**
567  * @todo Add code to initiate the SRP.
568  */
569 /**
570  * Show the SRP status bit
571  */
572 static ssize_t srp_show( struct device *_dev,
573 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
574                          struct device_attribute *attr,
575 #endif
576                          char *buf)
577 {
578 #ifndef DWC_HOST_ONLY
579         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
580
581         gotgctl_data_t val;
582         val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
583         return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
584 #else
585         return sprintf(buf, "Host Only Mode!\n");
586 #endif
587 }
588
589
590
591 /**
592  * Set the SRP Request bit
593  */
594 static ssize_t srp_store( struct device *_dev,
595 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
596                           struct device_attribute *attr,
597 #endif
598                           const char *buf,
599                           size_t count )
600 {
601 #ifndef DWC_HOST_ONLY
602         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
603
604         dwc_otg_pcd_initiate_srp(otg_dev->pcd);
605 #endif
606         return count;
607 }
608 DEVICE_ATTR(srp, 0644, srp_show, srp_store);
609
610 /**
611  * @todo Need to do more for power on/off?
612  */
613 /**
614  * Show the Bus Power status
615  */
616 static ssize_t buspower_show( struct device *_dev,
617 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
618                               struct device_attribute *attr,
619 #endif
620                               char *buf)
621 {
622         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
623
624         hprt0_data_t val;
625         val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
626         return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr);
627 }
628
629
630 /**
631  * Set the Bus Power status
632  */
633 static ssize_t buspower_store( struct device *_dev,
634 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
635                                struct device_attribute *attr,
636 #endif
637                                const char *buf,
638                                size_t count )
639 {
640         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
641
642         uint32_t on = simple_strtoul(buf, NULL, 16);
643         uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
644         hprt0_data_t mem;
645
646         mem.d32 = dwc_read_reg32(addr);
647         mem.b.prtpwr = on;
648
649         //dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
650         dwc_write_reg32(addr, mem.d32);
651
652         return count;
653 }
654 DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
655
656 /**
657  * @todo Need to do more for suspend?
658  */
659 /**
660  * Show the Bus Suspend status
661  */
662 static ssize_t bussuspend_show( struct device *_dev,
663 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
664                                 struct device_attribute *attr,
665 #endif
666                                 char *buf)
667 {
668         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
669
670         hprt0_data_t val;
671         val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
672         return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
673 }
674
675 /**
676  * Set the Bus Suspend status
677  */
678 static ssize_t bussuspend_store( struct device *_dev,
679 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
680                                  struct device_attribute *attr,
681 #endif
682                                  const char *buf,
683                                  size_t count )
684 {
685         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
686
687         uint32_t in = simple_strtoul(buf, NULL, 16);
688         uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
689         hprt0_data_t mem;
690         mem.d32 = dwc_read_reg32(addr);
691         mem.b.prtsusp = in;
692         dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
693         dwc_write_reg32(addr, mem.d32);
694         return count;
695 }
696 DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
697
698 /**
699  * Show the status of Remote Wakeup.
700  */
701 static ssize_t remote_wakeup_show( struct device *_dev,
702 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
703                                    struct device_attribute *attr,
704 #endif
705                                    char *buf)
706 {
707 #ifndef DWC_HOST_ONLY
708         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
709
710         dctl_data_t val;
711         val.d32 =
712                 dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl);
713         return sprintf( buf, "Remote Wakeup = %d Enabled = %d\n",
714                         val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable);
715 #else
716         return sprintf(buf, "Host Only Mode!\n");
717 #endif
718 }
719 /**
720  * Initiate a remote wakeup of the host.  The Device control register
721  * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
722  * flag is set.
723  *
724  */
725 static ssize_t remote_wakeup_store( struct device *_dev,
726 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
727                                     struct device_attribute *attr,
728 #endif
729                                     const char *buf,
730                                     size_t count )
731 {
732 #ifndef DWC_HOST_ONLY
733         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
734
735         uint32_t val = simple_strtoul(buf, NULL, 16);
736         if (val&1) {
737                 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
738         }
739         else {
740                 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
741         }
742 #endif
743         return count;
744 }
745 DEVICE_ATTR(remote_wakeup,  S_IRUGO|S_IWUSR, remote_wakeup_show,
746             remote_wakeup_store);
747
748 /**
749  * Dump global registers and either host or device registers (depending on the
750  * current mode of the core).
751  */
752 static ssize_t regdump_show( struct device *_dev,
753 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
754                              struct device_attribute *attr,
755 #endif
756                              char *buf)
757 {
758         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
759
760         dwc_otg_dump_global_registers( otg_dev->core_if);
761         if (dwc_otg_is_host_mode(otg_dev->core_if)) {
762                 dwc_otg_dump_host_registers( otg_dev->core_if);
763         } else {
764                 dwc_otg_dump_dev_registers( otg_dev->core_if);
765
766         }
767         return sprintf( buf, "Register Dump\n" );
768 }
769
770 DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0);
771
772 /**
773  * Dump global registers and either host or device registers (depending on the
774  * current mode of the core).
775  */
776 static ssize_t spramdump_show( struct device *_dev,
777 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
778                                struct device_attribute *attr,
779 #endif
780                                char *buf)
781 {
782         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
783
784         dwc_otg_dump_spram( otg_dev->core_if);
785
786         return sprintf( buf, "SPRAM Dump\n" );
787 }
788
789 DEVICE_ATTR(spramdump, S_IRUGO|S_IWUSR, spramdump_show, 0);
790
791 /**
792  * Dump the current hcd state.
793  */
794 static ssize_t hcddump_show( struct device *_dev,
795 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
796                              struct device_attribute *attr,
797 #endif
798                              char *buf)
799 {
800 #ifndef DWC_DEVICE_ONLY
801         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
802
803         dwc_otg_hcd_dump_state(otg_dev->hcd);
804 #endif
805         return sprintf( buf, "HCD Dump\n" );
806 }
807
808 DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0);
809
810 /**
811  * Dump the average frame remaining at SOF. This can be used to
812  * determine average interrupt latency. Frame remaining is also shown for
813  * start transfer and two additional sample points.
814  */
815 static ssize_t hcd_frrem_show( struct device *_dev,
816 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
817                                struct device_attribute *attr,
818 #endif
819                                char *buf)
820 {
821 #ifndef DWC_DEVICE_ONLY
822         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
823
824         dwc_otg_hcd_dump_frrem(otg_dev->hcd);
825 #endif
826         return sprintf( buf, "HCD Dump Frame Remaining\n" );
827 }
828
829 DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0);
830
831 /**
832  * Displays the time required to read the GNPTXFSIZ register many times (the
833  * output shows the number of times the register is read).
834  */
835 #define RW_REG_COUNT 10000000
836 #define MSEC_PER_JIFFIE 1000/HZ
837 static ssize_t rd_reg_test_show( struct device *_dev,
838 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
839                                  struct device_attribute *attr,
840 #endif
841                                  char *buf)
842 {
843         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
844
845         int i;
846         int time;
847         int start_jiffies;
848
849         printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
850                HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
851         start_jiffies = jiffies;
852         for (i = 0; i < RW_REG_COUNT; i++) {
853                 dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
854         }
855         time = jiffies - start_jiffies;
856         return sprintf( buf, "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
857                         RW_REG_COUNT, time * MSEC_PER_JIFFIE, time );
858 }
859
860 DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0);
861
862 /**
863  * Displays the time required to write the GNPTXFSIZ register many times (the
864  * output shows the number of times the register is written).
865  */
866 static ssize_t wr_reg_test_show( struct device *_dev,
867 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
868                                  struct device_attribute *attr,
869 #endif
870                                  char *buf)
871 {
872         dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
873
874         uint32_t reg_val;
875         int i;
876         int time;
877         int start_jiffies;
878
879         printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
880                HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
881         reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
882         start_jiffies = jiffies;
883         for (i = 0; i < RW_REG_COUNT; i++) {
884                 dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz, reg_val);
885         }
886         time = jiffies - start_jiffies;
887         return sprintf( buf, "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
888                         RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
889 }
890
891 DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
892 /**@}*/
893
894 /**
895  * Create the device files
896  */
897 void dwc_otg_attr_create (struct device *dev)
898 {
899         int error;
900
901         error = device_create_file(dev, &dev_attr_regoffset);
902         error = device_create_file(dev, &dev_attr_regvalue);
903         error = device_create_file(dev, &dev_attr_mode);
904         error = device_create_file(dev, &dev_attr_hnpcapable);
905         error = device_create_file(dev, &dev_attr_srpcapable);
906         error = device_create_file(dev, &dev_attr_hnp);
907         error = device_create_file(dev, &dev_attr_srp);
908         error = device_create_file(dev, &dev_attr_buspower);
909         error = device_create_file(dev, &dev_attr_bussuspend);
910         error = device_create_file(dev, &dev_attr_busconnected);
911         error = device_create_file(dev, &dev_attr_gotgctl);
912         error = device_create_file(dev, &dev_attr_gusbcfg);
913         error = device_create_file(dev, &dev_attr_grxfsiz);
914         error = device_create_file(dev, &dev_attr_gnptxfsiz);
915         error = device_create_file(dev, &dev_attr_gpvndctl);
916         error = device_create_file(dev, &dev_attr_ggpio);
917         error = device_create_file(dev, &dev_attr_guid);
918         error = device_create_file(dev, &dev_attr_gsnpsid);
919         error = device_create_file(dev, &dev_attr_devspeed);
920         error = device_create_file(dev, &dev_attr_enumspeed);
921         error = device_create_file(dev, &dev_attr_hptxfsiz);
922         error = device_create_file(dev, &dev_attr_hprt0);
923         error = device_create_file(dev, &dev_attr_remote_wakeup);
924         error = device_create_file(dev, &dev_attr_regdump);
925         error = device_create_file(dev, &dev_attr_spramdump);
926         error = device_create_file(dev, &dev_attr_hcddump);
927         error = device_create_file(dev, &dev_attr_hcd_frrem);
928         error = device_create_file(dev, &dev_attr_rd_reg_test);
929         error = device_create_file(dev, &dev_attr_wr_reg_test);
930 }
931
932 /**
933  * Remove the device files
934  */
935 void dwc_otg_attr_remove (struct device *dev)
936 {
937         device_remove_file(dev, &dev_attr_regoffset);
938         device_remove_file(dev, &dev_attr_regvalue);
939         device_remove_file(dev, &dev_attr_mode);
940         device_remove_file(dev, &dev_attr_hnpcapable);
941         device_remove_file(dev, &dev_attr_srpcapable);
942         device_remove_file(dev, &dev_attr_hnp);
943         device_remove_file(dev, &dev_attr_srp);
944         device_remove_file(dev, &dev_attr_buspower);
945         device_remove_file(dev, &dev_attr_bussuspend);
946         device_remove_file(dev, &dev_attr_busconnected);
947         device_remove_file(dev, &dev_attr_gotgctl);
948         device_remove_file(dev, &dev_attr_gusbcfg);
949         device_remove_file(dev, &dev_attr_grxfsiz);
950         device_remove_file(dev, &dev_attr_gnptxfsiz);
951         device_remove_file(dev, &dev_attr_gpvndctl);
952         device_remove_file(dev, &dev_attr_ggpio);
953         device_remove_file(dev, &dev_attr_guid);
954         device_remove_file(dev, &dev_attr_gsnpsid);
955         device_remove_file(dev, &dev_attr_devspeed);
956         device_remove_file(dev, &dev_attr_enumspeed);
957         device_remove_file(dev, &dev_attr_hptxfsiz);
958         device_remove_file(dev, &dev_attr_hprt0);
959         device_remove_file(dev, &dev_attr_remote_wakeup);
960         device_remove_file(dev, &dev_attr_regdump);
961         device_remove_file(dev, &dev_attr_spramdump);
962         device_remove_file(dev, &dev_attr_hcddump);
963         device_remove_file(dev, &dev_attr_hcd_frrem);
964         device_remove_file(dev, &dev_attr_rd_reg_test);
965         device_remove_file(dev, &dev_attr_wr_reg_test);
966 }