From f44f961812c059b69df19ac5bd828986ba10513f Mon Sep 17 00:00:00 2001 From: Marcoen Hirschberg Date: Wed, 18 Apr 2007 12:22:27 +0000 Subject: move the Gigabeat from gigabeat/meg-fx to s3c2440/gigabeat-fx to avoid problems with possible ports in the future: Gigabeat S/V (i.mx31 based) and Kenwood HD20GA7/HD20GA9 (s3c2440 based) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13200 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/gigabeat/meg-fx/adc-meg-fx.c | 144 ----- firmware/target/arm/gigabeat/meg-fx/adc-target.h | 37 -- firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c | 143 ----- firmware/target/arm/gigabeat/meg-fx/ata-target.h | 70 --- .../target/arm/gigabeat/meg-fx/backlight-meg-fx.c | 692 --------------------- .../target/arm/gigabeat/meg-fx/backlight-target.h | 87 --- .../target/arm/gigabeat/meg-fx/button-meg-fx.c | 157 ----- .../target/arm/gigabeat/meg-fx/button-target.h | 89 --- firmware/target/arm/gigabeat/meg-fx/dma_start.c | 8 - firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.c | 134 ---- firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.h | 22 - .../target/arm/gigabeat/meg-fx/kernel-meg-fx.c | 25 - .../target/arm/gigabeat/meg-fx/lcd-as-meg-fx.S | 222 ------- firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | 367 ----------- firmware/target/arm/gigabeat/meg-fx/lcd-target.h | 21 - firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.c | 222 ------- firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.h | 35 -- firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c | 376 ----------- firmware/target/arm/gigabeat/meg-fx/power-meg-fx.c | 90 --- firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.c | 225 ------- firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.h | 28 - .../target/arm/gigabeat/meg-fx/system-meg-fx.c | 96 --- .../target/arm/gigabeat/meg-fx/system-target.h | 40 -- firmware/target/arm/gigabeat/meg-fx/usb-meg-fx.c | 94 --- firmware/target/arm/gigabeat/meg-fx/usb-target.h | 26 - .../target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c | 71 --- .../target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c | 144 +++++ .../target/arm/s3c2440/gigabeat-fx/adc-target.h | 37 ++ .../target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c | 143 +++++ .../target/arm/s3c2440/gigabeat-fx/ata-target.h | 70 +++ .../arm/s3c2440/gigabeat-fx/backlight-meg-fx.c | 692 +++++++++++++++++++++ .../arm/s3c2440/gigabeat-fx/backlight-target.h | 87 +++ .../target/arm/s3c2440/gigabeat-fx/button-meg-fx.c | 157 +++++ .../target/arm/s3c2440/gigabeat-fx/button-target.h | 89 +++ .../target/arm/s3c2440/gigabeat-fx/dma_start.c | 8 + .../target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c | 134 ++++ .../target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h | 22 + .../target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c | 25 + .../target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S | 222 +++++++ .../target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | 367 +++++++++++ .../target/arm/s3c2440/gigabeat-fx/lcd-target.h | 21 + .../target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c | 222 +++++++ .../target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.h | 35 ++ .../target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c | 376 +++++++++++ .../target/arm/s3c2440/gigabeat-fx/power-meg-fx.c | 90 +++ .../target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c | 225 +++++++ .../target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.h | 28 + .../target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | 96 +++ .../target/arm/s3c2440/gigabeat-fx/system-target.h | 40 ++ .../target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c | 94 +++ .../target/arm/s3c2440/gigabeat-fx/usb-target.h | 26 + .../arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c | 71 +++ 52 files changed, 3521 insertions(+), 3521 deletions(-) delete mode 100644 firmware/target/arm/gigabeat/meg-fx/adc-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/adc-target.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/ata-target.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/backlight-target.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/button-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/button-target.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/dma_start.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/kernel-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/lcd-as-meg-fx.S delete mode 100644 firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/lcd-target.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/power-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/system-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/system-target.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/usb-meg-fx.c delete mode 100644 firmware/target/arm/gigabeat/meg-fx/usb-target.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/adc-target.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/backlight-target.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/button-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/button-target.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/dma_start.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/lcd-target.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/power-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/system-target.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/usb-target.h create mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c (limited to 'firmware/target') diff --git a/firmware/target/arm/gigabeat/meg-fx/adc-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/adc-meg-fx.c deleted file mode 100644 index 4c448c2e41..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/adc-meg-fx.c +++ /dev/null @@ -1,144 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Wade Brown - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "cpu.h" -#include "adc-target.h" -#include "kernel.h" - - - -static unsigned short adc_readings[NUM_ADC_CHANNELS]; - -/* prototypes */ -static unsigned short __adc_read(int channel); -static void adc_tick(void); - - - -void adc_init(void) -{ - int i; - - /* Turn on the ADC PCLK */ - CLKCON |= (1<<15); - - /* Set channel 0, normal mode, disable "start by read" */ - ADCCON &= ~(0x3F); - - /* No start delay. Use normal conversion mode. */ - ADCDLY = 0x1; - - /* Set and enable the prescaler */ - ADCCON = (ADCCON & ~(0xff<<6)) | (0x19<<6); - ADCCON |= (1<<14); - - /* prefill the adc channels */ - for (i = 0; i < NUM_ADC_CHANNELS; i++) - { - adc_readings[i] = __adc_read(i); - } - - /* start at zero so when the tick starts it is at zero */ - adc_readings[0] = __adc_read(0); - - /* attach the adc reading to the tick */ - tick_add_task(adc_tick); - - -} - - - -/* Called to get the recent ADC reading */ -inline unsigned short adc_read(int channel) -{ - return adc_readings[channel]; -} - - - -/** - * Read the ADC by polling - * @param channel The ADC channel to read - * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout - */ -static unsigned short __adc_read(int channel) -{ - int i; - - /* Set the channel */ - ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3); - - /* Start the conversion process */ - ADCCON |= 0x1; - - /* Wait for a low Enable_start */ - for (i = 20000;;) { - if(0 == (ADCCON & 0x1)) { - break; - } - else { - i--; - if (0 == i) { - /* Ran out of time */ - return ADC_READ_ERROR; - } - } - } - - /* Wait for high End_of_Conversion */ - for(i = 20000;;) { - if(ADCCON & (1<<15)) { - break; - } - else { - i--; - if(0 == i) { - /* Ran out of time */ - return ADC_READ_ERROR; - } - } - } - - return (ADCDAT0 & 0x3ff); -} - - - -/* add this to the tick so that the ADC converts are done in the background */ -static void adc_tick(void) -{ - static unsigned channel; - - /* Check if the End Of Conversion is set */ - if (ADCCON & (1<<15)) - { - adc_readings[channel] = (ADCDAT0 & 0x3FF); - if (++channel >= NUM_ADC_CHANNELS) - { - channel = 0; - } - - /* setup the next conversion and start it*/ - ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3) | 0x01; - } -} - - - - diff --git a/firmware/target/arm/gigabeat/meg-fx/adc-target.h b/firmware/target/arm/gigabeat/meg-fx/adc-target.h deleted file mode 100644 index 8d2beaf320..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/adc-target.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Barry Wardell - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef _ADC_TARGET_H_ -#define _ADC_TARGET_H_ - -/* only two channels used by the Gigabeat */ -#define NUM_ADC_CHANNELS 2 - -#define ADC_BATTERY 0 -#define ADC_HPREMOTE 1 -#define ADC_UNKNOWN_3 2 -#define ADC_UNKNOWN_4 3 -#define ADC_UNKNOWN_5 4 -#define ADC_UNKNOWN_6 5 -#define ADC_UNKNOWN_7 6 -#define ADC_UNKNOWN_8 7 - -#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */ -#define ADC_READ_ERROR 0xFFFF - -#endif diff --git a/firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c deleted file mode 100644 index bc2b53d776..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c +++ /dev/null @@ -1,143 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id $ - * - * Copyright (C) 2006,2007 by Marcoen Hirschberg - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "config.h" -#include "cpu.h" -#include -#include "kernel.h" -#include "system.h" -#include "power.h" -#include "panic.h" -#include "pcf50606.h" -#include "ata-target.h" -#include "mmu-meg-fx.h" -#include "backlight-target.h" - -/* ARESET on C7C68300 and RESET on ATA interface (Active Low) */ -#define ATA_RESET_ENABLE GPGDAT &= ~(1 << 10) -#define ATA_RESET_DISABLE GPGDAT |= (1 << 10) - -/* ATA_EN on C7C68300 */ -#define USB_ATA_ENABLE GPBDAT |= (1 << 5) -#define USB_ATA_DISABLE GPBDAT &= ~(1 << 5) - -void ata_reset(void) -{ - ATA_RESET_ENABLE; - sleep(1); /* > 25us */ - ATA_RESET_DISABLE; - sleep(1); /* > 2ms */ -} - -/* This function is called before enabling the USB bus */ -void ata_enable(bool on) -{ - if(on) - USB_ATA_DISABLE; - else - USB_ATA_ENABLE; - - GPBCON=( GPGCON&~(1<<11) ) | (1<<10); /* Make the pin an output */ -// GPBUP|=1<<5; /* Disable pullup in SOC as we are now driving */ -} - -bool ata_is_coldstart(void) -{ - /* Check the pin configuration - return true when pin is unconfigured */ - return (GPGCON & 0x00300000) == 0; -} - -void ata_device_init(void) -{ - /* ATA reset */ - ATA_RESET_DISABLE; /* Set the pin to disable an active low reset */ - GPGCON=( GPGCON&~(1<<21) ) | (1<<20); /* Make the pin an output */ - GPGUP |= 1<<10; /* Disable pullup in SOC as we are now driving */ -} - -#if !defined(BOOTLOADER) -void copy_read_sectors(unsigned char* buf, int wordcount) -{ - __buttonlight_trigger(); - - /* Unaligned transfer - slow copy */ - if ( (unsigned long)buf & 1) - { /* not 16-bit aligned, copy byte by byte */ - unsigned short tmp = 0; - unsigned char* bufend = buf + wordcount*2; - do - { - tmp = ATA_DATA; - *buf++ = tmp & 0xff; /* I assume big endian */ - *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */ - } while (buf < bufend); /* tail loop is faster */ - return; - } - /* This should never happen, but worth watching for */ - if(wordcount > (1 << 18)) - panicf("atd-meg-fx.c: copy_read_sectors: too many sectors per read!"); - -//#define GIGABEAT_DEBUG_ATA -#ifdef GIGABEAT_DEBUG_ATA - static int line = 0; - static char str[256]; - snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount); - lcd_puts(10, line, str); - line = (line+1) % 32; - lcd_update(); -#endif - /* Reset the channel */ - DMASKTRIG0 |= 4; - /* Wait for DMA controller to be ready */ - while(DMASKTRIG0 & 0x2) - ; - while(DSTAT0 & (1 << 20)) - ; - /* Source is ATA_DATA, on AHB Bus, Fixed */ - DISRC0 = (int) 0x18000000; - DISRCC0 = 0x1; - /* Dest mapped to physical address, on AHB bus, increment */ - DIDST0 = (int) buf; - if(DIDST0 < 0x30000000) - DIDST0 += 0x30000000; - DIDSTC0 = 0; - - /* DACK/DREQ Sync to AHB, Int on Transfer complete, Whole service, No reload, 16-bit transfers */ - DCON0 = ((1 << 30) | (1<< 29) | (1<<27) | (1<<22) | (1<<20)) | wordcount; - - /* Activate the channel */ - DMASKTRIG0 = 0x2; - - invalidate_dcache_range((void *)buf, wordcount*2); - - INTMSK &= ~(1<<17); /* unmask the interrupt */ - SRCPND = (1<<17); /* clear any pending interrupts */ - /* Start DMA */ - DMASKTRIG0 |= 0x1; - - /* Wait for transfer to complete */ - while((DSTAT0 & 0x000fffff)) - yield(); - /* Dump cache for the buffer */ -} -#endif -void dma0(void) -{ -} - - diff --git a/firmware/target/arm/gigabeat/meg-fx/ata-target.h b/firmware/target/arm/gigabeat/meg-fx/ata-target.h deleted file mode 100644 index 95e3e110f2..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/ata-target.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef ATA_TARGET_H -#define ATA_TARGET_H - -/* Plain C read & write loops */ -#define PREFER_C_READING -#define PREFER_C_WRITING -#if !defined(BOOTLOADER) -#define ATA_OPTIMIZED_READING -void copy_read_sectors(unsigned char* buf, int wordcount); -#endif - -#define ATA_IOBASE 0x18000000 -#define ATA_DATA (*((volatile unsigned short*)(ATA_IOBASE))) -#define ATA_ERROR (*((volatile unsigned char*)(ATA_IOBASE + 0x02))) -#define ATA_NSECTOR (*((volatile unsigned char*)(ATA_IOBASE + 0x04))) -#define ATA_SECTOR (*((volatile unsigned char*)(ATA_IOBASE + 0x06))) -#define ATA_LCYL (*((volatile unsigned char*)(ATA_IOBASE + 0x08))) -#define ATA_HCYL (*((volatile unsigned char*)(ATA_IOBASE + 0x0A))) -#define ATA_SELECT (*((volatile unsigned char*)(ATA_IOBASE + 0x0C))) -#define ATA_COMMAND (*((volatile unsigned char*)(ATA_IOBASE + 0x0E))) -#define ATA_CONTROL (*((volatile unsigned char*)(0x20000000 + 0x1C))) - -#define STATUS_BSY 0x80 -#define STATUS_RDY 0x40 -#define STATUS_DF 0x20 -#define STATUS_DRQ 0x08 -#define STATUS_ERR 0x01 -#define ERROR_ABRT 0x04 - -#define WRITE_PATTERN1 0xa5 -#define WRITE_PATTERN2 0x5a -#define WRITE_PATTERN3 0xaa -#define WRITE_PATTERN4 0x55 - -#define READ_PATTERN1 0xa5 -#define READ_PATTERN2 0x5a -#define READ_PATTERN3 0xaa -#define READ_PATTERN4 0x55 - -#define READ_PATTERN1_MASK 0xff -#define READ_PATTERN2_MASK 0xff -#define READ_PATTERN3_MASK 0xff -#define READ_PATTERN4_MASK 0xff - -#define SET_REG(reg,val) reg = (val) -#define SET_16BITREG(reg,val) reg = (val) - -void ata_reset(void); -void ata_device_init(void); -bool ata_is_coldstart(void); - -#endif diff --git a/firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c deleted file mode 100644 index a1b6a8a583..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c +++ /dev/null @@ -1,692 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "config.h" -#include "cpu.h" -#include "system.h" -#include "backlight-target.h" -#include "backlight.h" -#include "lcd.h" -#include "sc606-meg-fx.h" -#include "power.h" - - -#define FLICKER_PERIOD 15 -#define BUTTONLIGHT_MENU (SC606_LED_B1) -#define BUTTONLIGHT_ALL (SC606_LED_B1 | SC606_LED_B2 | SC606_LED_C1 | SC606_LED_C2) - -static void led_control_service(void); -static unsigned short backlight_brightness; -static unsigned short backlight_current; -static unsigned short backlight_target; -static unsigned short time_til_fade; -static unsigned short fade_interval; -static unsigned short initial_tick_delay; -static unsigned char backlight_leds; - -static enum backlight_states -{ - BACKLIGHT_CONTROL_IDLE, - BACKLIGHT_CONTROL_OFF, - BACKLIGHT_CONTROL_ON, - BACKLIGHT_CONTROL_SET, - BACKLIGHT_CONTROL_FADE_OFF, - BACKLIGHT_CONTROL_FADE_ON, - BACKLIGHT_CONTROL_FADE_ON_FROM_OFF -} backlight_control; - - - -enum buttonlight_states -{ - /* turn button lights off */ - BUTTONLIGHT_MODE_OFF_ENTRY, - BUTTONLIGHT_MODE_OFF, - - /* turns button lights on to setting */ - BUTTONLIGHT_MODE_ON_ENTRY, - BUTTONLIGHT_MODE_ON, - - /* turns button lights on to minimum */ - BUTTONLIGHT_MODE_FAINT_ENTRY, - BUTTONLIGHT_MODE_FAINT, - - /* allows button lights to flicker when triggered */ - BUTTONLIGHT_MODE_FLICKER_ENTRY, - BUTTONLIGHT_MODE_FLICKER, - BUTTONLIGHT_MODE_FLICKERING, - - /* button lights solid */ - BUTTONLIGHT_MODE_SOLID_ENTRY, - BUTTONLIGHT_MODE_SOLID, - - /* button light charing */ - BUTTONLIGHT_MODE_CHARGING_ENTRY, - BUTTONLIGHT_MODE_CHARGING, - BUTTONLIGHT_MODE_CHARGING_WAIT, - - /* internal use only */ - BUTTONLIGHT_HELPER_SET, - BUTTONLIGHT_HELPER_SET_FINAL, - BUTTONLIGHT_MODE_STOP, - - /* buttonlights follow the backlight settings */ - BUTTONLIGHT_MODE_FOLLOW_ENTRY, - BUTTONLIGHT_MODE_FOLLOW, -}; - - - -static char buttonlight_leds; -static unsigned short buttonlight_setting; -static unsigned short buttonlight_current; -static unsigned char buttonlight_selected; -static enum buttonlight_states buttonlight_state; -static enum buttonlight_states buttonlight_saved_state; -static unsigned short buttonlight_flickering; - -static unsigned short buttonlight_trigger_now; -static unsigned short buttonlight_trigger_brightness; - - - -static unsigned short charging_led_index; -static unsigned short buttonlight_charging_counter; - -#define CHARGING_LED_COUNT 60 -unsigned char charging_leds[] = { 0x00, 0x20, 0x38, 0x3C }; - - - -bool __backlight_init(void) -{ - backlight_control = BACKLIGHT_CONTROL_IDLE; - - backlight_current = DEFAULT_BRIGHTNESS_SETTING; - - buttonlight_state = BUTTONLIGHT_MODE_OFF; - - buttonlight_selected = 0x04; - - /* delay 4 seconds before any fading */ - initial_tick_delay = 400; - /* put the led control on the tick list */ - tick_add_task(led_control_service); - - return true; -} - - - -void __backlight_on(void) -{ - /* now go turn the backlight on */ - backlight_control = BACKLIGHT_CONTROL_ON; -} - - - -void __backlight_off(void) -{ - backlight_control = BACKLIGHT_CONTROL_OFF; -} - - - -/* Assumes that the backlight has been initialized */ -void __backlight_set_brightness(int brightness) -{ - /* stop the interrupt from messing us up */ - backlight_control = BACKLIGHT_CONTROL_IDLE; - - backlight_brightness = brightness + 1; - - /* only set the brightness if it is different from the current */ - if (backlight_brightness != backlight_current) - { - backlight_control = BACKLIGHT_CONTROL_SET; - } -} - - - -/* only works if the buttonlight mode is set to triggered mode */ -void __buttonlight_trigger(void) -{ - buttonlight_trigger_now = 1; -} - - - - -/* map the mode from the command into the state machine entries */ -void __buttonlight_mode(enum buttonlight_mode mode, - enum buttonlight_selection selection, - unsigned short brightness) -{ - /* choose stop to setup mode */ - buttonlight_state = BUTTONLIGHT_MODE_STOP; - - - /* clip brightness */ - if (brightness > MAX_BRIGHTNESS_SETTING) - { - brightness = MAX_BRIGHTNESS_SETTING; - } - - brightness++; - - /* Select which LEDs to use */ - switch (selection) - { - case BUTTONLIGHT_LED_ALL: - buttonlight_selected = BUTTONLIGHT_ALL; - break; - - case BUTTONLIGHT_LED_MENU: - buttonlight_selected = BUTTONLIGHT_MENU; - break; - } - - /* which mode to use */ - switch (mode) - { - case BUTTONLIGHT_OFF: - buttonlight_state = BUTTONLIGHT_MODE_OFF_ENTRY; - break; - - case BUTTONLIGHT_ON: - buttonlight_trigger_brightness = brightness; - buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY; - break; - - /* faint is just a quick way to set ON to 1 */ - case BUTTONLIGHT_FAINT: - buttonlight_trigger_brightness = 1; - buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY; - break; - - case BUTTONLIGHT_FLICKER: - buttonlight_trigger_brightness = brightness; - buttonlight_state = BUTTONLIGHT_MODE_FLICKER_ENTRY; - break; - - case BUTTONLIGHT_SIGNAL: - buttonlight_trigger_brightness = brightness; - buttonlight_state = BUTTONLIGHT_MODE_SOLID_ENTRY; - break; - - case BUTTONLIGHT_FOLLOW: - buttonlight_state = BUTTONLIGHT_MODE_FOLLOW_ENTRY; - break; - - case BUTTONLIGHT_CHARGING: - buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY; - break; - - default: - return; /* unknown mode */ - } - - -} - - - -/* - * The button lights have 'modes' of operation. Each mode must setup and - * execute its own operation - taking care that this is all done in an ISR. - * - */ - - - -/* led_control_service runs in interrupt context - be brief! - * This service is called once per interrupt timer tick - 100 times a second. - * - * There should be at most only one i2c operation per call - if more are need - * the calls should be spread across calls. - * - * Putting all led servicing in one thread means that we wont step on any - * i2c operations - they are all serialized here in the ISR tick. It also - * insures that we get called at equal timing for good visual effect. - * - * The buttonlight service runs only after all backlight services have finished. - * Fading the buttonlights is possible, but not recommended because of the - * additional calls needed during the ISR - */ -static void led_control_service(void) -{ - if(initial_tick_delay) { - initial_tick_delay--; - return; - } - switch (backlight_control) - { - case BACKLIGHT_CONTROL_IDLE: - switch (buttonlight_state) - { - case BUTTONLIGHT_MODE_STOP: break; - - /* Buttonlight mode: OFF */ - case BUTTONLIGHT_MODE_OFF_ENTRY: - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - buttonlight_state = BUTTONLIGHT_MODE_OFF; - break; - - case BUTTONLIGHT_MODE_OFF: - break; - - - /* button mode: CHARGING - show charging sequence */ - case BUTTONLIGHT_MODE_CHARGING_ENTRY: - /* start turned off */ - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = DEFAULT_BRIGHTNESS_SETTING; - buttonlight_saved_state = BUTTONLIGHT_MODE_CHARGING_WAIT; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - break; - - - case BUTTONLIGHT_MODE_CHARGING: - if (--buttonlight_charging_counter == 0) - { - /* change led */ - if (charging_state()) - { - buttonlight_leds = charging_leds[charging_led_index]; - if (++charging_led_index >= sizeof(charging_leds)) - { - charging_led_index = 0; - } - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - buttonlight_charging_counter = CHARGING_LED_COUNT; - } - else - { - buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY; - } - } - break; - - /* wait for the charget to be plugged in */ - case BUTTONLIGHT_MODE_CHARGING_WAIT: - if (charging_state()) - { - charging_led_index = 0; - buttonlight_charging_counter = CHARGING_LED_COUNT; - buttonlight_state = BUTTONLIGHT_MODE_CHARGING; - } - break; - - - /* Buttonlight mode: FOLLOW - try to stay current with backlight - * since this runs in the idle of the backlight it will not really - * follow in real time - */ - case BUTTONLIGHT_MODE_FOLLOW_ENTRY: - /* case 1 - backlight on, but buttonlight is off */ - if (backlight_current) - { - /* Turn the buttonlights on */ - buttonlight_leds = buttonlight_selected; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = backlight_current; - buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - } - /* case 2 - backlight off, but buttonlight is on */ - else - { - buttonlight_current = 0; - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_state = BUTTONLIGHT_MODE_FOLLOW; - } - break; - - case BUTTONLIGHT_MODE_FOLLOW: - if (buttonlight_current != backlight_current) - { - /* case 1 - backlight on, but buttonlight is off */ - if (backlight_current) - { - if (0 == buttonlight_current) - { - /* Turn the buttonlights on */ - buttonlight_leds = buttonlight_selected; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - } - - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = backlight_current; - buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - } - - /* case 2 - backlight off, but buttonlight is on */ - else - { - buttonlight_current = 0; - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - } - - } - break; - - - - /* Buttonlight mode: ON - stays at the set brightness */ - case BUTTONLIGHT_MODE_ON_ENTRY: - buttonlight_leds = buttonlight_selected; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = buttonlight_trigger_brightness; - buttonlight_saved_state = BUTTONLIGHT_MODE_ON; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - break; - - case BUTTONLIGHT_MODE_ON: - break; - - - - /* Buttonlight mode: FLICKER */ - case BUTTONLIGHT_MODE_FLICKER_ENTRY: - /* already on? turn it off */ - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - - /* set the brightness if not already set */ - if (buttonlight_current != buttonlight_trigger_brightness) - { - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = buttonlight_trigger_brightness; - buttonlight_saved_state = BUTTONLIGHT_MODE_FLICKER; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - } - else buttonlight_state = BUTTONLIGHT_MODE_FLICKER; - break; - - - case BUTTONLIGHT_MODE_FLICKER: - /* wait for the foreground to trigger flickering */ - if (buttonlight_trigger_now) - { - /* turn them on */ - buttonlight_leds = buttonlight_selected; - buttonlight_current = buttonlight_setting; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - - /* reset the trigger and go flicker the LEDs */ - buttonlight_trigger_now = 0; - buttonlight_flickering = FLICKER_PERIOD; - buttonlight_state = BUTTONLIGHT_MODE_FLICKERING; - } - break; - - - case BUTTONLIGHT_MODE_FLICKERING: - /* flicker the LEDs for as long as we get triggered */ - if (buttonlight_flickering) - { - /* turn the leds off if they are on */ - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - - buttonlight_flickering--; - } - else - { - /* is flickering triggered again? */ - if (!buttonlight_trigger_now) - { - /* completed a cycle - no new triggers - go back and wait */ - buttonlight_state = BUTTONLIGHT_MODE_FLICKER; - } - else - { - /* reset flickering */ - buttonlight_trigger_now = 0; - buttonlight_flickering = FLICKER_PERIOD; - - /* turn buttonlights on */ - buttonlight_leds = buttonlight_selected; - buttonlight_current = buttonlight_setting; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - } - } - break; - - - /* Buttonlight mode: SIGNAL / SOLID */ - case BUTTONLIGHT_MODE_SOLID_ENTRY: - /* already on? turn it off */ - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - - /* set the brightness if not already set */ - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = buttonlight_trigger_brightness; - buttonlight_saved_state = BUTTONLIGHT_MODE_SOLID; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - break; - - - case BUTTONLIGHT_MODE_SOLID: - /* wait for the foreground to trigger */ - if (buttonlight_trigger_now) - { - /* turn them on if not already on */ - if (0 == buttonlight_current) - { - buttonlight_leds = buttonlight_selected; - buttonlight_current = buttonlight_setting; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - } - - /* reset the trigger */ - buttonlight_trigger_now = 0; - } - else - { - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - } - break; - - - /* set the brightness for the buttonlights - takes 2 passes */ - case BUTTONLIGHT_HELPER_SET: - sc606_write(SC606_REG_B, buttonlight_setting-1); - buttonlight_state = BUTTONLIGHT_HELPER_SET_FINAL; - break; - - case BUTTONLIGHT_HELPER_SET_FINAL: - sc606_write(SC606_REG_C, buttonlight_setting-1); - buttonlight_current = buttonlight_setting; - buttonlight_state = buttonlight_saved_state; - break; - - default: - break; - - } - break; - - - case BACKLIGHT_CONTROL_FADE_ON_FROM_OFF: - backlight_leds = 0x03; - sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds); - backlight_control = BACKLIGHT_CONTROL_FADE_ON; - break; - - - case BACKLIGHT_CONTROL_OFF: - backlight_current = 0; - backlight_leds = 0x00; - sc606_write(SC606_REG_CONF, buttonlight_leds); - backlight_control = BACKLIGHT_CONTROL_IDLE; - - break; - - - case BACKLIGHT_CONTROL_ON: - backlight_leds = 0x03; - sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds); - backlight_current = backlight_brightness; - backlight_control = BACKLIGHT_CONTROL_IDLE; - break; - - - case BACKLIGHT_CONTROL_SET: - /* The SC606 LED driver can set the brightness in 64 steps */ - sc606_write(SC606_REG_A, backlight_brightness-1); - - /* if we were turned off - turn the backlight on */ - if (backlight_current) - { - backlight_current = backlight_brightness; - backlight_control = BACKLIGHT_CONTROL_IDLE; - } - else - { - backlight_control = BACKLIGHT_CONTROL_ON; - } - break; - - - case BACKLIGHT_CONTROL_FADE_ON: - if (--time_til_fade) return; - - /* The SC606 LED driver can set the brightness in 64 steps */ - sc606_write(SC606_REG_A, backlight_current++); - - /* have we hit the target? */ - if (backlight_current == backlight_target) - { - backlight_control = BACKLIGHT_CONTROL_IDLE; - } - else - { - time_til_fade = fade_interval; - } - break; - - - case BACKLIGHT_CONTROL_FADE_OFF: - if (--time_til_fade) return; - - /* The SC606 LED driver can set the brightness in 64 steps */ - sc606_write(SC606_REG_A, --backlight_current); - - /* have we hit the target? */ - if (backlight_current == backlight_target) - { - if (backlight_current) - { - backlight_control = BACKLIGHT_CONTROL_IDLE; - } - else - { - backlight_control = BACKLIGHT_CONTROL_OFF; - } - - } - else - { - time_til_fade = fade_interval; - } - break; - } - - if(backlight_current) - lcd_enable(true); - else - lcd_enable(false); -} - - - - - -void __backlight_dim(bool dim_now) -{ - unsigned short target; - - /* dont let the interrupt tick happen */ - backlight_control = BACKLIGHT_CONTROL_IDLE; - - target = (dim_now == true) ? 0 : backlight_brightness; - - /* only try and fade if the target is different */ - if (backlight_current != target) - { - backlight_target = target; - - if (backlight_current > backlight_target) - { - time_til_fade = fade_interval = 4; - backlight_control = BACKLIGHT_CONTROL_FADE_OFF; - } - else - { - time_til_fade = fade_interval = 1; - if (backlight_current) - { - backlight_control = BACKLIGHT_CONTROL_FADE_ON; - } - else - { - backlight_control = BACKLIGHT_CONTROL_FADE_ON_FROM_OFF; - } - } - } - -} - - diff --git a/firmware/target/arm/gigabeat/meg-fx/backlight-target.h b/firmware/target/arm/gigabeat/meg-fx/backlight-target.h deleted file mode 100644 index 5f92cee935..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/backlight-target.h +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef BACKLIGHT_TARGET_H -#define BACKLIGHT_TARGET_H - - -/* select the led */ -enum buttonlight_selection -{ - /* all leds */ - BUTTONLIGHT_LED_ALL, - - /* only the menu/power led (two buttons for one LED) */ - BUTTONLIGHT_LED_MENU -}; - - -/* Use these to set the buttonlight mode */ -enum buttonlight_mode -{ - /* ON follows the setting */ - BUTTONLIGHT_ON, - - /* buttonlights always off */ - BUTTONLIGHT_OFF, - - /* buttonlights always on but set at lowest brightness */ - BUTTONLIGHT_FAINT, - - /* buttonlights flicker when triggered - continues to flicker - * even if the flicker is still asserted. - */ - BUTTONLIGHT_FLICKER, - - /* buttonlights solid for as long as triggered */ - BUTTONLIGHT_SIGNAL, - - /* buttonlights follow backlight */ - BUTTONLIGHT_FOLLOW, - - /* buttonlights show battery charging */ - BUTTONLIGHT_CHARGING, -}; - - -/* Call this to flicker or signal the button lights. Only is effective for - * modes that take a trigger input. - */ -void __buttonlight_trigger(void); - - -/* select which led to use on the button lights. Other combinations are - * possible, but don't look very good. - */ - -/* map the mode from the command into the state machine entries */ -/* See enum buttonlight_mode for available functions */ -void __buttonlight_mode(enum buttonlight_mode mode, - enum buttonlight_selection selection, - unsigned short brightness); - - -bool __backlight_init(void); -void __backlight_on(void); -void __backlight_off(void); -void __backlight_set_brightness(int val); - -/* true: backlight fades off - false: backlight fades on */ -void __backlight_dim(bool dim); - -#endif diff --git a/firmware/target/arm/gigabeat/meg-fx/button-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/button-meg-fx.c deleted file mode 100644 index 71d45c385c..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/button-meg-fx.c +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include -#include "config.h" -#include "cpu.h" -#include "system.h" -#include "button.h" -#include "kernel.h" -#include "backlight.h" -#include "adc.h" -#include "system.h" -#include "backlight-target.h" - -static bool headphones_detect; -static bool hold_button = false; - -static int const remote_buttons[] = -{ - BUTTON_NONE, /* Headphones connected - remote disconnected */ - BUTTON_SELECT, - BUTTON_MENU, /* could be changed to BUTTON_A */ - BUTTON_LEFT, - BUTTON_RIGHT, - BUTTON_UP, /* could be changed to BUTTON_VOL_UP */ - BUTTON_DOWN, /* could be changed to BUTTON_VOL_DOWN */ - BUTTON_NONE, /* Remote control attached - no buttons pressed */ - BUTTON_NONE, /* Nothing in the headphone socket */ -}; - - - - - -void button_init_device(void) -{ - /* Power, Remote Play & Hold switch */ -} - - - -inline bool button_hold(void) -{ - return (GPGDAT & (1 << 15)); -} - - - -int button_read_device(void) -{ - int touchpad; - int buttons; - static int lastbutton; - unsigned short remote_adc; - int btn = BUTTON_NONE; - bool hold_button_old; - - /* normal buttons */ - hold_button_old = hold_button; - hold_button = button_hold(); - -#ifndef BOOTLOADER - /* give BL notice if HB state chaged */ - if (hold_button != hold_button_old) - backlight_hold_changed(hold_button); -#endif - - /* See header for ADC values when remote control buttons are pressed */ - /* Only one button can be sensed at a time on the remote. */ - /* Need to filter the remote button because the ADC is so fast */ - remote_adc = adc_read(ADC_HPREMOTE); - btn = remote_buttons[(remote_adc + 64) / 128]; - if (btn != lastbutton) - { - /* if the buttons dont agree twice in a row, then its none */ - lastbutton = btn; - btn = BUTTON_NONE; - } - - /* Check for hold first - exit if asserted with no button pressed */ - if (hold_button) - return btn; - - /* the side buttons - Check before doing all of the work on each bit */ - buttons = GPGDAT & 0x1F; - if (buttons) - { - if (buttons & (1 << 0)) - btn |= BUTTON_POWER; - - if (buttons & (1 << 1)) - btn |= BUTTON_MENU; - - if (buttons & (1 << 2)) - btn |= BUTTON_VOL_UP; - - if (buttons & (1 << 3)) - btn |= BUTTON_VOL_DOWN; - - if (buttons & (1 << 4)) - btn |= BUTTON_A; - } - - /* the touchpad */ - touchpad = GPJDAT & 0x10C9; - if (touchpad) - { - if (touchpad & (1 << 0)) - btn |= BUTTON_UP; - - if (touchpad & (1 << 12)) - btn |= BUTTON_RIGHT; - - if (touchpad & (1 << 6)) - btn |= BUTTON_DOWN; - - if (touchpad & (1 << 7)) - btn |= BUTTON_LEFT; - - if (touchpad & (1 << 3)) - btn |= BUTTON_SELECT; - } - - return btn; -} - - - -bool headphones_inserted(void) -{ - unsigned short remote_adc = adc_read(ADC_HPREMOTE); - if (remote_adc != ADC_READ_ERROR) - { - /* If there is nothing in the headphone socket, the ADC reads high */ - if (remote_adc < 940) - headphones_detect = true; - else - headphones_detect = false; - } - return headphones_detect; -} diff --git a/firmware/target/arm/gigabeat/meg-fx/button-target.h b/firmware/target/arm/gigabeat/meg-fx/button-target.h deleted file mode 100644 index ab68e8050f..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/button-target.h +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef _BUTTON_TARGET_H_ -#define _BUTTON_TARGET_H_ - -#include -#include "config.h" - -#define HAS_BUTTON_HOLD - -bool button_hold(void); -void button_init_device(void); -int button_read_device(void); - -/* Toshiba Gigabeat specific button codes */ - -#define BUTTON_POWER 0x00000001 -#define BUTTON_MENU 0x00000002 - -#define BUTTON_LEFT 0x00000004 -#define BUTTON_RIGHT 0x00000008 -#define BUTTON_UP 0x00000010 -#define BUTTON_DOWN 0x00000020 - -#define BUTTON_VOL_UP 0x00000040 -#define BUTTON_VOL_DOWN 0x00000080 - -#define BUTTON_SELECT 0x00000100 -#define BUTTON_A 0x00000200 - - -/* Toshiba Gigabeat specific remote button ADC values */ -/* The remote control uses ADC 1 to emulate button pushes - Reading (approx) Button HP plugged in? Remote plugged in? - 0 N/A Yes No - 125 Play/Pause Cant tell Yes - 241 Speaker+ Cant tell Yes - 369 Rewind Cant tell Yes - 492 Fast Fwd Cant tell Yes - 616 Vol + Cant tell Yes - 742 Vol - Cant tell Yes - 864 None Cant tell Yes - 1023 N/A No No -*/ - -/* - Notes: - - Buttons on the remote are translated into equivalent button presses just - as if you were pressing them on the Gigabeat itself. - - We cannot tell if the hold is asserted on the remote. The Hold function on - the remote is to block the output of the buttons changing. - - Only one button can be sensed at a time. If another is pressed, the button - with the lowest reading is dominant. So, if Rewind and Vol + are pressed - at the same time, Rewind value is the one that is read. -*/ - - - - -#define BUTTON_MAIN (BUTTON_POWER|BUTTON_MENU|BUTTON_LEFT|BUTTON_RIGHT\ - |BUTTON_UP|BUTTON_DOWN|BUTTON_VOL_UP|BUTTON_VOL_DOWN\ - |BUTTON_SELECT|BUTTON_A) - - -#define BUTTON_REMOTE 0 - -#define POWEROFF_BUTTON BUTTON_POWER -#define POWEROFF_COUNT 10 - -#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/gigabeat/meg-fx/dma_start.c b/firmware/target/arm/gigabeat/meg-fx/dma_start.c deleted file mode 100644 index c1ab6c15cb..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/dma_start.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -void dma_start(const void* addr, size_t size) { - (void) addr; - (void) size; - //TODO: -} - diff --git a/firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.c deleted file mode 100644 index 670d6cd04c..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.c +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "config.h" -#include "cpu.h" -#include -#include "kernel.h" -#include "system.h" -#include "logf.h" -#include "debug.h" -#include "string.h" -#include "generic_i2c.h" - -static void i2c_sda_output(void) -{ - GPECON |= (1 << 30); -} - -static void i2c_sda_input(void) -{ - GPECON &= ~(3 << 30); -} - -static void i2c_sda_lo(void) -{ - GPEDAT &= ~(1 << 15); -} - -static void i2c_sda_hi(void) -{ - GPEDAT |= (1 << 15); -} - -static int i2c_sda(void) -{ - return GPEDAT & (1 << 15); -} - -static void i2c_scl_output(void) -{ - GPECON |= (1 << 28); -} - -static void i2c_scl_input(void) -{ - GPECON &= ~(3 << 28); -} - -static void i2c_scl_lo(void) -{ - GPEDAT &= ~(1 << 14); -} - -static int i2c_scl(void) -{ - return GPEDAT & (1 << 14); -} - -static void i2c_scl_hi(void) -{ - i2c_scl_input(); - while(!i2c_scl()); - GPEDAT |= (1 << 14); - i2c_scl_output(); -} - - - -static void i2c_delay(void) -{ - unsigned _x; - - /* The i2c can clock at 500KHz: 2uS period -> 1uS half period */ - /* about 30 cycles overhead + X * 7 */ - /* 300MHz: 1000nS @3.36nS/cyc = 297cyc: X = 38*/ - /* 100MHz: 1000nS @10nS/cyc = 100cyc : X = 10 */ - for (_x = 38; _x; _x--) - { - /* burn CPU cycles */ - /* gcc makes it an inc loop - check with objdump for asm timing */ - } -} - - - -struct i2c_interface s3c2440_i2c = { - 0x34, /* Address */ - - /* Bit-banged interface definitions */ - i2c_scl_hi, /* Drive SCL high, might sleep on clk stretch */ - i2c_scl_lo, /* Drive SCL low */ - i2c_sda_hi, /* Drive SDA high */ - i2c_sda_lo, /* Drive SDA low */ - i2c_sda_input, /* Set SDA as input */ - i2c_sda_output, /* Set SDA as output */ - i2c_scl_input, /* Set SCL as input */ - i2c_scl_output, /* Set SCL as output */ - i2c_scl, /* Read SCL, returns 0 or nonzero */ - i2c_sda, /* Read SDA, returns 0 or nonzero */ - - i2c_delay, /* START SDA hold time (tHD:SDA) */ - i2c_delay, /* SDA hold time (tHD:DAT) */ - i2c_delay, /* SDA setup time (tSU:DAT) */ - i2c_delay, /* STOP setup time (tSU:STO) */ - i2c_delay, /* Rep. START setup time (tSU:STA) */ - i2c_delay, /* SCL high period (tHIGH) */ -}; - -void i2c_init(void) -{ - /* Set GPE15 (SDA) and GPE14 (SCL) to 1 */ - GPECON = (GPECON & ~(0xF<<28)) | 5<<28; - i2c_add_node(&s3c2440_i2c); -} - -void i2c_send(int bus_address, int reg_address, const unsigned char buf) -{ - i2c_write_data(bus_address, reg_address, &buf, 1); -} diff --git a/firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.h b/firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.h deleted file mode 100644 index cf69230487..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/i2c-meg-fx.h +++ /dev/null @@ -1,22 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -/* chip-specific i2c functions */ - -void i2c_send(int bus_address, int reg_address, const unsigned char buf); diff --git a/firmware/target/arm/gigabeat/meg-fx/kernel-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/kernel-meg-fx.c deleted file mode 100644 index 9df90a2344..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/kernel-meg-fx.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "kernel.h" -#include "thread.h" - -#include -#include "lcd.h" - -extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); - -void timer4(void) { - int i; - /* Run through the list of tick tasks */ - for(i = 0; i < MAX_NUM_TICK_TASKS; i++) - { - if(tick_funcs[i]) - { - tick_funcs[i](); - } - } - - current_tick++; - - /* following needs to be fixed. */ - /*wake_up_thread();*/ -} - diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-as-meg-fx.S b/firmware/target/arm/gigabeat/meg-fx/lcd-as-meg-fx.S deleted file mode 100644 index d431c95f29..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/lcd-as-meg-fx.S +++ /dev/null @@ -1,222 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 by Michael Sevakis - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "config.h" -#include "cpu.h" - -/**************************************************************************** - * void lcd_write_yuv_420_lines(fb_data *dst, - * unsigned char chroma_buf[LCD_HEIGHT/2*3], - unsigned char const * const src[3], - * int width, - * int stride); - * - * |R| |1.000000 -0.000001 1.402000| |Y'| - * |G| = |1.000000 -0.334136 -0.714136| |Pb| - * |B| |1.000000 1.772000 0.000000| |Pr| - * Scaled, normalized, rounded and tweaked to yield RGB 565: - * |R| |74 0 101| |Y' - 16| >> 9 - * |G| = |74 -24 -51| |Cb - 128| >> 8 - * |B| |74 128 0| |Cr - 128| >> 9 - */ - .section .icode, "ax", %progbits - .align 2 - .global lcd_write_yuv420_lines - .type lcd_write_yuv420_lines, %function -lcd_write_yuv420_lines: - @ r0 = dst - @ r1 = chroma_buf - @ r2 = yuv_src - @ r3 = width - @ [sp] = stride - stmdb sp!, { r4-r12, lr } @ save non-scratch - stmdb sp!, { r0, r3 } @ save dst and width - mov r14, #74 @ r14 = Y factor - ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p - @ r5 = yuv_src[1] = Cb_p - @ r6 = yuv_src[2] = Cr_p -10: @ loop line 1 @ - ldrb r2, [r4], #1 @ r2 = *Y'_p++; - ldrb r8, [r5], #1 @ r8 = *Cb_p++; - ldrb r11, [r6], #1 @ r11 = *Cr_p++; - @ - @ compute Y - sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 - mul r7, r2, r14 @ - @ - sub r8, r8, #128 @ Cb -= 128 - sub r11, r11, #128 @ Cr -= 128 - @ - mvn r2, #24 @ compute guv - mul r10, r2, r8 @ r10 = Cb*-24 - mvn r2, #51 @ - mla r10, r2, r11, r10 @ r10 = r10 + Cr*-51 - @ - mov r2, #101 @ compute rv - mul r9, r11, r2 @ r9 = rv = Cr*101 - @ - @ store chromas in line buffer - add r8, r8, #2 @ bu = (Cb + 2) >> 2 - mov r8, r8, asr #2 @ - strb r8, [r1], #1 @ - add r9, r9, #256 @ rv = (Cr + 256) >> 9 - mov r9, r9, asr #9 @ - strb r9, [r1], #1 @ - mov r10, r10, asr #8 @ guv >>= 8 - strb r10, [r1], #1 @ - @ compute R, G, and B - add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu - add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv - add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv - @ - orr r12, r2, r11 @ check if clamping is needed... - orr r12, r12, r7, asr #1 @ ...at all - cmp r12, #31 @ - bls 15f @ no clamp @ - mov r12, #31 @ - cmp r12, r2 @ clamp b - andlo r2, r12, r2, asr #31 @ - eorlo r2, r2, r12 @ - cmp r12, r11 @ clamp r - andlo r11, r12, r11, asr #31 @ - eorlo r11, r11, r12 @ - cmp r12, r7, asr #1 @ clamp g - andlo r7, r12, r7, asr #31 @ - eorlo r7, r7, r12 @ - orrlo r7, r7, r7, asl #1 @ -15: @ no clamp @ - @ - orr r12, r2, r7, lsl #5 @ r4 |= (g << 5) - ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ - orr r12, r12, r11, lsl #11 @ r4 = b | (r << 11) - strh r12, [r0], #240 @ store pixel - @ - sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 - mul r7, r2, r14 @ next Y - @ compute R, G, and B - add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu - add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv - add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv - @ - orr r12, r2, r11 @ check if clamping is needed... - orr r12, r12, r7, asr #1 @ ...at all - cmp r12, #31 @ - bls 15f @ no clamp @ - mov r12, #31 @ - cmp r12, r2 @ clamp b - andlo r2, r12, r2, asr #31 @ - eorlo r2, r2, r12 @ - cmp r12, r11 @ clamp r - andlo r11, r12, r11, asr #31 @ - eorlo r11, r11, r12 @ - cmp r12, r7, asr #1 @ clamp g - andlo r7, r12, r7, asr #31 @ - eorlo r7, r7, r12 @ - orrlo r7, r7, r7, asl #1 @ -15: @ no clamp @ - @ - orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) - orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) - strh r12, [r0, #240]! @ store pixel - add r0, r0, #2*240 @ - @ - subs r3, r3, #2 @ - bgt 10b @ loop line 1 @ - @ do second line - @ - ldmia sp!, { r0, r3 } @ pop dst and width - sub r0, r0, #2 @ set dst to start of next line - sub r1, r1, r3, asl #1 @ rewind chroma pointer... - ldr r2, [sp, #40] @ r2 = stride - add r1, r1, r3, asr #1 @ ... (r1 -= width/2*3) - @ move sources to start of next line - sub r2, r2, r3 @ r2 = skip = stride - width - add r4, r4, r2 @ r4 = Y'_p + skip - @ -20: @ loop line 2 @ - ldrb r2, [r4], #1 @ r7 = Y' = *Y'_p++ - ldrsb r8, [r1], #1 @ reload saved chromas - ldrsb r9, [r1], #1 @ - ldrsb r10, [r1], #1 @ - @ - sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 - mul r7, r2, r14 @ - @ compute R, G, and B - add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu - add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv - add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv - @ - orr r12, r2, r11 @ check if clamping is needed... - orr r12, r12, r7, asr #1 @ ...at all - cmp r12, #31 @ - bls 25f @ no clamp @ - mov r12, #31 @ - cmp r12, r2 @ clamp b - andlo r2, r12, r2, asr #31 @ - eorlo r2, r2, r12 @ - cmp r12, r11 @ clamp r - andlo r11, r12, r11, asr #31 @ - eorlo r11, r11, r12 @ - cmp r12, r7, asr #1 @ clamp g - andlo r7, r12, r7, asr #31 @ - eorlo r7, r7, r12 @ - orrlo r7, r7, r7, asl #1 @ -25: @ no clamp @ - @ - orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) - ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ - orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) - strh r12, [r0], #240 @ store pixel - @ - @ do second pixel - @ - sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 - mul r7, r2, r14 @ - @ compute R, G, and B - add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu - add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv - add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv - @ - orr r12, r2, r11 @ check if clamping is needed... - orr r12, r12, r7, asr #1 @ ...at all - cmp r12, #31 @ - bls 25f @ no clamp @ - mov r12, #31 @ - cmp r12, r2 @ clamp b - andlo r2, r12, r2, asr #31 @ - eorlo r2, r2, r12 @ - cmp r12, r11 @ clamp r - andlo r11, r12, r11, asr #31 @ - eorlo r11, r11, r12 @ - cmp r12, r7, asr #1 @ clamp g - andlo r7, r12, r7, asr #31 @ - eorlo r7, r7, r12 @ - orrlo r7, r7, r7, asl #1 @ -25: @ no clamp @ - @ - orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) - orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) - strh r12, [r0, #240]! @ store pixel - add r0, r0, #2*240 @ - @ - subs r3, r3, #2 @ - bgt 20b @ loop line 2 @ - @ - ldmia sp!, { r4-r12, pc } @ restore registers and return - .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c deleted file mode 100644 index 1bb68f9686..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c +++ /dev/null @@ -1,367 +0,0 @@ -#include "config.h" -#include -#include "cpu.h" -#include "lcd.h" -#include "kernel.h" -#include "system.h" -#include "mmu-meg-fx.h" -#include -#include "memory.h" -#include "lcd-target.h" -#include "font.h" -#include "rbunicode.h" -#include "bidi.h" - -#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) -/* -** We prepare foreground and background fills ahead of time - DMA fills in 16 byte groups -*/ -unsigned long fg_pattern_blit[4]; -unsigned long bg_pattern_blit[4]; - -volatile bool use_dma_blit = false; -static volatile bool lcd_on = true; -volatile bool lcd_poweroff = false; -/* -** These are imported from lcd-16bit.c -*/ -extern unsigned fg_pattern; -extern unsigned bg_pattern; - -bool lcd_enabled() -{ - return lcd_on; -} - -unsigned int LCDBANK(unsigned int address) -{ - return ((address >> 22) & 0xff); -} - -unsigned int LCDBASEU(unsigned int address) -{ - return (address & ((1 << 22)-1)) >> 1; -} - -unsigned int LCDBASEL(unsigned int address) -{ - address += 320*240*2; - return (address & ((1 << 22)-1)) >> 1; -} - - -/* LCD init */ -void lcd_init_device(void) -{ - LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME)); - LCDSADDR2 = LCDBASEL((unsigned)FRAME); - LCDSADDR3 = 0x000000F0; - - LCDCON5 |= 1 << 11; /* Switch from 555I mode to 565 mode */ - -#if !defined(BOOTLOADER) - memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); - memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); - clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); - clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); - use_dma_blit = true; - lcd_poweroff = false; -#endif -} - -/* Update a fraction of the display. */ -void lcd_update_rect(int x, int y, int width, int height) -{ - (void)x; - (void)width; - (void)y; - (void)height; - - if(!lcd_on) - { - sleep(200); - return; - } - if (use_dma_blit) - { - /* Wait for this controller to stop pending transfer */ - while((DSTAT1 & 0x000fffff)) - CLKCON |= (1 << 2); /* set IDLE bit */ - - /* Flush DCache */ - invalidate_dcache_range((void *)(((int) &lcd_framebuffer[0][0])+(y * sizeof(fb_data) * LCD_WIDTH)), (height * sizeof(fb_data) * LCD_WIDTH)); - - /* set DMA dest */ - DIDST1 = ((int) FRAME) + (y * sizeof(fb_data) * LCD_WIDTH); - - /* FRAME on AHB buf, increment */ - DIDSTC1 = 0; - /* Handshake on AHB, Burst transfer, Whole service, Don't reload, transfer 32-bits */ - DCON1 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((height * sizeof(fb_data) * LCD_WIDTH) >> 4); - - /* set DMA source */ - DISRC1 = ((int) &lcd_framebuffer[0][0]) + (y * sizeof(fb_data) * LCD_WIDTH) + 0x30000000; - /* memory is on AHB bus, increment addresses */ - DISRCC1 = 0x00; - - /* Activate the channel */ - DMASKTRIG1 = 0x2; - - /* Start DMA */ - DMASKTRIG1 |= 0x1; - - /* Wait for transfer to complete */ - while((DSTAT1 & 0x000fffff)) - CLKCON |= (1 << 2); /* set IDLE bit */ - } - else - memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); -} - - -void lcd_enable(bool state) -{ - if(!lcd_poweroff) - return; - if(state) { - if(!lcd_on) { - lcd_on = true; - memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); - LCDCON1 |= 1; - } - } - else { - if(lcd_on) { - lcd_on = false; - LCDCON1 &= ~1; - } - } -} - -void lcd_set_foreground(unsigned color) -{ - fg_pattern = color; - - memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); - invalidate_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); -} - -void lcd_set_background(unsigned color) -{ - bg_pattern = color; - memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); - invalidate_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); -} - -void lcd_device_prepare_backdrop(fb_data* backdrop) -{ - if(backdrop) - invalidate_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); -} - -void lcd_clear_display_dma(void) -{ - void *src; - bool inc = false; - - if(!lcd_on) { - sleep(200); - } - if (lcd_get_drawmode() & DRMODE_INVERSEVID) - src = fg_pattern_blit; - else - { - fb_data* lcd_backdrop = lcd_get_backdrop(); - - if (!lcd_backdrop) - src = bg_pattern_blit; - else - { - src = lcd_backdrop; - inc = true; - } - } - /* Wait for any pending transfer to complete */ - while((DSTAT3 & 0x000fffff)) - CLKCON |= (1 << 2); /* set IDLE bit */ - DMASKTRIG3 |= 0x4; /* Stop controller */ - DIDST3 = ((int) &lcd_framebuffer[0][0]) + 0x30000000; /* set DMA dest, physical address */ - DIDSTC3 = 0; /* Dest on AHB, increment */ - - DISRC3 = ((int) src) + 0x30000000; /* Set source, in physical space */ - DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */ - - /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */ - DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data)) >> 4); - - /* Dump DCache for dest, we are about to overwrite it with DMA */ - invalidate_dcache_range((void *)lcd_framebuffer, sizeof(lcd_framebuffer)); - /* Activate the channel */ - DMASKTRIG3 = 2; - /* Start DMA */ - DMASKTRIG3 |= 1; - - /* Wait for transfer to complete */ - while((DSTAT3 & 0x000fffff)) - CLKCON |= (1 << 2); /* set IDLE bit */ -} - -void lcd_clear_display(void) -{ - lcd_stop_scroll(); - - if(use_dma_blit) - { - lcd_clear_display_dma(); - return; - } - - fb_data *dst = &lcd_framebuffer[0][0]; - - if (lcd_get_drawmode() & DRMODE_INVERSEVID) - { - memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT); - } - else - { - fb_data* lcd_backdrop = lcd_get_backdrop(); - if (!lcd_backdrop) - memset16(dst, bg_pattern, LCD_WIDTH*LCD_HEIGHT); - else - memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); - } -} - - -/* Update the display. - This must be called after all other LCD functions that change the display. */ -void lcd_update(void) -{ - lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); -} - -void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, - int stride, int x, int y, int width, - int height) -{ - fb_data *dst, *dst_end; - unsigned int transcolor; - - /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) - || (x + width <= 0) || (y + height <= 0)) - return; - - /* clipping */ - if (x < 0) - { - width += x; - src_x -= x; - x = 0; - } - if (y < 0) - { - height += y; - src_y -= y; - y = 0; - } - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; - - src += stride * src_y + src_x; /* move starting point */ - dst = &lcd_framebuffer[(y)][(x)]; - dst_end = dst + height * LCD_WIDTH; - width *= 2; - stride *= 2; - transcolor = TRANSPARENT_COLOR; - asm volatile( - "rowstart: \n" - "mov r0, #0 \n" - "nextpixel: \n" - "ldrh r1, [%0, r0] \n" /* Load word src+r0 */ - "cmp r1, %5 \n" /* Compare to transparent color */ - "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */ - "add r0, r0, #2 \n" - "cmp r0, %2 \n" /* r0 == width? */ - "bne nextpixel \n" /* More in this row? */ - "add %0, %0, %4 \n" /* src += stride */ - "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */ - "cmp %1, %3 \n" - "bne rowstart \n" /* if(dst != dst_end), keep going */ - : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" ); -} - -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(fb_data *dst, - unsigned char chroma_buf[LCD_HEIGHT/2*3], - unsigned char const * const src[3], - int width, - int stride); -/* Performance function to blit a YUV bitmap directly to the LCD */ -/* For the Gigabeat - show it rotated */ -/* So the LCD_WIDTH is now the height */ -void lcd_yuv_blit(unsigned char * const src[3], - int src_x, int src_y, int stride, - int x, int y, int width, int height) -{ - /* Caches for chroma data so it only need be recaculated every other - line */ - unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ - unsigned char const * yuv_src[3]; - off_t z; - - if (!lcd_on) - return; - - /* Sorry, but width and height must be >= 2 or else */ - width &= ~1; - height >>= 1; - - fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; - - z = stride*src_y; - yuv_src[0] = src[0] + z + src_x; - yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); - yuv_src[2] = src[2] + (yuv_src[1] - src[1]); - - do - { - lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, - stride); - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst -= 2; - } - while (--height > 0); -} - -void lcd_set_contrast(int val) { - (void) val; - // TODO: -} - -void lcd_set_invert_display(bool yesno) { - (void) yesno; - // TODO: -} - -void lcd_blit(const fb_data* data, int bx, int y, int bwidth, - int height, int stride) -{ - (void) data; - (void) bx; - (void) y; - (void) bwidth; - (void) height; - (void) stride; - //TODO: -} - -void lcd_set_flip(bool yesno) { - (void) yesno; - // TODO: -} - diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-target.h b/firmware/target/arm/gigabeat/meg-fx/lcd-target.h deleted file mode 100644 index cb2a89f349..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/lcd-target.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id $ - * - * Copyright (C) 2007 by Greg White - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -extern void lcd_enable(bool state); - diff --git a/firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.c deleted file mode 100644 index 6142213f0c..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.c +++ /dev/null @@ -1,222 +0,0 @@ -#include -#include "s3c2440.h" -#include "mmu-meg-fx.h" -#include "panic.h" - -void map_memory(void); -static void enable_mmu(void); -static void set_ttb(void); -static void set_page_tables(void); -static void map_section(unsigned int pa, unsigned int va, int mb, int cache_flags); - -#define SECTION_ADDRESS_MASK (-1 << 20) -#define CACHE_ALL (1 << 3 | 1 << 2 ) -#define CACHE_NONE 0 -#define BUFFERED (1 << 2) -#define MB (1 << 20) - -void map_memory(void) { - set_ttb(); - set_page_tables(); - enable_mmu(); -} - -unsigned int* ttb_base = (unsigned int *) TTB_BASE; -const int ttb_size = 4096; - -void set_ttb() { - int i; - int* ttbPtr; - int domain_access; - - /* must be 16Kb (0x4000) aligned */ - ttb_base = (int*) TTB_BASE; - for (i=0; i> 20; /* sections are 1Mb size */ - ttbPtr = ttb_base + section_no; - pa &= SECTION_ADDRESS_MASK; /* align to 1Mb */ - for(i=0; i ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006,2007 by Greg White - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -/* Invalidate DCache for this range */ -/* Will do write back */ -void invalidate_dcache_range(const void *base, unsigned int size); - -/* clean DCache for this range */ -/* forces DCache writeback for the specified range */ -void clean_dcache_range(const void *base, unsigned int size); - -/* Dump DCache for this range */ -/* Will *NOT* do write back */ -void dump_dcache_range(const void *base, unsigned int size); - -/* Cleans entire DCache */ -void clean_dcache(void); - - diff --git a/firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c deleted file mode 100644 index 0f22aa5c5c..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c +++ /dev/null @@ -1,376 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Michael Sevakis - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "system.h" -#include "kernel.h" -#include "logf.h" -#include "audio.h" -#include "sound.h" -#include "file.h" -#include "mmu-meg-fx.h" - -static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ - -#define GIGABEAT_8000HZ 0x4d -#define GIGABEAT_11025HZ 0x32 -#define GIGABEAT_12000HZ 0x61 -#define GIGABEAT_16000HZ 0x55 -#define GIGABEAT_22050HZ 0x36 -#define GIGABEAT_24000HZ 0x79 -#define GIGABEAT_32000HZ 0x59 -#define GIGABEAT_44100HZ 0x22 -#define GIGABEAT_48000HZ 0x41 -#define GIGABEAT_88200HZ 0x3e -#define GIGABEAT_96000HZ 0x5d - -#define FIFO_COUNT ((IISFCON >> 6) & 0x01F) - -/* number of bytes in FIFO */ -#define IIS_FIFO_SIZE 64 - -/* Setup for the DMA controller */ -#define DMA_CONTROL_SETUP ((1<<31) | (1<<29) | (1<<23) | (1<<22) | (1<<20)) - -unsigned short * p; -size_t p_size; - - - -/* DMA count has hit zero - no more data */ -/* Get more data from the callback and top off the FIFO */ -//void fiq(void) __attribute__ ((interrupt ("naked"))); -void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ"))); -void fiq(void) -{ - /* clear any pending interrupt */ - SRCPND = (1<<19); - - /* Buffer empty. Try to get more. */ - if (pcm_callback_for_more) - { - pcm_callback_for_more((unsigned char**)&p, &p_size); - } - else - { - /* callback func is missing? */ - pcm_play_dma_stop(); - return; - } - - if (p_size) - { - /* Flush any pending cache writes */ - clean_dcache_range(p, p_size); - - /* set the new DMA values */ - DCON2 = DMA_CONTROL_SETUP | (p_size >> 1); - DISRC2 = (int)p + 0x30000000; - - /* Re-Activate the channel */ - DMASKTRIG2 = 0x2; - } - else - { - /* No more DMA to do */ - pcm_play_dma_stop(); - } - -} - - - -void pcm_init(void) -{ - pcm_playing = false; - pcm_paused = false; - pcm_callback_for_more = NULL; - - audiohw_init(); - audiohw_enable_output(true); - - /* cannot use the WM8975 defaults since our clock is not the same */ - /* the input master clock is 16.9344MHz - we can divide exact for that */ - pcm_set_frequency(SAMPR_44); - - /* init GPIO */ - GPCCON = (GPCCON & ~(3<<14)) | (1<<14); - GPCDAT |= 1<<7; - GPECON |= 0x2aa; - - /* Do not service DMA requests, yet */ - /* clear any pending int and mask it */ - INTMSK |= (1<<19); /* mask the interrupt */ - SRCPND = (1<<19); /* clear any pending interrupts */ - INTMOD |= (1<<19); /* connect to FIQ */ - -} - -void pcm_postinit(void) -{ - audiohw_postinit(); -} - -void pcm_play_dma_start(const void *addr, size_t size) -{ - /* sanity check: bad pointer or too small file */ - if (NULL == addr || size <= IIS_FIFO_SIZE) return; - - p = (unsigned short *)addr; - p_size = size; - - /* Enable the IIS clock */ - CLKCON |= (1<<17); - - /* IIS interface setup and set to idle */ - IISCON = (1<<5) | (1<<3); - - /* slave, transmit mode, 16 bit samples - 384fs - use 16.9344Mhz */ - IISMOD = (1<<9) | (1<<8) | (2<<6) | (1<<3) | (1<<2); - - /* connect DMA to the FIFO and enable the FIFO */ - IISFCON = (1<<15) | (1<<13); - - /* set DMA dest */ - DIDST2 = (int)&IISFIFO; - - /* IIS is on the APB bus, INT when TC reaches 0, fixed dest addr */ - DIDSTC2 = 0x03; - - /* How many transfers to make - we transfer half-word at a time = 2 bytes */ - /* DMA control: CURR_TC int, single service mode, I2SSDO int, HW trig */ - /* no auto-reload, half-word (16bit) */ - DCON2 = DMA_CONTROL_SETUP | (p_size / 2); - - /* set DMA source and options */ - DISRC2 = (int)p + 0x30000000; - DISRCC2 = 0x00; /* memory is on AHB bus, increment addresses */ - - /* clear pending DMA interrupt */ - SRCPND = 1<<19; - - set_fiq_handler(fiq); - enable_fiq(); - - /* unmask the DMA interrupt */ - INTMSK &= ~(1<<19); - - /* Flush any pending writes */ - clean_dcache_range(addr, size); - - /* Activate the channel */ - DMASKTRIG2 = 0x2; - - /* turn off the idle */ - IISCON &= ~(1<<3); - - pcm_playing = true; - - /* start the IIS */ - IISCON |= (1<<0); - -} - - - -/* Disconnect the DMA and wait for the FIFO to clear */ -void pcm_play_dma_stop(void) -{ - /* mask the DMA interrupt */ - INTMSK |= (1<<19); - - /* are we playing? wait for the chunk to finish */ - if (pcm_playing) - { - /* wait for the FIFO to empty before turning things off */ - while (IISCON & (1<<7)) ; - - pcm_playing = false; - } - - /* De-Activate the DMA channel */ - DMASKTRIG2 = 0x4; - - /* Disconnect the IIS clock */ - CLKCON &= ~(1<<17); - - disable_fiq(); - -} - - - -void pcm_play_pause_pause(void) -{ - /* stop servicing refills */ - INTMSK |= (1<<19); -} - - - -void pcm_play_pause_unpause(void) -{ - /* refill buffer and keep going */ - INTMSK &= ~(1<<19); -} - -void pcm_set_frequency(unsigned int frequency) -{ - int sr_ctrl; - - switch(frequency) - { - case SAMPR_8: - sr_ctrl = GIGABEAT_8000HZ; - break; - case SAMPR_11: - sr_ctrl = GIGABEAT_11025HZ; - break; - case SAMPR_12: - sr_ctrl = GIGABEAT_12000HZ; - break; - case SAMPR_16: - sr_ctrl = GIGABEAT_16000HZ; - break; - case SAMPR_22: - sr_ctrl = GIGABEAT_22050HZ; - break; - case SAMPR_24: - sr_ctrl = GIGABEAT_24000HZ; - break; - case SAMPR_32: - sr_ctrl = GIGABEAT_32000HZ; - break; - default: - frequency = SAMPR_44; - case SAMPR_44: - sr_ctrl = GIGABEAT_44100HZ; - break; - case SAMPR_48: - sr_ctrl = GIGABEAT_48000HZ; - break; - case SAMPR_88: - sr_ctrl = GIGABEAT_88200HZ; - break; - case SAMPR_96: - sr_ctrl = GIGABEAT_96000HZ; - break; - } - - audiohw_set_sample_rate(sr_ctrl); - pcm_freq = frequency; -} - - - -size_t pcm_get_bytes_waiting(void) -{ - return (DSTAT2 & 0xFFFFF) * 2; -} - - - -/* dummy functions for those not actually supporting all this yet */ -void pcm_apply_settings(void) -{ -} - -void pcm_set_monitor(int monitor) -{ - (void)monitor; -} -/** **/ - -void pcm_mute(bool mute) -{ - audiohw_mute(mute); - if (mute) - sleep(HZ/16); -} - -/* - * This function goes directly into the DMA buffer to calculate the left and - * right peak values. To avoid missing peaks it tries to look forward two full - * peek periods (2/HZ sec, 100% overlap), although it's always possible that - * the entire period will not be visible. To reduce CPU load it only looks at - * every third sample, and this can be reduced even further if needed (even - * every tenth sample would still be pretty accurate). - */ - -/* Check for a peak every PEAK_STRIDE samples */ -#define PEAK_STRIDE 3 -/* Up to 1/50th of a second of audio for peak calculation */ -/* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */ -#define PEAK_SAMPLES (44100/50) -void pcm_calculate_peaks(int *left, int *right) -{ - short *addr; - short *end; - { - size_t samples = p_size / 4; - addr = p; - - if (samples > PEAK_SAMPLES) - samples = PEAK_SAMPLES - (PEAK_STRIDE - 1); - else - samples -= MIN(PEAK_STRIDE - 1, samples); - - end = &addr[samples * 2]; - } - - if (left && right) { - int left_peak = 0, right_peak = 0; - - while (addr < end) { - int value; - if ((value = addr [0]) > left_peak) - left_peak = value; - else if (-value > left_peak) - left_peak = -value; - - if ((value = addr [PEAK_STRIDE | 1]) > right_peak) - right_peak = value; - else if (-value > right_peak) - right_peak = -value; - - addr = &addr[PEAK_STRIDE * 2]; - } - - *left = left_peak; - *right = right_peak; - } - else if (left || right) { - int peak_value = 0, value; - - if (right) - addr += (PEAK_STRIDE | 1); - - while (addr < end) { - if ((value = addr [0]) > peak_value) - peak_value = value; - else if (-value > peak_value) - peak_value = -value; - - addr += PEAK_STRIDE * 2; - } - - if (left) - *left = peak_value; - else - *right = peak_value; - } -} diff --git a/firmware/target/arm/gigabeat/meg-fx/power-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/power-meg-fx.c deleted file mode 100644 index eb2ffb5238..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/power-meg-fx.c +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "config.h" -#include "cpu.h" -#include -#include "kernel.h" -#include "system.h" -#include "power.h" -#include "pcf50606.h" -#include "backlight.h" -#include "backlight-target.h" - -#ifndef SIMULATOR - -void power_init(void) -{ - /* Charger detect */ -} - -bool charger_inserted(void) -{ - return (GPFDAT & (1 << 4)) ? false : true; -} - -/* Returns true if the unit is charging the batteries. */ -bool charging_state(void) { - return (GPGDAT & (1 << 8)) ? false : true; -} - -void ide_power_enable(bool on) -{ - if (on) - GPGDAT |= (1 << 11); - else - GPGDAT &= ~(1 << 11); -} - -bool ide_powered(void) -{ - return (GPGDAT & (1 << 11)) != 0; -} - -void power_off(void) -{ - /* turn off backlight and wait for 1 second */ - __backlight_off(); - sleep(HZ/2); - /* set SLEEP bit to on in CLKCON to turn off */ - CLKCON |=(1<<3); -} - -#else /* SIMULATOR */ - -bool charger_inserted(void) -{ - return false; -} - -void charger_enable(bool on) -{ - (void)on; -} - -void power_off(void) -{ -} - -void ide_power_enable(bool on) -{ - (void)on; -} - -#endif /* SIMULATOR */ - diff --git a/firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.c deleted file mode 100644 index e69eab432a..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.c +++ /dev/null @@ -1,225 +0,0 @@ -#include "config.h" -#include "cpu.h" -#include -#include "kernel.h" -#include "system.h" -#include "logf.h" -#include "debug.h" -#include "string.h" - -#define SLAVE_ADDRESS 0xCC - -#define SDA_LO (GPHDAT &= ~(1 << 9)) -#define SDA_HI (GPHDAT |= (1 << 9)) -#define SDA_INPUT (GPHCON &= ~(3 << 18)) -#define SDA_OUTPUT (GPHCON |= (1 << 18)) -#define SDA (GPHDAT & (1 << 9)) - -#define SCL_LO (GPHDAT &= ~(1 << 10)) -#define SCL_HI (GPHDAT |= (1 << 10)) -#define SCL_INPUT (GPHCON &= ~(3 << 20)) -#define SCL_OUTPUT (GPHCON |= (1 << 20)) -#define SCL (GPHDAT & (1 << 10)) - -#define SCL_SDA_HI (GPHDAT |= (3 << 9)) - -/* The SC606 can clock at 400KHz: */ -/* Clock period high is 600nS and low is 1300nS */ -/* The high and low times are different enough to need different timings */ -/* cycles delayed = 30 + 7 * loops */ -/* 100MHz = 10nS per cycle: LO:1300nS=130:14 HI:600nS=60:9 */ -/* 300MHz = 3.36nS per cycle: LO:1300nS=387:51 HI:600nS=179:21 */ -#define DELAY_LO do{int x;for(x=51;x;x--);} while (0) -#define DELAY do{int x;for(x=35;x;x--);} while (0) -#define DELAY_HI do{int x;for(x=21;x;x--);} while (0) - - - -static void sc606_i2c_start(void) -{ - SCL_SDA_HI; - DELAY; - SDA_LO; - DELAY; - SCL_LO; -} - -static void sc606_i2c_restart(void) -{ - SCL_SDA_HI; - DELAY; - SDA_LO; - DELAY; - SCL_LO; -} - -static void sc606_i2c_stop(void) -{ - SDA_LO; - SCL_HI; - DELAY_HI; - SDA_HI; -} - -static void sc606_i2c_ack(void) -{ - - SDA_LO; - SCL_HI; - DELAY_HI; - SCL_LO; -} - - - -static int sc606_i2c_getack(void) -{ - int ret; - - /* Don't need a delay since follows a data bit with a delay on the end */ - SDA_INPUT; /* And set to input */ - DELAY; - SCL_HI; - - ret = (SDA != 0); /* ack failed if SDA is not low */ - DELAY_HI; - - SCL_LO; - DELAY_LO; - - SDA_HI; - SDA_OUTPUT; - DELAY_LO; - - return ret; -} - - - -static void sc606_i2c_outb(unsigned char byte) -{ - int i; - - /* clock out each bit, MSB first */ - for (i = 0x80; i; i >>= 1) - { - if (i & byte) - { - SDA_HI; - } - else - { - SDA_LO; - } - DELAY; - - SCL_HI; - DELAY_HI; - - SCL_LO; - DELAY_LO; - } - - SDA_HI; - -} - - - -static unsigned char sc606_i2c_inb(void) -{ - int i; - unsigned char byte = 0; - - SDA_INPUT; /* And set to input */ - /* clock in each bit, MSB first */ - for (i = 0x80; i; i >>= 1) { - SCL_HI; - - if (SDA) - byte |= i; - - SCL_LO; - } - SDA_OUTPUT; - - sc606_i2c_ack(); - - return byte; -} - - - -/* returns number of acks that were bad */ -int sc606_write(unsigned char reg, unsigned char data) -{ - int x; - - sc606_i2c_start(); - - sc606_i2c_outb(SLAVE_ADDRESS); - x = sc606_i2c_getack(); - - sc606_i2c_outb(reg); - x += sc606_i2c_getack(); - - sc606_i2c_restart(); - - sc606_i2c_outb(SLAVE_ADDRESS); - x += sc606_i2c_getack(); - - sc606_i2c_outb(data); - x += sc606_i2c_getack(); - - sc606_i2c_stop(); - - return x; -} - - - -int sc606_read(unsigned char reg, unsigned char* data) -{ - int x; - - sc606_i2c_start(); - sc606_i2c_outb(SLAVE_ADDRESS); - x = sc606_i2c_getack(); - - sc606_i2c_outb(reg); - x += sc606_i2c_getack(); - - sc606_i2c_restart(); - sc606_i2c_outb(SLAVE_ADDRESS | 1); - x += sc606_i2c_getack(); - - *data = sc606_i2c_inb(); - sc606_i2c_stop(); - - return x; -} - - - -void sc606_init(void) -{ - volatile int i; - - /* Set GPB2 (EN) to 1 */ - GPBCON = (GPBCON & ~(3<<4)) | 1<<4; - - /* Turn enable line on */ - GPBDAT |= 1<<2; - /* OFF GPBDAT &= ~(1 << 2); */ - - /* About 400us - needs 350us */ - for (i = 200; i; i--) - { - DELAY_LO; - } - - /* Set GPH9 (SDA) and GPH10 (SCL) to 1 */ - GPHUP &= ~(3<<9); - GPHCON = (GPHCON & ~(0xF<<18)) | 5<<18; -} - diff --git a/firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.h b/firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.h deleted file mode 100644 index 3ea0917e86..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/sc606-meg-fx.h +++ /dev/null @@ -1,28 +0,0 @@ -#include "config.h" -#include "cpu.h" -#include -#include "kernel.h" -#include "system.h" -#include "logf.h" -#include "debug.h" -#include "string.h" - -#define SC606_REG_A 0 -#define SC606_REG_B 1 -#define SC606_REG_C 2 -#define SC606_REG_CONF 3 - -#define SC606_LED_A1 (1 << 0) -#define SC606_LED_A2 (1 << 1) -#define SC606_LED_B1 (1 << 2) -#define SC606_LED_B2 (1 << 3) -#define SC606_LED_C1 (1 << 4) -#define SC606_LED_C2 (1 << 5) - -#define SC606_LOW_FREQ (1 << 6) - -int sc606_write(unsigned char reg, unsigned char data); - -int sc606_read(unsigned char reg, unsigned char* data); - -void sc606_init(void); diff --git a/firmware/target/arm/gigabeat/meg-fx/system-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/system-meg-fx.c deleted file mode 100644 index b7e59e66ea..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/system-meg-fx.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "kernel.h" -#include "system.h" -#include "panic.h" - -#include "lcd.h" -#include - -const int TIMER4_MASK = (1 << 14); -const int LCD_MASK = (1 << 16); -const int DMA0_MASK = (1 << 17); -const int DMA1_MASK = (1 << 18); -const int DMA2_MASK = (1 << 19); -const int DMA3_MASK = (1 << 20); - -int system_memory_guard(int newmode) -{ - (void)newmode; - return 0; -} - -extern void timer4(void); -extern void dma0(void); -extern void dma1(void); -extern void dma3(void); - -void irq(void) -{ - int intpending = INTPND; - - SRCPND = intpending; /* Clear this interrupt. */ - INTPND = intpending; /* Clear this interrupt. */ - - /* Timer 4 */ - if ((intpending & TIMER4_MASK) != 0) - timer4(); - else if ((intpending & DMA0_MASK) != 0) - dma0(); - else - { - /* unexpected interrupt */ - } -} - -void system_reboot(void) -{ - WTCON = 0; - WTCNT = WTDAT = 1 ; - WTCON = 0x21; - for(;;) - ; -} - -void system_init(void) -{ - /* Turn off un-needed devices */ - - /* Turn off all of the UARTS */ - CLKCON &= ~( (1<<10) | (1<<11) |(1<<12) ); - - /* Turn off AC97 and Camera */ - CLKCON &= ~( (1<<19) | (1<<20) ); - - /* Turn off USB host */ - CLKCON &= ~(1 << 6); - - /* Turn off NAND flash controller */ - CLKCON &= ~(1 << 4); - -} - - -#ifdef HAVE_ADJUSTABLE_CPU_FREQ - -void set_cpu_frequency(long frequency) -{ - if (frequency == CPUFREQ_MAX) - { - asm volatile("mov r0, #0\n" - "mrc p15, 0, r0, c1, c0, 0\n" - "orr r0, r0, #3<<30\n" /* set to Asynchronous mode*/ - "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); - - FREQ = CPUFREQ_MAX; - } - else - { - asm volatile("mov r0, #0\n" - "mrc p15, 0, r0, c1, c0, 0\n" - "bic r0, r0, #3<<30\n" /* set to FastBus mode*/ - "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); - - FREQ = CPUFREQ_NORMAL; - } -} - -#endif diff --git a/firmware/target/arm/gigabeat/meg-fx/system-target.h b/firmware/target/arm/gigabeat/meg-fx/system-target.h deleted file mode 100644 index 215b5a4daa..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/system-target.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 by Greg White - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef SYSTEM_TARGET_H -#define SYSTEM_TARGET_H - -#include "mmu-meg-fx.h" -#include "system-arm.h" - -#define CPUFREQ_DEFAULT 98784000 -#define CPUFREQ_NORMAL 98784000 -#define CPUFREQ_MAX 296352000 - -#define HAVE_INVALIDATE_ICACHE -static inline void invalidate_icache(void) -{ - clean_dcache(); - asm volatile( - "mov r0, #0 \n" - "mcr p15, 0, r0, c7, c5, 0 \n" - : : : "r0" - ); -} - -#endif /* SYSTEM_TARGET_H */ diff --git a/firmware/target/arm/gigabeat/meg-fx/usb-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/usb-meg-fx.c deleted file mode 100644 index 3aed8c3256..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/usb-meg-fx.c +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "config.h" -#include -#include "cpu.h" -#include "system.h" -#include "kernel.h" -#include "ata.h" - -#define USB_RST_ASSERT GPBDAT &= ~(1 << 4) -#define USB_RST_DEASSERT GPBDAT |= (1 << 4) - -#define USB_VPLUS_PWR_ASSERT GPBDAT |= (1 << 6) -#define USB_VPLUS_PWR_DEASSERT GPBDAT &= ~(1 << 6) - -#define USB_UNIT_IS_PRESENT !(GPFDAT & 0x01) -#define USB_CRADLE_IS_PRESENT ((GPFDAT &0x02)&&!(GPGDAT&1<<14)) - -#define USB_CRADLE_BUS_ENABLE GPHDAT |= (1 << 8) -#define USB_CRADLE_BUS_DISABLE GPHDAT &= ~(1 << 8) - -/* The usb detect is one pin to the cpu active low */ -inline bool usb_detect(void) -{ - return USB_UNIT_IS_PRESENT | USB_CRADLE_IS_PRESENT; -} - -void usb_init_device(void) -{ - /* Input is the default configuration, only pullups need to be disabled */ - GPFUP|=0x02; - - USB_VPLUS_PWR_ASSERT; - GPBCON=( GPBCON&~(1<<13) ) | (1 << 12); - - sleep(HZ/20); - - /* Reset the usb port */ - USB_RST_ASSERT; - GPBCON = (GPBCON & ~0x200) | 0x100; /* Make sure reset line is an output */ - - sleep(HZ/25); - USB_RST_DEASSERT; - - /* needed to complete the reset */ - ata_enable(false); - - sleep(HZ/15); /* 66ms */ - - ata_enable(true); - - sleep(HZ/25); - - /* leave chip in low power mode */ - USB_VPLUS_PWR_DEASSERT; - - sleep(HZ/25); -} - -void usb_enable(bool on) -{ - if (on) - { - USB_VPLUS_PWR_ASSERT; - if(USB_CRADLE_IS_PRESENT) USB_CRADLE_BUS_ENABLE; - } - else - { - if(USB_CRADLE_IS_PRESENT) USB_CRADLE_BUS_DISABLE; - USB_VPLUS_PWR_DEASSERT; - } - - /* Make sure USB_CRADLE_BUS pin is an output */ - GPHCON=( GPHCON&~(1<<17) ) | (1<<16); /* Make the pin an output */ - GPHUP|=1<<8; /* Disable pullup in SOC as we are now driving */ - - sleep(HZ/20); // > 50ms for detecting the enable state change -} diff --git a/firmware/target/arm/gigabeat/meg-fx/usb-target.h b/firmware/target/arm/gigabeat/meg-fx/usb-target.h deleted file mode 100644 index baeb539b38..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/usb-target.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef USB_TARGET_H -#define USB_TARGET_H - -bool usb_init_device(void); -bool usb_detect(void); -void usb_enable(bool on); - -#endif diff --git a/firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c deleted file mode 100644 index fe42b7527a..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Gigabeat specific code for the Wolfson codec - * - * 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) - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "lcd.h" -#include "cpu.h" -#include "kernel.h" -#include "thread.h" -#include "power.h" -#include "debug.h" -#include "system.h" -#include "sprintf.h" -#include "button.h" -#include "string.h" -#include "file.h" -#include "buffer.h" -#include "audio.h" -#include "i2c.h" -#include "i2c-meg-fx.h" -/* - * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit - */ -void i2s_reset(void) -{ -} - -/* - * Initialise the WM8975 for playback via headphone and line out. - * Note, I'm using the WM8750 datasheet as its apparently close. - */ -int audiohw_init(void) { - /* reset I2C */ - i2c_init(); - - /* GPC5 controls headphone output */ - GPCCON &= ~(0x3 << 10); - GPCCON |= (1 << 10); - GPCDAT |= (1 << 5); - - return 0; -} - -void audiohw_postinit(void) -{ -} - -void wmcodec_write(int reg, int data) -{ - i2c_send(0x34, (reg<<1) | ((data&0x100)>>8), data&0xff); -} diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c new file mode 100644 index 0000000000..4c448c2e41 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c @@ -0,0 +1,144 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Wade Brown + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "cpu.h" +#include "adc-target.h" +#include "kernel.h" + + + +static unsigned short adc_readings[NUM_ADC_CHANNELS]; + +/* prototypes */ +static unsigned short __adc_read(int channel); +static void adc_tick(void); + + + +void adc_init(void) +{ + int i; + + /* Turn on the ADC PCLK */ + CLKCON |= (1<<15); + + /* Set channel 0, normal mode, disable "start by read" */ + ADCCON &= ~(0x3F); + + /* No start delay. Use normal conversion mode. */ + ADCDLY = 0x1; + + /* Set and enable the prescaler */ + ADCCON = (ADCCON & ~(0xff<<6)) | (0x19<<6); + ADCCON |= (1<<14); + + /* prefill the adc channels */ + for (i = 0; i < NUM_ADC_CHANNELS; i++) + { + adc_readings[i] = __adc_read(i); + } + + /* start at zero so when the tick starts it is at zero */ + adc_readings[0] = __adc_read(0); + + /* attach the adc reading to the tick */ + tick_add_task(adc_tick); + + +} + + + +/* Called to get the recent ADC reading */ +inline unsigned short adc_read(int channel) +{ + return adc_readings[channel]; +} + + + +/** + * Read the ADC by polling + * @param channel The ADC channel to read + * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout + */ +static unsigned short __adc_read(int channel) +{ + int i; + + /* Set the channel */ + ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3); + + /* Start the conversion process */ + ADCCON |= 0x1; + + /* Wait for a low Enable_start */ + for (i = 20000;;) { + if(0 == (ADCCON & 0x1)) { + break; + } + else { + i--; + if (0 == i) { + /* Ran out of time */ + return ADC_READ_ERROR; + } + } + } + + /* Wait for high End_of_Conversion */ + for(i = 20000;;) { + if(ADCCON & (1<<15)) { + break; + } + else { + i--; + if(0 == i) { + /* Ran out of time */ + return ADC_READ_ERROR; + } + } + } + + return (ADCDAT0 & 0x3ff); +} + + + +/* add this to the tick so that the ADC converts are done in the background */ +static void adc_tick(void) +{ + static unsigned channel; + + /* Check if the End Of Conversion is set */ + if (ADCCON & (1<<15)) + { + adc_readings[channel] = (ADCDAT0 & 0x3FF); + if (++channel >= NUM_ADC_CHANNELS) + { + channel = 0; + } + + /* setup the next conversion and start it*/ + ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3) | 0x01; + } +} + + + + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/adc-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/adc-target.h new file mode 100644 index 0000000000..8d2beaf320 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/adc-target.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Barry Wardell + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _ADC_TARGET_H_ +#define _ADC_TARGET_H_ + +/* only two channels used by the Gigabeat */ +#define NUM_ADC_CHANNELS 2 + +#define ADC_BATTERY 0 +#define ADC_HPREMOTE 1 +#define ADC_UNKNOWN_3 2 +#define ADC_UNKNOWN_4 3 +#define ADC_UNKNOWN_5 4 +#define ADC_UNKNOWN_6 5 +#define ADC_UNKNOWN_7 6 +#define ADC_UNKNOWN_8 7 + +#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */ +#define ADC_READ_ERROR 0xFFFF + +#endif diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c new file mode 100644 index 0000000000..bc2b53d776 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c @@ -0,0 +1,143 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id $ + * + * Copyright (C) 2006,2007 by Marcoen Hirschberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "cpu.h" +#include +#include "kernel.h" +#include "system.h" +#include "power.h" +#include "panic.h" +#include "pcf50606.h" +#include "ata-target.h" +#include "mmu-meg-fx.h" +#include "backlight-target.h" + +/* ARESET on C7C68300 and RESET on ATA interface (Active Low) */ +#define ATA_RESET_ENABLE GPGDAT &= ~(1 << 10) +#define ATA_RESET_DISABLE GPGDAT |= (1 << 10) + +/* ATA_EN on C7C68300 */ +#define USB_ATA_ENABLE GPBDAT |= (1 << 5) +#define USB_ATA_DISABLE GPBDAT &= ~(1 << 5) + +void ata_reset(void) +{ + ATA_RESET_ENABLE; + sleep(1); /* > 25us */ + ATA_RESET_DISABLE; + sleep(1); /* > 2ms */ +} + +/* This function is called before enabling the USB bus */ +void ata_enable(bool on) +{ + if(on) + USB_ATA_DISABLE; + else + USB_ATA_ENABLE; + + GPBCON=( GPGCON&~(1<<11) ) | (1<<10); /* Make the pin an output */ +// GPBUP|=1<<5; /* Disable pullup in SOC as we are now driving */ +} + +bool ata_is_coldstart(void) +{ + /* Check the pin configuration - return true when pin is unconfigured */ + return (GPGCON & 0x00300000) == 0; +} + +void ata_device_init(void) +{ + /* ATA reset */ + ATA_RESET_DISABLE; /* Set the pin to disable an active low reset */ + GPGCON=( GPGCON&~(1<<21) ) | (1<<20); /* Make the pin an output */ + GPGUP |= 1<<10; /* Disable pullup in SOC as we are now driving */ +} + +#if !defined(BOOTLOADER) +void copy_read_sectors(unsigned char* buf, int wordcount) +{ + __buttonlight_trigger(); + + /* Unaligned transfer - slow copy */ + if ( (unsigned long)buf & 1) + { /* not 16-bit aligned, copy byte by byte */ + unsigned short tmp = 0; + unsigned char* bufend = buf + wordcount*2; + do + { + tmp = ATA_DATA; + *buf++ = tmp & 0xff; /* I assume big endian */ + *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */ + } while (buf < bufend); /* tail loop is faster */ + return; + } + /* This should never happen, but worth watching for */ + if(wordcount > (1 << 18)) + panicf("atd-meg-fx.c: copy_read_sectors: too many sectors per read!"); + +//#define GIGABEAT_DEBUG_ATA +#ifdef GIGABEAT_DEBUG_ATA + static int line = 0; + static char str[256]; + snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount); + lcd_puts(10, line, str); + line = (line+1) % 32; + lcd_update(); +#endif + /* Reset the channel */ + DMASKTRIG0 |= 4; + /* Wait for DMA controller to be ready */ + while(DMASKTRIG0 & 0x2) + ; + while(DSTAT0 & (1 << 20)) + ; + /* Source is ATA_DATA, on AHB Bus, Fixed */ + DISRC0 = (int) 0x18000000; + DISRCC0 = 0x1; + /* Dest mapped to physical address, on AHB bus, increment */ + DIDST0 = (int) buf; + if(DIDST0 < 0x30000000) + DIDST0 += 0x30000000; + DIDSTC0 = 0; + + /* DACK/DREQ Sync to AHB, Int on Transfer complete, Whole service, No reload, 16-bit transfers */ + DCON0 = ((1 << 30) | (1<< 29) | (1<<27) | (1<<22) | (1<<20)) | wordcount; + + /* Activate the channel */ + DMASKTRIG0 = 0x2; + + invalidate_dcache_range((void *)buf, wordcount*2); + + INTMSK &= ~(1<<17); /* unmask the interrupt */ + SRCPND = (1<<17); /* clear any pending interrupts */ + /* Start DMA */ + DMASKTRIG0 |= 0x1; + + /* Wait for transfer to complete */ + while((DSTAT0 & 0x000fffff)) + yield(); + /* Dump cache for the buffer */ +} +#endif +void dma0(void) +{ +} + + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h new file mode 100644 index 0000000000..95e3e110f2 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef ATA_TARGET_H +#define ATA_TARGET_H + +/* Plain C read & write loops */ +#define PREFER_C_READING +#define PREFER_C_WRITING +#if !defined(BOOTLOADER) +#define ATA_OPTIMIZED_READING +void copy_read_sectors(unsigned char* buf, int wordcount); +#endif + +#define ATA_IOBASE 0x18000000 +#define ATA_DATA (*((volatile unsigned short*)(ATA_IOBASE))) +#define ATA_ERROR (*((volatile unsigned char*)(ATA_IOBASE + 0x02))) +#define ATA_NSECTOR (*((volatile unsigned char*)(ATA_IOBASE + 0x04))) +#define ATA_SECTOR (*((volatile unsigned char*)(ATA_IOBASE + 0x06))) +#define ATA_LCYL (*((volatile unsigned char*)(ATA_IOBASE + 0x08))) +#define ATA_HCYL (*((volatile unsigned char*)(ATA_IOBASE + 0x0A))) +#define ATA_SELECT (*((volatile unsigned char*)(ATA_IOBASE + 0x0C))) +#define ATA_COMMAND (*((volatile unsigned char*)(ATA_IOBASE + 0x0E))) +#define ATA_CONTROL (*((volatile unsigned char*)(0x20000000 + 0x1C))) + +#define STATUS_BSY 0x80 +#define STATUS_RDY 0x40 +#define STATUS_DF 0x20 +#define STATUS_DRQ 0x08 +#define STATUS_ERR 0x01 +#define ERROR_ABRT 0x04 + +#define WRITE_PATTERN1 0xa5 +#define WRITE_PATTERN2 0x5a +#define WRITE_PATTERN3 0xaa +#define WRITE_PATTERN4 0x55 + +#define READ_PATTERN1 0xa5 +#define READ_PATTERN2 0x5a +#define READ_PATTERN3 0xaa +#define READ_PATTERN4 0x55 + +#define READ_PATTERN1_MASK 0xff +#define READ_PATTERN2_MASK 0xff +#define READ_PATTERN3_MASK 0xff +#define READ_PATTERN4_MASK 0xff + +#define SET_REG(reg,val) reg = (val) +#define SET_16BITREG(reg,val) reg = (val) + +void ata_reset(void); +void ata_device_init(void); +bool ata_is_coldstart(void); + +#endif diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c new file mode 100644 index 0000000000..a1b6a8a583 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c @@ -0,0 +1,692 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "cpu.h" +#include "system.h" +#include "backlight-target.h" +#include "backlight.h" +#include "lcd.h" +#include "sc606-meg-fx.h" +#include "power.h" + + +#define FLICKER_PERIOD 15 +#define BUTTONLIGHT_MENU (SC606_LED_B1) +#define BUTTONLIGHT_ALL (SC606_LED_B1 | SC606_LED_B2 | SC606_LED_C1 | SC606_LED_C2) + +static void led_control_service(void); +static unsigned short backlight_brightness; +static unsigned short backlight_current; +static unsigned short backlight_target; +static unsigned short time_til_fade; +static unsigned short fade_interval; +static unsigned short initial_tick_delay; +static unsigned char backlight_leds; + +static enum backlight_states +{ + BACKLIGHT_CONTROL_IDLE, + BACKLIGHT_CONTROL_OFF, + BACKLIGHT_CONTROL_ON, + BACKLIGHT_CONTROL_SET, + BACKLIGHT_CONTROL_FADE_OFF, + BACKLIGHT_CONTROL_FADE_ON, + BACKLIGHT_CONTROL_FADE_ON_FROM_OFF +} backlight_control; + + + +enum buttonlight_states +{ + /* turn button lights off */ + BUTTONLIGHT_MODE_OFF_ENTRY, + BUTTONLIGHT_MODE_OFF, + + /* turns button lights on to setting */ + BUTTONLIGHT_MODE_ON_ENTRY, + BUTTONLIGHT_MODE_ON, + + /* turns button lights on to minimum */ + BUTTONLIGHT_MODE_FAINT_ENTRY, + BUTTONLIGHT_MODE_FAINT, + + /* allows button lights to flicker when triggered */ + BUTTONLIGHT_MODE_FLICKER_ENTRY, + BUTTONLIGHT_MODE_FLICKER, + BUTTONLIGHT_MODE_FLICKERING, + + /* button lights solid */ + BUTTONLIGHT_MODE_SOLID_ENTRY, + BUTTONLIGHT_MODE_SOLID, + + /* button light charing */ + BUTTONLIGHT_MODE_CHARGING_ENTRY, + BUTTONLIGHT_MODE_CHARGING, + BUTTONLIGHT_MODE_CHARGING_WAIT, + + /* internal use only */ + BUTTONLIGHT_HELPER_SET, + BUTTONLIGHT_HELPER_SET_FINAL, + BUTTONLIGHT_MODE_STOP, + + /* buttonlights follow the backlight settings */ + BUTTONLIGHT_MODE_FOLLOW_ENTRY, + BUTTONLIGHT_MODE_FOLLOW, +}; + + + +static char buttonlight_leds; +static unsigned short buttonlight_setting; +static unsigned short buttonlight_current; +static unsigned char buttonlight_selected; +static enum buttonlight_states buttonlight_state; +static enum buttonlight_states buttonlight_saved_state; +static unsigned short buttonlight_flickering; + +static unsigned short buttonlight_trigger_now; +static unsigned short buttonlight_trigger_brightness; + + + +static unsigned short charging_led_index; +static unsigned short buttonlight_charging_counter; + +#define CHARGING_LED_COUNT 60 +unsigned char charging_leds[] = { 0x00, 0x20, 0x38, 0x3C }; + + + +bool __backlight_init(void) +{ + backlight_control = BACKLIGHT_CONTROL_IDLE; + + backlight_current = DEFAULT_BRIGHTNESS_SETTING; + + buttonlight_state = BUTTONLIGHT_MODE_OFF; + + buttonlight_selected = 0x04; + + /* delay 4 seconds before any fading */ + initial_tick_delay = 400; + /* put the led control on the tick list */ + tick_add_task(led_control_service); + + return true; +} + + + +void __backlight_on(void) +{ + /* now go turn the backlight on */ + backlight_control = BACKLIGHT_CONTROL_ON; +} + + + +void __backlight_off(void) +{ + backlight_control = BACKLIGHT_CONTROL_OFF; +} + + + +/* Assumes that the backlight has been initialized */ +void __backlight_set_brightness(int brightness) +{ + /* stop the interrupt from messing us up */ + backlight_control = BACKLIGHT_CONTROL_IDLE; + + backlight_brightness = brightness + 1; + + /* only set the brightness if it is different from the current */ + if (backlight_brightness != backlight_current) + { + backlight_control = BACKLIGHT_CONTROL_SET; + } +} + + + +/* only works if the buttonlight mode is set to triggered mode */ +void __buttonlight_trigger(void) +{ + buttonlight_trigger_now = 1; +} + + + + +/* map the mode from the command into the state machine entries */ +void __buttonlight_mode(enum buttonlight_mode mode, + enum buttonlight_selection selection, + unsigned short brightness) +{ + /* choose stop to setup mode */ + buttonlight_state = BUTTONLIGHT_MODE_STOP; + + + /* clip brightness */ + if (brightness > MAX_BRIGHTNESS_SETTING) + { + brightness = MAX_BRIGHTNESS_SETTING; + } + + brightness++; + + /* Select which LEDs to use */ + switch (selection) + { + case BUTTONLIGHT_LED_ALL: + buttonlight_selected = BUTTONLIGHT_ALL; + break; + + case BUTTONLIGHT_LED_MENU: + buttonlight_selected = BUTTONLIGHT_MENU; + break; + } + + /* which mode to use */ + switch (mode) + { + case BUTTONLIGHT_OFF: + buttonlight_state = BUTTONLIGHT_MODE_OFF_ENTRY; + break; + + case BUTTONLIGHT_ON: + buttonlight_trigger_brightness = brightness; + buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY; + break; + + /* faint is just a quick way to set ON to 1 */ + case BUTTONLIGHT_FAINT: + buttonlight_trigger_brightness = 1; + buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY; + break; + + case BUTTONLIGHT_FLICKER: + buttonlight_trigger_brightness = brightness; + buttonlight_state = BUTTONLIGHT_MODE_FLICKER_ENTRY; + break; + + case BUTTONLIGHT_SIGNAL: + buttonlight_trigger_brightness = brightness; + buttonlight_state = BUTTONLIGHT_MODE_SOLID_ENTRY; + break; + + case BUTTONLIGHT_FOLLOW: + buttonlight_state = BUTTONLIGHT_MODE_FOLLOW_ENTRY; + break; + + case BUTTONLIGHT_CHARGING: + buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY; + break; + + default: + return; /* unknown mode */ + } + + +} + + + +/* + * The button lights have 'modes' of operation. Each mode must setup and + * execute its own operation - taking care that this is all done in an ISR. + * + */ + + + +/* led_control_service runs in interrupt context - be brief! + * This service is called once per interrupt timer tick - 100 times a second. + * + * There should be at most only one i2c operation per call - if more are need + * the calls should be spread across calls. + * + * Putting all led servicing in one thread means that we wont step on any + * i2c operations - they are all serialized here in the ISR tick. It also + * insures that we get called at equal timing for good visual effect. + * + * The buttonlight service runs only after all backlight services have finished. + * Fading the buttonlights is possible, but not recommended because of the + * additional calls needed during the ISR + */ +static void led_control_service(void) +{ + if(initial_tick_delay) { + initial_tick_delay--; + return; + } + switch (backlight_control) + { + case BACKLIGHT_CONTROL_IDLE: + switch (buttonlight_state) + { + case BUTTONLIGHT_MODE_STOP: break; + + /* Buttonlight mode: OFF */ + case BUTTONLIGHT_MODE_OFF_ENTRY: + if (buttonlight_current) + { + buttonlight_leds = 0x00; + sc606_write(SC606_REG_CONF, backlight_leds); + buttonlight_current = 0; + } + buttonlight_state = BUTTONLIGHT_MODE_OFF; + break; + + case BUTTONLIGHT_MODE_OFF: + break; + + + /* button mode: CHARGING - show charging sequence */ + case BUTTONLIGHT_MODE_CHARGING_ENTRY: + /* start turned off */ + buttonlight_leds = 0x00; + sc606_write(SC606_REG_CONF, backlight_leds); + buttonlight_current = 0; + + /* temporary save for the next mode - then to do settings */ + buttonlight_setting = DEFAULT_BRIGHTNESS_SETTING; + buttonlight_saved_state = BUTTONLIGHT_MODE_CHARGING_WAIT; + buttonlight_state = BUTTONLIGHT_HELPER_SET; + break; + + + case BUTTONLIGHT_MODE_CHARGING: + if (--buttonlight_charging_counter == 0) + { + /* change led */ + if (charging_state()) + { + buttonlight_leds = charging_leds[charging_led_index]; + if (++charging_led_index >= sizeof(charging_leds)) + { + charging_led_index = 0; + } + sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); + buttonlight_charging_counter = CHARGING_LED_COUNT; + } + else + { + buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY; + } + } + break; + + /* wait for the charget to be plugged in */ + case BUTTONLIGHT_MODE_CHARGING_WAIT: + if (charging_state()) + { + charging_led_index = 0; + buttonlight_charging_counter = CHARGING_LED_COUNT; + buttonlight_state = BUTTONLIGHT_MODE_CHARGING; + } + break; + + + /* Buttonlight mode: FOLLOW - try to stay current with backlight + * since this runs in the idle of the backlight it will not really + * follow in real time + */ + case BUTTONLIGHT_MODE_FOLLOW_ENTRY: + /* case 1 - backlight on, but buttonlight is off */ + if (backlight_current) + { + /* Turn the buttonlights on */ + buttonlight_leds = buttonlight_selected; + sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); + + /* temporary save for the next mode - then to do settings */ + buttonlight_setting = backlight_current; + buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; + buttonlight_state = BUTTONLIGHT_HELPER_SET; + } + /* case 2 - backlight off, but buttonlight is on */ + else + { + buttonlight_current = 0; + buttonlight_leds = 0x00; + sc606_write(SC606_REG_CONF, backlight_leds); + buttonlight_state = BUTTONLIGHT_MODE_FOLLOW; + } + break; + + case BUTTONLIGHT_MODE_FOLLOW: + if (buttonlight_current != backlight_current) + { + /* case 1 - backlight on, but buttonlight is off */ + if (backlight_current) + { + if (0 == buttonlight_current) + { + /* Turn the buttonlights on */ + buttonlight_leds = buttonlight_selected; + sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); + } + + /* temporary save for the next mode - then to do settings */ + buttonlight_setting = backlight_current; + buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; + buttonlight_state = BUTTONLIGHT_HELPER_SET; + } + + /* case 2 - backlight off, but buttonlight is on */ + else + { + buttonlight_current = 0; + buttonlight_leds = 0x00; + sc606_write(SC606_REG_CONF, backlight_leds); + } + + } + break; + + + + /* Buttonlight mode: ON - stays at the set brightness */ + case BUTTONLIGHT_MODE_ON_ENTRY: + buttonlight_leds = buttonlight_selected; + sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); + + /* temporary save for the next mode - then to do settings */ + buttonlight_setting = buttonlight_trigger_brightness; + buttonlight_saved_state = BUTTONLIGHT_MODE_ON; + buttonlight_state = BUTTONLIGHT_HELPER_SET; + break; + + case BUTTONLIGHT_MODE_ON: + break; + + + + /* Buttonlight mode: FLICKER */ + case BUTTONLIGHT_MODE_FLICKER_ENTRY: + /* already on? turn it off */ + if (buttonlight_current) + { + buttonlight_leds = 0x00; + sc606_write(SC606_REG_CONF, backlight_leds); + buttonlight_current = 0; + } + + /* set the brightness if not already set */ + if (buttonlight_current != buttonlight_trigger_brightness) + { + /* temporary save for the next mode - then to do settings */ + buttonlight_setting = buttonlight_trigger_brightness; + buttonlight_saved_state = BUTTONLIGHT_MODE_FLICKER; + buttonlight_state = BUTTONLIGHT_HELPER_SET; + } + else buttonlight_state = BUTTONLIGHT_MODE_FLICKER; + break; + + + case BUTTONLIGHT_MODE_FLICKER: + /* wait for the foreground to trigger flickering */ + if (buttonlight_trigger_now) + { + /* turn them on */ + buttonlight_leds = buttonlight_selected; + buttonlight_current = buttonlight_setting; + sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); + + /* reset the trigger and go flicker the LEDs */ + buttonlight_trigger_now = 0; + buttonlight_flickering = FLICKER_PERIOD; + buttonlight_state = BUTTONLIGHT_MODE_FLICKERING; + } + break; + + + case BUTTONLIGHT_MODE_FLICKERING: + /* flicker the LEDs for as long as we get triggered */ + if (buttonlight_flickering) + { + /* turn the leds off if they are on */ + if (buttonlight_current) + { + buttonlight_leds = 0x00; + sc606_write(SC606_REG_CONF, backlight_leds); + buttonlight_current = 0; + } + + buttonlight_flickering--; + } + else + { + /* is flickering triggered again? */ + if (!buttonlight_trigger_now) + { + /* completed a cycle - no new triggers - go back and wait */ + buttonlight_state = BUTTONLIGHT_MODE_FLICKER; + } + else + { + /* reset flickering */ + buttonlight_trigger_now = 0; + buttonlight_flickering = FLICKER_PERIOD; + + /* turn buttonlights on */ + buttonlight_leds = buttonlight_selected; + buttonlight_current = buttonlight_setting; + sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); + } + } + break; + + + /* Buttonlight mode: SIGNAL / SOLID */ + case BUTTONLIGHT_MODE_SOLID_ENTRY: + /* already on? turn it off */ + if (buttonlight_current) + { + buttonlight_leds = 0x00; + sc606_write(SC606_REG_CONF, backlight_leds); + buttonlight_current = 0; + } + + /* set the brightness if not already set */ + /* temporary save for the next mode - then to do settings */ + buttonlight_setting = buttonlight_trigger_brightness; + buttonlight_saved_state = BUTTONLIGHT_MODE_SOLID; + buttonlight_state = BUTTONLIGHT_HELPER_SET; + break; + + + case BUTTONLIGHT_MODE_SOLID: + /* wait for the foreground to trigger */ + if (buttonlight_trigger_now) + { + /* turn them on if not already on */ + if (0 == buttonlight_current) + { + buttonlight_leds = buttonlight_selected; + buttonlight_current = buttonlight_setting; + sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); + } + + /* reset the trigger */ + buttonlight_trigger_now = 0; + } + else + { + if (buttonlight_current) + { + buttonlight_leds = 0x00; + sc606_write(SC606_REG_CONF, backlight_leds); + buttonlight_current = 0; + } + } + break; + + + /* set the brightness for the buttonlights - takes 2 passes */ + case BUTTONLIGHT_HELPER_SET: + sc606_write(SC606_REG_B, buttonlight_setting-1); + buttonlight_state = BUTTONLIGHT_HELPER_SET_FINAL; + break; + + case BUTTONLIGHT_HELPER_SET_FINAL: + sc606_write(SC606_REG_C, buttonlight_setting-1); + buttonlight_current = buttonlight_setting; + buttonlight_state = buttonlight_saved_state; + break; + + default: + break; + + } + break; + + + case BACKLIGHT_CONTROL_FADE_ON_FROM_OFF: + backlight_leds = 0x03; + sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds); + backlight_control = BACKLIGHT_CONTROL_FADE_ON; + break; + + + case BACKLIGHT_CONTROL_OFF: + backlight_current = 0; + backlight_leds = 0x00; + sc606_write(SC606_REG_CONF, buttonlight_leds); + backlight_control = BACKLIGHT_CONTROL_IDLE; + + break; + + + case BACKLIGHT_CONTROL_ON: + backlight_leds = 0x03; + sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds); + backlight_current = backlight_brightness; + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + + + case BACKLIGHT_CONTROL_SET: + /* The SC606 LED driver can set the brightness in 64 steps */ + sc606_write(SC606_REG_A, backlight_brightness-1); + + /* if we were turned off - turn the backlight on */ + if (backlight_current) + { + backlight_current = backlight_brightness; + backlight_control = BACKLIGHT_CONTROL_IDLE; + } + else + { + backlight_control = BACKLIGHT_CONTROL_ON; + } + break; + + + case BACKLIGHT_CONTROL_FADE_ON: + if (--time_til_fade) return; + + /* The SC606 LED driver can set the brightness in 64 steps */ + sc606_write(SC606_REG_A, backlight_current++); + + /* have we hit the target? */ + if (backlight_current == backlight_target) + { + backlight_control = BACKLIGHT_CONTROL_IDLE; + } + else + { + time_til_fade = fade_interval; + } + break; + + + case BACKLIGHT_CONTROL_FADE_OFF: + if (--time_til_fade) return; + + /* The SC606 LED driver can set the brightness in 64 steps */ + sc606_write(SC606_REG_A, --backlight_current); + + /* have we hit the target? */ + if (backlight_current == backlight_target) + { + if (backlight_current) + { + backlight_control = BACKLIGHT_CONTROL_IDLE; + } + else + { + backlight_control = BACKLIGHT_CONTROL_OFF; + } + + } + else + { + time_til_fade = fade_interval; + } + break; + } + + if(backlight_current) + lcd_enable(true); + else + lcd_enable(false); +} + + + + + +void __backlight_dim(bool dim_now) +{ + unsigned short target; + + /* dont let the interrupt tick happen */ + backlight_control = BACKLIGHT_CONTROL_IDLE; + + target = (dim_now == true) ? 0 : backlight_brightness; + + /* only try and fade if the target is different */ + if (backlight_current != target) + { + backlight_target = target; + + if (backlight_current > backlight_target) + { + time_til_fade = fade_interval = 4; + backlight_control = BACKLIGHT_CONTROL_FADE_OFF; + } + else + { + time_til_fade = fade_interval = 1; + if (backlight_current) + { + backlight_control = BACKLIGHT_CONTROL_FADE_ON; + } + else + { + backlight_control = BACKLIGHT_CONTROL_FADE_ON_FROM_OFF; + } + } + } + +} + + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/backlight-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/backlight-target.h new file mode 100644 index 0000000000..5f92cee935 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/backlight-target.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef BACKLIGHT_TARGET_H +#define BACKLIGHT_TARGET_H + + +/* select the led */ +enum buttonlight_selection +{ + /* all leds */ + BUTTONLIGHT_LED_ALL, + + /* only the menu/power led (two buttons for one LED) */ + BUTTONLIGHT_LED_MENU +}; + + +/* Use these to set the buttonlight mode */ +enum buttonlight_mode +{ + /* ON follows the setting */ + BUTTONLIGHT_ON, + + /* buttonlights always off */ + BUTTONLIGHT_OFF, + + /* buttonlights always on but set at lowest brightness */ + BUTTONLIGHT_FAINT, + + /* buttonlights flicker when triggered - continues to flicker + * even if the flicker is still asserted. + */ + BUTTONLIGHT_FLICKER, + + /* buttonlights solid for as long as triggered */ + BUTTONLIGHT_SIGNAL, + + /* buttonlights follow backlight */ + BUTTONLIGHT_FOLLOW, + + /* buttonlights show battery charging */ + BUTTONLIGHT_CHARGING, +}; + + +/* Call this to flicker or signal the button lights. Only is effective for + * modes that take a trigger input. + */ +void __buttonlight_trigger(void); + + +/* select which led to use on the button lights. Other combinations are + * possible, but don't look very good. + */ + +/* map the mode from the command into the state machine entries */ +/* See enum buttonlight_mode for available functions */ +void __buttonlight_mode(enum buttonlight_mode mode, + enum buttonlight_selection selection, + unsigned short brightness); + + +bool __backlight_init(void); +void __backlight_on(void); +void __backlight_off(void); +void __backlight_set_brightness(int val); + +/* true: backlight fades off - false: backlight fades on */ +void __backlight_dim(bool dim); + +#endif diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/button-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/button-meg-fx.c new file mode 100644 index 0000000000..71d45c385c --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/button-meg-fx.c @@ -0,0 +1,157 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include "config.h" +#include "cpu.h" +#include "system.h" +#include "button.h" +#include "kernel.h" +#include "backlight.h" +#include "adc.h" +#include "system.h" +#include "backlight-target.h" + +static bool headphones_detect; +static bool hold_button = false; + +static int const remote_buttons[] = +{ + BUTTON_NONE, /* Headphones connected - remote disconnected */ + BUTTON_SELECT, + BUTTON_MENU, /* could be changed to BUTTON_A */ + BUTTON_LEFT, + BUTTON_RIGHT, + BUTTON_UP, /* could be changed to BUTTON_VOL_UP */ + BUTTON_DOWN, /* could be changed to BUTTON_VOL_DOWN */ + BUTTON_NONE, /* Remote control attached - no buttons pressed */ + BUTTON_NONE, /* Nothing in the headphone socket */ +}; + + + + + +void button_init_device(void) +{ + /* Power, Remote Play & Hold switch */ +} + + + +inline bool button_hold(void) +{ + return (GPGDAT & (1 << 15)); +} + + + +int button_read_device(void) +{ + int touchpad; + int buttons; + static int lastbutton; + unsigned short remote_adc; + int btn = BUTTON_NONE; + bool hold_button_old; + + /* normal buttons */ + hold_button_old = hold_button; + hold_button = button_hold(); + +#ifndef BOOTLOADER + /* give BL notice if HB state chaged */ + if (hold_button != hold_button_old) + backlight_hold_changed(hold_button); +#endif + + /* See header for ADC values when remote control buttons are pressed */ + /* Only one button can be sensed at a time on the remote. */ + /* Need to filter the remote button because the ADC is so fast */ + remote_adc = adc_read(ADC_HPREMOTE); + btn = remote_buttons[(remote_adc + 64) / 128]; + if (btn != lastbutton) + { + /* if the buttons dont agree twice in a row, then its none */ + lastbutton = btn; + btn = BUTTON_NONE; + } + + /* Check for hold first - exit if asserted with no button pressed */ + if (hold_button) + return btn; + + /* the side buttons - Check before doing all of the work on each bit */ + buttons = GPGDAT & 0x1F; + if (buttons) + { + if (buttons & (1 << 0)) + btn |= BUTTON_POWER; + + if (buttons & (1 << 1)) + btn |= BUTTON_MENU; + + if (buttons & (1 << 2)) + btn |= BUTTON_VOL_UP; + + if (buttons & (1 << 3)) + btn |= BUTTON_VOL_DOWN; + + if (buttons & (1 << 4)) + btn |= BUTTON_A; + } + + /* the touchpad */ + touchpad = GPJDAT & 0x10C9; + if (touchpad) + { + if (touchpad & (1 << 0)) + btn |= BUTTON_UP; + + if (touchpad & (1 << 12)) + btn |= BUTTON_RIGHT; + + if (touchpad & (1 << 6)) + btn |= BUTTON_DOWN; + + if (touchpad & (1 << 7)) + btn |= BUTTON_LEFT; + + if (touchpad & (1 << 3)) + btn |= BUTTON_SELECT; + } + + return btn; +} + + + +bool headphones_inserted(void) +{ + unsigned short remote_adc = adc_read(ADC_HPREMOTE); + if (remote_adc != ADC_READ_ERROR) + { + /* If there is nothing in the headphone socket, the ADC reads high */ + if (remote_adc < 940) + headphones_detect = true; + else + headphones_detect = false; + } + return headphones_detect; +} diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/button-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/button-target.h new file mode 100644 index 0000000000..ab68e8050f --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/button-target.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _BUTTON_TARGET_H_ +#define _BUTTON_TARGET_H_ + +#include +#include "config.h" + +#define HAS_BUTTON_HOLD + +bool button_hold(void); +void button_init_device(void); +int button_read_device(void); + +/* Toshiba Gigabeat specific button codes */ + +#define BUTTON_POWER 0x00000001 +#define BUTTON_MENU 0x00000002 + +#define BUTTON_LEFT 0x00000004 +#define BUTTON_RIGHT 0x00000008 +#define BUTTON_UP 0x00000010 +#define BUTTON_DOWN 0x00000020 + +#define BUTTON_VOL_UP 0x00000040 +#define BUTTON_VOL_DOWN 0x00000080 + +#define BUTTON_SELECT 0x00000100 +#define BUTTON_A 0x00000200 + + +/* Toshiba Gigabeat specific remote button ADC values */ +/* The remote control uses ADC 1 to emulate button pushes + Reading (approx) Button HP plugged in? Remote plugged in? + 0 N/A Yes No + 125 Play/Pause Cant tell Yes + 241 Speaker+ Cant tell Yes + 369 Rewind Cant tell Yes + 492 Fast Fwd Cant tell Yes + 616 Vol + Cant tell Yes + 742 Vol - Cant tell Yes + 864 None Cant tell Yes + 1023 N/A No No +*/ + +/* + Notes: + + Buttons on the remote are translated into equivalent button presses just + as if you were pressing them on the Gigabeat itself. + + We cannot tell if the hold is asserted on the remote. The Hold function on + the remote is to block the output of the buttons changing. + + Only one button can be sensed at a time. If another is pressed, the button + with the lowest reading is dominant. So, if Rewind and Vol + are pressed + at the same time, Rewind value is the one that is read. +*/ + + + + +#define BUTTON_MAIN (BUTTON_POWER|BUTTON_MENU|BUTTON_LEFT|BUTTON_RIGHT\ + |BUTTON_UP|BUTTON_DOWN|BUTTON_VOL_UP|BUTTON_VOL_DOWN\ + |BUTTON_SELECT|BUTTON_A) + + +#define BUTTON_REMOTE 0 + +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 10 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/dma_start.c b/firmware/target/arm/s3c2440/gigabeat-fx/dma_start.c new file mode 100644 index 0000000000..c1ab6c15cb --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/dma_start.c @@ -0,0 +1,8 @@ +#include + +void dma_start(const void* addr, size_t size) { + (void) addr; + (void) size; + //TODO: +} + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c new file mode 100644 index 0000000000..670d6cd04c --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c @@ -0,0 +1,134 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "cpu.h" +#include +#include "kernel.h" +#include "system.h" +#include "logf.h" +#include "debug.h" +#include "string.h" +#include "generic_i2c.h" + +static void i2c_sda_output(void) +{ + GPECON |= (1 << 30); +} + +static void i2c_sda_input(void) +{ + GPECON &= ~(3 << 30); +} + +static void i2c_sda_lo(void) +{ + GPEDAT &= ~(1 << 15); +} + +static void i2c_sda_hi(void) +{ + GPEDAT |= (1 << 15); +} + +static int i2c_sda(void) +{ + return GPEDAT & (1 << 15); +} + +static void i2c_scl_output(void) +{ + GPECON |= (1 << 28); +} + +static void i2c_scl_input(void) +{ + GPECON &= ~(3 << 28); +} + +static void i2c_scl_lo(void) +{ + GPEDAT &= ~(1 << 14); +} + +static int i2c_scl(void) +{ + return GPEDAT & (1 << 14); +} + +static void i2c_scl_hi(void) +{ + i2c_scl_input(); + while(!i2c_scl()); + GPEDAT |= (1 << 14); + i2c_scl_output(); +} + + + +static void i2c_delay(void) +{ + unsigned _x; + + /* The i2c can clock at 500KHz: 2uS period -> 1uS half period */ + /* about 30 cycles overhead + X * 7 */ + /* 300MHz: 1000nS @3.36nS/cyc = 297cyc: X = 38*/ + /* 100MHz: 1000nS @10nS/cyc = 100cyc : X = 10 */ + for (_x = 38; _x; _x--) + { + /* burn CPU cycles */ + /* gcc makes it an inc loop - check with objdump for asm timing */ + } +} + + + +struct i2c_interface s3c2440_i2c = { + 0x34, /* Address */ + + /* Bit-banged interface definitions */ + i2c_scl_hi, /* Drive SCL high, might sleep on clk stretch */ + i2c_scl_lo, /* Drive SCL low */ + i2c_sda_hi, /* Drive SDA high */ + i2c_sda_lo, /* Drive SDA low */ + i2c_sda_input, /* Set SDA as input */ + i2c_sda_output, /* Set SDA as output */ + i2c_scl_input, /* Set SCL as input */ + i2c_scl_output, /* Set SCL as output */ + i2c_scl, /* Read SCL, returns 0 or nonzero */ + i2c_sda, /* Read SDA, returns 0 or nonzero */ + + i2c_delay, /* START SDA hold time (tHD:SDA) */ + i2c_delay, /* SDA hold time (tHD:DAT) */ + i2c_delay, /* SDA setup time (tSU:DAT) */ + i2c_delay, /* STOP setup time (tSU:STO) */ + i2c_delay, /* Rep. START setup time (tSU:STA) */ + i2c_delay, /* SCL high period (tHIGH) */ +}; + +void i2c_init(void) +{ + /* Set GPE15 (SDA) and GPE14 (SCL) to 1 */ + GPECON = (GPECON & ~(0xF<<28)) | 5<<28; + i2c_add_node(&s3c2440_i2c); +} + +void i2c_send(int bus_address, int reg_address, const unsigned char buf) +{ + i2c_write_data(bus_address, reg_address, &buf, 1); +} diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h b/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h new file mode 100644 index 0000000000..cf69230487 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* chip-specific i2c functions */ + +void i2c_send(int bus_address, int reg_address, const unsigned char buf); diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c new file mode 100644 index 0000000000..9df90a2344 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c @@ -0,0 +1,25 @@ +#include "kernel.h" +#include "thread.h" + +#include +#include "lcd.h" + +extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); + +void timer4(void) { + int i; + /* Run through the list of tick tasks */ + for(i = 0; i < MAX_NUM_TICK_TASKS; i++) + { + if(tick_funcs[i]) + { + tick_funcs[i](); + } + } + + current_tick++; + + /* following needs to be fixed. */ + /*wake_up_thread();*/ +} + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S new file mode 100644 index 0000000000..d431c95f29 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S @@ -0,0 +1,222 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Michael Sevakis + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "cpu.h" + +/**************************************************************************** + * void lcd_write_yuv_420_lines(fb_data *dst, + * unsigned char chroma_buf[LCD_HEIGHT/2*3], + unsigned char const * const src[3], + * int width, + * int stride); + * + * |R| |1.000000 -0.000001 1.402000| |Y'| + * |G| = |1.000000 -0.334136 -0.714136| |Pb| + * |B| |1.000000 1.772000 0.000000| |Pr| + * Scaled, normalized, rounded and tweaked to yield RGB 565: + * |R| |74 0 101| |Y' - 16| >> 9 + * |G| = |74 -24 -51| |Cb - 128| >> 8 + * |B| |74 128 0| |Cr - 128| >> 9 + */ + .section .icode, "ax", %progbits + .align 2 + .global lcd_write_yuv420_lines + .type lcd_write_yuv420_lines, %function +lcd_write_yuv420_lines: + @ r0 = dst + @ r1 = chroma_buf + @ r2 = yuv_src + @ r3 = width + @ [sp] = stride + stmdb sp!, { r4-r12, lr } @ save non-scratch + stmdb sp!, { r0, r3 } @ save dst and width + mov r14, #74 @ r14 = Y factor + ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p + @ r5 = yuv_src[1] = Cb_p + @ r6 = yuv_src[2] = Cr_p +10: @ loop line 1 @ + ldrb r2, [r4], #1 @ r2 = *Y'_p++; + ldrb r8, [r5], #1 @ r8 = *Cb_p++; + ldrb r11, [r6], #1 @ r11 = *Cr_p++; + @ + @ compute Y + sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 + mul r7, r2, r14 @ + @ + sub r8, r8, #128 @ Cb -= 128 + sub r11, r11, #128 @ Cr -= 128 + @ + mvn r2, #24 @ compute guv + mul r10, r2, r8 @ r10 = Cb*-24 + mvn r2, #51 @ + mla r10, r2, r11, r10 @ r10 = r10 + Cr*-51 + @ + mov r2, #101 @ compute rv + mul r9, r11, r2 @ r9 = rv = Cr*101 + @ + @ store chromas in line buffer + add r8, r8, #2 @ bu = (Cb + 2) >> 2 + mov r8, r8, asr #2 @ + strb r8, [r1], #1 @ + add r9, r9, #256 @ rv = (Cr + 256) >> 9 + mov r9, r9, asr #9 @ + strb r9, [r1], #1 @ + mov r10, r10, asr #8 @ guv >>= 8 + strb r10, [r1], #1 @ + @ compute R, G, and B + add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu + add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv + add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv + @ + orr r12, r2, r11 @ check if clamping is needed... + orr r12, r12, r7, asr #1 @ ...at all + cmp r12, #31 @ + bls 15f @ no clamp @ + mov r12, #31 @ + cmp r12, r2 @ clamp b + andlo r2, r12, r2, asr #31 @ + eorlo r2, r2, r12 @ + cmp r12, r11 @ clamp r + andlo r11, r12, r11, asr #31 @ + eorlo r11, r11, r12 @ + cmp r12, r7, asr #1 @ clamp g + andlo r7, r12, r7, asr #31 @ + eorlo r7, r7, r12 @ + orrlo r7, r7, r7, asl #1 @ +15: @ no clamp @ + @ + orr r12, r2, r7, lsl #5 @ r4 |= (g << 5) + ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ + orr r12, r12, r11, lsl #11 @ r4 = b | (r << 11) + strh r12, [r0], #240 @ store pixel + @ + sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 + mul r7, r2, r14 @ next Y + @ compute R, G, and B + add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu + add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv + add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv + @ + orr r12, r2, r11 @ check if clamping is needed... + orr r12, r12, r7, asr #1 @ ...at all + cmp r12, #31 @ + bls 15f @ no clamp @ + mov r12, #31 @ + cmp r12, r2 @ clamp b + andlo r2, r12, r2, asr #31 @ + eorlo r2, r2, r12 @ + cmp r12, r11 @ clamp r + andlo r11, r12, r11, asr #31 @ + eorlo r11, r11, r12 @ + cmp r12, r7, asr #1 @ clamp g + andlo r7, r12, r7, asr #31 @ + eorlo r7, r7, r12 @ + orrlo r7, r7, r7, asl #1 @ +15: @ no clamp @ + @ + orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) + orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) + strh r12, [r0, #240]! @ store pixel + add r0, r0, #2*240 @ + @ + subs r3, r3, #2 @ + bgt 10b @ loop line 1 @ + @ do second line + @ + ldmia sp!, { r0, r3 } @ pop dst and width + sub r0, r0, #2 @ set dst to start of next line + sub r1, r1, r3, asl #1 @ rewind chroma pointer... + ldr r2, [sp, #40] @ r2 = stride + add r1, r1, r3, asr #1 @ ... (r1 -= width/2*3) + @ move sources to start of next line + sub r2, r2, r3 @ r2 = skip = stride - width + add r4, r4, r2 @ r4 = Y'_p + skip + @ +20: @ loop line 2 @ + ldrb r2, [r4], #1 @ r7 = Y' = *Y'_p++ + ldrsb r8, [r1], #1 @ reload saved chromas + ldrsb r9, [r1], #1 @ + ldrsb r10, [r1], #1 @ + @ + sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 + mul r7, r2, r14 @ + @ compute R, G, and B + add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu + add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv + add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv + @ + orr r12, r2, r11 @ check if clamping is needed... + orr r12, r12, r7, asr #1 @ ...at all + cmp r12, #31 @ + bls 25f @ no clamp @ + mov r12, #31 @ + cmp r12, r2 @ clamp b + andlo r2, r12, r2, asr #31 @ + eorlo r2, r2, r12 @ + cmp r12, r11 @ clamp r + andlo r11, r12, r11, asr #31 @ + eorlo r11, r11, r12 @ + cmp r12, r7, asr #1 @ clamp g + andlo r7, r12, r7, asr #31 @ + eorlo r7, r7, r12 @ + orrlo r7, r7, r7, asl #1 @ +25: @ no clamp @ + @ + orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) + ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ + orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) + strh r12, [r0], #240 @ store pixel + @ + @ do second pixel + @ + sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 + mul r7, r2, r14 @ + @ compute R, G, and B + add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu + add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv + add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv + @ + orr r12, r2, r11 @ check if clamping is needed... + orr r12, r12, r7, asr #1 @ ...at all + cmp r12, #31 @ + bls 25f @ no clamp @ + mov r12, #31 @ + cmp r12, r2 @ clamp b + andlo r2, r12, r2, asr #31 @ + eorlo r2, r2, r12 @ + cmp r12, r11 @ clamp r + andlo r11, r12, r11, asr #31 @ + eorlo r11, r11, r12 @ + cmp r12, r7, asr #1 @ clamp g + andlo r7, r12, r7, asr #31 @ + eorlo r7, r7, r12 @ + orrlo r7, r7, r7, asl #1 @ +25: @ no clamp @ + @ + orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) + orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) + strh r12, [r0, #240]! @ store pixel + add r0, r0, #2*240 @ + @ + subs r3, r3, #2 @ + bgt 20b @ loop line 2 @ + @ + ldmia sp!, { r4-r12, pc } @ restore registers and return + .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c new file mode 100644 index 0000000000..1bb68f9686 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c @@ -0,0 +1,367 @@ +#include "config.h" +#include +#include "cpu.h" +#include "lcd.h" +#include "kernel.h" +#include "system.h" +#include "mmu-meg-fx.h" +#include +#include "memory.h" +#include "lcd-target.h" +#include "font.h" +#include "rbunicode.h" +#include "bidi.h" + +#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) +/* +** We prepare foreground and background fills ahead of time - DMA fills in 16 byte groups +*/ +unsigned long fg_pattern_blit[4]; +unsigned long bg_pattern_blit[4]; + +volatile bool use_dma_blit = false; +static volatile bool lcd_on = true; +volatile bool lcd_poweroff = false; +/* +** These are imported from lcd-16bit.c +*/ +extern unsigned fg_pattern; +extern unsigned bg_pattern; + +bool lcd_enabled() +{ + return lcd_on; +} + +unsigned int LCDBANK(unsigned int address) +{ + return ((address >> 22) & 0xff); +} + +unsigned int LCDBASEU(unsigned int address) +{ + return (address & ((1 << 22)-1)) >> 1; +} + +unsigned int LCDBASEL(unsigned int address) +{ + address += 320*240*2; + return (address & ((1 << 22)-1)) >> 1; +} + + +/* LCD init */ +void lcd_init_device(void) +{ + LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME)); + LCDSADDR2 = LCDBASEL((unsigned)FRAME); + LCDSADDR3 = 0x000000F0; + + LCDCON5 |= 1 << 11; /* Switch from 555I mode to 565 mode */ + +#if !defined(BOOTLOADER) + memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); + memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); + clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); + clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); + use_dma_blit = true; + lcd_poweroff = false; +#endif +} + +/* Update a fraction of the display. */ +void lcd_update_rect(int x, int y, int width, int height) +{ + (void)x; + (void)width; + (void)y; + (void)height; + + if(!lcd_on) + { + sleep(200); + return; + } + if (use_dma_blit) + { + /* Wait for this controller to stop pending transfer */ + while((DSTAT1 & 0x000fffff)) + CLKCON |= (1 << 2); /* set IDLE bit */ + + /* Flush DCache */ + invalidate_dcache_range((void *)(((int) &lcd_framebuffer[0][0])+(y * sizeof(fb_data) * LCD_WIDTH)), (height * sizeof(fb_data) * LCD_WIDTH)); + + /* set DMA dest */ + DIDST1 = ((int) FRAME) + (y * sizeof(fb_data) * LCD_WIDTH); + + /* FRAME on AHB buf, increment */ + DIDSTC1 = 0; + /* Handshake on AHB, Burst transfer, Whole service, Don't reload, transfer 32-bits */ + DCON1 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((height * sizeof(fb_data) * LCD_WIDTH) >> 4); + + /* set DMA source */ + DISRC1 = ((int) &lcd_framebuffer[0][0]) + (y * sizeof(fb_data) * LCD_WIDTH) + 0x30000000; + /* memory is on AHB bus, increment addresses */ + DISRCC1 = 0x00; + + /* Activate the channel */ + DMASKTRIG1 = 0x2; + + /* Start DMA */ + DMASKTRIG1 |= 0x1; + + /* Wait for transfer to complete */ + while((DSTAT1 & 0x000fffff)) + CLKCON |= (1 << 2); /* set IDLE bit */ + } + else + memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); +} + + +void lcd_enable(bool state) +{ + if(!lcd_poweroff) + return; + if(state) { + if(!lcd_on) { + lcd_on = true; + memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); + LCDCON1 |= 1; + } + } + else { + if(lcd_on) { + lcd_on = false; + LCDCON1 &= ~1; + } + } +} + +void lcd_set_foreground(unsigned color) +{ + fg_pattern = color; + + memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); + invalidate_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); +} + +void lcd_set_background(unsigned color) +{ + bg_pattern = color; + memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); + invalidate_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); +} + +void lcd_device_prepare_backdrop(fb_data* backdrop) +{ + if(backdrop) + invalidate_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); +} + +void lcd_clear_display_dma(void) +{ + void *src; + bool inc = false; + + if(!lcd_on) { + sleep(200); + } + if (lcd_get_drawmode() & DRMODE_INVERSEVID) + src = fg_pattern_blit; + else + { + fb_data* lcd_backdrop = lcd_get_backdrop(); + + if (!lcd_backdrop) + src = bg_pattern_blit; + else + { + src = lcd_backdrop; + inc = true; + } + } + /* Wait for any pending transfer to complete */ + while((DSTAT3 & 0x000fffff)) + CLKCON |= (1 << 2); /* set IDLE bit */ + DMASKTRIG3 |= 0x4; /* Stop controller */ + DIDST3 = ((int) &lcd_framebuffer[0][0]) + 0x30000000; /* set DMA dest, physical address */ + DIDSTC3 = 0; /* Dest on AHB, increment */ + + DISRC3 = ((int) src) + 0x30000000; /* Set source, in physical space */ + DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */ + + /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */ + DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data)) >> 4); + + /* Dump DCache for dest, we are about to overwrite it with DMA */ + invalidate_dcache_range((void *)lcd_framebuffer, sizeof(lcd_framebuffer)); + /* Activate the channel */ + DMASKTRIG3 = 2; + /* Start DMA */ + DMASKTRIG3 |= 1; + + /* Wait for transfer to complete */ + while((DSTAT3 & 0x000fffff)) + CLKCON |= (1 << 2); /* set IDLE bit */ +} + +void lcd_clear_display(void) +{ + lcd_stop_scroll(); + + if(use_dma_blit) + { + lcd_clear_display_dma(); + return; + } + + fb_data *dst = &lcd_framebuffer[0][0]; + + if (lcd_get_drawmode() & DRMODE_INVERSEVID) + { + memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT); + } + else + { + fb_data* lcd_backdrop = lcd_get_backdrop(); + if (!lcd_backdrop) + memset16(dst, bg_pattern, LCD_WIDTH*LCD_HEIGHT); + else + memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); + } +} + + +/* Update the display. + This must be called after all other LCD functions that change the display. */ +void lcd_update(void) +{ + lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); +} + +void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, + int stride, int x, int y, int width, + int height) +{ + fb_data *dst, *dst_end; + unsigned int transcolor; + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + || (x + width <= 0) || (y + height <= 0)) + return; + + /* clipping */ + if (x < 0) + { + width += x; + src_x -= x; + x = 0; + } + if (y < 0) + { + height += y; + src_y -= y; + y = 0; + } + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; + + src += stride * src_y + src_x; /* move starting point */ + dst = &lcd_framebuffer[(y)][(x)]; + dst_end = dst + height * LCD_WIDTH; + width *= 2; + stride *= 2; + transcolor = TRANSPARENT_COLOR; + asm volatile( + "rowstart: \n" + "mov r0, #0 \n" + "nextpixel: \n" + "ldrh r1, [%0, r0] \n" /* Load word src+r0 */ + "cmp r1, %5 \n" /* Compare to transparent color */ + "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */ + "add r0, r0, #2 \n" + "cmp r0, %2 \n" /* r0 == width? */ + "bne nextpixel \n" /* More in this row? */ + "add %0, %0, %4 \n" /* src += stride */ + "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */ + "cmp %1, %3 \n" + "bne rowstart \n" /* if(dst != dst_end), keep going */ + : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" ); +} + +/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ +extern void lcd_write_yuv420_lines(fb_data *dst, + unsigned char chroma_buf[LCD_HEIGHT/2*3], + unsigned char const * const src[3], + int width, + int stride); +/* Performance function to blit a YUV bitmap directly to the LCD */ +/* For the Gigabeat - show it rotated */ +/* So the LCD_WIDTH is now the height */ +void lcd_yuv_blit(unsigned char * const src[3], + int src_x, int src_y, int stride, + int x, int y, int width, int height) +{ + /* Caches for chroma data so it only need be recaculated every other + line */ + unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ + unsigned char const * yuv_src[3]; + off_t z; + + if (!lcd_on) + return; + + /* Sorry, but width and height must be >= 2 or else */ + width &= ~1; + height >>= 1; + + fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; + + z = stride*src_y; + yuv_src[0] = src[0] + z + src_x; + yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); + yuv_src[2] = src[2] + (yuv_src[1] - src[1]); + + do + { + lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, + stride); + yuv_src[0] += stride << 1; /* Skip down two luma lines */ + yuv_src[1] += stride >> 1; /* Skip down one chroma line */ + yuv_src[2] += stride >> 1; + dst -= 2; + } + while (--height > 0); +} + +void lcd_set_contrast(int val) { + (void) val; + // TODO: +} + +void lcd_set_invert_display(bool yesno) { + (void) yesno; + // TODO: +} + +void lcd_blit(const fb_data* data, int bx, int y, int bwidth, + int height, int stride) +{ + (void) data; + (void) bx; + (void) y; + (void) bwidth; + (void) height; + (void) stride; + //TODO: +} + +void lcd_set_flip(bool yesno) { + (void) yesno; + // TODO: +} + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-target.h new file mode 100644 index 0000000000..cb2a89f349 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-target.h @@ -0,0 +1,21 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id $ + * + * Copyright (C) 2007 by Greg White + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +extern void lcd_enable(bool state); + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c new file mode 100644 index 0000000000..6142213f0c --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c @@ -0,0 +1,222 @@ +#include +#include "s3c2440.h" +#include "mmu-meg-fx.h" +#include "panic.h" + +void map_memory(void); +static void enable_mmu(void); +static void set_ttb(void); +static void set_page_tables(void); +static void map_section(unsigned int pa, unsigned int va, int mb, int cache_flags); + +#define SECTION_ADDRESS_MASK (-1 << 20) +#define CACHE_ALL (1 << 3 | 1 << 2 ) +#define CACHE_NONE 0 +#define BUFFERED (1 << 2) +#define MB (1 << 20) + +void map_memory(void) { + set_ttb(); + set_page_tables(); + enable_mmu(); +} + +unsigned int* ttb_base = (unsigned int *) TTB_BASE; +const int ttb_size = 4096; + +void set_ttb() { + int i; + int* ttbPtr; + int domain_access; + + /* must be 16Kb (0x4000) aligned */ + ttb_base = (int*) TTB_BASE; + for (i=0; i> 20; /* sections are 1Mb size */ + ttbPtr = ttb_base + section_no; + pa &= SECTION_ADDRESS_MASK; /* align to 1Mb */ + for(i=0; i ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006,2007 by Greg White + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* Invalidate DCache for this range */ +/* Will do write back */ +void invalidate_dcache_range(const void *base, unsigned int size); + +/* clean DCache for this range */ +/* forces DCache writeback for the specified range */ +void clean_dcache_range(const void *base, unsigned int size); + +/* Dump DCache for this range */ +/* Will *NOT* do write back */ +void dump_dcache_range(const void *base, unsigned int size); + +/* Cleans entire DCache */ +void clean_dcache(void); + + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c new file mode 100644 index 0000000000..0f22aa5c5c --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c @@ -0,0 +1,376 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Michael Sevakis + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "system.h" +#include "kernel.h" +#include "logf.h" +#include "audio.h" +#include "sound.h" +#include "file.h" +#include "mmu-meg-fx.h" + +static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ + +#define GIGABEAT_8000HZ 0x4d +#define GIGABEAT_11025HZ 0x32 +#define GIGABEAT_12000HZ 0x61 +#define GIGABEAT_16000HZ 0x55 +#define GIGABEAT_22050HZ 0x36 +#define GIGABEAT_24000HZ 0x79 +#define GIGABEAT_32000HZ 0x59 +#define GIGABEAT_44100HZ 0x22 +#define GIGABEAT_48000HZ 0x41 +#define GIGABEAT_88200HZ 0x3e +#define GIGABEAT_96000HZ 0x5d + +#define FIFO_COUNT ((IISFCON >> 6) & 0x01F) + +/* number of bytes in FIFO */ +#define IIS_FIFO_SIZE 64 + +/* Setup for the DMA controller */ +#define DMA_CONTROL_SETUP ((1<<31) | (1<<29) | (1<<23) | (1<<22) | (1<<20)) + +unsigned short * p; +size_t p_size; + + + +/* DMA count has hit zero - no more data */ +/* Get more data from the callback and top off the FIFO */ +//void fiq(void) __attribute__ ((interrupt ("naked"))); +void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ"))); +void fiq(void) +{ + /* clear any pending interrupt */ + SRCPND = (1<<19); + + /* Buffer empty. Try to get more. */ + if (pcm_callback_for_more) + { + pcm_callback_for_more((unsigned char**)&p, &p_size); + } + else + { + /* callback func is missing? */ + pcm_play_dma_stop(); + return; + } + + if (p_size) + { + /* Flush any pending cache writes */ + clean_dcache_range(p, p_size); + + /* set the new DMA values */ + DCON2 = DMA_CONTROL_SETUP | (p_size >> 1); + DISRC2 = (int)p + 0x30000000; + + /* Re-Activate the channel */ + DMASKTRIG2 = 0x2; + } + else + { + /* No more DMA to do */ + pcm_play_dma_stop(); + } + +} + + + +void pcm_init(void) +{ + pcm_playing = false; + pcm_paused = false; + pcm_callback_for_more = NULL; + + audiohw_init(); + audiohw_enable_output(true); + + /* cannot use the WM8975 defaults since our clock is not the same */ + /* the input master clock is 16.9344MHz - we can divide exact for that */ + pcm_set_frequency(SAMPR_44); + + /* init GPIO */ + GPCCON = (GPCCON & ~(3<<14)) | (1<<14); + GPCDAT |= 1<<7; + GPECON |= 0x2aa; + + /* Do not service DMA requests, yet */ + /* clear any pending int and mask it */ + INTMSK |= (1<<19); /* mask the interrupt */ + SRCPND = (1<<19); /* clear any pending interrupts */ + INTMOD |= (1<<19); /* connect to FIQ */ + +} + +void pcm_postinit(void) +{ + audiohw_postinit(); +} + +void pcm_play_dma_start(const void *addr, size_t size) +{ + /* sanity check: bad pointer or too small file */ + if (NULL == addr || size <= IIS_FIFO_SIZE) return; + + p = (unsigned short *)addr; + p_size = size; + + /* Enable the IIS clock */ + CLKCON |= (1<<17); + + /* IIS interface setup and set to idle */ + IISCON = (1<<5) | (1<<3); + + /* slave, transmit mode, 16 bit samples - 384fs - use 16.9344Mhz */ + IISMOD = (1<<9) | (1<<8) | (2<<6) | (1<<3) | (1<<2); + + /* connect DMA to the FIFO and enable the FIFO */ + IISFCON = (1<<15) | (1<<13); + + /* set DMA dest */ + DIDST2 = (int)&IISFIFO; + + /* IIS is on the APB bus, INT when TC reaches 0, fixed dest addr */ + DIDSTC2 = 0x03; + + /* How many transfers to make - we transfer half-word at a time = 2 bytes */ + /* DMA control: CURR_TC int, single service mode, I2SSDO int, HW trig */ + /* no auto-reload, half-word (16bit) */ + DCON2 = DMA_CONTROL_SETUP | (p_size / 2); + + /* set DMA source and options */ + DISRC2 = (int)p + 0x30000000; + DISRCC2 = 0x00; /* memory is on AHB bus, increment addresses */ + + /* clear pending DMA interrupt */ + SRCPND = 1<<19; + + set_fiq_handler(fiq); + enable_fiq(); + + /* unmask the DMA interrupt */ + INTMSK &= ~(1<<19); + + /* Flush any pending writes */ + clean_dcache_range(addr, size); + + /* Activate the channel */ + DMASKTRIG2 = 0x2; + + /* turn off the idle */ + IISCON &= ~(1<<3); + + pcm_playing = true; + + /* start the IIS */ + IISCON |= (1<<0); + +} + + + +/* Disconnect the DMA and wait for the FIFO to clear */ +void pcm_play_dma_stop(void) +{ + /* mask the DMA interrupt */ + INTMSK |= (1<<19); + + /* are we playing? wait for the chunk to finish */ + if (pcm_playing) + { + /* wait for the FIFO to empty before turning things off */ + while (IISCON & (1<<7)) ; + + pcm_playing = false; + } + + /* De-Activate the DMA channel */ + DMASKTRIG2 = 0x4; + + /* Disconnect the IIS clock */ + CLKCON &= ~(1<<17); + + disable_fiq(); + +} + + + +void pcm_play_pause_pause(void) +{ + /* stop servicing refills */ + INTMSK |= (1<<19); +} + + + +void pcm_play_pause_unpause(void) +{ + /* refill buffer and keep going */ + INTMSK &= ~(1<<19); +} + +void pcm_set_frequency(unsigned int frequency) +{ + int sr_ctrl; + + switch(frequency) + { + case SAMPR_8: + sr_ctrl = GIGABEAT_8000HZ; + break; + case SAMPR_11: + sr_ctrl = GIGABEAT_11025HZ; + break; + case SAMPR_12: + sr_ctrl = GIGABEAT_12000HZ; + break; + case SAMPR_16: + sr_ctrl = GIGABEAT_16000HZ; + break; + case SAMPR_22: + sr_ctrl = GIGABEAT_22050HZ; + break; + case SAMPR_24: + sr_ctrl = GIGABEAT_24000HZ; + break; + case SAMPR_32: + sr_ctrl = GIGABEAT_32000HZ; + break; + default: + frequency = SAMPR_44; + case SAMPR_44: + sr_ctrl = GIGABEAT_44100HZ; + break; + case SAMPR_48: + sr_ctrl = GIGABEAT_48000HZ; + break; + case SAMPR_88: + sr_ctrl = GIGABEAT_88200HZ; + break; + case SAMPR_96: + sr_ctrl = GIGABEAT_96000HZ; + break; + } + + audiohw_set_sample_rate(sr_ctrl); + pcm_freq = frequency; +} + + + +size_t pcm_get_bytes_waiting(void) +{ + return (DSTAT2 & 0xFFFFF) * 2; +} + + + +/* dummy functions for those not actually supporting all this yet */ +void pcm_apply_settings(void) +{ +} + +void pcm_set_monitor(int monitor) +{ + (void)monitor; +} +/** **/ + +void pcm_mute(bool mute) +{ + audiohw_mute(mute); + if (mute) + sleep(HZ/16); +} + +/* + * This function goes directly into the DMA buffer to calculate the left and + * right peak values. To avoid missing peaks it tries to look forward two full + * peek periods (2/HZ sec, 100% overlap), although it's always possible that + * the entire period will not be visible. To reduce CPU load it only looks at + * every third sample, and this can be reduced even further if needed (even + * every tenth sample would still be pretty accurate). + */ + +/* Check for a peak every PEAK_STRIDE samples */ +#define PEAK_STRIDE 3 +/* Up to 1/50th of a second of audio for peak calculation */ +/* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */ +#define PEAK_SAMPLES (44100/50) +void pcm_calculate_peaks(int *left, int *right) +{ + short *addr; + short *end; + { + size_t samples = p_size / 4; + addr = p; + + if (samples > PEAK_SAMPLES) + samples = PEAK_SAMPLES - (PEAK_STRIDE - 1); + else + samples -= MIN(PEAK_STRIDE - 1, samples); + + end = &addr[samples * 2]; + } + + if (left && right) { + int left_peak = 0, right_peak = 0; + + while (addr < end) { + int value; + if ((value = addr [0]) > left_peak) + left_peak = value; + else if (-value > left_peak) + left_peak = -value; + + if ((value = addr [PEAK_STRIDE | 1]) > right_peak) + right_peak = value; + else if (-value > right_peak) + right_peak = -value; + + addr = &addr[PEAK_STRIDE * 2]; + } + + *left = left_peak; + *right = right_peak; + } + else if (left || right) { + int peak_value = 0, value; + + if (right) + addr += (PEAK_STRIDE | 1); + + while (addr < end) { + if ((value = addr [0]) > peak_value) + peak_value = value; + else if (-value > peak_value) + peak_value = -value; + + addr += PEAK_STRIDE * 2; + } + + if (left) + *left = peak_value; + else + *right = peak_value; + } +} diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/power-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/power-meg-fx.c new file mode 100644 index 0000000000..eb2ffb5238 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/power-meg-fx.c @@ -0,0 +1,90 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "cpu.h" +#include +#include "kernel.h" +#include "system.h" +#include "power.h" +#include "pcf50606.h" +#include "backlight.h" +#include "backlight-target.h" + +#ifndef SIMULATOR + +void power_init(void) +{ + /* Charger detect */ +} + +bool charger_inserted(void) +{ + return (GPFDAT & (1 << 4)) ? false : true; +} + +/* Returns true if the unit is charging the batteries. */ +bool charging_state(void) { + return (GPGDAT & (1 << 8)) ? false : true; +} + +void ide_power_enable(bool on) +{ + if (on) + GPGDAT |= (1 << 11); + else + GPGDAT &= ~(1 << 11); +} + +bool ide_powered(void) +{ + return (GPGDAT & (1 << 11)) != 0; +} + +void power_off(void) +{ + /* turn off backlight and wait for 1 second */ + __backlight_off(); + sleep(HZ/2); + /* set SLEEP bit to on in CLKCON to turn off */ + CLKCON |=(1<<3); +} + +#else /* SIMULATOR */ + +bool charger_inserted(void) +{ + return false; +} + +void charger_enable(bool on) +{ + (void)on; +} + +void power_off(void) +{ +} + +void ide_power_enable(bool on) +{ + (void)on; +} + +#endif /* SIMULATOR */ + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c new file mode 100644 index 0000000000..e69eab432a --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c @@ -0,0 +1,225 @@ +#include "config.h" +#include "cpu.h" +#include +#include "kernel.h" +#include "system.h" +#include "logf.h" +#include "debug.h" +#include "string.h" + +#define SLAVE_ADDRESS 0xCC + +#define SDA_LO (GPHDAT &= ~(1 << 9)) +#define SDA_HI (GPHDAT |= (1 << 9)) +#define SDA_INPUT (GPHCON &= ~(3 << 18)) +#define SDA_OUTPUT (GPHCON |= (1 << 18)) +#define SDA (GPHDAT & (1 << 9)) + +#define SCL_LO (GPHDAT &= ~(1 << 10)) +#define SCL_HI (GPHDAT |= (1 << 10)) +#define SCL_INPUT (GPHCON &= ~(3 << 20)) +#define SCL_OUTPUT (GPHCON |= (1 << 20)) +#define SCL (GPHDAT & (1 << 10)) + +#define SCL_SDA_HI (GPHDAT |= (3 << 9)) + +/* The SC606 can clock at 400KHz: */ +/* Clock period high is 600nS and low is 1300nS */ +/* The high and low times are different enough to need different timings */ +/* cycles delayed = 30 + 7 * loops */ +/* 100MHz = 10nS per cycle: LO:1300nS=130:14 HI:600nS=60:9 */ +/* 300MHz = 3.36nS per cycle: LO:1300nS=387:51 HI:600nS=179:21 */ +#define DELAY_LO do{int x;for(x=51;x;x--);} while (0) +#define DELAY do{int x;for(x=35;x;x--);} while (0) +#define DELAY_HI do{int x;for(x=21;x;x--);} while (0) + + + +static void sc606_i2c_start(void) +{ + SCL_SDA_HI; + DELAY; + SDA_LO; + DELAY; + SCL_LO; +} + +static void sc606_i2c_restart(void) +{ + SCL_SDA_HI; + DELAY; + SDA_LO; + DELAY; + SCL_LO; +} + +static void sc606_i2c_stop(void) +{ + SDA_LO; + SCL_HI; + DELAY_HI; + SDA_HI; +} + +static void sc606_i2c_ack(void) +{ + + SDA_LO; + SCL_HI; + DELAY_HI; + SCL_LO; +} + + + +static int sc606_i2c_getack(void) +{ + int ret; + + /* Don't need a delay since follows a data bit with a delay on the end */ + SDA_INPUT; /* And set to input */ + DELAY; + SCL_HI; + + ret = (SDA != 0); /* ack failed if SDA is not low */ + DELAY_HI; + + SCL_LO; + DELAY_LO; + + SDA_HI; + SDA_OUTPUT; + DELAY_LO; + + return ret; +} + + + +static void sc606_i2c_outb(unsigned char byte) +{ + int i; + + /* clock out each bit, MSB first */ + for (i = 0x80; i; i >>= 1) + { + if (i & byte) + { + SDA_HI; + } + else + { + SDA_LO; + } + DELAY; + + SCL_HI; + DELAY_HI; + + SCL_LO; + DELAY_LO; + } + + SDA_HI; + +} + + + +static unsigned char sc606_i2c_inb(void) +{ + int i; + unsigned char byte = 0; + + SDA_INPUT; /* And set to input */ + /* clock in each bit, MSB first */ + for (i = 0x80; i; i >>= 1) { + SCL_HI; + + if (SDA) + byte |= i; + + SCL_LO; + } + SDA_OUTPUT; + + sc606_i2c_ack(); + + return byte; +} + + + +/* returns number of acks that were bad */ +int sc606_write(unsigned char reg, unsigned char data) +{ + int x; + + sc606_i2c_start(); + + sc606_i2c_outb(SLAVE_ADDRESS); + x = sc606_i2c_getack(); + + sc606_i2c_outb(reg); + x += sc606_i2c_getack(); + + sc606_i2c_restart(); + + sc606_i2c_outb(SLAVE_ADDRESS); + x += sc606_i2c_getack(); + + sc606_i2c_outb(data); + x += sc606_i2c_getack(); + + sc606_i2c_stop(); + + return x; +} + + + +int sc606_read(unsigned char reg, unsigned char* data) +{ + int x; + + sc606_i2c_start(); + sc606_i2c_outb(SLAVE_ADDRESS); + x = sc606_i2c_getack(); + + sc606_i2c_outb(reg); + x += sc606_i2c_getack(); + + sc606_i2c_restart(); + sc606_i2c_outb(SLAVE_ADDRESS | 1); + x += sc606_i2c_getack(); + + *data = sc606_i2c_inb(); + sc606_i2c_stop(); + + return x; +} + + + +void sc606_init(void) +{ + volatile int i; + + /* Set GPB2 (EN) to 1 */ + GPBCON = (GPBCON & ~(3<<4)) | 1<<4; + + /* Turn enable line on */ + GPBDAT |= 1<<2; + /* OFF GPBDAT &= ~(1 << 2); */ + + /* About 400us - needs 350us */ + for (i = 200; i; i--) + { + DELAY_LO; + } + + /* Set GPH9 (SDA) and GPH10 (SCL) to 1 */ + GPHUP &= ~(3<<9); + GPHCON = (GPHCON & ~(0xF<<18)) | 5<<18; +} + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.h b/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.h new file mode 100644 index 0000000000..3ea0917e86 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.h @@ -0,0 +1,28 @@ +#include "config.h" +#include "cpu.h" +#include +#include "kernel.h" +#include "system.h" +#include "logf.h" +#include "debug.h" +#include "string.h" + +#define SC606_REG_A 0 +#define SC606_REG_B 1 +#define SC606_REG_C 2 +#define SC606_REG_CONF 3 + +#define SC606_LED_A1 (1 << 0) +#define SC606_LED_A2 (1 << 1) +#define SC606_LED_B1 (1 << 2) +#define SC606_LED_B2 (1 << 3) +#define SC606_LED_C1 (1 << 4) +#define SC606_LED_C2 (1 << 5) + +#define SC606_LOW_FREQ (1 << 6) + +int sc606_write(unsigned char reg, unsigned char data); + +int sc606_read(unsigned char reg, unsigned char* data); + +void sc606_init(void); diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c new file mode 100644 index 0000000000..b7e59e66ea --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c @@ -0,0 +1,96 @@ +#include "kernel.h" +#include "system.h" +#include "panic.h" + +#include "lcd.h" +#include + +const int TIMER4_MASK = (1 << 14); +const int LCD_MASK = (1 << 16); +const int DMA0_MASK = (1 << 17); +const int DMA1_MASK = (1 << 18); +const int DMA2_MASK = (1 << 19); +const int DMA3_MASK = (1 << 20); + +int system_memory_guard(int newmode) +{ + (void)newmode; + return 0; +} + +extern void timer4(void); +extern void dma0(void); +extern void dma1(void); +extern void dma3(void); + +void irq(void) +{ + int intpending = INTPND; + + SRCPND = intpending; /* Clear this interrupt. */ + INTPND = intpending; /* Clear this interrupt. */ + + /* Timer 4 */ + if ((intpending & TIMER4_MASK) != 0) + timer4(); + else if ((intpending & DMA0_MASK) != 0) + dma0(); + else + { + /* unexpected interrupt */ + } +} + +void system_reboot(void) +{ + WTCON = 0; + WTCNT = WTDAT = 1 ; + WTCON = 0x21; + for(;;) + ; +} + +void system_init(void) +{ + /* Turn off un-needed devices */ + + /* Turn off all of the UARTS */ + CLKCON &= ~( (1<<10) | (1<<11) |(1<<12) ); + + /* Turn off AC97 and Camera */ + CLKCON &= ~( (1<<19) | (1<<20) ); + + /* Turn off USB host */ + CLKCON &= ~(1 << 6); + + /* Turn off NAND flash controller */ + CLKCON &= ~(1 << 4); + +} + + +#ifdef HAVE_ADJUSTABLE_CPU_FREQ + +void set_cpu_frequency(long frequency) +{ + if (frequency == CPUFREQ_MAX) + { + asm volatile("mov r0, #0\n" + "mrc p15, 0, r0, c1, c0, 0\n" + "orr r0, r0, #3<<30\n" /* set to Asynchronous mode*/ + "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); + + FREQ = CPUFREQ_MAX; + } + else + { + asm volatile("mov r0, #0\n" + "mrc p15, 0, r0, c1, c0, 0\n" + "bic r0, r0, #3<<30\n" /* set to FastBus mode*/ + "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); + + FREQ = CPUFREQ_NORMAL; + } +} + +#endif diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h new file mode 100644 index 0000000000..215b5a4daa --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Greg White + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef SYSTEM_TARGET_H +#define SYSTEM_TARGET_H + +#include "mmu-meg-fx.h" +#include "system-arm.h" + +#define CPUFREQ_DEFAULT 98784000 +#define CPUFREQ_NORMAL 98784000 +#define CPUFREQ_MAX 296352000 + +#define HAVE_INVALIDATE_ICACHE +static inline void invalidate_icache(void) +{ + clean_dcache(); + asm volatile( + "mov r0, #0 \n" + "mcr p15, 0, r0, c7, c5, 0 \n" + : : : "r0" + ); +} + +#endif /* SYSTEM_TARGET_H */ diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c new file mode 100644 index 0000000000..3aed8c3256 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c @@ -0,0 +1,94 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include +#include "cpu.h" +#include "system.h" +#include "kernel.h" +#include "ata.h" + +#define USB_RST_ASSERT GPBDAT &= ~(1 << 4) +#define USB_RST_DEASSERT GPBDAT |= (1 << 4) + +#define USB_VPLUS_PWR_ASSERT GPBDAT |= (1 << 6) +#define USB_VPLUS_PWR_DEASSERT GPBDAT &= ~(1 << 6) + +#define USB_UNIT_IS_PRESENT !(GPFDAT & 0x01) +#define USB_CRADLE_IS_PRESENT ((GPFDAT &0x02)&&!(GPGDAT&1<<14)) + +#define USB_CRADLE_BUS_ENABLE GPHDAT |= (1 << 8) +#define USB_CRADLE_BUS_DISABLE GPHDAT &= ~(1 << 8) + +/* The usb detect is one pin to the cpu active low */ +inline bool usb_detect(void) +{ + return USB_UNIT_IS_PRESENT | USB_CRADLE_IS_PRESENT; +} + +void usb_init_device(void) +{ + /* Input is the default configuration, only pullups need to be disabled */ + GPFUP|=0x02; + + USB_VPLUS_PWR_ASSERT; + GPBCON=( GPBCON&~(1<<13) ) | (1 << 12); + + sleep(HZ/20); + + /* Reset the usb port */ + USB_RST_ASSERT; + GPBCON = (GPBCON & ~0x200) | 0x100; /* Make sure reset line is an output */ + + sleep(HZ/25); + USB_RST_DEASSERT; + + /* needed to complete the reset */ + ata_enable(false); + + sleep(HZ/15); /* 66ms */ + + ata_enable(true); + + sleep(HZ/25); + + /* leave chip in low power mode */ + USB_VPLUS_PWR_DEASSERT; + + sleep(HZ/25); +} + +void usb_enable(bool on) +{ + if (on) + { + USB_VPLUS_PWR_ASSERT; + if(USB_CRADLE_IS_PRESENT) USB_CRADLE_BUS_ENABLE; + } + else + { + if(USB_CRADLE_IS_PRESENT) USB_CRADLE_BUS_DISABLE; + USB_VPLUS_PWR_DEASSERT; + } + + /* Make sure USB_CRADLE_BUS pin is an output */ + GPHCON=( GPHCON&~(1<<17) ) | (1<<16); /* Make the pin an output */ + GPHUP|=1<<8; /* Disable pullup in SOC as we are now driving */ + + sleep(HZ/20); // > 50ms for detecting the enable state change +} diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/usb-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/usb-target.h new file mode 100644 index 0000000000..baeb539b38 --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/usb-target.h @@ -0,0 +1,26 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef USB_TARGET_H +#define USB_TARGET_H + +bool usb_init_device(void); +bool usb_detect(void); +void usb_enable(bool on); + +#endif diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c new file mode 100644 index 0000000000..fe42b7527a --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c @@ -0,0 +1,71 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Gigabeat specific code for the Wolfson codec + * + * 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) + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "lcd.h" +#include "cpu.h" +#include "kernel.h" +#include "thread.h" +#include "power.h" +#include "debug.h" +#include "system.h" +#include "sprintf.h" +#include "button.h" +#include "string.h" +#include "file.h" +#include "buffer.h" +#include "audio.h" +#include "i2c.h" +#include "i2c-meg-fx.h" +/* + * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit + */ +void i2s_reset(void) +{ +} + +/* + * Initialise the WM8975 for playback via headphone and line out. + * Note, I'm using the WM8750 datasheet as its apparently close. + */ +int audiohw_init(void) { + /* reset I2C */ + i2c_init(); + + /* GPC5 controls headphone output */ + GPCCON &= ~(0x3 << 10); + GPCCON |= (1 << 10); + GPCDAT |= (1 << 5); + + return 0; +} + +void audiohw_postinit(void) +{ +} + +void wmcodec_write(int reg, int data) +{ + i2c_send(0x34, (reg<<1) | ((data&0x100)>>8), data&0xff); +} -- cgit v1.2.3