summaryrefslogtreecommitdiffstats
path: root/firmware/target/coldfire/iaudio/m5
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2007-03-05 00:04:00 +0000
committerJens Arnold <amiconn@rockbox.org>2007-03-05 00:04:00 +0000
commit8876018d25c6a56cce118482c1372bbff344cb23 (patch)
treea66dca10bf92674c655b9862fd366ecc77bba76a /firmware/target/coldfire/iaudio/m5
parentee07215d506def8d3483f4adf6e1d4ae51c10c52 (diff)
downloadrockbox-8876018d25c6a56cce118482c1372bbff344cb23.tar.gz
rockbox-8876018d25c6a56cce118482c1372bbff344cb23.zip
Bring up the M5 port to a working stage: Extended numerous explicit checks for IAUDIO_X5 to also check for IAUDIO_M5, moved code around the target tree, added preliminary background for the sim.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12610 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/coldfire/iaudio/m5')
-rw-r--r--firmware/target/coldfire/iaudio/m5/audio-m5.c82
-rw-r--r--firmware/target/coldfire/iaudio/m5/backlight-m5.c58
-rw-r--r--firmware/target/coldfire/iaudio/m5/backlight-target.h29
-rw-r--r--firmware/target/coldfire/iaudio/m5/button-m5.c151
-rw-r--r--firmware/target/coldfire/iaudio/m5/lcd-as-m5.S83
-rw-r--r--firmware/target/coldfire/iaudio/m5/lcd-m5.c219
-rw-r--r--firmware/target/coldfire/iaudio/m5/power-m5.c89
7 files changed, 711 insertions, 0 deletions
diff --git a/firmware/target/coldfire/iaudio/m5/audio-m5.c b/firmware/target/coldfire/iaudio/m5/audio-m5.c
new file mode 100644
index 0000000000..fcedbcad78
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m5/audio-m5.c
@@ -0,0 +1,82 @@
+/***************************************************************************
+ * __________ __ ___.
+ * 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 "cpu.h"
+#include "audio.h"
+#include "sound.h"
+
+void audio_set_output_source(int source)
+{
+ unsigned long txsrc;
+
+ if ((unsigned)source >= AUDIO_NUM_SOURCES)
+ txsrc = (3 << 8); /* playback, PDOR3 */
+ else
+ txsrc = (4 << 8); /* recording, iis1RcvData */
+
+ IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc;
+} /* audio_set_output_source */
+
+void audio_set_source(int source, unsigned flags)
+{
+ /* Prevent pops from unneeded switching */
+ static int last_source = AUDIO_SRC_PLAYBACK;
+
+ (void)flags;
+
+ switch (source)
+ {
+ default: /* playback - no recording */
+ source = AUDIO_SRC_PLAYBACK;
+ case AUDIO_SRC_PLAYBACK:
+ if (source != last_source)
+ {
+ audiohw_disable_recording();
+ audiohw_set_monitor(false);
+ /* Reset PDIR2 data flow */
+ DATAINCONTROL = (1 << 9);
+ }
+ break;
+
+ case AUDIO_SRC_MIC: /* recording only */
+ if (source != last_source)
+ {
+ audiohw_enable_recording(true); /* source mic */
+ /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */
+ DATAINCONTROL = (3 << 14) | (4 << 3);
+ }
+ break;
+
+ case AUDIO_SRC_LINEIN: /* recording only */
+ if (source != last_source)
+ {
+ audiohw_enable_recording(false); /* source line */
+ /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */
+ DATAINCONTROL = (3 << 14) | (4 << 3);
+ }
+ break;
+ } /* end switch */
+
+ or_l((1 << 29), &GPIO_OUT); /* Line In */
+ or_l((1 << 29), &GPIO_ENABLE);
+ or_l((1 << 29), &GPIO_FUNCTION);
+
+ last_source = source;
+} /* audio_set_source */
+
diff --git a/firmware/target/coldfire/iaudio/m5/backlight-m5.c b/firmware/target/coldfire/iaudio/m5/backlight-m5.c
new file mode 100644
index 0000000000..63bc5bc30e
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m5/backlight-m5.c
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * __________ __ ___.
+ * 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.h"
+#include "backlight-target.h"
+#include "pcf50606.h"
+#include "lcd.h"
+
+bool __backlight_init(void)
+{
+ __backlight_on();
+
+ return true; /* Backlight always ON after boot. */
+}
+
+void __backlight_on(void)
+{
+ int level = set_irq_level(HIGHEST_IRQ_LEVEL);
+
+ pcf50606_write(0x39, 0x07);
+ set_irq_level(level);
+}
+
+void __backlight_off(void)
+{
+ int level = set_irq_level(HIGHEST_IRQ_LEVEL);
+
+ pcf50606_write(0x39, 0x00);
+ set_irq_level(level);
+}
+
+void __remote_backlight_on(void)
+{
+ and_l(~0x00200000, &GPIO_OUT);
+}
+
+void __remote_backlight_off(void)
+{
+ or_l(0x00200000, &GPIO_OUT);
+}
diff --git a/firmware/target/coldfire/iaudio/m5/backlight-target.h b/firmware/target/coldfire/iaudio/m5/backlight-target.h
new file mode 100644
index 0000000000..d9c116803e
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m5/backlight-target.h
@@ -0,0 +1,29 @@
+/***************************************************************************
+ * __________ __ ___.
+ * 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
+
+#define __BACKLIGHT_INIT
+bool __backlight_init(void);
+void __backlight_on(void);
+void __backlight_off(void);
+void __remote_backlight_on(void);
+void __remote_backlight_off(void);
+
+#endif
diff --git a/firmware/target/coldfire/iaudio/m5/button-m5.c b/firmware/target/coldfire/iaudio/m5/button-m5.c
new file mode 100644
index 0000000000..a5fdd79fde
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m5/button-m5.c
@@ -0,0 +1,151 @@
+/***************************************************************************
+ * __________ __ ___.
+ * 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 "system.h"
+#include "button.h"
+#include "backlight.h"
+#include "adc.h"
+#include "lcd-remote-target.h"
+
+/* have buttons scan by default */
+static bool button_scan_on = true;
+static bool hold_button = false;
+static bool remote_hold_button = false;
+
+void button_init_device(void)
+{
+ /* Power, Remote Play & Hold switch */
+ GPIO_FUNCTION |= 0x0e000000;
+ GPIO_ENABLE &= ~0x0e000000;
+}
+
+void button_enable_scan(bool enable)
+{
+ button_scan_on = enable;
+}
+
+bool button_scan_enabled(void)
+{
+ return button_scan_on;
+}
+
+bool button_hold(void)
+{
+ return (GPIO_READ & 0x08000000) == 0;
+}
+
+bool remote_button_hold(void)
+{
+ return remote_hold_button;
+}
+
+int button_read_device(void)
+{
+ int btn = BUTTON_NONE;
+ bool hold_button_old;
+ bool remote_hold_button_old;
+ int data;
+
+ /* 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
+
+ if (button_scan_on && !hold_button)
+ {
+ data = adc_scan(ADC_BUTTONS);
+
+ if (data < 0xf0)
+ {
+ if(data < 0x7c)
+ if(data < 0x42)
+ btn = BUTTON_LEFT;
+ else
+ if(data < 0x62)
+ btn = BUTTON_RIGHT;
+ else
+ btn = BUTTON_SELECT;
+ else
+ if(data < 0xb6)
+ if(data < 0x98)
+ btn = BUTTON_PLAY;
+ else
+ btn = BUTTON_REC;
+ else
+ if(data < 0xd3)
+ btn = BUTTON_DOWN;
+ else
+ btn = BUTTON_UP;
+ }
+ }
+
+ /* remote buttons */
+ data = remote_detect() ? adc_scan(ADC_REMOTE) : 0xff;
+
+ remote_hold_button_old = remote_hold_button;
+ remote_hold_button = data < 0x17;
+
+#ifndef BOOTLOADER
+ if (remote_hold_button != remote_hold_button_old)
+ remote_backlight_hold_changed(remote_hold_button);
+#endif
+
+ if (!remote_hold_button)
+ {
+ if (data < 0xee)
+ {
+ if(data < 0x7a)
+ if(data < 0x41)
+ btn |= BUTTON_RC_FF;
+ else
+ if(data < 0x61)
+ btn |= BUTTON_RC_REW;
+ else
+ btn |= BUTTON_RC_MODE;
+ else
+ if(data < 0xb4)
+ if(data < 0x96)
+ btn |= BUTTON_RC_REC;
+ else
+ btn |= BUTTON_RC_MENU;
+ else
+ if(data < 0xd1)
+ btn |= BUTTON_RC_VOL_UP;
+ else
+ btn |= BUTTON_RC_VOL_DOWN;
+ }
+ }
+
+ data = GPIO_READ;
+
+ /* hold and power are mutually exclusive */
+ if (!(data & 0x04000000))
+ btn |= BUTTON_POWER;
+
+ /* remote play button should be dead if hold */
+ if (!remote_hold_button && !(data & 0x02000000))
+ btn |= BUTTON_RC_PLAY;
+
+ return btn;
+}
diff --git a/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S b/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S
new file mode 100644
index 0000000000..c973dc2c40
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Jens Arnold
+ *
+ * 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"
+
+ .section .icode,"ax",@progbits
+
+ .align 2
+ .global lcd_write_command
+ .type lcd_write_command,@function
+
+lcd_write_command:
+ move.l (4, %sp), %d0
+ move.w %d0, 0xf0008000
+ rts
+.wc_end:
+ .size lcd_write_command,.wc_end-lcd_write_command
+
+
+ .align 2
+ .global lcd_write_command_ex
+ .type lcd_write_command_ex,@function
+
+lcd_write_command_ex:
+ lea.l 0xf0008000, %a0
+
+ move.l (4, %sp), %d0 /* Command */
+ move.w %d0, (%a0)+ /* Write to LCD, set A0 = 1 */
+
+ move.l (8, %sp), %d0 /* Data */
+ cmp.l #-1, %d0 /* -1? */
+ beq.b .last
+ move.w %d0, (%a0) /* Write to LCD */
+
+ move.l (12, %sp), %d0 /* Data */
+ cmp.l #-1, %d0 /* -1? */
+ beq.b .last
+ move.w %d0, (%a0) /* Write to LCD */
+
+.last:
+ rts
+.wcex_end:
+ .size lcd_write_command_ex,.wcex_end-lcd_write_command_ex
+
+
+ .align 2
+ .global lcd_write_data
+ .type lcd_write_data,@function
+
+lcd_write_data:
+ move.l (4,%sp), %a0 /* Data pointer */
+ move.l (8,%sp), %d0 /* Length */
+
+ lea 0xf0008002, %a1
+.loop:
+ /* When running in IRAM, this loop takes 7 cycles plus the LCD write.
+ The 7 cycles are necessary to follow the LCD timing specs
+ at 140MHz */
+ move.b (%a0)+, %d1 /* 3(1/0) */
+ move.w %d1, (%a1) /* 1(0/1) */
+ subq.l #1, %d0 /* 1(0/0) */
+ nop /* 1(0/0) */
+ bne .loop /* 2(0/0) */
+ rts
+.wd_end:
+ .size lcd_write_data,.wd_end-lcd_write_data
diff --git a/firmware/target/coldfire/iaudio/m5/lcd-m5.c b/firmware/target/coldfire/iaudio/m5/lcd-m5.c
new file mode 100644
index 0000000000..2af46b3145
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m5/lcd-m5.c
@@ -0,0 +1,219 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Jens Arnold
+ *
+ * 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 "system.h"
+#include "kernel.h"
+#include "lcd.h"
+
+/*** definitions ***/
+
+/* LCD command codes */
+#define LCD_CNTL_POWER_CONTROL 0x25
+#define LCD_CNTL_VOLTAGE_SELECT 0x2b
+#define LCD_CNTL_LINE_INVERT_DRIVE 0x36
+#define LCD_CNTL_GRAY_SCALE_PATTERN 0x39
+#define LCD_CNTL_TEMP_GRADIENT_SELECT 0x4e
+#define LCD_CNTL_OSC_FREQUENCY 0x5f
+#define LCD_CNTL_ON_OFF 0xae
+#define LCD_CNTL_OSC_ON_OFF 0xaa
+#define LCD_CNTL_OFF_MODE 0xbe
+#define LCD_CNTL_POWER_SAVE 0xa8
+#define LCD_CNTL_REVERSE 0xa6
+#define LCD_CNTL_ALL_LIGHTING 0xa4
+#define LCD_CNTL_COMMON_OUTPUT_STATUS 0xc4
+#define LCD_CNTL_COLUMN_ADDRESS_DIR 0xa0
+#define LCD_CNTL_NLINE_ON_OFF 0xe4
+#define LCD_CNTL_DISPLAY_MODE 0x66
+#define LCD_CNTL_DUTY_SET 0x6d
+#define LCD_CNTL_ELECTRONIC_VOLUME 0x81
+#define LCD_CNTL_DATA_INPUT_DIR 0x84
+#define LCD_CNTL_DISPLAY_START_LINE 0x8a
+#define LCD_CNTL_AREA_SCROLL 0x10
+
+#define LCD_CNTL_PAGE 0xb1
+#define LCD_CNTL_COLUMN 0x13
+#define LCD_CNTL_DATA_WRITE 0x1d
+
+/*** shared semi-private declarations ***/
+extern const unsigned char lcd_dibits[16] ICONST_ATTR;
+
+/*** hardware configuration ***/
+int lcd_default_contrast(void)
+{
+ return DEFAULT_CONTRAST_SETTING;
+}
+
+void lcd_set_contrast(int val)
+{
+ /* Keep val in acceptable hw range */
+ if (val < 0)
+ val = 0;
+ else if (val > 127)
+ val = 127;
+
+ lcd_write_command_ex(LCD_CNTL_ELECTRONIC_VOLUME, val, -1);
+}
+
+void lcd_set_invert_display(bool yesno)
+{
+ lcd_write_command(LCD_CNTL_REVERSE | (yesno?1:0));
+}
+
+/* turn the display upside down (call lcd_update() afterwards) */
+void lcd_set_flip(bool yesno)
+{
+ if (yesno)
+ {
+ lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 0);
+ lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 1);
+ lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 2);
+ }
+ else
+ {
+ lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1);
+ lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0);
+ lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1);
+ }
+}
+
+void lcd_init_device(void)
+{
+ /* LCD Reset */
+ and_l(~0x00000010, &GPIO1_OUT);
+ or_l(0x00000010, &GPIO1_ENABLE);
+ or_l(0x00000010, &GPIO1_FUNCTION);
+ sleep(1);
+ or_l(0x00000010, &GPIO1_OUT);
+ sleep(1);
+
+ lcd_write_command(LCD_CNTL_ON_OFF | 1); /* LCD ON */
+ lcd_write_command(LCD_CNTL_OFF_MODE | 1); /* OFF -> VCC on drivers */
+ lcd_write_command(LCD_CNTL_REVERSE | 0); /* Reverse OFF */
+ lcd_write_command(LCD_CNTL_ALL_LIGHTING | 0); /* Normal */
+ lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0); /* Normal dir */
+ lcd_write_command_ex(LCD_CNTL_DISPLAY_START_LINE, 4, -1);
+ lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1); /* Reverse */
+ lcd_write_command_ex(LCD_CNTL_DISPLAY_MODE, 0, -1); /* Greyscale mode */
+ lcd_write_command_ex(LCD_CNTL_GRAY_SCALE_PATTERN, 0x53, -1);
+ lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1);
+ lcd_write_command_ex(LCD_CNTL_ELECTRONIC_VOLUME, 40, -1);
+
+ lcd_write_command(LCD_CNTL_OSC_ON_OFF | 1); /* Oscillator ON */
+ lcd_write_command(LCD_CNTL_POWER_SAVE | 0);
+ lcd_write_command_ex(LCD_CNTL_VOLTAGE_SELECT, 3, -1);
+ lcd_write_command_ex(LCD_CNTL_POWER_CONTROL, 0x17, -1);
+ lcd_write_command_ex(LCD_CNTL_OSC_FREQUENCY, 3, -1);
+ lcd_write_command(LCD_CNTL_NLINE_ON_OFF | 1); /* N-line ON */
+ lcd_write_command_ex(LCD_CNTL_LINE_INVERT_DRIVE, 0x10, -1);
+ lcd_write_command_ex(LCD_CNTL_TEMP_GRADIENT_SELECT, 0, -1);
+
+ lcd_update();
+}
+
+/*** update functions ***/
+
+/* Performance function that works with an external buffer
+ note that by and bheight are in 8-pixel units! */
+void lcd_blit(const unsigned char* data, int x, int by, int width,
+ int bheight, int stride)
+{
+ const unsigned char *src, *src_end;
+ unsigned char *dst_u, *dst_l;
+ static unsigned char upper[LCD_WIDTH] IBSS_ATTR;
+ static unsigned char lower[LCD_WIDTH] IBSS_ATTR;
+ unsigned int byte;
+
+ by *= 2;
+
+ while (bheight--)
+ {
+ src = data;
+ src_end = data + width;
+ dst_u = upper;
+ dst_l = lower;
+ do
+ {
+ byte = *src++;
+ *dst_u++ = lcd_dibits[byte & 0x0F];
+ byte >>= 4;
+ *dst_l++ = lcd_dibits[byte & 0x0F];
+ }
+ while (src < src_end);
+
+ lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
+ lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
+ lcd_write_command(LCD_CNTL_DATA_WRITE);
+ lcd_write_data(upper, width);
+
+ lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
+ lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
+ lcd_write_command(LCD_CNTL_DATA_WRITE);
+ lcd_write_data(lower, width);
+
+ data += stride;
+ }
+}
+
+
+/* Update the display.
+ This must be called after all other LCD functions that change the display. */
+void lcd_update(void) ICODE_ATTR;
+void lcd_update(void)
+{
+ int y;
+
+ /* Copy display bitmap to hardware */
+ for (y = 0; y < LCD_FBHEIGHT; y++)
+ {
+ lcd_write_command_ex(LCD_CNTL_PAGE, y, -1);
+ lcd_write_command_ex(LCD_CNTL_COLUMN, 0, -1);
+
+ lcd_write_command(LCD_CNTL_DATA_WRITE);
+ lcd_write_data (lcd_framebuffer[y], LCD_WIDTH);
+ }
+}
+
+/* Update a fraction of the display. */
+void lcd_update_rect(int, int, int, int) ICODE_ATTR;
+void lcd_update_rect(int x, int y, int width, int height)
+{
+ int ymax;
+
+ /* The Y coordinates have to work on even 8 pixel rows */
+ ymax = (y + height-1) >> 2;
+ y >>= 2;
+
+ if(x + width > LCD_WIDTH)
+ width = LCD_WIDTH - x;
+ if (width <= 0)
+ return; /* nothing left to do, 0 is harmful to lcd_write_data() */
+ if(ymax >= LCD_FBHEIGHT)
+ ymax = LCD_FBHEIGHT-1;
+
+ /* Copy specified rectange bitmap to hardware */
+ for (; y <= ymax; y++)
+ {
+ lcd_write_command_ex(LCD_CNTL_PAGE, y, -1);
+ lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
+
+ lcd_write_command(LCD_CNTL_DATA_WRITE);
+ lcd_write_data (&lcd_framebuffer[y][x], width);
+ }
+}
diff --git a/firmware/target/coldfire/iaudio/m5/power-m5.c b/firmware/target/coldfire/iaudio/m5/power-m5.c
new file mode 100644
index 0000000000..c689488bfe
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m5/power-m5.c
@@ -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.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "cpu.h"
+#include <stdbool.h>
+#include "kernel.h"
+#include "system.h"
+#include "power.h"
+#include "pcf50606.h"
+#include "lcd-remote-target.h"
+
+#ifndef SIMULATOR
+
+void power_init(void)
+{
+ /* Charger detect */
+ and_l(~0x01000000, &GPIO1_ENABLE);
+ or_l(0x01000000, &GPIO1_FUNCTION);
+
+ pcf50606_init();
+}
+
+bool charger_inserted(void)
+{
+ return (GPIO1_READ & 0x01000000)?true:false;
+}
+
+void ide_power_enable(bool on)
+{
+ /* GPOOD3 */
+ int level = set_irq_level(HIGHEST_IRQ_LEVEL);
+ if(on)
+ pcf50606_write(0x3c, 0x07);
+ else
+ pcf50606_write(0x3c, 0x00);
+ set_irq_level(level);
+}
+
+bool ide_powered(void)
+{
+ return false;
+}
+
+void power_off(void)
+{
+ lcd_remote_poweroff();
+ set_irq_level(HIGHEST_IRQ_LEVEL);
+ and_l(~0x00000008, &GPIO_OUT); /* Set KEEPACT low */
+ asm("halt");
+}
+
+#else
+
+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 */