mirror of https://github.com/hak5/openwrt.git
600 lines
18 KiB
C
600 lines
18 KiB
C
/*****************************************************************************
|
|
** FILE NAME : ifxhcd_es.c
|
|
** PROJECT : IFX USB sub-system V3
|
|
** MODULES : IFX USB sub-system Host and Device driver
|
|
** SRC VERSION : 1.0
|
|
** DATE : 1/Jan/2009
|
|
** AUTHOR : Chen, Howard
|
|
** DESCRIPTION : The file contain function to enable host mode USB-IF Electrical Test function.
|
|
** FUNCTIONS :
|
|
** COMPILER : gcc
|
|
** REFERENCE : Synopsys DWC-OTG Driver 2.7
|
|
** COPYRIGHT : Copyright (c) 2010
|
|
** LANTIQ DEUTSCHLAND GMBH,
|
|
** Am Campeon 3, 85579 Neubiberg, Germany
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** Version Control Section **
|
|
** $Author$
|
|
** $Date$
|
|
** $Revisions$
|
|
** $Log$ Revision history
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
* This file contains code fragments from Synopsys HS OTG Linux Software Driver.
|
|
* For this code the following notice is applicable:
|
|
*
|
|
* ==========================================================================
|
|
*
|
|
* Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
|
|
* "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
|
|
* otherwise expressly agreed to in writing between Synopsys and you.
|
|
*
|
|
* The Software IS NOT an item of Licensed Software or Licensed Product under
|
|
* any End User Software License Agreement or Agreement for Licensed Product
|
|
* with Synopsys or any supplement thereto. You are permitted to use and
|
|
* redistribute this Software in source and binary forms, with or without
|
|
* modification, provided that redistributions of source code must retain this
|
|
* notice. You may not view, use, disclose, copy or distribute this file or
|
|
* any information contained herein except pursuant to this license grant from
|
|
* Synopsys. If you do not agree with this notice, including the disclaimer
|
|
* below, then you are not authorized to use the Software.
|
|
*
|
|
* THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
* DAMAGE.
|
|
* ========================================================================== */
|
|
|
|
/*!
|
|
\file ifxhcd_es.c
|
|
\ingroup IFXUSB_DRIVER_V3
|
|
\brief The file contain function to enable host mode USB-IF Electrical Test function.
|
|
*/
|
|
|
|
#include <linux/version.h>
|
|
#include "ifxusb_version.h"
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/errno.h>
|
|
|
|
#include <linux/dma-mapping.h>
|
|
|
|
#include "ifxusb_plat.h"
|
|
#include "ifxusb_regs.h"
|
|
#include "ifxusb_cif.h"
|
|
#include "ifxhcd.h"
|
|
|
|
|
|
#ifdef __WITH_HS_ELECT_TST__
|
|
/*
|
|
* Quick and dirty hack to implement the HS Electrical Test
|
|
* SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
|
|
*
|
|
* This code was copied from our userspace app "hset". It sends a
|
|
* Get Device Descriptor control sequence in two parts, first the
|
|
* Setup packet by itself, followed some time later by the In and
|
|
* Ack packets. Rather than trying to figure out how to add this
|
|
* functionality to the normal driver code, we just hijack the
|
|
* hardware, using these two function to drive the hardware
|
|
* directly.
|
|
*/
|
|
|
|
|
|
void do_setup(ifxusb_core_if_t *_core_if)
|
|
{
|
|
|
|
ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
|
|
ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
|
|
ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
|
|
uint32_t *data_fifo = _core_if->data_fifo[0];
|
|
|
|
gint_data_t gintsts;
|
|
hctsiz_data_t hctsiz;
|
|
hcchar_data_t hcchar;
|
|
haint_data_t haint;
|
|
hcint_data_t hcint;
|
|
|
|
|
|
/* Enable HAINTs */
|
|
ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
|
|
|
|
/* Enable HCINTs */
|
|
ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
/*
|
|
* Send Setup packet (Get Device Descriptor)
|
|
*/
|
|
|
|
/* Make sure channel is disabled */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
if (hcchar.b.chen) {
|
|
//fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
|
|
hcchar.b.chdis = 1;
|
|
// hcchar.b.chen = 1;
|
|
ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
|
|
//sleep(1);
|
|
mdelay(1000);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//if (hcchar.b.chen) {
|
|
// fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
|
|
//}
|
|
}
|
|
|
|
/* Set HCTSIZ */
|
|
hctsiz.d32 = 0;
|
|
hctsiz.b.xfersize = 8;
|
|
hctsiz.b.pktcnt = 1;
|
|
hctsiz.b.pid = IFXUSB_HC_PID_SETUP;
|
|
ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
|
|
|
|
/* Set HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
|
|
hcchar.b.epdir = 0;
|
|
hcchar.b.epnum = 0;
|
|
hcchar.b.mps = 8;
|
|
hcchar.b.chen = 1;
|
|
ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
|
|
|
|
/* Fill FIFO with Setup data for Get Device Descriptor */
|
|
ifxusb_wreg(data_fifo++, 0x01000680);
|
|
ifxusb_wreg(data_fifo++, 0x00080000);
|
|
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Wait for host channel interrupt */
|
|
do {
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
} while (gintsts.b.hcintr == 0);
|
|
|
|
//fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Disable HCINTs */
|
|
ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
|
|
|
|
/* Disable HAINTs */
|
|
ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
}
|
|
|
|
void do_in_ack(ifxusb_core_if_t *_core_if)
|
|
{
|
|
|
|
ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
|
|
ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
|
|
ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
|
|
uint32_t *data_fifo = _core_if->data_fifo[0];
|
|
|
|
gint_data_t gintsts;
|
|
hctsiz_data_t hctsiz;
|
|
hcchar_data_t hcchar;
|
|
haint_data_t haint;
|
|
hcint_data_t hcint;
|
|
grxsts_data_t grxsts;
|
|
|
|
/* Enable HAINTs */
|
|
ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
|
|
|
|
/* Enable HCINTs */
|
|
ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
/*
|
|
* Receive Control In packet
|
|
*/
|
|
|
|
/* Make sure channel is disabled */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
if (hcchar.b.chen) {
|
|
//fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
|
|
hcchar.b.chdis = 1;
|
|
hcchar.b.chen = 1;
|
|
ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
|
|
//sleep(1);
|
|
mdelay(1000);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//if (hcchar.b.chen) {
|
|
// fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
|
|
//}
|
|
}
|
|
|
|
/* Set HCTSIZ */
|
|
hctsiz.d32 = 0;
|
|
hctsiz.b.xfersize = 8;
|
|
hctsiz.b.pktcnt = 1;
|
|
hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
|
|
ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
|
|
|
|
/* Set HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
|
|
hcchar.b.epdir = 1;
|
|
hcchar.b.epnum = 0;
|
|
hcchar.b.mps = 8;
|
|
hcchar.b.chen = 1;
|
|
ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
|
|
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Wait for receive status queue interrupt */
|
|
do {
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
} while (gintsts.b.rxstsqlvl == 0);
|
|
|
|
//fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Read RXSTS */
|
|
grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
|
|
//fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
|
|
|
|
/* Clear RXSTSQLVL in GINTSTS */
|
|
gintsts.d32 = 0;
|
|
gintsts.b.rxstsqlvl = 1;
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
switch (grxsts.hb.pktsts) {
|
|
case IFXUSB_HSTS_DATA_UPDT:
|
|
/* Read the data into the host buffer */
|
|
if (grxsts.hb.bcnt > 0) {
|
|
int i;
|
|
int word_count = (grxsts.hb.bcnt + 3) / 4;
|
|
|
|
for (i = 0; i < word_count; i++) {
|
|
(void)ifxusb_rreg(data_fifo++);
|
|
}
|
|
}
|
|
|
|
//fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.hb.bcnt);
|
|
break;
|
|
|
|
default:
|
|
//fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
|
|
break;
|
|
}
|
|
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Wait for receive status queue interrupt */
|
|
do {
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
} while (gintsts.b.rxstsqlvl == 0);
|
|
|
|
//fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Read RXSTS */
|
|
grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
|
|
//fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
|
|
|
|
/* Clear RXSTSQLVL in GINTSTS */
|
|
gintsts.d32 = 0;
|
|
gintsts.b.rxstsqlvl = 1;
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
switch (grxsts.hb.pktsts) {
|
|
case IFXUSB_HSTS_XFER_COMP:
|
|
break;
|
|
|
|
default:
|
|
//fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
|
|
break;
|
|
}
|
|
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Wait for host channel interrupt */
|
|
do {
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
} while (gintsts.b.hcintr == 0);
|
|
|
|
//fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
// usleep(100000);
|
|
// mdelay(100);
|
|
mdelay(1);
|
|
|
|
/*
|
|
* Send handshake packet
|
|
*/
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
/* Make sure channel is disabled */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
if (hcchar.b.chen) {
|
|
//fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
|
|
hcchar.b.chdis = 1;
|
|
hcchar.b.chen = 1;
|
|
ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
|
|
//sleep(1);
|
|
mdelay(1000);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//if (hcchar.b.chen) {
|
|
// fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
|
|
//}
|
|
}
|
|
|
|
/* Set HCTSIZ */
|
|
hctsiz.d32 = 0;
|
|
hctsiz.b.xfersize = 0;
|
|
hctsiz.b.pktcnt = 1;
|
|
hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
|
|
ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
|
|
|
|
/* Set HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
|
|
hcchar.b.epdir = 0;
|
|
hcchar.b.epnum = 0;
|
|
hcchar.b.mps = 8;
|
|
hcchar.b.chen = 1;
|
|
ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
|
|
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Wait for host channel interrupt */
|
|
do {
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
} while (gintsts.b.hcintr == 0);
|
|
|
|
//fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
|
|
|
|
/* Disable HCINTs */
|
|
ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
|
|
|
|
/* Disable HAINTs */
|
|
ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
|
|
|
|
/* Read HAINT */
|
|
haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
|
|
//fprintf(stderr, "HAINT: %08x\n", haint.d32);
|
|
|
|
/* Read HCINT */
|
|
hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
|
|
//fprintf(stderr, "HCINT: %08x\n", hcint.d32);
|
|
|
|
/* Read HCCHAR */
|
|
hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
|
|
//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
|
|
|
|
/* Clear HCINT */
|
|
ifxusb_wreg(&hc_regs->hcint, hcint.d32);
|
|
|
|
/* Clear HAINT */
|
|
ifxusb_wreg(&hc_global_regs->haint, haint.d32);
|
|
|
|
/* Clear GINTSTS */
|
|
ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
|
|
|
|
/* Read GINTSTS */
|
|
gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
|
|
//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
|
|
}
|
|
#endif //__WITH_HS_ELECT_TST__
|
|
|