1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
4 * $Date: 2008-11-21 05:39:15 $
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.
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.
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
32 * ========================================================================== */
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.
42 /** @page "Linux Module Attributes"
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.
50 The following table shows the attributes.
54 <td><b> Description</b></td>
55 <td><b> Access</b></td>
60 <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
66 <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
67 Read returns the current value.</td>
73 <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
74 Read returns the current value.</td>
80 <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
86 <td> Initiates the Session Request Protocol. Read returns the status.</td>
92 <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
98 <td> Suspends the USB bus.</td>
103 <td> busconnected </td>
104 <td> Gets the connection status of the bus</td>
110 <td> Gets or sets the Core Control Status Register.</td>
116 <td> Gets or sets the Core USB Configuration Register</td>
122 <td> Gets or sets the Receive FIFO Size Register</td>
128 <td> Gets or sets the non-periodic Transmit Size Register</td>
134 <td> Gets or sets the PHY Vendor Control Register</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>
147 <td> Gets or sets the value of the User ID Register</td>
153 <td> Gets the value of the Synopsys ID Regester</td>
159 <td> Gets or sets the device speed setting in the DCFG register</td>
165 <td> Gets the device enumeration Speed.</td>
171 <td> Gets the value of the Host Periodic Transmit FIFO</td>
177 <td> Gets or sets the value in the Host Port Control and Status Register</td>
183 <td> Sets the register offset for the next Register Access</td>
189 <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
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
204 <td> Dumps the contents of core registers.</td>
210 <td> Dumps the contents of core registers.</td>
216 <td> Dumps the current HCD state.</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>
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).
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).
248 To get the current mode:
249 cat /sys/devices/lm0/mode
251 To power down the USB:
252 echo 0 > /sys/devices/lm0/buspower
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>
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"
273 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
275 * MACROs for defining sysfs attribute
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) \
280 dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
282 val = dwc_read_reg32 (_addr_); \
283 val = (val & (_mask_)) >> _shift_; \
284 return sprintf (buf, "%s = 0x%x\n", _string_, val); \
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) \
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); \
301 * MACROs for defining sysfs attribute for 32-bit registers
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) \
306 dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
308 val = dwc_read_reg32 (_addr_); \
309 return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
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) \
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); \
325 * MACROs for defining sysfs attribute
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) \
330 dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
332 val = dwc_read_reg32 (_addr_); \
333 val = (val & (_mask_)) >> _shift_; \
334 return sprintf (buf, "%s = 0x%x\n", _string_, val); \
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) \
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); \
350 * MACROs for defining sysfs attribute for 32-bit registers
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) \
355 dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
357 val = dwc_read_reg32 (_addr_); \
358 return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
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) \
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); \
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);
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);
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);
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);
391 /** @name Functions for Show/Store of Attributes */
395 * Show the register offset of the Register Access.
397 static ssize_t
regoffset_show( struct device
*_dev
,
398 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
399 struct device_attribute
*attr
,
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
);
408 * Set the register offset for the next Register Access Read/Write
410 static ssize_t
regoffset_store( struct device
*_dev
,
411 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
412 struct device_attribute
*attr
,
417 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
;
425 dev_err( _dev
, "invalid offset\n" );
430 DEVICE_ATTR(regoffset
, S_IRUGO
|S_IWUSR
, (void *)regoffset_show
, regoffset_store
);
434 * Show the value of the register at the offset in the reg_offset
437 static ssize_t
regvalue_show( struct device
*_dev
,
438 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
439 struct device_attribute
*attr
,
443 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
446 volatile uint32_t *addr
;
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
);
460 dev_err(_dev
, "Invalid offset (0x%0x)\n",
461 otg_dev
->reg_offset
);
462 return sprintf(buf
, "invalid offset\n" );
467 * Store the value in the register at the offset in the reg_offset
471 static ssize_t
regvalue_store( struct device
*_dev
,
472 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
473 struct device_attribute
*attr
,
478 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
491 dev_err(_dev
, "Invalid Register Offset (0x%08x)\n",
492 otg_dev
->reg_offset
);
496 DEVICE_ATTR(regvalue
, S_IRUGO
|S_IWUSR
, regvalue_show
, regvalue_store
);
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");
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");
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");
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");
525 * @todo Add code to initiate the HNP.
528 * Show the HNP status bit
530 static ssize_t
hnp_show( struct device
*_dev
,
531 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
532 struct device_attribute
*attr
,
536 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
544 * Set the HNP Request bit
546 static ssize_t
hnp_store( struct device
*_dev
,
547 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
548 struct device_attribute
*attr
,
553 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
555 uint32_t in
= simple_strtoul(buf
, NULL
, 16);
556 uint32_t *addr
= (uint32_t *)&(otg_dev
->core_if
->core_global_regs
->gotgctl
);
558 mem
.d32
= dwc_read_reg32(addr
);
560 dev_dbg(_dev
, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr
, mem
.d32
);
561 dwc_write_reg32(addr
, mem
.d32
);
564 DEVICE_ATTR(hnp
, 0644, hnp_show
, hnp_store
);
567 * @todo Add code to initiate the SRP.
570 * Show the SRP status bit
572 static ssize_t
srp_show( struct device
*_dev
,
573 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
574 struct device_attribute
*attr
,
578 #ifndef DWC_HOST_ONLY
579 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
585 return sprintf(buf
, "Host Only Mode!\n");
592 * Set the SRP Request bit
594 static ssize_t
srp_store( struct device
*_dev
,
595 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
596 struct device_attribute
*attr
,
601 #ifndef DWC_HOST_ONLY
602 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
604 dwc_otg_pcd_initiate_srp(otg_dev
->pcd
);
608 DEVICE_ATTR(srp
, 0644, srp_show
, srp_store
);
611 * @todo Need to do more for power on/off?
614 * Show the Bus Power status
616 static ssize_t
buspower_show( struct device
*_dev
,
617 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
618 struct device_attribute
*attr
,
622 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
631 * Set the Bus Power status
633 static ssize_t
buspower_store( struct device
*_dev
,
634 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
635 struct device_attribute
*attr
,
640 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
642 uint32_t on
= simple_strtoul(buf
, NULL
, 16);
643 uint32_t *addr
= (uint32_t *)otg_dev
->core_if
->host_if
->hprt0
;
646 mem
.d32
= dwc_read_reg32(addr
);
649 //dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
650 dwc_write_reg32(addr
, mem
.d32
);
654 DEVICE_ATTR(buspower
, 0644, buspower_show
, buspower_store
);
657 * @todo Need to do more for suspend?
660 * Show the Bus Suspend status
662 static ssize_t
bussuspend_show( struct device
*_dev
,
663 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
664 struct device_attribute
*attr
,
668 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
676 * Set the Bus Suspend status
678 static ssize_t
bussuspend_store( struct device
*_dev
,
679 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
680 struct device_attribute
*attr
,
685 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
687 uint32_t in
= simple_strtoul(buf
, NULL
, 16);
688 uint32_t *addr
= (uint32_t *)otg_dev
->core_if
->host_if
->hprt0
;
690 mem
.d32
= dwc_read_reg32(addr
);
692 dev_dbg(_dev
, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr
, mem
.d32
);
693 dwc_write_reg32(addr
, mem
.d32
);
696 DEVICE_ATTR(bussuspend
, 0644, bussuspend_show
, bussuspend_store
);
699 * Show the status of Remote Wakeup.
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
,
707 #ifndef DWC_HOST_ONLY
708 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
716 return sprintf(buf
, "Host Only Mode!\n");
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
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
,
732 #ifndef DWC_HOST_ONLY
733 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
735 uint32_t val
= simple_strtoul(buf
, NULL
, 16);
737 dwc_otg_pcd_remote_wakeup(otg_dev
->pcd
, 1);
740 dwc_otg_pcd_remote_wakeup(otg_dev
->pcd
, 0);
745 DEVICE_ATTR(remote_wakeup
, S_IRUGO
|S_IWUSR
, remote_wakeup_show
,
746 remote_wakeup_store
);
749 * Dump global registers and either host or device registers (depending on the
750 * current mode of the core).
752 static ssize_t
regdump_show( struct device
*_dev
,
753 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
754 struct device_attribute
*attr
,
758 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
764 dwc_otg_dump_dev_registers( otg_dev
->core_if
);
767 return sprintf( buf
, "Register Dump\n" );
770 DEVICE_ATTR(regdump
, S_IRUGO
|S_IWUSR
, regdump_show
, 0);
773 * Dump global registers and either host or device registers (depending on the
774 * current mode of the core).
776 static ssize_t
spramdump_show( struct device
*_dev
,
777 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
778 struct device_attribute
*attr
,
782 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
784 dwc_otg_dump_spram( otg_dev
->core_if
);
786 return sprintf( buf
, "SPRAM Dump\n" );
789 DEVICE_ATTR(spramdump
, S_IRUGO
|S_IWUSR
, spramdump_show
, 0);
792 * Dump the current hcd state.
794 static ssize_t
hcddump_show( struct device
*_dev
,
795 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
796 struct device_attribute
*attr
,
800 #ifndef DWC_DEVICE_ONLY
801 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
803 dwc_otg_hcd_dump_state(otg_dev
->hcd
);
805 return sprintf( buf
, "HCD Dump\n" );
808 DEVICE_ATTR(hcddump
, S_IRUGO
|S_IWUSR
, hcddump_show
, 0);
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.
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
,
821 #ifndef DWC_DEVICE_ONLY
822 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
824 dwc_otg_hcd_dump_frrem(otg_dev
->hcd
);
826 return sprintf( buf
, "HCD Dump Frame Remaining\n" );
829 DEVICE_ATTR(hcd_frrem
, S_IRUGO
|S_IWUSR
, hcd_frrem_show
, 0);
832 * Displays the time required to read the GNPTXFSIZ register many times (the
833 * output shows the number of times the register is read).
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
,
843 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
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
);
860 DEVICE_ATTR(rd_reg_test
, S_IRUGO
|S_IWUSR
, rd_reg_test_show
, 0);
863 * Displays the time required to write the GNPTXFSIZ register many times (the
864 * output shows the number of times the register is written).
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
,
872 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(_dev
);
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
);
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
);
891 DEVICE_ATTR(wr_reg_test
, S_IRUGO
|S_IWUSR
, wr_reg_test_show
, 0);
895 * Create the device files
897 void dwc_otg_attr_create (struct device
*dev
)
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
);
933 * Remove the device files
935 void dwc_otg_attr_remove (struct device
*dev
)
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
);
This page took 0.109932 seconds and 5 git commands to generate.