summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/s5l8700/boot.lds10
-rw-r--r--firmware/target/arm/s5l8700/crt0.S14
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/button-nano2g.c44
-rw-r--r--firmware/target/arm/s5l8700/pcm-s5l8700.c47
-rw-r--r--firmware/target/arm/s5l8700/system-s5l8700.c7
-rw-r--r--firmware/target/arm/s5l8700/wmcodec-s5l8700.c46
6 files changed, 152 insertions, 16 deletions
diff --git a/firmware/target/arm/s5l8700/boot.lds b/firmware/target/arm/s5l8700/boot.lds
index 28271822e8..12f03ef463 100644
--- a/firmware/target/arm/s5l8700/boot.lds
+++ b/firmware/target/arm/s5l8700/boot.lds
@@ -9,12 +9,16 @@ OUTPUT_FORMAT(elf32-bigarm)
OUTPUT_ARCH(arm)
STARTUP(target/arm/s5l8700/crt0.o)
-/* DRAMORIG is in fact 0x8000000 but remapped to 0x0 */
-#define DRAMORIG 0x8000000
-#define DRAMSIZE 16M
+/* DRAMORIG is in fact 0x08000000 but remapped to 0x0 */
+#define DRAMORIG 0x08000000
+#define DRAMSIZE (MEMORYSIZE * 0x100000)
#define IRAMORIG 0x22000000
+#if CONFIG_CPU==S5L8701
+#define IRAMSIZE 176K
+#else
#define IRAMSIZE 256K
+#endif
#ifdef MEIZU_M6SL
#define DFULOADADDR IRAMORIG
diff --git a/firmware/target/arm/s5l8700/crt0.S b/firmware/target/arm/s5l8700/crt0.S
index c6e201e73f..bb374ae5a4 100644
--- a/firmware/target/arm/s5l8700/crt0.S
+++ b/firmware/target/arm/s5l8700/crt0.S
@@ -82,6 +82,9 @@ newstart2:
// orr r0, r0, r2
// str r0, [r1] // switch backlight on
+#ifndef IPOD_NANO2G
+/* Currently disabled for the Nano2G as it doesn't appear to be
+ correct - e.g. audio doesn't work with this code enabled. */
ldr r1, =0x3c500000 // CLKCON
ldr r0, =0x00800080
str r0, [r1]
@@ -90,7 +93,7 @@ newstart2:
str r0, [r1]
ldr r1, =0x3c500004 // PLL0PMS
#ifdef IPOD_NANO2G
- ldr r0, =0x21200
+ ldr r0, =0x21200 // pdiv=2, mdiv=?? sdiv=0
#else
ldr r0, =0x1ad200
#endif
@@ -123,7 +126,8 @@ newstart2:
nop
nop
nop
-
+#endif
+
// ldr r0, =0x10100000
// ldr r1, =0x38200034
// str r0, [r1] // SRAM0/1 data width 16 bit
@@ -143,7 +147,7 @@ newstart2:
str r0, [r1, #40] // enable clock for all peripherals
mov r0, #0 // 0x0
str r0, [r1, #44] // do not enter any power saving mode
-
+
mov r1, #0x1
mrc 15, 0, r0, c1, c0, 0
bic r0, r0, r1
@@ -186,7 +190,7 @@ newstart2:
mcr 15, 0, r0, c6, c0, 1
mov r0, #0x2f
mcr 15, 0, r0, c6, c1, 1
- ldr r0, =0x0800002f
+ ldr r0, =0x08000031
mcr 15, 0, r0, c6, c2, 1
ldr r0, =0x22000023
mcr 15, 0, r0, c6, c3, 1
@@ -196,7 +200,7 @@ newstart2:
mcr 15, 0, r0, c6, c0, 0
mov r0, #0x2f
mcr 15, 0, r0, c6, c1, 0
- ldr r0, =0x0800002f
+ ldr r0, =0x08000031
mcr 15, 0, r0, c6, c2, 0
ldr r0, =0x22000023
mcr 15, 0, r0, c6, c3, 0
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/button-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/button-nano2g.c
index 8049028a59..739b48b511 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/button-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/button-nano2g.c
@@ -25,16 +25,58 @@
#include "s5l8700.h"
#include "button-target.h"
+#define CLICKWHEEL00 (*(volatile unsigned long*)(0x3c200000))
+#define CLICKWHEEL10 (*(volatile unsigned long*)(0x3c200010))
+#define CLICKWHEELINT (*(volatile unsigned long*)(0x3c200014))
+#define CLICKWHEEL_DATA (*(volatile unsigned long*)(0x3c200018))
+
+static int buttons = 0;
+
+void INT_SPI(void)
+{
+ int clickwheel_events;
+ int btn =0;
+ int status;
+
+ clickwheel_events = CLICKWHEELINT;
+
+ if (clickwheel_events & 4) CLICKWHEELINT = 4;
+ if (clickwheel_events & 2) CLICKWHEELINT = 2;
+ if (clickwheel_events & 1) CLICKWHEELINT = 1;
+
+ status = CLICKWHEEL_DATA;
+ if ((status & 0x800000ff) == 0x8000001a)
+ {
+ if (status & 0x00000100)
+ btn |= BUTTON_SELECT;
+ if (status & 0x00000200)
+ btn |= BUTTON_RIGHT;
+ if (status & 0x00000400)
+ btn |= BUTTON_LEFT;
+ if (status & 0x00000800)
+ btn |= BUTTON_PLAY;
+ if (status & 0x00001000)
+ btn |= BUTTON_MENU;
+ }
+
+ buttons = btn;
+}
+
void button_init_device(void)
{
+ CLICKWHEEL00 = 0x280000;
+ CLICKWHEEL10 = 3;
+ INTMOD = 0;
+ INTMSK |= (1<<26);
+ PCON10 &= ~0xF00;
}
int button_read_device(void)
{
+ return buttons;
}
bool button_hold(void)
{
return ((PDAT14 & (1 << 6)) == 0);
}
-
diff --git a/firmware/target/arm/s5l8700/pcm-s5l8700.c b/firmware/target/arm/s5l8700/pcm-s5l8700.c
index 7a4bdeb174..9421956131 100644
--- a/firmware/target/arm/s5l8700/pcm-s5l8700.c
+++ b/firmware/target/arm/s5l8700/pcm-s5l8700.c
@@ -48,7 +48,11 @@ static const struct div_entry {
int pdiv, mdiv, sdiv, cdiv;
} div_table[HW_NUM_FREQ] = {
[HW_FREQ_11] = { 26, 189, 3, 8},
+#ifdef IPOD_NANO2G
+ [HW_FREQ_22] = { 5, 6, 3, 4},
+#else
[HW_FREQ_22] = { 50, 98, 2, 8},
+#endif
[HW_FREQ_44] = { 37, 151, 1, 9},
[HW_FREQ_88] = { 50, 98, 1, 4},
#if 0 /* disabled because the codec driver does not support it (yet) */
@@ -116,6 +120,17 @@ void pcm_play_dma_start(const void *addr, size_t size)
DMA_IISOUT_DSIZE, DMA_IISOUT_BLEN, (void *)addr, size / 2,
dma_callback);
+#ifdef IPOD_NANO2G
+ I2STXCON = (0x10 << 16) | /* burst length */
+ (0 << 15) | /* 0 = falling edge */
+ (0 << 13) | /* 0 = basic I2S format */
+ (0 << 12) | /* 0 = MSB first */
+ (0 << 11) | /* 0 = left channel for low polarity */
+ (5 << 8) | /* MCLK divider */
+ (0 << 5) | /* 0 = 16-bit */
+ (2 << 3) | /* bit clock per frame */
+ (1 << 0); /* channel index */
+#else
/* S2: IIS Tx mode set */
I2STXCON = (DMA_IISOUT_BLEN << 16) | /* burst length */
(0 << 15) | /* 0 = falling edge */
@@ -126,6 +141,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
(0 << 5) | /* 0 = 16-bit */
(0 << 3) | /* bit clock per frame */
(1 << 0); /* channel index */
+#endif
/* S3: DMA channel 0 on */
dma_enable_channel(DMA_IISOUT_CHANNEL);
@@ -169,7 +185,12 @@ void pcm_play_dma_pause(bool pause)
void pcm_play_dma_init(void)
{
/* configure IIS pins */
+#ifdef IPOD_NANO2G
+ PCON5 = (PCON5 & ~(0xFFFFF000)) | 0x22220000;
+ PCON6 = (PCON6 & ~(0x0F000000)) | 0x02000000;
+#else
PCON7 = (PCON7 & ~(0x0FFFFF00)) | 0x02222200;
+#endif
/* enable clock to the IIS module */
PWRCON &= ~(1 << 6);
@@ -185,26 +206,42 @@ void pcm_postinit(void)
/* set the configured PCM frequency */
void pcm_dma_apply_settings(void)
{
- audiohw_set_frequency(pcm_sampr);
+ // audiohw_set_frequency(pcm_sampr);
struct div_entry div = div_table[pcm_fsel];
-
+
+ PLLCON &= ~4;
+ PLLCON &= ~0x10;
+ PLLCON &= 0x3f;
+ PLLCON |= 4;
+
/* configure PLL1 and MCLK for the desired sample rate */
+#ifdef IPOD_NANO2G
+ PLL1PMS = (2 << 16) | /* PDIV */
+ (12 << 8) | /* MDIV */
+ (2 << 0); /* SDIV */
+ PLL1LCNT = 0x4d2;
+#else
PLL1PMS = (div.pdiv << 16) |
(div.mdiv << 8) |
(div.sdiv << 0);
PLL1LCNT = 7500; /* no idea what to put here */
-
+#endif
+
/* enable PLL1 and wait for lock */
PLLCON |= (1 << 1);
while ((PLLLOCK & (1 << 1)) == 0);
/* configure MCLK */
- CLKCON = (CLKCON & ~(0xFF)) |
+ CLKCON = (CLKCON & ~(0xFF)) |
(0 << 7) | /* MCLK_MASK */
- (2 << 5) | /* MCLK_SEL = PLL1 */
+ (2 << 5) | /* MCLK_SEL = PLL2 */
(1 << 4) | /* MCLK_DIV_ON */
+#ifdef IPOD_NANO2G
+ (3 - 1); /* MCLK_DIV_VAL */
+#else
(div.cdiv - 1); /* MCLK_DIV_VAL */
+#endif
}
size_t pcm_get_bytes_waiting(void)
diff --git a/firmware/target/arm/s5l8700/system-s5l8700.c b/firmware/target/arm/s5l8700/system-s5l8700.c
index 48c50645e9..a282c45235 100644
--- a/firmware/target/arm/s5l8700/system-s5l8700.c
+++ b/firmware/target/arm/s5l8700/system-s5l8700.c
@@ -96,12 +96,15 @@ void irq_handler(void)
"sub sp, sp, #8 \n"); /* Reserve stack */
int irq_no = INTOFFSET;
+ int sources = SRCPND;
+
+ if (irq_no==10) { INTMSK &= ~(1<<10); }
irqvector[irq_no]();
/* clear interrupt */
- SRCPND = (1 << irq_no);
- INTPND = INTPND;
+ SRCPND = sources;
+ INTPND = sources;
asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */
"ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */
diff --git a/firmware/target/arm/s5l8700/wmcodec-s5l8700.c b/firmware/target/arm/s5l8700/wmcodec-s5l8700.c
new file mode 100644
index 0000000000..3c7c24994d
--- /dev/null
+++ b/firmware/target/arm/s5l8700/wmcodec-s5l8700.c
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * TCC specific code for Wolfson audio codecs
+ *
+ * Based on code from the ipodlinux project - http://ipodlinux.org/
+ * Adapted for Rockbox in December 2005
+ *
+ * Original file: linux/arch/armnommu/mach-ipod/audio.c
+ *
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "system.h"
+#include "audiohw.h"
+#include "i2c-s5l8700.h"
+#include "wmcodec.h"
+
+void audiohw_init(void)
+{
+#if defined(HAVE_WM8731) || defined(HAVE_WM8751) || defined(HAVE_WM8985)
+ audiohw_preinit();
+#endif
+}
+
+void wmcodec_write(int reg, int data)
+{
+ unsigned char d = data & 0xff;
+
+ i2c_write(0x34, (reg << 1) | ((data & 0x100) >> 8), 1, &d);
+}