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.
302 <td> hird_thres </td>
303 <td> Gets or sets the "HIRD_Thres[3:0]" bits in the Core LPM Configuration Register.
308 <td> besl_reject </td>
309 <td> Gets or sets the "besl_reject" bit in the Device Control Register.
316 To get the current mode:
317 cat /sys/devices/lm0/mode
319 To power down the USB:
320 echo 0 > /sys/devices/lm0/buspower
323 #include "dwc_otg_os_dep.h"
324 #include "common_port/dwc_os.h"
325 #include "dwc_otg_driver.h"
326 #include "dwc_otg_attr.h"
327 #include "dwc_otg_core_if.h"
328 #include "dwc_otg_pcd_if.h"
329 #include "dwc_otg_hcd_if.h"
330 #include "dwc_otg_regs.h"
331 #include "dwc_otg_cil.h"
332 #include "usbdev_rk.h"
335 * MACROs for defining sysfs attribute
338 #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, _string_) \
339 static ssize_t _otg_attr_name_##_show(struct device *_dev, struct device_attribute *attr, char *buf) \
342 dwc_otg_device_t *otg_dev = _dev->platform_data; \
344 val = dwc_otg_get_##_otg_attr_name_(otg_dev->core_if); \
345 return sprintf(buf, "%s = 0x%x\n", _string_, val); \
347 #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_, _string_) \
348 static ssize_t _otg_attr_name_##_store(struct device *_dev, struct device_attribute *attr, \
349 const char *buf, size_t count) \
352 dwc_otg_device_t *otg_dev = _dev->platform_data; \
353 uint32_t set = simple_strtoul(buf, NULL, 16); \
354 dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
359 * MACROs for defining sysfs attribute for 32-bit registers
362 #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _string_) \
363 static ssize_t _otg_attr_name_##_show(struct device *_dev, struct device_attribute *attr, char *buf) \
366 dwc_otg_device_t *otg_dev = _dev->platform_data; \
368 val = dwc_otg_get_##_otg_attr_name_(otg_dev->core_if); \
369 return sprintf(buf, "%s = 0x%08x\n", _string_, val); \
371 #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_, _string_) \
372 static ssize_t _otg_attr_name_##_store(struct device *_dev, struct device_attribute *attr, \
373 const char *buf, size_t count) \
376 dwc_otg_device_t *otg_dev = _dev->platform_data; \
377 uint32_t val = simple_strtoul(buf, NULL, 16); \
378 dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, val); \
382 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_, _string_) \
383 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, _string_) \
384 DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_, _string_) \
385 DEVICE_ATTR(_otg_attr_name_, 0644, _otg_attr_name_##_show, \
386 _otg_attr_name_##_store);
388 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_, _string_) \
389 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, _string_) \
390 DEVICE_ATTR(_otg_attr_name_, 0444, _otg_attr_name_##_show, NULL);
392 #define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_, _addr_, _string_) \
393 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _string_) \
394 DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_, _string_) \
395 DEVICE_ATTR(_otg_attr_name_, 0644, _otg_attr_name_##_show, \
396 _otg_attr_name_##_store);
398 #define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_, _addr_, _string_) \
399 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _string_) \
400 DEVICE_ATTR(_otg_attr_name_, 0444, _otg_attr_name_##_show, NULL);
402 void dwc_set_device_platform_data(struct platform_device *pdev, void *data)
404 if (NULL == pdev || NULL == &pdev->dev)
405 DWC_ERROR("NULL Pointer in func %s \n", __func__);
407 pdev->dev.platform_data = data;
410 void *dwc_get_device_platform_data(const struct platform_device *pdev)
412 if (NULL == pdev || NULL == &pdev->dev)
413 DWC_ERROR("NULL Pointer in func %s \n", __func__);
415 return pdev->dev.platform_data;
418 /** @name Functions for Show/Store of Attributes */
422 * Show the register offset of the Register Access.
424 static ssize_t regoffset_show(struct device *_dev,
425 struct device_attribute *attr, char *buf)
428 dwc_otg_device_t *otg_dev = _dev->platform_data;
430 return snprintf(buf, sizeof("0xFFFFFFFF\n") + 1, "0x%08x\n",
431 otg_dev->os_dep.reg_offset);
435 * Set the register offset for the next Register Access Read/Write
437 static ssize_t regoffset_store(struct device *_dev,
438 struct device_attribute *attr,
439 const char *buf, size_t count)
442 dwc_otg_device_t *otg_dev = _dev->platform_data;
443 uint32_t offset = simple_strtoul(buf, NULL, 16);
445 if (offset < SZ_256K)
446 otg_dev->os_dep.reg_offset = offset;
448 dev_err(_dev, "invalid offset\n");
453 DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store);
456 * Show the value of the register at the offset in the reg_offset
459 static ssize_t regvalue_show(struct device *_dev,
460 struct device_attribute *attr, char *buf)
463 dwc_otg_device_t *otg_dev = _dev->platform_data;
465 volatile uint32_t *addr;
467 if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF
468 && 0 != otg_dev->os_dep.base) {
469 /* Calculate the address */
470 addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
471 (uint8_t *) otg_dev->os_dep.base);
472 val = DWC_READ_REG32(addr);
474 sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n") + 1,
475 "Reg@0x%06x = 0x%08x\n",
476 otg_dev->os_dep.reg_offset, val);
478 dev_err(_dev, "Invalid offset (0x%0x)\n",
479 otg_dev->os_dep.reg_offset);
480 return sprintf(buf, "invalid offset\n");
485 * Store the value in the register at the offset in the reg_offset
489 static ssize_t regvalue_store(struct device *_dev,
490 struct device_attribute *attr,
491 const char *buf, size_t count)
494 dwc_otg_device_t *otg_dev = _dev->platform_data;
495 volatile uint32_t *addr;
496 uint32_t val = simple_strtoul(buf, NULL, 16);
497 /* dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n",
498 * otg_dev->reg_offset, val);
500 if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF
501 && 0 != otg_dev->os_dep.base) {
502 /* Calculate the address */
503 addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
504 (uint8_t *) otg_dev->os_dep.base);
505 DWC_WRITE_REG32(addr, val);
507 dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
508 otg_dev->os_dep.reg_offset);
513 DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store);
518 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode, "Mode");
519 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable, "HNPCapable");
520 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable, "SRPCapable");
521 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hsic_connect, "HSIC Connect");
522 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(inv_sel_hsic, "Invert Select HSIC");
524 /* DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,
525 * &(otg_dev->core_if->core_global_regs->gotgctl), (1<<8), 8, "Mode");
527 /* DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,
528 * &(otg_dev->core_if->core_global_regs->gotgctl), (1<<8), 8, "Mode");
530 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, "Bus Connected");
532 DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl, 0, "GOTGCTL");
533 DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,
534 &(otg_dev->core_if->core_global_regs->gusbcfg),
536 DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,
537 &(otg_dev->core_if->core_global_regs->grxfsiz),
539 DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,
540 &(otg_dev->core_if->core_global_regs->gnptxfsiz),
542 DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,
543 &(otg_dev->core_if->core_global_regs->gpvndctl),
545 DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,
546 &(otg_dev->core_if->core_global_regs->ggpio),
548 DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid),
550 DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,
551 &(otg_dev->core_if->core_global_regs->gsnpsid),
553 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed, "Device Speed");
554 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed, "Device Enumeration Speed");
556 DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,
557 &(otg_dev->core_if->core_global_regs->hptxfsiz),
559 DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0");
562 * @todo Need to do more for power on/off?
565 * Show the Bus Power status
567 static ssize_t buspower_show(struct device *_dev,
568 struct device_attribute *attr, char *buf)
571 dwc_otg_device_t *otg_dev = _dev->platform_data;
572 return sprintf(buf, "Bus Power = 0x%x\n",
573 dwc_otg_get_prtpower(otg_dev->core_if));
577 * Set the Bus Power status
579 static ssize_t buspower_store(struct device *_dev,
580 struct device_attribute *attr,
581 const char *buf, size_t count)
583 dwc_otg_device_t *otg_dev = _dev->platform_data;
584 struct dwc_otg_platform_data *pldata = otg_dev->pldata;
585 uint32_t on = simple_strtoul(buf, NULL, 16);
587 if (on != 0 && on != 1)
590 dwc_otg_set_prtpower(otg_dev->core_if, on);
591 pldata->power_enable(on);
595 DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
598 * @todo Need to do more for suspend?
601 * Show the Bus Suspend status
603 static ssize_t bussuspend_show(struct device *_dev,
604 struct device_attribute *attr, char *buf)
607 dwc_otg_device_t *otg_dev = _dev->platform_data;
608 return sprintf(buf, "Bus Suspend = 0x%x\n",
609 dwc_otg_get_prtsuspend(otg_dev->core_if));
613 * Set the Bus Suspend status
615 static ssize_t bussuspend_store(struct device *_dev,
616 struct device_attribute *attr,
617 const char *buf, size_t count)
620 dwc_otg_device_t *otg_dev = _dev->platform_data;
621 uint32_t in = simple_strtoul(buf, NULL, 16);
622 dwc_otg_set_prtsuspend(otg_dev->core_if, in);
626 DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
629 * Show the Mode Change Ready Timer status
631 static ssize_t mode_ch_tim_en_show(struct device *_dev,
632 struct device_attribute *attr, char *buf)
635 dwc_otg_device_t *otg_dev = _dev->platform_data;
636 return sprintf(buf, "Mode Change Ready Timer Enable = 0x%x\n",
637 dwc_otg_get_mode_ch_tim(otg_dev->core_if));
641 * Set the Mode Change Ready Timer status
643 static ssize_t mode_ch_tim_en_store(struct device *_dev,
644 struct device_attribute *attr,
645 const char *buf, size_t count)
648 dwc_otg_device_t *otg_dev = _dev->platform_data;
649 uint32_t in = simple_strtoul(buf, NULL, 16);
650 dwc_otg_set_mode_ch_tim(otg_dev->core_if, in);
654 DEVICE_ATTR(mode_ch_tim_en, 0644, mode_ch_tim_en_show, mode_ch_tim_en_store);
657 * Show the value of HFIR Frame Interval bitfield
659 static ssize_t fr_interval_show(struct device *_dev,
660 struct device_attribute *attr, char *buf)
663 dwc_otg_device_t *otg_dev = _dev->platform_data;
664 return sprintf(buf, "Frame Interval = 0x%x\n",
665 dwc_otg_get_fr_interval(otg_dev->core_if));
669 * Set the HFIR Frame Interval value
671 static ssize_t fr_interval_store(struct device *_dev,
672 struct device_attribute *attr,
673 const char *buf, size_t count)
676 dwc_otg_device_t *otg_dev = _dev->platform_data;
677 uint32_t in = simple_strtoul(buf, NULL, 10);
678 dwc_otg_set_fr_interval(otg_dev->core_if, in);
682 DEVICE_ATTR(fr_interval, 0644, fr_interval_show, fr_interval_store);
685 * Show the status of Remote Wakeup.
687 static ssize_t remote_wakeup_show(struct device *_dev,
688 struct device_attribute *attr, char *buf)
690 #ifndef DWC_HOST_ONLY
692 dwc_otg_device_t *otg_dev = _dev->platform_data;
694 "Remote Wakeup Sig = %d\n",
695 dwc_otg_get_remotewakesig(otg_dev->core_if));
697 return sprintf(buf, "Host Only Mode!\n");
698 #endif /* DWC_HOST_ONLY */
702 * Initiate a remote wakeup of the host. The Device control register
703 * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
707 static ssize_t remote_wakeup_store(struct device *_dev,
708 struct device_attribute *attr,
709 const char *buf, size_t count)
711 #ifndef DWC_HOST_ONLY
713 dwc_otg_device_t *otg_dev = _dev->platform_data;
714 uint32_t val = simple_strtoul(buf, NULL, 16);
717 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
719 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
721 #endif /* DWC_HOST_ONLY */
725 DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show,
726 remote_wakeup_store);
729 * Show the whether core is hibernated or not.
731 static ssize_t rem_wakeup_pwrdn_show(struct device *_dev,
732 struct device_attribute *attr, char *buf)
734 #ifndef DWC_HOST_ONLY
736 dwc_otg_device_t *otg_dev = _dev->platform_data;
737 if (dwc_otg_get_core_state(otg_dev->core_if))
738 DWC_PRINTF("Core is in hibernation\n");
740 DWC_PRINTF("Core is not in hibernation\n");
742 #endif /* DWC_HOST_ONLY */
746 extern int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t *core_if,
747 int rem_wakeup, int reset);
750 * Initiate a remote wakeup of the device to exit from hibernation.
752 static ssize_t rem_wakeup_pwrdn_store(struct device *_dev,
753 struct device_attribute *attr,
754 const char *buf, size_t count)
756 #ifndef DWC_HOST_ONLY
758 dwc_otg_device_t *otg_dev = _dev->platform_data;
759 dwc_otg_device_hibernation_restore(otg_dev->core_if, 1, 0);
764 DEVICE_ATTR(rem_wakeup_pwrdn, S_IRUGO | S_IWUSR, rem_wakeup_pwrdn_show,
765 rem_wakeup_pwrdn_store);
767 static ssize_t disconnect_us(struct device *_dev,
768 struct device_attribute *attr,
769 const char *buf, size_t count)
772 #ifndef DWC_HOST_ONLY
774 dwc_otg_device_t *otg_dev = _dev->platform_data;
775 uint32_t val = simple_strtoul(buf, NULL, 16);
776 DWC_PRINTF("The Passed value is %04x\n", val);
778 dwc_otg_pcd_disconnect_us(otg_dev->pcd, 50);
780 #endif /* DWC_HOST_ONLY */
784 DEVICE_ATTR(disconnect_us, S_IWUSR, 0, disconnect_us);
787 * Dump global registers and either host or device registers (depending on the
788 * current mode of the core).
790 static ssize_t regdump_show(struct device *_dev,
791 struct device_attribute *attr, char *buf)
794 dwc_otg_device_t *otg_dev = _dev->platform_data;
795 dwc_otg_dump_global_registers(otg_dev->core_if);
796 if (dwc_otg_is_host_mode(otg_dev->core_if))
797 dwc_otg_dump_host_registers(otg_dev->core_if);
799 dwc_otg_dump_dev_registers(otg_dev->core_if);
801 return sprintf(buf, "Register Dump\n");
804 DEVICE_ATTR(regdump, S_IRUGO, regdump_show, 0);
807 * Dump global registers and either host or device registers (depending on the
808 * current mode of the core).
810 static ssize_t spramdump_show(struct device *_dev,
811 struct device_attribute *attr, char *buf)
814 dwc_otg_device_t *otg_dev = _dev->platform_data;
815 dwc_otg_dump_spram(otg_dev->core_if);
817 return sprintf(buf, "SPRAM Dump\n");
820 DEVICE_ATTR(spramdump, S_IRUGO, spramdump_show, 0);
823 * Dump the current hcd state.
825 static ssize_t hcddump_show(struct device *_dev,
826 struct device_attribute *attr, char *buf)
828 #ifndef DWC_DEVICE_ONLY
830 dwc_otg_device_t *otg_dev = _dev->platform_data;
831 dwc_otg_hcd_dump_state(otg_dev->hcd);
832 #endif /* DWC_DEVICE_ONLY */
833 return sprintf(buf, "HCD Dump\n");
836 DEVICE_ATTR(hcddump, S_IRUGO, hcddump_show, 0);
839 * Dump the average frame remaining at SOF. This can be used to
840 * determine average interrupt latency. Frame remaining is also shown for
841 * start transfer and two additional sample points.
843 static ssize_t hcd_frrem_show(struct device *_dev,
844 struct device_attribute *attr, char *buf)
846 #ifndef DWC_DEVICE_ONLY
848 dwc_otg_device_t *otg_dev = _dev->platform_data;
849 dwc_otg_hcd_dump_frrem(otg_dev->hcd);
850 #endif /* DWC_DEVICE_ONLY */
851 return sprintf(buf, "HCD Dump Frame Remaining\n");
854 DEVICE_ATTR(hcd_frrem, S_IRUGO, hcd_frrem_show, 0);
857 * Displays the time required to read the GNPTXFSIZ register many times (the
858 * output shows the number of times the register is read).
860 #define RW_REG_COUNT 10000000
861 #define MSEC_PER_JIFFIE (1000/HZ)
862 static ssize_t rd_reg_test_show(struct device *_dev,
863 struct device_attribute *attr, char *buf)
866 dwc_otg_device_t *otg_dev = _dev->platform_data;
871 printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
872 HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
873 start_jiffies = jiffies;
874 for (i = 0; i < RW_REG_COUNT; i++)
875 dwc_otg_get_gnptxfsiz(otg_dev->core_if);
876 time = jiffies - start_jiffies;
878 "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
879 RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
882 DEVICE_ATTR(rd_reg_test, S_IRUGO, rd_reg_test_show, 0);
885 * Displays the time required to write the GNPTXFSIZ register many times (the
886 * output shows the number of times the register is written).
888 static ssize_t wr_reg_test_show(struct device *_dev,
889 struct device_attribute *attr, char *buf)
892 dwc_otg_device_t *otg_dev = _dev->platform_data;
898 printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
899 HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
900 reg_val = dwc_otg_get_gnptxfsiz(otg_dev->core_if);
901 start_jiffies = jiffies;
902 for (i = 0; i < RW_REG_COUNT; i++)
903 dwc_otg_set_gnptxfsiz(otg_dev->core_if, reg_val);
904 time = jiffies - start_jiffies;
906 "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
907 RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
910 DEVICE_ATTR(wr_reg_test, S_IRUGO, wr_reg_test_show, 0);
912 #ifdef CONFIG_USB_DWC_OTG_LPM
915 * Show the lpm_response attribute.
917 static ssize_t lpmresp_show(struct device *_dev,
918 struct device_attribute *attr, char *buf)
921 dwc_otg_device_t *otg_dev = _dev->platform_data;
922 if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
923 return sprintf(buf, "** LPM is DISABLED **\n");
925 if (!dwc_otg_is_device_mode(otg_dev->core_if))
926 return sprintf(buf, "** Current mode is not device mode\n");
928 return sprintf(buf, "lpm_response = %d\n",
929 dwc_otg_get_lpmresponse(otg_dev->core_if));
933 * Store the lpm_response attribute.
935 static ssize_t lpmresp_store(struct device *_dev,
936 struct device_attribute *attr,
937 const char *buf, size_t count)
940 dwc_otg_device_t *otg_dev = _dev->platform_data;
941 uint32_t val = simple_strtoul(buf, NULL, 16);
943 if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
946 if (!dwc_otg_is_device_mode(otg_dev->core_if))
949 dwc_otg_set_lpmresponse(otg_dev->core_if, val);
953 DEVICE_ATTR(lpm_response, S_IRUGO | S_IWUSR, lpmresp_show, lpmresp_store);
956 * Show the besl_reject attribute.
958 static ssize_t beslreject_show(struct device *_dev,
959 struct device_attribute *attr, char *buf)
962 dwc_otg_device_t *otg_dev = _dev->platform_data;
964 if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
965 return sprintf(buf, "** LPM is DISABLED **\n");
966 if (!dwc_otg_get_param_besl_enable(otg_dev->core_if))
967 return sprintf(buf, "** EnBesl is DISABLED **\n");
969 if (!dwc_otg_is_device_mode(otg_dev->core_if))
970 return sprintf(buf, "** Current mode is not device mode\n");
972 return sprintf(buf, "besl_reject = %d\n",
973 dwc_otg_get_beslreject(otg_dev->core_if));
977 * Store the besl_reject attribute.
979 static ssize_t beslreject_store(struct device *_dev,
980 struct device_attribute *attr,
981 const char *buf, size_t count)
984 dwc_otg_device_t *otg_dev = _dev->platform_data;
985 uint32_t val = simple_strtoul(buf, NULL, 16);
987 if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
990 if (!dwc_otg_get_param_besl_enable(otg_dev->core_if))
993 if (!dwc_otg_is_device_mode(otg_dev->core_if))
996 dwc_otg_set_beslreject(otg_dev->core_if, val);
1001 DEVICE_ATTR(besl_reject, S_IRUGO | S_IWUSR, beslreject_show, beslreject_store);
1004 * Show the hird_thresh attribute.
1006 static ssize_t hirdthresh_show(struct device *_dev,
1007 struct device_attribute *attr, char *buf)
1010 dwc_otg_device_t *otg_dev = _dev->platform_data;
1012 if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
1013 return sprintf(buf, "** LPM is DISABLED **\n");
1015 if (!dwc_otg_is_device_mode(otg_dev->core_if))
1016 return sprintf(buf, "** Current mode is not device mode\n");
1018 return sprintf(buf, "hirdthresh = 0x%x\n",
1019 dwc_otg_get_hirdthresh(otg_dev->core_if));
1023 * Store the hird_thresh attribute.
1025 static ssize_t hirdthresh_store(struct device *_dev,
1026 struct device_attribute *attr,
1027 const char *buf, size_t count)
1030 dwc_otg_device_t *otg_dev = _dev->platform_data;
1032 uint32_t val = simple_strtoul(buf, NULL, 16);
1034 if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
1037 if (!dwc_otg_is_device_mode(otg_dev->core_if))
1040 dwc_otg_set_hirdthresh(otg_dev->core_if, val);
1045 DEVICE_ATTR(hird_thres, S_IRUGO | S_IWUSR, hirdthresh_show, hirdthresh_store);
1048 * Show the sleep_status attribute.
1050 static ssize_t sleepstatus_show(struct device *_dev,
1051 struct device_attribute *attr, char *buf)
1054 dwc_otg_device_t *otg_dev = _dev->platform_data;
1055 return sprintf(buf, "Sleep Status = %d\n",
1056 dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if));
1060 * Store the sleep_status attribure.
1062 static ssize_t sleepstatus_store(struct device *_dev,
1063 struct device_attribute *attr,
1064 const char *buf, size_t count)
1067 dwc_otg_device_t *otg_dev = _dev->platform_data;
1068 dwc_otg_core_if_t *core_if = otg_dev->core_if;
1070 if (dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if)) {
1071 if (dwc_otg_is_host_mode(core_if)) {
1073 DWC_PRINTF("Host initiated resume\n");
1074 dwc_otg_set_prtresume(otg_dev->core_if, 1);
1081 DEVICE_ATTR(sleep_status, S_IRUGO | S_IWUSR, sleepstatus_show,
1084 #endif /* CONFIG_USB_DWC_OTG_LPM_ENABLE */
1086 static int test_sq(dwc_otg_core_if_t *core_if)
1088 hprt0_data_t hprt0 = { .d32 = 0 };
1089 dctl_data_t dctl = { .d32 = 0 };
1090 dsts_data_t dsts = { .d32 = 0 };
1093 * Step.1 check current mode
1094 * Step.2 check connection
1095 * Step.3 enter test packet mode
1098 if (dwc_otg_is_host_mode(core_if)) {
1099 DWC_PRINTF("Host Mode\n");
1100 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
1102 if (hprt0.b.prtena && !hprt0.b.prtsusp &&
1103 hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) {
1105 hprt0.b.prttstctl = 0x4;
1106 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
1107 DWC_PRINTF("Start packet test\n");
1111 DWC_PRINTF("Invalid connect status HPRT0 = 0x%08x\n",
1114 DWC_PRINTF("Device Mode\n");
1115 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
1117 if (!dsts.b.suspsts &&
1118 dsts.b.enumspd == DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) {
1119 dctl.b.tstctl = 0x4;
1120 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
1122 DWC_PRINTF("Start packet test\n");
1126 DWC_PRINTF("Invalid connect status DSTS = 0x%08x\n",
1135 * Show the usage of usb controler test_sq attribute.
1137 static ssize_t test_sq_show(struct device *_dev,
1138 struct device_attribute *attr, char *buf)
1141 "USAGE : echo anything to \"test\" to start test packet pattern\n");
1144 static ssize_t test_sq_store(struct device *_dev,
1145 struct device_attribute *attr,
1146 const char *buf, size_t count)
1149 dwc_otg_device_t *otg_dev = _dev->platform_data;
1150 struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1152 if (pldata->phy_status == USB_PHY_SUSPEND) {
1153 DWC_PRINTF("Invalid status : SUSPEND\n");
1157 if (test_sq(otg_dev->core_if))
1163 DEVICE_ATTR(test_sq, S_IWUSR | S_IRUSR, test_sq_show, test_sq_store);
1168 * Create the device files
1170 void dwc_otg_attr_create(struct platform_device *dev)
1174 error = device_create_file(&dev->dev, &dev_attr_regoffset);
1175 error = device_create_file(&dev->dev, &dev_attr_regvalue);
1176 error = device_create_file(&dev->dev, &dev_attr_mode);
1177 error = device_create_file(&dev->dev, &dev_attr_buspower);
1178 error = device_create_file(&dev->dev, &dev_attr_bussuspend);
1179 error = device_create_file(&dev->dev, &dev_attr_mode_ch_tim_en);
1180 error = device_create_file(&dev->dev, &dev_attr_fr_interval);
1181 error = device_create_file(&dev->dev, &dev_attr_busconnected);
1182 error = device_create_file(&dev->dev, &dev_attr_gotgctl);
1183 error = device_create_file(&dev->dev, &dev_attr_gusbcfg);
1184 error = device_create_file(&dev->dev, &dev_attr_grxfsiz);
1185 error = device_create_file(&dev->dev, &dev_attr_gnptxfsiz);
1186 error = device_create_file(&dev->dev, &dev_attr_gpvndctl);
1187 error = device_create_file(&dev->dev, &dev_attr_ggpio);
1188 error = device_create_file(&dev->dev, &dev_attr_guid);
1189 error = device_create_file(&dev->dev, &dev_attr_gsnpsid);
1190 error = device_create_file(&dev->dev, &dev_attr_devspeed);
1191 error = device_create_file(&dev->dev, &dev_attr_enumspeed);
1192 error = device_create_file(&dev->dev, &dev_attr_hptxfsiz);
1193 error = device_create_file(&dev->dev, &dev_attr_hprt0);
1194 error = device_create_file(&dev->dev, &dev_attr_remote_wakeup);
1195 error = device_create_file(&dev->dev, &dev_attr_disconnect_us);
1196 error = device_create_file(&dev->dev, &dev_attr_regdump);
1197 error = device_create_file(&dev->dev, &dev_attr_spramdump);
1198 error = device_create_file(&dev->dev, &dev_attr_hcddump);
1199 error = device_create_file(&dev->dev, &dev_attr_hcd_frrem);
1200 error = device_create_file(&dev->dev, &dev_attr_rd_reg_test);
1201 error = device_create_file(&dev->dev, &dev_attr_wr_reg_test);
1202 #ifdef CONFIG_USB_DWC_OTG_LPM
1203 error = device_create_file(&dev->dev, &dev_attr_lpm_response);
1204 error = device_create_file(&dev->dev, &dev_attr_sleep_status);
1205 error = device_create_file(&dev->dev, &dev_attr_besl_reject);
1206 error = device_create_file(&dev->dev, &dev_attr_hird_thres);
1208 error = device_create_file(&dev->dev, &dev_attr_test_sq);
1212 * Remove the device files
1214 void dwc_otg_attr_remove(struct platform_device *dev)
1216 device_remove_file(&dev->dev, &dev_attr_regoffset);
1217 device_remove_file(&dev->dev, &dev_attr_regvalue);
1218 device_remove_file(&dev->dev, &dev_attr_mode);
1219 device_remove_file(&dev->dev, &dev_attr_buspower);
1220 device_remove_file(&dev->dev, &dev_attr_bussuspend);
1221 device_remove_file(&dev->dev, &dev_attr_mode_ch_tim_en);
1222 device_remove_file(&dev->dev, &dev_attr_fr_interval);
1223 device_remove_file(&dev->dev, &dev_attr_busconnected);
1224 device_remove_file(&dev->dev, &dev_attr_gotgctl);
1225 device_remove_file(&dev->dev, &dev_attr_gusbcfg);
1226 device_remove_file(&dev->dev, &dev_attr_grxfsiz);
1227 device_remove_file(&dev->dev, &dev_attr_gnptxfsiz);
1228 device_remove_file(&dev->dev, &dev_attr_gpvndctl);
1229 device_remove_file(&dev->dev, &dev_attr_ggpio);
1230 device_remove_file(&dev->dev, &dev_attr_guid);
1231 device_remove_file(&dev->dev, &dev_attr_gsnpsid);
1232 device_remove_file(&dev->dev, &dev_attr_devspeed);
1233 device_remove_file(&dev->dev, &dev_attr_enumspeed);
1234 device_remove_file(&dev->dev, &dev_attr_hptxfsiz);
1235 device_remove_file(&dev->dev, &dev_attr_hprt0);
1236 device_remove_file(&dev->dev, &dev_attr_remote_wakeup);
1237 device_remove_file(&dev->dev, &dev_attr_disconnect_us);
1238 device_remove_file(&dev->dev, &dev_attr_regdump);
1239 device_remove_file(&dev->dev, &dev_attr_spramdump);
1240 device_remove_file(&dev->dev, &dev_attr_hcddump);
1241 device_remove_file(&dev->dev, &dev_attr_hcd_frrem);
1242 device_remove_file(&dev->dev, &dev_attr_rd_reg_test);
1243 device_remove_file(&dev->dev, &dev_attr_wr_reg_test);
1244 #ifdef CONFIG_USB_DWC_OTG_LPM
1245 device_remove_file(&dev->dev, &dev_attr_lpm_response);
1246 device_remove_file(&dev->dev, &dev_attr_sleep_status);
1247 device_remove_file(&dev->dev, &dev_attr_besl_reject);
1248 device_remove_file(&dev->dev, &dev_attr_hird_thres);
1250 device_remove_file(&dev->dev, &dev_attr_test_sq);