summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/imx233/adc-imx233.c34
-rw-r--r--firmware/target/arm/imx233/adc-target.h (renamed from firmware/target/arm/imx233/sansa-fuzeplus/adc-target.h)0
-rw-r--r--firmware/target/arm/imx233/app.lds119
-rw-r--r--firmware/target/arm/imx233/crt0.S34
-rw-r--r--firmware/target/arm/imx233/debug-imx233.c33
-rw-r--r--firmware/target/arm/imx233/debug-target.h30
-rw-r--r--firmware/target/arm/imx233/dma-imx233.c48
-rw-r--r--firmware/target/arm/imx233/dma-imx233.h15
-rw-r--r--firmware/target/arm/imx233/i2c-imx233.c2
-rw-r--r--firmware/target/arm/imx233/i2c-imx233.h2
-rw-r--r--firmware/target/arm/imx233/power-imx233.c46
-rw-r--r--firmware/target/arm/imx233/powermgmt-imx233.c34
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/button-target.h12
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/debug-fuzeplus.c28
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c19
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c32
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/power-fuzeplus.c46
-rw-r--r--firmware/target/arm/imx233/sd-imx233.c134
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.c1
19 files changed, 629 insertions, 40 deletions
diff --git a/firmware/target/arm/imx233/adc-imx233.c b/firmware/target/arm/imx233/adc-imx233.c
new file mode 100644
index 0000000000..8236f58767
--- /dev/null
+++ b/firmware/target/arm/imx233/adc-imx233.c
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * 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 "config.h"
+#include "adc.h"
+#include "adc-target.h"
+
+void adc_init(void)
+{
+}
+
+unsigned short adc_read(int channel)
+{
+ (void) channel;
+ return 0;
+}
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/adc-target.h b/firmware/target/arm/imx233/adc-target.h
index e6b5152f5b..e6b5152f5b 100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/adc-target.h
+++ b/firmware/target/arm/imx233/adc-target.h
diff --git a/firmware/target/arm/imx233/app.lds b/firmware/target/arm/imx233/app.lds
new file mode 100644
index 0000000000..66d0b04391
--- /dev/null
+++ b/firmware/target/arm/imx233/app.lds
@@ -0,0 +1,119 @@
+#include "config.h"
+#include "cpu.h"
+
+ENTRY(start)
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+STARTUP(target/arm/imx233/crt0.o)
+
+#define PLUGINSIZE PLUGIN_BUFFER_SIZE
+#define CODECSIZE CODEC_SIZE
+
+#define DRAMORIG DRAM_ORIG
+#define IRAMORIG IRAM_ORIG
+
+#define IRAMSIZE (IRAM_SIZE - TTB_SIZE)
+
+#define DRAMSIZE (DRAM_SIZE - PLUGINSIZE - CODECSIZE - FRAME_SIZE)
+
+/* End of the audio buffer, where the codec buffer starts */
+#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
+
+/* Where the codec buffer ends, and the plugin buffer starts */
+#define ENDADDR (ENDAUDIOADDR + CODEC_SIZE)
+
+/* INIT section is the codec buffer */
+#define INITSIZE CODEC_SIZE
+#define INITSTART ENDAUDIOADDR
+
+MEMORY
+{
+ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+ DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+}
+
+SECTIONS
+{
+ .text :
+ {
+ loadaddress = .;
+ _loadaddress = .;
+ *(.text*)
+ } > DRAM
+
+ .data :
+ {
+ *(.data*)
+ *(.rodata*)
+ _dataend = . ;
+ } > DRAM
+
+ .iram :
+ {
+ _iramstart = .; // always 0
+ *(.vectors)
+ KEEP(*(.vectors));// otherwise there are no references to it and the linker strip it
+ *(.icode)
+ *(.irodata)
+ *(.idata)
+ . = ALIGN(0x4);
+ _iramend = .;
+ } > IRAM AT> DRAM
+
+ _iramcopy = LOADADDR(.iram);
+
+ .ibss (NOLOAD) :
+ {
+ _iedata = .;
+ *(.qharray)
+ *(.ibss)
+ . = ALIGN(0x4);
+ _iend = .;
+ } > IRAM
+
+ .init ENDAUDIOADDR :
+ {
+ . = ALIGN(4);
+ _initstart = .;
+ *(.init)
+ _initend = .;
+ } AT> DRAM
+
+ _initcopy = LOADADDR(.init);
+
+ .stack (NOLOAD) :
+ {
+ *(.stack)
+ stackbegin = .;
+ . += 0x2000;
+ stackend = .;
+ } > DRAM
+
+ .bss (NOLOAD) :
+ {
+ _edata = .;
+ *(.bss*);
+ _end = .;
+ } > DRAM
+
+ .audiobuf (NOLOAD) :
+ {
+ . = ALIGN(4);
+ _audiobuffer = .;
+ audiobuffer = .;
+ } > DRAM
+
+ .codec ENDAUDIOADDR (NOLOAD) :
+ {
+ audiobufend = .;
+ _audiobufend = .;
+ codecbuf = .;
+ _codecbuf = .;
+ } > DRAM
+
+ .plugin ENDADDR (NOLOAD) :
+ {
+ _pluginbuf = .;
+ pluginbuf = .;
+ }
+}
diff --git a/firmware/target/arm/imx233/crt0.S b/firmware/target/arm/imx233/crt0.S
index b8b63e5f26..a0f9ec270b 100644
--- a/firmware/target/arm/imx233/crt0.S
+++ b/firmware/target/arm/imx233/crt0.S
@@ -39,6 +39,13 @@ start:
/* Save r0 */
mov r6, r0
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
+ /* Disable MMU, disable caching and buffering;
+ * use low exception range address (the core uses high range by default) */
+ mrc p15, 0, r0, c1, c0, 0
+ ldr r1, =0x3005
+ bic r0, r1
+ mcr p15, 0, r0, c1, c0, 0
+
/* Zero out IBSS */
ldr r2, =_iedata
ldr r3, =_iend
@@ -59,6 +66,22 @@ start:
strhi r5, [r3], #4
bhi 1b
+#ifdef HAVE_INIT_ATTR
+ /* copy init data to codec buffer */
+ /* must be done before bss is zeroed */
+ ldr r2, =_initcopy
+ ldr r3, =_initstart
+ ldr r4, =_initend
+1:
+ cmp r4, r3
+ ldrhi r5, [r2], #4
+ strhi r5, [r3], #4
+ bhi 1b
+
+ mov r2, #0
+ mcr p15, 0, r2, c7, c5, 0 @ Invalidate ICache
+#endif
+
/* Initialise bss section to zero */
ldr r2, =_edata
ldr r3, =_end
@@ -68,7 +91,6 @@ start:
strhi r4, [r2], #4
bhi 1b
-
/* Set up some stack and munge it with 0xdeadbeef */
ldr sp, =stackend
ldr r2, =stackbegin
@@ -92,16 +114,12 @@ start:
msr cpsr_c, #0xdb
ldr sp, =irq_stack
+ /* Enable MMU */
+ bl memory_init
+
/* Switch back to supervisor mode */
msr cpsr_c, #0xd3
- /* Disable MMU, disable caching and buffering;
- * use low exception range address (the core uses high range by default) */
- mrc p15, 0, r0, c1, c0, 0
- ldr r1, =0x3005
- bic r0, r1
- mcr p15, 0, r0, c1, c0, 0
-
/* Jump to main */
mov r0, r6
bl main
diff --git a/firmware/target/arm/imx233/debug-imx233.c b/firmware/target/arm/imx233/debug-imx233.c
new file mode 100644
index 0000000000..4cfddb3de8
--- /dev/null
+++ b/firmware/target/arm/imx233/debug-imx233.c
@@ -0,0 +1,33 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * 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 "debug-target.h"
+
+bool dbg_hw_info(void)
+{
+ return false;
+}
+
+bool dbg_ports(void)
+{
+ return false;
+}
diff --git a/firmware/target/arm/imx233/debug-target.h b/firmware/target/arm/imx233/debug-target.h
new file mode 100644
index 0000000000..402514ae83
--- /dev/null
+++ b/firmware/target/arm/imx233/debug-target.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * 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.
+ *
+ ****************************************************************************/
+#ifndef DEBUG_TARGET_H
+#define DEBUG_TARGET_H
+
+#define DEBUG_CANCEL BUTTON_BACK
+
+bool dbg_hw_target_info(void);
+bool dbg_hw_info(void);
+bool dbg_ports(void);
+
+#endif /* DEBUG_TARGET_H */
diff --git a/firmware/target/arm/imx233/dma-imx233.c b/firmware/target/arm/imx233/dma-imx233.c
index d75c334aeb..8a42bd12da 100644
--- a/firmware/target/arm/imx233/dma-imx233.c
+++ b/firmware/target/arm/imx233/dma-imx233.c
@@ -106,8 +106,54 @@ bool imx233_dma_is_channel_error_irq(unsigned chan)
HW_APBH_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan)));
}
+/* Commit and/or discard all DMA descriptors and buffers pointed by them,
+ * handle circular lists */
+static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
+{
+ /* We handle circular descriptors by using unused bits:
+ * bits 8-11 are not used by the hardware so we first go through the whole
+ * list and mark them all a special value at the same time we commit buffers
+ * and then we go through the list another time to clear the mark and
+ * commit the descriptors */
+ struct apb_dma_command_t *cur = cmd;
+
+ while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != HW_APB_CHx_CMD__UNUSED_MAGIC)
+ {
+ cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC;
+ int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM;
+ int sz = (cur->cmd & HW_APB_CHx_CMD__XFER_COUNT_BM) >> HW_APB_CHx_CMD__XFER_COUNT_BP;
+ /* device > host: discard */
+ if(op == HW_APB_CHx_CMD__COMMAND__WRITE)
+ discard_dcache_range(cur->buffer, sz);
+ /* host > device: commit and discard */
+ else if(op == HW_APB_CHx_CMD__COMMAND__READ)
+ commit_discard_dcache_range(cur->buffer, sz);
+ /* chain ? */
+ if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
+ cur = cur->next;
+ else
+ break;
+ }
+
+ cur = cmd;
+ while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0)
+ {
+ cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM;
+ int sz = (cur->cmd & HW_APB_CHx_CMD__CMDWORDS_BM) >> HW_APB_CHx_CMD__CMDWORDS_BP;
+ /* commit descriptor (don't discard since we access it after) */
+ commit_dcache_range(cur,
+ sizeof(struct apb_dma_command_t) + sizeof(uint32_t) * sz);
+ /* chain ? */
+ if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
+ cur = cur->next;
+ else
+ break;
+ }
+}
+
void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
{
+ imx233_dma_commit_and_discard(cmd);
if(APB_IS_APBX_CHANNEL(chan))
{
HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
@@ -129,5 +175,5 @@ void imx233_dma_wait_completion(unsigned chan)
sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
- ;
+ yield();
}
diff --git a/firmware/target/arm/imx233/dma-imx233.h b/firmware/target/arm/imx233/dma-imx233.h
index fcf1a2c5c2..bb88a746d0 100644
--- a/firmware/target/arm/imx233/dma-imx233.h
+++ b/firmware/target/arm/imx233/dma-imx233.h
@@ -138,11 +138,16 @@ struct apb_dma_command_t
#define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5)
#define HW_APB_CHx_CMD__SEMAPHORE (1 << 6)
#define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7)
-#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8)
-#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000
-#define HW_APB_CHx_CMD__CMDWORDS_BP 12
-#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000
-#define HW_APB_CHx_CMD__XFER_COUNT_BP 16
+/* An errata advise not to use it */
+//#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8)
+#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000
+#define HW_APB_CHx_CMD__CMDWORDS_BP 12
+#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000
+#define HW_APB_CHx_CMD__XFER_COUNT_BP 16
+/* For software use */
+#define HW_APB_CHx_CMD__UNUSED_BP 8
+#define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8)
+#define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8)
#define HW_APB_CHx_SEMA__PHORE_BM 0xff0000
#define HW_APB_CHx_SEMA__PHORE_BP 16
diff --git a/firmware/target/arm/imx233/i2c-imx233.c b/firmware/target/arm/imx233/i2c-imx233.c
index 9d29605bce..6fa3182066 100644
--- a/firmware/target/arm/imx233/i2c-imx233.c
+++ b/firmware/target/arm/imx233/i2c-imx233.c
@@ -53,7 +53,7 @@ void INT_I2C_DMA(void)
semaphore_release(&i2c_sema);
}
-void imx233_i2c_init(void)
+void i2c_init(void)
{
__REG_SET(HW_I2C_CTRL0) = __BLOCK_SFTRST | __BLOCK_CLKGATE;
/* setup pins (must be done when shutdown) */
diff --git a/firmware/target/arm/imx233/i2c-imx233.h b/firmware/target/arm/imx233/i2c-imx233.h
index 5ee22efd2a..de90e168f2 100644
--- a/firmware/target/arm/imx233/i2c-imx233.h
+++ b/firmware/target/arm/imx233/i2c-imx233.h
@@ -126,7 +126,7 @@ enum imx233_i2c_error_t
I2C_SLAVE_NAK = -5
};
-void imx233_i2c_init(void);
+void i2c_init(void);
/* start building a transfer, will acquire an exclusive lock */
void imx233_i2c_begin(void);
/* add stage */
diff --git a/firmware/target/arm/imx233/power-imx233.c b/firmware/target/arm/imx233/power-imx233.c
new file mode 100644
index 0000000000..f01a4ad3f2
--- /dev/null
+++ b/firmware/target/arm/imx233/power-imx233.c
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * 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 "config.h"
+#include "system.h"
+#include "power.h"
+#include "system-target.h"
+
+void power_init(void)
+{
+}
+
+void power_off(void)
+{
+ /* power down */
+ HW_POWER_RESET = HW_POWER_RESET__UNLOCK | HW_POWER_RESET__PWD;
+ while(1);
+}
+
+unsigned int power_input_status(void)
+{
+ return POWER_INPUT_NONE;
+}
+
+bool charging_state(void)
+{
+ return false;
+}
diff --git a/firmware/target/arm/imx233/powermgmt-imx233.c b/firmware/target/arm/imx233/powermgmt-imx233.c
new file mode 100644
index 0000000000..f11618b50c
--- /dev/null
+++ b/firmware/target/arm/imx233/powermgmt-imx233.c
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * 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 "powermgmt.h"
+
+void powermgmt_init_target(void)
+{
+}
+
+void charging_algorithm_step(void)
+{
+}
+
+void charging_algorithm_close(void)
+{
+}
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
index f22c06882f..d68bc9eda4 100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
@@ -32,8 +32,18 @@ void button_debug_screen(void);
#define BUTTON_POWER 0x00000001
#define BUTTON_VOL_UP 0x00000002
#define BUTTON_VOL_DOWN 0x00000004
+/* Virtual buttons */
+#define BUTTON_LEFT 0x00000008
+#define BUTTON_UP 0x00000010
+#define BUTTON_RIGHT 0x00000020
+#define BUTTON_DOWN 0x00000040
+#define BUTTON_SELECT 0x00000080
+#define BUTTON_PLAYPAUSE 0x00000100
+#define BUTTON_BACK 0x00000200
-#define BUTTON_MAIN (BUTTON_VOL_UP|BUTTON_VOL_DOWN|BUTTON_POWER)
+#define BUTTON_MAIN (BUTTON_VOL_UP|BUTTON_VOL_DOWN|BUTTON_POWER|BUTTON_LEFT| \
+ BUTTON_UP|BUTTON_RIGHT|BUTTON_DOWN|BUTTON_SELECT| \
+ BUTTON_PLAYPAUSE|BUTTON_BACK)
#define BUTTON_REMOTE 0
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/debug-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/debug-fuzeplus.c
new file mode 100644
index 0000000000..c27f28fe24
--- /dev/null
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/debug-fuzeplus.c
@@ -0,0 +1,28 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * 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 "debug-target.h"
+
+bool dbg_hw_target_info(void)
+{
+ return false;
+}
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c
index 5882a7da9f..d4113332ac 100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c
@@ -85,22 +85,17 @@ struct i2c_interface fmradio_i2c =
.delay_thigh = 4
};
-void fmradio_i2c_init(void)
+void fmradio_i2c_enable(bool enable)
{
+ if(fmradio_i2c_bus == -1)
+ fmradio_i2c_bus = i2c_add_node(&fmradio_i2c);
imx233_set_pin_function(0, 29, PINCTRL_FUNCTION_GPIO);
imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO);
imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO);
- imx233_enable_gpio_output(1, 22, true);
- imx233_enable_gpio_output(1, 24, true);
- imx233_set_gpio_output(1, 22, true);
- imx233_set_gpio_output(1, 24, true);
- fmradio_i2c_bus = i2c_add_node(&fmradio_i2c);
-}
-
-void fmradio_i2c_enable(bool enable)
-{
- imx233_enable_gpio_output(0, 29, enable);
- imx233_set_gpio_output(0, 29, enable);
+ imx233_enable_gpio_output(1, 22, enable);
+ imx233_enable_gpio_output(1, 24, enable);
+ imx233_set_gpio_output(1, 22, enable);
+ imx233_set_gpio_output(1, 24, enable);
}
int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count)
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
index bc8a20d2ff..dba54373be 100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
@@ -29,6 +29,16 @@
#define logf(...)
+/* Copies a rectangle from one framebuffer to another. Can be used in
+ single transfer mode with width = num pixels, and height = 1 which
+ allows a full-width rectangle to be copied more efficiently. */
+extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src,
+ int width, int height);
+
+#ifdef HAVE_LCD_ENABLE
+static bool lcd_on = false;
+#endif
+
static enum lcd_kind_t
{
LCD_KIND_7783 = 0x7783,
@@ -375,7 +385,7 @@ void lcd_init_device(void)
}
}
-
+#ifdef HAVE_LCD_ENABLE
static void lcd_enable_7783(bool enable)
{
if(!enable)
@@ -454,6 +464,10 @@ static void lcd_enable_9325(bool enable)
void lcd_enable(bool enable)
{
+ if(lcd_on == enable)
+ return;
+ lcd_on = enable;
+
if(enable)
common_lcd_enable(true);
switch(lcd_kind)
@@ -466,8 +480,19 @@ void lcd_enable(bool enable)
common_lcd_enable(false);
}
+bool lcd_active(void)
+{
+ return lcd_on;
+}
+#endif
+
void lcd_update(void)
{
+#ifdef HAVE_LCD_ENABLE
+ if(!lcd_on)
+ return;
+#endif
+ imx233_lcdif_wait_ready();
lcd_write_reg(0x50, 0);
lcd_write_reg(0x51, LCD_WIDTH - 1);
lcd_write_reg(0x52, 0);
@@ -479,8 +504,9 @@ void lcd_update(void)
imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_16_BIT);
imx233_lcdif_set_byte_packing_format(0xf); /* two pixels per 32-bit word */
imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */
- imx233_lcdif_dma_send(lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT);
- imx233_lcdif_wait_ready();
+ lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0],
+ LCD_WIDTH * LCD_HEIGHT, 1);
+ imx233_lcdif_dma_send(FRAME, LCD_WIDTH, LCD_HEIGHT);
}
void lcd_update_rect(int x, int y, int width, int height)
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/power-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/power-fuzeplus.c
new file mode 100644
index 0000000000..5cda13e2bb
--- /dev/null
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/power-fuzeplus.c
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * 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 "power.h"
+#include "tuner.h"
+#include "fmradio_i2c.h"
+#include "pinctrl-imx233.h"
+
+static bool tuner_enable = false;
+
+bool tuner_power(bool enable)
+{
+ if(enable != tuner_enable)
+ {
+ fmradio_i2c_enable(enable);
+ /* CE is B029 (active high) */
+ imx233_enable_gpio_output(0, 29, enable);
+ imx233_set_gpio_output(0, 29, enable);
+ tuner_enable = enable;
+ }
+ return tuner_enable;
+}
+
+bool tuner_powered(void)
+{
+ return tuner_enable;
+}
diff --git a/firmware/target/arm/imx233/sd-imx233.c b/firmware/target/arm/imx233/sd-imx233.c
index 5e9f2cf030..b9114ae130 100644
--- a/firmware/target/arm/imx233/sd-imx233.c
+++ b/firmware/target/arm/imx233/sd-imx233.c
@@ -25,6 +25,10 @@
#include "ssp-imx233.h"
#include "pinctrl-imx233.h"
#include "button-target.h"
+#include "fat.h"
+#include "disk.h"
+#include "usb.h"
+#include "debug.h"
/**
* This code assumes a single SD card slot
@@ -37,7 +41,13 @@
#endif
static tCardInfo card_info;
+static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
static struct mutex sd_mutex;
+static const char sd_thread_name[] = "sd";
+static struct event_queue sd_queue;
+static int sd_first_drive;
+static bool sd_initialized;
+static int last_disk_activity;
static void sd_detect_callback(int ssp)
{
@@ -53,22 +63,132 @@ static void sd_detect_callback(int ssp)
imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
}
-int sd_init(void)
+void sd_enable(bool on)
{
- mutex_init(&sd_mutex);
+ static bool sd_enable = false;
+ if(sd_enable == on)
+ return;
+ mutex_lock(&sd_mutex);
+ if(on)
+ imx233_ssp_start(SD_SSP);
+ else
+ imx233_ssp_stop(SD_SSP);
+ mutex_unlock(&sd_mutex);
+ sd_enable = on;
+}
+
+static int sd_init_card(void)
+{
+ printf("sd_init_card");
imx233_ssp_start(SD_SSP);
imx233_ssp_softreset(SD_SSP);
imx233_ssp_set_mode(SD_SSP, HW_SSP_CTRL1__SSP_MODE__SD_MMC);
- #ifdef SANSA_FUZEPLUS
- imx233_ssp_setup_ssp1_sd_mmc_pins(true, 4, PINCTRL_DRIVE_8mA, false);
- #endif
- imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
/* SSPCLK @ 96MHz
* gives bitrate of 96000 / 240 / 1 = 400kHz */
imx233_ssp_set_timings(SD_SSP, 240, 0, 0xffff);
imx233_ssp_set_bus_width(SD_SSP, 1);
imx233_ssp_set_block_size(SD_SSP, 9);
+
+ card_info.rca = 0;
+ bool is_v2 = false;
+ uint32_t resp;
+ /* go to idle state */
+ int ret = imx233_ssp_sd_mmc_transfer(SD_SSP, SD_GO_IDLE_STATE, 0, SSP_NO_RESP, NULL, 0, false, false, NULL);
+ if(ret != 0)
+ return -1;
+ /* CMD8 Check for v2 sd card. Must be sent before using ACMD41
+ Non v2 cards will not respond to this command*/
+ ret = imx233_ssp_sd_mmc_transfer(SD_SSP, SD_SEND_IF_COND, 0x1AA, SSP_SHORT_RESP, NULL, 0, false, false, &resp);
+ if(ret == 0 && (resp & 0xFFF) == 0x1AA)
+ is_v2 = true;
+
+ return -10;
+}
+
+static void sd_thread(void) NORETURN_ATTR;
+static void sd_thread(void)
+{
+ struct queue_event ev;
+
+ while (1)
+ {
+ queue_wait_w_tmo(&sd_queue, &ev, HZ);
+
+ switch(ev.id)
+ {
+ case SYS_HOTSWAP_INSERTED:
+ case SYS_HOTSWAP_EXTRACTED:
+ {
+ int microsd_init = 1;
+ fat_lock(); /* lock-out FAT activity first -
+ prevent deadlocking via disk_mount that
+ would cause a reverse-order attempt with
+ another thread */
+ mutex_lock(&sd_mutex); /* lock-out card activity - direct calls
+ into driver that bypass the fat cache */
+
+ /* We now have exclusive control of fat cache and sd */
+
+ disk_unmount(sd_first_drive); /* release "by force", ensure file
+ descriptors aren't leaked and any busy
+ ones are invalid if mounting */
+ /* Force card init for new card, re-init for re-inserted one or
+ * clear if the last attempt to init failed with an error. */
+ card_info.initialized = 0;
+
+ if(ev.id == SYS_HOTSWAP_INSERTED)
+ {
+ int ret = sd_init_card();
+ if(ret == 0)
+ {
+ ret = disk_mount(sd_first_drive); /* 0 if fail */
+ if(ret < 0)
+ DEBUGF("disk_mount failed: %d", ret);
+ }
+ else
+ DEBUGF("sd_init_card failed: %d", ret);
+ }
+
+ /*
+ * Mount succeeded, or this was an EXTRACTED event,
+ * in both cases notify the system about the changed filesystems
+ */
+ if(card_info.initialized)
+ queue_broadcast(SYS_FS_CHANGED, 0);
+
+ /* Access is now safe */
+ mutex_unlock(&sd_mutex);
+ fat_unlock();
+ }
+ break;
+ case SYS_TIMEOUT:
+ if(!TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
+ sd_enable(false);
+ break;
+ case SYS_USB_CONNECTED:
+ usb_acknowledge(SYS_USB_CONNECTED_ACK);
+ /* Wait until the USB cable is extracted again */
+ usb_wait_for_disconnect(&sd_queue);
+ break;
+ }
+ }
+}
+
+int sd_init(void)
+{
+ mutex_init(&sd_mutex);
+ queue_init(&sd_queue, true);
+ create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
+ sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
+
+ #ifdef SANSA_FUZEPLUS
+ imx233_ssp_setup_ssp1_sd_mmc_pins(true, 4, PINCTRL_DRIVE_8mA, false);
+ #endif
+ imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
+
+ if(imx233_ssp_sdmmc_detect(SD_SSP))
+ queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
return 0;
}
@@ -101,7 +221,7 @@ tCardInfo *card_get_info_target(int card_no)
int sd_num_drives(int first_drive)
{
- (void) first_drive;
+ sd_first_drive = first_drive;
return 1;
}
diff --git a/firmware/target/arm/imx233/ssp-imx233.c b/firmware/target/arm/imx233/ssp-imx233.c
index c3ce8a8f58..912f9c3ae4 100644
--- a/firmware/target/arm/imx233/ssp-imx233.c
+++ b/firmware/target/arm/imx233/ssp-imx233.c
@@ -325,7 +325,6 @@ void imx233_ssp_sd_mmc_power_up_sequence(int ssp)
static int ssp_detect_oneshot_callback(int ssp)
{
- printf("ssp_detect_oneshot_callback(%d)", ssp);
if(ssp_detect_cb[ssp - 1])
ssp_detect_cb[ssp - 1](ssp);