summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2009-01-19 13:41:25 +0000
committerMichael Sevakis <jethead71@rockbox.org>2009-01-19 13:41:25 +0000
commit616c98b38f6ddac0ac3dde8ec0fa248f835717e2 (patch)
tree5eeeabb85fbefa162a438edca88611c1bc688269
parentcef6399c4c3bcaa35733bdab8b9016b66b71a6f0 (diff)
downloadrockbox-616c98b38f6ddac0ac3dde8ec0fa248f835717e2.tar.gz
rockbox-616c98b38f6ddac0ac3dde8ec0fa248f835717e2.zip
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
-rw-r--r--bootloader/gigabeat-s.c1
-rw-r--r--firmware/export/config-c200.h3
-rw-r--r--firmware/export/config-e200.h3
-rw-r--r--firmware/export/config-gigabeat-s.h6
-rwxr-xr-xfirmware/export/imx31l.h8
-rw-r--r--firmware/export/pp5020.h7
-rw-r--r--firmware/export/usb.h8
-rw-r--r--firmware/export/usb_core.h10
-rw-r--r--firmware/export/usb_drv.h6
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-target.h8
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/usb-imx31.c35
-rw-r--r--firmware/target/arm/powermgmt-ascodec.c10
-rw-r--r--firmware/target/arm/usb-drv-arc.c186
-rw-r--r--firmware/target/arm/usb-fw-pp502x.c49
-rw-r--r--firmware/target/arm/usb-target.h7
-rw-r--r--firmware/usb.c65
-rw-r--r--firmware/usbstack/usb_core.c6
-rw-r--r--firmware/usbstack/usb_storage.c2
18 files changed, 276 insertions, 144 deletions
diff --git a/bootloader/gigabeat-s.c b/bootloader/gigabeat-s.c
index e860a2e379..15cbcbed46 100644
--- a/bootloader/gigabeat-s.c
+++ b/bootloader/gigabeat-s.c
@@ -95,7 +95,6 @@ static void handle_usb(void)
95 if (!usb_plugged() || !pause_if_button_pressed(true)) 95 if (!usb_plugged() || !pause_if_button_pressed(true))
96 { 96 {
97 /* Bang on the controller */ 97 /* Bang on the controller */
98 usb_init_device();
99 return; 98 return;
100 } 99 }
101 100
diff --git a/firmware/export/config-c200.h b/firmware/export/config-c200.h
index d68d21455f..ff260dc956 100644
--- a/firmware/export/config-c200.h
+++ b/firmware/export/config-c200.h
@@ -180,6 +180,9 @@
180 180
181/* enable these for the experimental usb stack */ 181/* enable these for the experimental usb stack */
182#define HAVE_USBSTACK 182#define HAVE_USBSTACK
183#ifndef BOOTLOADER
184#define USB_DETECT_BY_DRV
185#endif
183#define USB_VENDOR_ID 0x0781 186#define USB_VENDOR_ID 0x0781
184#define USB_PRODUCT_ID 0x7450 187#define USB_PRODUCT_ID 0x7450
185 188
diff --git a/firmware/export/config-e200.h b/firmware/export/config-e200.h
index 2be64d95cc..7b27391c64 100644
--- a/firmware/export/config-e200.h
+++ b/firmware/export/config-e200.h
@@ -177,6 +177,9 @@
177 177
178/* enable these for the experimental usb stack */ 178/* enable these for the experimental usb stack */
179#define HAVE_USBSTACK 179#define HAVE_USBSTACK
180#ifndef BOOTLOADER
181#define USB_DETECT_BY_DRV
182#endif
180#define USB_VENDOR_ID 0x0781 183#define USB_VENDOR_ID 0x0781
181#define USB_PRODUCT_ID 0x7421 184#define USB_PRODUCT_ID 0x7421
182 185
diff --git a/firmware/export/config-gigabeat-s.h b/firmware/export/config-gigabeat-s.h
index 64f351c1ce..9e6029f00b 100644
--- a/firmware/export/config-gigabeat-s.h
+++ b/firmware/export/config-gigabeat-s.h
@@ -176,10 +176,12 @@
176/* USB On-the-go */ 176/* USB On-the-go */
177#define CONFIG_USBOTG USBOTG_ARC 177#define CONFIG_USBOTG USBOTG_ARC
178 178
179/* enable these for the experimental usb stack */ 179/* enable these for the usb stack */
180#define USE_ROCKBOX_USB 180#define USE_ROCKBOX_USB
181#define HAVE_USBSTACK 181#define HAVE_USBSTACK
182#define USB_STORAGE 182#define USB_STORAGE
183/* usb stack and driver settings */
184#define USB_PORTSCX_PHY_TYPE PORTSCX_PTS_ULPI
183#define USB_VENDOR_ID 0x0930 185#define USB_VENDOR_ID 0x0930
184#define USB_PRODUCT_ID 0x0010 186#define USB_PRODUCT_ID 0x0010
185 187
@@ -201,7 +203,7 @@
201/* Offset ( in the firmware file's header ) to the real data */ 203/* Offset ( in the firmware file's header ) to the real data */
202#define FIRMWARE_OFFSET_FILE_DATA 8 204#define FIRMWARE_OFFSET_FILE_DATA 8
203 205
204#define HAVE_SERIAL 206//#define HAVE_SERIAL
205#define HAVE_VOLUME_IN_LIST 207#define HAVE_VOLUME_IN_LIST
206 208
207/*Remove Comments from UART_INT to enable the UART interrupts,*/ 209/*Remove Comments from UART_INT to enable the UART interrupts,*/
diff --git a/firmware/export/imx31l.h b/firmware/export/imx31l.h
index b572c788a9..b55a56b105 100755
--- a/firmware/export/imx31l.h
+++ b/firmware/export/imx31l.h
@@ -36,7 +36,11 @@
36#define FRAME_SIZE (240*320*2) 36#define FRAME_SIZE (240*320*2)
37 37
38#define DEVBSS_ATTR __attribute__((section(".devbss"),nocommon)) 38#define DEVBSS_ATTR __attribute__((section(".devbss"),nocommon))
39#define QHARRAY_ATTR __attribute__((section(".qharray"),nocommon)) 39/* USBOTG */
40#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(2048)))
41#define USB_NUM_ENDPOINTS 8
42#define USB_DEVBSS_ATTR DEVBSS_ATTR
43#define USB_BASE OTG_BASE_ADDR
40 44
41/* 45/*
42 * AIPS 1 46 * AIPS 1
@@ -1580,6 +1584,4 @@
1580#define UART_FIFO_CTRL 0x881 1584#define UART_FIFO_CTRL 0x881
1581#define TIMEOUT 1000 1585#define TIMEOUT 1000
1582 1586
1583#define USB_BASE OTG_BASE_ADDR
1584
1585#endif /* __IMX31L_H__ */ 1587#endif /* __IMX31L_H__ */
diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h
index b4919a219e..0f622a907d 100644
--- a/firmware/export/pp5020.h
+++ b/firmware/export/pp5020.h
@@ -23,7 +23,12 @@
23 23
24/* All info gleaned and/or copied from the iPodLinux project. */ 24/* All info gleaned and/or copied from the iPodLinux project. */
25 25
26#define QHARRAY_ATTR __attribute__((section(".qharray"),nocommon)) 26/* USBOTG */
27#define USB_NUM_ENDPOINTS 3
28/* This needs to be 2048 byte aligned, but USB_QHARRAY_ATTR should take care
29 * of that */
30#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(4)))
31#define USB_DEVBSS_ATTR IBSS_ATTR
27 32
28/* DRAM starts at 0x10000000, but in Rockbox we remap it to 0x00000000 */ 33/* DRAM starts at 0x10000000, but in Rockbox we remap it to 0x00000000 */
29#define DRAM_START 0x10000000 34#define DRAM_START 0x10000000
diff --git a/firmware/export/usb.h b/firmware/export/usb.h
index a6cfad5889..0a0539a622 100644
--- a/firmware/export/usb.h
+++ b/firmware/export/usb.h
@@ -33,8 +33,11 @@
33enum { 33enum {
34 USB_INSERTED, /* Event+State */ 34 USB_INSERTED, /* Event+State */
35 USB_EXTRACTED, /* Event+State */ 35 USB_EXTRACTED, /* Event+State */
36#ifdef HAVE_USB_POWER 36#if defined(HAVE_USB_POWER) || defined(USB_DETECT_BY_DRV)
37 USB_POWERED, /* State */ 37 USB_POWERED, /* Event+State */
38#endif
39#ifdef USB_DETECT_BY_DRV
40 USB_UNPOWERED, /* Event */
38#endif 41#endif
39#ifdef HAVE_LCD_BITMAP 42#ifdef HAVE_LCD_BITMAP
40 USB_SCREENDUMP, /* State */ 43 USB_SCREENDUMP, /* State */
@@ -107,6 +110,7 @@ struct usb_transfer_completion_event_data
107 110
108void usb_init(void); 111void usb_init(void);
109void usb_enable(bool on); 112void usb_enable(bool on);
113void usb_attach(void);
110void usb_start_monitoring(void); 114void usb_start_monitoring(void);
111void usb_close(void); 115void usb_close(void);
112void usb_acknowledge(long id); 116void usb_acknowledge(long id);
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h
index 7af8e43c8d..d0c8270d93 100644
--- a/firmware/export/usb_core.h
+++ b/firmware/export/usb_core.h
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2007 by Bjรถrn Stenberg 10 * Copyright (C) 2007 by Bjrn Stenberg
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -35,14 +35,6 @@
35 35
36/* endpoints */ 36/* endpoints */
37#define EP_CONTROL 0 37#define EP_CONTROL 0
38#if CONFIG_CPU == IMX31L
39#define NUM_ENDPOINTS 8
40#define USBDEVBSS_ATTR DEVBSS_ATTR
41#else
42#define USBDEVBSS_ATTR IBSS_ATTR
43#define NUM_ENDPOINTS 3
44#endif
45
46extern int usb_max_pkt_size; 38extern int usb_max_pkt_size;
47 39
48struct usb_class_driver; 40struct usb_class_driver;
diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h
index 3d2e689050..23f6f4ce2a 100644
--- a/firmware/export/usb_drv.h
+++ b/firmware/export/usb_drv.h
@@ -24,9 +24,13 @@
24#include "kernel.h" 24#include "kernel.h"
25 25
26void usb_drv_startup(void); 26void usb_drv_startup(void);
27void usb_drv_usb_detect_event(void); /* Target implemented */
28void usb_drv_int_enable(bool enable); /* Target implemented */
29void usb_drv_reset(void);
27void usb_drv_init(void); 30void usb_drv_init(void);
28void usb_drv_exit(void); 31void usb_drv_exit(void);
29void usb_drv_int(void); 32void usb_drv_attach(void);
33void usb_drv_int(void); /* Call from target INT handler */
30void usb_drv_stall(int endpoint, bool stall,bool in); 34void usb_drv_stall(int endpoint, bool stall,bool in);
31bool usb_drv_stalled(int endpoint,bool in); 35bool usb_drv_stalled(int endpoint,bool in);
32int usb_drv_send(int endpoint, void* ptr, int length); 36int usb_drv_send(int endpoint, void* ptr, int length);
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h
index 847e6cfc51..b99b31d1b4 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h
@@ -31,6 +31,14 @@
31#define CPUFREQ_MAX CPU_FREQ 31#define CPUFREQ_MAX CPU_FREQ
32#endif 32#endif
33 33
34/* For USB driver - no accuracy assurance */
35static inline void udelay(unsigned int usecs)
36{
37 unsigned int x;
38 for (x = 0; x < 300*usecs; x++)
39 asm volatile ("");
40}
41
34#if 0 42#if 0
35static inline void udelay(unsigned int usecs) 43static inline void udelay(unsigned int usecs)
36{ 44{
diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c
index cd8b513ecd..c0d7cb8d2a 100644
--- a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c
@@ -29,6 +29,7 @@
29#include "usb-target.h" 29#include "usb-target.h"
30#include "clkctl-imx31.h" 30#include "clkctl-imx31.h"
31#include "power-imx31.h" 31#include "power-imx31.h"
32#include "avic-imx31.h"
32#include "mc13783.h" 33#include "mc13783.h"
33 34
34static int usb_status = USB_EXTRACTED; 35static int usb_status = USB_EXTRACTED;
@@ -75,11 +76,7 @@ bool usb_plugged(void)
75 76
76void usb_init_device(void) 77void usb_init_device(void)
77{ 78{
78 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL); 79 /* Do one-time inits */
79
80 enable_transceiver(true);
81
82 /* Module will be turned off later after firmware init */
83 usb_drv_startup(); 80 usb_drv_startup();
84 81
85 /* Initially poll */ 82 /* Initially poll */
@@ -91,19 +88,37 @@ void usb_init_device(void)
91 88
92void usb_enable(bool on) 89void usb_enable(bool on)
93{ 90{
91 /* Module clock should be on since since this could be called with
92 * OFF initially and writing module registers would hardlock otherwise. */
93 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
94 enable_transceiver(true);
95
94 if (on) 96 if (on)
95 { 97 {
96 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
97 enable_transceiver(true);
98 usb_core_init(); 98 usb_core_init();
99 } 99 }
100 else 100 else
101 { 101 {
102 /* Module clock should be on since this could be called first */
103 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
104 enable_transceiver(true);
105 usb_core_exit(); 102 usb_core_exit();
106 enable_transceiver(false); 103 enable_transceiver(false);
107 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_OFF); 104 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_OFF);
108 } 105 }
109} 106}
107
108void usb_attach(void)
109{
110 usb_enable(true);
111}
112
113static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void)
114{
115 usb_drv_int(); /* Call driver handler */
116}
117
118void usb_drv_int_enable(bool enable)
119{
120 if (enable)
121 avic_enable_int(USB_OTG, IRQ, 7, USB_OTG_HANDLER);
122 else
123 avic_disable_int(USB_OTG);
124}
diff --git a/firmware/target/arm/powermgmt-ascodec.c b/firmware/target/arm/powermgmt-ascodec.c
index ab9fd7b490..6ee6209823 100644
--- a/firmware/target/arm/powermgmt-ascodec.c
+++ b/firmware/target/arm/powermgmt-ascodec.c
@@ -27,6 +27,8 @@
27#include "adc.h" 27#include "adc.h"
28#include "powermgmt.h" 28#include "powermgmt.h"
29#include "power.h" 29#include "power.h"
30#include "usb-target.h"
31#include "usb.h"
30 32
31/*=========================================================================== 33/*===========================================================================
32 * These parameters may be defined per target: 34 * These parameters may be defined per target:
@@ -132,6 +134,10 @@ static inline void charger_plugged(void)
132{ 134{
133 batt_threshold = BATT_FULL_VOLTAGE; /* Start with topped value. */ 135 batt_threshold = BATT_FULL_VOLTAGE; /* Start with topped value. */
134 battery_voltage_sync(); 136 battery_voltage_sync();
137#if defined(USB_STATUS_BY_EVENT) && defined(USB_DETECT_BY_DRV)
138 /* Charger pin detect is USB pin detect */
139 usb_connect_event(true);
140#endif
135} 141}
136 142
137static inline void charger_control(void) 143static inline void charger_control(void)
@@ -186,6 +192,10 @@ static inline void charger_unplugged(void)
186 disable_charger(); 192 disable_charger();
187 if (charge_state >= CHARGE_STATE_ERROR) 193 if (charge_state >= CHARGE_STATE_ERROR)
188 charge_state = DISCHARGING; /* Reset error */ 194 charge_state = DISCHARGING; /* Reset error */
195#if defined(USB_STATUS_BY_EVENT) && defined(USB_DETECT_BY_DRV)
196 /* Charger pin detect is USB pin detect */
197 usb_connect_event(false);
198#endif
189} 199}
190 200
191/* Main charging algorithm - called from powermgmt.c */ 201/* Main charging algorithm - called from powermgmt.c */
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c
index 1cdc0f9e90..99845c2a49 100644
--- a/firmware/target/arm/usb-drv-arc.c
+++ b/firmware/target/arm/usb-drv-arc.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * Driver for ARC USBOTG Device Controller 10 * Driver for ARC USBOTG Device Controller
11 * 11 *
12 * Copyright (C) 2007 by Bjรถrn Stenberg 12 * Copyright (C) 2007 by Bjrn Stenberg
13 * 13 *
14 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
@@ -33,11 +33,6 @@
33//#define LOGF_ENABLE 33//#define LOGF_ENABLE
34#include "logf.h" 34#include "logf.h"
35 35
36#if CONFIG_CPU == IMX31L
37#include "avic-imx31.h"
38static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void);
39#endif
40
41/* USB device mode registers (Little Endian) */ 36/* USB device mode registers (Little Endian) */
42 37
43#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000)) 38#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000))
@@ -326,8 +321,8 @@ struct transfer_descriptor {
326 unsigned int reserved; 321 unsigned int reserved;
327} __attribute__ ((packed)); 322} __attribute__ ((packed));
328 323
329static struct transfer_descriptor td_array[NUM_ENDPOINTS*2] 324static struct transfer_descriptor td_array[USB_NUM_ENDPOINTS*2]
330 USBDEVBSS_ATTR __attribute__((aligned(32))); 325 USB_DEVBSS_ATTR __attribute__((aligned(32)));
331 326
332/* manual: 32.13.1 Endpoint Queue Head (dQH) */ 327/* manual: 32.13.1 Endpoint Queue Head (dQH) */
333struct queue_head { 328struct queue_head {
@@ -342,17 +337,10 @@ struct queue_head {
342 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */ 337 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
343} __attribute__((packed)); 338} __attribute__((packed));
344 339
345#if CONFIG_CPU == IMX31L 340static struct queue_head qh_array[USB_NUM_ENDPOINTS*2]
346static struct queue_head qh_array[NUM_ENDPOINTS*2] 341 USB_QHARRAY_ATTR;
347 QHARRAY_ATTR __attribute__((aligned (2048)));
348#else
349/* This still needs to be 2048 byte aligned, but QHARRAY_ATTR should take
350 care of that */
351static struct queue_head qh_array[NUM_ENDPOINTS*2]
352 QHARRAY_ATTR __attribute__((aligned (4)));
353#endif
354 342
355static struct wakeup transfer_completion_signal[NUM_ENDPOINTS*2] 343static struct wakeup transfer_completion_signal[USB_NUM_ENDPOINTS*2]
356 SHAREDBSS_ATTR; 344 SHAREDBSS_ATTR;
357 345
358static const unsigned int pipe2mask[] = { 346static const unsigned int pipe2mask[] = {
@@ -363,7 +351,7 @@ static const unsigned int pipe2mask[] = {
363 0x10, 0x100000, 351 0x10, 0x100000,
364}; 352};
365 353
366static char ep_allocation[NUM_ENDPOINTS]; 354static char ep_allocation[USB_NUM_ENDPOINTS];
367 355
368/*-------------------------------------------------------------------------*/ 356/*-------------------------------------------------------------------------*/
369static void transfer_completed(void); 357static void transfer_completed(void);
@@ -378,52 +366,46 @@ static void init_control_queue_heads(void);
378static void init_bulk_queue_heads(void); 366static void init_bulk_queue_heads(void);
379static void init_endpoints(void); 367static void init_endpoints(void);
380/*-------------------------------------------------------------------------*/ 368/*-------------------------------------------------------------------------*/
381 369static void usb_drv_stop(void)
382bool usb_drv_powered(void)
383{ 370{
384 return (REG_OTGSC & OTGSC_B_SESSION_VALID) ? true : false; 371 /* disable interrupts */
372 REG_USBINTR = 0;
373 /* stop usb controller (disconnect) */
374 REG_USBCMD &= ~USBCMD_RUN;
385} 375}
386 376
387/* One-time driver startup init */ 377void usb_drv_reset(void)
388void usb_drv_startup(void)
389{ 378{
390#if CONFIG_CPU == IMX31L && defined(BOOTLOADER) 379 int oldlevel = disable_irq_save();
391 /* This is the bootloader - activate the OTG controller or cold
392 * connect later could/will fail */
393 REG_USBCMD &= ~USBCMD_RUN; 380 REG_USBCMD &= ~USBCMD_RUN;
381 restore_irq(oldlevel);
394 382
383#ifdef USB_PORTSCX_PHY_TYPE
384 /* If a PHY type is specified, set it now */
385 REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | USB_PORTSCX_PHY_TYPE;
386#endif
395 sleep(HZ/20); 387 sleep(HZ/20);
396 REG_USBCMD |= USBCMD_CTRL_RESET; 388 REG_USBCMD |= USBCMD_CTRL_RESET;
397 while (REG_USBCMD & USBCMD_CTRL_RESET); 389 while (REG_USBCMD & USBCMD_CTRL_RESET);
390}
398 391
399 /* Set to ULPI */ 392/* One-time driver startup init */
400 REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | PORTSCX_PTS_ULPI; 393void usb_drv_startup(void)
401 sleep(HZ/10); 394{
402#endif
403
404 /* Initialize all the signal objects once */ 395 /* Initialize all the signal objects once */
405 int i; 396 int i;
406 for(i=0;i<NUM_ENDPOINTS*2;i++) { 397 for(i=0;i<USB_NUM_ENDPOINTS*2;i++) {
407 wakeup_init(&transfer_completion_signal[i]); 398 wakeup_init(&transfer_completion_signal[i]);
408 } 399 }
409} 400}
410 401
411/* manual: 32.14.1 Device Controller Initialization */ 402/* manual: 32.14.1 Device Controller Initialization */
412void usb_drv_init(void) 403static void _usb_drv_init(bool attach)
413{ 404{
414 REG_USBCMD &= ~USBCMD_RUN; 405 usb_drv_reset();
415 sleep(HZ/20);
416 REG_USBCMD |= USBCMD_CTRL_RESET;
417 while (REG_USBCMD & USBCMD_CTRL_RESET);
418
419 406
420 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE; 407 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
421 408
422#if CONFIG_CPU == IMX31L
423 /* Set to ULPI */
424 REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | PORTSCX_PTS_ULPI;
425#endif
426
427#ifdef USB_NO_HIGH_SPEED 409#ifdef USB_NO_HIGH_SPEED
428 /* Force device to full speed */ 410 /* Force device to full speed */
429 /* See 32.9.5.9.2 */ 411 /* See 32.9.5.9.2 */
@@ -436,69 +418,76 @@ void usb_drv_init(void)
436 REG_ENDPOINTLISTADDR = (unsigned int)qh_array; 418 REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
437 REG_DEVICEADDR = 0; 419 REG_DEVICEADDR = 0;
438 420
439 /* enable USB interrupts */ 421#ifdef USB_DETECT_BY_DRV
440 REG_USBINTR = 422 if (!attach) {
441 USBINTR_INT_EN | 423 /* enable RESET interrupt */
442 USBINTR_ERR_INT_EN | 424 REG_USBINTR = USBINTR_RESET_EN;
443 USBINTR_PTC_DETECT_EN | 425 }
444 USBINTR_RESET_EN | 426 else
445 USBINTR_SYS_ERR_EN;
446
447#if CONFIG_CPU == IMX31L
448 avic_enable_int(USB_OTG, IRQ, 7, USB_OTG_HANDLER);
449#else
450 /* enable USB IRQ in CPU */
451 CPU_INT_EN = USB_MASK;
452#endif 427#endif
428 {
429 /* enable USB interrupts */
430 REG_USBINTR =
431 USBINTR_INT_EN |
432 USBINTR_ERR_INT_EN |
433 USBINTR_PTC_DETECT_EN |
434 USBINTR_RESET_EN;
435 }
436
437 usb_drv_int_enable(true);
453 438
454 /* go go go */ 439 /* go go go */
455 REG_USBCMD |= USBCMD_RUN; 440 REG_USBCMD |= USBCMD_RUN;
456 441
457
458 logf("usb_drv_init() finished"); 442 logf("usb_drv_init() finished");
459 logf("usb id %x", REG_ID); 443 logf("usb id %x", REG_ID);
460 logf("usb dciversion %x", REG_DCIVERSION); 444 logf("usb dciversion %x", REG_DCIVERSION);
461 logf("usb dccparams %x", REG_DCCPARAMS); 445 logf("usb dccparams %x", REG_DCCPARAMS);
462 446
463 /* now a bus reset will occur. see bus_reset() */ 447 /* now a bus reset will occur. see bus_reset() */
448 (void)attach;
464} 449}
465 450
466void usb_drv_exit(void) 451/** With USB_DETECT_BY_DRV, attach is distinct from init, otherwise eqivalent. **/
452
453/* USB_DETECT_BY_DRV - enable bus reset detection only
454 * else fully enable driver */
455void usb_drv_init(void)
467{ 456{
468 /* disable interrupts */ 457 _usb_drv_init(false);
469 REG_USBINTR = 0; 458}
470 459
471 /* stop usb controller */ 460#ifdef USB_DETECT_BY_DRV
472 REG_USBCMD &= ~USBCMD_RUN; 461/* fully enable driver */
462void usb_drv_attach(void)
463{
464 sleep(HZ/10);
465 _usb_drv_init(true);
466}
467#endif /* USB_DETECT_BY_DRV */
468
469void usb_drv_exit(void)
470{
471 usb_drv_stop();
473 472
474 /* TODO : is one of these needed to save power ? 473 /* TODO : is one of these needed to save power ?
475 REG_PORTSC1 |= PORTSCX_PHY_LOW_POWER_SPD; 474 REG_PORTSC1 |= PORTSCX_PHY_LOW_POWER_SPD;
476 REG_USBCMD |= USBCMD_CTRL_RESET; 475 REG_USBCMD |= USBCMD_CTRL_RESET;
477 */ 476 */
478 477
479#if CONFIG_CPU == IMX31L 478 usb_drv_int_enable(false);
480 avic_disable_int(USB_OTG);
481#else
482 CPU_INT_DIS = USB_MASK;
483#endif
484
485 cancel_cpu_boost();
486} 479}
487 480
488#if CONFIG_CPU == IMX31L
489static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void)
490#else
491void usb_drv_int(void) 481void usb_drv_int(void)
492#endif
493{ 482{
494 unsigned int status = REG_USBSTS; 483 unsigned int usbintr = REG_USBINTR; /* Only watch enabled ints */
484 unsigned int status = REG_USBSTS & usbintr;
495 485
496#if 0 486#if 0
497 if (status & USBSTS_INT) logf("int: usb ioc"); 487 if (status & USBSTS_INT) logf("int: usb ioc");
498 if (status & USBSTS_ERR) logf("int: usb err"); 488 if (status & USBSTS_ERR) logf("int: usb err");
499 if (status & USBSTS_PORT_CHANGE) logf("int: portchange"); 489 if (status & USBSTS_PORT_CHANGE) logf("int: portchange");
500 if (status & USBSTS_RESET) logf("int: reset"); 490 if (status & USBSTS_RESET) logf("int: reset");
501 if (status & USBSTS_SYS_ERR) logf("int: syserr");
502#endif 491#endif
503 492
504 /* usb transaction interrupt */ 493 /* usb transaction interrupt */
@@ -523,8 +512,18 @@ void usb_drv_int(void)
523 /* reset interrupt */ 512 /* reset interrupt */
524 if (status & USBSTS_RESET) { 513 if (status & USBSTS_RESET) {
525 REG_USBSTS = USBSTS_RESET; 514 REG_USBSTS = USBSTS_RESET;
526 bus_reset(); 515#ifdef USB_DETECT_BY_DRV
527 usb_core_bus_reset(); /* tell mom */ 516 if (UNLIKELY(usbintr == USBINTR_RESET_EN)) {
517 /* USB detected - detach and inform */
518 usb_drv_stop();
519 usb_drv_usb_detect_event();
520 }
521 else
522#endif
523 {
524 bus_reset();
525 usb_core_bus_reset(); /* tell mom */
526 }
528 } 527 }
529 528
530 /* port change */ 529 /* port change */
@@ -588,7 +587,14 @@ int usb_drv_port_speed(void)
588 587
589bool usb_drv_connected(void) 588bool usb_drv_connected(void)
590{ 589{
591 return ((REG_PORTSC1 & PORTSCX_CURRENT_CONNECT_STATUS) !=0); 590 return (REG_PORTSC1 &
591 (PORTSCX_PORT_SUSPEND | PORTSCX_CURRENT_CONNECT_STATUS))
592 == PORTSCX_CURRENT_CONNECT_STATUS;
593}
594
595bool usb_drv_powered(void)
596{
597 return (REG_OTGSC & OTGSC_B_SESSION_VALID) ? true : false;
592} 598}
593 599
594void usb_drv_set_address(int address) 600void usb_drv_set_address(int address)
@@ -628,10 +634,7 @@ void usb_drv_set_test_mode(int mode)
628 REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN; 634 REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
629 break; 635 break;
630 } 636 }
631 REG_USBCMD &= ~USBCMD_RUN; 637 usb_drv_reset();
632 sleep(HZ/20);
633 REG_USBCMD |= USBCMD_CTRL_RESET;
634 while (REG_USBCMD & USBCMD_CTRL_RESET);
635 REG_USBCMD |= USBCMD_RUN; 638 REG_USBCMD |= USBCMD_RUN;
636} 639}
637 640
@@ -735,7 +738,7 @@ void usb_drv_cancel_all_transfers(void)
735 while (REG_ENDPTFLUSH); 738 while (REG_ENDPTFLUSH);
736 739
737 memset(td_array, 0, sizeof td_array); 740 memset(td_array, 0, sizeof td_array);
738 for(i=0;i<NUM_ENDPOINTS*2;i++) { 741 for(i=0;i<USB_NUM_ENDPOINTS*2;i++) {
739 if(qh_array[i].wait) { 742 if(qh_array[i].wait) {
740 qh_array[i].wait=0; 743 qh_array[i].wait=0;
741 qh_array[i].status=DTD_STATUS_HALTED; 744 qh_array[i].status=DTD_STATUS_HALTED;
@@ -750,7 +753,7 @@ int usb_drv_request_endpoint(int dir)
750 753
751 bit=(dir & USB_DIR_IN)? 2:1; 754 bit=(dir & USB_DIR_IN)? 2:1;
752 755
753 for (i=1; i < NUM_ENDPOINTS; i++) { 756 for (i=1; i < USB_NUM_ENDPOINTS; i++) {
754 if((ep_allocation[i] & bit)!=0) 757 if((ep_allocation[i] & bit)!=0)
755 continue; 758 continue;
756 ep_allocation[i] |= bit; 759 ep_allocation[i] |= bit;
@@ -819,7 +822,7 @@ static void transfer_completed(void)
819 unsigned int mask = REG_ENDPTCOMPLETE; 822 unsigned int mask = REG_ENDPTCOMPLETE;
820 REG_ENDPTCOMPLETE = mask; 823 REG_ENDPTCOMPLETE = mask;
821 824
822 for (ep=0; ep<NUM_ENDPOINTS; ep++) { 825 for (ep=0; ep<USB_NUM_ENDPOINTS; ep++) {
823 int dir; 826 int dir;
824 for (dir=0; dir<2; dir++) { 827 for (dir=0; dir<2; dir++) {
825 int pipe = ep * 2 + dir; 828 int pipe = ep * 2 + dir;
@@ -869,13 +872,8 @@ static void bus_reset(void)
869 logf("usb: double reset"); 872 logf("usb: double reset");
870 return; 873 return;
871 } 874 }
872#if CONFIG_CPU == IMX31L 875
873 int x;
874 for (x = 0; x < 30000; x++)
875 asm volatile ("");
876#else
877 udelay(100); 876 udelay(100);
878#endif
879 } 877 }
880 if (REG_ENDPTPRIME) { 878 if (REG_ENDPTPRIME) {
881 logf("usb: short reset timeout"); 879 logf("usb: short reset timeout");
@@ -917,7 +915,7 @@ static void init_bulk_queue_heads(void)
917 /* TODO: this should take ep_allocation into account */ 915 /* TODO: this should take ep_allocation into account */
918 916
919 /*** bulk ***/ 917 /*** bulk ***/
920 for(i=1;i<NUM_ENDPOINTS;i++) { 918 for(i=1;i<USB_NUM_ENDPOINTS;i++) {
921 qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 919 qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
922 qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; 920 qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE;
923 qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 921 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)
930 int i; 928 int i;
931 /* TODO: this should take ep_allocation into account */ 929 /* TODO: this should take ep_allocation into account */
932 /* bulk */ 930 /* bulk */
933 for(i=1;i<NUM_ENDPOINTS;i++) { 931 for(i=1;i<USB_NUM_ENDPOINTS;i++) {
934 REG_ENDPTCTRL(i) = 932 REG_ENDPTCTRL(i) =
935 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | 933 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
936 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | 934 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c
index a41ef9a598..8a6d78675f 100644
--- a/firmware/target/arm/usb-fw-pp502x.c
+++ b/firmware/target/arm/usb-fw-pp502x.c
@@ -25,13 +25,13 @@
25 ****************************************************************************/ 25 ****************************************************************************/
26#include "config.h" 26#include "config.h"
27#include "system.h" 27#include "system.h"
28#include "usb-target.h"
28#include "usb.h" 29#include "usb.h"
29#include "button.h" 30#include "button.h"
30#include "ata.h" 31#include "ata.h"
31#include "string.h" 32#include "string.h"
32#include "usb_core.h" 33#include "usb_core.h"
33#include "usb_drv.h" 34#include "usb_drv.h"
34#include "usb-target.h"
35 35
36void usb_init_device(void) 36void usb_init_device(void)
37{ 37{
@@ -94,6 +94,31 @@ void usb_enable(bool on)
94 } 94 }
95} 95}
96 96
97void usb_attach(void)
98{
99#ifdef USB_DETECT_BY_DRV
100 usb_drv_attach();
101#else
102 usb_enable(true);
103#endif
104}
105
106#ifdef USB_DETECT_BY_DRV
107/* Cannot tell charger pin from USB pin */
108static int usb_status = USB_EXTRACTED;
109
110void usb_connect_event(bool inserted)
111{
112 usb_status = inserted ? USB_INSERTED : USB_EXTRACTED;
113 usb_status_event(inserted ? USB_POWERED : USB_UNPOWERED);
114}
115
116/* Called during the bus reset interrupt when in detect mode */
117void usb_drv_usb_detect_event(void)
118{
119 usb_status_event(USB_INSERTED);
120}
121#else /* !USB_DETECT_BY_DRV */
97static bool usb_pin_detect(void) 122static bool usb_pin_detect(void)
98{ 123{
99 bool retval = false; 124 bool retval = false;
@@ -110,12 +135,12 @@ static bool usb_pin_detect(void)
110 retval = true; 135 retval = true;
111 136
112#elif defined(SANSA_C200) 137#elif defined(SANSA_C200)
113 /* GPIO H bit 1 is usb detect */ 138 /* GPIO H bit 1 is usb/charger detect */
114 if (GPIOH_INPUT_VAL & 0x02) 139 if (GPIOH_INPUT_VAL & 0x02)
115 retval = true; 140 retval = true;
116 141
117#elif defined(SANSA_E200) 142#elif defined(SANSA_E200)
118 /* GPIO B bit 4 is usb detect */ 143 /* GPIO B bit 4 is usb/charger detect */
119 if (GPIOB_INPUT_VAL & 0x10) 144 if (GPIOB_INPUT_VAL & 0x10)
120 retval = true; 145 retval = true;
121 146
@@ -137,16 +162,32 @@ static bool usb_pin_detect(void)
137 162
138 return retval; 163 return retval;
139} 164}
165#endif /* USB_DETECT_BY_DRV */
140 166
141/* detect host or charger (INSERTED or POWERED) */ 167void usb_drv_int_enable(bool enable)
168{
169 /* enable/disable USB IRQ in CPU */
170 if(enable) {
171 CPU_INT_EN = USB_MASK;
172 }
173 else {
174 CPU_INT_DIS = USB_MASK;
175 }
176}
177
178/* detect host or charger (INSERTED or EXTRACTED) */
142int usb_detect(void) 179int usb_detect(void)
143{ 180{
181#ifdef USB_DETECT_BY_DRV
182 return usb_status;
183#else
144 if(usb_pin_detect()) { 184 if(usb_pin_detect()) {
145 return USB_INSERTED; 185 return USB_INSERTED;
146 } 186 }
147 else { 187 else {
148 return USB_EXTRACTED; 188 return USB_EXTRACTED;
149 } 189 }
190#endif
150} 191}
151 192
152#if defined(IPOD_COLOR) || defined(IPOD_4G) \ 193#if defined(IPOD_COLOR) || defined(IPOD_4G) \
diff --git a/firmware/target/arm/usb-target.h b/firmware/target/arm/usb-target.h
index cdf6776cc1..913ad805ce 100644
--- a/firmware/target/arm/usb-target.h
+++ b/firmware/target/arm/usb-target.h
@@ -23,4 +23,11 @@
23 23
24void usb_init_device(void); 24void usb_init_device(void);
25 25
26#ifndef BOOTLOADER
27#if defined(SANSA_C200) || defined(SANSA_E200)
28#define USB_STATUS_BY_EVENT /* No USB tick */
29void usb_connect_event(bool inserted);
30#endif
31#endif /* BOOTLOADER */
32
26#endif 33#endif
diff --git a/firmware/usb.c b/firmware/usb.c
index 918d9802a3..10a7ae1bff 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -34,11 +34,11 @@
34#include "disk.h" 34#include "disk.h"
35#include "panic.h" 35#include "panic.h"
36#include "lcd.h" 36#include "lcd.h"
37#include "usb-target.h"
37#include "usb.h" 38#include "usb.h"
38#include "button.h" 39#include "button.h"
39#include "sprintf.h" 40#include "sprintf.h"
40#include "string.h" 41#include "string.h"
41#include "usb-target.h"
42#ifdef HAVE_USBSTACK 42#ifdef HAVE_USBSTACK
43#include "usb_core.h" 43#include "usb_core.h"
44#endif 44#endif
@@ -129,11 +129,13 @@ static inline void usb_slave_mode(bool on)
129#ifdef HAVE_PRIORITY_SCHEDULING 129#ifdef HAVE_PRIORITY_SCHEDULING
130 thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME); 130 thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME);
131#endif 131#endif
132 usb_enable(true); 132 usb_attach();
133 } 133 }
134 else /* usb_state == USB_INSERTED (only!) */ 134 else /* usb_state == USB_INSERTED (only!) */
135 { 135 {
136#ifndef USB_DETECT_BY_DRV
136 usb_enable(false); 137 usb_enable(false);
138#endif
137#ifdef HAVE_PRIORITY_SCHEDULING 139#ifdef HAVE_PRIORITY_SCHEDULING
138 thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM); 140 thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM);
139#endif 141#endif
@@ -234,6 +236,26 @@ static void usb_thread(void)
234 (struct usb_transfer_completion_event_data*)ev.data); 236 (struct usb_transfer_completion_event_data*)ev.data);
235 break; 237 break;
236#endif 238#endif
239#ifdef USB_DETECT_BY_DRV
240 /* In this case, these events the handle cable insertion USB
241 * driver determines INSERTED/EXTRACTED state. */
242 case USB_POWERED:
243 /* Set the state to USB_POWERED for now and enable the driver
244 * to detect a bus reset only. If a bus reset is detected,
245 * USB_INSERTED will be received. */
246 usb_state = USB_POWERED;
247 usb_enable(true);
248 break;
249
250 case USB_UNPOWERED:
251 usb_enable(false);
252 /* This part shouldn't be obligatory for anything that can
253 * reliably detect removal of the data lines. USB_EXTRACTED
254 * could be posted on that event while bus power remains
255 * available. */
256 queue_post(&usb_queue, USB_EXTRACTED, 0);
257 break;
258#endif /* USB_DETECT_BY_DRV */
237 case USB_INSERTED: 259 case USB_INSERTED:
238#ifdef HAVE_LCD_BITMAP 260#ifdef HAVE_LCD_BITMAP
239 if(do_screendump_instead_of_usb) 261 if(do_screendump_instead_of_usb)
@@ -244,14 +266,14 @@ static void usb_thread(void)
244 } 266 }
245#endif 267#endif
246#ifdef HAVE_USB_POWER 268#ifdef HAVE_USB_POWER
247 if (usb_power_button()) 269 if(usb_power_button())
248 { 270 {
249 /* Only charging is desired */ 271 /* Only charging is desired */
250 usb_state = USB_POWERED; 272 usb_state = USB_POWERED;
251#ifdef HAVE_USBSTACK 273#ifdef HAVE_USBSTACK
252 usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); 274 usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false);
253 usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); 275 usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true);
254 usb_enable(true); 276 usb_attach();
255#endif 277#endif
256 break; 278 break;
257 } 279 }
@@ -272,7 +294,7 @@ static void usb_thread(void)
272 294
273 if(!exclusive_storage_access) 295 if(!exclusive_storage_access)
274 { 296 {
275 usb_enable(true); 297 usb_attach();
276 break; 298 break;
277 } 299 }
278#endif /* HAVE_USBSTACK */ 300#endif /* HAVE_USBSTACK */
@@ -304,7 +326,7 @@ static void usb_thread(void)
304 usb_state = USB_EXTRACTED; 326 usb_state = USB_EXTRACTED;
305 break; /* Connected for screendump only */ 327 break; /* Connected for screendump only */
306 } 328 }
307#endif /* HAVE_LCD_BITMAP */ 329#endif
308#ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */ 330#ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */
309#ifdef HAVE_USB_POWER 331#ifdef HAVE_USB_POWER
310 if(usb_state == USB_POWERED) 332 if(usb_state == USB_POWERED)
@@ -312,7 +334,7 @@ static void usb_thread(void)
312 usb_state = USB_EXTRACTED; 334 usb_state = USB_EXTRACTED;
313 break; 335 break;
314 } 336 }
315#endif /* HAVE_USB_POWER */ 337#endif
316#endif /* HAVE_USBSTACK */ 338#endif /* HAVE_USBSTACK */
317 if(usb_state == USB_INSERTED) 339 if(usb_state == USB_INSERTED)
318 { 340 {
@@ -324,9 +346,11 @@ static void usb_thread(void)
324 346
325 usb_state = USB_EXTRACTED; 347 usb_state = USB_EXTRACTED;
326#ifdef HAVE_USBSTACK 348#ifdef HAVE_USBSTACK
327 if (!exclusive_storage_access) 349 if(!exclusive_storage_access)
328 { 350 {
351#ifndef USB_DETECT_BY_DRV /* Disabled handling USB_UNPOWERED */
329 usb_enable(false); 352 usb_enable(false);
353#endif
330 break; 354 break;
331 } 355 }
332 356
@@ -392,19 +416,34 @@ static void usb_thread(void)
392#ifdef USB_STATUS_BY_EVENT 416#ifdef USB_STATUS_BY_EVENT
393void usb_status_event(int current_status) 417void usb_status_event(int current_status)
394{ 418{
395 /* Status should be USB_INSERTED or USB_EXTRACTED. 419 /* Status should be USB_POWERED, USB_UNPOWERED, USB_INSERTED or
420 * USB_EXTRACTED.
396 * Caller isn't expected to filter for changes in status. */ 421 * Caller isn't expected to filter for changes in status. */
397 if (usb_monitor_enabled && last_usb_status != current_status) 422 if(usb_monitor_enabled)
398 { 423 {
399 last_usb_status = current_status; 424 int oldstatus = disable_irq_save(); /* Dual-use function */
400 queue_post(&usb_queue, current_status, 0); 425
426 if(last_usb_status != current_status)
427 {
428 last_usb_status = current_status;
429 queue_post(&usb_queue, current_status, 0);
430 }
431
432 restore_irq(oldstatus);
401 } 433 }
402} 434}
403 435
404void usb_start_monitoring(void) 436void usb_start_monitoring(void)
405{ 437{
438 int status = usb_detect();
439#ifdef USB_DETECT_BY_DRV
440 /* USB detection begins by USB_POWERED, not USB_INSERTED. If it is
441 * USB_EXTRACTED, then nothing changes and post will be skipped. */
442 if(USB_INSERTED == status)
443 status = USB_POWERED;
444#endif
406 usb_monitor_enabled = true; 445 usb_monitor_enabled = true;
407 usb_status_event(usb_detect()); 446 usb_status_event(status);
408} 447}
409#else /* !USB_STATUS_BY_EVENT */ 448#else /* !USB_STATUS_BY_EVENT */
410static void usb_tick(void) 449static void usb_tick(void)
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index 50c9d8589c..5fac5d3815 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -175,7 +175,7 @@ static struct
175 completion_handler_t completion_handler[2]; 175 completion_handler_t completion_handler[2];
176 control_handler_t control_handler[2]; 176 control_handler_t control_handler[2];
177 struct usb_transfer_completion_event_data completion_event; 177 struct usb_transfer_completion_event_data completion_event;
178} ep_data[NUM_ENDPOINTS]; 178} ep_data[USB_NUM_ENDPOINTS];
179 179
180static struct usb_class_driver drivers[USB_NUM_DRIVERS] = 180static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
181{ 181{
@@ -240,7 +240,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
240 240
241static void usb_core_control_request_handler(struct usb_ctrlrequest* req); 241static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
242 242
243static unsigned char response_data[256] USBDEVBSS_ATTR; 243static unsigned char response_data[256] USB_DEVBSS_ATTR;
244 244
245 245
246static short hex[16] = {'0','1','2','3','4','5','6','7', 246static short hex[16] = {'0','1','2','3','4','5','6','7',
@@ -476,7 +476,7 @@ static void allocate_interfaces_and_endpoints(void)
476 476
477 memset(ep_data,0,sizeof(ep_data)); 477 memset(ep_data,0,sizeof(ep_data));
478 478
479 for (i = 0; i < NUM_ENDPOINTS; i++) { 479 for (i = 0; i < USB_NUM_ENDPOINTS; i++) {
480 usb_drv_release_endpoint(i | USB_DIR_OUT); 480 usb_drv_release_endpoint(i | USB_DIR_OUT);
481 usb_drv_release_endpoint(i | USB_DIR_IN); 481 usb_drv_release_endpoint(i | USB_DIR_IN);
482 } 482 }
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index a70681d3e0..e2d58cf0a9 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -401,7 +401,7 @@ void usb_storage_init_connection(void)
401#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \ 401#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \
402 defined(CPU_TCC77X) || defined(CPU_TCC780X) 402 defined(CPU_TCC77X) || defined(CPU_TCC780X)
403 static unsigned char _transfer_buffer[BUFFER_SIZE*2] 403 static unsigned char _transfer_buffer[BUFFER_SIZE*2]
404 USBDEVBSS_ATTR __attribute__((aligned(32))); 404 USB_DEVBSS_ATTR __attribute__((aligned(32)));
405 tb.transfer_buffer = (void *)_transfer_buffer; 405 tb.transfer_buffer = (void *)_transfer_buffer;
406#else 406#else
407 /* TODO : check if bufsize is at least 32K ? */ 407 /* TODO : check if bufsize is at least 32K ? */