summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2008-12-31 01:11:04 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2008-12-31 01:11:04 +0000
commit9ac7af749bceb67916b3179a3b7c7eee6ee6443a (patch)
treedcc9c594eaeed65015d6dab3fa04da5d1734314d
parent5d3a035cb3714028a659ecd8abbad034666b7b3c (diff)
downloadrockbox-9ac7af749bceb67916b3179a3b7c7eee6ee6443a.tar.gz
rockbox-9ac7af749bceb67916b3179a3b7c7eee6ee6443a.zip
Ingenic players:
* Further implement USB driver * Add preliminary clock setup * Fix USB VID/PID git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19618 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/config-ondavx747.h4
-rw-r--r--firmware/export/jz4740.h68
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c171
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4740.c294
5 files changed, 444 insertions, 95 deletions
diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h
index 2856e7e16d..2fe0564e71 100644
--- a/firmware/export/config-ondavx747.h
+++ b/firmware/export/config-ondavx747.h
@@ -158,7 +158,7 @@
158 158
159#define CONFIG_USBOTG USBOTG_JZ4740 159#define CONFIG_USBOTG USBOTG_JZ4740
160#define HAVE_USBSTACK 160#define HAVE_USBSTACK
161#define USB_VENDOR_ID 0x041e 161#define USB_VENDOR_ID 0x07C4
162#define USB_PRODUCT_ID 0x4133 162#define USB_PRODUCT_ID 0xA4A5
163 163
164#endif 164#endif
diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h
index e63228ff70..7fbfba283f 100644
--- a/firmware/export/jz4740.h
+++ b/firmware/export/jz4740.h
@@ -260,28 +260,29 @@
260 #define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT) 260 #define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT)
261 261
262/* Clock Gate Register */ 262/* Clock Gate Register */
263#define CPM_CLKGR_UART1 (1 << 15) 263#define CPM_CLKGR_UART1 (1 << 15)
264#define CPM_CLKGR_UHC (1 << 14) 264#define CPM_CLKGR_UHC (1 << 14)
265#define CPM_CLKGR_IPU (1 << 13) 265#define CPM_CLKGR_IPU (1 << 13)
266#define CPM_CLKGR_DMAC (1 << 12) 266#define CPM_CLKGR_DMAC (1 << 12)
267#define CPM_CLKGR_UDC (1 << 11) 267#define CPM_CLKGR_UDC (1 << 11)
268#define CPM_CLKGR_LCD (1 << 10) 268#define CPM_CLKGR_LCD (1 << 10)
269#define CPM_CLKGR_CIM (1 << 9) 269#define CPM_CLKGR_CIM (1 << 9)
270#define CPM_CLKGR_SADC (1 << 8) 270#define CPM_CLKGR_SADC (1 << 8)
271#define CPM_CLKGR_MSC (1 << 7) 271#define CPM_CLKGR_MSC (1 << 7)
272#define CPM_CLKGR_AIC1 (1 << 6) 272#define CPM_CLKGR_AIC1 (1 << 6)
273#define CPM_CLKGR_AIC2 (1 << 5) 273#define CPM_CLKGR_AIC2 (1 << 5)
274#define CPM_CLKGR_SSI (1 << 4) 274#define CPM_CLKGR_SSI (1 << 4)
275#define CPM_CLKGR_I2C (1 << 3) 275#define CPM_CLKGR_I2C (1 << 3)
276#define CPM_CLKGR_RTC (1 << 2) 276#define CPM_CLKGR_RTC (1 << 2)
277#define CPM_CLKGR_TCU (1 << 1) 277#define CPM_CLKGR_TCU (1 << 1)
278#define CPM_CLKGR_UART0 (1 << 0) 278#define CPM_CLKGR_UART0 (1 << 0)
279 279
280/* Sleep Control Register */ 280/* Sleep Control Register */
281#define CPM_SCR_O1ST_BIT 8 281#define CPM_SCR_O1ST_BIT 8
282#define CPM_SCR_O1ST_MASK (0xff << CPM_SCR_O1ST_BIT) 282#define CPM_SCR_O1ST_MASK (0xff << CPM_SCR_O1ST_BIT)
283#define CPM_SCR_USBHOST_SUSPEND (1 << 7)
283#define CPM_SCR_USBPHY_ENABLE (1 << 6) 284#define CPM_SCR_USBPHY_ENABLE (1 << 6)
284#define CPM_SCR_OSC_ENABLE (1 << 4) 285#define CPM_SCR_OSC_ENABLE (1 << 4)
285 286
286/* Hibernate Control Register */ 287/* Hibernate Control Register */
287#define CPM_HCR_PD (1 << 0) 288#define CPM_HCR_PD (1 << 0)
@@ -2419,7 +2420,7 @@
2419#define USB_INTR_OUTEP1 0x0002 2420#define USB_INTR_OUTEP1 0x0002
2420#define USB_INTR_OUTEP2 0x0004 2421#define USB_INTR_OUTEP2 0x0004
2421 2422
2422#define USB_INTR_EP(n) (n*2) 2423#define USB_INTR_EP(n) ((n)==0 ? 1 : ((n)*2))
2423 2424
2424/* CSR0 bit masks */ 2425/* CSR0 bit masks */
2425#define USB_CSR0_OUTPKTRDY 0x01 2426#define USB_CSR0_OUTPKTRDY 0x01
@@ -3282,56 +3283,59 @@ do { \
3282#define __cpm_sleep_mode() \ 3283#define __cpm_sleep_mode() \
3283 (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP) 3284 (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP)
3284 3285
3285#define __cpm_stop_all() (REG_CPM_CLKGR = 0xffff) 3286#define __cpm_stop_all() (REG_CPM_CLKGR = 0xffff)
3286#define __cpm_stop_uart1() (REG_CPM_CLKGR |= CPM_CLKGR_UART1) 3287#define __cpm_stop_uart1() (REG_CPM_CLKGR |= CPM_CLKGR_UART1)
3287#define __cpm_stop_uhc() (REG_CPM_CLKGR |= CPM_CLKGR_UHC) 3288#define __cpm_stop_uhc() (REG_CPM_CLKGR |= CPM_CLKGR_UHC)
3288#define __cpm_stop_ipu() (REG_CPM_CLKGR |= CPM_CLKGR_IPU) 3289#define __cpm_stop_ipu() (REG_CPM_CLKGR |= CPM_CLKGR_IPU)
3289#define __cpm_stop_dmac() (REG_CPM_CLKGR |= CPM_CLKGR_DMAC) 3290#define __cpm_stop_dmac() (REG_CPM_CLKGR |= CPM_CLKGR_DMAC)
3290#define __cpm_stop_udc() (REG_CPM_CLKGR |= CPM_CLKGR_UDC) 3291#define __cpm_stop_udc() (REG_CPM_CLKGR |= CPM_CLKGR_UDC)
3291#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD) 3292#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD)
3292#define __cpm_stop_cim() (REG_CPM_CLKGR |= CPM_CLKGR_CIM) 3293#define __cpm_stop_cim() (REG_CPM_CLKGR |= CPM_CLKGR_CIM)
3293#define __cpm_stop_sadc() (REG_CPM_CLKGR |= CPM_CLKGR_SADC) 3294#define __cpm_stop_sadc() (REG_CPM_CLKGR |= CPM_CLKGR_SADC)
3294#define __cpm_stop_msc() (REG_CPM_CLKGR |= CPM_CLKGR_MSC) 3295#define __cpm_stop_msc() (REG_CPM_CLKGR |= CPM_CLKGR_MSC)
3295#define __cpm_stop_aic1() (REG_CPM_CLKGR |= CPM_CLKGR_AIC1) 3296#define __cpm_stop_aic1() (REG_CPM_CLKGR |= CPM_CLKGR_AIC1)
3296#define __cpm_stop_aic2() (REG_CPM_CLKGR |= CPM_CLKGR_AIC2) 3297#define __cpm_stop_aic2() (REG_CPM_CLKGR |= CPM_CLKGR_AIC2)
3297#define __cpm_stop_ssi() (REG_CPM_CLKGR |= CPM_CLKGR_SSI) 3298#define __cpm_stop_ssi() (REG_CPM_CLKGR |= CPM_CLKGR_SSI)
3298#define __cpm_stop_i2c() (REG_CPM_CLKGR |= CPM_CLKGR_I2C) 3299#define __cpm_stop_i2c() (REG_CPM_CLKGR |= CPM_CLKGR_I2C)
3299#define __cpm_stop_rtc() (REG_CPM_CLKGR |= CPM_CLKGR_RTC) 3300#define __cpm_stop_rtc() (REG_CPM_CLKGR |= CPM_CLKGR_RTC)
3300#define __cpm_stop_tcu() (REG_CPM_CLKGR |= CPM_CLKGR_TCU) 3301#define __cpm_stop_tcu() (REG_CPM_CLKGR |= CPM_CLKGR_TCU)
3301#define __cpm_stop_uart0() (REG_CPM_CLKGR |= CPM_CLKGR_UART0) 3302#define __cpm_stop_uart0() (REG_CPM_CLKGR |= CPM_CLKGR_UART0)
3302 3303
3303#define __cpm_start_all() (REG_CPM_CLKGR = 0x0) 3304#define __cpm_start_all() (REG_CPM_CLKGR = 0x0)
3304#define __cpm_start_uart1() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1) 3305#define __cpm_start_uart1() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1)
3305#define __cpm_start_uhc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC) 3306#define __cpm_start_uhc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC)
3306#define __cpm_start_ipu() (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU) 3307#define __cpm_start_ipu() (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU)
3307#define __cpm_start_dmac() (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC) 3308#define __cpm_start_dmac() (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC)
3308#define __cpm_start_udc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC) 3309#define __cpm_start_udc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC)
3309#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD) 3310#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD)
3310#define __cpm_start_cim() (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM) 3311#define __cpm_start_cim() (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM)
3311#define __cpm_start_sadc() (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC) 3312#define __cpm_start_sadc() (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC)
3312#define __cpm_start_msc() (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC) 3313#define __cpm_start_msc() (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC)
3313#define __cpm_start_aic1() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1) 3314#define __cpm_start_aic1() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1)
3314#define __cpm_start_aic2() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2) 3315#define __cpm_start_aic2() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2)
3315#define __cpm_start_ssi() (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI) 3316#define __cpm_start_ssi() (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI)
3316#define __cpm_start_i2c() (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C) 3317#define __cpm_start_i2c() (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C)
3317#define __cpm_start_rtc() (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC) 3318#define __cpm_start_rtc() (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC)
3318#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU) 3319#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU)
3319#define __cpm_start_uart0() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0) 3320#define __cpm_start_uart0() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0)
3320 3321
3321#define __cpm_get_o1st() \ 3322#define __cpm_get_o1st() \
3322 ((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT) 3323 ((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT)
3323#define __cpm_set_o1st(v) \ 3324#define __cpm_set_o1st(v) \
3324 (REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT))) 3325 (REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT)))
3325#define __cpm_suspend_usbphy() (REG_CPM_SCR |= CPM_SCR_USBPHY_SUSPEND) 3326#define __cpm_suspend_usbphy() (REG_CPM_SCR |= CPM_SCR_USBPHY_SUSPEND)
3327#define __cpm_suspend_usbhost() (REG_CPM_SCR |= CPM_SCR_USBHOST_SUSPEND)
3326#define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE) 3328#define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE)
3327 3329
3328 3330
3331#define CFG_EXTAL 12000000
3332
3329#ifdef CFG_EXTAL 3333#ifdef CFG_EXTAL
3330#define JZ_EXTAL CFG_EXTAL 3334#define JZ_EXTAL CFG_EXTAL
3331#else 3335#else
3332#define JZ_EXTAL 3686400 3336#define JZ_EXTAL 3686400
3333#endif 3337#endif
3334#define JZ_EXTAL2 32768 /* RTC clock */ 3338#define JZ_EXTAL2 32768 /* RTC clock */
3335 3339
3336/* PLL output frequency */ 3340/* PLL output frequency */
3337static __inline__ unsigned int __cpm_get_pllout(void) 3341static __inline__ unsigned int __cpm_get_pllout(void)
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c
index 40d9bb6106..faed5ecda2 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c
@@ -203,7 +203,7 @@ static void _set_lcd_clock(void)
203 203
204 __cpm_stop_lcd(); 204 __cpm_stop_lcd();
205 pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source, 0:pllout/2 1: pllout */ 205 pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source, 0:pllout/2 1: pllout */
206 pll_div = pll_div ? 1 : 2 ; 206 pll_div = pll_div ? 1 : 2;
207 val = ( __cpm_get_pllout()/pll_div ) / __cpm_get_pclk(); 207 val = ( __cpm_get_pllout()/pll_div ) / __cpm_get_pclk();
208 val--; 208 val--;
209 if ( val > 0x1ff ) 209 if ( val > 0x1ff )
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index 48fb192810..c741d9f311 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -663,6 +663,168 @@ void dma_disable(void)
663 } 663 }
664} 664}
665 665
666static inline void pll_convert(unsigned int pllin, unsigned int *pll_cfcr, unsigned int *pll_plcr1)
667{
668 register unsigned int cfcr, plcr1;
669 int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
670 int nf;
671
672 cfcr = CPM_CPCCR_CLKOEN |
673 (div[0] << CPM_CPCCR_CDIV_BIT) |
674 (div[1] << CPM_CPCCR_HDIV_BIT) |
675 (div[2] << CPM_CPCCR_PDIV_BIT) |
676 (div[3] << CPM_CPCCR_MDIV_BIT) |
677 (div[4] << CPM_CPCCR_LDIV_BIT);
678
679 //nf = pllin * 2 / CFG_EXTAL;
680 nf = pllin * 2 / 375299969;
681 plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
682 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
683 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
684 (0xa << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
685 CPM_CPPCR_PLLEN; /* enable PLL */
686
687 /* init PLL */
688 *pll_cfcr = cfcr;
689 *pll_plcr1 = plcr1;
690}
691
692static inline void sdram_convert(unsigned int pllin, unsigned int *sdram_freq)
693{
694 register unsigned int ns, tmp;
695
696 ns = 1000000000 / pllin;
697 tmp = 15625 / ns;
698
699 /* Set refresh registers */
700 tmp = tmp / 64 + 1;
701
702 if(tmp > 0xff)
703 tmp = 0xff;
704
705 *sdram_freq = tmp;
706}
707
708static inline void set_cpu_freq(unsigned int pllin, unsigned int div)
709{
710 unsigned int sdram_freq;
711 unsigned int pll_cfcr, pll_plcr1;
712 int div_preq[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
713
714 if(pllin < 25000000 || pllin > 420000000)
715 panicf("PLL should be >25000000 and <420000000 !");
716
717 unsigned long t = read_c0_status();
718 write_c0_status(t & ~1);
719
720 pll_convert(pllin, &pll_cfcr, &pll_plcr1);
721
722 sdram_convert(pllin / div_preq[div], &sdram_freq);
723
724 REG_CPM_CPCCR &= ~CPM_CPCCR_CE;
725
726 REG_CPM_CPCCR = pll_cfcr;
727 REG_CPM_CPPCR = pll_plcr1;
728
729 REG_EMC_RTCOR = sdram_freq;
730 REG_EMC_RTCNT = sdram_freq;
731
732 REG_CPM_CPCCR |= CPM_CPCCR_CE;
733
734 detect_clock();
735
736 write_c0_status(t);
737}
738
739static void OF_init_clocks(void)
740{
741 unsigned int prog_entry = ((unsigned int)OF_init_clocks >> 5) << 5;
742 unsigned int i, prog_size = 1024;
743
744 for(i = prog_entry; i < prog_entry + prog_size; i += 32)
745 __asm__ __volatile__("cache 0x1c, 0x00(%0) \n"
746 :
747 : "r" (i)
748 );
749
750 /* disable PLL clock */
751 REG_CPM_CPPCR &= ~CPM_CPPCR_PLLEN;
752 REG_CPM_CPCCR |= CPM_CPCCR_CE;
753
754 unsigned long old_clocks = REG_CPM_CLKGR;
755 /*
756 REG_CPM_CLKGR = ~( CPM_CLKGR_UART0 | CPM_CLKGR_TCU |
757 CPM_CLKGR_RTC | CPM_CLKGR_SADC |
758 CPM_CLKGR_LCD );
759 */
760
761 unsigned long old_scr = REG_CPM_SCR;
762 REG_CPM_SCR &= ~CPM_SCR_OSC_ENABLE; /* O1SE: 12M oscillator is disabled in Sleep mode */
763
764 REG_EMC_DMCR |= (EMC_DMCR_RMODE | EMC_DMCR_RFSH); /* self refresh + refresh is performed */
765 REG_EMC_DMCR = (REG_EMC_DMCR & ~EMC_DMCR_RMODE) | 1; /* -> RMODE = auto refresh
766 -> CAS mode = 2 cycles */
767 __asm__ __volatile__("wait \n");
768
769 REG_CPM_CLKGR = old_clocks;
770 REG_CPM_SCR = old_scr;
771
772 for(i=0; i<90; i++);
773
774 set_cpu_freq(336000000, 1);
775
776 for(i=0; i<60; i++);
777}
778
779static void my_init_clocks(void)
780{
781 unsigned long t = read_c0_status();
782 write_c0_status(t & ~1);
783
784 unsigned int prog_entry = ((unsigned int)my_init_clocks / 32 - 1) * 32;
785 unsigned int i, prog_size = 1024;
786
787 for(i = prog_entry; i < prog_entry + prog_size; i += 32)
788 __asm__ __volatile__("cache 0x1c, 0x00(%0) \n"
789 :
790 : "r" (i)
791 );
792
793 unsigned int sdram_freq, plcr1, cfcr;
794
795 sdram_convert(336000000/3, &sdram_freq);
796
797 cfcr = CPM_CPCCR_CLKOEN |
798 (6 << CPM_CPCCR_UDIV_BIT) |
799 CPM_CPCCR_UCS |
800 CPM_CPCCR_PCS |
801 (0 << CPM_CPCCR_CDIV_BIT) |
802 (2 << CPM_CPCCR_HDIV_BIT) |
803 (2 << CPM_CPCCR_PDIV_BIT) |
804 (2 << CPM_CPCCR_MDIV_BIT) |
805 (2 << CPM_CPCCR_LDIV_BIT);
806
807 plcr1 = (54 << CPM_CPPCR_PLLM_BIT) | /* FD */
808 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
809 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
810 (0x20 << CPM_CPPCR_PLLST_BIT)| /* PLL stable time */
811 CPM_CPPCR_PLLEN; /* enable PLL */
812
813 REG_CPM_CPCCR &= ~CPM_CPCCR_CE;
814
815 REG_CPM_CPCCR = cfcr;
816 REG_CPM_CPPCR = plcr1;
817
818 REG_EMC_RTCOR = sdram_freq;
819 REG_EMC_RTCNT = sdram_freq;
820
821 REG_CPM_CPCCR |= CPM_CPCCR_CE;
822
823 REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | (11 << CPM_LPCDR_PIXDIV_BIT);
824
825 write_c0_status(t);
826}
827
666extern int main(void); 828extern int main(void);
667extern void except_common_entry(void); 829extern void except_common_entry(void);
668 830
@@ -696,6 +858,15 @@ void system_main(void)
696 858
697 /* Disable unneeded clocks, clocks are enabled when needed */ 859 /* Disable unneeded clocks, clocks are enabled when needed */
698 __cpm_stop_all(); 860 __cpm_stop_all();
861 __cpm_suspend_usbhost();
862
863#if 0
864 my_init_clocks();
865 /*__cpm_stop_udc();
866 REG_CPM_CPCCR |= CPM_CPCCR_UCS;
867 REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | (3 << CPM_CPCCR_UDIV_BIT);
868 __cpm_start_udc();*/
869#endif
699 870
700 /* Enable interrupts at core level */ 871 /* Enable interrupts at core level */
701 sti(); 872 sti();
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
index f06e796e05..eda3fb3b88 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
@@ -34,11 +34,12 @@
34#define USB_EP0_RX 1 34#define USB_EP0_RX 1
35#define USB_EP0_TX 2 35#define USB_EP0_TX 2
36 36
37#define EP_BUF_LEFT(ep) (ep->length - ep->sent) 37#define EP_BUF_LEFT(ep) ((ep)->length - (ep)->sent)
38#define EP_PTR(ep) ((void*)((unsigned int)ep->buf + ep->sent)) 38#define EP_PTR(ep) ((void*)((unsigned int)(ep)->buf + (ep)->sent))
39#define EP_NUMBER(ep) (((int)ep - (int)&endpoints[0])/sizeof(struct usb_endpoint)) 39#define EP_NUMBER(ep) (((int)(ep) - (int)&endpoints[0])/sizeof(struct usb_endpoint))
40#define EP_NUMBER2(ep) (EP_NUMBER((ep))/2)
40#define TOTAL_EP() (sizeof(endpoints)/sizeof(struct usb_endpoint)) 41#define TOTAL_EP() (sizeof(endpoints)/sizeof(struct usb_endpoint))
41#define EP_IS_IN(ep) (EP_NUMBER(ep)%2) 42#define EP_IS_IN(ep) (EP_NUMBER((ep))%2)
42 43
43enum ep_type 44enum ep_type
44{ 45{
@@ -66,11 +67,11 @@ static unsigned char ep0_rx_buf[64];
66static unsigned char ep0state = USB_EP0_IDLE; 67static unsigned char ep0state = USB_EP0_IDLE;
67static struct usb_endpoint endpoints[] = 68static struct usb_endpoint endpoints[] =
68{ 69{
69 /* buf length sent type use_dma fifo_addr fifo_size */ 70 /* buf length sent type use_dma fifo_addr fifo_size */
70 {&ep0_rx_buf, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 }, 71 {&ep0_rx_buf, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 },
71 {NULL, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 }, 72 {NULL, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 },
72 {NULL, 0, {0}, ep_bulk, true, USB_FIFO_EP1, 512}, 73 {NULL, 0, {0}, ep_bulk, false, USB_FIFO_EP1, 512},
73 {NULL, 0, {0}, ep_bulk, true, USB_FIFO_EP1, 512}, 74 {NULL, 0, {0}, ep_bulk, false, USB_FIFO_EP1, 512},
74 {NULL, 0, {0}, ep_interrupt, false, USB_FIFO_EP2, 64 } 75 {NULL, 0, {0}, ep_interrupt, false, USB_FIFO_EP2, 64 }
75}; 76};
76 77
@@ -81,7 +82,7 @@ static inline void select_endpoint(int ep)
81 82
82static void readFIFO(struct usb_endpoint *ep, unsigned int size) 83static void readFIFO(struct usb_endpoint *ep, unsigned int size)
83{ 84{
84 logf("readFIFO(EP%d, %d)", EP_NUMBER(ep), size); 85 logf("readFIFO(EP%d, %d)", EP_NUMBER2(ep), size);
85 86
86 register unsigned char *ptr = (unsigned char*)EP_PTR(ep); 87 register unsigned char *ptr = (unsigned char*)EP_PTR(ep);
87 register unsigned int *ptr32 = (unsigned int*)ptr; 88 register unsigned int *ptr32 = (unsigned int*)ptr;
@@ -117,19 +118,19 @@ static void readFIFO(struct usb_endpoint *ep, unsigned int size)
117 118
118static void writeFIFO(struct usb_endpoint *ep, unsigned int size) 119static void writeFIFO(struct usb_endpoint *ep, unsigned int size)
119{ 120{
120 logf("writeFIFO(EP%d, %d)", EP_NUMBER(ep), size); 121 //logf("writeFIFO(EP%d, %d)", EP_NUMBER2(ep), size);
121 122
122 register unsigned int *d = (unsigned int *)EP_PTR(ep); 123 register unsigned int *d = (unsigned int *)EP_PTR(ep);
123 register unsigned char *c; 124 register unsigned char *c;
124 register int s; 125 register int s;
125 126
126 if (size > 0) 127 if(size > 0)
127 { 128 {
128 s = size >> 2; 129 s = size >> 2;
129 while (s--) 130 while (s--)
130 REG32(ep->fifo_addr) = *d++; 131 REG32(ep->fifo_addr) = *d++;
131 132
132 if ( (s = size & 3) ) 133 if( (s = size & 3) )
133 { 134 {
134 c = (unsigned char *)d; 135 c = (unsigned char *)d;
135 while (s--) 136 while (s--)
@@ -140,18 +141,43 @@ static void writeFIFO(struct usb_endpoint *ep, unsigned int size)
140 REG32(ep->fifo_addr) = 0; 141 REG32(ep->fifo_addr) = 0;
141} 142}
142 143
144static void flushFIFO(struct usb_endpoint *ep)
145{
146 //logf("flushFIFO(%d)", EP_NUMBER(ep));
147
148 switch (ep->type)
149 {
150 case ep_control:
151 break;
152
153 case ep_bulk:
154 case ep_interrupt:
155 if(EP_IS_IN(ep))
156 REG_USB_REG_INCSR |= USB_INCSR_FF;
157 else
158 REG_USB_REG_OUTCSR |= USB_OUTCSR_FF;
159 break;
160 }
161}
162
143static void EP0_send(void) 163static void EP0_send(void)
144{ 164{
145 register struct usb_endpoint* ep = &endpoints[1]; 165 register struct usb_endpoint* ep = &endpoints[1];
146 register unsigned int length; 166 register unsigned int length;
147 167
168 if(ep->length == 0)
169 {
170 select_endpoint(0);
171 REG_USB_REG_CSR0 |= (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND);
172 return;
173 }
174
148 if(ep->sent == 0) 175 if(ep->sent == 0)
149 length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); 176 length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size);
150 else 177 else
151 length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size); 178 length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size);
152 179
153 select_endpoint(0); 180 select_endpoint(0);
154
155 writeFIFO(ep, length); 181 writeFIFO(ep, length);
156 ep->sent += length; 182 ep->sent += length;
157 183
@@ -166,6 +192,7 @@ static void EP0_send(void)
166 192
167static void EP0_handler(void) 193static void EP0_handler(void)
168{ 194{
195logf("EP0_handler");
169 register unsigned char csr0; 196 register unsigned char csr0;
170 197
171 /* Read CSR0 */ 198 /* Read CSR0 */
@@ -208,46 +235,127 @@ static void EP0_handler(void)
208 EP0_send(); 235 EP0_send();
209} 236}
210 237
238static void EPIN_handler(unsigned int endpoint)
239{
240logf("EPIN_handler(%d)", endpoint);
241 struct usb_endpoint* ep = &endpoints[endpoint*2+1];
242 unsigned int length, csr;
243
244 select_endpoint(endpoint);
245 csr = REG_USB_REG_INCSR;
246
247 if(ep->length == 0)
248 {
249 REG_USB_REG_INCSR = csr | USB_INCSR_INPKTRDY;
250 return;
251 }
252
253 if(csr & USB_INCSR_SENTSTALL)
254 {
255 REG_USB_REG_INCSR = csr & ~USB_INCSR_SENTSTALL;
256 return;
257 }
258
259 if(ep->sent == 0)
260 length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size);
261 else
262 length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size);
263
264 writeFIFO(ep, length);
265 ep->sent += length;
266
267 REG_USB_REG_INCSR = csr | USB_INCSR_INPKTRDY;
268 if(ep->sent >= ep->length)
269 usb_core_transfer_complete(endpoint|USB_DIR_IN, USB_DIR_IN, 0, ep->sent);
270}
271
272static void EPOUT_handler(unsigned int endpoint)
273{
274logf("EPOUT_handler(%d)", endpoint);
275 struct usb_endpoint* ep = &endpoints[endpoint*2];
276 unsigned int size, csr;
277
278 select_endpoint(endpoint);
279 csr = REG_USB_REG_OUTCSR;
280
281 if(ep->buf == NULL && ep->length == 0)
282 {
283 REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY;
284 return;
285 }
286
287 if(csr & USB_OUTCSR_SENTSTALL)
288 {
289 REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL;
290 return;
291 }
292
293 size = REG_USB_REG_OUTCOUNT;
294 ep->received += size;
295
296 readFIFO(ep, size);
297
298 REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY;
299
300 logf("received: %d length: %d", ep->received, ep->length);
301
302 //if(ep->received >= ep->length)
303 usb_core_transfer_complete(endpoint|USB_DIR_OUT, USB_DIR_OUT, 0, ep->received);
304}
305
211static void setup_endpoint(struct usb_endpoint *ep) 306static void setup_endpoint(struct usb_endpoint *ep)
212{ 307{
308 int csr;
213 ep->sent = 0; 309 ep->sent = 0;
214 ep->length = 0; 310 ep->length = 0;
215 311
312 select_endpoint(EP_NUMBER2(ep));
313
314 if(ep->type == ep_bulk)
315 {
316 if(REG_USB_REG_POWER & USB_POWER_HSMODE)
317 ep->fifo_size = 512;
318 else
319 ep->fifo_size = 64;
320 }
321
216 if(EP_IS_IN(ep)) 322 if(EP_IS_IN(ep))
217 { 323 {
218 if(ep->type == ep_bulk) 324 REG_USB_REG_INMAXP = ep->fifo_size;
219 { 325 csr = (USB_INCSR_FF | USB_INCSR_CDT | USB_INCSRH_MODE);
220 register int size; 326 if(ep->use_dma)
221 327 csr |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET);
222 if((REG_USB_REG_POWER & USB_POWER_HSMODE) == 0)
223 size = 64;
224 else
225 size = 512;
226
227 REG_USB_REG_INMAXP = size;
228 ep->fifo_size = size;
229 }
230 else 328 else
231 REG_USB_REG_INMAXP = ep->fifo_size; 329 REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep));
232 330
233 REG_USB_REG_INCSR = (USB_INCSR_FF | USB_INCSR_CDT | USB_INCSRH_MODE); 331 REG_USB_REG_INCSR = csr;
234 REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER(ep));
235 } 332 }
236 else 333 else
237 { 334 {
238 REG_USB_REG_OUTMAXP = ep->fifo_size; 335 REG_USB_REG_OUTMAXP = ep->fifo_size;
239 REG_USB_REG_OUTCSR = (USB_OUTCSR_FF | USB_OUTCSR_CDT); 336 csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT);
240 REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER(ep)); 337
338 if(ep->type == ep_interrupt)
339 csr |= USB_OUTCSRH_DNYT;
340
341 if(ep->use_dma)
342 csr |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE);
343 else
344 REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep));
345
346 csr = REG_USB_REG_OUTCSR;
241 } 347 }
348
349 //flushFIFO(ep);
242} 350}
243 351
244static void udc_reset(void) 352static void udc_reset(void)
245{ 353{
246 logf("udc_reset"); 354 logf("udc_reset()");
247 355
248 register unsigned int i; 356 register unsigned int i;
249 357
250 /* data init */ 358 /* EP0 init */
251 ep0state = USB_EP0_IDLE; 359 ep0state = USB_EP0_IDLE;
252 360
253 /* Disable interrupts */ 361 /* Disable interrupts */
@@ -261,19 +369,20 @@ static void udc_reset(void)
261 369
262 /* Reset address */ 370 /* Reset address */
263 REG_USB_REG_FADDR = 0; 371 REG_USB_REG_FADDR = 0;
264 //REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB); /* High speed and softconnect */ 372
373 /* High speed and softconnect */
374 //REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB);
265 REG_USB_REG_POWER = USB_POWER_SOFTCONN; 375 REG_USB_REG_POWER = USB_POWER_SOFTCONN;
376
266 /* Enable SUSPEND */ 377 /* Enable SUSPEND */
267 /* REG_USB_REG_POWER |= USB_POWER_SUSPENDM; */ 378 /* REG_USB_REG_POWER |= USB_POWER_SUSPENDM; */
268 379
380 /* Reset EP0 */
269 select_endpoint(0); 381 select_endpoint(0);
270 REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND); 382 REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND);
271 383
272 for(i=2; i<TOTAL_EP(); i++) /* Skip EP0 */ 384 for(i=2; i<TOTAL_EP(); i++) /* Skip EP0 */
273 {
274 select_endpoint(i);
275 setup_endpoint(&endpoints[i]); 385 setup_endpoint(&endpoints[i]);
276 }
277 386
278 /* Enable interrupts */ 387 /* Enable interrupts */
279 REG_USB_REG_INTRINE |= USB_INTR_EP0; 388 REG_USB_REG_INTRINE |= USB_INTR_EP0;
@@ -297,19 +406,31 @@ void UDC(void)
297 /* EPIN & EPOUT are all handled in DMA */ 406 /* EPIN & EPOUT are all handled in DMA */
298 if(intrIn & USB_INTR_EP0) 407 if(intrIn & USB_INTR_EP0)
299 EP0_handler(); 408 EP0_handler();
409 if(intrIn & USB_INTR_INEP1)
410 EPIN_handler(1);
411 if(intrIn & USB_INTR_INEP2)
412 EPIN_handler(2);
413 if(intrOut & USB_INTR_OUTEP1)
414 EPOUT_handler(1);
415 if(intrOut & USB_INTR_OUTEP2)
416 EPOUT_handler(2);
300 if(intrUSB & USB_INTR_RESET) 417 if(intrUSB & USB_INTR_RESET)
301 udc_reset(); 418 udc_reset();
302 if(intrUSB & USB_INTR_SUSPEND); 419 //if(intrUSB & USB_INTR_SUSPEND);
303 if(intrUSB & USB_INTR_RESUME); 420 //if(intrUSB & USB_INTR_RESUME);
304 if(intrDMA & USB_INTR_DMA_BULKIN) 421 if(intrDMA & USB_INTR_DMA_BULKIN)
305 { 422 {
306 logf("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF)); 423 logf("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF));
307 usb_core_transfer_complete(((REG_USB_REG_CNTL1 >> 4) & 0xF) | USB_DIR_IN, USB_DIR_IN, 0, 0); 424 usb_core_transfer_complete(1 | USB_DIR_IN, USB_DIR_IN, 0, 0);
308 } 425 }
309 if(intrDMA & USB_INTR_DMA_BULKOUT) 426 if(intrDMA & USB_INTR_DMA_BULKOUT)
310 { 427 {
311 logf("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF)); 428 logf("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF));
312 usb_core_transfer_complete(((REG_USB_REG_CNTL2 >> 4) & 0xF) | USB_DIR_OUT, USB_DIR_OUT, 0, 0); 429
430 select_endpoint(1);
431 REG_USB_REG_OUTCSR &= ~(USB_OUTCSRH_DMAREQENAB | USB_OUTCSR_OUTPKTRDY);
432
433 usb_core_transfer_complete(1 | USB_DIR_OUT, USB_DIR_OUT, 0, 0);
313 } 434 }
314} 435}
315 436
@@ -317,7 +438,7 @@ bool usb_drv_stalled(int endpoint, bool in)
317{ 438{
318 logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT"); 439 logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT");
319 440
320 select_endpoint(endpoint); 441 select_endpoint(endpoint & 0x7F);
321 442
322 if(endpoint == 0) 443 if(endpoint == 0)
323 return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; 444 return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0;
@@ -332,7 +453,7 @@ bool usb_drv_stalled(int endpoint, bool in)
332 453
333void usb_drv_stall(int endpoint, bool stall, bool in) 454void usb_drv_stall(int endpoint, bool stall, bool in)
334{ 455{
335 logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"y":"n", in?"IN":"OUT"); 456 logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"Y":"N", in?"IN":"OUT");
336 457
337 select_endpoint(endpoint); 458 select_endpoint(endpoint);
338 459
@@ -350,14 +471,14 @@ void usb_drv_stall(int endpoint, bool stall, bool in)
350 if(stall) 471 if(stall)
351 REG_USB_REG_INCSR |= USB_INCSR_SENDSTALL; 472 REG_USB_REG_INCSR |= USB_INCSR_SENDSTALL;
352 else 473 else
353 REG_USB_REG_INCSR &= ~USB_INCSR_SENDSTALL; 474 REG_USB_REG_INCSR = (REG_USB_REG_INCSR & ~USB_INCSR_SENDSTALL) | USB_INCSR_CDT;
354 } 475 }
355 else 476 else
356 { 477 {
357 if(stall) 478 if(stall)
358 REG_USB_REG_OUTCSR |= USB_OUTCSR_SENDSTALL; 479 REG_USB_REG_OUTCSR |= USB_OUTCSR_SENDSTALL;
359 else 480 else
360 REG_USB_REG_OUTCSR &= ~USB_OUTCSR_SENDSTALL; 481 REG_USB_REG_OUTCSR = (REG_USB_REG_OUTCSR & ~USB_OUTCSR_SENDSTALL) | USB_OUTCSR_CDT;
361 } 482 }
362 } 483 }
363} 484}
@@ -388,12 +509,13 @@ void usb_enable(bool on)
388 509
389void usb_drv_init(void) 510void usb_drv_init(void)
390{ 511{
512 logf("usb_drv_init()");
513
391 /* Set this bit to allow the UDC entering low-power mode when 514 /* Set this bit to allow the UDC entering low-power mode when
392 * there are no actions on the USB bus. 515 * there are no actions on the USB bus.
393 * UDC still works during this bit was set. 516 * UDC still works during this bit was set.
394 */ 517 */
395 //__cpm_stop_udc(); 518 //__cpm_stop_udc();
396
397 __cpm_start_udc(); 519 __cpm_start_udc();
398 520
399 /* Enable the USB PHY */ 521 /* Enable the USB PHY */
@@ -404,6 +526,8 @@ void usb_drv_init(void)
404 526
405void usb_drv_exit(void) 527void usb_drv_exit(void)
406{ 528{
529 logf("usb_drv_exit()");
530
407 /* Disable interrupts */ 531 /* Disable interrupts */
408 REG_USB_REG_INTRINE = 0; 532 REG_USB_REG_INTRINE = 0;
409 REG_USB_REG_INTROUTE = 0; 533 REG_USB_REG_INTROUTE = 0;
@@ -413,7 +537,7 @@ void usb_drv_exit(void)
413 REG_USB_REG_CNTL1 = 0; 537 REG_USB_REG_CNTL1 = 0;
414 REG_USB_REG_CNTL2 = 0; 538 REG_USB_REG_CNTL2 = 0;
415 539
416 /* Disconnect from usb */ 540 /* Disconnect from USB */
417 REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; 541 REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN;
418 542
419 /* Disable the USB PHY */ 543 /* Disable the USB PHY */
@@ -431,32 +555,71 @@ void usb_drv_set_address(int address)
431 555
432int usb_drv_send(int endpoint, void* ptr, int length) 556int usb_drv_send(int endpoint, void* ptr, int length)
433{ 557{
434 logf("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length); 558 int flags;
435 559 endpoint &= 0x7F;
436 if(endpoint == EP_CONTROL && ptr == NULL && length == 0) /* ACK request */
437 return 0;
438 560
561 logf("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length);
562
439 if(endpoint == EP_CONTROL) 563 if(endpoint == EP_CONTROL)
440 { 564 {
565 flags = disable_irq_save();
441 endpoints[1].buf = ptr; 566 endpoints[1].buf = ptr;
442 endpoints[1].sent = 0; 567 endpoints[1].sent = 0;
443 endpoints[1].length = length; 568 endpoints[1].length = length;
444 ep0state = USB_EP0_TX; 569 ep0state = USB_EP0_TX;
445 EP0_send(); 570 EP0_send();
571
572 restore_irq(flags);
446 return 0; 573 return 0;
447 } 574 }
448 else 575 else if(endpoint == 1)
576 {
577#if 0
578 select_endpoint(endpoint);
579
580 REG_USB_REG_ADDR2 = ((unsigned long)ptr) & 0x7fffffff;
581 REG_USB_REG_COUNT2 = length;
582 REG_USB_REG_CNTL2 = 1;
583#else
584 flags = disable_irq_save();
585 endpoints[3].buf = ptr;
586 endpoints[3].sent = 0;
587 endpoints[3].length = length;
588 EPIN_handler(1);
589 restore_irq(flags);
590#endif
449 return 0; 591 return 0;
592 }
593 else
594 return -1;
595}
596
597int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
598{
599 return usb_drv_send(endpoint, ptr, length);
450} 600}
451 601
452int usb_drv_recv(int endpoint, void* ptr, int length) 602int usb_drv_recv(int endpoint, void* ptr, int length)
453{ 603{
604 int flags;
605 endpoint &= 0x7F;
606
454 logf("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length); 607 logf("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length);
455 608
456 if(endpoint == EP_CONTROL && ptr == NULL && length == 0) /* ACK request */ 609 if(endpoint == EP_CONTROL && ptr == NULL && length == 0)
610 return 0; /* ACK request, handled by the USB controller */
611 else if(endpoint == 1)
612 {
613 logf("EP1 handled: %d", length);
614 flags = disable_irq_save();
615 endpoints[2].buf = ptr;
616 endpoints[2].received = 0;
617 endpoints[2].length = length;
618 restore_irq(flags);
457 return 0; 619 return 0;
458 620 }
459 return -1; 621 else
622 return -1;
460} 623}
461 624
462void usb_drv_set_test_mode(int mode) 625void usb_drv_set_test_mode(int mode)
@@ -492,13 +655,18 @@ void usb_drv_cancel_all_transfers(void)
492{ 655{
493 logf("usb_drv_cancel_all_transfers()"); 656 logf("usb_drv_cancel_all_transfers()");
494 657
495 unsigned int i; 658 unsigned int i, flags;
659 flags = disable_irq_save();
660
496 for(i=0; i<TOTAL_EP(); i++) 661 for(i=0; i<TOTAL_EP(); i++)
497 { 662 {
498 endpoints[i].sent = 0; 663 endpoints[i].sent = 0;
499 endpoints[i].length = 0; 664 endpoints[i].length = 0;
500 /* TODO: flush FIFO's ? */ 665
666 select_endpoint(i/2);
667 flushFIFO(&endpoints[i]);
501 } 668 }
669 restore_irq(flags);
502 670
503 ep0state = USB_EP0_IDLE; 671 ep0state = USB_EP0_IDLE;
504} 672}
@@ -512,8 +680,14 @@ void usb_drv_release_endpoint(int ep)
512 680
513int usb_drv_request_endpoint(int dir) 681int usb_drv_request_endpoint(int dir)
514{ 682{
515 logf("usb_drv_request_endpoint(%d)", dir); 683 logf("usb_drv_request_endpoint(%s)", dir == USB_DIR_IN ? "IN" : "OUT");
516 684
517 (void)dir; 685 /* There are only 3+2 endpoints, so hardcode this ... */
518 return -1; 686 /* Currently only BULK endpoints ... */
687 if(dir == USB_DIR_OUT)
688 return (1 | USB_DIR_OUT);
689 else if(dir == USB_DIR_IN)
690 return (1 | USB_DIR_IN);
691 else
692 return -1;
519} 693}