diff --git a/apps/SOURCES b/apps/SOURCES index 075ca9a563..79642e1f1d 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -317,4 +317,6 @@ keymaps/keymap-mpio-hd300.c keymaps/keymap-android.c #elif CONFIG_KEYPAD == SDL_PAD keymaps/keymap-sdl.c +#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD +keymaps/keymap-fuzeplus.c #endif diff --git a/apps/misc.c b/apps/misc.c index bba3969e81..83e42cf3e0 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -528,7 +528,7 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame case SYS_USB_CONNECTED: if (callback != NULL) callback(parameter); -#if (CONFIG_STORAGE & STORAGE_MMC) +#if (CONFIG_STORAGE & STORAGE_MMC) && (defined(ARCHOS_ONDIOSP) || defined(ARCHOS_ONDIOFM)) if (!mmc_touched() || (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED)) #endif diff --git a/apps/screens.c b/apps/screens.c index 6c70477fbd..e20f96731c 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -59,7 +59,7 @@ #include "dsp.h" #endif -#if (CONFIG_STORAGE & STORAGE_MMC) +#if (CONFIG_STORAGE & STORAGE_MMC) && (defined(ARCHOS_ONDIOSP) || defined(ARCHOS_ONDIOFM)) int mmc_remove_request(void) { struct queue_event ev; diff --git a/firmware/SOURCES b/firmware/SOURCES index 610cc42112..21917de72d 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -269,6 +269,8 @@ drivers/rtc/rtc_s35390a.c drivers/rtc/rtc_s35380a.c #elif (CONFIG_RTC == RTC_D2) drivers/rtc/rtc_d2.c +#elif (CONFIG_RTC == RTC_IMX233) +drivers/rtc/rtc_imx233.c #endif /* (CONFIG_RTC == RTC_) */ #endif /* PLATFORM_NATIVE */ @@ -490,6 +492,7 @@ target/arm/pnx0101/timer-pnx0101.c #endif #if CONFIG_CPU == IMX233 +target/arm/mmu-arm.S target/arm/imx233/lcdif-imx233.c target/arm/imx233/clkctrl-imx233.c target/arm/imx233/system-imx233.c @@ -499,9 +502,15 @@ target/arm/imx233/kernel-imx233.c target/arm/imx233/sd-imx233.c target/arm/imx233/mmc-imx233.c target/arm/imx233/ssp-imx233.c -target/arm/imx233/usb-imx233.c target/arm/imx233/dma-imx233.c target/arm/imx233/pinctrl-imx233.c +target/arm/imx233/power-imx233.c +target/arm/imx233/powermgmt-imx233.c +target/arm/imx233/adc-imx233.c +target/arm/imx233/debug-imx233.c +#if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE) +target/arm/imx233/usb-imx233.c +#endif #endif /* IMX233 */ #if CONFIG_CPU == AS3525 || CONFIG_CPU == AS3525v2 @@ -1456,10 +1465,13 @@ target/arm/as3525/lcd-as-e200v2-fuze-fuzev2.S #ifndef SIMULATOR drivers/synaptics-rmi.c drivers/generic_i2c.c +target/arm/lcd-as-memframe.S target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c +target/arm/imx233/sansa-fuzeplus/debug-fuzeplus.c +target/arm/imx233/sansa-fuzeplus/power-fuzeplus.c #endif /* SIMULATOR */ #endif diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index a4eb24ce7f..f76b10c078 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -218,7 +218,7 @@ static struct mutex tempbuf_mutex; static char fat_tempbuf[SECTOR_SIZE] CACHEALIGN_ATTR; static bool tempbuf_locked; -#if defined(HAVE_HOTSWAP) && !(CONFIG_STORAGE & STORAGE_MMC) /* A better condition ?? */ +#if defined(HAVE_HOTSWAP) void fat_lock(void) { mutex_lock(&cache_mutex); diff --git a/firmware/drivers/rtc/rtc_imx233.c b/firmware/drivers/rtc/rtc_imx233.c new file mode 100644 index 0000000000..4368610875 --- /dev/null +++ b/firmware/drivers/rtc/rtc_imx233.c @@ -0,0 +1,68 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "rtc.h" +#include "timefuncs.h" + +void rtc_init(void) +{ +} + +int rtc_read_datetime(struct tm *tm) +{ + (void) tm; + return -1; +} + +int rtc_write_datetime(const struct tm *tm) +{ + (void) tm; + return -1; +} + +void rtc_set_alarm(int h, int m) +{ + (void) h; + (void) m; +} + +void rtc_get_alarm(int *h, int *m) +{ + (void) h; + (void) m; +} + +void rtc_enable_alarm(bool enable) +{ + (void) enable; +} + +bool rtc_check_alarm_started(bool release_alarm) +{ + (void) release_alarm; + return false; +} + +bool rtc_check_alarm_flag(void) +{ + return false; +} diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index 651c9cd254..593924d370 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -70,6 +70,8 @@ #include "ak4537.h" #elif defined(HAVE_CS42L55) #include "cs42l55.h" +#elif defined(HAVE_IMX233_CODEC) +#include "imx233-codec.h" #endif #if (CONFIG_PLATFORM & PLATFORM_HOSTED) /* #include gives errors in other code areas, diff --git a/firmware/export/config.h b/firmware/export/config.h index 37acec04e1..036354180c 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -869,7 +869,7 @@ Lyre prototype 1 */ #endif #if (defined(CPU_PP) || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) || \ - (CONFIG_CPU == IMX31L)) \ + (CONFIG_CPU == IMX31L) || (CONFIG_CPU == IMX233)) \ && (CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(BOOTLOADER) /* Functions that have INIT_ATTR attached are NOT guaranteed to survive after * root_menu() has been called. Their code may be overwritten by other data or diff --git a/firmware/export/config/sansafuzeplus.h b/firmware/export/config/sansafuzeplus.h index 4c3cd6014b..971ff019b6 100644 --- a/firmware/export/config/sansafuzeplus.h +++ b/firmware/export/config/sansafuzeplus.h @@ -28,7 +28,7 @@ /* define this if you have a colour LCD */ #define HAVE_LCD_COLOR -#ifndef BOOTLOADER/* define this if you want album art for this target */ +#ifndef BOOTLOADER #define HAVE_ALBUMART /* define this to enable bitmap scaling */ @@ -37,9 +37,6 @@ /* define this to enable JPEG decoding */ #define HAVE_JPEG -/* define this if you have a light associated with the buttons */ -#define HAVE_BUTTON_LIGHT - /* define this if you have access to the quickscreen */ #define HAVE_QUICKSCREEN @@ -69,13 +66,19 @@ /* define this if you have a real-time clock */ #define CONFIG_RTC RTC_IMX233 +/* define this if you have a real-time clock with alarm facilities */ +#define HAVE_RTC_ALARM + +#endif /* !BOOTLOADER */ + +/* define this if you have an i.MX23 codec */ +#define HAVE_IMX233_CODEC + #define CONFIG_TUNER SI4700 /* There is no hardware tone control */ #define HAVE_SW_TONE_CONTROLS -#endif /* !BOOTLOADER */ - #define CONFIG_KEYPAD SANSA_FUZEPLUS_PAD /* Define this to enable morse code input */ @@ -84,7 +87,6 @@ /* Define this if you do software codec */ #define CONFIG_CODEC SWCODEC - /* LCD dimensions */ #define LCD_WIDTH 240 #define LCD_HEIGHT 320 diff --git a/firmware/export/imx233-codec.h b/firmware/export/imx233-codec.h new file mode 100644 index 0000000000..99d49f6adb --- /dev/null +++ b/firmware/export/imx233-codec.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * __________ __ ___. + * 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 __IMX233_CODEC_H_ +#define __IMX233_CODEC_H_ + +#define VOLUME_MIN -1000 +#define VOLUME_MAX -5 + +void audiohw_set_volume(int v); + +#endif /* __IMX233_CODEC_H_ */ 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 similarity index 100% rename from firmware/target/arm/imx233/sansa-fuzeplus/adc-target.h rename to 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);