summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-05-22 15:34:24 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-05-22 15:34:24 +0000
commite7075db2a76425051b2ecfdd14f14b07384c7e08 (patch)
treeea8d3c314b96d33451aa0c67780505076c4845e7
parent213e7d847245f9ac61a64497424faeac0e22b4a2 (diff)
downloadrockbox-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.c2
-rw-r--r--firmware/target/arm/i2s-pp.c60
-rw-r--r--firmware/target/arm/pcm-pp.c23
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}