| /*******************************************************************************
|
|
|
| This software file (the "File") is distributed by Marvell International Ltd.
|
| or its affiliate(s) under the terms of the GNU General Public License Version 2,
|
| June 1991 (the "License"). You may use, redistribute and/or modify this File
|
| in accordance with the terms and conditions of the License, a copy of which
|
| is available along with the File in the license.txt file or by writing to the
|
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
| or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
|
|
|
| THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
|
| WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
|
| DISCLAIMED. The GPL License provides additional details about this warranty
|
| disclaimer.
|
|
|
| (C) Copyright 2004 - 2007 Marvell Semiconductor Israel Ltd. All Rights Reserved.
|
| (C) Copyright 1999 - 2004 Chipidea Microelectronica, S.A. All Rights Reserved.
|
|
|
| *******************************************************************************/
|
| |
| #include "usb/api/mvUsbDevApi.h" |
| #include "usb/device/mvUsbDevPrv.h" |
| #include "usb/api/mvUsbDefs.h" |
| |
| /* Test packet for Test Mode : TEST_PACKET. USB 2.0 Specification section 7.1.20 */ |
| uint_8 test_packet[USB_TEST_MODE_TEST_PACKET_LENGTH] = |
| { |
| /* Synch */ |
| /* DATA 0 PID */ |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, |
| 0xAA, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, |
| 0xEE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xBF, 0xDF, |
| 0xEF, 0xF7, 0xFB, 0xFD, 0xFC, 0x7E, 0xBF, 0xDF, |
| 0xEF, 0xF7, 0xFB, 0xFD, 0x7E |
| }; |
| |
| /*FUNCTION*------------------------------------------------------------- |
| * |
| * Function Name : _usb_dci_vusb20_assert_resume |
| * Returned Value : None |
| * Comments : |
| * Resume signalling for remote wakeup |
| * |
| *END*-----------------------------------------------------------------*/ |
| void _usb_dci_vusb20_assert_resume |
| ( |
| /* [IN] the USB_dev_initialize state structure */ |
| _usb_device_handle handle |
| ) |
| { /* Body */ |
| USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; |
| VUSB20_REG_STRUCT_PTR dev_ptr; |
| uint_32 temp; |
| |
| usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; |
| dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_dev_ptr->DEV_PTR; |
| |
| /* Assert the Resume signal */ |
| temp = USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]); |
| temp &= ~EHCI_PORTSCX_W1C_BITS; |
| temp |= EHCI_PORTSCX_PORT_FORCE_RESUME; |
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0] = USB_32BIT_LE(temp); |
| |
| /* Port change interrupt will be asserted at the end of resume |
| ** operation |
| */ |
| |
| } /* EndBody */ |
| |
| /*FUNCTION*------------------------------------------------------------- |
| * |
| * Function Name : _usb_dci_vusb20_stall_endpoint |
| * Returned Value : None |
| * Comments : |
| * Stalls the specified endpoint |
| * |
| *END*-----------------------------------------------------------------*/ |
| void _usb_dci_vusb20_stall_endpoint |
| ( |
| /* [IN] the USB_dev_initialize state structure */ |
| _usb_device_handle handle, |
| |
| /* [IN] the Endpoint number */ |
| uint_8 ep_num, |
| |
| /* [IN] direction */ |
| uint_8 direction |
| ) |
| { /* Body */ |
| USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; |
| VUSB20_REG_STRUCT_PTR dev_ptr; |
| VUSB20_EP_QUEUE_HEAD_STRUCT _PTR_ ep_queue_head_ptr; |
| |
| usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; |
| dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_dev_ptr->DEV_PTR; |
| |
| /* Get the endpoint queue head address */ |
| ep_queue_head_ptr = (VUSB20_EP_QUEUE_HEAD_STRUCT_PTR)usb_dev_ptr->EP_QUEUE_HEAD_PTR + |
| 2*ep_num + direction; |
| /* Stall the endpoint for Rx or Tx and set the endpoint type */ |
| if (ep_queue_head_ptr->MAX_PKT_LENGTH & USB_32BIT_LE(VUSB_EP_QUEUE_HEAD_IOS)) |
| { |
| /* This is a control endpoint so STALL both directions */ |
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num] |= |
| USB_32BIT_LE((EHCI_EPCTRL_TX_EP_STALL | EHCI_EPCTRL_RX_EP_STALL)); |
| } |
| else |
| { |
| if(direction) |
| { |
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num] |= |
| USB_32BIT_LE(EHCI_EPCTRL_TX_EP_STALL); |
| } |
| else { |
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num] |= |
| USB_32BIT_LE(EHCI_EPCTRL_RX_EP_STALL); |
| } |
| } /* Endif */
|
|
|
| ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_STALL,
|
| "STALL ep=%d %s: EPCTRLX=0x%x, CURR_dTD=0x%x, NEXT_dTD=0x%x, SIZE=0x%x\n",
|
| ep_num, direction ? "SEND" : "RECV",
|
| (unsigned)USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num]),
|
| (unsigned)USB_32BIT_LE(ep_queue_head_ptr->CURR_DTD_PTR),
|
| (unsigned)USB_32BIT_LE(ep_queue_head_ptr->NEXT_DTD_PTR),
|
| (unsigned)USB_32BIT_LE(ep_queue_head_ptr->SIZE_IOC_INT_STS));
|
| |
| } /* EndBody */ |
| |
| /*FUNCTION*------------------------------------------------------------- |
| * |
| * Function Name : _usb_dci_vusb20_unstall_endpoint |
| * Returned Value : None |
| * Comments : |
| * Unstall the specified endpoint in the specified direction |
| * |
| *END*-----------------------------------------------------------------*/ |
| void _usb_dci_vusb20_unstall_endpoint |
| ( |
| /* [IN] the USB_dev_initialize state structure */ |
| _usb_device_handle handle, |
| |
| /* [IN] the Endpoint number */ |
| uint_8 ep_num, |
| |
| /* [IN] direction */ |
| uint_8 direction |
| ) |
| { /* Body */ |
| USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; |
| VUSB20_REG_STRUCT_PTR dev_ptr; |
| |
| usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; |
| dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_dev_ptr->DEV_PTR; |
| |
| /* Enable the endpoint for Rx or Tx and set the endpoint type */ |
| if(direction) |
| {
|
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num] |=
|
| USB_32BIT_LE(EHCI_EPCTRL_TX_DATA_TOGGLE_RST);
|
| |
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num] &= |
| ~(USB_32BIT_LE(EHCI_EPCTRL_TX_EP_STALL)); |
| } |
| else |
| { |
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num] |=
|
| USB_32BIT_LE(EHCI_EPCTRL_RX_DATA_TOGGLE_RST);
|
|
|
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num] &= |
| ~(USB_32BIT_LE(EHCI_EPCTRL_RX_EP_STALL)); |
| }
|
|
|
| ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_STALL,
|
| "UNSTALL ep=%d %s: EPCTRLX=0x%x\n",
|
| ep_num, direction ? "SEND" : "RECV",
|
| (unsigned)USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num]));
|
|
|
| |
| } /* EndBody */ |
| |
| /*FUNCTION*---------------------------------------------------------------- |
| * |
| * Function Name : _usb_dci_vusb20_is_endpoint_stalled |
| * Returned Value : None |
| * Comments : |
| * Gets the endpoint status |
| * |
| *END*--------------------------------------------------------------------*/ |
| uint_8 _usb_dci_vusb20_is_endpoint_stalled |
| ( |
| /* [IN] Handle to the USB device */ |
| _usb_device_handle handle, |
| |
| /* [IN] Endpoint number */ |
| uint_8 ep,
|
|
|
| /* [IN] Endpoint direction */
|
| uint_8 dir |
| ) |
| { /* Body */ |
| USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; |
| VUSB20_REG_STRUCT_PTR dev_ptr;
|
| uint_32 value; |
| |
| ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_TRACE, "is_endpoint_stalled\n"); |
| |
| usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; |
| dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_dev_ptr->DEV_PTR; |
|
|
| if(dir)
|
| { |
| value = dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep] &
|
| (USB_32BIT_LE(EHCI_EPCTRL_TX_EP_STALL));
|
| }
|
| else
|
| {
|
| value = dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep] &
|
| (USB_32BIT_LE(EHCI_EPCTRL_RX_EP_STALL));
|
| }
|
| return (value) ? 1 : 0; |
| } /* EndBody */ |
| |
| /*FUNCTION*---------------------------------------------------------------- |
| * |
| * Function Name : _usb_dci_vusb20_set_test_mode |
| * Returned Value : None |
| * Comments : |
| * sets/resets the test mode |
| * |
| *END*--------------------------------------------------------------------*/ |
| void _usb_dci_vusb20_set_test_mode |
| ( |
| /* [IN] Handle to the USB device */ |
| _usb_device_handle handle, |
| |
| /* [IN] Test mode */ |
| uint_16 test_mode |
| ) |
| { /* Body */ |
| USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; |
| VUSB20_REG_STRUCT_PTR dev_ptr; |
| uint_32 temp; |
| |
| ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_ANY, "set_test_mode\n"); |
| |
| usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; |
| dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_dev_ptr->DEV_PTR; |
| |
| temp = USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[0]); |
| |
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[0] = |
| USB_32BIT_LE((temp | EHCI_EPCTRL_TX_DATA_TOGGLE_RST)); |
| |
| if (test_mode == ARC_USB_TEST_MODE_TEST_PACKET) |
| { |
| USB_memcopy(test_packet, usb_dev_ptr->TEST_PKT_PTR, USB_TEST_MODE_TEST_PACKET_LENGTH); |
| _usb_device_send_data(handle, 0, usb_dev_ptr->TEST_PKT_PTR, USB_TEST_MODE_TEST_PACKET_LENGTH); |
| |
| } /* Endif */ |
| |
| temp = USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]); |
| temp &= ~EHCI_PORTSCX_W1C_BITS; |
| |
| dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0] = |
| USB_32BIT_LE(temp | ((uint_32)test_mode << 8)); |
| |
| } /* EndBody */ |
| |