diff --git a/firmware/export/config/sansafuze.h b/firmware/export/config/sansafuze.h
index 7e722d6..c85340f 100644
--- a/firmware/export/config/sansafuze.h
+++ b/firmware/export/config/sansafuze.h
@@ -186,13 +186,12 @@

 #ifndef BOOTLOADER

-#define USB_HANDLED_BY_OF
-
 /* USB On-the-go */
 #define CONFIG_USBOTG USBOTG_AS3525

 /* enable these for the experimental usb stack */
 #define HAVE_USBSTACK
+#define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x0781
 #define USB_PRODUCT_ID 0x74c1

diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index 4e1714b..6021556 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -113,6 +113,7 @@ struct vec_int_src vec_int_srcs[] =
     { INT_SRC_NAND, INT_NAND },
     { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO },
     { INT_SRC_AUDIO, INT_AUDIO },
+    { INT_SRC_USB, INT_USB, },
 #ifdef HAVE_MULTIDRIVE
     { INT_SRC_MCI0, INT_MCI0 },
 #endif
@@ -263,11 +264,11 @@ void system_init(void)
     CGU_PLLA = AS3525_PLLA_SETTING;
     while(!(CGU_INTCTRL & (1<<0)));           /* wait until PLLA is locked */

-#if (AS3525_MCLK_SEL == AS3525_CLK_PLLB)
+//#if (AS3525_MCLK_SEL == AS3525_CLK_PLLB)
     CGU_PLLBSUP = 0;        /* enable PLLB */
     CGU_PLLB = AS3525_PLLB_SETTING;
     while(!(CGU_INTCTRL & (1<<1)));           /* wait until PLLB is locked */
-#endif
+//#endif

 #if CONFIG_CPU == AS3525
     /*  Set FCLK frequency */
diff --git a/firmware/target/arm/as3525/usb-drv-as3525.c b/firmware/target/arm/as3525/usb-drv-as3525.c
index 496d434..8bb6040 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525.c
+++ b/firmware/target/arm/as3525/usb-drv-as3525.c
@@ -95,6 +95,33 @@
 #define USB_USER_CONF4          *((volatile unsigned long*) USB_BASE + 0x2020)
 #define USB_USER_CONF5          *((volatile unsigned long*) USB_BASE + 0x2024)

+
+/* register bits */
+
+/* write bits 31..16 */
+#define USB_GPIO_IDDIG_SEL              (1<<30)
+#define USB_GPIO_FS_DATA_EXT            (1<<29)
+#define USB_GPIO_FS_SE0_EXT             (1<<28)
+#define USB_GPIO_FS_XCVR_OWNER          (1<<27)
+#define USB_GPIO_TX_ENABLE_N            (1<<26)
+#define USB_GPIO_TX_BIT_STUFF_EN        (1<<25)
+#define USB_GPIO_BSESSVLD_EXT           (1<<24)
+#define USB_GPIO_ASESSVLD_EXT           (1<<23)
+#define USB_GPIO_VBUS_VLD_EXT           (1<<22)
+#define USB_GPIO_VBUS_VLD_EXT_SEL       (1<<21)
+#define USB_GPIO_XO_ON                  (1<<20)
+#define USB_GPIO_CLK_SEL11              (3<<18)
+#define USB_GPIO_CLK_SEL10              (2<<18)
+#define USB_GPIO_CLK_SEL01              (1<<18)
+#define USB_GPIO_CLK_SEL00              (0<<18)
+#define USB_GPIO_XO_EXT_CLK_ENBN        (1<<17)
+#define USB_GPIO_XO_REFCLK_ENB          (1<<16)
+/* readronly bits 15..0 */
+#define USB_GPIO_PHY_VBUSDRV            (1<<1)
+#define USB_GPIO_HS_INTR                (1<<0)
+
+
+
 struct usb_endpoint
 {
     void *buf;
@@ -121,76 +148,79 @@ void usb_drv_init(void)
     for(i = 0; i < USB_NUM_ENDPOINTS * 2; i++)
         endpoints[i].busy = false;

+    /* length regulator: normal operation */
     ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2);
-    ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) & ~(1<<4));
-
-    /* PHY part */
-    CGU_USB = 1<<5 /* enable */
-        | (CLK_DIV(AS3525_PLLA_FREQ, 48000000) / 2) << 2
-        | 1; /* source = PLLA */

     /* AHB part */
     CGU_PERI |= CGU_USB_CLOCK_ENABLE;

-    USB_GPIO_CSR = 0x6180000;
-    USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */
-    USB_DEV_CTRL |= 0x400; /* soft disconnect */
+    /* PHY part */
+    CGU_USB = 1<<5 /* enable */
+        | (CLK_DIV(AS3525_PLLB_FREQ, 48000000) / 2) << 2
+        | 2; /* source = PLLB */

-    /* UVDD */
+    /* UVDD on */
     ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) | (1<<4));
-    sleep(10); //msleep(100)
+    sleep(HZ/10);

-    USB_GPIO_CSR = 0x6180000;
+    USB_GPIO_CSR = USB_GPIO_CLK_SEL10
+         | USB_GPIO_TX_BIT_STUFF_EN
+         | USB_GPIO_TX_ENABLE_N
+         | USB_GPIO_XO_ON
+         | USB_GPIO_IDDIG_SEL;

-    USB_GPIO_CSR |= 0x1C00000;
-    sleep(1); //msleep(3)
-    USB_GPIO_CSR |= 0x200000;
-    sleep(1); //msleep(10)
+    /* device init */

-    USB_DEV_CTRL |= 0x400; /* soft disconnect */
+    USB_DEV_EP_INTR_MASK = 0xffffffff;   /* unmask all flags */
+    USB_DEV_INTR_MASK = 0;

-    USB_GPIO_CSR &= ~0x1C00000;
-    sleep(1); //msleep(3)
-    USB_GPIO_CSR &= ~0x200000;
-    sleep(1); //msleep(10)
-    USB_DEV_CTRL &= ~0x400; /* clear soft disconnect */
+    USB_DEV_CFG = (1<<1) /* low speed */ |
+                  (0<<2)  /* remote wakeup */ |
+                  (1<<3)  /* self powered */ |
+                  (0<<5)  /* 16 bit phy */ |
+                  (1<<6)  /* bidir phy */ |
+                  (0<<17) /* csr prog */ ;

-#if defined(SANSA_CLIP)
-    GPIOA_DIR |= (1<<6);
-    GPIOA_PIN(6) = (1<<6);
-    GPIOA_DIR &= ~(1<<6);   /* restore direction for usb_detect() */
-#elif defined(SANSA_FUZE) || defined(SANSA_E200V2)
-    GPIOA_DIR |= (1<<3);
-    GPIOA_PIN(3) = (1<<3);
-    GPIOA_DIR &= ~(1<<3);   /* restore direction for usb_detect() */
-#elif defined(SANSA_C200V2)
-    GPIOA_DIR |= (1<<1);
-    GPIOA_PIN(1) = (1<<1);
-    GPIOA_DIR &= ~(1<<1);   /* restore direction for usb_detect() */
-#endif
+    USB_DEV_CTRL = (1<<8) /* burst control */ |
+                   (1<<4) /* descriptor update */ |
+                   (1<<2) /* dma */ |
+                   (1<<10) /* soft disconnect */ |
+                   (3 << 16) /* burst len  = 8 dwords */;

-#if 0 /* linux */
-    USB_DEV_CFG |= (1<<17)  /* csr programming */
-                |  (1<<3)   /* self powered */
-                |  (1<<2);  /* remote wakeup */
+    /* control endpoint setup (in/out) */
+    USB_IEP_CTRL(0) = USB_OEP_CTRL(0) = 0;

-    USB_DEV_CFG &= ~3; /* high speed */
-#endif
+    USB_IEP_CTRL(0) &= ~(3 << 4); /* control endpoint */
+    USB_OEP_CTRL(0) &= ~(3 << 4); /* control endpoint */

-    USB_IEP_CTRL(0) &= (3 << 4); /* control endpoint */
-    USB_IEP_DESC_PTR(0) = 0;
+    USB_IEP_TXFSIZE(0) = 32; // full speed
+    USB_IEP_MPS(0) = 64; // max packet size
+    USB_OEP_MPS(0) = 64; //max packet size

-    USB_OEP_CTRL(0) &= (3 << 4); /* control endpoint */
-    USB_OEP_DESC_PTR(0) = 0;
+    USB_PHY_EP0_INFO = 0 /* number */ |
+            (0<<4) /* direction */ |
+            (0<<5) /* ctrl ep */ |
+            (1<< 7) /* config num  */ |
+            (0<<11) /* interface num */ |
+            (0<<15) /* alternat setting number */ |
+            (64 << 19); // max packet size

-    USB_DEV_INTR_MASK &= ~0xff;   /* unmask all flags */
+    //USB_IEP_CTRL(0) |= (1<<0); // stall bit
+    USB_IEP_CTRL(0) |= (1<<7)|(1<<1); // Set NAK, FLUSH
+    USB_OEP_CTRL(0) |= (1<<8)|(1<<1); // clear NAK, FLUSH

-    USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16));    /* ep 0 */
+    /* TODO : dma setup */

-    VIC_INT_ENABLE = INTERRUPT_USB;
+    USB_DEV_EP_INTR |= (1<<0) | (1<<16); /* clear interrupts */
+    USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16));    /* ep 0 in & out */
+
+    /* unmask status */
+    USB_IEP_STS_MASK(0) &= ~0x1ff0;  // bits 12-4: mask for all status
+    USB_OEP_STS_MASK(0) &= ~0x1ff0;  // bits 12-4: mask for all status
+
+    USB_DEV_CFG &= ~(1<<10); /* clear soft disconnect */

-    USB_IEP_CTRL(0) |= (1<<7); /* set NAK */
-    USB_OEP_CTRL(0) |= (1<<7); /* set NAK */
+    VIC_INT_ENABLE = INTERRUPT_USB;
 }

 void usb_drv_exit(void)
@@ -209,6 +239,7 @@ int usb_drv_port_speed(void)

 int usb_drv_request_endpoint(int type, int dir)
 {
+    panicf("%s(%d,%d)",__func__,type,dir);
     (void) type;
     int i = dir == USB_DIR_IN ? 0 : 1;

@@ -227,9 +258,11 @@ int usb_drv_request_endpoint(int type, int dir)
 void usb_drv_release_endpoint(int ep)
 {
     int i = (ep & 0x7f) * 2;
-    if(ep & USB_DIR_OUT)
+    if(!(ep & USB_DIR_IN))
         i++;
     endpoints[i].busy = false;
+
+    ep &= ~USB_DIR_IN;
     USB_DEV_EP_INTR_MASK |= (1<<ep) | (1<<(16+ep));
 }

@@ -239,19 +272,31 @@ void usb_drv_cancel_all_transfers(void)

 int usb_drv_recv(int ep, void *ptr, int len)
 {
-    (void)ep;(void)ptr;(void)len;
+    panicf("%s(%d,%p,%d)", __func__,ep,ptr,len);
+    int i = (ep & 0x7f) * 2;
+    if(!(ep & USB_DIR_IN))
+        i++;
+
     if(ep >= 2)
         return -1;

+    (void)ptr;(void)len;
+
     return -1;
 }

 int usb_drv_send(int ep, void *ptr, int len)
 {
-    (void)ep;(void)ptr;(void)len;
+    panicf("%s(%d,%p,%d)", __func__,ep,ptr,len);
+    int i = (ep & 0x7f) * 2;
+    if(!(ep & USB_DIR_IN))
+        i++;
+
     if(ep >= 2)
         return -1;

+    (void)ptr;(void)len;
+
     return -1;
 }

@@ -264,7 +309,37 @@ int usb_drv_send_nonblocking(int ep, void *ptr, int len)
 /* interrupt service routine */
 void INT_USB(void)
 {
-    panicf("USB interrupt !");
+    int intr = USB_DEV_INTR;
+    if(intr)
+    {
+        panicf("USB devintr: 0x%x", intr);
+        USB_DEV_INTR = intr;
+    }
+
+    int ep = USB_DEV_EP_INTR; // = 0x10001 (in/out)
+    if(ep)
+    {
+        if(ep & (1<<0)) // ctrl in
+        {
+            panicf("ctrl in 0x%x",USB_IEP_STS(0));
+        }
+        if(ep & (1<<1)) // bulk in
+        {
+        }
+        if(ep & (1<<3)) // intr in
+        {
+        }
+        if(ep & (1<<16)) // ctrl out
+        {
+            panicf("ctrl in 0x%x",USB_OEP_STS(0));
+        }
+        if(ep & (1<<17)) // bulk out
+        {
+        }
+
+        panicf("USB : 0x%x 0x%x", intr, ep);
+        USB_DEV_EP_INTR = ep;
+    }
 }

 /* (not essential? , not implemented in usb-tcc.c) */