summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-05-19 16:09:46 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2012-05-19 16:10:52 +0200
commit12c64a4b79e043d8e8d77a278b340310f867a588 (patch)
treeb34b56131d6eb0e06340a8a6d7e32843027d0f59 /firmware/target/arm
parente09c1e3d43665d04ae0ce2f288ba695b5abc3622 (diff)
downloadrockbox-12c64a4b79e043d8e8d77a278b340310f867a588.tar.gz
rockbox-12c64a4b79e043d8e8d77a278b340310f867a588.tar.bz2
rockbox-12c64a4b79e043d8e8d77a278b340310f867a588.zip
Initial commit for the Creative ZEN X-Fi2 and X-Fi3 ports
These are really similar devices so one commit for both is ok. Change-Id: I8bd1d3fef1eb6d00aaadfb7af56c771f62d0c9c3
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/adc-target.h32
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/adc-zenxfi2.c40
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/audio-zenxfi2.c55
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/backlight-target.h29
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/backlight-zenxfi2.c58
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/button-target.h59
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/button-zenxfi2.c119
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/debug-zenxfi2.c28
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/lcd-target.h24
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/lcd-zenxfi2.c512
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/power-zenxfi2.c42
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/powermgmt-target.h60
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi2/powermgmt-zenxfi2.c46
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/adc-target.h32
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/adc-zenxfi3.c40
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/audio-zenxfi3.c61
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/backlight-target.h33
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c85
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/button-target.h54
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c171
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/debug-zenxfi3.c28
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/lcd-target.h24
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/lcd-zenxfi3.c490
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/power-zenxfi3.c42
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/powermgmt-target.h58
-rw-r--r--firmware/target/arm/imx233/creative-zenxfi3/powermgmt-zenxfi3.c46
-rw-r--r--firmware/target/arm/imx233/sd-imx233.c22
-rw-r--r--firmware/target/arm/system-arm.c2
28 files changed, 2291 insertions, 1 deletions
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/adc-target.h b/firmware/target/arm/imx233/creative-zenxfi2/adc-target.h
new file mode 100644
index 0000000000..79b281b892
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/adc-target.h
@@ -0,0 +1,32 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _ADC_TARGET_H_
+#define _ADC_TARGET_H_
+
+#define NUM_ADC_CHANNELS 5
+
+#define ADC_BATTERY 0
+#define ADC_DIE_TEMP 1
+#define ADC_VDDIO 2
+#define ADC_5V 3
+#define ADC_BATT_TEMP 4
+
+#endif
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/adc-zenxfi2.c b/firmware/target/arm/imx233/creative-zenxfi2/adc-zenxfi2.c
new file mode 100644
index 0000000000..50ed498cc6
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/adc-zenxfi2.c
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "adc-target.h"
+#include "adc-imx233.h"
+
+int imx233_adc_mapping[] =
+{
+ [ADC_BATTERY] = IMX233_ADC_BATTERY,
+ [ADC_DIE_TEMP] = IMX233_ADC_DIE_TEMP,
+ [ADC_VDDIO] = IMX233_ADC_VDDIO,
+ [ADC_5V] = HW_LRADC_CHANNEL_5V,
+ [ADC_BATT_TEMP] = IMX233_ADC_BATT_TEMP,
+};
+
+const char *imx233_adc_channel_name[] =
+{
+ "Battery(raw)",
+ "Die temperature(°C)",
+ "VddIO",
+ "Vdd5V",
+ "Battery temperature(raw)",
+};
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/audio-zenxfi2.c b/firmware/target/arm/imx233/creative-zenxfi2/audio-zenxfi2.c
new file mode 100644
index 0000000000..810f1c156f
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/audio-zenxfi2.c
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "system.h"
+#include "audiohw.h"
+#include "audio.h"
+#include "audioout-imx233.h"
+#include "audioin-imx233.h"
+
+static int input_source = AUDIO_SRC_PLAYBACK;
+static unsigned input_flags = 0;
+static int output_source = AUDIO_SRC_PLAYBACK;
+
+static void select_audio_path(void)
+{
+ if(input_source == AUDIO_SRC_PLAYBACK)
+ imx233_audioout_select_hp_input(false);
+ else
+ imx233_audioout_select_hp_input(true);
+}
+
+void audio_input_mux(int source, unsigned flags)
+{
+ (void) source;
+ (void) flags;
+ input_source = source;
+ input_flags = flags;
+ select_audio_path();
+}
+
+void audio_set_output_source(int source)
+{
+ (void) source;
+ output_source = source;
+ select_audio_path();
+}
+
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/backlight-target.h b/firmware/target/arm/imx233/creative-zenxfi2/backlight-target.h
new file mode 100644
index 0000000000..e3766965d8
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/backlight-target.h
@@ -0,0 +1,29 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef BACKLIGHT_TARGET_H
+#define BACKLIGHT_TARGET_H
+
+bool _backlight_init(void);
+void _backlight_on(void);
+void _backlight_off(void);
+void _backlight_set_brightness(int brightness);
+
+#endif /* BACKLIGHT_TARGET_H */
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/backlight-zenxfi2.c b/firmware/target/arm/imx233/creative-zenxfi2/backlight-zenxfi2.c
new file mode 100644
index 0000000000..8fcdd8ba32
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/backlight-zenxfi2.c
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "system.h"
+#include "lcd.h"
+#include "backlight.h"
+#include "backlight-target.h"
+#include "pwm-imx233.h"
+
+void _backlight_set_brightness(int brightness)
+{
+ imx233_pwm_setup_channel(4, 1024, HW_PWM_PERIODx__CDIV__DIV_1,
+ 0, HW_PWM_PERIODx__STATE__HIGH,
+ (brightness * 1024) / 100, HW_PWM_PERIODx__STATE__LOW);
+ imx233_pwm_enable_channel(4, true);
+}
+
+bool _backlight_init(void)
+{
+ _backlight_set_brightness(DEFAULT_BRIGHTNESS_SETTING);
+ return true;
+}
+
+void _backlight_on(void)
+{
+#ifdef HAVE_LCD_ENABLE
+ lcd_enable(true); /* power on lcd + visible display */
+#endif
+ /* don't do anything special, the core will set the brightness */
+}
+
+void _backlight_off(void)
+{
+ /* there is no real on/off but we can set to 0 brightness */
+ _backlight_set_brightness(0);
+#ifdef HAVE_LCD_ENABLE
+ lcd_enable(false); /* power off visible display */
+#endif
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/button-target.h b/firmware/target/arm/imx233/creative-zenxfi2/button-target.h
new file mode 100644
index 0000000000..8f4cda85d8
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/button-target.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _BUTTON_TARGET_H_
+#define _BUTTON_TARGET_H_
+
+#include <stdbool.h>
+#include "config.h"
+
+void button_init_device(void);
+int button_read_device(int *data);
+bool button_debug_screen(void);
+
+/* Main unit's buttons */
+#define BUTTON_POWER 0x00000001
+#define BUTTON_MENU 0x00000002
+/* For compatibility */
+#define BUTTON_LEFT BUTTON_MIDLEFT
+#define BUTTON_RIGHT BUTTON_MIDRIGHT
+#define BUTTON_UP BUTTON_TOPMIDDLE
+#define BUTTON_DOWN BUTTON_BOTTOMMIDDLE
+
+/* Touch Screen Area Buttons */
+#define BUTTON_TOPLEFT 0x00000010
+#define BUTTON_TOPMIDDLE 0x00000020
+#define BUTTON_TOPRIGHT 0x00000040
+#define BUTTON_MIDLEFT 0x00000080
+#define BUTTON_CENTER 0x00000100
+#define BUTTON_MIDRIGHT 0x00000200
+#define BUTTON_BOTTOMLEFT 0x00000400
+#define BUTTON_BOTTOMMIDDLE 0x00000800
+#define BUTTON_BOTTOMRIGHT 0x00001000
+
+#define BUTTON_MAIN 0x1fff
+
+#define BUTTON_REMOTE 0
+
+/* Software power-off */
+#define POWEROFF_BUTTON BUTTON_POWER
+#define POWEROFF_COUNT 10
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/button-zenxfi2.c b/firmware/target/arm/imx233/creative-zenxfi2/button-zenxfi2.c
new file mode 100644
index 0000000000..d6a4209292
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/button-zenxfi2.c
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "button-target.h"
+#include "system.h"
+#include "system-target.h"
+#include "pinctrl-imx233.h"
+#include "power-imx233.h"
+#include "string.h"
+#include "usb.h"
+#include "touchscreen.h"
+#include "touchscreen-imx233.h"
+
+struct touch_calibration_point
+{
+ short px_x; /* known pixel value */
+ short px_y;
+ short val_x; /* touchscreen value at the known pixel */
+ short val_y;
+};
+
+static struct touch_calibration_point topleft, bottomright;
+
+/* Amaury Pouly: values on my device
+ * Portait: (x and y are swapped)
+ * (0,0) = 200, 300
+ * (240,400) = 3900, 3800
+ * Landscape:
+ * (0,0) = 200, 3800
+ * (400,240) = 3900, 300
+*/
+void button_init_device(void)
+{
+#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
+ topleft.val_x = 300;
+ topleft.val_y = 200;
+
+ bottomright.val_x = 3800;
+ bottomright.val_y = 3900;
+#else
+ topleft.val_x = 300;
+ topleft.val_y = 3900;
+
+ bottomright.val_x = 3800;
+ bottomright.val_y = 200;
+#endif
+ topleft.px_x = 0;
+ topleft.px_y = 0;
+
+ bottomright.px_x = LCD_WIDTH;
+ bottomright.px_y = LCD_HEIGHT;
+
+ imx233_touchscreen_init();
+ imx233_touchscreen_enable(true);
+}
+
+static int touch_to_pixels(int *val_x, int *val_y)
+{
+ short x,y;
+
+#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
+ x = *val_y;
+ y = *val_x;
+#else
+ x = *val_x;
+ y = *val_y;
+#endif
+
+ x = (x - topleft.val_x) * (bottomright.px_x - topleft.px_x) / (bottomright.val_x - topleft.val_x) + topleft.px_x;
+ y = (y - topleft.val_y) * (bottomright.px_y - topleft.px_y) / (bottomright.val_y - topleft.val_y) + topleft.px_y;
+
+ x = MAX(0, MIN(x, LCD_WIDTH - 1));
+ y = MAX(0, MIN(y, LCD_HEIGHT - 1));
+
+ *val_x = x;
+ *val_y = y;
+
+ return (x<<16)|y;
+}
+
+static int touchscreen_read_device(int *data)
+{
+ int x, y;
+ if(!imx233_touchscreen_get_touch(&x, &y))
+ return 0;
+ if(data)
+ *data = touch_to_pixels(&x, &y);
+ return touchscreen_to_pixels(x, y, data);
+}
+
+int button_read_device(int *data)
+{
+ int res = 0;
+ /* B0P11: #power
+ * B0P14: #select */
+ uint32_t mask = imx233_get_gpio_input_mask(0, 0x4800);
+ if(!(mask & 0x800))
+ res |= BUTTON_POWER;
+ if(!(mask & 0x4000))
+ res |= BUTTON_MENU;
+ return res | touchscreen_read_device(data);
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/debug-zenxfi2.c b/firmware/target/arm/imx233/creative-zenxfi2/debug-zenxfi2.c
new file mode 100644
index 0000000000..a18704243e
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/debug-zenxfi2.c
@@ -0,0 +1,28 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "system.h"
+#include "button-target.h"
+
+bool dbg_hw_target_info(void)
+{
+ return false;
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/lcd-target.h b/firmware/target/arm/imx233/creative-zenxfi2/lcd-target.h
new file mode 100644
index 0000000000..5c1ecdd406
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/lcd-target.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (c) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef LCD_TARGET_H
+#define LCD_TARGET_H
+
+#endif /* LCD_TARGET_H */
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/lcd-zenxfi2.c b/firmware/target/arm/imx233/creative-zenxfi2/lcd-zenxfi2.c
new file mode 100644
index 0000000000..277c7120e1
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/lcd-zenxfi2.c
@@ -0,0 +1,512 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (c) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <sys/types.h> /* off_t */
+#include <string.h>
+#include "cpu.h"
+#include "system.h"
+#include "backlight-target.h"
+#include "lcd.h"
+#include "lcdif-imx233.h"
+#include "clkctrl-imx233.h"
+#include "pinctrl-imx233.h"
+#include "logf.h"
+
+#ifdef HAVE_LCD_ENABLE
+static bool lcd_on;
+#endif
+static unsigned lcd_yuv_options = 0;
+
+static void setup_parameters(void)
+{
+ imx233_lcdif_reset();
+ imx233_lcdif_set_lcd_databus_width(HW_LCDIF_CTRL__LCD_DATABUS_WIDTH_18_BIT);
+ imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_18_BIT);
+ imx233_lcdif_set_timings(2, 2, 3, 3);
+}
+
+static void setup_lcd_pins(bool use_lcdif)
+{
+ if(use_lcdif)
+ {
+ imx233_set_pin_function(1, 25, PINCTRL_FUNCTION_MAIN); /* lcd_vsync */
+ imx233_set_pin_function(1, 21, PINCTRL_FUNCTION_MAIN); /* lcd_cs */
+ imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_MAIN); /* lcd_dotclk */
+ imx233_set_pin_function(1, 23, PINCTRL_FUNCTION_MAIN); /* lcd_enable */
+ imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_MAIN); /* lcd_hsync */
+ imx233_set_pin_function(1, 18, PINCTRL_FUNCTION_MAIN); /* lcd_reset */
+ imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_MAIN); /* lcd_rs */
+ imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_MAIN); /* lcd_d16 */
+ imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_MAIN); /* lcd_d17 */
+ imx233_set_pin_function(1, 20, PINCTRL_FUNCTION_MAIN); /* lcd_wr */
+ __REG_CLR(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} */
+ }
+ else
+ {
+ __REG_SET(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} */
+ imx233_enable_gpio_output_mask(1, 0x3ffffff, false); /* lcd_{d{0-17},reset,rs,wr,cs,dotclk,enable,hsync,vsync} */
+ imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_GPIO); /* lcd_d16 */
+ imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_GPIO); /* lcd_d17 */
+ imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_GPIO); /* lcd_rs */
+ imx233_set_pin_function(1, 20, PINCTRL_FUNCTION_GPIO); /* lcd_wr */
+ imx233_set_pin_function(1, 21, PINCTRL_FUNCTION_GPIO); /* lcd_cs */
+ imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO); /* lcd_dotclk */
+ imx233_set_pin_function(1, 23, PINCTRL_FUNCTION_GPIO); /* lcd_enable */
+ imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO); /* lcd_hsync */
+ imx233_set_pin_function(1, 25, PINCTRL_FUNCTION_GPIO); /* lcd_vsync */
+ }
+}
+
+static void common_lcd_enable(bool enable)
+{
+ imx233_lcdif_enable(enable);
+ setup_lcd_pins(enable); /* use GPIO pins when disable */
+}
+
+static void setup_lcdif(void)
+{
+ setup_parameters();
+ common_lcd_enable(true);
+ imx233_lcdif_enable_bus_master(true);
+}
+
+static inline uint32_t encode_16_to_18(uint32_t a)
+{
+ return ((a & 0xff) << 1) | (((a >> 8) & 0xff) << 10);
+}
+
+static inline uint32_t decode_18_to_16(uint32_t a)
+{
+ return ((a >> 1) & 0xff) | ((a >> 2) & 0xff00);
+}
+
+static void setup_lcdif_clock(void)
+{
+ /* the LCD seems to work at 24Mhz, so use the xtal clock with no divider */
+ imx233_clkctrl_enable_clock(CLK_PIX, false);
+ imx233_clkctrl_set_clock_divisor(CLK_PIX, 1);
+ imx233_clkctrl_set_bypass_pll(CLK_PIX, true); /* use XTAL */
+ imx233_clkctrl_enable_clock(CLK_PIX, true);
+}
+
+static void lcd_write_reg(uint32_t reg, uint32_t data)
+{
+ uint32_t old_reg = reg;
+ /* get back to 18-bit word length */
+ imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_18_BIT);
+ reg = encode_16_to_18(reg);
+ data = encode_16_to_18(data);
+
+ imx233_lcdif_pio_send(false, 2, &reg);
+ if(old_reg != 0 && old_reg != 0x202)
+ imx233_lcdif_pio_send(true, 2, &data);
+}
+
+#define REG_MDELAY 0xffffffff
+struct lcd_sequence_entry_t
+{
+ uint32_t reg, data;
+};
+
+static void lcd_send_sequence(struct lcd_sequence_entry_t *seq, unsigned count)
+{
+ for(;count-- > 0; seq++)
+ {
+ if(seq->reg == REG_MDELAY)
+ mdelay(seq->data);
+ else
+ lcd_write_reg(seq->reg, seq->data);
+ }
+}
+
+#define _begin_seq() static struct lcd_sequence_entry_t __seq[] = {
+#define _mdelay(a) {REG_MDELAY, a},
+#define _lcd_write_reg(a, b) {a, b},
+#define _end_seq() }; lcd_send_sequence(__seq, sizeof(__seq) / sizeof(__seq[0]));
+
+static void lcd_init_seq(void)
+{
+ _begin_seq()
+ _lcd_write_reg(0, 0)
+ _lcd_write_reg(0, 0)
+ _lcd_write_reg(0, 0)
+ _lcd_write_reg(0, 0)
+ _mdelay(100)
+ _lcd_write_reg(8, 0x808)
+ _lcd_write_reg(0x10, 0x10)
+ _lcd_write_reg(0x400, 0x6200)
+ _lcd_write_reg(0x300, 0xc0a)
+ _lcd_write_reg(0x301, 0x4c11)
+ _lcd_write_reg(0x302, 0x906)
+ _lcd_write_reg(0x303, 0x1417)
+ _lcd_write_reg(0x304, 0x3333)
+ _lcd_write_reg(0x305, 0x150d)
+ _lcd_write_reg(0x306, 0x740a)
+ _lcd_write_reg(0x307, 0x100c)
+ _lcd_write_reg(0x308, 0x60c)
+ _lcd_write_reg(0x309, 0)
+ _lcd_write_reg(0x100, 0x730)
+ _lcd_write_reg(0x101, 0x237)
+ _lcd_write_reg(0x103, 0x2b00)
+ _lcd_write_reg(0x280, 0x4000)
+ _lcd_write_reg(0x102, 0x81b0)
+ _mdelay(400)
+ _lcd_write_reg(1, 0x100)
+ _lcd_write_reg(2, 0x100)
+ _lcd_write_reg(3, 0x5028)
+ _lcd_write_reg(9, 1)
+ _lcd_write_reg(0xc, 0)
+ _lcd_write_reg(0x11, 0x202)
+ _lcd_write_reg(0x12, 0x101)
+ _lcd_write_reg(0x13, 1)
+ _lcd_write_reg(0x90, 0x8000)
+ _lcd_write_reg(0x210, 0)
+ _lcd_write_reg(0x211, 0xef)
+ _lcd_write_reg(0x212, 0)
+ _lcd_write_reg(0x213, 0x18f)
+ _lcd_write_reg(0x200, 0)
+ _lcd_write_reg(0x201, 0)
+ _lcd_write_reg(0x401, 1)
+ _lcd_write_reg(0x404, 0)
+ _mdelay(400)
+ _lcd_write_reg(7, 0x100)
+ _mdelay(400)
+ _lcd_write_reg(3, 0x1030)
+ _end_seq()
+}
+
+void lcd_init_device(void)
+{
+ setup_lcdif();
+ setup_lcdif_clock();
+
+ // reset device
+ __REG_SET(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
+ mdelay(50);
+ __REG_CLR(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
+ mdelay(10);
+ __REG_SET(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
+
+ lcd_init_seq();
+#ifdef HAVE_LCD_ENABLE
+ lcd_on = true;
+#endif
+}
+
+#ifdef HAVE_LCD_ENABLE
+bool lcd_active(void)
+{
+ return lcd_on;
+}
+
+static void lcd_enable_seq(bool enable)
+{
+ if(!enable)
+ {
+ _begin_seq()
+ _end_seq()
+ }
+ else
+ {
+ _begin_seq()
+ _end_seq()
+ }
+}
+
+void lcd_enable(bool enable)
+{
+ if(lcd_on == enable)
+ return;
+
+ lcd_on = enable;
+
+ if(enable)
+ common_lcd_enable(true);
+ lcd_enable_seq(enable);
+ if(!enable)
+ common_lcd_enable(false);
+}
+#endif
+
+void lcd_update(void)
+{
+ lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+}
+
+void lcd_update_rect(int x, int y, int w, int h)
+{
+#ifdef HAVE_LCD_ENABLE
+ if(!lcd_on)
+ return;
+#endif
+ /* make sure the rectangle is included in the screen */
+ x = MIN(x, LCD_WIDTH);
+ y = MIN(y, LCD_HEIGHT);
+ w = MIN(w, LCD_WIDTH - x);
+ h = MIN(h, LCD_HEIGHT - y);
+
+ imx233_lcdif_wait_ready();
+ lcd_write_reg(0x210, x);
+ lcd_write_reg(0x211, x + w - 1);
+ lcd_write_reg(0x212, y);
+ lcd_write_reg(0x213, y + h - 1);
+ lcd_write_reg(0x200, 0);
+ lcd_write_reg(0x201, 0);
+ lcd_write_reg(0x202, 0);
+ imx233_lcdif_wait_ready();
+ imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_16_BIT);
+ imx233_lcdif_set_byte_packing_format(0xf); /* two pixels per 32-bit word */
+ imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */
+
+ /* there are two cases here:
+ * - either width = LCD_WIDTH and we can directly memcopy a part of lcd_framebuffer to FRAME
+ * and send it
+ * - either width != LCD_WIDTH and we have to build a contiguous copy of the rectangular area
+ * into FRAME before sending it (which is slower and doesn't use the hardware)
+ * In all cases, FRAME just acts as a temporary buffer.
+ * NOTE It's more interesting to do a copy to FRAME in all cases since in system mode
+ * the clock runs at 24MHz which provides barely 10MB/s bandwidth compared to >100MB/s
+ * for memcopy operations
+ */
+ if(w == LCD_WIDTH)
+ {
+ memcpy((void *)FRAME, FBADDR(x,y), w * h * sizeof(fb_data));
+ }
+ else
+ {
+ for(int i = 0; i < h; i++)
+ memcpy((fb_data *)FRAME + i * w, FBADDR(x,y + i), w * sizeof(fb_data));
+ }
+ /* WARNING The LCDIF has a limitation on the vertical count ! In 16-bit packed mode
+ * (which we used, ie 16-bit per pixel, 2 pixels per 32-bit words), the v_count
+ * field must be a multiple of 2. Furthermore, it seems the lcd controller doesn't
+ * really like when both w and h are even, probably because the writes to the GRAM
+ * are done on several words and the controller requires dummy writes.
+ * The workaround is to always make sure that we send a number of pixels which is
+ * a multiple of 4 so that both the lcdif and the controller are happy. If any
+ * of w or h is odd, we will send a copy of the first pixels as dummy writes. We will
+ * send at most 3 bytes. We then send (w * h + 3) / 4 x 4 bytes.
+ */
+ if(w % 2 == 1 || h % 2 == 1)
+ {
+ /* copy three pixel after the last one */
+ for(int i = 0; i < 3; i++)
+ *((fb_data *)FRAME + w * h + i) = *((fb_data *)FRAME + i);
+ /* WARNING we need to update w and h to reflect the pixel count BUT it
+ * has no relation to w * h (it can even be 2 * prime). Hopefully, w <= 240 and
+ * h <= 320 so w * h <= 76800 and (w * h + 3) / 4 <= 38400 which fits into
+ * a 16-bit integer (horizontal count). */
+ h = (w * h + 3) / 4;
+ w = 4;
+ }
+ imx233_lcdif_dma_send((void *)FRAME_PHYS_ADDR, w, h);
+}
+
+void lcd_yuv_set_options(unsigned options)
+{
+ lcd_yuv_options = options;
+}
+
+#define YFAC (74)
+#define RVFAC (101)
+#define GUFAC (-24)
+#define GVFAC (-51)
+#define BUFAC (128)
+
+static inline int clamp(int val, int min, int max)
+{
+ if (val < min)
+ val = min;
+ else if (val > max)
+ val = max;
+ return val;
+}
+
+void lcd_blit_yuv(unsigned char * const src[3],
+ int src_x, int src_y, int stride,
+ int x, int y, int width, int height)
+{
+ const unsigned char *ysrc, *usrc, *vsrc;
+ int linecounter;
+ fb_data *dst, *row_end;
+ long z;
+
+ /* width and height must be >= 2 and an even number */
+ width &= ~1;
+ linecounter = height >> 1;
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst = FBADDR(x,y);
+ row_end = dst + width;
+ #else
+ dst = FBADDR(LCD_WIDTH - y - 1,x);
+ row_end = dst + LCD_WIDTH * width;
+ #endif
+
+ z = stride * src_y;
+ ysrc = src[0] + z + src_x;
+ usrc = src[1] + (z >> 2) + (src_x >> 1);
+ vsrc = src[2] + (usrc - src[1]);
+
+ /* stride => amount to jump from end of last row to start of next */
+ stride -= width;
+
+ /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
+
+ do
+ {
+ do
+ {
+ int y, cb, cr, rv, guv, bu, r, g, b;
+
+ y = YFAC*(*ysrc++ - 16);
+ cb = *usrc++ - 128;
+ cr = *vsrc++ - 128;
+
+ rv = RVFAC*cr;
+ guv = GUFAC*cb + GVFAC*cr;
+ bu = BUFAC*cb;
+
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 64*256-1)
+ {
+ r = clamp(r, 0, 64*256-1);
+ g = clamp(g, 0, 64*256-1);
+ b = clamp(b, 0, 64*256-1);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+ #else
+ dst += LCD_WIDTH;
+ #endif
+
+ y = YFAC*(*ysrc++ - 16);
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 64*256-1)
+ {
+ r = clamp(r, 0, 64*256-1);
+ g = clamp(g, 0, 64*256-1);
+ b = clamp(b, 0, 64*256-1);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+ #else
+ dst += LCD_WIDTH;
+ #endif
+ }
+ while (dst < row_end);
+
+ ysrc += stride;
+ usrc -= width >> 1;
+ vsrc -= width >> 1;
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ row_end += LCD_WIDTH;
+ dst += LCD_WIDTH - width;
+ #else
+ row_end -= 1;
+ dst -= LCD_WIDTH*width + 1;
+ #endif
+
+ do
+ {
+ int y, cb, cr, rv, guv, bu, r, g, b;
+
+ y = YFAC*(*ysrc++ - 16);
+ cb = *usrc++ - 128;
+ cr = *vsrc++ - 128;
+
+ rv = RVFAC*cr;
+ guv = GUFAC*cb + GVFAC*cr;
+ bu = BUFAC*cb;
+
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 64*256-1)
+ {
+ r = clamp(r, 0, 64*256-1);
+ g = clamp(g, 0, 64*256-1);
+ b = clamp(b, 0, 64*256-1);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+ #else
+ dst += LCD_WIDTH;
+ #endif
+
+ y = YFAC*(*ysrc++ - 16);
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 64*256-1)
+ {
+ r = clamp(r, 0, 64*256-1);
+ g = clamp(g, 0, 64*256-1);
+ b = clamp(b, 0, 64*256-1);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+ #else
+ dst += LCD_WIDTH;
+ #endif
+ }
+ while (dst < row_end);
+
+ ysrc += stride;
+ usrc += stride >> 1;
+ vsrc += stride >> 1;
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ row_end += LCD_WIDTH;
+ dst += LCD_WIDTH - width;
+ #else
+ row_end -= 1;
+ dst -= LCD_WIDTH*width + 1;
+ #endif
+ }
+ while (--linecounter > 0);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ lcd_update_rect(x, y, width, height);
+ #else
+ lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
+ #endif
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/power-zenxfi2.c b/firmware/target/arm/imx233/creative-zenxfi2/power-zenxfi2.c
new file mode 100644
index 0000000000..180b7f9d4c
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/power-zenxfi2.c
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "system.h"
+#include "power.h"
+#include "tuner.h"
+#include "fmradio_i2c.h"
+#include "pinctrl-imx233.h"
+
+static bool tuner_enable = false;
+
+bool tuner_power(bool enable)
+{
+ if(enable != tuner_enable)
+ {
+ tuner_enable = enable;
+ }
+ return tuner_enable;
+}
+
+bool tuner_powered(void)
+{
+ return tuner_enable;
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/powermgmt-target.h b/firmware/target/arm/imx233/creative-zenxfi2/powermgmt-target.h
new file mode 100644
index 0000000000..6790772704
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/powermgmt-target.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef POWERMGMT_TARGET_H
+#define POWERMGMT_TARGET_H
+
+#include "config.h"
+#include "powermgmt-imx233.h"
+
+/* Creative ZEN X-Fi2 OF settings:
+ * - current ramp slope: 100 mA/s
+ * - conditioning threshold voltage: 3 V
+ * - conditioning max voltage: 3.1 V
+ * - conditioning current: 60 mA
+ * - conditioning timeout: 1 h
+ * - charging voltage: 4.2 V
+ * - charging current: 550 mA
+ * - charging threshold current: 60 mA
+ * - charging timeout: 4 h
+ * - top off period: 30 min
+ * - high die temperature: 74 °C
+ * - low die temperature: 56 °C
+ * - safe die temperature current: 30 mA
+ * - battery temperature channel: 1
+ * - high battery temperature: 440
+ * - low battery temperature: 605
+ * - safe battery temperature current: 0 mA
+ * - low DCDC battery voltage: 3.9 V
+ *
+ * FIXME is this an OF bug that low batt temp > high batt temp ?
+ */
+
+#define IMX233_CHARGE_CURRENT 550
+#define IMX233_STOP_CURRENT 60
+#define IMX233_TOPOFF_TIMEOUT (30 * 60 * HZ)
+#define IMX233_CHARGING_TIMEOUT (4 * 3600 * HZ)
+#define IMX233_DIE_TEMP_HIGH 74
+#define IMX233_DIE_TEMP_LOW 56
+#define IMX233_BATT_TEMP_SENSOR 1
+#define IMX233_BATT_TEMP_HIGH 440
+#define IMX233_BATT_TEMP_LOW 605
+
+#endif /* POWERMGMT_TARGET_H */
diff --git a/firmware/target/arm/imx233/creative-zenxfi2/powermgmt-zenxfi2.c b/firmware/target/arm/imx233/creative-zenxfi2/powermgmt-zenxfi2.c
new file mode 100644
index 0000000000..3e068f007d
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi2/powermgmt-zenxfi2.c
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "powermgmt-target.h"
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+ 3659
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+ 3630
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+ /* Toshiba Gigabeat S Li Ion 700mAH figured from discharge curve */
+ { 3659, 3719, 3745, 3761, 3785, 3813, 3856, 3926, 3984, 4040, 4121 },
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+{
+ /* Toshiba Gigabeat S Li Ion 700mAH figured from charge curve */
+ 4028, 4063, 4087, 4111, 4135, 4156, 4173, 4185, 4194, 4202, 4208
+};
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/adc-target.h b/firmware/target/arm/imx233/creative-zenxfi3/adc-target.h
new file mode 100644
index 0000000000..d946989c1c
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/adc-target.h
@@ -0,0 +1,32 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _ADC_TARGET_H_
+#define _ADC_TARGET_H_
+
+#define NUM_ADC_CHANNELS 5
+
+#define ADC_BATTERY 0
+#define ADC_DIE_TEMP 1
+#define ADC_VDDIO 2
+#define ADC_5V 3
+#define ADC_BATT_TEMP 4
+
+#endif
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/adc-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/adc-zenxfi3.c
new file mode 100644
index 0000000000..6671c7202e
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/adc-zenxfi3.c
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "adc-target.h"
+#include "adc-imx233.h"
+
+int imx233_adc_mapping[] =
+{
+ [ADC_BATTERY] = IMX233_ADC_BATTERY,
+ [ADC_DIE_TEMP] = IMX233_ADC_DIE_TEMP,
+ [ADC_VDDIO] = IMX233_ADC_VDDIO,
+ [ADC_5V] = HW_LRADC_CHANNEL_5V,
+ [ADC_BATT_TEMP] = IMX233_ADC_BATT_TEMP,
+};
+
+const char *imx233_adc_channel_name[] =
+{
+ "Battery(raw)",
+ "Die temperature(°C)",
+ "VddIO",
+ "Vdd5V",
+ "Battery temperature(raw)",
+};
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/audio-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/audio-zenxfi3.c
new file mode 100644
index 0000000000..faf15242ab
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/audio-zenxfi3.c
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "system.h"
+#include "audiohw.h"
+#include "audio.h"
+#include "audioout-imx233.h"
+#include "audioin-imx233.h"
+#include "pinctrl-imx233.h"
+
+static int input_source = AUDIO_SRC_PLAYBACK;
+static unsigned input_flags = 0;
+static int output_source = AUDIO_SRC_PLAYBACK;
+
+static void select_audio_path(void)
+{
+ /* route audio to HP */
+ imx233_set_pin_function(1, 30, PINCTRL_FUNCTION_GPIO);
+ imx233_enable_gpio_output(1, 30, true);
+ imx233_set_gpio_output(1, 30, true);
+
+ if(input_source == AUDIO_SRC_PLAYBACK)
+ imx233_audioout_select_hp_input(false);
+ else
+ imx233_audioout_select_hp_input(true);
+}
+
+void audio_input_mux(int source, unsigned flags)
+{
+ (void) source;
+ (void) flags;
+ input_source = source;
+ input_flags = flags;
+ select_audio_path();
+}
+
+void audio_set_output_source(int source)
+{
+ (void) source;
+ output_source = source;
+ select_audio_path();
+}
+
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/backlight-target.h b/firmware/target/arm/imx233/creative-zenxfi3/backlight-target.h
new file mode 100644
index 0000000000..c7508c87a3
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/backlight-target.h
@@ -0,0 +1,33 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef BACKLIGHT_TARGET_H
+#define BACKLIGHT_TARGET_H
+
+bool _backlight_init(void);
+void _backlight_on(void);
+void _backlight_off(void);
+void _backlight_set_brightness(int brightness);
+
+void _buttonlight_on(void);
+void _buttonlight_off(void);
+void _buttonlight_set_brightness(int brightness);
+
+#endif /* BACKLIGHT_TARGET_H */
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c
new file mode 100644
index 0000000000..59c3c133aa
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "system.h"
+#include "lcd.h"
+#include "backlight.h"
+#include "backlight-target.h"
+#include "pwm-imx233.h"
+#include "mpr121.h"
+
+void _backlight_set_brightness(int brightness)
+{
+ imx233_pwm_setup_channel(2, 1024, HW_PWM_PERIODx__CDIV__DIV_1,
+ 0, HW_PWM_PERIODx__STATE__HIGH,
+ (brightness * 1024) / 100, HW_PWM_PERIODx__STATE__LOW);
+ imx233_pwm_enable_channel(2, true);
+}
+
+bool _backlight_init(void)
+{
+ _backlight_set_brightness(DEFAULT_BRIGHTNESS_SETTING);
+ return true;
+}
+
+void _backlight_on(void)
+{
+#ifdef HAVE_LCD_ENABLE
+ lcd_enable(true); /* power on lcd + visible display */
+#endif
+ /* don't do anything special, the core will set the brightness */
+}
+
+void _backlight_off(void)
+{
+ /* there is no real on/off but we can set to 0 brightness */
+ _backlight_set_brightness(0);
+#ifdef HAVE_LCD_ENABLE
+ lcd_enable(false); /* power off visible display */
+#endif
+}
+
+/* ELE8 is the button light GPIO */
+void _buttonlight_on(void)
+{
+ /* assume mpr121 was initialized by button-zenxfi3.c */
+ mpr121_set_gpio_output(8, ELE_GPIO_SET);
+}
+
+void _buttonlight_off(void)
+{
+ /* assume mpr121 was initialized by button-zenxfi3.c */
+ mpr121_set_gpio_output(8, ELE_GPIO_CLR);
+}
+
+void _buttonlight_set_brightness(int brightness)
+{
+ /* assume mpr121 was initialized by button-zenxfi3.c */
+ /* since backlight brightness is the same for the screen and the button light,
+ * map [MIN_BRIGHTNESS_SETTING,MAX_BRIGHTNESS_SETTING] to
+ * [ELE_PWM_MIN_DUTY,ELE_PWM_MAX_DUTY] */
+ brightness = ELE_PWM_MIN_DUTY + (brightness - MIN_BRIGHTNESS_SETTING) *
+ (ELE_PWM_MAX_DUTY - ELE_PWM_MIN_DUTY + 1) /
+ (MAX_BRIGHTNESS_SETTING - MIN_BRIGHTNESS_SETTING + 1);
+ brightness = MIN(brightness, ELE_PWM_MAX_DUTY);
+ mpr121_set_gpio_pwm(8, brightness);
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/button-target.h b/firmware/target/arm/imx233/creative-zenxfi3/button-target.h
new file mode 100644
index 0000000000..202e695eb3
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/button-target.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _BUTTON_TARGET_H_
+#define _BUTTON_TARGET_H_
+
+#include <stdbool.h>
+#include "config.h"
+
+void button_init_device(void);
+int button_read_device(void);
+bool button_debug_screen(void);
+
+#define HAS_BUTTON_HOLD
+
+/* Main unit's buttons */
+#define BUTTON_POWER 0x00000001
+#define BUTTON_MENU 0x00000002
+#define BUTTON_BACK 0x00000004
+#define BUTTON_PLAY 0x00000008
+#define BUTTON_UP 0x00000010
+#define BUTTON_DOWN 0x00000020
+#define BUTTON_VOL_UP 0x00000040
+#define BUTTON_VOL_DOWN 0x00000080
+/* For compatibility */
+#define BUTTON_LEFT BUTTON_BACK
+#define BUTTON_RIGHT BUTTON_PLAY
+
+#define BUTTON_MAIN 0xff
+
+#define BUTTON_REMOTE 0
+
+/* Software power-off */
+#define POWEROFF_BUTTON BUTTON_POWER
+#define POWEROFF_COUNT 10
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c
new file mode 100644
index 0000000000..174ddc217c
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c
@@ -0,0 +1,171 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "button-target.h"
+#include "system.h"
+#include "system-target.h"
+#include "pinctrl-imx233.h"
+#include "power-imx233.h"
+#include "string.h"
+#include "usb.h"
+#include "backlight.h"
+#include "mpr121.h"
+
+static struct mpr121_config_t config =
+{
+ .ele =
+ {
+ [0] = {.tth = 5, .rth = 4 },
+ [1] = {.tth = 5, .rth = 4 },
+ [2] = {.tth = 5, .rth = 4 },
+ [3] = {.tth = 5, .rth = 4 },
+ [4] = {.tth = 4, .rth = 3 },
+ [5] = {.tth = 4, .rth = 3 },
+ [6] = {.tth = 5, .rth = 4 },
+ [7] = {.tth = 5, .rth = 4 },
+ [8] = {.gpio = ELE_GPIO_OUTPUT_OPEN_LED },
+ },
+ .filters =
+ {
+ .ele =
+ {
+ .rising = {.mhd = 1, .nhd = 1, .ncl = 1, .fdl = 1 },
+ .falling = {.mhd = 1, .nhd = 1, .ncl = 0xff, .fdl = 2 },
+ }
+ },
+ .autoconf =
+ {
+ .en = true, .ren = true, .retry = RETRY_NEVER,
+ .usl = 0xc4, .lsl = 0x7f, .tl = 0xb0
+ },
+ .ele_en = ELE_EN0_x(7),
+ .cal_lock = CL_TRACK
+};
+
+#define MPR121_INTERRUPT 1
+
+static int touchpad_btns = 0;
+static long mpr121_stack[DEFAULT_STACK_SIZE/sizeof(long)];
+static const char mpr121_thread_name[] = "mpr121";
+static struct event_queue mpr121_queue;
+
+static void mpr121_irq_cb(int bank, int pin)
+{
+ (void) bank;
+ (void) pin;
+ /* the callback will not be fired until interrupt is enabled back so
+ * the queue will not overflow or contain multiple MPR121_INTERRUPT events */
+ queue_post(&mpr121_queue, MPR121_INTERRUPT, 0);
+}
+
+static void mpr121_thread(void)
+{
+ struct queue_event ev;
+
+ while(1)
+ {
+ queue_wait(&mpr121_queue, &ev);
+ /* handle usb connect and ignore all messages except rmi interrupts */
+ if(ev.id == SYS_USB_CONNECTED)
+ {
+ usb_acknowledge(SYS_USB_CONNECTED_ACK);
+ continue;
+ }
+ else if(ev.id != MPR121_INTERRUPT)
+ continue;
+ /* clear interrupt and get status */
+ unsigned status;
+ touchpad_btns = 0;
+ if(!mpr121_get_touch_status(&status))
+ {
+ /* ELE3: up
+ * ELE4: back
+ * ELE5: menu
+ * ELE6: down
+ * ELE7: play */
+ if(status & 0x8) touchpad_btns |= BUTTON_UP;
+ if(status & 0x10) touchpad_btns |= BUTTON_BACK;
+ if(status & 0x20) touchpad_btns |= BUTTON_MENU;
+ if(status & 0x40) touchpad_btns |= BUTTON_DOWN;
+ if(status & 0x80) touchpad_btns |= BUTTON_PLAY;
+ }
+ /* enable interrupt */
+ imx233_setup_pin_irq(0, 18, true, true, false, &mpr121_irq_cb);
+ }
+}
+
+/* B0P18 is #IRQ line of the touchpad */
+void button_init_device(void)
+{
+ mpr121_init(0xb4);
+ mpr121_soft_reset();
+ mpr121_set_config(&config);
+
+ queue_init(&mpr121_queue, true);
+ create_thread(mpr121_thread, mpr121_stack, sizeof(mpr121_stack), 0,
+ mpr121_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
+ /* enable interrupt */
+ imx233_set_pin_function(0, 18, PINCTRL_FUNCTION_GPIO);
+ imx233_enable_gpio_output(0, 18, false);
+ imx233_setup_pin_irq(0, 18, true, true, false, &mpr121_irq_cb);
+}
+
+bool button_hold(void)
+{
+ /* B0P04: #hold */
+ return !imx233_get_gpio_input_mask(0, 0x10);
+}
+
+int button_read_device(void)
+{
+ /* since sliding hold will usually trigger power, ignore power button
+ * for one second after hold is released */
+ static int power_ignore_counter = 0;
+ static bool old_hold;
+ /* light handling */
+ bool hold = button_hold();
+ if(hold != old_hold)
+ {
+ old_hold = hold;
+#ifndef BOOTLOADER
+ backlight_hold_changed(hold);
+#endif /* BOOTLOADER */
+ if(!hold)
+ power_ignore_counter = HZ;
+ }
+
+ if(power_ignore_counter)
+ power_ignore_counter--;
+
+ int res = 0;
+ /* B2P07: #volume-
+ * B2P08: #volume+
+ * PSWITCH: power */
+ uint32_t mask = imx233_get_gpio_input_mask(2, 0x180);
+ if(!(mask & 0x80))
+ res |= BUTTON_VOL_DOWN;
+ if(!(mask & 0x100))
+ res |= BUTTON_VOL_UP;
+ /* WARNING: it seems that the voltage on PSWITCH depends on whether
+ * usb is connected or not ! Thus the value of this field can be 1 or 3 */
+ if(__XTRACT(HW_POWER_STS, PSWITCH) != 0 && power_ignore_counter == 0)
+ res |= BUTTON_POWER;
+ return res | touchpad_btns;
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/debug-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/debug-zenxfi3.c
new file mode 100644
index 0000000000..0f003bcd1e
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/debug-zenxfi3.c
@@ -0,0 +1,28 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "system.h"
+#include "button-target.h"
+
+bool dbg_hw_target_info(void)
+{
+ return false;
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/lcd-target.h b/firmware/target/arm/imx233/creative-zenxfi3/lcd-target.h
new file mode 100644
index 0000000000..931fcb32a0
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/lcd-target.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (c) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef LCD_TARGET_H
+#define LCD_TARGET_H
+
+#endif /* LCD_TARGET_H */
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/lcd-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/lcd-zenxfi3.c
new file mode 100644
index 0000000000..3579f8306e
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/lcd-zenxfi3.c
@@ -0,0 +1,490 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (c) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <sys/types.h> /* off_t */
+#include <string.h>
+#include "cpu.h"
+#include "system.h"
+#include "backlight-target.h"
+#include "lcd.h"
+#include "lcdif-imx233.h"
+#include "clkctrl-imx233.h"
+#include "pinctrl-imx233.h"
+#include "logf.h"
+
+#ifdef HAVE_LCD_ENABLE
+static bool lcd_on;
+#endif
+static unsigned lcd_yuv_options = 0;
+
+static void setup_parameters(void)
+{
+ imx233_lcdif_reset();
+ imx233_lcdif_set_lcd_databus_width(HW_LCDIF_CTRL__LCD_DATABUS_WIDTH_16_BIT);
+ imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_16_BIT);
+ imx233_lcdif_set_timings(2, 2, 3, 3);
+}
+
+static void setup_lcd_pins(bool use_lcdif)
+{
+ if(use_lcdif)
+ {
+ imx233_set_pin_function(1, 25, PINCTRL_FUNCTION_MAIN); /* lcd_vsync */
+ imx233_set_pin_function(1, 21, PINCTRL_FUNCTION_MAIN); /* lcd_cs */
+ imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_MAIN); /* lcd_dotclk */
+ imx233_set_pin_function(1, 23, PINCTRL_FUNCTION_MAIN); /* lcd_enable */
+ imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_MAIN); /* lcd_hsync */
+ imx233_set_pin_function(1, 18, PINCTRL_FUNCTION_MAIN); /* lcd_reset */
+ imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_MAIN); /* lcd_rs */
+ imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_MAIN); /* lcd_d16 */
+ imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_MAIN); /* lcd_d17 */
+ imx233_set_pin_function(1, 20, PINCTRL_FUNCTION_MAIN); /* lcd_wr */
+ __REG_CLR(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} */
+ }
+ else
+ {
+ __REG_SET(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} */
+ imx233_enable_gpio_output_mask(1, 0x3ffffff, false); /* lcd_{d{0-17},reset,rs,wr,cs,dotclk,enable,hsync,vsync} */
+ imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_GPIO); /* lcd_d16 */
+ imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_GPIO); /* lcd_d17 */
+ imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_GPIO); /* lcd_rs */
+ imx233_set_pin_function(1, 20, PINCTRL_FUNCTION_GPIO); /* lcd_wr */
+ imx233_set_pin_function(1, 21, PINCTRL_FUNCTION_GPIO); /* lcd_cs */
+ imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO); /* lcd_dotclk */
+ imx233_set_pin_function(1, 23, PINCTRL_FUNCTION_GPIO); /* lcd_enable */
+ imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO); /* lcd_hsync */
+ imx233_set_pin_function(1, 25, PINCTRL_FUNCTION_GPIO); /* lcd_vsync */
+ }
+}
+
+static void common_lcd_enable(bool enable)
+{
+ imx233_lcdif_enable(enable);
+ setup_lcd_pins(enable); /* use GPIO pins when disable */
+}
+
+static void setup_lcdif(void)
+{
+ setup_parameters();
+ common_lcd_enable(true);
+ imx233_lcdif_enable_bus_master(true);
+}
+
+static void setup_lcdif_clock(void)
+{
+ /* the LCD seems to work at 24Mhz, so use the xtal clock with no divider */
+ imx233_clkctrl_enable_clock(CLK_PIX, false);
+ imx233_clkctrl_set_clock_divisor(CLK_PIX, 1);
+ imx233_clkctrl_set_bypass_pll(CLK_PIX, true); /* use XTAL */
+ imx233_clkctrl_enable_clock(CLK_PIX, true);
+}
+
+static void lcd_write_reg(uint32_t reg, uint32_t data)
+{
+ imx233_lcdif_pio_send(false, 2, &reg);
+ if(reg != 0x22)
+ imx233_lcdif_pio_send(true, 2, &data);
+}
+
+#define REG_UDELAY 0xffffffff
+struct lcd_sequence_entry_t
+{
+ uint32_t reg, data;
+};
+
+static void lcd_send_sequence(struct lcd_sequence_entry_t *seq, unsigned count)
+{
+ for(;count-- > 0; seq++)
+ {
+ if(seq->reg == REG_UDELAY)
+ udelay(seq->data);
+ else
+ lcd_write_reg(seq->reg, seq->data);
+ }
+}
+
+#define _begin_seq() static struct lcd_sequence_entry_t __seq[] = {
+#define _udelay(a) {REG_UDELAY, a},
+#define _lcd_write_reg(a, b) {a, b},
+#define _end_seq() }; lcd_send_sequence(__seq, sizeof(__seq) / sizeof(__seq[0]));
+
+static void lcd_init_seq(void)
+{
+ _begin_seq()
+ _lcd_write_reg(1, 0x11c)
+ _lcd_write_reg(2, 0x100)
+ _lcd_write_reg(3, 0x1030)
+ _lcd_write_reg(8, 0x808)
+ _lcd_write_reg(0xc, 0)
+ _lcd_write_reg(0xf, 0xc01)
+ _lcd_write_reg(0x20, 0)
+ _lcd_write_reg(0x21, 0)
+ _udelay(30)
+ _lcd_write_reg(0x10, 0xa00)
+ _lcd_write_reg(0x11, 0x1038)
+ _udelay(30)
+ _lcd_write_reg(0x12, 0x1010)
+ _lcd_write_reg(0x13, 0x50)
+ _lcd_write_reg(0x14, 0x4f58)
+ _lcd_write_reg(0x30, 0)
+ _lcd_write_reg(0x31, 0xdb)
+ _lcd_write_reg(0x32, 0)
+ _lcd_write_reg(0x33, 0)
+ _lcd_write_reg(0x34, 0xdb)
+ _lcd_write_reg(0x35, 0)
+ _lcd_write_reg(0x36, 0xaf)
+ _lcd_write_reg(0x37, 0)
+ _lcd_write_reg(0x38, 0xdb)
+ _lcd_write_reg(0x39, 0)
+ _lcd_write_reg(0x50, 0)
+ _lcd_write_reg(0x51, 0x705)
+ _lcd_write_reg(0x52, 0xe0a)
+ _lcd_write_reg(0x53, 0x300)
+ _lcd_write_reg(0x54, 0xa0e)
+ _lcd_write_reg(0x55, 0x507)
+ _lcd_write_reg(0x56, 0)
+ _lcd_write_reg(0x57, 3)
+ _lcd_write_reg(0x58, 0x90a)
+ _lcd_write_reg(0x59, 0xa09)
+ _udelay(30)
+ _lcd_write_reg(7, 0x1017)
+ _udelay(40)
+ _end_seq()
+}
+
+void lcd_init_device(void)
+{
+ setup_lcdif();
+ setup_lcdif_clock();
+
+ // reset device
+ __REG_SET(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
+ mdelay(50);
+ __REG_CLR(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
+ mdelay(10);
+ __REG_SET(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
+
+ lcd_init_seq();
+#ifdef HAVE_LCD_ENABLE
+ lcd_on = true;
+#endif
+}
+
+#ifdef HAVE_LCD_ENABLE
+bool lcd_active(void)
+{
+ return lcd_on;
+}
+
+static void lcd_enable_seq(bool enable)
+{
+ if(!enable)
+ {
+ _begin_seq()
+ _end_seq()
+ }
+ else
+ {
+ _begin_seq()
+ _end_seq()
+ }
+}
+
+void lcd_enable(bool enable)
+{
+ if(lcd_on == enable)
+ return;
+
+ lcd_on = enable;
+
+ if(enable)
+ common_lcd_enable(true);
+ lcd_enable_seq(enable);
+ if(!enable)
+ common_lcd_enable(false);
+}
+#endif
+
+void lcd_update(void)
+{
+ lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+}
+
+void lcd_update_rect(int x, int y, int w, int h)
+{
+#ifdef HAVE_LCD_ENABLE
+ if(!lcd_on)
+ return;
+#endif
+ /* make sure the rectangle is included in the screen */
+ x = MIN(x, LCD_WIDTH);
+ y = MIN(y, LCD_HEIGHT);
+ w = MIN(w, LCD_WIDTH - x);
+ h = MIN(h, LCD_HEIGHT - y);
+
+ imx233_lcdif_wait_ready();
+ lcd_write_reg(0x37, x);
+ lcd_write_reg(0x36, x + w - 1);
+ lcd_write_reg(0x39, y);
+ lcd_write_reg(0x38, y + h - 1);
+ lcd_write_reg(0x20, x);
+ lcd_write_reg(0x21, y);
+ lcd_write_reg(0x22, 0);
+
+ imx233_lcdif_wait_ready();
+ imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_16_BIT);
+ imx233_lcdif_set_byte_packing_format(0xf); /* two pixels per 32-bit word */
+ imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */
+
+ /* there are two cases here:
+ * - either width = LCD_WIDTH and we can directly memcopy a part of lcd_framebuffer to FRAME
+ * and send it
+ * - either width != LCD_WIDTH and we have to build a contiguous copy of the rectangular area
+ * into FRAME before sending it (which is slower and doesn't use the hardware)
+ * In all cases, FRAME just acts as a temporary buffer.
+ * NOTE It's more interesting to do a copy to FRAME in all cases since in system mode
+ * the clock runs at 24MHz which provides barely 10MB/s bandwidth compared to >100MB/s
+ * for memcopy operations
+ */
+ if(w == LCD_WIDTH)
+ {
+ memcpy((void *)FRAME, FBADDR(x,y), w * h * sizeof(fb_data));
+ }
+ else
+ {
+ for(int i = 0; i < h; i++)
+ memcpy((fb_data *)FRAME + i * w, FBADDR(x,y + i), w * sizeof(fb_data));
+ }
+ /* WARNING The LCDIF has a limitation on the vertical count ! In 16-bit packed mode
+ * (which we used, ie 16-bit per pixel, 2 pixels per 32-bit words), the v_count
+ * field must be a multiple of 2. Furthermore, it seems the lcd controller doesn't
+ * really like when both w and h are even, probably because the writes to the GRAM
+ * are done on several words and the controller requires dummy writes.
+ * The workaround is to always make sure that we send a number of pixels which is
+ * a multiple of 4 so that both the lcdif and the controller are happy. If any
+ * of w or h is odd, we will send a copy of the first pixels as dummy writes. We will
+ * send at most 3 bytes. We then send (w * h + 3) / 4 x 4 bytes.
+ */
+ if(w % 2 == 1 || h % 2 == 1)
+ {
+ /* copy three pixel after the last one */
+ for(int i = 0; i < 3; i++)
+ *((fb_data *)FRAME + w * h + i) = *((fb_data *)FRAME + i);
+ /* WARNING we need to update w and h to reflect the pixel count BUT it
+ * has no relation to w * h (it can even be 2 * prime). Hopefully, w <= 240 and
+ * h <= 320 so w * h <= 76800 and (w * h + 3) / 4 <= 38400 which fits into
+ * a 16-bit integer (horizontal count). */
+ h = (w * h + 3) / 4;
+ w = 4;
+ }
+ imx233_lcdif_dma_send((void *)FRAME_PHYS_ADDR, w, h);
+}
+
+void lcd_yuv_set_options(unsigned options)
+{
+ lcd_yuv_options = options;
+}
+
+#define YFAC (74)
+#define RVFAC (101)
+#define GUFAC (-24)
+#define GVFAC (-51)
+#define BUFAC (128)
+
+static inline int clamp(int val, int min, int max)
+{
+ if (val < min)
+ val = min;
+ else if (val > max)
+ val = max;
+ return val;
+}
+
+void lcd_blit_yuv(unsigned char * const src[3],
+ int src_x, int src_y, int stride,
+ int x, int y, int width, int height)
+{
+ const unsigned char *ysrc, *usrc, *vsrc;
+ int linecounter;
+ fb_data *dst, *row_end;
+ long z;
+
+ /* width and height must be >= 2 and an even number */
+ width &= ~1;
+ linecounter = height >> 1;
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst = FBADDR(x,y);
+ row_end = dst + width;
+ #else
+ dst = FBADDR(LCD_WIDTH - y - 1,x);
+ row_end = dst + LCD_WIDTH * width;
+ #endif
+
+ z = stride * src_y;
+ ysrc = src[0] + z + src_x;
+ usrc = src[1] + (z >> 2) + (src_x >> 1);
+ vsrc = src[2] + (usrc - src[1]);
+
+ /* stride => amount to jump from end of last row to start of next */
+ stride -= width;
+
+ /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
+
+ do
+ {
+ do
+ {
+ int y, cb, cr, rv, guv, bu, r, g, b;
+
+ y = YFAC*(*ysrc++ - 16);
+ cb = *usrc++ - 128;
+ cr = *vsrc++ - 128;
+
+ rv = RVFAC*cr;
+ guv = GUFAC*cb + GVFAC*cr;
+ bu = BUFAC*cb;
+
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 64*256-1)
+ {
+ r = clamp(r, 0, 64*256-1);
+ g = clamp(g, 0, 64*256-1);
+ b = clamp(b, 0, 64*256-1);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+ #else
+ dst += LCD_WIDTH;
+ #endif
+
+ y = YFAC*(*ysrc++ - 16);
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 64*256-1)
+ {
+ r = clamp(r, 0, 64*256-1);
+ g = clamp(g, 0, 64*256-1);
+ b = clamp(b, 0, 64*256-1);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+ #else
+ dst += LCD_WIDTH;
+ #endif
+ }
+ while (dst < row_end);
+
+ ysrc += stride;
+ usrc -= width >> 1;
+ vsrc -= width >> 1;
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ row_end += LCD_WIDTH;
+ dst += LCD_WIDTH - width;
+ #else
+ row_end -= 1;
+ dst -= LCD_WIDTH*width + 1;
+ #endif
+
+ do
+ {
+ int y, cb, cr, rv, guv, bu, r, g, b;
+
+ y = YFAC*(*ysrc++ - 16);
+ cb = *usrc++ - 128;
+ cr = *vsrc++ - 128;
+
+ rv = RVFAC*cr;
+ guv = GUFAC*cb + GVFAC*cr;
+ bu = BUFAC*cb;
+
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 64*256-1)
+ {
+ r = clamp(r, 0, 64*256-1);
+ g = clamp(g, 0, 64*256-1);
+ b = clamp(b, 0, 64*256-1);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+ #else
+ dst += LCD_WIDTH;
+ #endif
+
+ y = YFAC*(*ysrc++ - 16);
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 64*256-1)
+ {
+ r = clamp(r, 0, 64*256-1);
+ g = clamp(g, 0, 64*256-1);
+ b = clamp(b, 0, 64*256-1);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+ #else
+ dst += LCD_WIDTH;
+ #endif
+ }
+ while (dst < row_end);
+
+ ysrc += stride;
+ usrc += stride >> 1;
+ vsrc += stride >> 1;
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ row_end += LCD_WIDTH;
+ dst += LCD_WIDTH - width;
+ #else
+ row_end -= 1;
+ dst -= LCD_WIDTH*width + 1;
+ #endif
+ }
+ while (--linecounter > 0);
+
+ #if LCD_WIDTH >= LCD_HEIGHT
+ lcd_update_rect(x, y, width, height);
+ #else
+ lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
+ #endif
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/power-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/power-zenxfi3.c
new file mode 100644
index 0000000000..26f2159cec
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/power-zenxfi3.c
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "system.h"
+#include "power.h"
+#include "tuner.h"
+#include "fmradio_i2c.h"
+#include "pinctrl-imx233.h"
+
+static bool tuner_enable = false;
+
+bool tuner_power(bool enable)
+{
+ if(enable != tuner_enable)
+ {
+ tuner_enable = enable;
+ }
+ return tuner_enable;
+}
+
+bool tuner_powered(void)
+{
+ return tuner_enable;
+}
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/powermgmt-target.h b/firmware/target/arm/imx233/creative-zenxfi3/powermgmt-target.h
new file mode 100644
index 0000000000..6c010a72d3
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/powermgmt-target.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef POWERMGMT_TARGET_H
+#define POWERMGMT_TARGET_H
+
+#include "config.h"
+#include "powermgmt-imx233.h"
+
+/* Creative ZEN X-Fi3 OF settings:
+ * - current ramp slope: 10 mA/s
+ * - conditioning threshold voltage: 3 V
+ * - conditioning max voltage: 3.1 V
+ * - conditioning current: 60 mA
+ * - conditioning timeout: 1 h
+ * - charging voltage: 4.2 V
+ * - charging current: 260 mA
+ * - charging threshold current: 20 mA
+ * - charging timeout: 4 h
+ * - top off period: 30 min
+ * - high die temperature: 91 °C
+ * - low die temperature: 56 °C
+ * - safe die temperature current: 30 mA
+ * - battery temperature channel: 0
+ * - high battery temperature: 2400
+ * - low battery temperature: 2300
+ * - safe battery temperature current: 0 mA
+ * - low DCDC battery voltage: 3.9 V
+ */
+
+#define IMX233_CHARGE_CURRENT 260
+#define IMX233_STOP_CURRENT 20
+#define IMX233_TOPOFF_TIMEOUT (30 * 60 * HZ)
+#define IMX233_CHARGING_TIMEOUT (4 * 3600 * HZ)
+#define IMX233_DIE_TEMP_HIGH 91
+#define IMX233_DIE_TEMP_LOW 56
+#define IMX233_BATT_TEMP_SENSOR 0
+#define IMX233_BATT_TEMP_HIGH 2400
+#define IMX233_BATT_TEMP_LOW 2300
+
+#endif /* POWERMGMT_TARGET_H */
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/powermgmt-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/powermgmt-zenxfi3.c
new file mode 100644
index 0000000000..2951df5f58
--- /dev/null
+++ b/firmware/target/arm/imx233/creative-zenxfi3/powermgmt-zenxfi3.c
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "powermgmt-target.h"
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+ 3659
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+ 3630
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+ /* Toshiba Gigabeat S Li Ion 700mAH figured from discharge curve */
+ { 3659, 3719, 3745, 3761, 3785, 3813, 3856, 3926, 3984, 4040, 4121 },
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+{
+ /* Toshiba Gigabeat S Li Ion 700mAH figured from charge curve */
+ 4028, 4063, 4087, 4111, 4135, 4156, 4173, 4185, 4194, 4202, 4208
+};
diff --git a/firmware/target/arm/imx233/sd-imx233.c b/firmware/target/arm/imx233/sd-imx233.c
index d3c29ee5be..8928faf3f9 100644
--- a/firmware/target/arm/imx233/sd-imx233.c
+++ b/firmware/target/arm/imx233/sd-imx233.c
@@ -62,6 +62,28 @@ struct sd_config_t sd_config[] =
.power_pin = PIN(0, 8),
.ssp = 1
},
+#elif defined(CREATIVE_ZENXFI2)
+ /* The Zen X-Fi2 uses pin B1P29 for power*/
+ {
+ .name = "microSD",
+ .flags = POWER_PIN | REMOVABLE | DETECT_INVERTED,
+ .power_pin = PIN(1, 29),
+ .ssp = 1,
+ },
+#elif defined(CREATIVE_ZENXFI3)
+ {
+ .name = "internal/SD",
+ .flags = WINDOW,
+ .ssp = 2
+ },
+ /* The Zen X-Fi3 uses pin #B0P07 for power*/
+ {
+ .name = "microSD",
+ .flags = POWER_PIN | POWER_INVERTED | REMOVABLE | POWER_DELAY,
+ .power_pin = PIN(0, 7),
+ .power_delay = HZ / 10, /* extra delay, to ramp up voltage? */
+ .ssp = 1
+ },
#else
#error You need to write the sd config!
#endif
diff --git a/firmware/target/arm/system-arm.c b/firmware/target/arm/system-arm.c
index e687e1d82b..c8d12e296a 100644
--- a/firmware/target/arm/system-arm.c
+++ b/firmware/target/arm/system-arm.c
@@ -148,7 +148,7 @@ void NORETURN_ATTR UIE(unsigned int pc, unsigned int num)
if (!triggered)
{
triggered = true;
- backtrace(pc, __get_sp(), &line);
+ //backtrace(pc, __get_sp(), &line);
}
lcd_update();