1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
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.
49 The following table shows the attributes.
53 <td><b> Description</b></td>
54 <td><b> Access</b></td>
59 <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
65 <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
66 Read returns the current value.</td>
72 <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
73 Read returns the current value.</td>
78 <td> hsic_connect </td>
79 <td> Gets or sets the "HSIC-Connect" bit in the GLPMCFG Register.
80 Read returns the current value.</td>
85 <td> inv_sel_hsic </td>
86 <td> Gets or sets the "Invert Select HSIC" bit in the GLPMFG Register.
87 Read returns the current value.</td>
93 <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
99 <td> Initiates the Session Request Protocol. Read returns the status.</td>
105 <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
110 <td> bussuspend </td>
111 <td> Suspends the USB bus.</td>
116 <td> busconnected </td>
117 <td> Gets the connection status of the bus</td>
123 <td> Gets or sets the Core Control Status Register.</td>
129 <td> Gets or sets the Core USB Configuration Register</td>
135 <td> Gets or sets the Receive FIFO Size Register</td>
141 <td> Gets or sets the non-periodic Transmit Size Register</td>
147 <td> Gets or sets the PHY Vendor Control Register</td>
153 <td> Gets the value in the lower 16-bits of the General Purpose IO Register
154 or sets the upper 16 bits.</td>
160 <td> Gets or sets the value of the User ID Register</td>
166 <td> Gets the value of the Synopsys ID Regester</td>
172 <td> Gets or sets the device speed setting in the DCFG register</td>
178 <td> Gets the device enumeration Speed.</td>
184 <td> Gets the value of the Host Periodic Transmit FIFO</td>
190 <td> Gets or sets the value in the Host Port Control and Status Register</td>
196 <td> Sets the register offset for the next Register Access</td>
202 <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
207 <td> remote_wakeup </td>
208 <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
209 wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
210 Wakeup signalling bit in the Device Control Register is set for 1
216 <td> rem_wakeup_pwrdn </td>
217 <td> On read, shows the status core - hibernated or not. On write, initiates
218 a remote wakeup of the device from Hibernation. </td>
223 <td> mode_ch_tim_en </td>
224 <td> This bit is used to enable or disable the host core to wait for 200 PHY
225 clock cycles at the end of Resume to change the opmode signal to the PHY to 00
226 after Suspend or LPM. </td>
231 <td> fr_interval </td>
232 <td> On read, shows the value of HFIR Frame Interval. On write, dynamically
233 reload HFIR register during runtime. The application can write a value to this
234 register only after the Port Enable bit of the Host Port Control and Status
235 register (HPRT.PrtEnaPort) has been set </td>
240 <td> disconnect_us </td>
241 <td> On read, shows the status of disconnect_device_us. On write, sets disconnect_us
242 which causes soft disconnect for 100us. Applicable only for device mode of operation.</td>
248 <td> Dumps the contents of core registers.</td>
254 <td> Dumps the contents of core registers.</td>
260 <td> Dumps the current HCD state.</td>
266 <td> Shows the average value of the Frame Remaining
267 field in the Host Frame Number/Frame Remaining register when an SOF interrupt
268 occurs. This can be used to determine the average interrupt latency. Also
269 shows the average Frame Remaining value for start_transfer and the "a" and
270 "b" sample points. The "a" and "b" sample points may be used during debugging
271 bto determine how long it takes to execute a section of the HCD code.</td>
276 <td> rd_reg_test </td>
277 <td> Displays the time required to read the GNPTXFSIZ register many times
278 (the output shows the number of times the register is read).
283 <td> wr_reg_test </td>
284 <td> Displays the time required to write the GNPTXFSIZ register many times
285 (the output shows the number of times the register is written).
290 <td> lpm_response </td>
291 <td> Gets or sets lpm_response mode. Applicable only in device mode.
296 <td> sleep_status </td>
297 <td> Shows sleep status of device.
304 To get the current mode:
305 cat /sys/devices/lm0/mode
307 To power down the USB:
308 echo 0 > /sys/devices/lm0/buspower
311 #include "dwc_otg_os_dep.h"
313 #include "dwc_otg_driver.h"
314 #include "dwc_otg_attr.h"
315 #include "dwc_otg_core_if.h"
316 #include "dwc_otg_pcd_if.h"
317 #include "dwc_otg_hcd_if.h"
320 * MACROs for defining sysfs attribute
324 #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
325 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
327 struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
328 dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
330 val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
331 return sprintf (buf, "%s = 0x%x\n", _string_, val); \
333 #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
334 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
335 const char *buf, size_t count) \
337 struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
338 dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
339 uint32_t set = simple_strtoul(buf, NULL, 16); \
340 dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
344 #elif defined(PCI_INTERFACE)
346 #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
347 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
349 dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
351 val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
352 return sprintf (buf, "%s = 0x%x\n", _string_, val); \
354 #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
355 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
356 const char *buf, size_t count) \
358 dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
359 uint32_t set = simple_strtoul(buf, NULL, 16); \
360 dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
364 #elif defined(PLATFORM_INTERFACE)
366 #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
367 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
369 struct platform_device *platform_dev = \
370 container_of(_dev, struct platform_device, dev); \
371 dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
373 DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \
374 __func__, _dev, platform_dev, otg_dev); \
375 val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
376 return sprintf (buf, "%s = 0x%x\n", _string_, val); \
378 #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
379 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
380 const char *buf, size_t count) \
382 struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
383 dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
384 uint32_t set = simple_strtoul(buf, NULL, 16); \
385 dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
391 * MACROs for defining sysfs attribute for 32-bit registers
394 #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
395 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
397 struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
398 dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
400 val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
401 return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
403 #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
404 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
405 const char *buf, size_t count) \
407 struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
408 dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
409 uint32_t val = simple_strtoul(buf, NULL, 16); \
410 dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
413 #elif defined(PCI_INTERFACE)
414 #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
415 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
417 dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
419 val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
420 return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
422 #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
423 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
424 const char *buf, size_t count) \
426 dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
427 uint32_t val = simple_strtoul(buf, NULL, 16); \
428 dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
432 #elif defined(PLATFORM_INTERFACE)
433 #include "dwc_otg_dbg.h"
434 #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
435 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
437 struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
438 dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
440 DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \
441 __func__, _dev, platform_dev, otg_dev); \
442 val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
443 return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
445 #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
446 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
447 const char *buf, size_t count) \
449 struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
450 dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
451 uint32_t val = simple_strtoul(buf, NULL, 16); \
452 dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
458 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_string_) \
459 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
460 DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
461 DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
463 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_string_) \
464 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
465 DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
467 #define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
468 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
469 DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
470 DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
472 #define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
473 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
474 DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
476 /** @name Functions for Show/Store of Attributes */
480 * Helper function returning the otg_device structure of the given device
482 static dwc_otg_device_t *dwc_otg_drvdev(struct device *_dev)
484 dwc_otg_device_t *otg_dev;
485 DWC_OTG_GETDRVDEV(otg_dev, _dev);
490 * Show the register offset of the Register Access.
492 static ssize_t regoffset_show(struct device *_dev,
493 struct device_attribute *attr, char *buf)
495 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
496 return snprintf(buf, sizeof("0xFFFFFFFF\n") + 1, "0x%08x\n",
497 otg_dev->os_dep.reg_offset);
501 * Set the register offset for the next Register Access Read/Write
503 static ssize_t regoffset_store(struct device *_dev,
504 struct device_attribute *attr,
505 const char *buf, size_t count)
507 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
508 uint32_t offset = simple_strtoul(buf, NULL, 16);
509 #if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE)
510 if (offset < SZ_256K) {
511 #elif defined(PCI_INTERFACE)
512 if (offset < 0x00040000) {
514 otg_dev->os_dep.reg_offset = offset;
516 dev_err(_dev, "invalid offset\n");
522 DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store);
525 * Show the value of the register at the offset in the reg_offset
528 static ssize_t regvalue_show(struct device *_dev,
529 struct device_attribute *attr, char *buf)
531 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
533 volatile uint32_t *addr;
535 if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) {
536 /* Calculate the address */
537 addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
538 (uint8_t *) otg_dev->os_dep.base);
539 val = DWC_READ_REG32(addr);
541 sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n") + 1,
542 "Reg@0x%06x = 0x%08x\n", otg_dev->os_dep.reg_offset,
545 dev_err(_dev, "Invalid offset (0x%0x)\n", otg_dev->os_dep.reg_offset);
546 return sprintf(buf, "invalid offset\n");
551 * Store the value in the register at the offset in the reg_offset
555 static ssize_t regvalue_store(struct device *_dev,
556 struct device_attribute *attr,
557 const char *buf, size_t count)
559 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
560 volatile uint32_t *addr;
561 uint32_t val = simple_strtoul(buf, NULL, 16);
562 //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
563 if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) {
564 /* Calculate the address */
565 addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
566 (uint8_t *) otg_dev->os_dep.base);
567 DWC_WRITE_REG32(addr, val);
569 dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
570 otg_dev->os_dep.reg_offset);
575 DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store);
580 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode, "Mode");
581 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable, "HNPCapable");
582 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable, "SRPCapable");
583 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hsic_connect, "HSIC Connect");
584 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(inv_sel_hsic, "Invert Select HSIC");
586 //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
587 //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
588 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, "Bus Connected");
590 DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl, 0, "GOTGCTL");
591 DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,
592 &(otg_dev->core_if->core_global_regs->gusbcfg),
594 DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,
595 &(otg_dev->core_if->core_global_regs->grxfsiz),
597 DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,
598 &(otg_dev->core_if->core_global_regs->gnptxfsiz),
600 DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,
601 &(otg_dev->core_if->core_global_regs->gpvndctl),
603 DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,
604 &(otg_dev->core_if->core_global_regs->ggpio),
606 DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid),
608 DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,
609 &(otg_dev->core_if->core_global_regs->gsnpsid),
611 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed, "Device Speed");
612 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed, "Device Enumeration Speed");
614 DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,
615 &(otg_dev->core_if->core_global_regs->hptxfsiz),
617 DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0");
620 * @todo Add code to initiate the HNP.
623 * Show the HNP status bit
625 static ssize_t hnp_show(struct device *_dev,
626 struct device_attribute *attr, char *buf)
628 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
629 return sprintf(buf, "HstNegScs = 0x%x\n",
630 dwc_otg_get_hnpstatus(otg_dev->core_if));
634 * Set the HNP Request bit
636 static ssize_t hnp_store(struct device *_dev,
637 struct device_attribute *attr,
638 const char *buf, size_t count)
640 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
641 uint32_t in = simple_strtoul(buf, NULL, 16);
642 dwc_otg_set_hnpreq(otg_dev->core_if, in);
646 DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
649 * @todo Add code to initiate the SRP.
652 * Show the SRP status bit
654 static ssize_t srp_show(struct device *_dev,
655 struct device_attribute *attr, char *buf)
657 #ifndef DWC_HOST_ONLY
658 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
659 return sprintf(buf, "SesReqScs = 0x%x\n",
660 dwc_otg_get_srpstatus(otg_dev->core_if));
662 return sprintf(buf, "Host Only Mode!\n");
667 * Set the SRP Request bit
669 static ssize_t srp_store(struct device *_dev,
670 struct device_attribute *attr,
671 const char *buf, size_t count)
673 #ifndef DWC_HOST_ONLY
674 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
675 dwc_otg_pcd_initiate_srp(otg_dev->pcd);
680 DEVICE_ATTR(srp, 0644, srp_show, srp_store);
683 * @todo Need to do more for power on/off?
686 * Show the Bus Power status
688 static ssize_t buspower_show(struct device *_dev,
689 struct device_attribute *attr, char *buf)
691 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
692 return sprintf(buf, "Bus Power = 0x%x\n",
693 dwc_otg_get_prtpower(otg_dev->core_if));
697 * Set the Bus Power status
699 static ssize_t buspower_store(struct device *_dev,
700 struct device_attribute *attr,
701 const char *buf, size_t count)
703 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
704 uint32_t on = simple_strtoul(buf, NULL, 16);
705 dwc_otg_set_prtpower(otg_dev->core_if, on);
709 DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
712 * @todo Need to do more for suspend?
715 * Show the Bus Suspend status
717 static ssize_t bussuspend_show(struct device *_dev,
718 struct device_attribute *attr, char *buf)
720 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
721 return sprintf(buf, "Bus Suspend = 0x%x\n",
722 dwc_otg_get_prtsuspend(otg_dev->core_if));
726 * Set the Bus Suspend status
728 static ssize_t bussuspend_store(struct device *_dev,
729 struct device_attribute *attr,
730 const char *buf, size_t count)
732 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
733 uint32_t in = simple_strtoul(buf, NULL, 16);
734 dwc_otg_set_prtsuspend(otg_dev->core_if, in);
738 DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
741 * Show the Mode Change Ready Timer status
743 static ssize_t mode_ch_tim_en_show(struct device *_dev,
744 struct device_attribute *attr, char *buf)
746 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
747 return sprintf(buf, "Mode Change Ready Timer Enable = 0x%x\n",
748 dwc_otg_get_mode_ch_tim(otg_dev->core_if));
752 * Set the Mode Change Ready Timer status
754 static ssize_t mode_ch_tim_en_store(struct device *_dev,
755 struct device_attribute *attr,
756 const char *buf, size_t count)
758 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
759 uint32_t in = simple_strtoul(buf, NULL, 16);
760 dwc_otg_set_mode_ch_tim(otg_dev->core_if, in);
764 DEVICE_ATTR(mode_ch_tim_en, 0644, mode_ch_tim_en_show, mode_ch_tim_en_store);
767 * Show the value of HFIR Frame Interval bitfield
769 static ssize_t fr_interval_show(struct device *_dev,
770 struct device_attribute *attr, char *buf)
772 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
773 return sprintf(buf, "Frame Interval = 0x%x\n",
774 dwc_otg_get_fr_interval(otg_dev->core_if));
778 * Set the HFIR Frame Interval value
780 static ssize_t fr_interval_store(struct device *_dev,
781 struct device_attribute *attr,
782 const char *buf, size_t count)
784 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
785 uint32_t in = simple_strtoul(buf, NULL, 10);
786 dwc_otg_set_fr_interval(otg_dev->core_if, in);
790 DEVICE_ATTR(fr_interval, 0644, fr_interval_show, fr_interval_store);
793 * Show the status of Remote Wakeup.
795 static ssize_t remote_wakeup_show(struct device *_dev,
796 struct device_attribute *attr, char *buf)
798 #ifndef DWC_HOST_ONLY
799 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
802 "Remote Wakeup Sig = %d Enabled = %d LPM Remote Wakeup = %d\n",
803 dwc_otg_get_remotewakesig(otg_dev->core_if),
804 dwc_otg_pcd_get_rmwkup_enable(otg_dev->pcd),
805 dwc_otg_get_lpm_remotewakeenabled(otg_dev->core_if));
807 return sprintf(buf, "Host Only Mode!\n");
808 #endif /* DWC_HOST_ONLY */
812 * Initiate a remote wakeup of the host. The Device control register
813 * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
817 static ssize_t remote_wakeup_store(struct device *_dev,
818 struct device_attribute *attr,
819 const char *buf, size_t count)
821 #ifndef DWC_HOST_ONLY
822 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
823 uint32_t val = simple_strtoul(buf, NULL, 16);
826 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
828 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
830 #endif /* DWC_HOST_ONLY */
834 DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show,
835 remote_wakeup_store);
838 * Show the whether core is hibernated or not.
840 static ssize_t rem_wakeup_pwrdn_show(struct device *_dev,
841 struct device_attribute *attr, char *buf)
843 #ifndef DWC_HOST_ONLY
844 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
846 if (dwc_otg_get_core_state(otg_dev->core_if)) {
847 DWC_PRINTF("Core is in hibernation\n");
849 DWC_PRINTF("Core is not in hibernation\n");
851 #endif /* DWC_HOST_ONLY */
855 extern int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
856 int rem_wakeup, int reset);
859 * Initiate a remote wakeup of the device to exit from hibernation.
861 static ssize_t rem_wakeup_pwrdn_store(struct device *_dev,
862 struct device_attribute *attr,
863 const char *buf, size_t count)
865 #ifndef DWC_HOST_ONLY
866 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
867 dwc_otg_device_hibernation_restore(otg_dev->core_if, 1, 0);
872 DEVICE_ATTR(rem_wakeup_pwrdn, S_IRUGO | S_IWUSR, rem_wakeup_pwrdn_show,
873 rem_wakeup_pwrdn_store);
875 static ssize_t disconnect_us(struct device *_dev,
876 struct device_attribute *attr,
877 const char *buf, size_t count)
880 #ifndef DWC_HOST_ONLY
881 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
882 uint32_t val = simple_strtoul(buf, NULL, 16);
883 DWC_PRINTF("The Passed value is %04x\n", val);
885 dwc_otg_pcd_disconnect_us(otg_dev->pcd, 50);
887 #endif /* DWC_HOST_ONLY */
891 DEVICE_ATTR(disconnect_us, S_IWUSR, 0, disconnect_us);
894 * Dump global registers and either host or device registers (depending on the
895 * current mode of the core).
897 static ssize_t regdump_show(struct device *_dev,
898 struct device_attribute *attr, char *buf)
900 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
902 dwc_otg_dump_global_registers(otg_dev->core_if);
903 if (dwc_otg_is_host_mode(otg_dev->core_if)) {
904 dwc_otg_dump_host_registers(otg_dev->core_if);
906 dwc_otg_dump_dev_registers(otg_dev->core_if);
909 return sprintf(buf, "Register Dump\n");
912 DEVICE_ATTR(regdump, S_IRUGO, regdump_show, 0);
915 * Dump global registers and either host or device registers (depending on the
916 * current mode of the core).
918 static ssize_t spramdump_show(struct device *_dev,
919 struct device_attribute *attr, char *buf)
922 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
924 dwc_otg_dump_spram(otg_dev->core_if);
927 return sprintf(buf, "SPRAM Dump\n");
930 DEVICE_ATTR(spramdump, S_IRUGO, spramdump_show, 0);
933 * Dump the current hcd state.
935 static ssize_t hcddump_show(struct device *_dev,
936 struct device_attribute *attr, char *buf)
938 #ifndef DWC_DEVICE_ONLY
939 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
940 dwc_otg_hcd_dump_state(otg_dev->hcd);
941 #endif /* DWC_DEVICE_ONLY */
942 return sprintf(buf, "HCD Dump\n");
945 DEVICE_ATTR(hcddump, S_IRUGO, hcddump_show, 0);
948 * Dump the average frame remaining at SOF. This can be used to
949 * determine average interrupt latency. Frame remaining is also shown for
950 * start transfer and two additional sample points.
952 static ssize_t hcd_frrem_show(struct device *_dev,
953 struct device_attribute *attr, char *buf)
955 #ifndef DWC_DEVICE_ONLY
956 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
958 dwc_otg_hcd_dump_frrem(otg_dev->hcd);
959 #endif /* DWC_DEVICE_ONLY */
960 return sprintf(buf, "HCD Dump Frame Remaining\n");
963 DEVICE_ATTR(hcd_frrem, S_IRUGO, hcd_frrem_show, 0);
966 * Displays the time required to read the GNPTXFSIZ register many times (the
967 * output shows the number of times the register is read).
969 #define RW_REG_COUNT 10000000
970 #define MSEC_PER_JIFFIE 1000/HZ
971 static ssize_t rd_reg_test_show(struct device *_dev,
972 struct device_attribute *attr, char *buf)
974 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
979 printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
980 HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
981 start_jiffies = jiffies;
982 for (i = 0; i < RW_REG_COUNT; i++) {
983 dwc_otg_get_gnptxfsiz(otg_dev->core_if);
985 time = jiffies - start_jiffies;
987 "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
988 RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
991 DEVICE_ATTR(rd_reg_test, S_IRUGO, rd_reg_test_show, 0);
994 * Displays the time required to write the GNPTXFSIZ register many times (the
995 * output shows the number of times the register is written).
997 static ssize_t wr_reg_test_show(struct device *_dev,
998 struct device_attribute *attr, char *buf)
1000 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1006 printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
1007 HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
1008 reg_val = dwc_otg_get_gnptxfsiz(otg_dev->core_if);
1009 start_jiffies = jiffies;
1010 for (i = 0; i < RW_REG_COUNT; i++) {
1011 dwc_otg_set_gnptxfsiz(otg_dev->core_if, reg_val);
1013 time = jiffies - start_jiffies;
1015 "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
1016 RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
1019 DEVICE_ATTR(wr_reg_test, S_IRUGO, wr_reg_test_show, 0);
1021 #ifdef CONFIG_USB_DWC_OTG_LPM
1024 * Show the lpm_response attribute.
1026 static ssize_t lpmresp_show(struct device *_dev,
1027 struct device_attribute *attr, char *buf)
1029 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1031 if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
1032 return sprintf(buf, "** LPM is DISABLED **\n");
1034 if (!dwc_otg_is_device_mode(otg_dev->core_if)) {
1035 return sprintf(buf, "** Current mode is not device mode\n");
1037 return sprintf(buf, "lpm_response = %d\n",
1038 dwc_otg_get_lpmresponse(otg_dev->core_if));
1042 * Store the lpm_response attribute.
1044 static ssize_t lpmresp_store(struct device *_dev,
1045 struct device_attribute *attr,
1046 const char *buf, size_t count)
1048 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1049 uint32_t val = simple_strtoul(buf, NULL, 16);
1051 if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if)) {
1055 if (!dwc_otg_is_device_mode(otg_dev->core_if)) {
1059 dwc_otg_set_lpmresponse(otg_dev->core_if, val);
1063 DEVICE_ATTR(lpm_response, S_IRUGO | S_IWUSR, lpmresp_show, lpmresp_store);
1066 * Show the sleep_status attribute.
1068 static ssize_t sleepstatus_show(struct device *_dev,
1069 struct device_attribute *attr, char *buf)
1071 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1072 return sprintf(buf, "Sleep Status = %d\n",
1073 dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if));
1077 * Store the sleep_status attribure.
1079 static ssize_t sleepstatus_store(struct device *_dev,
1080 struct device_attribute *attr,
1081 const char *buf, size_t count)
1083 dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1084 dwc_otg_core_if_t *core_if = otg_dev->core_if;
1086 if (dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if)) {
1087 if (dwc_otg_is_host_mode(core_if)) {
1089 DWC_PRINTF("Host initiated resume\n");
1090 dwc_otg_set_prtresume(otg_dev->core_if, 1);
1097 DEVICE_ATTR(sleep_status, S_IRUGO | S_IWUSR, sleepstatus_show,
1100 #endif /* CONFIG_USB_DWC_OTG_LPM_ENABLE */
1105 * Create the device files
1107 void dwc_otg_attr_create(
1109 struct lm_device *dev
1110 #elif defined(PCI_INTERFACE)
1112 #elif defined(PLATFORM_INTERFACE)
1113 struct platform_device *dev
1119 error = device_create_file(&dev->dev, &dev_attr_regoffset);
1120 error = device_create_file(&dev->dev, &dev_attr_regvalue);
1121 error = device_create_file(&dev->dev, &dev_attr_mode);
1122 error = device_create_file(&dev->dev, &dev_attr_hnpcapable);
1123 error = device_create_file(&dev->dev, &dev_attr_srpcapable);
1124 error = device_create_file(&dev->dev, &dev_attr_hsic_connect);
1125 error = device_create_file(&dev->dev, &dev_attr_inv_sel_hsic);
1126 error = device_create_file(&dev->dev, &dev_attr_hnp);
1127 error = device_create_file(&dev->dev, &dev_attr_srp);
1128 error = device_create_file(&dev->dev, &dev_attr_buspower);
1129 error = device_create_file(&dev->dev, &dev_attr_bussuspend);
1130 error = device_create_file(&dev->dev, &dev_attr_mode_ch_tim_en);
1131 error = device_create_file(&dev->dev, &dev_attr_fr_interval);
1132 error = device_create_file(&dev->dev, &dev_attr_busconnected);
1133 error = device_create_file(&dev->dev, &dev_attr_gotgctl);
1134 error = device_create_file(&dev->dev, &dev_attr_gusbcfg);
1135 error = device_create_file(&dev->dev, &dev_attr_grxfsiz);
1136 error = device_create_file(&dev->dev, &dev_attr_gnptxfsiz);
1137 error = device_create_file(&dev->dev, &dev_attr_gpvndctl);
1138 error = device_create_file(&dev->dev, &dev_attr_ggpio);
1139 error = device_create_file(&dev->dev, &dev_attr_guid);
1140 error = device_create_file(&dev->dev, &dev_attr_gsnpsid);
1141 error = device_create_file(&dev->dev, &dev_attr_devspeed);
1142 error = device_create_file(&dev->dev, &dev_attr_enumspeed);
1143 error = device_create_file(&dev->dev, &dev_attr_hptxfsiz);
1144 error = device_create_file(&dev->dev, &dev_attr_hprt0);
1145 error = device_create_file(&dev->dev, &dev_attr_remote_wakeup);
1146 error = device_create_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn);
1147 error = device_create_file(&dev->dev, &dev_attr_disconnect_us);
1148 error = device_create_file(&dev->dev, &dev_attr_regdump);
1149 error = device_create_file(&dev->dev, &dev_attr_spramdump);
1150 error = device_create_file(&dev->dev, &dev_attr_hcddump);
1151 error = device_create_file(&dev->dev, &dev_attr_hcd_frrem);
1152 error = device_create_file(&dev->dev, &dev_attr_rd_reg_test);
1153 error = device_create_file(&dev->dev, &dev_attr_wr_reg_test);
1154 #ifdef CONFIG_USB_DWC_OTG_LPM
1155 error = device_create_file(&dev->dev, &dev_attr_lpm_response);
1156 error = device_create_file(&dev->dev, &dev_attr_sleep_status);
1161 * Remove the device files
1163 void dwc_otg_attr_remove(
1165 struct lm_device *dev
1166 #elif defined(PCI_INTERFACE)
1168 #elif defined(PLATFORM_INTERFACE)
1169 struct platform_device *dev
1173 device_remove_file(&dev->dev, &dev_attr_regoffset);
1174 device_remove_file(&dev->dev, &dev_attr_regvalue);
1175 device_remove_file(&dev->dev, &dev_attr_mode);
1176 device_remove_file(&dev->dev, &dev_attr_hnpcapable);
1177 device_remove_file(&dev->dev, &dev_attr_srpcapable);
1178 device_remove_file(&dev->dev, &dev_attr_hsic_connect);
1179 device_remove_file(&dev->dev, &dev_attr_inv_sel_hsic);
1180 device_remove_file(&dev->dev, &dev_attr_hnp);
1181 device_remove_file(&dev->dev, &dev_attr_srp);
1182 device_remove_file(&dev->dev, &dev_attr_buspower);
1183 device_remove_file(&dev->dev, &dev_attr_bussuspend);
1184 device_remove_file(&dev->dev, &dev_attr_mode_ch_tim_en);
1185 device_remove_file(&dev->dev, &dev_attr_fr_interval);
1186 device_remove_file(&dev->dev, &dev_attr_busconnected);
1187 device_remove_file(&dev->dev, &dev_attr_gotgctl);
1188 device_remove_file(&dev->dev, &dev_attr_gusbcfg);
1189 device_remove_file(&dev->dev, &dev_attr_grxfsiz);
1190 device_remove_file(&dev->dev, &dev_attr_gnptxfsiz);
1191 device_remove_file(&dev->dev, &dev_attr_gpvndctl);
1192 device_remove_file(&dev->dev, &dev_attr_ggpio);
1193 device_remove_file(&dev->dev, &dev_attr_guid);
1194 device_remove_file(&dev->dev, &dev_attr_gsnpsid);
1195 device_remove_file(&dev->dev, &dev_attr_devspeed);
1196 device_remove_file(&dev->dev, &dev_attr_enumspeed);
1197 device_remove_file(&dev->dev, &dev_attr_hptxfsiz);
1198 device_remove_file(&dev->dev, &dev_attr_hprt0);
1199 device_remove_file(&dev->dev, &dev_attr_remote_wakeup);
1200 device_remove_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn);
1201 device_remove_file(&dev->dev, &dev_attr_disconnect_us);
1202 device_remove_file(&dev->dev, &dev_attr_regdump);
1203 device_remove_file(&dev->dev, &dev_attr_spramdump);
1204 device_remove_file(&dev->dev, &dev_attr_hcddump);
1205 device_remove_file(&dev->dev, &dev_attr_hcd_frrem);
1206 device_remove_file(&dev->dev, &dev_attr_rd_reg_test);
1207 device_remove_file(&dev->dev, &dev_attr_wr_reg_test);
1208 #ifdef CONFIG_USB_DWC_OTG_LPM
1209 device_remove_file(&dev->dev, &dev_attr_lpm_response);
1210 device_remove_file(&dev->dev, &dev_attr_sleep_status);