summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2008-12-04 18:26:19 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2008-12-04 18:26:19 +0000
commita119c44c7ec7a383dafbb391f052aaade0b6c981 (patch)
tree166f1ebc5dad5c132adeca9376ad323023f55a28
parentb2dd3c210e909baec303a94463dc5517acc2780a (diff)
downloadrockbox-a119c44c7ec7a383dafbb391f052aaade0b6c981.tar.gz
rockbox-a119c44c7ec7a383dafbb391f052aaade0b6c981.zip
Ingenic targets:
* Clean up codec & PCM + functional changes * LCD: Don't wait on DMAC in lcd_unlock() * SADC: add battery mutex + other changes * NAND: add mutex * USB rework (still not working) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19327 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/jz4740.h32
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c12
-rw-r--r--firmware/target/mips/ingenic_jz47xx/codec-jz4740.c60
-rw-r--r--firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c32
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c55
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h20
-rw-r--r--firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c47
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h3
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4740.c1267
10 files changed, 354 insertions, 1176 deletions
diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h
index 55c0ac7b1d..505248a67a 100644
--- a/firmware/export/jz4740.h
+++ b/firmware/export/jz4740.h
@@ -2339,6 +2339,7 @@
2339#define USB_REG_TESTMODE (USB_BASE + 0x0f) /* USB test mode 8-bit */ 2339#define USB_REG_TESTMODE (USB_BASE + 0x0f) /* USB test mode 8-bit */
2340 2340
2341#define USB_REG_CSR0 (USB_BASE + 0x12) /* EP0 CSR 8-bit */ 2341#define USB_REG_CSR0 (USB_BASE + 0x12) /* EP0 CSR 8-bit */
2342#define USB_REG_COUNT0 (USB_BASE + 0x18) /* bytes in EP0 FIFO 16-bit */
2342#define USB_REG_INMAXP (USB_BASE + 0x10) /* EP1-2 IN Max Pkt Size 16-bit */ 2343#define USB_REG_INMAXP (USB_BASE + 0x10) /* EP1-2 IN Max Pkt Size 16-bit */
2343#define USB_REG_INCSR (USB_BASE + 0x12) /* EP1-2 IN CSR LSB 8/16bit */ 2344#define USB_REG_INCSR (USB_BASE + 0x12) /* EP1-2 IN CSR LSB 8/16bit */
2344#define USB_REG_INCSRH (USB_BASE + 0x13) /* EP1-2 IN CSR MSB 8-bit */ 2345#define USB_REG_INCSRH (USB_BASE + 0x13) /* EP1-2 IN CSR MSB 8-bit */
@@ -2375,6 +2376,7 @@
2375#define REG_USB_REG_TESTMODE REG8(USB_REG_TESTMODE) 2376#define REG_USB_REG_TESTMODE REG8(USB_REG_TESTMODE)
2376 2377
2377#define REG_USB_REG_CSR0 REG8(USB_REG_CSR0) 2378#define REG_USB_REG_CSR0 REG8(USB_REG_CSR0)
2379#define REG_USB_REG_COUNT0 REG16(USB_REG_COUNT0)
2378#define REG_USB_REG_INMAXP REG16(USB_REG_INMAXP) 2380#define REG_USB_REG_INMAXP REG16(USB_REG_INMAXP)
2379#define REG_USB_REG_INCSR REG16(USB_REG_INCSR) 2381#define REG_USB_REG_INCSR REG16(USB_REG_INCSR)
2380#define REG_USB_REG_INCSRH REG8(USB_REG_INCSRH) 2382#define REG_USB_REG_INCSRH REG8(USB_REG_INCSRH)
@@ -2395,6 +2397,9 @@
2395#define REG_USB_REG_ADDR2 REG32(USB_REG_ADDR2) 2397#define REG_USB_REG_ADDR2 REG32(USB_REG_ADDR2)
2396#define REG_USB_REG_COUNT2 REG32(USB_REG_COUNT2) 2398#define REG_USB_REG_COUNT2 REG32(USB_REG_COUNT2)
2397 2399
2400#define REG_USB_REG_EPINFO REG16(USB_REG_EPINFO)
2401#define REG_USB_REG_RAMINFO REG8(USB_REG_RAMINFO)
2402
2398 2403
2399/* Power register bit masks */ 2404/* Power register bit masks */
2400#define USB_POWER_SUSPENDM 0x01 2405#define USB_POWER_SUSPENDM 0x01
@@ -2414,6 +2419,8 @@
2414#define USB_INTR_OUTEP1 0x0002 2419#define USB_INTR_OUTEP1 0x0002
2415#define USB_INTR_OUTEP2 0x0004 2420#define USB_INTR_OUTEP2 0x0004
2416 2421
2422#define USB_INTR_EP(n) (n*2)
2423
2417/* CSR0 bit masks */ 2424/* CSR0 bit masks */
2418#define USB_CSR0_OUTPKTRDY 0x01 2425#define USB_CSR0_OUTPKTRDY 0x01
2419#define USB_CSR0_INPKTRDY 0x02 2426#define USB_CSR0_INPKTRDY 0x02
@@ -2425,11 +2432,11 @@
2425#define USB_CSR0_SVDSETUPEND 0x80 2432#define USB_CSR0_SVDSETUPEND 0x80
2426 2433
2427/* Endpoint CSR register bits */ 2434/* Endpoint CSR register bits */
2428#define USB_INCSRH_AUTOSET 0x80 2435#define USB_INCSRH_AUTOSET 0x8000
2429#define USB_INCSRH_ISO 0x40 2436#define USB_INCSRH_ISO 0x4000
2430#define USB_INCSRH_MODE 0x20 2437#define USB_INCSRH_MODE 0x2000
2431#define USB_INCSRH_DMAREQENAB 0x10 2438#define USB_INCSRH_DMAREQENAB 0x1000
2432#define USB_INCSRH_DMAREQMODE 0x04 2439#define USB_INCSRH_DMAREQMODE 0x0400
2433#define USB_INCSR_CDT 0x40 2440#define USB_INCSR_CDT 0x40
2434#define USB_INCSR_SENTSTALL 0x20 2441#define USB_INCSR_SENTSTALL 0x20
2435#define USB_INCSR_SENDSTALL 0x10 2442#define USB_INCSR_SENDSTALL 0x10
@@ -2437,11 +2444,11 @@
2437#define USB_INCSR_UNDERRUN 0x04 2444#define USB_INCSR_UNDERRUN 0x04
2438#define USB_INCSR_FFNOTEMPT 0x02 2445#define USB_INCSR_FFNOTEMPT 0x02
2439#define USB_INCSR_INPKTRDY 0x01 2446#define USB_INCSR_INPKTRDY 0x01
2440#define USB_OUTCSRH_AUTOCLR 0x80 2447#define USB_OUTCSRH_AUTOCLR 0x8000
2441#define USB_OUTCSRH_ISO 0x40 2448#define USB_OUTCSRH_ISO 0x4000
2442#define USB_OUTCSRH_DMAREQENAB 0x20 2449#define USB_OUTCSRH_DMAREQENAB 0x2000
2443#define USB_OUTCSRH_DNYT 0x10 2450#define USB_OUTCSRH_DNYT 0x1000
2444#define USB_OUTCSRH_DMAREQMODE 0x08 2451#define USB_OUTCSRH_DMAREQMODE 0x0800
2445#define USB_OUTCSR_CDT 0x80 2452#define USB_OUTCSR_CDT 0x80
2446#define USB_OUTCSR_SENTSTALL 0x40 2453#define USB_OUTCSR_SENTSTALL 0x40
2447#define USB_OUTCSR_SENDSTALL 0x20 2454#define USB_OUTCSR_SENDSTALL 0x20
@@ -2456,6 +2463,11 @@
2456#define USB_TEST_J 0x02 2463#define USB_TEST_J 0x02
2457#define USB_TEST_K 0x04 2464#define USB_TEST_K 0x04
2458#define USB_TEST_PACKET 0x08 2465#define USB_TEST_PACKET 0x08
2466#define USB_TEST_FORCE_HS 0x10
2467#define USB_TEST_FORCE_FS 0x20
2468#define USB_TEST_ALL ( USB_TEST_SE0NAK | USB_TEST_J \
2469 | USB_TEST_K | USB_TEST_PACKET \
2470 | USB_TEST_FORCE_HS | USB_TEST_FORCE_FS)
2459 2471
2460/* DMA control bits */ 2472/* DMA control bits */
2461#define USB_CNTL_ENA 0x01 2473#define USB_CNTL_ENA 0x01
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
index 7a937bf7cf..979a9067d3 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
@@ -26,6 +26,7 @@
26#include "nand_id.h" 26#include "nand_id.h"
27#include "system.h" 27#include "system.h"
28#include "panic.h" 28#include "panic.h"
29#include "kernel.h"
29 30
30/* 31/*
31 * Standard NAND flash commands 32 * Standard NAND flash commands
@@ -104,6 +105,7 @@ struct nand_param
104 105
105static struct nand_info* chip_info = NULL; 106static struct nand_info* chip_info = NULL;
106static struct nand_param internal_param; 107static struct nand_param internal_param;
108static struct mutex nand_mtx;
107 109
108static inline void jz_nand_wait_ready(void) 110static inline void jz_nand_wait_ready(void)
109{ 111{
@@ -132,6 +134,8 @@ static inline void jz_nand_read_buf8(void *buf, int count)
132 134
133static void jz_nand_write_dma(void *source, unsigned int len, int bw) 135static void jz_nand_write_dma(void *source, unsigned int len, int bw)
134{ 136{
137 mutex_lock(&nand_mtx);
138
135 if(((unsigned int)source < 0xa0000000) && len) 139 if(((unsigned int)source < 0xa0000000) && len)
136 dma_cache_wback_inv((unsigned long)source, len); 140 dma_cache_wback_inv((unsigned long)source, len);
137 141
@@ -146,10 +150,14 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
146 REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = (DMAC_DCCSR_EN | DMAC_DCCSR_NDES); 150 REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = (DMAC_DCCSR_EN | DMAC_DCCSR_NDES);
147 while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) ) 151 while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
148 yield(); 152 yield();
153
154 mutex_unlock(&nand_mtx);
149} 155}
150 156
151static void jz_nand_read_dma(void *target, unsigned int len, int bw) 157static void jz_nand_read_dma(void *target, unsigned int len, int bw)
152{ 158{
159 mutex_lock(&nand_mtx);
160
153 if(((unsigned int)target < 0xa0000000) && len) 161 if(((unsigned int)target < 0xa0000000) && len)
154 dma_cache_wback_inv((unsigned long)target, len); 162 dma_cache_wback_inv((unsigned long)target, len);
155 163
@@ -163,6 +171,8 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
163 REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = (DMAC_DCCSR_EN | DMAC_DCCSR_NDES); 171 REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = (DMAC_DCCSR_EN | DMAC_DCCSR_NDES);
164 while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) ) 172 while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
165 yield(); 173 yield();
174
175 mutex_unlock(&nand_mtx);
166} 176}
167 177
168static inline void jz_nand_read_buf(void *buf, int count, int bw) 178static inline void jz_nand_read_buf(void *buf, int count, int bw)
@@ -433,6 +443,8 @@ static int jz_nand_init(void)
433 internal_param.oob_size = chip_info->page_size/32; 443 internal_param.oob_size = chip_info->page_size/32;
434 internal_param.page_per_block = chip_info->pages_per_block; 444 internal_param.page_per_block = chip_info->pages_per_block;
435 445
446 mutex_init(&nand_mtx);
447
436 return 0; 448 return 0;
437} 449}
438 450
diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
index 6c3ed8cf2a..dec343a0da 100644
--- a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
@@ -21,6 +21,7 @@
21 21
22#include "config.h" 22#include "config.h"
23#include "jz4740.h" 23#include "jz4740.h"
24#include "system.h"
24 25
25static unsigned short codec_volume; 26static unsigned short codec_volume;
26static unsigned short codec_base_gain; 27static unsigned short codec_base_gain;
@@ -29,6 +30,8 @@ static bool HP_on_off_flag;
29static int HP_register_value; 30static int HP_register_value;
30static int IS_WRITE_PCM; 31static int IS_WRITE_PCM;
31 32
33static void i2s_codec_set_samplerate(unsigned short rate);
34
32static void i2s_codec_clear(void) 35static void i2s_codec_clear(void)
33{ 36{
34 REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL | 37 REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL |
@@ -38,11 +41,11 @@ static void i2s_codec_clear(void)
38 41
39static void i2s_codec_init(void) 42static void i2s_codec_init(void)
40{ 43{
44 __aic_enable();
45
41 __aic_select_i2s(); 46 __aic_select_i2s();
42 __i2s_internal_codec(); 47 __i2s_internal_codec();
43 48
44 __aic_enable();
45
46 __i2s_set_oss_sample_size(16); 49 __i2s_set_oss_sample_size(16);
47 50
48 REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL | 51 REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL |
@@ -55,14 +58,32 @@ static void i2s_codec_init(void)
55 //REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(ICDC_CDCCR2_AINVOL_DB(0)) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) | 58 //REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(ICDC_CDCCR2_AINVOL_DB(0)) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) |
56 REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) | 59 REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) |
57 ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_6)); 60 ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_6));
61
62 REG_ICDC_CDCCR1 &= 0xfffffffc;
63
64 mdelay(15);
65 REG_ICDC_CDCCR1 &= 0xffecffff;
66 REG_ICDC_CDCCR1 |= (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_HPCG);
67
68 mdelay(600);
69 REG_ICDC_CDCCR1 &= 0xfff7ecff;
70
71 mdelay(2);
72
73 /* CDCCR1.ELININ=0, CDCCR1.EMIC=0, CDCCR1.EADC=0, CDCCR1.SW1ON=0, CDCCR1.EDAC=1, CDCCR1.SW2ON=1, CDCCR1.HPMUTE=0 */
74 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~((1 << 29) | (1 << 28) | (1 << 26) | (1 << 27) | (1 << 14))) | ((1 << 24) | (1 << 25));
75
76 REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x3)) | 3);
77
78 i2s_codec_set_samplerate(44100);
79
58 HP_on_off_flag = 0; /* HP is off */ 80 HP_on_off_flag = 0; /* HP is off */
59} 81}
60 82
61static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */ 83static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */
62{ 84{
63 v = v & 0xff; 85 v &= 0xff;
64 if(v < 0) 86
65 v = 0;
66 if(v > 100) 87 if(v > 100)
67 v = 100; 88 v = 100;
68 codec_mic_gain = 31 * v/100; 89 codec_mic_gain = 31 * v/100;
@@ -72,9 +93,8 @@ static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */
72 93
73static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */ 94static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */
74{ 95{
75 v = v & 0xff; 96 v &= 0xff;
76 if(v < 0) 97
77 v = 0;
78 if(v > 100) 98 if(v > 100)
79 v = 100; 99 v = 100;
80 100
@@ -92,9 +112,8 @@ static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */
92 112
93static void i2s_codec_set_volume(unsigned short v) /* 0 <= v <= 100 */ 113static void i2s_codec_set_volume(unsigned short v) /* 0 <= v <= 100 */
94{ 114{
95 v = v & 0xff; 115 v &= 0xff;
96 if(v < 0) 116
97 v = 0;
98 if(v > 100) 117 if(v > 100)
99 v = 100; 118 v = 100;
100 119
@@ -114,6 +133,7 @@ static unsigned short i2s_codec_get_bass(void)
114{ 133{
115 unsigned short val; 134 unsigned short val;
116 int ret; 135 int ret;
136
117 if(codec_base_gain == 0) 137 if(codec_base_gain == 0)
118 val = 0; 138 val = 0;
119 if(codec_base_gain == 1) 139 if(codec_base_gain == 1)
@@ -124,7 +144,9 @@ static unsigned short i2s_codec_get_bass(void)
124 val = 75; 144 val = 75;
125 145
126 ret = val << 8; 146 ret = val << 8;
127 val = val | ret; 147 val |= ret;
148
149 return val;
128} 150}
129 151
130static unsigned short i2s_codec_get_mic(void) 152static unsigned short i2s_codec_get_mic(void)
@@ -133,7 +155,9 @@ static unsigned short i2s_codec_get_mic(void)
133 int ret; 155 int ret;
134 val = 100 * codec_mic_gain / 31; 156 val = 100 * codec_mic_gain / 31;
135 ret = val << 8; 157 ret = val << 8;
136 val = val | ret; 158 val |= ret;
159
160 return val;
137} 161}
138 162
139static unsigned short i2s_codec_get_volume(void) 163static unsigned short i2s_codec_get_volume(void)
@@ -151,7 +175,8 @@ static unsigned short i2s_codec_get_volume(void)
151 val = 75; 175 val = 75;
152 176
153 ret = val << 8; 177 ret = val << 8;
154 val = val | ret; 178 val |= ret;
179
155 return val; 180 return val;
156} 181}
157 182
@@ -271,10 +296,15 @@ void audiohw_mute(bool mute)
271 296
272void audiohw_preinit(void) 297void audiohw_preinit(void)
273{ 298{
274 i2s_reset(); 299 i2s_codec_init();
275} 300}
276 301
277void audiohw_postinit(void) 302void audiohw_postinit(void)
278{ 303{
279 audiohw_mute(false); 304 audiohw_mute(false);
280} 305}
306
307void audiohw_init(void)
308{
309
310}
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
index f45ffc0349..1401bf8a3f 100644
--- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
@@ -26,15 +26,14 @@
26#include "system.h" 26#include "system.h"
27#include "kernel.h" 27#include "kernel.h"
28 28
29static volatile bool _lcd_on = false; 29static volatile bool lcd_is_on = false;
30static volatile bool lcd_poweroff = false;
31static struct mutex lcd_mtx; 30static struct mutex lcd_mtx;
32 31
33/* LCD init */ 32/* LCD init */
34void lcd_init_device(void) 33void lcd_init_device(void)
35{ 34{
36 lcd_init_controller(); 35 lcd_init_controller();
37 _lcd_on = true; 36 lcd_is_on = true;
38 mutex_init(&lcd_mtx); 37 mutex_init(&lcd_mtx);
39} 38}
40 39
@@ -48,16 +47,16 @@ void lcd_enable(bool state)
48 else 47 else
49 lcd_off(); 48 lcd_off();
50 49
51 _lcd_on = state; 50 lcd_is_on = state;
52} 51}
53 52
54bool lcd_enabled(void) 53bool lcd_enabled(void)
55{ 54{
56 return _lcd_on; 55 return lcd_is_on;
57} 56}
58 57
59/* Don't switch threads when in interrupt mode! */ 58/* Don't switch threads when in interrupt mode! */
60static void lcd_lock(void) 59static inline void lcd_lock(void)
61{ 60{
62 if(LIKELY(!in_interrupt_mode())) 61 if(LIKELY(!in_interrupt_mode()))
63 mutex_lock(&lcd_mtx); 62 mutex_lock(&lcd_mtx);
@@ -65,10 +64,19 @@ static void lcd_lock(void)
65 while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT)); 64 while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
66} 65}
67 66
68static void lcd_unlock(void) 67static inline void lcd_unlock(void)
69{ 68{
70 if(LIKELY(!in_interrupt_mode())) 69 if(LIKELY(!in_interrupt_mode()))
71 mutex_unlock(&lcd_mtx); 70 mutex_unlock(&lcd_mtx);
71}
72
73static inline void lcd_wait(void)
74{
75 if(LIKELY(!in_interrupt_mode()))
76 {
77 while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT) )
78 yield();
79 }
72 else 80 else
73 while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT)); 81 while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
74} 82}
@@ -98,13 +106,7 @@ void lcd_update_rect(int x, int y, int width, int height)
98 REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN; 106 REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN;
99 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; 107 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN;
100 108
101 if(LIKELY(!in_interrupt_mode())) 109 lcd_wait();
102 {
103 while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT) )
104 yield();
105 }
106 else
107 while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
108 110
109 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; 111 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN;
110 112
@@ -119,7 +121,7 @@ void lcd_update_rect(int x, int y, int width, int height)
119 This must be called after all other LCD functions that change the display. */ 121 This must be called after all other LCD functions that change the display. */
120void lcd_update(void) 122void lcd_update(void)
121{ 123{
122 if (!_lcd_on) 124 if (!lcd_is_on)
123 return; 125 return;
124 126
125 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 127 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
index 64ea86135f..2624eb3d82 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
@@ -25,6 +25,7 @@
25#include "button.h" 25#include "button.h"
26#include "button-target.h" 26#include "button-target.h"
27#include "powermgmt.h" 27#include "powermgmt.h"
28#include "kernel.h"
28 29
29#define BTN_OFF (1 << 29) 30#define BTN_OFF (1 << 29)
30#define BTN_VOL_DOWN (1 << 27) 31#define BTN_VOL_DOWN (1 << 27)
@@ -36,21 +37,22 @@
36 37
37 38
38#define TS_AD_COUNT 5 39#define TS_AD_COUNT 5
39#define M_SADC_CFG_SNUM ((TS_AD_COUNT - 1) << SADC_CFG_SNUM_BIT) 40#define SADC_CFG_SNUM ((TS_AD_COUNT - 1) << SADC_CFG_SNUM_BIT)
40 41
41#define SADC_CFG_INIT ( \ 42#define SADC_CFG_INIT ( \
42 (2 << SADC_CFG_CLKOUT_NUM_BIT) | \ 43 (2 << SADC_CFG_CLKOUT_NUM_BIT) | \
43 SADC_CFG_XYZ1Z2 | \ 44 SADC_CFG_XYZ1Z2 | \
44 M_SADC_CFG_SNUM | \ 45 SADC_CFG_SNUM | \
45 (2 << SADC_CFG_CLKDIV_BIT) | \ 46 (2 << SADC_CFG_CLKDIV_BIT) | \
46 SADC_CFG_PBAT_HIGH | \ 47 SADC_CFG_PBAT_HIGH | \
47 SADC_CFG_CMD_INT_PEN \ 48 SADC_CFG_CMD_INT_PEN \
48 ) 49 )
49 50
50static short x_pos = -1, y_pos = -1, datacount = 0; 51static signed int x_pos, y_pos;
52static int datacount = 0, cur_touch = 0;
51static bool pen_down = false; 53static bool pen_down = false;
52static int cur_touch = 0; 54static volatile unsigned short bat_val = 0;
53static unsigned short bat_val = 0; 55static struct mutex battery_mtx;
54 56
55static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; 57static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT;
56static const int touchscreen_buttons[3][3] = 58static const int touchscreen_buttons[3][3] =
@@ -93,15 +95,21 @@ const unsigned short percent_to_volt_charge[11] =
93unsigned int battery_adc_voltage(void) 95unsigned int battery_adc_voltage(void)
94{ 96{
95 register unsigned short dummy; 97 register unsigned short dummy;
98
99 mutex_lock(&battery_mtx);
100
96 dummy = REG_SADC_BATDAT; 101 dummy = REG_SADC_BATDAT;
97 dummy = REG_SADC_BATDAT; 102 dummy = REG_SADC_BATDAT;
98 103
99 bat_val = 0; 104 bat_val = 0;
100 REG_SADC_ENA |= SADC_ENA_PBATEN; 105 REG_SADC_ENA |= SADC_ENA_PBATEN;
101 106
107 /* Primitive wakeup event */
102 while(bat_val == 0) 108 while(bat_val == 0)
103 yield(); 109 yield();
104 110
111 mutex_unlock(&battery_mtx);
112
105 return (bat_val*BATTERY_SCALE_FACTOR)>>12; 113 return (bat_val*BATTERY_SCALE_FACTOR)>>12;
106} 114}
107 115
@@ -127,6 +135,8 @@ void button_init_device(void)
127 __gpio_as_input(32*3 + 16); 135 __gpio_as_input(32*3 + 16);
128 __gpio_as_input(32*3 + 1); 136 __gpio_as_input(32*3 + 1);
129 __gpio_as_input(32*3 + 0); 137 __gpio_as_input(32*3 + 0);
138
139 mutex_init(&battery_mtx);
130} 140}
131 141
132static int touch_to_pixels(short x, short y) 142static int touch_to_pixels(short x, short y)
@@ -162,6 +172,7 @@ int button_read_device(int *data)
162{ 172{
163 int ret = 0, tmp; 173 int ret = 0, tmp;
164 174
175 /* Filter button events out if HOLD button is pressed at firmware/ level */
165 if((~REG_GPIO_PXPIN(3)) & BTN_HOLD) 176 if((~REG_GPIO_PXPIN(3)) & BTN_HOLD)
166 return 0; 177 return 0;
167 178
@@ -186,7 +197,7 @@ int button_read_device(int *data)
186 else if(pen_down) 197 else if(pen_down)
187 { 198 {
188 ret |= BUTTON_TOUCH; 199 ret |= BUTTON_TOUCH;
189 if(data != NULL) 200 if(data != NULL && cur_touch != 0)
190 *data = cur_touch; 201 *data = cur_touch;
191 } 202 }
192 203
@@ -226,18 +237,16 @@ void SADC(void)
226 REG_SADC_CTRL &= (~SADC_CTRL_PENDM ); 237 REG_SADC_CTRL &= (~SADC_CTRL_PENDM );
227 REG_SADC_CTRL |= SADC_CTRL_PENUM; 238 REG_SADC_CTRL |= SADC_CTRL_PENUM;
228 pen_down = false; 239 pen_down = false;
229 x_pos = -1; 240 datacount = 0;
230 y_pos = -1;
231 cur_touch = 0; 241 cur_touch = 0;
232 } 242 }
233 if(state & SADC_CTRL_TSRDYM) 243 if(state & SADC_CTRL_TSRDYM)
234 { 244 {
235 unsigned int dat; 245 unsigned int dat;
236 unsigned short xData, yData; 246 unsigned short xData, yData;
237 short tsz1Data, tsz2Data; 247 signed short tsz1Data, tsz2Data;
238 248
239 dat = REG_SADC_TSDAT; 249 dat = REG_SADC_TSDAT;
240
241 xData = (dat >> 0) & 0xFFF; 250 xData = (dat >> 0) & 0xFFF;
242 yData = (dat >> 16) & 0xFFF; 251 yData = (dat >> 16) & 0xFFF;
243 252
@@ -245,34 +254,30 @@ void SADC(void)
245 tsz1Data = (dat >> 0) & 0xFFF; 254 tsz1Data = (dat >> 0) & 0xFFF;
246 tsz2Data = (dat >> 16) & 0xFFF; 255 tsz2Data = (dat >> 16) & 0xFFF;
247 256
248 if( !pen_down ) 257 if(!pen_down)
249 return; 258 return;
250 259
251 tsz1Data = tsz2Data - tsz1Data; 260 tsz1Data = tsz2Data - tsz1Data;
252 261
253 if((tsz1Data > 15) || (tsz1Data < -15)) 262 if((tsz1Data > 100) || (tsz1Data < -100))
254 { 263 {
255 if(x_pos == -1) 264 if(datacount == 0)
265 {
256 x_pos = xData; 266 x_pos = xData;
257 else
258 x_pos = (x_pos + xData) / 2;
259
260 if(y_pos == -1)
261 y_pos = yData; 267 y_pos = yData;
268 }
262 else 269 else
263 y_pos = (y_pos + yData) / 2; 270 {
271 x_pos += xData;
272 y_pos += yData;
273 }
264 } 274 }
265 275
266 datacount++; 276 datacount++;
267 277
268 if(datacount > TS_AD_COUNT - 1) 278 if(datacount >= TS_AD_COUNT)
269 { 279 {
270 if(x_pos != -1) 280 cur_touch = touch_to_pixels(x_pos/datacount, y_pos/datacount);
271 {
272 cur_touch = touch_to_pixels(x_pos, y_pos);
273 x_pos = -1;
274 y_pos = -1;
275 }
276 datacount = 0; 281 datacount = 0;
277 } 282 }
278 } 283 }
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h
index c681bdaa12..09b563fd14 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h
@@ -24,23 +24,19 @@
24 24
25#include "config.h" 25#include "config.h"
26 26
27#define __gpio_as_usb_detect() \
28do { \
29 REG_GPIO_PXFUNS(3) = 0x10000000; \
30 REG_GPIO_PXSELS(3) = 0x10000000; \
31 REG_GPIO_PXPES(3) = 0x10000000; \
32} while (0)
33
34#define GPIO_UDC_DETE (32 * 3 + 28) 27#define GPIO_UDC_DETE (32 * 3 + 28)
35#define IRQ_GPIO_UDC_DETE (IRQ_GPIO_0 + GPIO_UDC_DETE) 28#define IRQ_GPIO_UDC_DETE (IRQ_GPIO_0 + GPIO_UDC_DETE)
36 29
37static inline void usb_init_gpio(void) 30#define USB_INIT_GPIO() \
38{ 31{ \
39 __gpio_as_usb_detect(); 32 REG_GPIO_PXFUNS(3) = 0x10000000; \
40 system_enable_irq(IRQ_UDC); 33 REG_GPIO_PXSELS(3) = 0x10000000; \
41 __gpio_as_input(GPIO_UDC_DETE); 34 REG_GPIO_PXPES(3) = 0x10000000; \
35 __gpio_as_input(GPIO_UDC_DETE); \
42} 36}
43 37
38#define USB_DRV_CONNECTED() (__gpio_get_pin(GPIO_UDC_DETE) == 1)
39
44int usb_detect(void); 40int usb_detect(void);
45void usb_init_device(void); 41void usb_init_device(void);
46bool usb_drv_connected(void); 42bool usb_drv_connected(void);
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
index 0343723493..5549ce4dbf 100644
--- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
@@ -27,13 +27,14 @@
27#include "pcm.h" 27#include "pcm.h"
28#include "jz4740.h" 28#include "jz4740.h"
29 29
30
30/**************************************************************************** 31/****************************************************************************
31 ** Playback DMA transfer 32 ** Playback DMA transfer
32 **/ 33 **/
33 34
34void pcm_postinit(void) 35void pcm_postinit(void)
35{ 36{
36 audiohw_postinit(); /* implemented not for all codecs */ 37 audiohw_postinit();
37 pcm_apply_settings(); 38 pcm_apply_settings();
38} 39}
39 40
@@ -61,29 +62,55 @@ void pcm_set_frequency(unsigned int frequency)
61{ 62{
62 (void) frequency; 63 (void) frequency;
63 /* TODO */ 64 /* TODO */
65
66 /*
67 __i2s_set_oss_sample_size(frequency);
68 i2s_codec_set_samplerate(frequency);
69 */
64} 70}
65 71
66static void play_start_pcm(void) 72static void play_start_pcm(void)
67{ 73{
68 pcm_apply_settings(); 74 pcm_apply_settings();
69 75
70 /* TODO */ 76 __aic_enable_transmit_dma();
77 __aic_enable_replay();
78
79 REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
71} 80}
72 81
73static void play_stop_pcm(void) 82static void play_stop_pcm(void)
74{ 83{
75 /* TODO */ 84 REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) | DMAC_DCCSR_HLT) & ~DMAC_DCCSR_EN;
85
86 __aic_disable_transmit_dma();
87 __aic_disable_replay();
76} 88}
77 89
78void pcm_play_dma_start(const void *addr, size_t size) 90void pcm_play_dma_start(const void *addr, size_t size)
79{ 91{
80 (void)addr; 92 REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = 0;
81 (void)size; 93 REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr);
82 /* TODO */ 94 REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR);
95 REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size;
96 REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT;
97 REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = ( DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DWDH_32
98 | DMAC_DCMD_TIE);
83 99
84 play_start_pcm(); 100 play_start_pcm();
85} 101}
86 102
103void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void)
104{
105 if( REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_TT )
106 __aic_disable_transmit_dma();
107}
108
109size_t pcm_get_bytes_waiting(void)
110{
111 return REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL);
112}
113
87void pcm_play_dma_stop(void) 114void pcm_play_dma_stop(void)
88{ 115{
89 play_stop_pcm(); 116 play_stop_pcm();
@@ -110,12 +137,6 @@ void pcm_play_dma_pause(bool pause)
110 137
111} 138}
112 139
113size_t pcm_get_bytes_waiting(void)
114{
115 /* TODO */
116 return 0;
117}
118
119#ifdef HAVE_RECORDING 140#ifdef HAVE_RECORDING
120/* TODO */ 141/* TODO */
121void pcm_rec_dma_init(void) 142void pcm_rec_dma_init(void)
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index 10741024a9..f733582d70 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -372,7 +372,7 @@ static char* parse_exception(unsigned int cause)
372} 372}
373 373
374void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc) 374void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc)
375{ 375{
376 panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), cause, epc, (unsigned int)stack_ptr); 376 panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), cause, epc, (unsigned int)stack_ptr);
377} 377}
378 378
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index 6ab5d02135..a8133140fa 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -108,4 +108,7 @@ bool in_interrupt_mode(void);
108#define DMA_USB_CHANNEL 2 108#define DMA_USB_CHANNEL 2
109#define DMA_AIC_TX_CHANNEL 3 109#define DMA_AIC_TX_CHANNEL 3
110 110
111#define XDMA_CALLBACK(n) DMA ## n
112#define DMA_CALLBACK(n) XDMA_CALLBACK(n)
113
111#endif /* __SYSTEM_TARGET_H_ */ 114#endif /* __SYSTEM_TARGET_H_ */
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
index f0b4eb4694..83dedfdd48 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
@@ -20,7 +20,6 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "config.h" 22#include "config.h"
23#include "string.h"
24#include "system.h" 23#include "system.h"
25#include "usb_ch9.h" 24#include "usb_ch9.h"
26#include "usb_drv.h" 25#include "usb_drv.h"
@@ -29,16 +28,18 @@
29#include "jz4740.h" 28#include "jz4740.h"
30#include "thread.h" 29#include "thread.h"
31 30
32#if 1 31//#define DEBUGF printf
32#define DEBUGF
33 33
34#define EP1_INTR_BIT 2 34#define USB_EP0_IDLE 0
35#define EP_FIFO_NOEMPTY 2 35#define USB_EP0_RX 1
36#define USB_EP0_TX 2
36 37
37#define IS_CACHE(x) (x < 0xa0000000) 38#define EP_BUF_LEFT(ep) (ep->length - ep->sent)
38 39#define EP_PTR(ep) ((void*)((unsigned int)ep->buf + ep->sent))
39#define USB_EP0_IDLE 0 40#define EP_NUMBER(ep) (((int)ep - (int)&endpoints[0])/sizeof(struct usb_endpoint))
40#define USB_EP0_RX 1 41#define TOTAL_EP() (sizeof(endpoints)/sizeof(struct usb_endpoint))
41#define USB_EP0_TX 2 42#define EP_IS_IN(ep) (EP_NUMBER(ep)%2)
42 43
43enum ep_type 44enum ep_type
44{ 45{
@@ -49,27 +50,29 @@ struct usb_endpoint
49{ 50{
50 void *buf; 51 void *buf;
51 unsigned int length; 52 unsigned int length;
52 void *ptr; 53 union
54 {
55 unsigned int sent;
56 unsigned int received;
57 };
53 58
54 const enum ep_type type; 59 const enum ep_type type;
55 const bool use_dma; 60 const bool use_dma;
56 const bool in;
57 61
58 const void *fifo_addr; 62 const unsigned int fifo_addr;
59 unsigned short fifo_size; 63 unsigned short fifo_size;
60}; 64};
61 65
62static unsigned char ep0_rx_buf[64]; 66static unsigned char ep0_rx_buf[64];
63static unsigned char ep0_tx_buf[64];
64static unsigned char ep0state = USB_EP0_IDLE; 67static unsigned char ep0state = USB_EP0_IDLE;
65static struct usb_endpoint endpoints[] = 68static struct usb_endpoint endpoints[] =
66{ 69{
67 /* buf length ptr type use_dma in fifo_addr fifo_size */ 70 /* buf length sent type use_dma fifo_addr fifo_size */
68 {&ep0_rx_buf, 0, &ep0_rx_buf, ep_control, false, true, (void*)USB_FIFO_EP0, 64 }, 71 {&ep0_rx_buf, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 },
69 {&ep0_tx_buf, 0, &ep0_tx_buf, ep_control, false, false, (void*)USB_FIFO_EP0, 64 }, 72 {NULL, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 },
70 {NULL, 0, NULL, ep_bulk, true, true, (void*)USB_FIFO_EP1, 512}, 73 {NULL, 0, {0}, ep_bulk, true, USB_FIFO_EP1, 512},
71 {NULL, 0, NULL, ep_bulk, true, false, (void*)USB_FIFO_EP1, 512}, 74 {NULL, 0, {0}, ep_bulk, true, USB_FIFO_EP1, 512},
72 {NULL, 0, NULL, ep_interrupt, false, true, (void*)USB_FIFO_EP2, 64 } 75 {NULL, 0, {0}, ep_interrupt, false, USB_FIFO_EP2, 64 }
73}; 76};
74 77
75static inline void select_endpoint(int ep) 78static inline void select_endpoint(int ep)
@@ -78,103 +81,109 @@ static inline void select_endpoint(int ep)
78} 81}
79 82
80static void readFIFO(struct usb_endpoint *ep, unsigned int size) 83static void readFIFO(struct usb_endpoint *ep, unsigned int size)
81{ 84{
82 unsigned int *d = (unsigned int *)ep->ptr; 85 DEBUGF("readFIFO(EP%d, %d)", EP_NUMBER(ep), size);
83 unsigned int s; 86
84 s = (size + 3) >> 2; 87 register unsigned char *ptr = (unsigned char*)EP_PTR(ep);
85 while (s--) 88 register unsigned int *ptr32 = (unsigned int*)ptr;
86 *d++ = REG32(ep->fifo_addr); 89 register unsigned int s = size / 4;
90 register unsigned int x;
91
92 if(size > 0)
93 {
94 if( ((int)ptr & 3) == 0 )
95 {
96 while(s--)
97 *ptr32++ = REG32(ep->fifo_addr);
98
99 ptr = (unsigned char*)ptr32;
100 }
101 else
102 {
103 while(s--)
104 {
105 x = REG32(ep->fifo_addr);
106 *ptr++ = (x >> 0) & 0xff;
107 *ptr++ = (x >> 8) & 0xff;
108 *ptr++ = (x >> 16) & 0xff;
109 *ptr++ = (x >> 24) & 0xff;
110 }
111 }
112
113 s = size & 3;
114 while(s--)
115 *ptr++ = REG8(ep->fifo_addr);
116 }
87} 117}
88 118
89static void writeFIFO(struct usb_endpoint *ep, unsigned int size) 119static void writeFIFO(struct usb_endpoint *ep, unsigned int size)
90{ 120{
91 unsigned int *d = (unsigned int *)ep->ptr; 121 DEBUGF("writeFIFO(EP%d, %d)", EP_NUMBER(ep), size);
92 unsigned char *c; 122
93 int s, q; 123 register unsigned int *d = (unsigned int *)EP_PTR(ep);
124 register unsigned char *c;
125 register int s;
94 126
95 if (size > 0) 127 if (size > 0)
96 { 128 {
97 s = size >> 2; 129 s = size >> 2;
98 while (s--) 130 while (s--)
99 REG32(ep->fifo_addr) = *d++; 131 REG32(ep->fifo_addr) = *d++;
100 132
101 q = size & 3; 133 if ( (s = size & 3) )
102 if (q)
103 { 134 {
104 c = (unsigned char *)d; 135 c = (unsigned char *)d;
105 while (q--) 136 while (s--)
106 REG8(ep->fifo_addr) = *c++; 137 REG8(ep->fifo_addr) = *c++;
107 } 138 }
108 }
109}
110
111static void sendPKT(int ep_nr, const unsigned char* ptr, unsigned int size)
112{
113 struct usb_endpoint *ep = &endpoints[ep_nr];
114
115 if (ep_nr != 0)
116 {
117 ep->buf = (void*)ptr;
118 ep->ptr = (void*)ptr;
119 ep->length = size;
120 select_endpoint(ep_nr);
121 if (size <= ep->fifo_size)
122 {
123 writeFIFO(ep, size);
124 REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY;
125 ep->ptr = ep->buf + size;
126 }
127 else
128 {
129 writeFIFO(ep, ep->fifo_size);
130 REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY;
131 ep->ptr += ep->fifo_size;
132 }
133 }
134 else /* EP0 */
135 {
136 ep->length = size;
137 ep->ptr = ep->buf;
138 memcpy(ep->buf, ptr, size);
139 ep0state = USB_EP0_TX;
140 } 139 }
141} 140}
142 141
143static void getPKT(int ep_nr, const unsigned char *ptr, unsigned int size) 142static void EP0_send(void)
144{ 143{
145 struct usb_endpoint *ep = &endpoints[ep_nr]; 144 register struct usb_endpoint* ep = &endpoints[1];
145 register unsigned int length;
146 146
147 memcpy((void*)ptr, ep->ptr, size); 147 if(ep->sent == 0)
148 if (ep->length > size) 148 length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size);
149 ep->length -= size;
150 else 149 else
150 length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size);
151
152 writeFIFO(ep, length);
153 ep->sent += length;
154
155 if(ep->sent >= ep->length)
151 { 156 {
152 size = ep->length; 157 REG_USB_REG_CSR0 |= (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */
153 ep->length = 0; 158 ep0state = USB_EP0_IDLE;
154 } 159 }
155 160 else
156 ep->ptr += size; 161 REG_USB_REG_CSR0 |= USB_CSR0_INPKTRDY;
157} 162}
158 163
159static void EP0_handler(void) 164static void EP0_handler(void)
160{ 165{
161 unsigned char csr0; 166 register unsigned char csr0;
162 167
163 /* Read CSR0 */ 168 /* Read CSR0 */
164 select_endpoint(0); 169 select_endpoint(0);
165 csr0 = REG_USB_REG_CSR0; 170 csr0 = REG_USB_REG_CSR0;
166 171
167 /* Check for SentStall 172 /* Check for SentStall:
168 if sentstall is set, clear the sentstall bit 173 This bit is set when a STALL handshake is transmitted. The CPU should clear this bit.
169 */ 174 */
170 if (csr0 & USB_CSR0_SENTSTALL) 175 if (csr0 & USB_CSR0_SENTSTALL)
171 { 176 {
172 REG_USB_REG_CSR0 = csr0 & ~USB_CSR0_SENTSTALL; 177 REG_USB_REG_CSR0 &= ~USB_CSR0_SENTSTALL;
173 ep0state = USB_EP0_IDLE; 178 ep0state = USB_EP0_IDLE;
174 return; 179 return;
175 } 180 }
176 181
177 /* Check for SetupEnd */ 182 /* Check for SetupEnd:
183 This bit will be set when a control transaction ends before the DataEnd bit has been set.
184 An interrupt will be generated and the FIFO flushed at this time.
185 The bit is cleared by the CPU writing a 1 to the ServicedSetupEnd bit.
186 */
178 if (csr0 & USB_CSR0_SETUPEND) 187 if (csr0 & USB_CSR0_SETUPEND)
179 { 188 {
180 REG_USB_REG_CSR0 |= USB_CSR0_SVDSETUPEND; 189 REG_USB_REG_CSR0 |= USB_CSR0_SVDSETUPEND;
@@ -187,38 +196,21 @@ static void EP0_handler(void)
187 { 196 {
188 if (csr0 & USB_CSR0_OUTPKTRDY) /* There is data in the fifo */ 197 if (csr0 & USB_CSR0_OUTPKTRDY) /* There is data in the fifo */
189 { 198 {
190 readFIFO(&endpoints[0], 8); 199 readFIFO(&endpoints[0], REG_USB_REG_COUNT0);
191 REG_USB_REG_CSR0 |= USB_CSR0_SVDOUTPKTRDY; /* clear OUTRD bit */ 200 REG_USB_REG_CSR0 |= USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */
192 usb_core_control_request((struct usb_ctrlrequest*)endpoints[0].buf); 201 usb_core_control_request((struct usb_ctrlrequest*)endpoints[0].buf);
193 } 202 }
194 endpoints[0].length = 0;
195 endpoints[0].ptr = endpoints[0].buf;
196 }
197
198 if (ep0state == USB_EP0_TX)
199 {
200 if ((&endpoints[1].ptr - &endpoints[1].buf) <= endpoints[1].fifo_size)
201 {
202 writeFIFO(&endpoints[1], (&endpoints[1].ptr - &endpoints[1].buf));
203 endpoints[1].ptr = &endpoints[1].buf + endpoints[1].length;
204 REG_USB_REG_CSR0 |= (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */
205 ep0state = USB_EP0_IDLE;
206 }
207 else
208 {
209 writeFIFO(&endpoints[1], endpoints[1].fifo_size);
210 REG_USB_REG_CSR0 |= USB_CSR0_INPKTRDY;
211 endpoints[1].ptr += endpoints[1].fifo_size;
212 }
213 } 203 }
204 else if (ep0state == USB_EP0_TX)
205 EP0_send();
214} 206}
215 207
216static void setup_endpoint(struct usb_endpoint *ep) 208static void setup_endpoint(struct usb_endpoint *ep)
217{ 209{
218 ep->ptr = ep->buf; 210 ep->sent = 0;
219 ep->length = 0; 211 ep->length = 0;
220 212
221 if(ep->in) 213 if(EP_IS_IN(ep))
222 { 214 {
223 if(ep->type == ep_bulk) 215 if(ep->type == ep_bulk)
224 { 216 {
@@ -235,53 +227,66 @@ static void setup_endpoint(struct usb_endpoint *ep)
235 else 227 else
236 REG_USB_REG_INMAXP = ep->fifo_size; 228 REG_USB_REG_INMAXP = ep->fifo_size;
237 229
238 REG_USB_REG_INCSR = 0x2048; 230 REG_USB_REG_INCSR = (USB_INCSR_FF | USB_INCSR_CDT | USB_INCSRH_MODE);
231 REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER(ep));
239 } 232 }
240 else 233 else
241 { 234 {
242 REG_USB_REG_OUTMAXP = ep->fifo_size; 235 REG_USB_REG_OUTMAXP = ep->fifo_size;
243 REG_USB_REG_OUTCSR = 0x0090; 236 REG_USB_REG_OUTCSR = (USB_OUTCSR_FF | USB_OUTCSR_CDT);
237 REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER(ep));
244 } 238 }
245} 239}
246 240
247static void udc_reset(void) 241static void udc_reset(void)
248{ 242{
249 register int i; 243 DEBUGF("udc_reset");
244
245 register unsigned int i;
250 246
251 /* data init */ 247 /* data init */
252 ep0state = USB_EP0_IDLE; 248 ep0state = USB_EP0_IDLE;
253 249
254 /* Disable interrupts */ 250 /* Disable interrupts */
255 REG_USB_REG_INTRINE = 0; 251 REG_USB_REG_INTRINE = 0;
256 REG_USB_REG_INTROUTE = 0; 252 REG_USB_REG_INTROUTE = 0;
257 REG_USB_REG_INTRUSBE = 0; 253 REG_USB_REG_INTRUSBE = 0;
258 254
255 /* Disable DMA */
256 REG_USB_REG_CNTL1 = 0;
257 REG_USB_REG_CNTL2 = 0;
258
259 /* Reset address */
259 REG_USB_REG_FADDR = 0; 260 REG_USB_REG_FADDR = 0;
260 REG_USB_REG_POWER = 0x60; /* High speed */ 261 //REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB); /* High speed and softconnect */
262 REG_USB_REG_POWER = USB_POWER_SOFTCONN;
263 /* Enable SUSPEND */
264 /* REG_USB_REG_POWER |= USB_POWER_SUSPENDM; */
261 265
262 select_endpoint(0); 266 select_endpoint(0);
263 REG_USB_REG_CSR0 = 0xC0; 267 REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND);
264 268
265 for(i=1; i<3; i++) 269 for(i=2; i<TOTAL_EP(); i++) /* Skip EP0 */
266 { 270 {
267 select_endpoint(i); 271 select_endpoint(i);
268 setup_endpoint(&endpoints[i]); 272 setup_endpoint(&endpoints[i]);
269 } 273 }
270 274
271 /* enable intr */ 275 /* Enable interrupts */
272 REG_USB_REG_INTRINE = 0x3; 276 REG_USB_REG_INTRINE |= USB_INTR_EP0;
273 REG_USB_REG_INTROUTE = 0x2; 277 REG_USB_REG_INTRUSBE |= USB_INTR_RESET;
274 REG_USB_REG_INTRUSBE = 0x4; 278
279 usb_core_bus_reset();
275} 280}
276 281
277/* Interrupt handler */ 282/* Interrupt handler */
278void UDC(void) 283void UDC(void)
279{ 284{
280 /* Read interrupt registers */ 285 /* Read interrupt registers */
281 unsigned char intrUSB = REG_USB_REG_INTRUSB & 0x07; /* Mask SOF */ 286 register unsigned char intrUSB = REG_USB_REG_INTRUSB & 0x07; /* Mask SOF */
282 unsigned short intrIn = REG_USB_REG_INTRIN; 287 register unsigned short intrIn = REG_USB_REG_INTRIN;
283 unsigned short intrOut = REG_USB_REG_INTROUT; 288 register unsigned short intrOut = REG_USB_REG_INTROUT;
284 unsigned char intrDMA = REG_USB_REG_INTR; 289 register unsigned char intrDMA = REG_USB_REG_INTR;
285 290
286 if(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0) 291 if(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0)
287 return; 292 return;
@@ -295,16 +300,20 @@ void UDC(void)
295 if(intrUSB & USB_INTR_RESUME); 300 if(intrUSB & USB_INTR_RESUME);
296 if(intrDMA & USB_INTR_DMA_BULKIN) 301 if(intrDMA & USB_INTR_DMA_BULKIN)
297 { 302 {
303 DEBUGF("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF));
298 usb_core_transfer_complete(((REG_USB_REG_CNTL1 >> 4) & 0xF) | USB_DIR_IN, USB_DIR_IN, 0, 0); 304 usb_core_transfer_complete(((REG_USB_REG_CNTL1 >> 4) & 0xF) | USB_DIR_IN, USB_DIR_IN, 0, 0);
299 } 305 }
300 if(intrDMA & USB_INTR_DMA_BULKOUT) 306 if(intrDMA & USB_INTR_DMA_BULKOUT)
301 { 307 {
308 DEBUGF("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF));
302 usb_core_transfer_complete(((REG_USB_REG_CNTL2 >> 4) & 0xF) | USB_DIR_OUT, USB_DIR_OUT, 0, 0); 309 usb_core_transfer_complete(((REG_USB_REG_CNTL2 >> 4) & 0xF) | USB_DIR_OUT, USB_DIR_OUT, 0, 0);
303 } 310 }
304} 311}
305 312
306bool usb_drv_stalled(int endpoint, bool in) 313bool usb_drv_stalled(int endpoint, bool in)
307{ 314{
315 DEBUGF("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT");
316
308 select_endpoint(endpoint); 317 select_endpoint(endpoint);
309 318
310 if(endpoint == 0) 319 if(endpoint == 0)
@@ -320,6 +329,8 @@ bool usb_drv_stalled(int endpoint, bool in)
320 329
321void usb_drv_stall(int endpoint, bool stall, bool in) 330void usb_drv_stall(int endpoint, bool stall, bool in)
322{ 331{
332 DEBUGF("usb_drv_stall(%d,%s,%s)", endpoint, stall?"y":"n", in?"IN":"OUT");
333
323 select_endpoint(endpoint); 334 select_endpoint(endpoint);
324 335
325 if(endpoint == 0) 336 if(endpoint == 0)
@@ -348,23 +359,20 @@ void usb_drv_stall(int endpoint, bool stall, bool in)
348 } 359 }
349} 360}
350 361
351
352bool usb_drv_connected(void) 362bool usb_drv_connected(void)
353{ 363{
354 return __gpio_get_pin(GPIO_UDC_DETE) == 1; 364 return USB_DRV_CONNECTED();
355} 365}
356 366
357int usb_detect(void) 367int usb_detect(void)
358{ 368{
359 if(usb_drv_connected()) 369 return usb_drv_connected() ? USB_INSERTED : USB_EXTRACTED;
360 return USB_INSERTED;
361 else
362 return USB_EXTRACTED;
363} 370}
364 371
365void usb_init_device(void) 372void usb_init_device(void)
366{ 373{
367 usb_init_gpio(); 374 USB_INIT_GPIO();
375 system_enable_irq(IRQ_UDC);
368} 376}
369 377
370void usb_enable(bool on) 378void usb_enable(bool on)
@@ -387,27 +395,6 @@ void usb_drv_init(void)
387 395
388 /* Enable the USB PHY */ 396 /* Enable the USB PHY */
389 REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; 397 REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE;
390
391 /* Disable interrupts */
392 REG_USB_REG_INTRINE = 0;
393 REG_USB_REG_INTROUTE = 0;
394 REG_USB_REG_INTRUSBE = 0;
395
396 /* Enable interrupts */
397 REG_USB_REG_INTRINE |= USB_INTR_EP0;
398 REG_USB_REG_INTRUSBE |= USB_INTR_RESET;
399
400 /* Enable SUSPEND */
401 /* usb_setb(USB_REG_POWER, USB_POWER_SUSPENDM); */
402
403 /* Enable HS Mode */
404 REG_USB_REG_POWER |= USB_POWER_HSENAB;
405
406 /* Let host detect UDC:
407 * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this
408 * transistor on and pull the USBDP pin HIGH.
409 */
410 REG_USB_REG_POWER |= USB_POWER_SOFTCONN;
411 398
412 udc_reset(); 399 udc_reset();
413} 400}
@@ -434,984 +421,94 @@ void usb_drv_exit(void)
434 421
435void usb_drv_set_address(int address) 422void usb_drv_set_address(int address)
436{ 423{
424 DEBUGF("set adr: 0x%x", address);
425
437 REG_USB_REG_FADDR = address; 426 REG_USB_REG_FADDR = address;
438} 427}
439 428
440int usb_drv_send(int endpoint, void* ptr, int length) 429int usb_drv_send(int endpoint, void* ptr, int length)
441{ 430{
442 return 0; 431 DEBUGF("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length);
443}
444
445int usb_drv_recv(int endpoint, void* ptr, int length)
446{
447 return 0;
448}
449 432
450void usb_drv_set_test_mode(int mode) 433 if(endpoint == EP_CONTROL && ptr == NULL && length == 0) /* ACK request */
451{ 434 return 0;
452
453}
454
455int usb_drv_port_speed(void)
456{
457 return ((REG_USB_REG_POWER & USB_POWER_HSMODE) != 0) ? 1 : 0;
458}
459
460void usb_drv_cancel_all_transfers(void)
461{
462 int i;
463 for(i=0; i<5; i++)
464 {
465 endpoints[i].ptr = endpoints[i].buf;
466 endpoints[i].length = 0;
467 }
468}
469
470void usb_drv_release_endpoint(int ep)
471{
472 435
473} 436 if(endpoint == EP_CONTROL)
474
475#else
476
477//------------------------------------------
478#ifndef u8
479#define u8 unsigned char
480#endif
481
482#ifndef u16
483#define u16 unsigned short
484#endif
485
486#ifndef u32
487#define u32 unsigned int
488#endif
489
490#ifndef s8
491#define s8 char
492#endif
493
494#ifndef s16
495#define s16 short
496#endif
497
498#ifndef s32
499#define s32 int
500#endif
501
502extern int usbdebug;
503
504enum USB_ENDPOINT_TYPE
505{
506 ENDPOINT_TYPE_CONTROL,
507 /* Typically used to configure a device when attached to the host.
508 * It may also be used for other device specific purposes, including
509 * control of other pipes on the device.
510 */
511 ENDPOINT_TYPE_ISOCHRONOUS,
512 /* Typically used for applications which need guaranteed speed.
513 * Isochronous transfer is fast but with possible data loss. A typical
514 * use is audio data which requires a constant data rate.
515 */
516 ENDPOINT_TYPE_BULK,
517 /* Typically used by devices that generate or consume data in relatively
518 * large and bursty quantities. Bulk transfer has wide dynamic latitude
519 * in transmission constraints. It can use all remaining available bandwidth,
520 * but with no guarantees on bandwidth or latency. Since the USB bus is
521 * normally not very busy, there is typically 90% or more of the bandwidth
522 * available for USB transfers.
523 */
524 ENDPOINT_TYPE_INTERRUPT
525 /* Typically used by devices that need guaranteed quick responses
526 * (bounded latency).
527 */
528};
529
530
531enum USB_STANDARD_REQUEST_CODE {
532 GET_STATUS,
533 CLEAR_FEATURE,
534 SET_FEATURE = 3,
535 SET_ADDRESS = 5,
536 GET_DESCRIPTOR,
537 SET_DESCRIPTOR,
538 GET_CONFIGURATION,
539 SET_CONFIGURATION,
540 GET_INTERFACE,
541 SET_INTERFACE,
542 SYNCH_FRAME
543};
544
545
546enum USB_DESCRIPTOR_TYPE {
547 DEVICE_DESCRIPTOR = 1,
548 CONFIGURATION_DESCRIPTOR,
549 STRING_DESCRIPTOR,
550 INTERFACE_DESCRIPTOR,
551 ENDPOINT_DESCRIPTOR,
552 DEVICE_QUALIFIER_DESCRIPTOR,
553 OTHER_SPEED_CONFIGURATION_DESCRIPTOR,
554 INTERFACE_POWER1_DESCRIPTOR
555};
556
557
558enum USB_FEATURE_SELECTOR {
559 ENDPOINT_HALT,
560 DEVICE_REMOTE_WAKEUP,
561 TEST_MODE
562};
563
564enum USB_CLASS_CODE {
565 CLASS_DEVICE,
566 CLASS_AUDIO,
567 CLASS_COMM_AND_CDC_CONTROL,
568 CLASS_HID,
569 CLASS_PHYSICAL = 0x05,
570 CLASS_STILL_IMAGING,
571 CLASS_PRINTER,
572 CLASS_MASS_STORAGE,
573 CLASS_HUB,
574 CLASS_CDC_DATA,
575 CLASS_SMART_CARD,
576 CLASS_CONTENT_SECURITY = 0x0d,
577 CLASS_VIDEO,
578 CLASS_DIAGNOSTIC_DEVICE = 0xdc,
579 CLASS_WIRELESS_CONTROLLER = 0xe0,
580 CLASS_MISCELLANEOUS = 0xef,
581 CLASS_APP_SPECIFIC = 0xfe,
582 CLASS_VENDOR_SPECIFIC = 0xff
583};
584
585
586typedef struct {
587 u8 bmRequestType;
588 u8 bRequest;
589 u16 wValue;
590 u16 wIndex;
591 u16 wLength;
592} __attribute__ ((packed)) USB_DeviceRequest;
593
594
595typedef struct {
596 u8 bLength;
597 u8 bDescriptorType;
598 u16 bcdUSB;
599 u8 bDeviceClass;
600 u8 bDeviceSubClass;
601 u8 bDeviceProtocol;
602 u8 bMaxPacketSize0;
603 u16 idVendor;
604 u16 idProduct;
605 u16 bcdDevice;
606 u8 iManufacturer;
607 u8 iProduct;
608 u8 iSerialNumber;
609 u8 bNumConfigurations;
610} __attribute__ ((packed)) USB_DeviceDescriptor;
611
612
613typedef struct {
614 u8 bLength;
615 u8 bDescriptorType;
616 u16 bcdUSB;
617 u8 bDeviceClass;
618 u8 bDeviceSubClass;
619 u8 bDeviceProtocol;
620 u8 bMaxPacketSize0;
621 u8 bNumConfigurations;
622 u8 bReserved;
623} __attribute__ ((packed)) USB_DeviceQualifierDescriptor;
624
625
626typedef struct {
627 u8 bLength;
628 u8 bDescriptorType;
629 u16 wTotalLength;
630 u8 bNumInterfaces;
631 u8 bConfigurationValue;
632 u8 iConfiguration;
633 u8 bmAttributes;
634 u8 MaxPower;
635} __attribute__ ((packed)) USB_ConfigDescriptor;
636
637
638typedef struct {
639 u8 bLength;
640 u8 bDescriptorType;
641 u16 wTotalLength;
642 u8 bNumInterfaces;
643 u8 bConfigurationValue;
644 u8 iConfiguration;
645 u8 bmAttributes;
646 u8 bMaxPower;
647} __attribute__ ((packed)) USB_OtherSpeedConfigDescriptor;
648
649
650typedef struct {
651 u8 bLength;
652 u8 bDescriptorType;
653 u8 bInterfaceNumber;
654 u8 bAlternateSetting;
655 u8 bNumEndpoints;
656 u8 bInterfaceClass;
657 u8 bInterfaceSubClass;
658 u8 bInterfaceProtocol;
659 u8 iInterface;
660} __attribute__ ((packed)) USB_InterfaceDescriptor;
661
662
663typedef struct {
664 u8 bLegth;
665 u8 bDescriptorType;
666 u8 bEndpointAddress;
667 u8 bmAttributes;
668 u16 wMaxPacketSize;
669 u8 bInterval;
670} __attribute__ ((packed)) USB_EndPointDescriptor;
671
672
673typedef struct {
674 u8 bLength;
675 u8 bDescriptorType;
676 u16 SomeDesriptor[1];
677} __attribute__ ((packed)) USB_StringDescriptor;
678//------------------------------------------
679#define MAX_EP0_SIZE 64
680#define MAX_EP1_SIZE 512
681
682#define USB_HS 0
683#define USB_FS 1
684#define USB_LS 2
685
686//definitions of EP0
687#define USB_EP0_IDLE 0
688#define USB_EP0_RX 1
689#define USB_EP0_TX 2
690/* Define maximum packet size for endpoint 0 */
691#define M_EP0_MAXP 64
692/* Endpoint 0 status structure */
693
694static __inline__ void usb_setb(u32 port, u8 val)
695{
696 volatile u8 *ioport = (volatile u8 *)(port);
697 *ioport = (*ioport) | val;
698}
699
700static __inline__ void usb_clearb(u32 port, u8 val)
701{
702 volatile u8 *ioport = (volatile u8 *)(port);
703 *ioport = (*ioport) & ~val;
704}
705
706static __inline__ void usb_setw(u32 port, u16 val)
707{
708 volatile u16 *ioport = (volatile u16 *)(port);
709 *ioport = (*ioport) | val;
710}
711
712static __inline__ void usb_clearw(u32 port, u16 val)
713{
714 volatile u16 *ioport = (volatile u16 *)(port);
715 *ioport = (*ioport) & ~val;
716}
717//---------------------------------
718#define BULK_OUT_BUF_SIZE 0x20000 //buffer size :
719#define BULK_IN_BUF_SIZE 0x20000 // too
720
721enum UDC_STATE
722{
723 IDLE,
724 BULK_IN,
725 BULK_OUT
726};
727
728enum USB_JZ4740_REQUEST //add for USB_BOOT
729{
730 VR_GET_CUP_INFO = 0,
731 VR_SET_DATA_ADDERSS,
732 VR_SET_DATA_LENGTH,
733 VR_FLUSH_CACHES,
734 VR_PROGRAM_START1,
735 VR_PROGRAM_START2,
736 VR_NOR_OPS,
737 VR_NAND_OPS,
738 VR_SDRAM_OPS,
739 VR_CONFIGRATION
740};
741
742enum NOR_OPS_TYPE
743{
744 NOR_INIT = 0,
745 NOR_QUERY,
746 NOR_WRITE,
747 NOR_ERASE_CHIP,
748 NOR_ERASE_SECTOR
749};
750
751enum NOR_FLASH_TYPE
752{
753 NOR_AM29 = 0,
754 NOR_SST28,
755 NOR_SST39x16,
756 NOR_SST39x8
757};
758
759enum NAND_OPS_TYPE
760{
761 NAND_QUERY = 0,
762 NAND_INIT,
763 NAND_MARK_BAD,
764 NAND_READ_OOB,
765 NAND_READ_RAW,
766 NAND_ERASE,
767 NAND_READ,
768 NAND_PROGRAM,
769 NAND_READ_TO_RAM
770};
771
772enum SDRAM_OPS_TYPE
773{
774 SDRAM_LOAD,
775
776};
777
778enum DATA_STRUCTURE_OB
779{
780 DS_flash_info ,
781 DS_hand
782};
783
784
785/*typedef enum _USB_BOOT_STATUS
786{
787 USB_NO_ERR =0 ,
788 GET_CPU_INFO_ERR,
789 SET_DATA_ADDRESS_ERR,
790 SET_DATA_LENGTH_ERR,
791 FLUSH_CAHCES_ERR,
792 PROGRAM_START1_ERR,
793 PROGRAM_START2_ERR,
794 NOR_OPS_ERR,
795 NAND_OPS_ERR,
796 NOR_FLASHTYPE_ERR,
797 OPS_NOTSUPPORT_ERR
798}USB_BOOT_STATUS;*/
799
800enum OPTION
801{
802 OOB_ECC,
803 OOB_NO_ECC,
804 NO_OOB,
805};
806//-------------------------
807static inline void jz_writeb(u32 address, u8 value)
808{
809 *((volatile u8 *)address) = value;
810}
811
812static inline void jz_writew(u32 address, u16 value)
813{
814 *((volatile u16 *)address) = value;
815}
816
817static inline void jz_writel(u32 address, u32 value)
818{
819 *((volatile u32 *)address) = value;
820}
821
822static inline u8 jz_readb(u32 address)
823{
824 return *((volatile u8 *)address);
825}
826
827static inline u16 jz_readw(u32 address)
828{
829 return *((volatile u16 *)address);
830}
831
832static inline u32 jz_readl(u32 address)
833{
834 return *((volatile u32 *)address);
835}
836//---------------------------
837
838#define TXFIFOEP0 USB_FIFO_EP0
839
840u8 *Bulk_in_buf;
841u32 Bulk_out_buf[BULK_OUT_BUF_SIZE];
842u32 Bulk_in_size,Bulk_in_finish,Bulk_out_size;
843u16 handshake_PKT[4]={0,0,0,0};
844u8 udc_state;
845
846static u32 rx_buf[32];
847static u32 tx_buf[32];
848static u32 tx_size, rx_size, finished,fifo;
849static u8 ep0state,USB_Version;
850
851static u32 fifoaddr[] =
852{
853 TXFIFOEP0, TXFIFOEP0+4 ,TXFIFOEP0+8
854};
855
856static u32 fifosize[] = {
857 MAX_EP0_SIZE, MAX_EP1_SIZE
858};
859
860static void udcReadFifo(u8 *ptr, int size)
861{
862 u32 *d = (u32 *)ptr;
863 int s;
864 s = (size + 3) >> 2;
865 while (s--)
866 *d++ = REG32(fifo);
867}
868
869static void udcWriteFifo(u8 *ptr, int size)
870{
871 u32 *d = (u32 *)ptr;
872 u8 *c;
873 int s, q;
874
875 if (size > 0) {
876 s = size >> 2;
877 while (s--)
878 REG32(fifo) = *d++;
879 q = size & 3;
880 if (q) {
881 c = (u8 *)d;
882 while (q--)
883 REG8(fifo) = *c++;
884 }
885 }
886}
887
888void HW_SendPKT(int ep, const u8 *buf, int size)
889{
890 fifo = fifoaddr[ep];
891
892 if (ep!=0)
893 { 437 {
894 Bulk_in_size = size; 438 endpoints[1].buf = ptr;
895 Bulk_in_finish = 0; 439 endpoints[1].sent = 0;
896 jz_writeb(USB_REG_INDEX, ep); 440 endpoints[1].length = length;
897 if (Bulk_in_size - Bulk_in_finish <= fifosize[ep]) 441 ep0state = USB_EP0_TX;
898 { 442 EP0_send();
899 udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), 443 return 0;
900 Bulk_in_size - Bulk_in_finish);
901 usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY);
902 Bulk_in_finish = Bulk_in_size;
903 }
904 else
905 {
906 udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish),
907 fifosize[ep]);
908 usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY);
909 Bulk_in_finish += fifosize[ep];
910 Bulk_in_buf = (u8*)buf;
911 }
912 }
913 else //EP0
914 {
915 tx_size = size;
916 finished = 0;
917 memcpy((void *)tx_buf, buf, size);
918 ep0state = USB_EP0_TX;
919 } 444 }
920}
921
922void HW_GetPKT(int ep, const u8 *buf, unsigned int size)
923{
924 memcpy((void *)buf, (u8 *)rx_buf, size);
925 fifo = fifoaddr[ep];
926 if (rx_size > size)
927 rx_size -= size;
928 else 445 else
929 { 446 return 0;
930 size = rx_size;
931 rx_size = 0;
932 }
933 memcpy((u8 *)rx_buf, (u8 *)((u32)rx_buf+size), rx_size);
934}
935
936void Enable_DMA(u8* buf, u32 length)
937{
938 dma_cache_wback_inv((u32)buf, length);
939 jz_writeb(USB_REG_INDEX, 1);
940 usb_setw(USB_REG_INCSR, 0x9400);
941 usb_clearw(USB_REG_INTRINE, 0x2); //disable OUT intr
942 jz_writel(USB_REG_ADDR1, (u32)buf);
943 jz_writel(USB_REG_COUNT1, length);
944 jz_writel(USB_REG_CNTL1, 0x001f);
945}
946
947void Disable_DMA(void)
948{
949 jz_writeb(USB_REG_INDEX, 1);
950 usb_clearw(USB_REG_INCSR, 0x9400);
951 usb_setw(USB_REG_INTRINE, 0x2); //Enable OUT intr
952}
953
954static USB_DeviceDescriptor devDesc =
955{
956 sizeof(USB_DeviceDescriptor),
957 DEVICE_DESCRIPTOR, //1
958 0x0200, //Version 2.0
959 0xff, //Vendor spec class
960 0xff,
961 0xff,
962 64, /* Ep0 FIFO size */
963 0x601a, //vendor ID
964 0xDEAD, //Product ID
965 0xffff,
966 0x00,
967 0x00,
968 0x00,
969 0x01
970};
971
972#define CONFIG_DESCRIPTOR_LEN (sizeof(USB_ConfigDescriptor) + \
973 sizeof(USB_InterfaceDescriptor) + \
974 sizeof(USB_EndPointDescriptor) * 2)
975
976static struct {
977 USB_ConfigDescriptor configuration_descriptor;
978 USB_InterfaceDescriptor interface_descritor;
979 USB_EndPointDescriptor endpoint_descriptor[2];
980} __attribute__ ((packed)) confDesc = {
981 {
982 sizeof(USB_ConfigDescriptor),
983 CONFIGURATION_DESCRIPTOR,
984 CONFIG_DESCRIPTOR_LEN,
985 0x01,
986 0x01,
987 0x00,
988 0xc0, // Self Powered, no remote wakeup
989 0x64 // Maximum power consumption 2000 mA
990 },
991 {
992 sizeof(USB_InterfaceDescriptor),
993 INTERFACE_DESCRIPTOR,
994 0x00,
995 0x00,
996 0x02, /* ep number */
997 0xff,
998 0xff,
999 0xff,
1000 0x00
1001 },
1002 {
1003 {
1004 sizeof(USB_EndPointDescriptor),
1005 ENDPOINT_DESCRIPTOR,
1006 (1 << 7) | 1,// endpoint 2 is IN endpoint
1007 2, /* bulk */
1008 512,
1009 0
1010 },
1011 {
1012 sizeof(USB_EndPointDescriptor),
1013 ENDPOINT_DESCRIPTOR,
1014 (0 << 7) | 1,// endpoint 5 is OUT endpoint
1015 2, /* bulk */
1016 512, /* OUT EP FIFO size */
1017 0
1018 }
1019 }
1020};
1021
1022void sendDevDescString(int size)
1023{
1024 u16 str_ret[13] = {
1025 0x031a,//0x1a=26 byte
1026 0x0041,
1027 0x0030,
1028 0x0030,
1029 0x0041,
1030 0x0030,
1031 0x0030,
1032 0x0041,
1033 0x0030,
1034 0x0030,
1035 0x0041,
1036 0x0030,
1037 0x0030
1038 };
1039 if(size >= 26)
1040 size = 26;
1041 str_ret[0] = (0x0300 | size);
1042 HW_SendPKT(0, (u8 *)str_ret,size);
1043} 447}
1044 448
1045void sendDevDesc(int size) 449int usb_drv_recv(int endpoint, void* ptr, int length)
1046{
1047 switch (size) {
1048 case 18:
1049 HW_SendPKT(0, (u8 *)&devDesc, sizeof(devDesc));
1050 break;
1051 default:
1052 HW_SendPKT(0, (u8 *)&devDesc, 8);
1053 break;
1054 }
1055}
1056
1057void sendConfDesc(int size)
1058{ 450{
1059 switch (size) { 451 DEBUGF("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length);
1060 case 9:
1061 HW_SendPKT(0, (u8 *)&confDesc, 9);
1062 break;
1063 case 8:
1064 HW_SendPKT(0, (u8 *)&confDesc, 8);
1065 break;
1066 default:
1067 HW_SendPKT(0, (u8 *)&confDesc, sizeof(confDesc));
1068 break;
1069 }
1070}
1071 452
1072void EP0_init(u32 out, u32 out_size, u32 in, u32 in_size) 453 if(endpoint == EP_CONTROL && ptr == NULL && length == 0) /* ACK request */
1073{ 454 return 0;
1074 confDesc.endpoint_descriptor[0].bEndpointAddress = (1<<7) | in; 455
1075 confDesc.endpoint_descriptor[0].wMaxPacketSize = in_size; 456 return -1;
1076 confDesc.endpoint_descriptor[1].bEndpointAddress = (0<<7) | out;
1077 confDesc.endpoint_descriptor[1].wMaxPacketSize = out_size;
1078} 457}
1079 458
1080static void udc_reset(void) 459void usb_drv_set_test_mode(int mode)
1081{ 460{
1082 //data init 461 switch(mode)
1083 ep0state = USB_EP0_IDLE;
1084 Bulk_in_size = 0;
1085 Bulk_in_finish = 0;
1086 Bulk_out_size = 0;
1087 udc_state = IDLE;
1088 tx_size = 0;
1089 rx_size = 0;
1090 finished = 0;
1091 /* Enable the USB PHY */
1092// REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE;
1093 /* Disable interrupts */
1094 jz_writew(USB_REG_INTRINE, 0);
1095 jz_writew(USB_REG_INTROUTE, 0);
1096 jz_writeb(USB_REG_INTRUSBE, 0);
1097 jz_writeb(USB_REG_FADDR,0);
1098 jz_writeb(USB_REG_POWER,0x60); //High speed
1099 jz_writeb(USB_REG_INDEX,0);
1100 jz_writeb(USB_REG_CSR0,0xc0);
1101 jz_writeb(USB_REG_INDEX,1);
1102 jz_writew(USB_REG_INMAXP,512);
1103 jz_writew(USB_REG_INCSR,0x2048);
1104 jz_writeb(USB_REG_INDEX,1);
1105 jz_writew(USB_REG_OUTMAXP,512);
1106 jz_writew(USB_REG_OUTCSR,0x0090);
1107 jz_writew(USB_REG_INTRINE,0x3); //enable intr
1108 jz_writew(USB_REG_INTROUTE,0x2);
1109 jz_writeb(USB_REG_INTRUSBE,0x4);
1110
1111 if ((jz_readb(USB_REG_POWER)&0x10)==0)
1112 {
1113 jz_writeb(USB_REG_INDEX,1);
1114 jz_writew(USB_REG_INMAXP,64);
1115 jz_writew(USB_REG_INCSR,0x2048);
1116 jz_writeb(USB_REG_INDEX,1);
1117 jz_writew(USB_REG_OUTMAXP,64);
1118 jz_writew(USB_REG_OUTCSR,0x0090);
1119 USB_Version=USB_FS;
1120 fifosize[1]=64;
1121 EP0_init(1,64,1,64);
1122 }
1123 else
1124 { 462 {
1125 jz_writeb(USB_REG_INDEX,1); 463 case 0:
1126 jz_writew(USB_REG_INMAXP,512); 464 REG_USB_REG_TESTMODE &= ~USB_TEST_ALL;
1127 jz_writew(USB_REG_INCSR,0x2048);
1128 jz_writeb(USB_REG_INDEX,1);
1129 jz_writew(USB_REG_OUTMAXP,512);
1130 jz_writew(USB_REG_OUTCSR,0x0090);
1131 USB_Version=USB_HS;
1132 fifosize[1]=512;
1133 EP0_init(1,512,1,512);
1134 }
1135
1136}
1137
1138void usbHandleStandDevReq(u8 *buf)
1139{
1140 USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
1141 switch (dreq->bRequest) {
1142 case GET_DESCRIPTOR:
1143 if (dreq->bmRequestType == 0x80) /* Dev2Host */
1144 switch(dreq->wValue >> 8)
1145 {
1146 case DEVICE_DESCRIPTOR:
1147 sendDevDesc(dreq->wLength);
1148 break;
1149 case CONFIGURATION_DESCRIPTOR:
1150 sendConfDesc(dreq->wLength);
1151 break;
1152 case STRING_DESCRIPTOR:
1153 if (dreq->wLength == 0x02)
1154 HW_SendPKT(0, "\x04\x03", 2);
1155 else
1156 sendDevDescString(dreq->wLength);
1157 //HW_SendPKT(0, "\x04\x03\x09\x04", 2);
1158 break;
1159 }
1160 ep0state=USB_EP0_TX;
1161
1162 break;
1163 case SET_ADDRESS:
1164 jz_writeb(USB_REG_FADDR,dreq->wValue);
1165 break;
1166 case GET_STATUS:
1167 switch (dreq->bmRequestType) {
1168 case 80: /* device */
1169 HW_SendPKT(0, "\x01\x00", 2);
1170 break; 465 break;
1171 case 81: /* interface */ 466 case 1:
1172 case 82: /* ep */ 467 REG_USB_REG_TESTMODE |= USB_TEST_J;
1173 HW_SendPKT(0, "\x00\x00", 2);
1174 break; 468 break;
1175 } 469 case 2:
1176 ep0state=USB_EP0_TX; 470 REG_USB_REG_TESTMODE |= USB_TEST_K;
1177 break;
1178 case CLEAR_FEATURE:
1179 case SET_CONFIGURATION:
1180 case SET_INTERFACE:
1181 case SET_FEATURE:
1182 break;
1183 }
1184}
1185
1186unsigned char nandbuffer[4096];
1187extern void jz_nand_read(int block, int page, unsigned char *buf);
1188
1189void usbHandleVendorReq(u8 *buf)
1190{
1191 USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
1192 switch (dreq->bRequest)
1193 {
1194 case 0xB0:
1195 memset(&nandbuffer, 0, 4096);
1196 jz_nand_read(dreq->wValue, dreq->wIndex, nandbuffer);
1197 //printf("Read block %d page %d", dreq->wValue, dreq->wIndex);
1198 udc_state = IDLE;
1199 break; 471 break;
1200 case 0xAB: 472 case 3:
1201 Enable_DMA(nandbuffer, 4096); 473 REG_USB_REG_TESTMODE |= USB_TEST_SE0NAK;
1202 //HW_SendPKT(1, nandbuffer, 4096);
1203 //printf("Send data");
1204 //udc_state = BULK_OUT;
1205 break; 474 break;
1206 case 0x12: 475 case 4:
1207 HW_SendPKT(0, "TEST", 4); 476 REG_USB_REG_TESTMODE |= USB_TEST_PACKET;
1208 //printf("Send test");
1209 udc_state = IDLE;
1210 break; 477 break;
1211 } 478 }
1212} 479}
1213 480
1214void Handshake_PKT(void) 481int usb_drv_port_speed(void)
1215{
1216 if (udc_state!=IDLE)
1217 {
1218 HW_SendPKT(1,(u8 *)handshake_PKT,sizeof(handshake_PKT));
1219 udc_state = IDLE;
1220 }
1221}
1222
1223void usbHandleDevReq(u8 *buf)
1224{ 482{
1225 switch ((buf[0] & (3 << 5)) >> 5) { 483 return ((REG_USB_REG_POWER & USB_POWER_HSMODE) != 0) ? 1 : 0;
1226 case 0: /* Standard request */
1227 usbHandleStandDevReq(buf);
1228 break;
1229 case 1: /* Class request */
1230 break;
1231 case 2: /* Vendor request */
1232 usbHandleVendorReq(buf);
1233 break;
1234 }
1235} 484}
1236 485
1237void EP0_Handler (void) 486void usb_drv_cancel_all_transfers(void)
1238{ 487{
1239 u8 byCSR0; 488 DEBUGF("usb_drv_cancel_all_transfers()");
1240
1241/* Read CSR0 */
1242 jz_writeb(USB_REG_INDEX, 0);
1243 byCSR0 = jz_readb(USB_REG_CSR0);
1244
1245/* Check for SentStall
1246 if sendstall is set ,clear the sendstall bit*/
1247 if (byCSR0 & USB_CSR0_SENTSTALL)
1248 {
1249 jz_writeb(USB_REG_CSR0, (byCSR0 & ~USB_CSR0_SENDSTALL));
1250 ep0state = USB_EP0_IDLE;
1251 return;
1252 }
1253
1254/* Check for SetupEnd */
1255 if (byCSR0 & USB_CSR0_SETUPEND)
1256 {
1257 jz_writeb(USB_REG_CSR0, (byCSR0 | USB_CSR0_SVDSETUPEND));
1258 ep0state = USB_EP0_IDLE;
1259 return;
1260 }
1261/* Call relevant routines for endpoint 0 state */
1262 if (ep0state == USB_EP0_IDLE)
1263 {
1264 if (byCSR0 & USB_CSR0_OUTPKTRDY) //There are datas in fifo
1265 {
1266 USB_DeviceRequest *dreq;
1267 fifo=fifoaddr[0];
1268 udcReadFifo((u8 *)rx_buf, sizeof(USB_DeviceRequest));
1269 usb_setb(USB_REG_CSR0, 0x48);//clear OUTRD bit
1270 dreq = (USB_DeviceRequest *)rx_buf;
1271 usbHandleDevReq((u8 *)rx_buf);
1272 }
1273 rx_size = 0;
1274 }
1275 489
1276 if (ep0state == USB_EP0_TX) 490 unsigned int i;
491 for(i=0; i<TOTAL_EP(); i++)
1277 { 492 {
1278 fifo=fifoaddr[0]; 493 endpoints[i].sent = 0;
1279 if (tx_size - finished <= 64) 494 endpoints[i].length = 0;
1280 { 495 /* TODO: flush FIFO's ? */
1281 udcWriteFifo((u8 *)((u32)tx_buf+finished),
1282 tx_size - finished);
1283 finished = tx_size;
1284 usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY);
1285 usb_setb(USB_REG_CSR0, USB_CSR0_DATAEND); //Set dataend!
1286 ep0state=USB_EP0_IDLE;
1287 } else
1288 {
1289 udcWriteFifo((u8 *)((u32)tx_buf+finished), 64);
1290 usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY);
1291 finished += 64;
1292 }
1293 }
1294 return;
1295}
1296
1297void EPIN_Handler(u8 EP)
1298{
1299 jz_writeb(USB_REG_INDEX, EP);
1300 fifo = fifoaddr[EP];
1301
1302 if (Bulk_in_size-Bulk_in_finish==0)
1303 {
1304 Handshake_PKT();
1305 return;
1306 }
1307
1308 if (Bulk_in_size - Bulk_in_finish <= fifosize[EP])
1309 {
1310 udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish),
1311 Bulk_in_size - Bulk_in_finish);
1312 usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY);
1313 Bulk_in_finish = Bulk_in_size;
1314 }
1315 else
1316 {
1317 udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish),
1318 fifosize[EP]);
1319 usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY);
1320 Bulk_in_finish += fifosize[EP];
1321 }
1322}
1323
1324void EPOUT_Handler(u8 EP)
1325{
1326 u32 size;
1327 jz_writeb(USB_REG_INDEX, EP);
1328 size = jz_readw(USB_REG_OUTCOUNT);
1329 fifo = fifoaddr[EP];
1330 udcReadFifo((u8 *)((u32)Bulk_out_buf+Bulk_out_size), size);
1331 usb_clearb(USB_REG_OUTCSR,USB_OUTCSR_OUTPKTRDY);
1332 Bulk_out_size += size;
1333}
1334
1335void UDC(void)
1336{
1337 u8 IntrUSB;
1338 u16 IntrIn;
1339 u16 IntrOut;
1340 u16 IntrDMA;
1341/* Read interrupt registers */
1342 IntrUSB = jz_readb(USB_REG_INTRUSB);
1343 IntrIn = jz_readw(USB_REG_INTRIN);
1344 IntrOut = jz_readw(USB_REG_INTROUT);
1345 IntrDMA = jz_readb(USB_REG_INTR);
1346
1347 if ( IntrUSB == 0 && IntrIn == 0 && IntrOut == 0)
1348 return;
1349
1350 if (IntrIn & 2)
1351 {
1352 EPIN_Handler(1);
1353 }
1354 if (IntrOut & 2)
1355 {
1356 EPOUT_Handler(1);
1357 }
1358 if (IntrUSB & USB_INTR_RESET)
1359 {
1360 udc_reset();
1361 }
1362
1363/* Check for endpoint 0 interrupt */
1364 if (IntrIn & USB_INTR_EP0)
1365 {
1366 EP0_Handler();
1367 }
1368
1369 if (IntrDMA & 0x1) //channel 1 :OUT
1370 {
1371 if (tx_size > 0 && tx_size % fifosize[1] != 0)
1372 {
1373 jz_writeb(USB_REG_INDEX, 1);
1374 usb_clearb(USB_REG_INCSR, USB_INCSR_INPKTRDY);
1375 }
1376 Disable_DMA();
1377 } 496 }
497
498 ep0state = USB_EP0_IDLE;
1378} 499}
1379 500
1380void __udc_start(void) 501void usb_drv_release_endpoint(int ep)
1381{ 502{
1382 udc_reset(); 503 //DEBUGF("usb_drv_release_endpoint(%d)", ep);
1383 504
1384 ep0state = USB_EP0_IDLE; 505 (void)ep;
1385 Bulk_in_size = 0;
1386 Bulk_in_finish = 0;
1387 Bulk_out_size = 0;
1388 udc_state = IDLE;
1389 tx_size = 0;
1390 rx_size = 0;
1391 finished = 0;
1392
1393 if ((jz_readb(USB_REG_POWER)&0x10)==0)
1394 {
1395 USB_Version=USB_FS;
1396 fifosize[1]=64;
1397 EP0_init(1,64,1,64);
1398 }
1399 else
1400 {
1401 USB_Version=USB_HS;
1402 fifosize[1]=512;
1403 EP0_init(1,512,1,512);
1404 }
1405
1406 USB_Version=USB_HS;
1407 system_enable_irq(IRQ_UDC);
1408} 506}
1409 507
1410void usb_init_device(void) 508int usb_drv_request_endpoint(int dir)
1411{ 509{
1412 REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; 510 DEBUGF("usb_drv_request_endpoint(%d)", dir);
1413 REG_USB_REG_POWER |= USB_POWER_SOFTCONN; 511
1414 __udc_start(); 512 (void)dir;
513 return -1;
1415} 514}
1416
1417#endif