diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-05-22 15:34:24 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-05-22 15:34:24 +0000 |
commit | e7075db2a76425051b2ecfdd14f14b07384c7e08 (patch) | |
tree | ea8d3c314b96d33451aa0c67780505076c4845e7 | |
parent | 213e7d847245f9ac61a64497424faeac0e22b4a2 (diff) | |
download | rockbox-e7075db2a76425051b2ecfdd14f14b07384c7e08.tar.gz rockbox-e7075db2a76425051b2ecfdd14f14b07384c7e08.zip |
e200: Use 16-16 L-R pairs when writing to the TX FIFO. Kill the channel swapping and clicks. Reduce number of FIQs. Should be adaptable to iPods and other PP targets in a few minutes work, eh?
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13463 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/drivers/audio/as3514.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/i2s-pp.c | 60 | ||||
-rw-r--r-- | firmware/target/arm/pcm-pp.c | 23 |
3 files changed, 68 insertions, 17 deletions
diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c index 771275e8fa..d068e08081 100644 --- a/firmware/drivers/audio/as3514.c +++ b/firmware/drivers/audio/as3514.c | |||
@@ -106,7 +106,7 @@ int audiohw_init(void) | |||
106 | as3514_write(HPH_OUT_L, 0x16); /* set default vol for headphone */ | 106 | as3514_write(HPH_OUT_L, 0x16); /* set default vol for headphone */ |
107 | as3514_write(LINE_IN1_R, 0x36); /* unmute lineIn 1 and set gain */ | 107 | as3514_write(LINE_IN1_R, 0x36); /* unmute lineIn 1 and set gain */ |
108 | as3514_write(LINE_IN1_L, 0x36); /* unmute lineIn 1 and set gain */ | 108 | as3514_write(LINE_IN1_L, 0x36); /* unmute lineIn 1 and set gain */ |
109 | as3514_write(PLLMODE, 0x04); | 109 | as3514_write(PLLMODE, 0x00); |
110 | 110 | ||
111 | /* read all reg values */ | 111 | /* read all reg values */ |
112 | for (i = 0; i < sizeof(as3514_regs) / sizeof(int); i++) | 112 | for (i = 0; i < sizeof(as3514_regs) / sizeof(int); i++) |
diff --git a/firmware/target/arm/i2s-pp.c b/firmware/target/arm/i2s-pp.c index a2a74bf72b..c63287b72b 100644 --- a/firmware/target/arm/i2s-pp.c +++ b/firmware/target/arm/i2s-pp.c | |||
@@ -46,20 +46,58 @@ void i2s_reset(void) | |||
46 | } | 46 | } |
47 | #else /* PP502X */ | 47 | #else /* PP502X */ |
48 | 48 | ||
49 | /* All I2S formats send MSB first */ | ||
50 | |||
49 | /* Data format on the I2S bus */ | 51 | /* Data format on the I2S bus */ |
50 | #define FORMAT_MASK (0x3 << 10) | 52 | #define FORMAT_MASK (0x3 << 10) |
51 | #define FORMAT_I2S (0x00 << 10) | 53 | #define FORMAT_I2S (0x0 << 10) /* Standard I2S - leading dummy bit */ |
52 | /* Other formats not yet known */ | 54 | #define FORMAT_1 (0x1 << 10) |
55 | #define FORMAT_LJUST (0x2 << 10) /* Left justified - no dummy bit */ | ||
56 | #define FORMAT_3 (0x3 << 10) | ||
57 | /* Other formats not yet known */ | ||
53 | 58 | ||
54 | /* Data size on I2S bus */ | 59 | /* Data size on I2S bus */ |
55 | #define SIZE_MASK (0x3 << 8) | 60 | #define SIZE_MASK (0x3 << 8) |
56 | #define SIZE_16BIT (0x00 << 10) | 61 | #define SIZE_16BIT (0x0 << 8) |
57 | /* Other sizes not yet known */ | 62 | /* Other sizes not yet known */ |
58 | 63 | ||
59 | /* Data size/format on I2S FIFO */ | 64 | /* Data size/format on I2S FIFO */ |
60 | #define FIFO_FORMAT_MASK (0x7 << 4) | 65 | #define FIFO_FORMAT_MASK (0x7 << 4) |
61 | #define FIFO_FORMAT_32LSB (0x03 << 4) | 66 | #define FIFO_FORMAT_0 (0x0 << 4) |
62 | /* Other formats not yet known */ | 67 | /* Big-endian formats - data sent to the FIFO must be big endian. |
68 | * I forgot which is which size but did test them. */ | ||
69 | #define FIFO_FORMAT_1 (0x1 << 4) | ||
70 | #define FIFO_FORMAT_2 (0x2 << 4) | ||
71 | /* 32bit-MSB-little endian */ | ||
72 | #define FIFO_FORMAT_LE32 (0x3 << 4) | ||
73 | /* 16bit-MSB-little endian */ | ||
74 | #define FIFO_FORMAT_LE16 (0x4 << 4) | ||
75 | |||
76 | /* FIFO formats 0x5 and above seem equivalent to 0x4 ?? */ | ||
77 | |||
78 | /** | ||
79 | * PP502x | ||
80 | * | ||
81 | * IISCONFIG bits: | ||
82 | * | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | | ||
83 | * | RESET | |TXFIFOEN|RXFIFOEN| | ???? | MS | ???? | | ||
84 | * | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | | ||
85 | * | | | | | | | | | | ||
86 | * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | | ||
87 | * | | | | | Bus Format[1:0] | Size[1:0] | | ||
88 | * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | ||
89 | * | | Size Format[2:0] | ???? | ???? | IRQTX | IRQRX | | ||
90 | * | ||
91 | * IISFIFO_CFG bits: | ||
92 | * | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | | ||
93 | * | | Free[6:0] | | ||
94 | * | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | | ||
95 | * | | | | | | | | | | ||
96 | * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | | ||
97 | * | | | | RXCLR | | | | TXCLR | | ||
98 | * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | ||
99 | * | | | RX_ATN_LEVEL | | | TX_ATN_LEVEL | | ||
100 | */ | ||
63 | 101 | ||
64 | /* Are we I2S Master or slave? */ | 102 | /* Are we I2S Master or slave? */ |
65 | #define I2S_MASTER (1<<25) | 103 | #define I2S_MASTER (1<<25) |
@@ -83,12 +121,16 @@ void i2s_reset(void) | |||
83 | 121 | ||
84 | /* FIFO.FORMAT */ | 122 | /* FIFO.FORMAT */ |
85 | /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */ | 123 | /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */ |
86 | IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_32LSB); | ||
87 | #ifdef HAVE_AS3514 | 124 | #ifdef HAVE_AS3514 |
88 | /* AS3514 can only operate as I2S Slave */ | 125 | /* AS3514 can only operate as I2S Slave */ |
89 | IISCONFIG |= I2S_MASTER; | 126 | IISCONFIG |= I2S_MASTER; |
90 | /* Set I2S to 44.1kHz */ | 127 | /* Set I2S to 44.1kHz */ |
91 | outl((inl(0x70002808) & ~(0x1ff)) | 271, 0x70002808); | 128 | outl((inl(0x70002808) & ~(0x1ff)) | 33, 0x70002808); |
129 | outl(7, 0x60006080); | ||
130 | |||
131 | IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_LE16); | ||
132 | #else | ||
133 | IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_LE32); | ||
92 | #endif | 134 | #endif |
93 | 135 | ||
94 | /* RX_ATN_LVL=1 == when 12 slots full */ | 136 | /* RX_ATN_LVL=1 == when 12 slots full */ |
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index e483700e88..41bd92bd0d 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c | |||
@@ -93,13 +93,7 @@ void fiq(void) | |||
93 | "bls .fifo_full \n\t" /* FIFO full, exit */ | 93 | "bls .fifo_full \n\t" /* FIFO full, exit */ |
94 | "ldr r10, [r9], #4 \n\t" /* load two samples */ | 94 | "ldr r10, [r9], #4 \n\t" /* load two samples */ |
95 | #ifdef HAVE_AS3514 | 95 | #ifdef HAVE_AS3514 |
96 | /* The AS3514 reads 3 bytes at a time, it seems, ignoring the lowest. | 96 | "str r10, [r12, #0x40]\n\t" /* write them */ |
97 | This code seems to work well, but we may have to mask off the extra | ||
98 | bits - at the expense of a few extra cycles in the FIQ */ | ||
99 | "mov r10, r10, ror #2\n\t" /* put left sample at the top bits */ | ||
100 | "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */ | ||
101 | "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */ | ||
102 | "str r10, [r12, #0x40]\n\t" /* then write it */ | ||
103 | #else | 97 | #else |
104 | "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */ | 98 | "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */ |
105 | "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */ | 99 | "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */ |
@@ -184,8 +178,13 @@ void fiq(void) | |||
184 | return; | 178 | return; |
185 | } | 179 | } |
186 | 180 | ||
181 | #ifdef HAVE_AS3514 | ||
182 | IISFIFO_WR = *(int32_t *)p; | ||
183 | p += 2; | ||
184 | #else | ||
187 | IISFIFO_WR = (*(p++))<<16; | 185 | IISFIFO_WR = (*(p++))<<16; |
188 | IISFIFO_WR = (*(p++))<<16; | 186 | IISFIFO_WR = (*(p++))<<16; |
187 | #endif | ||
189 | p_size-=4; | 188 | p_size-=4; |
190 | } | 189 | } |
191 | 190 | ||
@@ -240,8 +239,13 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
240 | return; | 239 | return; |
241 | } | 240 | } |
242 | 241 | ||
242 | #ifdef HAVE_AS3514 | ||
243 | IISFIFO_WR = *(int32_t *)p; | ||
244 | p += 2; | ||
245 | #else | ||
243 | IISFIFO_WR = (*(p++))<<16; | 246 | IISFIFO_WR = (*(p++))<<16; |
244 | IISFIFO_WR = (*(p++))<<16; | 247 | IISFIFO_WR = (*(p++))<<16; |
248 | #endif | ||
245 | p_size-=4; | 249 | p_size-=4; |
246 | } | 250 | } |
247 | } | 251 | } |
@@ -315,8 +319,13 @@ void pcm_play_pause_unpause(void) | |||
315 | return; | 319 | return; |
316 | } | 320 | } |
317 | 321 | ||
322 | #ifdef HAVE_AS3514 | ||
323 | IISFIFO_WR = *(int32_t *)p; | ||
324 | p += 2; | ||
325 | #else | ||
318 | IISFIFO_WR = (*(p++))<<16; | 326 | IISFIFO_WR = (*(p++))<<16; |
319 | IISFIFO_WR = (*(p++))<<16; | 327 | IISFIFO_WR = (*(p++))<<16; |
328 | #endif | ||
320 | p_size-=4; | 329 | p_size-=4; |
321 | } | 330 | } |
322 | } | 331 | } |