forked from len0rd/rockbox
USB detection changes. c200/e200: Consider USB to be powered when charger is plugged but detect USB connection by bus reset. When received, disconnect and restart the driver fully enabled. imx31: Fix hack used to make initial connect succeeded-- set PHY type before initial reset. General: Move some target code out of usb-drv-arc.c and implement it in respective usb sources and CPU headers so things stay clean.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19797 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
cef6399c4c
commit
616c98b38f
18 changed files with 280 additions and 148 deletions
|
|
@ -95,7 +95,6 @@ static void handle_usb(void)
|
||||||
if (!usb_plugged() || !pause_if_button_pressed(true))
|
if (!usb_plugged() || !pause_if_button_pressed(true))
|
||||||
{
|
{
|
||||||
/* Bang on the controller */
|
/* Bang on the controller */
|
||||||
usb_init_device();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,9 @@
|
||||||
|
|
||||||
/* enable these for the experimental usb stack */
|
/* enable these for the experimental usb stack */
|
||||||
#define HAVE_USBSTACK
|
#define HAVE_USBSTACK
|
||||||
|
#ifndef BOOTLOADER
|
||||||
|
#define USB_DETECT_BY_DRV
|
||||||
|
#endif
|
||||||
#define USB_VENDOR_ID 0x0781
|
#define USB_VENDOR_ID 0x0781
|
||||||
#define USB_PRODUCT_ID 0x7450
|
#define USB_PRODUCT_ID 0x7450
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,9 @@
|
||||||
|
|
||||||
/* enable these for the experimental usb stack */
|
/* enable these for the experimental usb stack */
|
||||||
#define HAVE_USBSTACK
|
#define HAVE_USBSTACK
|
||||||
|
#ifndef BOOTLOADER
|
||||||
|
#define USB_DETECT_BY_DRV
|
||||||
|
#endif
|
||||||
#define USB_VENDOR_ID 0x0781
|
#define USB_VENDOR_ID 0x0781
|
||||||
#define USB_PRODUCT_ID 0x7421
|
#define USB_PRODUCT_ID 0x7421
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,10 +176,12 @@
|
||||||
/* USB On-the-go */
|
/* USB On-the-go */
|
||||||
#define CONFIG_USBOTG USBOTG_ARC
|
#define CONFIG_USBOTG USBOTG_ARC
|
||||||
|
|
||||||
/* enable these for the experimental usb stack */
|
/* enable these for the usb stack */
|
||||||
#define USE_ROCKBOX_USB
|
#define USE_ROCKBOX_USB
|
||||||
#define HAVE_USBSTACK
|
#define HAVE_USBSTACK
|
||||||
#define USB_STORAGE
|
#define USB_STORAGE
|
||||||
|
/* usb stack and driver settings */
|
||||||
|
#define USB_PORTSCX_PHY_TYPE PORTSCX_PTS_ULPI
|
||||||
#define USB_VENDOR_ID 0x0930
|
#define USB_VENDOR_ID 0x0930
|
||||||
#define USB_PRODUCT_ID 0x0010
|
#define USB_PRODUCT_ID 0x0010
|
||||||
|
|
||||||
|
|
@ -201,7 +203,7 @@
|
||||||
/* Offset ( in the firmware file's header ) to the real data */
|
/* Offset ( in the firmware file's header ) to the real data */
|
||||||
#define FIRMWARE_OFFSET_FILE_DATA 8
|
#define FIRMWARE_OFFSET_FILE_DATA 8
|
||||||
|
|
||||||
#define HAVE_SERIAL
|
//#define HAVE_SERIAL
|
||||||
#define HAVE_VOLUME_IN_LIST
|
#define HAVE_VOLUME_IN_LIST
|
||||||
|
|
||||||
/*Remove Comments from UART_INT to enable the UART interrupts,*/
|
/*Remove Comments from UART_INT to enable the UART interrupts,*/
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,11 @@
|
||||||
#define FRAME_SIZE (240*320*2)
|
#define FRAME_SIZE (240*320*2)
|
||||||
|
|
||||||
#define DEVBSS_ATTR __attribute__((section(".devbss"),nocommon))
|
#define DEVBSS_ATTR __attribute__((section(".devbss"),nocommon))
|
||||||
#define QHARRAY_ATTR __attribute__((section(".qharray"),nocommon))
|
/* USBOTG */
|
||||||
|
#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(2048)))
|
||||||
|
#define USB_NUM_ENDPOINTS 8
|
||||||
|
#define USB_DEVBSS_ATTR DEVBSS_ATTR
|
||||||
|
#define USB_BASE OTG_BASE_ADDR
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AIPS 1
|
* AIPS 1
|
||||||
|
|
@ -1580,6 +1584,4 @@
|
||||||
#define UART_FIFO_CTRL 0x881
|
#define UART_FIFO_CTRL 0x881
|
||||||
#define TIMEOUT 1000
|
#define TIMEOUT 1000
|
||||||
|
|
||||||
#define USB_BASE OTG_BASE_ADDR
|
|
||||||
|
|
||||||
#endif /* __IMX31L_H__ */
|
#endif /* __IMX31L_H__ */
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,12 @@
|
||||||
|
|
||||||
/* All info gleaned and/or copied from the iPodLinux project. */
|
/* All info gleaned and/or copied from the iPodLinux project. */
|
||||||
|
|
||||||
#define QHARRAY_ATTR __attribute__((section(".qharray"),nocommon))
|
/* USBOTG */
|
||||||
|
#define USB_NUM_ENDPOINTS 3
|
||||||
|
/* This needs to be 2048 byte aligned, but USB_QHARRAY_ATTR should take care
|
||||||
|
* of that */
|
||||||
|
#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(4)))
|
||||||
|
#define USB_DEVBSS_ATTR IBSS_ATTR
|
||||||
|
|
||||||
/* DRAM starts at 0x10000000, but in Rockbox we remap it to 0x00000000 */
|
/* DRAM starts at 0x10000000, but in Rockbox we remap it to 0x00000000 */
|
||||||
#define DRAM_START 0x10000000
|
#define DRAM_START 0x10000000
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,11 @@
|
||||||
enum {
|
enum {
|
||||||
USB_INSERTED, /* Event+State */
|
USB_INSERTED, /* Event+State */
|
||||||
USB_EXTRACTED, /* Event+State */
|
USB_EXTRACTED, /* Event+State */
|
||||||
#ifdef HAVE_USB_POWER
|
#if defined(HAVE_USB_POWER) || defined(USB_DETECT_BY_DRV)
|
||||||
USB_POWERED, /* State */
|
USB_POWERED, /* Event+State */
|
||||||
|
#endif
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
USB_UNPOWERED, /* Event */
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
USB_SCREENDUMP, /* State */
|
USB_SCREENDUMP, /* State */
|
||||||
|
|
@ -107,6 +110,7 @@ struct usb_transfer_completion_event_data
|
||||||
|
|
||||||
void usb_init(void);
|
void usb_init(void);
|
||||||
void usb_enable(bool on);
|
void usb_enable(bool on);
|
||||||
|
void usb_attach(void);
|
||||||
void usb_start_monitoring(void);
|
void usb_start_monitoring(void);
|
||||||
void usb_close(void);
|
void usb_close(void);
|
||||||
void usb_acknowledge(long id);
|
void usb_acknowledge(long id);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
* \/ \/ \/ \/ \/
|
* \/ \/ \/ \/ \/
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 by Björn Stenberg
|
* Copyright (C) 2007 by Björn Stenberg
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -35,14 +35,6 @@
|
||||||
|
|
||||||
/* endpoints */
|
/* endpoints */
|
||||||
#define EP_CONTROL 0
|
#define EP_CONTROL 0
|
||||||
#if CONFIG_CPU == IMX31L
|
|
||||||
#define NUM_ENDPOINTS 8
|
|
||||||
#define USBDEVBSS_ATTR DEVBSS_ATTR
|
|
||||||
#else
|
|
||||||
#define USBDEVBSS_ATTR IBSS_ATTR
|
|
||||||
#define NUM_ENDPOINTS 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int usb_max_pkt_size;
|
extern int usb_max_pkt_size;
|
||||||
|
|
||||||
struct usb_class_driver;
|
struct usb_class_driver;
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,13 @@
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
|
||||||
void usb_drv_startup(void);
|
void usb_drv_startup(void);
|
||||||
|
void usb_drv_usb_detect_event(void); /* Target implemented */
|
||||||
|
void usb_drv_int_enable(bool enable); /* Target implemented */
|
||||||
|
void usb_drv_reset(void);
|
||||||
void usb_drv_init(void);
|
void usb_drv_init(void);
|
||||||
void usb_drv_exit(void);
|
void usb_drv_exit(void);
|
||||||
void usb_drv_int(void);
|
void usb_drv_attach(void);
|
||||||
|
void usb_drv_int(void); /* Call from target INT handler */
|
||||||
void usb_drv_stall(int endpoint, bool stall,bool in);
|
void usb_drv_stall(int endpoint, bool stall,bool in);
|
||||||
bool usb_drv_stalled(int endpoint,bool in);
|
bool usb_drv_stalled(int endpoint,bool in);
|
||||||
int usb_drv_send(int endpoint, void* ptr, int length);
|
int usb_drv_send(int endpoint, void* ptr, int length);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,14 @@
|
||||||
#define CPUFREQ_MAX CPU_FREQ
|
#define CPUFREQ_MAX CPU_FREQ
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For USB driver - no accuracy assurance */
|
||||||
|
static inline void udelay(unsigned int usecs)
|
||||||
|
{
|
||||||
|
unsigned int x;
|
||||||
|
for (x = 0; x < 300*usecs; x++)
|
||||||
|
asm volatile ("");
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static inline void udelay(unsigned int usecs)
|
static inline void udelay(unsigned int usecs)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "usb-target.h"
|
#include "usb-target.h"
|
||||||
#include "clkctl-imx31.h"
|
#include "clkctl-imx31.h"
|
||||||
#include "power-imx31.h"
|
#include "power-imx31.h"
|
||||||
|
#include "avic-imx31.h"
|
||||||
#include "mc13783.h"
|
#include "mc13783.h"
|
||||||
|
|
||||||
static int usb_status = USB_EXTRACTED;
|
static int usb_status = USB_EXTRACTED;
|
||||||
|
|
@ -75,11 +76,7 @@ bool usb_plugged(void)
|
||||||
|
|
||||||
void usb_init_device(void)
|
void usb_init_device(void)
|
||||||
{
|
{
|
||||||
imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
|
/* Do one-time inits */
|
||||||
|
|
||||||
enable_transceiver(true);
|
|
||||||
|
|
||||||
/* Module will be turned off later after firmware init */
|
|
||||||
usb_drv_startup();
|
usb_drv_startup();
|
||||||
|
|
||||||
/* Initially poll */
|
/* Initially poll */
|
||||||
|
|
@ -91,19 +88,37 @@ void usb_init_device(void)
|
||||||
|
|
||||||
void usb_enable(bool on)
|
void usb_enable(bool on)
|
||||||
{
|
{
|
||||||
if (on)
|
/* Module clock should be on since since this could be called with
|
||||||
{
|
* OFF initially and writing module registers would hardlock otherwise. */
|
||||||
imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
|
imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
|
||||||
enable_transceiver(true);
|
enable_transceiver(true);
|
||||||
|
|
||||||
|
if (on)
|
||||||
|
{
|
||||||
usb_core_init();
|
usb_core_init();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Module clock should be on since this could be called first */
|
|
||||||
imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
|
|
||||||
enable_transceiver(true);
|
|
||||||
usb_core_exit();
|
usb_core_exit();
|
||||||
enable_transceiver(false);
|
enable_transceiver(false);
|
||||||
imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_OFF);
|
imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usb_attach(void)
|
||||||
|
{
|
||||||
|
usb_enable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void)
|
||||||
|
{
|
||||||
|
usb_drv_int(); /* Call driver handler */
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_drv_int_enable(bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
avic_enable_int(USB_OTG, IRQ, 7, USB_OTG_HANDLER);
|
||||||
|
else
|
||||||
|
avic_disable_int(USB_OTG);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "powermgmt.h"
|
#include "powermgmt.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
#include "usb-target.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
* These parameters may be defined per target:
|
* These parameters may be defined per target:
|
||||||
|
|
@ -132,6 +134,10 @@ static inline void charger_plugged(void)
|
||||||
{
|
{
|
||||||
batt_threshold = BATT_FULL_VOLTAGE; /* Start with topped value. */
|
batt_threshold = BATT_FULL_VOLTAGE; /* Start with topped value. */
|
||||||
battery_voltage_sync();
|
battery_voltage_sync();
|
||||||
|
#if defined(USB_STATUS_BY_EVENT) && defined(USB_DETECT_BY_DRV)
|
||||||
|
/* Charger pin detect is USB pin detect */
|
||||||
|
usb_connect_event(true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void charger_control(void)
|
static inline void charger_control(void)
|
||||||
|
|
@ -186,6 +192,10 @@ static inline void charger_unplugged(void)
|
||||||
disable_charger();
|
disable_charger();
|
||||||
if (charge_state >= CHARGE_STATE_ERROR)
|
if (charge_state >= CHARGE_STATE_ERROR)
|
||||||
charge_state = DISCHARGING; /* Reset error */
|
charge_state = DISCHARGING; /* Reset error */
|
||||||
|
#if defined(USB_STATUS_BY_EVENT) && defined(USB_DETECT_BY_DRV)
|
||||||
|
/* Charger pin detect is USB pin detect */
|
||||||
|
usb_connect_event(false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main charging algorithm - called from powermgmt.c */
|
/* Main charging algorithm - called from powermgmt.c */
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
* Driver for ARC USBOTG Device Controller
|
* Driver for ARC USBOTG Device Controller
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 by Björn Stenberg
|
* Copyright (C) 2007 by Björn Stenberg
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -33,11 +33,6 @@
|
||||||
//#define LOGF_ENABLE
|
//#define LOGF_ENABLE
|
||||||
#include "logf.h"
|
#include "logf.h"
|
||||||
|
|
||||||
#if CONFIG_CPU == IMX31L
|
|
||||||
#include "avic-imx31.h"
|
|
||||||
static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* USB device mode registers (Little Endian) */
|
/* USB device mode registers (Little Endian) */
|
||||||
|
|
||||||
#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000))
|
#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000))
|
||||||
|
|
@ -326,8 +321,8 @@ struct transfer_descriptor {
|
||||||
unsigned int reserved;
|
unsigned int reserved;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
static struct transfer_descriptor td_array[NUM_ENDPOINTS*2]
|
static struct transfer_descriptor td_array[USB_NUM_ENDPOINTS*2]
|
||||||
USBDEVBSS_ATTR __attribute__((aligned(32)));
|
USB_DEVBSS_ATTR __attribute__((aligned(32)));
|
||||||
|
|
||||||
/* manual: 32.13.1 Endpoint Queue Head (dQH) */
|
/* manual: 32.13.1 Endpoint Queue Head (dQH) */
|
||||||
struct queue_head {
|
struct queue_head {
|
||||||
|
|
@ -342,17 +337,10 @@ struct queue_head {
|
||||||
unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
|
unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#if CONFIG_CPU == IMX31L
|
static struct queue_head qh_array[USB_NUM_ENDPOINTS*2]
|
||||||
static struct queue_head qh_array[NUM_ENDPOINTS*2]
|
USB_QHARRAY_ATTR;
|
||||||
QHARRAY_ATTR __attribute__((aligned (2048)));
|
|
||||||
#else
|
|
||||||
/* This still needs to be 2048 byte aligned, but QHARRAY_ATTR should take
|
|
||||||
care of that */
|
|
||||||
static struct queue_head qh_array[NUM_ENDPOINTS*2]
|
|
||||||
QHARRAY_ATTR __attribute__((aligned (4)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct wakeup transfer_completion_signal[NUM_ENDPOINTS*2]
|
static struct wakeup transfer_completion_signal[USB_NUM_ENDPOINTS*2]
|
||||||
SHAREDBSS_ATTR;
|
SHAREDBSS_ATTR;
|
||||||
|
|
||||||
static const unsigned int pipe2mask[] = {
|
static const unsigned int pipe2mask[] = {
|
||||||
|
|
@ -363,7 +351,7 @@ static const unsigned int pipe2mask[] = {
|
||||||
0x10, 0x100000,
|
0x10, 0x100000,
|
||||||
};
|
};
|
||||||
|
|
||||||
static char ep_allocation[NUM_ENDPOINTS];
|
static char ep_allocation[USB_NUM_ENDPOINTS];
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static void transfer_completed(void);
|
static void transfer_completed(void);
|
||||||
|
|
@ -378,52 +366,46 @@ static void init_control_queue_heads(void);
|
||||||
static void init_bulk_queue_heads(void);
|
static void init_bulk_queue_heads(void);
|
||||||
static void init_endpoints(void);
|
static void init_endpoints(void);
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static void usb_drv_stop(void)
|
||||||
bool usb_drv_powered(void)
|
|
||||||
{
|
{
|
||||||
return (REG_OTGSC & OTGSC_B_SESSION_VALID) ? true : false;
|
/* disable interrupts */
|
||||||
|
REG_USBINTR = 0;
|
||||||
|
/* stop usb controller (disconnect) */
|
||||||
|
REG_USBCMD &= ~USBCMD_RUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_drv_reset(void)
|
||||||
|
{
|
||||||
|
int oldlevel = disable_irq_save();
|
||||||
|
REG_USBCMD &= ~USBCMD_RUN;
|
||||||
|
restore_irq(oldlevel);
|
||||||
|
|
||||||
|
#ifdef USB_PORTSCX_PHY_TYPE
|
||||||
|
/* If a PHY type is specified, set it now */
|
||||||
|
REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | USB_PORTSCX_PHY_TYPE;
|
||||||
|
#endif
|
||||||
|
sleep(HZ/20);
|
||||||
|
REG_USBCMD |= USBCMD_CTRL_RESET;
|
||||||
|
while (REG_USBCMD & USBCMD_CTRL_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* One-time driver startup init */
|
/* One-time driver startup init */
|
||||||
void usb_drv_startup(void)
|
void usb_drv_startup(void)
|
||||||
{
|
{
|
||||||
#if CONFIG_CPU == IMX31L && defined(BOOTLOADER)
|
|
||||||
/* This is the bootloader - activate the OTG controller or cold
|
|
||||||
* connect later could/will fail */
|
|
||||||
REG_USBCMD &= ~USBCMD_RUN;
|
|
||||||
|
|
||||||
sleep(HZ/20);
|
|
||||||
REG_USBCMD |= USBCMD_CTRL_RESET;
|
|
||||||
while (REG_USBCMD & USBCMD_CTRL_RESET);
|
|
||||||
|
|
||||||
/* Set to ULPI */
|
|
||||||
REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | PORTSCX_PTS_ULPI;
|
|
||||||
sleep(HZ/10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize all the signal objects once */
|
/* Initialize all the signal objects once */
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<NUM_ENDPOINTS*2;i++) {
|
for(i=0;i<USB_NUM_ENDPOINTS*2;i++) {
|
||||||
wakeup_init(&transfer_completion_signal[i]);
|
wakeup_init(&transfer_completion_signal[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* manual: 32.14.1 Device Controller Initialization */
|
/* manual: 32.14.1 Device Controller Initialization */
|
||||||
void usb_drv_init(void)
|
static void _usb_drv_init(bool attach)
|
||||||
{
|
{
|
||||||
REG_USBCMD &= ~USBCMD_RUN;
|
usb_drv_reset();
|
||||||
sleep(HZ/20);
|
|
||||||
REG_USBCMD |= USBCMD_CTRL_RESET;
|
|
||||||
while (REG_USBCMD & USBCMD_CTRL_RESET);
|
|
||||||
|
|
||||||
|
|
||||||
REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
|
REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
|
||||||
|
|
||||||
#if CONFIG_CPU == IMX31L
|
|
||||||
/* Set to ULPI */
|
|
||||||
REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | PORTSCX_PTS_ULPI;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USB_NO_HIGH_SPEED
|
#ifdef USB_NO_HIGH_SPEED
|
||||||
/* Force device to full speed */
|
/* Force device to full speed */
|
||||||
/* See 32.9.5.9.2 */
|
/* See 32.9.5.9.2 */
|
||||||
|
|
@ -436,69 +418,76 @@ void usb_drv_init(void)
|
||||||
REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
|
REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
|
||||||
REG_DEVICEADDR = 0;
|
REG_DEVICEADDR = 0;
|
||||||
|
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
if (!attach) {
|
||||||
|
/* enable RESET interrupt */
|
||||||
|
REG_USBINTR = USBINTR_RESET_EN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
/* enable USB interrupts */
|
/* enable USB interrupts */
|
||||||
REG_USBINTR =
|
REG_USBINTR =
|
||||||
USBINTR_INT_EN |
|
USBINTR_INT_EN |
|
||||||
USBINTR_ERR_INT_EN |
|
USBINTR_ERR_INT_EN |
|
||||||
USBINTR_PTC_DETECT_EN |
|
USBINTR_PTC_DETECT_EN |
|
||||||
USBINTR_RESET_EN |
|
USBINTR_RESET_EN;
|
||||||
USBINTR_SYS_ERR_EN;
|
}
|
||||||
|
|
||||||
#if CONFIG_CPU == IMX31L
|
usb_drv_int_enable(true);
|
||||||
avic_enable_int(USB_OTG, IRQ, 7, USB_OTG_HANDLER);
|
|
||||||
#else
|
|
||||||
/* enable USB IRQ in CPU */
|
|
||||||
CPU_INT_EN = USB_MASK;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* go go go */
|
/* go go go */
|
||||||
REG_USBCMD |= USBCMD_RUN;
|
REG_USBCMD |= USBCMD_RUN;
|
||||||
|
|
||||||
|
|
||||||
logf("usb_drv_init() finished");
|
logf("usb_drv_init() finished");
|
||||||
logf("usb id %x", REG_ID);
|
logf("usb id %x", REG_ID);
|
||||||
logf("usb dciversion %x", REG_DCIVERSION);
|
logf("usb dciversion %x", REG_DCIVERSION);
|
||||||
logf("usb dccparams %x", REG_DCCPARAMS);
|
logf("usb dccparams %x", REG_DCCPARAMS);
|
||||||
|
|
||||||
/* now a bus reset will occur. see bus_reset() */
|
/* now a bus reset will occur. see bus_reset() */
|
||||||
|
(void)attach;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** With USB_DETECT_BY_DRV, attach is distinct from init, otherwise eqivalent. **/
|
||||||
|
|
||||||
|
/* USB_DETECT_BY_DRV - enable bus reset detection only
|
||||||
|
* else fully enable driver */
|
||||||
|
void usb_drv_init(void)
|
||||||
|
{
|
||||||
|
_usb_drv_init(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
/* fully enable driver */
|
||||||
|
void usb_drv_attach(void)
|
||||||
|
{
|
||||||
|
sleep(HZ/10);
|
||||||
|
_usb_drv_init(true);
|
||||||
|
}
|
||||||
|
#endif /* USB_DETECT_BY_DRV */
|
||||||
|
|
||||||
void usb_drv_exit(void)
|
void usb_drv_exit(void)
|
||||||
{
|
{
|
||||||
/* disable interrupts */
|
usb_drv_stop();
|
||||||
REG_USBINTR = 0;
|
|
||||||
|
|
||||||
/* stop usb controller */
|
|
||||||
REG_USBCMD &= ~USBCMD_RUN;
|
|
||||||
|
|
||||||
/* TODO : is one of these needed to save power ?
|
/* TODO : is one of these needed to save power ?
|
||||||
REG_PORTSC1 |= PORTSCX_PHY_LOW_POWER_SPD;
|
REG_PORTSC1 |= PORTSCX_PHY_LOW_POWER_SPD;
|
||||||
REG_USBCMD |= USBCMD_CTRL_RESET;
|
REG_USBCMD |= USBCMD_CTRL_RESET;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if CONFIG_CPU == IMX31L
|
usb_drv_int_enable(false);
|
||||||
avic_disable_int(USB_OTG);
|
|
||||||
#else
|
|
||||||
CPU_INT_DIS = USB_MASK;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cancel_cpu_boost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_CPU == IMX31L
|
|
||||||
static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void)
|
|
||||||
#else
|
|
||||||
void usb_drv_int(void)
|
void usb_drv_int(void)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
unsigned int status = REG_USBSTS;
|
unsigned int usbintr = REG_USBINTR; /* Only watch enabled ints */
|
||||||
|
unsigned int status = REG_USBSTS & usbintr;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (status & USBSTS_INT) logf("int: usb ioc");
|
if (status & USBSTS_INT) logf("int: usb ioc");
|
||||||
if (status & USBSTS_ERR) logf("int: usb err");
|
if (status & USBSTS_ERR) logf("int: usb err");
|
||||||
if (status & USBSTS_PORT_CHANGE) logf("int: portchange");
|
if (status & USBSTS_PORT_CHANGE) logf("int: portchange");
|
||||||
if (status & USBSTS_RESET) logf("int: reset");
|
if (status & USBSTS_RESET) logf("int: reset");
|
||||||
if (status & USBSTS_SYS_ERR) logf("int: syserr");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* usb transaction interrupt */
|
/* usb transaction interrupt */
|
||||||
|
|
@ -523,9 +512,19 @@ void usb_drv_int(void)
|
||||||
/* reset interrupt */
|
/* reset interrupt */
|
||||||
if (status & USBSTS_RESET) {
|
if (status & USBSTS_RESET) {
|
||||||
REG_USBSTS = USBSTS_RESET;
|
REG_USBSTS = USBSTS_RESET;
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
if (UNLIKELY(usbintr == USBINTR_RESET_EN)) {
|
||||||
|
/* USB detected - detach and inform */
|
||||||
|
usb_drv_stop();
|
||||||
|
usb_drv_usb_detect_event();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
bus_reset();
|
bus_reset();
|
||||||
usb_core_bus_reset(); /* tell mom */
|
usb_core_bus_reset(); /* tell mom */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* port change */
|
/* port change */
|
||||||
if (status & USBSTS_PORT_CHANGE) {
|
if (status & USBSTS_PORT_CHANGE) {
|
||||||
|
|
@ -588,7 +587,14 @@ int usb_drv_port_speed(void)
|
||||||
|
|
||||||
bool usb_drv_connected(void)
|
bool usb_drv_connected(void)
|
||||||
{
|
{
|
||||||
return ((REG_PORTSC1 & PORTSCX_CURRENT_CONNECT_STATUS) !=0);
|
return (REG_PORTSC1 &
|
||||||
|
(PORTSCX_PORT_SUSPEND | PORTSCX_CURRENT_CONNECT_STATUS))
|
||||||
|
== PORTSCX_CURRENT_CONNECT_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool usb_drv_powered(void)
|
||||||
|
{
|
||||||
|
return (REG_OTGSC & OTGSC_B_SESSION_VALID) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_drv_set_address(int address)
|
void usb_drv_set_address(int address)
|
||||||
|
|
@ -628,10 +634,7 @@ void usb_drv_set_test_mode(int mode)
|
||||||
REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
|
REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
REG_USBCMD &= ~USBCMD_RUN;
|
usb_drv_reset();
|
||||||
sleep(HZ/20);
|
|
||||||
REG_USBCMD |= USBCMD_CTRL_RESET;
|
|
||||||
while (REG_USBCMD & USBCMD_CTRL_RESET);
|
|
||||||
REG_USBCMD |= USBCMD_RUN;
|
REG_USBCMD |= USBCMD_RUN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -735,7 +738,7 @@ void usb_drv_cancel_all_transfers(void)
|
||||||
while (REG_ENDPTFLUSH);
|
while (REG_ENDPTFLUSH);
|
||||||
|
|
||||||
memset(td_array, 0, sizeof td_array);
|
memset(td_array, 0, sizeof td_array);
|
||||||
for(i=0;i<NUM_ENDPOINTS*2;i++) {
|
for(i=0;i<USB_NUM_ENDPOINTS*2;i++) {
|
||||||
if(qh_array[i].wait) {
|
if(qh_array[i].wait) {
|
||||||
qh_array[i].wait=0;
|
qh_array[i].wait=0;
|
||||||
qh_array[i].status=DTD_STATUS_HALTED;
|
qh_array[i].status=DTD_STATUS_HALTED;
|
||||||
|
|
@ -750,7 +753,7 @@ int usb_drv_request_endpoint(int dir)
|
||||||
|
|
||||||
bit=(dir & USB_DIR_IN)? 2:1;
|
bit=(dir & USB_DIR_IN)? 2:1;
|
||||||
|
|
||||||
for (i=1; i < NUM_ENDPOINTS; i++) {
|
for (i=1; i < USB_NUM_ENDPOINTS; i++) {
|
||||||
if((ep_allocation[i] & bit)!=0)
|
if((ep_allocation[i] & bit)!=0)
|
||||||
continue;
|
continue;
|
||||||
ep_allocation[i] |= bit;
|
ep_allocation[i] |= bit;
|
||||||
|
|
@ -819,7 +822,7 @@ static void transfer_completed(void)
|
||||||
unsigned int mask = REG_ENDPTCOMPLETE;
|
unsigned int mask = REG_ENDPTCOMPLETE;
|
||||||
REG_ENDPTCOMPLETE = mask;
|
REG_ENDPTCOMPLETE = mask;
|
||||||
|
|
||||||
for (ep=0; ep<NUM_ENDPOINTS; ep++) {
|
for (ep=0; ep<USB_NUM_ENDPOINTS; ep++) {
|
||||||
int dir;
|
int dir;
|
||||||
for (dir=0; dir<2; dir++) {
|
for (dir=0; dir<2; dir++) {
|
||||||
int pipe = ep * 2 + dir;
|
int pipe = ep * 2 + dir;
|
||||||
|
|
@ -869,13 +872,8 @@ static void bus_reset(void)
|
||||||
logf("usb: double reset");
|
logf("usb: double reset");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if CONFIG_CPU == IMX31L
|
|
||||||
int x;
|
|
||||||
for (x = 0; x < 30000; x++)
|
|
||||||
asm volatile ("");
|
|
||||||
#else
|
|
||||||
udelay(100);
|
udelay(100);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (REG_ENDPTPRIME) {
|
if (REG_ENDPTPRIME) {
|
||||||
logf("usb: short reset timeout");
|
logf("usb: short reset timeout");
|
||||||
|
|
@ -917,7 +915,7 @@ static void init_bulk_queue_heads(void)
|
||||||
/* TODO: this should take ep_allocation into account */
|
/* TODO: this should take ep_allocation into account */
|
||||||
|
|
||||||
/*** bulk ***/
|
/*** bulk ***/
|
||||||
for(i=1;i<NUM_ENDPOINTS;i++) {
|
for(i=1;i<USB_NUM_ENDPOINTS;i++) {
|
||||||
qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
|
qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
|
||||||
qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE;
|
qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE;
|
||||||
qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
|
qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
|
||||||
|
|
@ -930,7 +928,7 @@ static void init_endpoints(void)
|
||||||
int i;
|
int i;
|
||||||
/* TODO: this should take ep_allocation into account */
|
/* TODO: this should take ep_allocation into account */
|
||||||
/* bulk */
|
/* bulk */
|
||||||
for(i=1;i<NUM_ENDPOINTS;i++) {
|
for(i=1;i<USB_NUM_ENDPOINTS;i++) {
|
||||||
REG_ENDPTCTRL(i) =
|
REG_ENDPTCTRL(i) =
|
||||||
EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
|
EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
|
||||||
EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
|
EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,13 @@
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
#include "usb-target.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "usb_core.h"
|
#include "usb_core.h"
|
||||||
#include "usb_drv.h"
|
#include "usb_drv.h"
|
||||||
#include "usb-target.h"
|
|
||||||
|
|
||||||
void usb_init_device(void)
|
void usb_init_device(void)
|
||||||
{
|
{
|
||||||
|
|
@ -94,6 +94,31 @@ void usb_enable(bool on)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usb_attach(void)
|
||||||
|
{
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
usb_drv_attach();
|
||||||
|
#else
|
||||||
|
usb_enable(true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
/* Cannot tell charger pin from USB pin */
|
||||||
|
static int usb_status = USB_EXTRACTED;
|
||||||
|
|
||||||
|
void usb_connect_event(bool inserted)
|
||||||
|
{
|
||||||
|
usb_status = inserted ? USB_INSERTED : USB_EXTRACTED;
|
||||||
|
usb_status_event(inserted ? USB_POWERED : USB_UNPOWERED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called during the bus reset interrupt when in detect mode */
|
||||||
|
void usb_drv_usb_detect_event(void)
|
||||||
|
{
|
||||||
|
usb_status_event(USB_INSERTED);
|
||||||
|
}
|
||||||
|
#else /* !USB_DETECT_BY_DRV */
|
||||||
static bool usb_pin_detect(void)
|
static bool usb_pin_detect(void)
|
||||||
{
|
{
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
|
|
@ -110,12 +135,12 @@ static bool usb_pin_detect(void)
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
#elif defined(SANSA_C200)
|
#elif defined(SANSA_C200)
|
||||||
/* GPIO H bit 1 is usb detect */
|
/* GPIO H bit 1 is usb/charger detect */
|
||||||
if (GPIOH_INPUT_VAL & 0x02)
|
if (GPIOH_INPUT_VAL & 0x02)
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
#elif defined(SANSA_E200)
|
#elif defined(SANSA_E200)
|
||||||
/* GPIO B bit 4 is usb detect */
|
/* GPIO B bit 4 is usb/charger detect */
|
||||||
if (GPIOB_INPUT_VAL & 0x10)
|
if (GPIOB_INPUT_VAL & 0x10)
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
|
|
@ -137,16 +162,32 @@ static bool usb_pin_detect(void)
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
#endif /* USB_DETECT_BY_DRV */
|
||||||
|
|
||||||
/* detect host or charger (INSERTED or POWERED) */
|
void usb_drv_int_enable(bool enable)
|
||||||
|
{
|
||||||
|
/* enable/disable USB IRQ in CPU */
|
||||||
|
if(enable) {
|
||||||
|
CPU_INT_EN = USB_MASK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CPU_INT_DIS = USB_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* detect host or charger (INSERTED or EXTRACTED) */
|
||||||
int usb_detect(void)
|
int usb_detect(void)
|
||||||
{
|
{
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
return usb_status;
|
||||||
|
#else
|
||||||
if(usb_pin_detect()) {
|
if(usb_pin_detect()) {
|
||||||
return USB_INSERTED;
|
return USB_INSERTED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return USB_EXTRACTED;
|
return USB_EXTRACTED;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(IPOD_COLOR) || defined(IPOD_4G) \
|
#if defined(IPOD_COLOR) || defined(IPOD_4G) \
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,11 @@
|
||||||
|
|
||||||
void usb_init_device(void);
|
void usb_init_device(void);
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER
|
||||||
|
#if defined(SANSA_C200) || defined(SANSA_E200)
|
||||||
|
#define USB_STATUS_BY_EVENT /* No USB tick */
|
||||||
|
void usb_connect_event(bool inserted);
|
||||||
|
#endif
|
||||||
|
#endif /* BOOTLOADER */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,11 @@
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
|
#include "usb-target.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "sprintf.h"
|
#include "sprintf.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "usb-target.h"
|
|
||||||
#ifdef HAVE_USBSTACK
|
#ifdef HAVE_USBSTACK
|
||||||
#include "usb_core.h"
|
#include "usb_core.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -129,11 +129,13 @@ static inline void usb_slave_mode(bool on)
|
||||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||||
thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME);
|
thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME);
|
||||||
#endif
|
#endif
|
||||||
usb_enable(true);
|
usb_attach();
|
||||||
}
|
}
|
||||||
else /* usb_state == USB_INSERTED (only!) */
|
else /* usb_state == USB_INSERTED (only!) */
|
||||||
{
|
{
|
||||||
|
#ifndef USB_DETECT_BY_DRV
|
||||||
usb_enable(false);
|
usb_enable(false);
|
||||||
|
#endif
|
||||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||||
thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM);
|
thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -234,6 +236,26 @@ static void usb_thread(void)
|
||||||
(struct usb_transfer_completion_event_data*)ev.data);
|
(struct usb_transfer_completion_event_data*)ev.data);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
/* In this case, these events the handle cable insertion USB
|
||||||
|
* driver determines INSERTED/EXTRACTED state. */
|
||||||
|
case USB_POWERED:
|
||||||
|
/* Set the state to USB_POWERED for now and enable the driver
|
||||||
|
* to detect a bus reset only. If a bus reset is detected,
|
||||||
|
* USB_INSERTED will be received. */
|
||||||
|
usb_state = USB_POWERED;
|
||||||
|
usb_enable(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_UNPOWERED:
|
||||||
|
usb_enable(false);
|
||||||
|
/* This part shouldn't be obligatory for anything that can
|
||||||
|
* reliably detect removal of the data lines. USB_EXTRACTED
|
||||||
|
* could be posted on that event while bus power remains
|
||||||
|
* available. */
|
||||||
|
queue_post(&usb_queue, USB_EXTRACTED, 0);
|
||||||
|
break;
|
||||||
|
#endif /* USB_DETECT_BY_DRV */
|
||||||
case USB_INSERTED:
|
case USB_INSERTED:
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
if(do_screendump_instead_of_usb)
|
if(do_screendump_instead_of_usb)
|
||||||
|
|
@ -251,7 +273,7 @@ static void usb_thread(void)
|
||||||
#ifdef HAVE_USBSTACK
|
#ifdef HAVE_USBSTACK
|
||||||
usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false);
|
usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false);
|
||||||
usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true);
|
usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true);
|
||||||
usb_enable(true);
|
usb_attach();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +294,7 @@ static void usb_thread(void)
|
||||||
|
|
||||||
if(!exclusive_storage_access)
|
if(!exclusive_storage_access)
|
||||||
{
|
{
|
||||||
usb_enable(true);
|
usb_attach();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_USBSTACK */
|
#endif /* HAVE_USBSTACK */
|
||||||
|
|
@ -304,7 +326,7 @@ static void usb_thread(void)
|
||||||
usb_state = USB_EXTRACTED;
|
usb_state = USB_EXTRACTED;
|
||||||
break; /* Connected for screendump only */
|
break; /* Connected for screendump only */
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LCD_BITMAP */
|
#endif
|
||||||
#ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */
|
#ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */
|
||||||
#ifdef HAVE_USB_POWER
|
#ifdef HAVE_USB_POWER
|
||||||
if(usb_state == USB_POWERED)
|
if(usb_state == USB_POWERED)
|
||||||
|
|
@ -312,7 +334,7 @@ static void usb_thread(void)
|
||||||
usb_state = USB_EXTRACTED;
|
usb_state = USB_EXTRACTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_USB_POWER */
|
#endif
|
||||||
#endif /* HAVE_USBSTACK */
|
#endif /* HAVE_USBSTACK */
|
||||||
if(usb_state == USB_INSERTED)
|
if(usb_state == USB_INSERTED)
|
||||||
{
|
{
|
||||||
|
|
@ -326,7 +348,9 @@ static void usb_thread(void)
|
||||||
#ifdef HAVE_USBSTACK
|
#ifdef HAVE_USBSTACK
|
||||||
if(!exclusive_storage_access)
|
if(!exclusive_storage_access)
|
||||||
{
|
{
|
||||||
|
#ifndef USB_DETECT_BY_DRV /* Disabled handling USB_UNPOWERED */
|
||||||
usb_enable(false);
|
usb_enable(false);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -392,19 +416,34 @@ static void usb_thread(void)
|
||||||
#ifdef USB_STATUS_BY_EVENT
|
#ifdef USB_STATUS_BY_EVENT
|
||||||
void usb_status_event(int current_status)
|
void usb_status_event(int current_status)
|
||||||
{
|
{
|
||||||
/* Status should be USB_INSERTED or USB_EXTRACTED.
|
/* Status should be USB_POWERED, USB_UNPOWERED, USB_INSERTED or
|
||||||
|
* USB_EXTRACTED.
|
||||||
* Caller isn't expected to filter for changes in status. */
|
* Caller isn't expected to filter for changes in status. */
|
||||||
if (usb_monitor_enabled && last_usb_status != current_status)
|
if(usb_monitor_enabled)
|
||||||
|
{
|
||||||
|
int oldstatus = disable_irq_save(); /* Dual-use function */
|
||||||
|
|
||||||
|
if(last_usb_status != current_status)
|
||||||
{
|
{
|
||||||
last_usb_status = current_status;
|
last_usb_status = current_status;
|
||||||
queue_post(&usb_queue, current_status, 0);
|
queue_post(&usb_queue, current_status, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restore_irq(oldstatus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_start_monitoring(void)
|
void usb_start_monitoring(void)
|
||||||
{
|
{
|
||||||
|
int status = usb_detect();
|
||||||
|
#ifdef USB_DETECT_BY_DRV
|
||||||
|
/* USB detection begins by USB_POWERED, not USB_INSERTED. If it is
|
||||||
|
* USB_EXTRACTED, then nothing changes and post will be skipped. */
|
||||||
|
if(USB_INSERTED == status)
|
||||||
|
status = USB_POWERED;
|
||||||
|
#endif
|
||||||
usb_monitor_enabled = true;
|
usb_monitor_enabled = true;
|
||||||
usb_status_event(usb_detect());
|
usb_status_event(status);
|
||||||
}
|
}
|
||||||
#else /* !USB_STATUS_BY_EVENT */
|
#else /* !USB_STATUS_BY_EVENT */
|
||||||
static void usb_tick(void)
|
static void usb_tick(void)
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ static struct
|
||||||
completion_handler_t completion_handler[2];
|
completion_handler_t completion_handler[2];
|
||||||
control_handler_t control_handler[2];
|
control_handler_t control_handler[2];
|
||||||
struct usb_transfer_completion_event_data completion_event;
|
struct usb_transfer_completion_event_data completion_event;
|
||||||
} ep_data[NUM_ENDPOINTS];
|
} ep_data[USB_NUM_ENDPOINTS];
|
||||||
|
|
||||||
static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
|
static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
|
||||||
{
|
{
|
||||||
|
|
@ -240,7 +240,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
|
||||||
|
|
||||||
static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
|
static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
|
||||||
|
|
||||||
static unsigned char response_data[256] USBDEVBSS_ATTR;
|
static unsigned char response_data[256] USB_DEVBSS_ATTR;
|
||||||
|
|
||||||
|
|
||||||
static short hex[16] = {'0','1','2','3','4','5','6','7',
|
static short hex[16] = {'0','1','2','3','4','5','6','7',
|
||||||
|
|
@ -476,7 +476,7 @@ static void allocate_interfaces_and_endpoints(void)
|
||||||
|
|
||||||
memset(ep_data,0,sizeof(ep_data));
|
memset(ep_data,0,sizeof(ep_data));
|
||||||
|
|
||||||
for (i = 0; i < NUM_ENDPOINTS; i++) {
|
for (i = 0; i < USB_NUM_ENDPOINTS; i++) {
|
||||||
usb_drv_release_endpoint(i | USB_DIR_OUT);
|
usb_drv_release_endpoint(i | USB_DIR_OUT);
|
||||||
usb_drv_release_endpoint(i | USB_DIR_IN);
|
usb_drv_release_endpoint(i | USB_DIR_IN);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -401,7 +401,7 @@ void usb_storage_init_connection(void)
|
||||||
#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \
|
#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \
|
||||||
defined(CPU_TCC77X) || defined(CPU_TCC780X)
|
defined(CPU_TCC77X) || defined(CPU_TCC780X)
|
||||||
static unsigned char _transfer_buffer[BUFFER_SIZE*2]
|
static unsigned char _transfer_buffer[BUFFER_SIZE*2]
|
||||||
USBDEVBSS_ATTR __attribute__((aligned(32)));
|
USB_DEVBSS_ATTR __attribute__((aligned(32)));
|
||||||
tb.transfer_buffer = (void *)_transfer_buffer;
|
tb.transfer_buffer = (void *)_transfer_buffer;
|
||||||
#else
|
#else
|
||||||
/* TODO : check if bufsize is at least 32K ? */
|
/* TODO : check if bufsize is at least 32K ? */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue