3 new ports: Samsung YH-820, YH-920, and YH-925. Mostly functional. Audio working on 820 & 925 (untested on the 920). No battery readings. No recording. No plugins. Keymap needs work.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21083 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Mark Arigo 2009-05-25 21:10:45 +00:00
parent d2ea7db6f5
commit 758bb3bc62
46 changed files with 5028 additions and 26 deletions

View file

@ -230,4 +230,6 @@ keymaps/keymap-fuze.c
keymaps/keymap-ondavx747.c
#elif CONFIG_KEYPAD == ONDAVX767_PAD
keymaps/keymap-ondavx767.c
#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
keymaps/keymap-yh8xx_yh9xx.c
#endif

View file

@ -1032,6 +1032,9 @@ static bool dbg_spdif(void)
(CONFIG_KEYPAD == PHILIPS_HDD1630_PAD)
# define DEBUG_CANCEL BUTTON_POWER
#elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
# define DEBUG_CANCEL BUTTON_PLAY
#endif /* key definitions */
/* Test code!!! */

356
apps/keymaps/keymap-yh8xx_yh9xx.c Executable file
View file

@ -0,0 +1,356 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: keymap-h1x0_h3x0.c 17847 2008-06-28 18:10:04Z bagder $
*
* Copyright (C) 2006 Jonathan Gordon
*
* 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.
*
****************************************************************************/
/* Button Code Definitions for iriver h100/h300 target */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "config.h"
#include "action.h"
#include "button.h"
#include "settings.h"
/*
* The format of the list is as follows
* { Action Code, Button code, Prereq button code }
* if there's no need to check the previous button's value, use BUTTON_NONE
* Insert LAST_ITEM_IN_LIST at the end of each mapping
*/
/* CONTEXT_CUSTOM's used in this file...
CONTEXT_CUSTOM|CONTEXT_TREE = the standard list/tree defines (without directions)
CONTEXT_CUSTOM|CONTEXT_SETTINGS = the direction keys for the eq/col picker screens
i.e where up/down is inc/dec
CONTEXT_SETTINGS = up/down is prev/next, l/r is inc/dec
*/
static const struct button_mapping button_context_standard[] = {
{ ACTION_STD_OK, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_PREV, BUTTON_UP, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_MENU, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_LEFT },
{ ACTION_STD_CONTEXT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_RIGHT },
{ ACTION_STD_QUICKSCREEN, BUTTON_PLAY|BUTTON_LEFT, BUTTON_PLAY },
{ ACTION_STD_REC, BUTTON_REC|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST
}; /* button_context_standard */
static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_WPS_STOP, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
{ ACTION_WPS_SKIPNEXT, BUTTON_FFWD|BUTTON_REL, BUTTON_FFWD },
{ ACTION_WPS_SEEKFWD, BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_FFWD|BUTTON_REL, BUTTON_FFWD|BUTTON_REPEAT },
{ ACTION_WPS_SKIPPREV, BUTTON_REW|BUTTON_REL, BUTTON_REW },
{ ACTION_WPS_SEEKBACK, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_REW|BUTTON_REL, BUTTON_REW|BUTTON_REPEAT },
{ ACTION_WPS_ABSETB_NEXTDIR,BUTTON_PLAY|BUTTON_RIGHT, BUTTON_PLAY },
{ ACTION_WPS_ABSETA_PREVDIR,BUTTON_PLAY|BUTTON_LEFT, BUTTON_PLAY },
{ ACTION_WPS_ABRESET, BUTTON_PLAY|BUTTON_UP, BUTTON_PLAY },
{ ACTION_WPS_VOLDOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_UP, BUTTON_NONE },
{ ACTION_WPS_BROWSE, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_WPS_ID3SCREEN, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_WPS_PITCHSCREEN, BUTTON_PLAY|BUTTON_RIGHT, BUTTON_PLAY },
/* these match context_standard */
{ ACTION_WPS_MENU, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_LEFT },
{ ACTION_WPS_CONTEXT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_RIGHT },
{ ACTION_WPS_QUICKSCREEN, BUTTON_PLAY|BUTTON_LEFT, BUTTON_PLAY },
{ ACTION_WPS_REC, BUTTON_REC|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST
}; /* button_context_wps */
static const struct button_mapping button_context_list[] = {
#ifdef SAMSUNG_YH820
{ ACTION_LISTTREE_PGUP, BUTTON_REC|BUTTON_UP, BUTTON_REC },
{ ACTION_LISTTREE_PGDOWN, BUTTON_REC|BUTTON_DOWN, BUTTON_REC },
#else
{ ACTION_LISTTREE_PGUP, BUTTON_FFWD, BUTTON_NONE },
{ ACTION_LISTTREE_PGDOWN, BUTTON_REW, BUTTON_NONE },
#endif
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_list */
static const struct button_mapping button_context_tree[] = {
{ ACTION_TREE_WPS, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_TREE_STOP, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
}; /* button_context_tree */
static const struct button_mapping button_context_listtree_scroll_with_combo[] = {
{ ACTION_TREE_ROOT_INIT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_TREE_PGLEFT, BUTTON_REC|BUTTON_LEFT, BUTTON_REC },
{ ACTION_TREE_PGLEFT, BUTTON_REC|BUTTON_LEFT|BUTTON_REPEAT,BUTTON_NONE },
{ ACTION_TREE_PGRIGHT, BUTTON_REC|BUTTON_RIGHT, BUTTON_REC },
{ ACTION_TREE_PGRIGHT, BUTTON_REC|BUTTON_RIGHT|BUTTON_REPEAT,BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE)
};
static const struct button_mapping button_context_listtree_scroll_without_combo[] = {
{ ACTION_NONE, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
{ ACTION_TREE_ROOT_INIT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_LEFT },
{ ACTION_TREE_PGLEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_TREE_PGLEFT, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT },
{ ACTION_NONE, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_STD_OK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
{ ACTION_TREE_PGRIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_TREE_PGRIGHT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT|BUTTON_REPEAT },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE)
};
static const struct button_mapping button_context_settings[] = {
{ ACTION_SETTINGS_INC, BUTTON_UP, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT,BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT,BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_RESET, BUTTON_PLAY, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_settings */
static const struct button_mapping button_context_settings_right_is_inc[] = {
{ ACTION_SETTINGS_INC, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT,BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT,BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_PREV, BUTTON_UP, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_RESET, BUTTON_PLAY, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_settingsgraphical */
static const struct button_mapping button_context_yesno[] = {
{ ACTION_YESNO_ACCEPT, BUTTON_RIGHT|BUTTON_REL, BUTTON_PLAY },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_settings_yesno */
static const struct button_mapping button_context_colorchooser[] = {
{ ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS)
}; /* button_context_settings_colorchooser */
static const struct button_mapping button_context_eq[] = {
{ ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS)
}; /* button_context_settings_context_eq */
static const struct button_mapping button_context_bmark[] = {
{ ACTION_BMS_DELETE, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
}; /* button_context_settings_bmark */
static const struct button_mapping button_context_time[] = {
{ ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_STD_CANCEL, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
}; /* button_context_settings_bmark */
static const struct button_mapping button_context_quickscreen[] = {
{ ACTION_QS_DOWNINV, BUTTON_UP, BUTTON_NONE },
{ ACTION_QS_DOWNINV, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_PLAY, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_quickscreen */
static const struct button_mapping button_context_pitchscreen[] = {
{ ACTION_PS_INC_SMALL, BUTTON_UP, BUTTON_NONE },
{ ACTION_PS_INC_BIG, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_PS_DEC_SMALL, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_PS_DEC_BIG, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_PS_NUDGE_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_TOGGLE_MODE, BUTTON_FFWD, BUTTON_NONE },
{ ACTION_PS_RESET, BUTTON_REW, BUTTON_NONE },
{ ACTION_PS_EXIT, BUTTON_PLAY, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_pitchcreen */
static const struct button_mapping button_context_recscreen[] = {
{ ACTION_REC_PAUSE, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE },
#ifdef SAMSUNG_YH820
/* the yh-820 has a rec button */
{ ACTION_REC_NEWFILE, BUTTON_REC, BUTTON_NONE },
#else
/* the yh-920 & yh-925 have a rec switch */
{ ACTION_REC_NEWFILE, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE },
#endif
{ ACTION_SETTINGS_INC, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_recscreen */
static const struct button_mapping button_context_keyboard[] = {
{ ACTION_KBD_UP, BUTTON_UP, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_KBD_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_REW, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_FFWD, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_BACKSPACE, BUTTON_LEFT|BUTTON_REW, BUTTON_NONE },
{ ACTION_KBD_BACKSPACE, BUTTON_LEFT|BUTTON_REW|BUTTON_REPEAT,BUTTON_NONE },
{ ACTION_KBD_SELECT, BUTTON_PLAY, BUTTON_NONE },
{ ACTION_KBD_PAGE_FLIP, BUTTON_PLAY|BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_KBD_DONE, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
{ ACTION_KBD_ABORT, BUTTON_PLAY|BUTTON_LEFT, BUTTON_PLAY },
{ ACTION_KBD_MORSE_INPUT, BUTTON_PLAY|BUTTON_FFWD, BUTTON_NONE },
{ ACTION_KBD_MORSE_SELECT, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE },
LAST_ITEM_IN_LIST
}; /* button_context_keyboard */
const struct button_mapping* get_context_mapping(int context)
{
switch (context)
{
case CONTEXT_STD:
return button_context_standard;
case CONTEXT_WPS:
return button_context_wps;
case CONTEXT_LIST:
return button_context_list;
case CONTEXT_TREE:
case CONTEXT_MAINMENU:
if (global_settings.hold_lr_for_scroll_in_list)
return button_context_listtree_scroll_without_combo;
else
return button_context_listtree_scroll_with_combo;
case CONTEXT_CUSTOM|CONTEXT_TREE:
return button_context_tree;
case CONTEXT_SETTINGS:
return button_context_settings;
case CONTEXT_CUSTOM|CONTEXT_SETTINGS:
case CONTEXT_SETTINGS_RECTRIGGER:
return button_context_settings_right_is_inc;
case CONTEXT_SETTINGS_COLOURCHOOSER:
return button_context_colorchooser;
case CONTEXT_SETTINGS_EQ:
return button_context_eq;
case CONTEXT_SETTINGS_TIME:
return button_context_time;
case CONTEXT_YESNOSCREEN:
return button_context_yesno;
case CONTEXT_BOOKMARKSCREEN:
return button_context_bmark;
case CONTEXT_QUICKSCREEN:
return button_context_quickscreen;
case CONTEXT_PITCHSCREEN:
return button_context_pitchscreen;
case CONTEXT_RECSCREEN:
return button_context_recscreen;
case CONTEXT_KEYBOARD:
return button_context_keyboard;
}
return button_context_standard;
}

View file

@ -10,7 +10,8 @@ gigabeat-s.c
#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \
defined(SANSA_E200) || defined(SANSA_C200) || \
defined(MROBE_100) || defined(PHILIPS_SA9200) || \
defined(PHILIPS_HDD1630)
defined(PHILIPS_HDD1630) || defined(SAMSUNG_YH820) || \
defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
#ifdef E200R_INSTALLER
main-e200r-installer.c
#elif defined(C240_ERASE)

View file

@ -70,6 +70,9 @@ extern int show_logo(void);
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
#define BOOTLOADER_BOOT_OF BUTTON_MENU
#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
#define BOOTLOADER_BOOT_OF BUTTON_LEFT
#endif
/* Maximum allowed firmware image size. 10MB is more than enough */

View file

@ -250,6 +250,8 @@ drivers/audio/as3514.c
drivers/audio/tlv320.c
#elif defined(HAVE_MAS35XX)
drivers/audio/mas35xx.c
#elif defined(HAVE_AK4537)
drivers/audio/ak4537.c
#endif /* defined(HAVE_*) */
#endif /* !defined(SIMULATOR) && !defined(BOOTLOADER) */
@ -1282,3 +1284,53 @@ target/arm/at91sam/lyre_proto1/system-lyre_proto1.c
target/arm/at91sam/lyre_proto1/timer-lyre_proto1.c
#endif
#endif /* SIMULATOR */
#ifdef SAMSUNG_YH820
#ifndef SIMULATOR
target/arm/ata-as-arm.S
target/arm/ata-pp5020.c
target/arm/adc-pp5020.c
target/arm/i2s-pp.c
target/arm/usb-fw-pp502x.c
target/arm/samsung/akcodec-yh82x_yh92x.c
target/arm/samsung/button-yh82x_yh92x.c
target/arm/samsung/power-yh82x_yh92x.c
target/arm/samsung/yh820/backlight-yh820.c
target/arm/samsung/yh820/lcd-yh820.c
target/arm/samsung/yh820/lcd-as-yh820.S
target/arm/samsung/yh820/powermgmt-yh820.c
#endif /* SIMULATOR */
#endif /* SAMSUNG_YH820 */
#ifdef SAMSUNG_YH920
#ifndef SIMULATOR
target/arm/ata-as-arm.S
target/arm/ata-pp5020.c
target/arm/adc-pp5020.c
target/arm/i2s-pp.c
target/arm/usb-fw-pp502x.c
target/arm/samsung/akcodec-yh82x_yh92x.c
target/arm/samsung/button-yh82x_yh92x.c
target/arm/samsung/power-yh82x_yh92x.c
target/arm/samsung/yh920/backlight-yh920.c
target/arm/samsung/yh920/lcd-yh920.c
target/arm/samsung/yh920/powermgmt-yh920.c
#endif /* SIMULATOR */
#endif /* SAMSUNG_YH920 */
#ifdef SAMSUNG_YH925
#ifndef SIMULATOR
target/arm/ata-as-arm.S
target/arm/ata-pp5020.c
target/arm/adc-pp5020.c
target/arm/i2s-pp.c
target/arm/usb-fw-pp502x.c
target/arm/samsung/akcodec-yh82x_yh92x.c
target/arm/samsung/button-yh82x_yh92x.c
target/arm/samsung/power-yh82x_yh92x.c
target/arm/samsung/yh925/backlight-yh925.c
target/arm/samsung/yh925/lcd-yh925.c
target/arm/samsung/yh925/lcd-as-yh925.S
target/arm/samsung/yh925/powermgmt-yh925.c
#endif /* SIMULATOR */
#endif /* SAMSUNG_YH925 */

View file

@ -0,0 +1,280 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (c) 2009 Mark Arigo
*
* 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 "string.h"
// #define LOGF_ENABLE
#include "logf.h"
#include "pcm_sampr.h"
#include "audio.h"
#include "akcodec.h"
#include "audiohw.h"
#include "sound.h"
const struct sound_settings_info audiohw_settings[] = {
[SOUND_VOLUME] = {"dB", 0, 1,-127, 0, -25},
/* HAVE_SW_TONE_CONTROLS */
[SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
[SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
[SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
[SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
[SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
#if defined(HAVE_RECORDING)
[SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23},
[SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23},
[SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 0},
#endif
};
static unsigned char akc_regs[AKC_NUM_REGS];
static void akc_write(int reg, unsigned val)
{
if ((unsigned)reg >= AKC_NUM_REGS)
return;
akc_regs[reg] = (unsigned char)val;
akcodec_write(reg, val);
}
static void akc_set(int reg, unsigned bits)
{
akc_write(reg, akc_regs[reg] | bits);
}
static void akc_clear(int reg, unsigned bits)
{
akc_write(reg, akc_regs[reg] & ~bits);
}
static void akc_write_masked(int reg, unsigned bits, unsigned mask)
{
akc_write(reg, (akc_regs[reg] & ~mask) | (bits & mask));
}
#if 0
static void codec_set_active(int active)
{
(void)active;
}
#endif
/* convert tenth of dB volume (-1270..0) to master volume register value */
int tenthdb2master(int db)
{
if (db < VOLUME_MIN)
return 0xff; /* mute */
else if (db >= VOLUME_MAX)
return 0x00;
else
return ((-db)/5);
}
int sound_val2phys(int setting, int value)
{
int result;
switch(setting)
{
#ifdef HAVE_RECORDING
case SOUND_LEFT_GAIN:
case SOUND_RIGHT_GAIN:
result = (value - 23) * 15; /* fix */
break;
case SOUND_MIC_GAIN:
result = value * 200; /* fix */
break;
#endif
default:
result = value;
break;
}
return result;
}
void audiohw_mute(bool mute)
{
if (mute)
{
akc_set(AK4537_DAC, SMUTE);
udelay(200000);
}
else
{
udelay(200000);
akc_clear(AK4537_DAC, SMUTE);
}
}
void audiohw_preinit(void)
{
int i;
for (i = 0; i < AKC_NUM_REGS; i++)
akc_regs[i] = akcodec_read(i);
/* POWER UP SEQUENCE (from the datasheet) */
/* Note: the delay length is what the OF uses, although the datasheet
suggests they can be shorter */
/* power up VCOM */
akc_set(AK4537_PM1, PMVCM);
udelay(100000);
/* setup AK4537_SIGSEL1 */
akc_set(AK4537_SIGSEL1, ALCS | MOUT2);
udelay(100000);
/* setup AK4537_SIGSEL2 */
akc_write_masked(AK4537_SIGSEL2, DAHS, (DAHS | HPL | HPR));
udelay(100000);
/* setup AK4537_MODE1 */
akc_write_masked(AK4537_MODE1, DIF_I2S | BICK_32FS | MCKI_PLL_12000KHZ,
(DIF_MASK | BICK_MASK | MCKI_MASK));
udelay(100000);
/* CLOCK SETUP - X'tal used in PLL mode (master mode) */
/* release the pull-down of the XTI pin and power-up the X'tal osc */
akc_write_masked(AK4537_PM2, PMXTL, (MCLKPD | PMXTL));
udelay(100000);
/* power-up the PLL */
akc_set(AK4537_PM2, PMPLL);
udelay(100000);
/* enable MCKO output and setup MCKO output freq */
akc_set(AK4537_MODE1, MCKO_EN);
udelay(100000);
/* ENABLE HEADPHONE AMP OUTPUT */
/* setup the sampling freq if PLL mode is used */
akc_write_masked(AK4537_MODE2, AKC_PLL_44100HZ, FS_MASK);
/* setup the low freq boost level */
akc_write_masked(AK4537_DAC, BST_OFF, BST_MASK);
/* setup the digital volume */
akc_write(AK4537_ATTL, 0x10);
akc_write(AK4537_ATTR, 0x10);
/* power up the DAC */
akc_set(AK4537_PM2, PMDAC);
udelay(100000);
/* power up the headphone amp */
akc_clear(AK4537_SIGSEL2, HPL | HPR);
udelay(100000);
/* power up the common voltage of headphone amp */
akc_set(AK4537_PM2, PMHPL | PMHPR);
udelay(100000);
}
void audiohw_postinit(void)
{
/* nothing */
}
void audiohw_close(void)
{
/* POWER DOWN SEQUENCE (from the datasheet) */
/* mute */
akc_write(AK4537_ATTL, 0xff);
akc_write(AK4537_ATTR, 0xff);
akc_set(AK4537_DAC, SMUTE);
udelay(100000);
/* power down the common voltage of headphone amp */
akc_clear(AK4537_PM2, PMHPL | PMHPR);
/* power down the DAC */
akc_clear(AK4537_PM2, PMDAC);
/* power down the headphone amp */
akc_set(AK4537_SIGSEL2, HPL | HPR);
/* disable MCKO */
akc_clear(AK4537_MODE1, MCKO_EN);
/* power down X'tal and PLL, pull down the XTI pin */
akc_write_masked(AK4537_PM2, MCLKPD, (MCLKPD | PMXTL | PMPLL));
/* power down VCOM */
akc_clear(AK4537_PM1, PMVCM);
udelay(100000);
akcodec_close(); /* target-specific */
}
void audiohw_set_master_vol(int vol_l, int vol_r)
{
akc_write(AK4537_ATTL, vol_l & 0xff);
akc_write(AK4537_ATTR, vol_r & 0xff);
}
void audiohw_set_frequency(int fsel)
{
static const unsigned char srctrl_table[HW_NUM_FREQ] =
{
HW_HAVE_8_([HW_FREQ_8] = AKC_PLL_8000HZ, )
HW_HAVE_11_([HW_FREQ_11] = AKC_PLL_11025HZ,)
HW_HAVE_16_([HW_FREQ_16] = AKC_PLL_16000HZ,)
HW_HAVE_22_([HW_FREQ_22] = AKC_PLL_22050HZ,)
HW_HAVE_24_([HW_FREQ_24] = AKC_PLL_24000HZ,)
HW_HAVE_32_([HW_FREQ_32] = AKC_PLL_32000HZ,)
HW_HAVE_44_([HW_FREQ_44] = AKC_PLL_44100HZ,)
HW_HAVE_48_([HW_FREQ_48] = AKC_PLL_48000HZ,)
};
if ((unsigned)fsel >= HW_NUM_FREQ)
fsel = HW_FREQ_DEFAULT;
akc_write_masked(AK4537_MODE2, srctrl_table[fsel], FS_MASK);
}
#if defined(HAVE_RECORDING)
void audiohw_enable_recording(bool source_mic)
{
(void)source_mic;
}
void audiohw_disable_recording(void)
{
}
void audiohw_set_recvol(int left, int right, int type)
{
(void)left;
(void)right;
(void)type;
}
void audiohw_set_monitor(bool enable)
{
(void)enable;
}
#endif /* HAVE_RECORDING */

193
firmware/export/ak4537.h Normal file
View file

@ -0,0 +1,193 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2009 by Mark Arigo
*
* 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 _AK4537_H
#define _AK4537_H
/* Volume goes from -127.0 ... 0 dB in 0.5 dB increments */
#define VOLUME_MIN -1270
#define VOLUME_MAX 0
extern int tenthdb2master(int db);
extern void audiohw_set_master_vol(int vol_l, int vol_r);
#define AKC_NUM_REGS 0x11
/* Common register bits */
/* Power Management 1 */
#define AK4537_PM1 0x00
#define PMADL (1 << 0)
#define PMMICL (1 << 1)
#define PMIPGL (1 << 2)
#define PMMO (1 << 3)
#define PMLO (1 << 4)
#define PMBPM (1 << 5)
#define PMBPS (1 << 6)
#define PMVCM (1 << 7)
/* Power Management 2 */
#define AK4537_PM2 0x01
#define PMDAC (1 << 0)
#define PMHPR (1 << 1)
#define PMHPL (1 << 2)
#define PMSPK (1 << 3)
#define SPKG (1 << 4)
#define PMPLL (1 << 5)
#define PMXTL (1 << 6)
#define MCLKPD (1 << 7)
/* Signal Select 1 */
#define AK4537_SIGSEL1 0x02
#define MOUT2 (1 << 0)
#define ALCS (1 << 1)
#define BPMSP (1 << 2)
#define BPSSP (1 << 3)
#define MICM (1 << 4)
#define DAMO (1 << 5)
#define PSMO (1 << 6)
#define MOGN (1 << 7)
/* Signal Select 2 */
#define AK4537_SIGSEL2 0x03
#define HPR (1 << 0)
#define HPL (1 << 1)
#define BPMHP (1 << 2)
#define BPSHP (1 << 3)
#define MICL (1 << 4)
#define PSLO (1 << 6)
#define DAHS (1 << 7)
/* Mode Control 1 */
#define AK4537_MODE1 0x04
#define DIF_MASK (3 << 0)
#define BICK_MASK (1 << 2)
#define MCKO_EN (1 << 3)
#define MCKO_MASK (3 << 4)
#define MCKI_MASK (3 << 6)
/* Mode Control 2 */
#define AK4537_MODE2 0x05
#define SPPS (1 << 0)
#define LOOP (1 << 1)
#define HPM (1 << 2)
#define FS_MASK (7 << 5)
/* DAC Control */
#define AK4537_DAC 0x06
#define DEM_MASK (3 << 0)
#define BST_MASK (3 << 2)
#define DATTC (1 << 4)
#define SMUTE (1 << 5)
#define TM_MASK (3 << 6)
/* MIC Control */
#define AK4537_MIC 0x07
#define MGAIN (1 << 0)
#define MSEL (1 << 1)
#define MICAD (1 << 2)
#define MPWRI (1 << 3)
#define MPWRE (1 << 4)
#define IPGAC (1 << 5)
/* Timer Select */
#define AK4537_TIMER 0x08
#define LTM_MASK (3 << 0)
#define WTM_MASK (3 << 2)
#define ZTM_MASK (3 << 4)
#define ZTM1 (1 << 5)
#define ROTM (1 << 6)
/* ALC Mode Control 1 */
#define AK4537_ALC1 0x09
#define LMTH (1 << 0)
#define RATT (1 << 1)
#define LMAT_MASK (3 << 2)
#define ZELM (1 << 4)
#define ALC1 (1 << 5)
#define ALC2 (1 << 6)
/* ALC Mode Control 2 */
#define AK4537_ALC2 0x0a
/* Lch Input PGA Control */
#define AK4537_IPGAL 0x0b
/* Lch Digital ATT Control */
#define AK4537_ATTL 0x0c
/* Rch Digital ATT Control */
#define AK4537_ATTR 0x0d
/* Volume Control */
#define AK4537_VOLUME 0x0e
#define ATTS_MASK (7 << 4)
#define ATTRM (1 << 7)
/* Rch Input PGA Control */
#define AK4537_IPGAR 0x0f
/* Power Management 3 */
#define AK4537_PM3 0x10
#define PMADR (1 << 0)
#define PMMICR (1 << 1)
#define PMIPGR (1 << 2)
#define INR (1 << 3)
#define INL (1 << 4)
/* Sampling frequency (PLL mode) */
#define AKC_PLL_8000HZ (7 << 5)
#define AKC_PLL_11025HZ (2 << 5)
#define AKC_PLL_16000HZ (6 << 5)
#define AKC_PLL_22050HZ (1 << 5)
#define AKC_PLL_24000HZ (5 << 5)
#define AKC_PLL_32000HZ (4 << 5)
#define AKC_PLL_44100HZ (0 << 5)
#define AKC_PLL_48000HZ (3 << 5)
/* MCKI input frequency (PLL mode) */
#define MCKI_PLL_12288KHZ (0 << 6)
#define MCKI_PLL_11289KHZ (1 << 6)
#define MCKI_PLL_12000KHZ (2 << 6)
/* MCKO frequency (PLL mode, MCKO bit = 1) */
#define MCKO_PLL_256FS (0 << 4)
#define MCKO_PLL_128FS (1 << 4)
#define MCKO_PLL_64FS (2 << 4)
#define MCKO_PLL_32FS (3 << 4)
/* BICK frequency */
#define BICK_64FS (0 << 2)
#define BICK_32FS (1 << 2)
/* Audio interface format */
#define DIF_MSB_LSB (0 << 0)
#define DIF_MSB_MSB (1 << 0)
#define DIF_I2S (2 << 0)
/* Low frequency boost control */
#define BST_OFF (0 << 2)
#define BST_MIN (1 << 2)
#define BST_MID (2 << 2)
#define BST_MAX (3 << 2)
#endif /* _AK4537_H */

29
firmware/export/akcodec.h Normal file
View file

@ -0,0 +1,29 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 by Marcoen Hirschberg
*
* 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 _AKCODEC_H
#define _AKCODEC_H
int akcodec_read(int reg);
void akcodec_write(int reg, int data);
void akcodec_close(void);
#endif

View file

@ -59,6 +59,8 @@
#include "tsc2100.h"
#elif defined(HAVE_JZ4740_CODEC)
#include "jz4740-codec.h"
#elif defined(HAVE_AK4537)
#include "ak4537.h"
#endif
/* convert caps into defines */

View file

@ -0,0 +1,187 @@
/*
* This config file is for the Samsung YH-820
*/
#define TARGET_TREE /* this target is using the target tree system */
/* For Rolo and boot loader */
#define MODEL_NUMBER 57
#define MODEL_NAME "Samsung YH-820"
/* define this if you have recording possibility */
/* todo #define HAVE_RECORDING */
/* Define bitmask of input sources - recordable bitmask can be defined
explicitly if different */
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN )
/* define the bitmask of hardware sample rates */
#define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \
SAMPR_CAP_11 | SAMPR_CAP_8)
/* define the bitmask of recording sample rates */
#define REC_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \
SAMPR_CAP_11 | SAMPR_CAP_8)
/* Type of LCD */
#define CONFIG_LCD LCD_S6B33B2
/* LCD dimensions */
#define LCD_WIDTH 128
#define LCD_HEIGHT 96
#define LCD_DEPTH 16 /* 65536 colours */
#define LCD_PIXELFORMAT RGB565
#ifndef BOOTLOADER
/* Define this if your LCD can be enabled/disabled */
#define HAVE_LCD_ENABLE
/* Define this if your LCD can be put to sleep.
HAVE_LCD_ENABLE should be defined as well. */
/* todo #define HAVE_LCD_SLEEP*/
/* todo #define HAVE_LCD_SLEEP_SETTING */
#endif /* !BOOTLOADER */
/* Define this for LCD backlight available */
#define HAVE_BACKLIGHT
/* Define this if your LCD can set contrast */
#define HAVE_LCD_CONTRAST
#define MIN_CONTRAST_SETTING 0
#define MAX_CONTRAST_SETTING 255
#define DEFAULT_CONTRAST_SETTING 137
/* define this if you can flip your LCD */
/* #define HAVE_LCD_FLIP */
/* define this if you can invert the colours on your LCD */
/* todo #define HAVE_LCD_INVERT */
/* put the lcd frame buffer in IRAM */
/* #define IRAM_LCDFRAMEBUFFER IDATA_ATTR */
/* define this if you have a bitmap LCD display */
#define HAVE_LCD_BITMAP
/* define this if you have a colour LCD */
#define HAVE_LCD_COLOR
/* define this if you want album art for this target */
#define HAVE_ALBUMART
/* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN
/* define this if you have access to the pitchscreen */
#define HAVE_PITCHSCREEN
/* define this if you would like tagcache to build on this target */
#define HAVE_TAGCACHE
#define CONFIG_KEYPAD SAMSUNG_YH_PAD
/* Define this if you do software codec */
#define CONFIG_CODEC SWCODEC
/* define this if you have a real-time clock */
/* todo verify rtc (or none) */
/* #ifndef BOOTLOADER */
#if 0
#define CONFIG_RTC RTC_E8564
#define HAVE_RTC_ALARM
#endif
/* define this if you have a disk storage, i.e. something
that needs spinups and can cause skips when shaked */
#define HAVE_DISK_STORAGE
/* define this if you use an ATA controller */
#define CONFIG_STORAGE STORAGE_ATA
/* We're able to shut off power to the HDD */
#ifndef SIMULATOR
/* todo #define HAVE_ATA_POWER_OFF */
#endif
/* Define this if you have a software controlled poweroff */
#define HAVE_SW_POWEROFF
/* The number of bytes reserved for loadable codecs */
#define CODEC_SIZE 0x100000
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x80000
/* Define this if you have the AK4537 audio codec */
#define HAVE_AK4537
/* AK4537 has no tone controls, so we use the software ones */
#define HAVE_SW_TONE_CONTROLS
#define AB_REPEAT_ENABLE 1
#define BATTERY_CAPACITY_DEFAULT 1550 /* default battery capacity */
#define BATTERY_CAPACITY_MIN 1500 /* min. capacity selectable */
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
#define BATTERY_TYPES_COUNT 1 /* only one type */
/* Hardware controlled charging */
#define CONFIG_CHARGING CHARGING_SIMPLE
/* define this if the unit can be powered or charged via USB */
#define HAVE_USB_POWER
#ifndef SIMULATOR
/* Define this if you have a PortalPlayer PP5020 */
#define CONFIG_CPU PP5020
/* Define this if you want to use the PP5020 i2c interface */
#define CONFIG_I2C I2C_PP5020
/* define this if the hardware can be powered off while charging */
#define HAVE_POWEROFF_WHILE_CHARGING
/* The start address index for ROM builds */
#define ROM_START 0x00000000
/* The size of the flash ROM */
#define FLASH_SIZE 0x100000
/* Define this to the CPU frequency */
#define CPU_FREQ 75000000
/* USB On-the-go */
#define CONFIG_USBOTG USBOTG_ARC
/* enable these for the experimental usb stack */
#define HAVE_USBSTACK
#define USE_ROCKBOX_USB
/* todo - check */
#define USB_VENDOR_ID 0x04e8
#define USB_PRODUCT_ID 0x5023
/* Virtual LED (icon) */
#define CONFIG_LED LED_VIRTUAL
/* Define this if you have adjustable CPU frequency */
#define HAVE_ADJUSTABLE_CPU_FREQ
#define MI4_FORMAT
#define BOOTFILE_EXT "mi4"
#define BOOTFILE "rockbox." BOOTFILE_EXT
#define BOOTDIR "/.rockbox"
/* Offset ( in the firmware file's header ) to the file CRC */
#define FIRMWARE_OFFSET_FILE_CRC 0x00
/* Offset ( in the firmware file's header ) to the real data */
#define FIRMWARE_OFFSET_FILE_DATA 0x00
#define ICODE_ATTR_TREMOR_NOT_MDCT
#endif /* !SIMULATOR */

View file

@ -0,0 +1,193 @@
/*
* This config file is for the Samsung YH-920
*/
#define TARGET_TREE /* this target is using the target tree system */
/* For Rolo and boot loader */
#define MODEL_NUMBER 58
#define MODEL_NAME "Samsung YH-920"
/* define this if you have recording possibility */
/* todo #define HAVE_RECORDING */
/* Define bitmask of input sources - recordable bitmask can be defined
explicitly if different */
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN )
/* define the bitmask of hardware sample rates */
#define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \
SAMPR_CAP_11 | SAMPR_CAP_8)
/* define the bitmask of recording sample rates */
#define REC_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \
SAMPR_CAP_11 | SAMPR_CAP_8)
/* Type of LCD */
#define CONFIG_LCD LCD_S1D15E06
/* LCD dimensions */
#define LCD_WIDTH 160
#define LCD_HEIGHT 128
#define LCD_DEPTH 2
#define LCD_PIXELFORMAT VERTICAL_PACKING
/* Display colours, for screenshots and sim (0xRRGGBB) */
#define LCD_DARKCOLOR 0x000000
#define LCD_BRIGHTCOLOR 0x5a915a
#define LCD_BL_DARKCOLOR 0x000000
#define LCD_BL_BRIGHTCOLOR 0xadd8e6
/* todo */
/* #ifndef BOOTLOADER */
#if 0
/* Define this if your LCD can be enabled/disabled */
#define HAVE_LCD_ENABLE
/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE
* should be defined as well.
* We can currently put the lcd to sleep but it won't wake up properly */
#define HAVE_LCD_SLEEP
#define HAVE_LCD_SLEEP_SETTING
#endif
/* Define this for LCD backlight available */
#define HAVE_BACKLIGHT
/* Define this if your LCD can set contrast */
/* todo #define HAVE_LCD_CONTRAST */
#define MIN_CONTRAST_SETTING 0
#define MAX_CONTRAST_SETTING 30
#define DEFAULT_CONTRAST_SETTING 14 /* Match boot contrast */
/* define this if you can flip your LCD */
/* todo #define HAVE_LCD_FLIP */
/* define this if you can invert the colours on your LCD */
/* todo #define HAVE_LCD_INVERT */
/* put the lcd frame buffer in IRAM */
/* #define IRAM_LCDFRAMEBUFFER IDATA_ATTR */
/* define this if you have a bitmap LCD display */
#define HAVE_LCD_BITMAP
/* define this if you want album art for this target */
#define HAVE_ALBUMART
/* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN
/* define this if you have access to the pitchscreen */
#define HAVE_PITCHSCREEN
/* define this if you would like tagcache to build on this target */
#define HAVE_TAGCACHE
#define CONFIG_KEYPAD SAMSUNG_YH_PAD
/* Define this if you do software codec */
#define CONFIG_CODEC SWCODEC
/* define this if you have a real-time clock */
/* todo verify rtc (or none) */
/* #ifndef BOOTLOADER */
#if 0
#define CONFIG_RTC RTC_E8564
#define HAVE_RTC_ALARM
#endif
/* define this if you have a disk storage, i.e. something
that needs spinups and can cause skips when shaked */
#define HAVE_DISK_STORAGE
/* define this if you use an ATA controller */
#define CONFIG_STORAGE STORAGE_ATA
/* We're able to shut off power to the HDD */
#ifndef SIMULATOR
/* todo #define HAVE_ATA_POWER_OFF */
#endif
/* Define this if you have a software controlled poweroff */
#define HAVE_SW_POWEROFF
/* The number of bytes reserved for loadable codecs */
#define CODEC_SIZE 0x100000
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x80000
/* Define this if you have the AK4537 audio codec */
#define HAVE_AK4537
/* AK4537 has no tone controls, so we use the software ones */
#define HAVE_SW_TONE_CONTROLS
#define AB_REPEAT_ENABLE 1
#define BATTERY_CAPACITY_DEFAULT 1550 /* default battery capacity */
#define BATTERY_CAPACITY_MIN 1500 /* min. capacity selectable */
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
#define BATTERY_TYPES_COUNT 1 /* only one type */
/* Hardware controlled charging */
#define CONFIG_CHARGING CHARGING_SIMPLE
/* define this if the unit can be powered or charged via USB */
#define HAVE_USB_POWER
#ifndef SIMULATOR
/* Define this if you have a PortalPlayer PP5020 */
#define CONFIG_CPU PP5020
/* Define this if you want to use the PP5020 i2c interface */
#define CONFIG_I2C I2C_PP5020
/* define this if the hardware can be powered off while charging */
#define HAVE_POWEROFF_WHILE_CHARGING
/* The start address index for ROM builds */
#define ROM_START 0x00000000
/* The size of the flash ROM */
#define FLASH_SIZE 0x100000
/* Define this to the CPU frequency */
#define CPU_FREQ 75000000
/* USB On-the-go */
#define CONFIG_USBOTG USBOTG_ARC
/* enable these for the experimental usb stack */
#define HAVE_USBSTACK
#define USE_ROCKBOX_USB
/* todo - check */
#define USB_VENDOR_ID 0x04e8
#define USB_PRODUCT_ID 0x5022
/* Virtual LED (icon) */
#define CONFIG_LED LED_VIRTUAL
/* Define this if you have adjustable CPU frequency */
#define HAVE_ADJUSTABLE_CPU_FREQ
#define MI4_FORMAT
#define BOOTFILE_EXT "mi4"
#define BOOTFILE "rockbox." BOOTFILE_EXT
#define BOOTDIR "/.rockbox"
/* Offset ( in the firmware file's header ) to the file CRC */
#define FIRMWARE_OFFSET_FILE_CRC 0x00
/* Offset ( in the firmware file's header ) to the real data */
#define FIRMWARE_OFFSET_FILE_DATA 0x00
#define ICODE_ATTR_TREMOR_NOT_MDCT
#endif /* !SIMULATOR */

View file

@ -0,0 +1,190 @@
/*
* This config file is for the Samsung YH-925
*/
#define TARGET_TREE /* this target is using the target tree system */
/* For Rolo and boot loader */
#define MODEL_NUMBER 59
#define MODEL_NAME "Samsung YH-925"
/* define this if you have recording possibility */
/* todo #define HAVE_RECORDING */
/* Define bitmask of input sources - recordable bitmask can be defined
explicitly if different */
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN )
/* define the bitmask of hardware sample rates */
#define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \
SAMPR_CAP_11 | SAMPR_CAP_8)
/* define the bitmask of recording sample rates */
#define REC_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \
SAMPR_CAP_11 | SAMPR_CAP_8)
/* Type of LCD */
#define CONFIG_LCD LCD_YH925
/* LCD dimensions */
#define LCD_WIDTH 160
#define LCD_HEIGHT 128
#define LCD_DEPTH 16 /* 65536 colours */
#define LCD_PIXELFORMAT RGB565
/* todo */
/* #ifndef BOOTLOADER */
#if 0
/* Define this if your LCD can be enabled/disabled */
#define HAVE_LCD_ENABLE
/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE
* should be defined as well.
* We can currently put the lcd to sleep but it won't wake up properly */
#define HAVE_LCD_SLEEP
#define HAVE_LCD_SLEEP_SETTING
#endif
/* Define this for LCD backlight available */
#define HAVE_BACKLIGHT
/* Define this if your LCD can set contrast */
/* todo #define HAVE_LCD_CONTRAST */
#define MIN_CONTRAST_SETTING 0
#define MAX_CONTRAST_SETTING 30
#define DEFAULT_CONTRAST_SETTING 14 /* Match boot contrast */
/* define this if you can flip your LCD */
/* todo #define HAVE_LCD_FLIP */
/* define this if you can invert the colours on your LCD */
/* todo #define HAVE_LCD_INVERT */
/* put the lcd frame buffer in IRAM */
/* #define IRAM_LCDFRAMEBUFFER IDATA_ATTR */
/* define this if you have a bitmap LCD display */
#define HAVE_LCD_BITMAP
/* define this if you have a colour LCD */
#define HAVE_LCD_COLOR
/* define this if you want album art for this target */
#define HAVE_ALBUMART
/* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN
/* define this if you have access to the pitchscreen */
#define HAVE_PITCHSCREEN
/* define this if you would like tagcache to build on this target */
#define HAVE_TAGCACHE
#define CONFIG_KEYPAD SAMSUNG_YH_PAD
/* Define this if you do software codec */
#define CONFIG_CODEC SWCODEC
/* define this if you have a real-time clock */
/* todo verify rtc (or none) */
/* #ifndef BOOTLOADER */
#if 0
#define CONFIG_RTC RTC_E8564
#define HAVE_RTC_ALARM
#endif
/* define this if you have a disk storage, i.e. something
that needs spinups and can cause skips when shaked */
#define HAVE_DISK_STORAGE
/* define this if you use an ATA controller */
#define CONFIG_STORAGE STORAGE_ATA
/* We're able to shut off power to the HDD */
#ifndef SIMULATOR
/* todo #define HAVE_ATA_POWER_OFF */
#endif
/* Define this if you have a software controlled poweroff */
#define HAVE_SW_POWEROFF
/* The number of bytes reserved for loadable codecs */
#define CODEC_SIZE 0x100000
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x80000
/* Define this if you have the AK4537 audio codec */
#define HAVE_AK4537
/* AK4537 has no tone controls, so we use the software ones */
#define HAVE_SW_TONE_CONTROLS
#define AB_REPEAT_ENABLE 1
#define BATTERY_CAPACITY_DEFAULT 1550 /* default battery capacity */
#define BATTERY_CAPACITY_MIN 1500 /* min. capacity selectable */
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
#define BATTERY_TYPES_COUNT 1 /* only one type */
/* Hardware controlled charging */
#define CONFIG_CHARGING CHARGING_SIMPLE
/* define this if the unit can be powered or charged via USB */
#define HAVE_USB_POWER
#ifndef SIMULATOR
/* Define this if you have a PortalPlayer PP5020 */
#define CONFIG_CPU PP5020
/* Define this if you want to use the PP5020 i2c interface */
#define CONFIG_I2C I2C_PP5020
/* define this if the hardware can be powered off while charging */
#define HAVE_POWEROFF_WHILE_CHARGING
/* The start address index for ROM builds */
#define ROM_START 0x00000000
/* The size of the flash ROM */
#define FLASH_SIZE 0x100000
/* Define this to the CPU frequency */
#define CPU_FREQ 75000000
/* USB On-the-go */
#define CONFIG_USBOTG USBOTG_ARC
/* enable these for the experimental usb stack */
#define HAVE_USBSTACK
#define USE_ROCKBOX_USB
/* todo - check */
#define USB_VENDOR_ID 0x04e8
#define USB_PRODUCT_ID 0x5024
/* Virtual LED (icon) */
#define CONFIG_LED LED_VIRTUAL
/* Define this if you have adjustable CPU frequency */
#define HAVE_ADJUSTABLE_CPU_FREQ
#define MI4_FORMAT
#define BOOTFILE_EXT "mi4"
#define BOOTFILE "rockbox." BOOTFILE_EXT
#define BOOTDIR "/.rockbox"
/* Offset ( in the firmware file's header ) to the file CRC */
#define FIRMWARE_OFFSET_FILE_CRC 0x00
/* Offset ( in the firmware file's header ) to the real data */
#define FIRMWARE_OFFSET_FILE_DATA 0x00
#define ICODE_ATTR_TREMOR_NOT_MDCT
#endif /* !SIMULATOR */

View file

@ -109,6 +109,7 @@
#define SANSA_CLIP_PAD 35
#define SANSA_FUZE_PAD 36
#define LYRE_PROTO1_PAD 37
#define SAMSUNG_YH_PAD 38
/* CONFIG_REMOTE_KEYPAD */
#define H100_REMOTE 1
@ -185,6 +186,7 @@
#define LCD_SSD1303 31 /* as used by the Sansa Clip */
#define LCD_FUZE 32 /* as used by the Sansa Fuze */
#define LCD_LYRE_PROTO1 33 /* as used by the Lyre */
#define LCD_YH925 34 /* as used by Samsung YH-925 (similar to the H10 20GB) */
/* LCD_PIXELFORMAT */
#define HORIZONTAL_PACKING 1
@ -364,6 +366,12 @@ Lyre prototype 1*/
#include "config-c200v2.h"
#elif defined(LYRE_PROTO1)
#include "config-lyre_proto1.h"
#elif defined(SAMSUNG_YH820)
#include "config-yh820.h"
#elif defined(SAMSUNG_YH920)
#include "config-yh920.h"
#elif defined(SAMSUNG_YH925)
#include "config-yh925.h"
#else
/* no known platform */
#endif

View file

@ -84,6 +84,9 @@ enum {
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
#define USBPOWER_BUTTON BUTTON_PLAYLIST
#define USBPOWER_BTN_IGNORE BUTTON_POWER
#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
#define USBPOWER_BUTTON BUTTON_RIGHT
#define USBPOWER_BTN_IGNORE BUTTON_LEFT
#endif
#endif /* HAVE_USB_POWER */

View file

@ -254,7 +254,8 @@ static void set_prescaled_volume(void)
dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
#elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
|| defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
|| defined(HAVE_WM8751) || defined(HAVE_AS3514) || defined(HAVE_TSC2100)
|| defined(HAVE_WM8751) || defined(HAVE_AS3514) || defined(HAVE_TSC2100) \
|| defined(HAVE_AK4537)
audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
#if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
|| (defined(HAVE_WM8751) && !defined(MROBE_100)) || defined(HAVE_WM8985)
@ -584,8 +585,8 @@ void sound_set(int setting, int value)
#if (!defined(HAVE_AS3514) && !defined(HAVE_WM8975) \
&& !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \
&& !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \
&& !defined (HAVE_WM8731) && !defined (HAVE_WM8978)) \
|| defined(SIMULATOR)
&& !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \
&& !defined(HAVE_AK4537)) || defined(SIMULATOR)
int sound_val2phys(int setting, int value)
{
#if CONFIG_CODEC == MAS3587F

View file

@ -45,6 +45,10 @@ bool ata_is_coldstart()
void ata_device_init()
{
#ifdef SAMSUNG_YH920
CPU_INT_DIS = (1<<IDE_IRQ);
#endif
/* From ipod-ide.c:ipod_ide_register() */
IDE0_CFG |= (1<<5);
#ifdef IPOD_NANO

View file

@ -269,7 +269,8 @@ void i2c_init(void)
#if CONFIG_I2C == I2C_PP5020
outl(0x0, 0x600060a4);
#if defined(PHILIPS_HDD1630)
#if defined(PHILIPS_HDD1630) || defined(SAMSUNG_YH820) || \
defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
outl(inl(0x600060a4) | 0x20, 0x600060a4);
outl(inl(0x7000c020) | 0x3, 0x7000c020);
outl(0x55, 0x7000c02c);

View file

@ -0,0 +1,36 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 by Barry Wardell
*
* 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 2
#define ADC_CHANNEL_0 0
#define ADC_CHANNEL_1 1
#define ADC_CHANNEL_2 2
#define ADC_CHANNEL_3 3
#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
/* Force a scan now */
unsigned short adc_scan(int channel);
#endif

View file

@ -0,0 +1,102 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (c) 2009 Mark Arigo
*
* 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 "audiohw.h"
#include "i2c-pp.h"
#include "i2s.h"
#include "akcodec.h"
// #define LOGF_ENABLE
#include "logf.h"
#define I2C_AUDIO_ADDRESS 0x10
/*
* Initialise the PP I2C and I2S.
*/
void audiohw_init(void)
{
unsigned long tmp;
logf("audiohw_init");
/* I2S device enable */
DEV_EN |= (DEV_I2S | DEV_EXTCLOCKS);
/* I2S device reset */
DEV_RS |= DEV_I2S;
asm volatile ("nop\n");
DEV_RS &= ~DEV_I2S;
DEV_INIT1 &= ~0x3000000;
tmp = DEV_INIT1;
DEV_INIT1 = tmp;
DEV_INIT2 &= ~0x100;
/* reset the I2S controller into known state */
i2s_reset();
/* this gpio pin maybe powers the codec chip */
GPIOB_ENABLE |= 0x01;
GPIOB_OUTPUT_EN |= 0x01;
GPIOB_OUTPUT_VAL |= 0x01;
GPIOL_ENABLE |= 0x20;
GPIOL_OUTPUT_VAL &= ~0x20;
GPIOL_OUTPUT_EN |= 0x20;
GPO32_VAL |= 0x00000020;
GPO32_ENABLE |= 0x00000020;
GPIOF_ENABLE |= 0x80;
GPIOF_OUTPUT_VAL |= 0x80;
GPIOF_OUTPUT_EN |= 0x80;
audiohw_preinit();
GPIOL_ENABLE |= 0x20;
GPIOL_OUTPUT_VAL |= 0x20;
GPIOL_OUTPUT_EN |= 0x20;
}
void akcodec_close(void)
{
GPIOF_ENABLE |= 0x80;
GPIOF_OUTPUT_VAL &= ~0x80;
GPIOF_OUTPUT_EN |= 0x80;
GPIOB_ENABLE |= 0x01;
GPIOB_OUTPUT_EN |= 0x01;
GPIOB_OUTPUT_VAL |= 0x01;
}
void akcodec_write(int reg, int data)
{
pp_i2c_send(I2C_AUDIO_ADDRESS, reg, data);
}
int akcodec_read(int reg)
{
return i2c_readbyte(I2C_AUDIO_ADDRESS, reg);
}

View file

@ -0,0 +1,198 @@
#include "config.h"
ENTRY(start)
OUTPUT_FORMAT(elf32-littlearm)
OUTPUT_ARCH(arm)
STARTUP(target/arm/crt0-pp.o)
#define PLUGINSIZE PLUGIN_BUFFER_SIZE
#define CODECSIZE CODEC_SIZE
#ifdef DEBUG
#define STUBOFFSET 0x10000
#else
#define STUBOFFSET 0
#endif
#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - STUBOFFSET - CODECSIZE
#define DRAMORIG 0x00000000 + STUBOFFSET
#define IRAMORIG 0x40000000
#define IRAMSIZE 0xc000
#ifdef CPU_PP502x
#define NOCACHE_BASE 0x10000000
#else
#define NOCACHE_BASE 0x28000000
#endif
#define CACHEALIGN_SIZE 16
/* End of the audio buffer, where the codec buffer starts */
#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
/* Where the codec buffer ends, and the plugin buffer starts */
#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
MEMORY
{
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
}
SECTIONS
{
.text :
{
loadaddress = .;
_loadaddress = .;
. = ALIGN(0x200);
*(.init.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(0x4);
} > DRAM
.rodata :
{
*(.rodata) /* problems without this, dunno why */
*(.rodata*)
*(.rodata.str1.1)
*(.rodata.str1.4)
. = ALIGN(0x4);
/* Pseudo-allocate the copies of the data sections */
_datacopy = .;
} > DRAM
/* TRICK ALERT! For RAM execution, we put the .data section at the
same load address as the copy. Thus, we don't waste extra RAM
when we don't actually need the copy. */
.data : AT ( _datacopy )
{
_datastart = .;
*(.data*)
. = ALIGN(0x4);
_dataend = .;
} > DRAM
#if NOCACHE_BASE != 0
/* .ncdata section is placed at uncached physical alias address and is
* loaded at the proper cached virtual address - no copying is
* performed in the init code */
.ncdata . + NOCACHE_BASE :
{
. = ALIGN(CACHEALIGN_SIZE);
*(.ncdata*)
. = ALIGN(CACHEALIGN_SIZE);
} AT> DRAM
#endif
/DISCARD/ :
{
*(.eh_frame)
}
.vectors 0x0 :
{
_vectorsstart = .;
*(.vectors);
_vectorsend = .;
} AT> DRAM
_vectorscopy = LOADADDR(.vectors);
_noloaddram = LOADADDR(.vectors);
.ibss IRAMORIG (NOLOAD) :
{
_iedata = .;
*(.qharray)
*(.ibss)
. = ALIGN(0x4);
_iend = .;
} > IRAM
.iram _iend :
{
_iramstart = .;
*(.icode)
*(.irodata)
*(.idata)
. = ALIGN(0x4);
_iramend = .;
} > IRAM AT> DRAM
_iramcopy = LOADADDR(.iram);
.idle_stacks (NOLOAD) :
{
*(.idle_stacks)
#if NUM_CORES > 1
cpu_idlestackbegin = .;
. += IDLE_STACK_SIZE;
cpu_idlestackend = .;
#endif
cop_idlestackbegin = .;
. += IDLE_STACK_SIZE;
cop_idlestackend = .;
} > IRAM
.stack (NOLOAD) :
{
*(.stack)
stackbegin = .;
. += 0x2000;
stackend = .;
} > IRAM
/* .bss and .ncbss are treated as a single section to use one init loop to
* zero it - note "_edata" and "_end" */
.bss _noloaddram (NOLOAD) :
{
_edata = .;
*(.bss*)
*(COMMON)
. = ALIGN(0x4);
} > DRAM
#if NOCACHE_BASE != 0
.ncbss . + NOCACHE_BASE (NOLOAD):
{
. = ALIGN(CACHEALIGN_SIZE);
*(.ncbss*)
. = ALIGN(CACHEALIGN_SIZE);
} AT> DRAM
#endif
/* This will be aligned by preceding alignments */
.endaddr . - NOCACHE_BASE (NOLOAD) :
{
_end = .;
} > DRAM
.audiobuf (NOLOAD) :
{
_audiobuffer = .;
audiobuffer = .;
} > DRAM
.audiobufend ENDAUDIOADDR (NOLOAD) :
{
audiobufend = .;
_audiobufend = .;
} > DRAM
.codec ENDAUDIOADDR (NOLOAD) :
{
codecbuf = .;
_codecbuf = .;
}
.plugin ENDADDR (NOLOAD) :
{
_pluginbuf = .;
pluginbuf = .;
}
}

View file

@ -0,0 +1,28 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 by Barry Wardell
*
* 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
#define _backlight_init() true
void _backlight_on(void);
void _backlight_off(void);
#endif

View file

@ -0,0 +1,64 @@
#include "config.h"
ENTRY(start)
OUTPUT_FORMAT(elf32-littlearm)
OUTPUT_ARCH(arm)
STARTUP(target/arm/crt0-pp-bl.o)
#define DRAMSIZE (MEMORYSIZE * 0x100000)
#define DRAMORIG 0x10000000
#define IRAMORIG 0x40000000
#define IRAMSIZE 0x18000
#define FLASHORIG 0x001f0000
#define FLASHSIZE 2M
MEMORY
{
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
}
SECTIONS
{
. = IRAMORIG;
.text : {
*(.init.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
} > IRAM
.data : {
*(.icode)
*(.irodata)
*(.idata)
*(.data*)
*(.ncdata*)
*(.rodata*)
_dataend = . ;
} > IRAM
.stack : {
*(.stack)
_stackbegin = .;
stackbegin = .;
. += 0x2000;
_stackend = .;
stackend = .;
} > IRAM
/* The bss section is too large for IRAM - we just move it 16MB into the
DRAM */
. = DRAMORIG;
.bss . + (16*1024*1024) : {
_edata = .;
*(.bss*);
*(.ibss);
*(COMMON)
*(.ncbss*);
_end = .;
} > DRAM
}

View file

@ -0,0 +1,55 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2009 by Mark Arigo
*
* 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"
#define HAS_BUTTON_HOLD
bool button_hold(void);
void button_init_device(void);
int button_read_device(void);
/* Button codes for Samsung YH-820, 920, 925 */
/* Main unit's buttons */
/* Left = Menu, Right = Sel */
#define BUTTON_LEFT 0x00000001
#define BUTTON_RIGHT 0x00000002
#define BUTTON_UP 0x00000004
#define BUTTON_DOWN 0x00000008
#define BUTTON_PLAY 0x00000010
#define BUTTON_REW 0x00000020
#define BUTTON_FFWD 0x00000040
#define BUTTON_REC 0x00000080
#define BUTTON_MAIN 0x000000ff
/* No Remote control */
#define BUTTON_REMOTE 0
#define POWEROFF_BUTTON BUTTON_PLAY
#define POWEROFF_COUNT 15
#endif /* _BUTTON_TARGET_H_ */

View file

@ -0,0 +1,72 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2009 by Mark Arigo
*
* 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.h"
#include "backlight.h"
void button_init_device(void)
{
/* TODO...for now, hardware initialisation is done by the OF bootloader */
}
bool button_hold(void)
{
return (~GPIOA_INPUT_VAL & 0x1);
}
/*
* Get button pressed from hardware
*/
int button_read_device(void)
{
int btn = BUTTON_NONE;
static bool hold_button = false;
bool hold_button_old;
/* Hold */
hold_button_old = hold_button;
hold_button = button_hold();
#ifndef BOOTLOADER
if (hold_button != hold_button_old)
backlight_hold_changed(hold_button);
#endif
/* device buttons */
if (!hold_button)
{
if (~GPIOA_INPUT_VAL & 0x04) btn |= BUTTON_LEFT;
if (~GPIOA_INPUT_VAL & 0x20) btn |= BUTTON_RIGHT;
if (~GPIOA_INPUT_VAL & 0x10) btn |= BUTTON_UP;
if (~GPIOA_INPUT_VAL & 0x08) btn |= BUTTON_DOWN;
if (~GPIOA_INPUT_VAL & 0x02) btn |= BUTTON_FFWD;
if (~GPIOA_INPUT_VAL & 0x80) btn |= BUTTON_REW;
if (~GPIOA_INPUT_VAL & 0x40) btn |= BUTTON_REC;
#if defined(SAMSUNG_YH820)
if ( GPIOB_INPUT_VAL & 0x80) btn |= BUTTON_PLAY;
#elif defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
if ( GPIOD_INPUT_VAL & 0x04) btn |= BUTTON_PLAY;
#endif
}
return btn;
}

View file

@ -0,0 +1,77 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2009 by Mark Arigo
*
* 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.
*
****************************************************************************/
/* Created from power.c using some iPod code, and some custom stuff based on
GPIO analysis
*/
#include "config.h"
#include "cpu.h"
#include <stdbool.h>
#include "adc.h"
#include "kernel.h"
#include "system.h"
#include "power.h"
#include "logf.h"
#include "usb.h"
void power_init(void)
{
}
unsigned int power_input_status(void)
{
unsigned int status = POWER_INPUT_NONE;
if (GPIOL_INPUT_VAL & 0x80)
status = POWER_INPUT_MAIN_CHARGER;
if (GPIOD_INPUT_VAL & 0x10)
status |= POWER_INPUT_USB_CHARGER;
return status;
}
void ide_power_enable(bool on)
{
(void)on;
/* We do nothing */
}
bool ide_powered(void)
{
/* pretend we are always powered - we don't turn it off */
return true;
}
void power_off(void)
{
/* Disable interrupts on this core */
disable_interrupt(IRQ_FIQ_STATUS);
/* Mask them on both cores */
CPU_INT_DIS = -1;
COP_INT_DIS = -1;
while (1)
DEV_RS = -1;
}

View file

@ -0,0 +1,47 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 by Barry Wardell
*
* 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 "cpu.h"
#include "system.h"
#include "backlight.h"
#include "lcd.h"
void _backlight_on(void)
{
#ifdef HAVE_LCD_SLEEP
backlight_lcd_sleep_countdown(false); /* stop counter */
#endif
#ifdef HAVE_LCD_ENABLE
lcd_enable(true); /* power on lcd + visible display */
#endif
GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x2);
}
void _backlight_off(void)
{
GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x2);
#ifdef HAVE_LCD_ENABLE
lcd_enable(false); /* power off visible display */
#endif
#ifdef HAVE_LCD_SLEEP
backlight_lcd_sleep_countdown(true); /* start countdown */
#endif
}

View file

@ -0,0 +1,551 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Jens Arnold
* Heavily based on lcd-as-memframe.c by Michael Sevakis
*
* 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 "cpu.h"
/****************************************************************************
* void lcd_write_yuv_420_lines(unsigned char const * const src[3],
* int width,
* int stride);
*
* |R| |1.000000 -0.000001 1.402000| |Y'|
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
* |B| |1.000000 1.772000 0.000000| |Pr|
* Scaled, normalized, rounded and tweaked to yield RGB 565:
* |R| |74 0 101| |Y' - 16| >> 9
* |G| = |74 -24 -51| |Cb - 128| >> 8
* |B| |74 128 0| |Cr - 128| >> 9
*
* Write four RGB565 pixels in the following order on each loop:
* 1 3 + > down
* 2 4 \/ left
*/
.section .icode, "ax", %progbits
.align 2
.global lcd_write_yuv420_lines
.type lcd_write_yuv420_lines, %function
lcd_write_yuv420_lines:
@ r0 = yuv_src
@ r1 = width
@ r2 = stride
stmfd sp!, { r4-r12 } @ save non-scratch
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
@ r5 = yuv_src[1] = Cb_p
@ r6 = yuv_src[2] = Cr_p
@ r0 = scratch
sub r2, r2, #1 @
mov r3, #0x70000000 @
orr r3, r3, #0x3000 @ r3 = LCD1_BASE
10: @ loop line @
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
@
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
add r7, r12, r7, asl #5 @ by one less when adding - same for all
@
sub r8, r8, #128 @ Cb -= 128
sub r9, r9, #128 @ Cr -= 128
@
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
add r10, r10, r10, asl #4 @
add r10, r10, r8, asl #3 @
add r10, r10, r8, asl #4 @
@
add r11, r9, r9, asl #2 @ r9 = Cr*101
add r11, r11, r9, asl #5 @
add r9, r11, r9, asl #6 @
@
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
mov r8, r8, asr #2 @
add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
mov r9, r9, asr #9 @
rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
mov r10, r10, asr #8 @
@ compute R, G, and B
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
@
orr r12, r0, r11 @ check if clamping is needed...
orr r12, r12, r7, asr #1 @ ...at all
cmp r12, #31 @
bls 15f @ no clamp @
cmp r0, #31 @ clamp b
mvnhi r0, r0, asr #31 @
andhi r0, r0, #31 @
cmp r11, #31 @ clamp r
mvnhi r11, r11, asr #31 @
andhi r11, r11, #31 @
cmp r7, #63 @ clamp g
mvnhi r7, r7, asr #31 @
andhi r7, r7, #63 @
15: @ no clamp @
@
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
@
mov r11, r11, lsl #3 @
orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r11, [r3, #0x10] @ send MSB
1: @busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r0, [r3, #0x10] @ send LSB
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
add r12, r7, r7, asl #2 @
add r7, r12, r7, asl #5 @
@ compute R, G, and B
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
@
orr r12, r0, r11 @ check if clamping is needed...
orr r12, r12, r7, asr #1 @ ...at all
cmp r12, #31 @
bls 15f @ no clamp @
cmp r0, #31 @ clamp b
mvnhi r0, r0, asr #31 @
andhi r0, r0, #31 @
cmp r11, #31 @ clamp r
mvnhi r11, r11, asr #31 @
andhi r11, r11, #31 @
cmp r7, #63 @ clamp g
mvnhi r7, r7, asr #31 @
andhi r7, r7, #63 @
15: @ no clamp @
@
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
@
mov r11, r11, lsl #3 @
orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r11, [r3, #0x10] @ send MSB
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r0, [r3, #0x10] @ send LSB
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
add r12, r7, r7, asl #2 @
add r7, r12, r7, asl #5 @
@ compute R, G, and B
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
@
orr r12, r0, r11 @ check if clamping is needed...
orr r12, r12, r7, asr #1 @ ...at all
cmp r12, #31 @
bls 15f @ no clamp @
cmp r0, #31 @ clamp b
mvnhi r0, r0, asr #31 @
andhi r0, r0, #31 @
cmp r11, #31 @ clamp r
mvnhi r11, r11, asr #31 @
andhi r11, r11, #31 @
cmp r7, #63 @ clamp g
mvnhi r7, r7, asr #31 @
andhi r7, r7, #63 @
15: @ no clamp @
@
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
@
@
mov r11, r11, lsl #3 @
orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r11, [r3, #0x10] @ send MSB
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r0, [r3, #0x10] @ send LSB
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
add r12, r7, r7, asl #2 @
add r7, r12, r7, asl #5 @
@ compute R, G, and B
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
@
orr r12, r0, r11 @ check if clamping is needed...
orr r12, r12, r7, asr #1 @ ...at all
cmp r12, #31 @
bls 15f @ no clamp @
cmp r0, #31 @ clamp b
mvnhi r0, r0, asr #31 @
andhi r0, r0, #31 @
cmp r11, #31 @ clamp r
mvnhi r11, r11, asr #31 @
andhi r11, r11, #31 @
cmp r7, #63 @ clamp g
mvnhi r7, r7, asr #31 @
andhi r7, r7, #63 @
15: @ no clamp @
@
mov r11, r11, lsl #3 @
orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r11, [r3, #0x10] @ send MSB
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r0, [r3, #0x10] @ send LSB
@
subs r1, r1, #2 @ subtract block from width
bgt 10b @ loop line @
@
ldmfd sp!, { r4-r12 } @ restore registers and return
bx lr @
.ltorg @ dump constant pool
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
/****************************************************************************
* void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
* int width,
* int stride,
* int x_screen,
* int y_screen);
*
* |R| |1.000000 -0.000001 1.402000| |Y'|
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
* |B| |1.000000 1.772000 0.000000| |Pr|
* Red scaled at twice g & b but at same precision to place it in correct
* bit position after multiply and leave instruction count lower.
* |R| |258 0 408| |Y' - 16|
* |G| = |149 -49 -104| |Cb - 128|
* |B| |149 258 0| |Cr - 128|
*
* Write four RGB565 pixels in the following order on each loop:
* 1 3 + > down
* 2 4 \/ left
*
* Kernel pattern (raw|rotated|use order):
* 5 3 4 2 2 6 3 7 row0 row2 > down
* 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
* 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
* 0 6 1 7 5 1 4 0
*/
.section .icode, "ax", %progbits
.align 2
.global lcd_write_yuv420_lines_odither
.type lcd_write_yuv420_lines_odither, %function
lcd_write_yuv420_lines_odither:
@ r0 = yuv_src
@ r1 = width
@ r2 = stride
@ r3 = x_screen
@ [sp] = y_screen
stmfd sp!, { r4-r12, lr } @ save non-scratch
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
@ r5 = yuv_src[1] = Cb_p
@ r6 = yuv_src[2] = Cr_p
@
sub r2, r2, #1 @
ldr r14, [sp, #40] @ Line up pattern and kernel quadrant
eor r14, r14, r3 @
and r14, r14, #0x2 @
mov r14, r14, lsl #6 @ 0x00 or 0x80
mov r3, #0x70000000 @
orr r3, r3, #0x3000 @ r3 = LCD1_BASE
10: @ loop line @
@
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
@
eor r14, r14, #0x80 @ flip pattern quadrant
@
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
add r12, r7, r7, asl #2 @
add r12, r12, r12, asl #4 @
add r7, r12, r7, asl #6 @
@
sub r8, r8, #128 @ Cb -= 128
sub r9, r9, #128 @ Cr -= 128
@
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
add r10, r10, r8, asl #5 @
add r10, r10, r9, asl #3 @
add r10, r10, r9, asl #5 @
add r10, r10, r9, asl #6 @
@
mov r8, r8, asl #1 @ r8 = bu = Cb*258
add r8, r8, r8, asl #7 @
@
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
add r9, r9, r9, asl #4 @
mov r9, r9, asl #3 @
@
@ compute R, G, and B
add r0, r8, r7 @ r0 = b' = Y + bu
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
rsb r7, r10, r7 @ r7 = g' = Y + guv
@
@ r8 = bu, r9 = rv, r10 = guv
@
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
add r0, r12, r0, lsr #8 @
@
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
add r11, r12, r11, lsr #8 @
@
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
add r7, r12, r7, lsr #8 @
@
add r12, r14, #0x100 @
@
add r0, r0, r12 @ b = r0 + delta
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
@
orr r12, r0, r11, asr #1 @ check if clamping is needed...
orr r12, r12, r7 @ ...at all
movs r12, r12, asr #15 @
beq 15f @ no clamp @
movs r12, r0, asr #15 @ clamp b
mvnne r0, r12, lsr #15 @
andne r0, r0, #0x7c00 @ mask b only if clamped
movs r12, r11, asr #16 @ clamp r
mvnne r11, r12, lsr #16 @
movs r12, r7, asr #15 @ clamp g
mvnne r7, r12, lsr #15 @
15: @ no clamp @
@
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
@
and r11, r11, #0xf800 @ pack pixel
mov r11, r11, lsr #8
and r7, r7, #0x7e00
orr r11, r11, r7, lsr #12
mov r7, r7, lsr#4
orr r0, r7, r0, lsr #10
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r11, [r3, #0x10] @ send MSB
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r0, [r3, #0x10] @ send LSB
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
add r12, r7, r7, asl #2 @
add r12, r12, r12, asl #4 @
add r7, r12, r7, asl #6 @
@ compute R, G, and B
add r0, r8, r7 @ r0 = b' = Y + bu
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
rsb r7, r10, r7 @ r7 = g' = Y + guv
@
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
add r0, r12, r0, lsr #8 @
@
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
add r11, r12, r11, lsr #8 @
@
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
add r7, r12, r7, lsr #8 @
@
add r12, r14, #0x200 @
@
add r0, r0, r12 @ b = r0 + delta
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
@
orr r12, r0, r11, asr #1 @ check if clamping is needed...
orr r12, r12, r7 @ ...at all
movs r12, r12, asr #15 @
beq 15f @ no clamp @
movs r12, r0, asr #15 @ clamp b
mvnne r0, r12, lsr #15 @
andne r0, r0, #0x7c00 @ mask b only if clamped
movs r12, r11, asr #16 @ clamp r
mvnne r11, r12, lsr #16 @
movs r12, r7, asr #15 @ clamp g
mvnne r7, r12, lsr #15 @
15: @ no clamp @
@
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
and r11, r11, #0xf800 @ pack pixel
mov r11, r11, lsr #8
and r7, r7, #0x7e00
orr r11, r11, r7, lsr #12
mov r7, r7, lsr#4
orr r0, r7, r0, lsr #10
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r11, [r3, #0x10] @ send MSB
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r0, [r3, #0x10] @ send LSB
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
add r12, r7, r7, asl #2 @
add r12, r12, r12, asl #4 @
add r7, r12, r7, asl #6 @
@ compute R, G, and B
add r0, r8, r7 @ r0 = b' = Y + bu
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
rsb r7, r10, r7 @ r7 = g' = Y + guv
@
@ r8 = bu, r9 = rv, r10 = guv
@
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
add r0, r12, r0, lsr #8 @
@
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
add r11, r12, r11, lsr #8 @
@
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
add r7, r12, r7, lsr #8 @
@
add r12, r14, #0x300 @
@
add r0, r0, r12 @ b = r0 + delta
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
@
orr r12, r0, r11, asr #1 @ check if clamping is needed...
orr r12, r12, r7 @ ...at all
movs r12, r12, asr #15 @
beq 15f @ no clamp @
movs r12, r0, asr #15 @ clamp b
mvnne r0, r12, lsr #15 @
andne r0, r0, #0x7c00 @ mask b only if clamped
movs r12, r11, asr #16 @ clamp r
mvnne r11, r12, lsr #16 @
movs r12, r7, asr #15 @ clamp g
mvnne r7, r12, lsr #15 @
15: @ no clamp @
@
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
and r11, r11, #0xf800 @ pack pixel
mov r11, r11, lsr #8
and r7, r7, #0x7e00
orr r11, r11, r7, lsr #12
mov r7, r7, lsr#4
orr r0, r7, r0, lsr #10
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r11, [r3, #0x10] @ send MSB
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r0, [r3, #0x10] @ send LSB
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
add r12, r7, r7, asl #2 @
add r12, r12, r12, asl #4 @
add r7, r12, r7, asl #6 @
@ compute R, G, and B
add r0, r8, r7 @ r0 = b' = Y + bu
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
rsb r7, r10, r7 @ r7 = g' = Y + guv
@
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
add r0, r12, r0, lsr #8 @
@
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
add r11, r12, r11, lsr #8 @
@
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
add r7, r12, r7, lsr #8 @
@
@ This element is zero - use r14 @
@
add r0, r0, r14 @ b = r0 + delta
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
@
orr r12, r0, r11, asr #1 @ check if clamping is needed...
orr r12, r12, r7 @ ...at all
movs r12, r12, asr #15 @
beq 15f @ no clamp @
movs r12, r0, asr #15 @ clamp b
mvnne r0, r12, lsr #15 @
andne r0, r0, #0x7c00 @ mask b only if clamped
movs r12, r11, asr #16 @ clamp r
mvnne r11, r12, lsr #16 @
movs r12, r7, asr #15 @ clamp g
mvnne r7, r12, lsr #15 @
15: @ no clamp @
and r11, r11, #0xf800 @ pack pixel
mov r11, r11, lsr #8
and r7, r7, #0x7e00
orr r11, r11, r7, lsr #12
mov r7, r7, lsr#4
orr r0, r7, r0, lsr #10
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r11, [r3, #0x10] @ send MSB
1: @ busy @
ldr r7, [r3] @ r7 = LCD1_BASE
tst r7, #LCD1_BUSY_MASK @ bridge busy?
bne 1b @
str r0, [r3, #0x10] @ send LSB
subs r1, r1, #2 @ subtract block from width
bgt 10b @ loop line @
@
ldmfd sp!, { r4-r12, pc } @ restore registers and return
.ltorg @ dump constant pool
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither

View file

@ -0,0 +1,375 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Mark Arigo
*
* 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 "cpu.h"
#include "lcd.h"
#include "kernel.h"
#include "system.h"
/* Display status */
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
static bool is_lcd_enabled = true;
#endif
/* NOTE: the LCD is rotated 90 degrees */
/* LCD command set for Samsung S6B33B2 */
#define R_NOP 0x00
#define R_OSCILLATION_MODE 0x02
#define R_DRIVER_OUTPUT_MODE 0x10
#define R_DCDC_SET 0x20
#define R_BIAS_SET 0x22
#define R_DCDC_CLOCK_DIV 0x24
#define R_DCDC_AMP_ONOFF 0x26
#define R_TEMP_COMPENSATION 0x28
#define R_CONTRAST_CONTROL1 0x2a
#define R_CONTRAST_CONTROL2 0x2b
#define R_STANDBY_OFF 0x2c
#define R_STANDBY_ON 0x2d
#define R_DDRAM_BURST_OFF 0x2e
#define R_DDRAM_BURST_ON 0x2f
#define R_ADDRESSING_MODE 0x30
#define R_ROW_VECTOR_MODE 0x32
#define R_N_LINE_INVERSION 0x34
#define R_FRAME_FREQ_CONTROL 0x36
#define R_RED_PALETTE 0x38
#define R_GREEN_PALETTE 0x3a
#define R_BLUE_PALETTE 0x3c
#define R_ENTRY_MODE 0x40
#define R_X_ADDR_AREA 0x42
#define R_Y_ADDR_AREA 0x43
#define R_RAM_SKIP_AREA 0x45
#define R_DISPLAY_OFF 0x50
#define R_DISPLAY_ON 0x51
#define R_SPEC_DISPLAY_PATTERN 0x53
#define R_PARTIAL_DISPLAY_MODE 0x55
#define R_PARTIAL_START_LINE 0x56
#define R_PARTIAL_END_LINE 0x57
#define R_AREA_SCROLL_MODE 0x59
#define R_SCROLL_START_LINE 0x5a
#define R_DATA_FORMAT_SELECT 0x60
/* wait for LCD */
static inline void lcd_wait_write(void)
{
while (LCD1_CONTROL & LCD1_BUSY_MASK);
}
/* send LCD data */
static void lcd_send_data(unsigned data)
{
lcd_wait_write();
LCD1_DATA = data >> 8;
lcd_wait_write();
LCD1_DATA = data & 0xff;
}
/* send LCD command */
static void lcd_send_command(unsigned cmd)
{
lcd_wait_write();
LCD1_CMD = cmd;
}
/* LCD init */
void lcd_init_device(void)
{
#if 0
/* This is the init sequence from the yh820 OF bootloader */
unsigned long tmp;
DEV_INIT1 &= ~0x3000;
tmp = DEV_INIT1;
DEV_INIT1 = tmp;
DEV_INIT2 &= ~0x400;
LCD1_CONTROL &= ~0x4;
udelay(15);
LCD1_CONTROL |= 0x4;
LCD1_CONTROL = 0x680;
LCD1_CONTROL = 0x684;
LCD1_CONTROL |= 0x1;
udelay(200);
lcd_send_command(R_STANDBY_OFF);
udelay(100000);
lcd_send_command(R_DISPLAY_OFF);
udelay(10000);
lcd_send_command(R_OSCILLATION_MODE);
lcd_send_command(0x01);
udelay(30000);
lcd_send_command(R_DCDC_SET);
lcd_send_command(0x01);
udelay(30000);
lcd_send_command(R_DCDC_AMP_ONOFF);
lcd_send_command(0x01);
udelay(30000);
lcd_send_command(R_DCDC_AMP_ONOFF);
lcd_send_command(0x09);
udelay(30000);
lcd_send_command(R_DCDC_AMP_ONOFF);
lcd_send_command(0x0b);
udelay(30000);
lcd_send_command(R_DCDC_AMP_ONOFF);
lcd_send_command(0x0f);
udelay(30000);
lcd_send_command(R_DCDC_CLOCK_DIV);
lcd_send_command(0x03);
udelay(10000);
lcd_send_command(R_CONTRAST_CONTROL1);
lcd_send_command(0x89);
udelay(10000);
lcd_send_command(R_TEMP_COMPENSATION);
lcd_send_command(0x01);
udelay(10000);
lcd_send_command(R_ADDRESSING_MODE);
lcd_send_command(0x19);
udelay(10000);
lcd_send_command(R_ROW_VECTOR_MODE);
lcd_send_command(0x00);
udelay(10000);
lcd_send_command(R_N_LINE_INVERSION);
lcd_send_command(0x8b);
udelay(10000);
lcd_send_command(R_ENTRY_MODE);
lcd_send_command(0x01);
lcd_send_command(R_DRIVER_OUTPUT_MODE);
lcd_send_command(0x34);
udelay(10000);
lcd_send_command(R_X_ADDR_AREA); /* vertical dimensions */
lcd_send_command(0x00); /* y1 */
lcd_send_command(LCD_HEIGHT - 1); /* y2 */
lcd_send_command(R_Y_ADDR_AREA); /* horizontal dimensions */
lcd_send_command(0x04); /* x1 + 4 */
lcd_send_command(LCD_WIDTH - 1 + 4); /* x2 + 4 */
udelay(100);
lcd_send_command(R_BIAS_SET);
lcd_send_command(0x01);
lcd_send_command(R_DDRAM_BURST_OFF);
udelay(100);
lcd_send_command(R_DISPLAY_ON);
udelay(30000);
#endif
}
/*** hardware configuration ***/
int lcd_default_contrast(void)
{
return DEFAULT_CONTRAST_SETTING;
}
void lcd_set_contrast(int val)
{
lcd_send_command(R_CONTRAST_CONTROL1);
lcd_send_command(val);
}
void lcd_set_invert_display(bool yesno)
{
/* TODO: Implement lcd_set_invert_display() */
(void)yesno;
}
#if defined(HAVE_LCD_ENABLE)
void lcd_enable(bool yesno)
{
if (yesno == is_lcd_enabled)
return;
if ((is_lcd_enabled = yesno))
{
lcd_send_command(R_STANDBY_OFF);
lcd_send_command(R_DISPLAY_ON);
lcd_activation_call_hook();
}
else
{
lcd_send_command(R_STANDBY_ON);
}
}
#endif
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
bool lcd_active(void)
{
return is_lcd_enabled;
}
#endif
#ifdef HAVE_LCD_FLIP
/* turn the display upside down (call lcd_update() afterwards) */
/* Note: since the lcd is rotated, this will flip horiz instead of vert */
void lcd_set_flip(bool yesno)
{
lcd_send_command(R_DRIVER_OUTPUT_MODE);
lcd_send_command(yesno ? 0x30 : 0x34);
}
#endif
/*** update functions ***/
void lcd_yuv_set_options(unsigned options)
{
lcd_yuv_options = options;
}
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
int width,
int stride);
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
int width,
int stride,
int x_screen, /* To align dither pattern */
int y_screen);
/* Performance function to blit a YUV bitmap directly to the LCD */
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)
{
unsigned char const * yuv_src[3];
off_t z;
/* Sorry, but width and height must be >= 2 or else */
width &= ~1;
height >>= 1;
z = stride*src_y;
yuv_src[0] = src[0] + z + src_x;
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
lcd_send_command(R_ENTRY_MODE);
lcd_send_command(0x03);
lcd_send_command(R_Y_ADDR_AREA);
lcd_send_command(x + 4);
lcd_send_command(x + width - 1 + 4);
if (lcd_yuv_options & LCD_YUV_DITHER)
{
do
{
lcd_send_command(R_X_ADDR_AREA);
lcd_send_command(y);
lcd_send_command(y + 1);
lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
yuv_src[0] += stride << 1; /* Skip down two luma lines */
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
yuv_src[2] += stride >> 1;
y += 2;
}
while (--height > 0);
}
else
{
do
{
lcd_send_command(R_X_ADDR_AREA);
lcd_send_command(y);
lcd_send_command(y + 1);
lcd_write_yuv420_lines(yuv_src, width, stride);
yuv_src[0] += stride << 1; /* Skip down two luma lines */
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
yuv_src[2] += stride >> 1;
y += 2;
}
while (--height > 0);
}
}
/* Update the display.
This must be called after all other LCD functions that change the display. */
void lcd_update(void)
{
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
}
/* Update a fraction of the display. */
void lcd_update_rect(int x, int y, int width, int height)
{
const fb_data *addr;
if (x + width >= LCD_WIDTH)
width = LCD_WIDTH - x;
if (y + height >= LCD_HEIGHT)
height = LCD_HEIGHT - y;
if ((width <= 0) || (height <= 0))
return; /* Nothing left to do. */
addr = &lcd_framebuffer[y][x];
if (width <= 1) {
lcd_send_command(R_ENTRY_MODE); /* The X end address must be larger */
lcd_send_command(0x03); /* that the X start address, so we */
lcd_send_command(R_Y_ADDR_AREA); /* switch to vertical mode for */
lcd_send_command(x + 4); /* single column updates and set */
lcd_send_command(x + 1 + 4); /* the window width to 2 */
} else {
lcd_send_command(R_ENTRY_MODE);
lcd_send_command(0x01);
lcd_send_command(R_Y_ADDR_AREA);
lcd_send_command(x + 4);
lcd_send_command(x + width - 1 + 4);
}
lcd_send_command(R_X_ADDR_AREA);
lcd_send_command(y);
lcd_send_command(y + height - 1);
do {
int w = width;
do {
lcd_send_data(*addr++);
} while (--w > 0);
addr += LCD_WIDTH - width;
} while (--height > 0);
}

View file

@ -0,0 +1,59 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
* Revisions copyright (C) 2005 by Gerald Van Baren
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "adc.h"
#include "powermgmt.h"
/* TODO: Not yet calibrated */
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
3695
};
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
{
3627
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
{ 3695, 3714, 3772, 3791, 3811, 3850, 3908, 3985, 4024, 4111, 4198 }
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
const unsigned short percent_to_volt_charge[11] =
{
3850, 3888, 3927, 3966, 4024, 4063, 4111, 4150, 4198, 4237, 4286
};
#define BATTERY_SCALE_FACTOR 4650
/* full-scale ADC readout (2^10) in millivolt */
/* Returns battery voltage from ADC [millivolts] */
unsigned int battery_adc_voltage(void)
{
/* return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; */
return 4100;
}

View file

@ -0,0 +1,47 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 by Barry Wardell
*
* 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 "cpu.h"
#include "system.h"
#include "backlight.h"
#include "lcd.h"
void _backlight_on(void)
{
#ifdef HAVE_LCD_SLEEP
backlight_lcd_sleep_countdown(false); /* stop counter */
#endif
#ifdef HAVE_LCD_ENABLE
lcd_enable(true); /* power on lcd + visible display */
#endif
GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x2);
}
void _backlight_off(void)
{
GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x2);
#ifdef HAVE_LCD_ENABLE
lcd_enable(false); /* power off visible display */
#endif
#ifdef HAVE_LCD_SLEEP
backlight_lcd_sleep_countdown(true); /* start countdown */
#endif
}

View file

@ -0,0 +1,294 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2004 by Linus Nielsen Feltzing
*
* 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 "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_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
/* lcd commands */
static void lcd_send_data(unsigned byte)
{
while (LCD1_CONTROL & LCD1_BUSY_MASK); /* wait for LCD */
LCD1_DATA = byte;
}
static void lcd_send_cmd(unsigned byte)
{
while (LCD1_CONTROL & LCD1_BUSY_MASK); /* wait for LCD */
LCD1_CMD = byte;
}
static void lcd_write_reg(unsigned cmd, unsigned data)
{
lcd_send_cmd(cmd);
lcd_send_data(data);
}
static void lcd_write_reg_ex(unsigned cmd, unsigned data0, unsigned data1)
{
lcd_send_cmd(cmd);
lcd_send_data(data0);
lcd_send_data(data1);
}
/*** 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_reg_ex(LCD_CNTL_ELECTRONIC_VOLUME, val, -1);
}
void lcd_set_invert_display(bool yesno)
{
lcd_send_cmd(LCD_CNTL_REVERSE | (yesno?1:0));
}
/* turn the display upside down (call lcd_update() afterwards) */
void lcd_set_flip(bool yesno)
{
if (yesno)
{
lcd_send_cmd(LCD_CNTL_COLUMN_ADDRESS_DIR | 1);
lcd_send_cmd(LCD_CNTL_COMMON_OUTPUT_STATUS | 0);
lcd_write_reg_ex(LCD_CNTL_DUTY_SET, 0x20, 0);
}
else
{
lcd_send_cmd(LCD_CNTL_COLUMN_ADDRESS_DIR | 0);
lcd_send_cmd(LCD_CNTL_COMMON_OUTPUT_STATUS | 1);
lcd_write_reg_ex(LCD_CNTL_DUTY_SET, 0x20, 1);
}
}
void lcd_init_device(void)
{
#if 0
/* This is the init sequence from the yh820 OF bootloader */
unsigned long tmp;
DEV_INIT2 |= 0x400;
DEV_INIT1 &= ~0x3000;
tmp = DEV_INIT1;
DEV_INIT1 = tmp;
DEV_INIT2 &= ~0x400;
LCD1_CONTROL &= ~0x4;
udelay(15);
LCD1_CONTROL |= 0x4;
LCD1_CONTROL = 0x680;
LCD1_CONTROL = 0x684;
LCD1_CONTROL |= 0x1;
lcd_send_cmd(LCD_CNTL_RESET);
lcd_send_cmd(LCD_CNTL_DISCHARGE_ON_OFF | 0);
lcd_send_cmd(LCD_CNTL_ON_OFF | 0); /* LCD OFF */
lcd_send_cmd(LCD_CNTL_COLUMN_ADDRESS_DIR | 0); /* Normal */
lcd_send_cmd(LCD_CNTL_COMMON_OUTPUT_STATUS | 0); /* Normal */
lcd_send_cmd(LCD_CNTL_REVERSE | 0); /* Reverse OFF */
lcd_send_cmd(LCD_CNTL_ALL_LIGHTING | 0); /* Normal */
lcd_write_reg_ex(LCD_CNTL_DUTY_SET, 0x1f, 0x00);
lcd_send_cmd(LCD_CNTL_OFF_MODE | 1); /* OFF -> VCC on drivers */
lcd_write_reg(LCD_CNTL_VOLTAGE_SELECT, 0x03);
lcd_write_reg(LCD_CNTL_ELECTRONIC_VOLUME, 0x40);
lcd_write_reg(LCD_CNTL_TEMP_GRADIENT_SELECT, 0x00);
lcd_write_reg(LCD_CNTL_LINE_INVERT_DRIVE, 0x1f);
lcd_send_cmd(LCD_CNTL_NLINE_ON_OFF | 1); /* N-line ON */
lcd_write_reg(LCD_CNTL_OSC_FREQUENCY, 0x00);
lcd_send_cmd(LCD_CNTL_OSC_ON_OFF | 1); /* Oscillator ON */
lcd_write_reg(LCD_CNTL_STEPUP_CK_FREQ, 0x03);
lcd_write_reg(LCD_CNTL_POWER_CONTROL, 0x1c);
lcd_write_reg(LCD_CNTL_POWER_CONTROL, 0x1e);
lcd_write_reg(LCD_CNTL_DISPLAY_START_LINE, 0x00);
lcd_send_cmd(LCD_CNTL_DATA_INPUT_DIR | 0); /* Column mode */
lcd_send_cmd(LCD_CNTL_DISPLAY_MODE, 0); /* Greyscale mode */
lcd_write_reg(LCD_CNTL_GRAY_SCALE_PATTERN, 0x52);
lcd_send_cmd(LCD_CNTL_PARTIAL_DISPLAY_ON_OFF | 0);
lcd_write_reg(LCD_CNTL_POWER_CONTROL, 0x1f);
lcd_send_cmd(LCD_CNTL_ON_OFF | 1); /* LCD ON */
#endif
}
/*** update functions ***/
/* Performance function that works with an external buffer
note that by and bheight are in 8-pixel units! */
void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
int bheight, int stride)
{
(void)data;
(void)x;
(void)by;
(void)width;
(void)bheight;
(void)stride;
#if 0
/* This is from the h100 lcd code, perhaps we can adapt */
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_reg_ex(LCD_CNTL_PAGE, by++, -1);
lcd_write_reg_ex(LCD_CNTL_COLUMN, x, -1);
lcd_send_cmd(LCD_CNTL_DATA_WRITE);
lcd_write_data(upper, width);
lcd_write_reg_ex(LCD_CNTL_PAGE, by++, -1);
lcd_write_reg_ex(LCD_CNTL_COLUMN, x, -1);
lcd_send_cmd(LCD_CNTL_DATA_WRITE);
lcd_write_data(lower, width);
data += stride;
}
#endif
}
/* Helper function for lcd_grey_phase_blit(). */
/* void lcd_grey_data(unsigned char *values, unsigned char *phases, int count); */
/* Performance function that works with an external buffer
note that by and bheight are in 4-pixel units! */
void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
int x, int by, int width, int bheight, int stride)
{
(void)values;
(void)phases;
(void)x;
(void)by;
(void)width;
(void)bheight;
(void)stride;
#if 0
/* This is from the h100 lcd code, perhaps we can adapt */
stride <<= 2; /* 4 pixels per block */
while (bheight--)
{
lcd_write_reg_ex(LCD_CNTL_PAGE, by++, -1);
lcd_write_reg_ex(LCD_CNTL_COLUMN, x, -1);
lcd_send_cmd(LCD_CNTL_DATA_WRITE);
lcd_grey_data(values, phases, width);
values += stride;
phases += stride;
}
#endif
}
/* Update a fraction of the display. */
/* void lcd_update_rect(int, int, int, int) ICODE_ATTR; */
void lcd_update_rect(int x0, int y, int width, int height)
{
const fb_data *addr;
int ymax;
int x = x0;
/* 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_reg(LCD_CNTL_PAGE, y);
lcd_write_reg(LCD_CNTL_COLUMN, x0);
addr = &lcd_framebuffer[y][x0];
lcd_send_cmd(LCD_CNTL_DATA_WRITE);
for (x = x0; x < width; x++)
lcd_send_data(*addr++);
}
}
/* Update the display.
This must be called after all other LCD functions that change the display. */
void lcd_update(void)
{
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
}

View file

@ -0,0 +1,59 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
* Revisions copyright (C) 2005 by Gerald Van Baren
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "adc.h"
#include "powermgmt.h"
/* TODO: Not yet calibrated */
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
3733
};
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
{
3627
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
{ 3733, 3772, 3821, 3840, 3869, 3917, 3985, 4034, 4072, 4140, 4198 }
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
const unsigned short percent_to_volt_charge[11] =
{
3956, 3995, 4024, 4043, 4063, 4082, 4111, 4140, 4179, 4218, 4266
};
#define BATTERY_SCALE_FACTOR 4650
/* full-scale ADC readout (2^10) in millivolt */
/* Returns battery voltage from ADC [millivolts] */
unsigned int battery_adc_voltage(void)
{
/* return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; */
return 4100;
}

View file

@ -0,0 +1,47 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 by Barry Wardell
*
* 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 "cpu.h"
#include "system.h"
#include "backlight.h"
#include "lcd.h"
void _backlight_on(void)
{
#ifdef HAVE_LCD_SLEEP
backlight_lcd_sleep_countdown(false); /* stop counter */
#endif
#ifdef HAVE_LCD_ENABLE
lcd_enable(true); /* power on lcd + visible display */
#endif
GPIO_SET_BITWISE(GPIOF_OUTPUT_VAL, 0x1);
}
void _backlight_off(void)
{
GPIO_CLEAR_BITWISE(GPIOF_OUTPUT_VAL, 0x1);
#ifdef HAVE_LCD_ENABLE
lcd_enable(false); /* power off visible display */
#endif
#ifdef HAVE_LCD_SLEEP
backlight_lcd_sleep_countdown(true); /* start countdown */
#endif
}

View file

@ -0,0 +1,538 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007-2008 by Michael Sevakis
*
* H10 20GB LCD assembly routines
*
* 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 "cpu.h"
/****************************************************************************
* void lcd_write_yuv_420_lines(unsigned char const * const src[3],
* int width,
* int stride);
*
* |R| |1.000000 -0.000001 1.402000| |Y'|
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
* |B| |1.000000 1.772000 0.000000| |Pr|
* Scaled, normalized, rounded and tweaked to yield RGB 565:
* |R| |74 0 101| |Y' - 16| >> 9
* |G| = |74 -24 -51| |Cb - 128| >> 8
* |B| |74 128 0| |Cr - 128| >> 9
*
* Write four RGB565 pixels in the following order on each loop:
* 1 3 + > down
* 2 4 \/ left
*/
.section .icode, "ax", %progbits
.align 2
.global lcd_write_yuv420_lines
.type lcd_write_yuv420_lines, %function
lcd_write_yuv420_lines:
@ r0 = yuv_src
@ r1 = width
@ r2 = stride
stmfd sp!, { r4-r12, lr } @ save non-scratch
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
@ r5 = yuv_src[1] = Cb_p
@ r6 = yuv_src[2] = Cr_p
@
mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c
add r0, r0, #0x8a00 @
mov r14, #LCD2_DATA_MASK @
@
sub r2, r2, #1 @ Adjust stride because of increment
10: @ loop line @
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
@
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
add r7, r12, r7, asl #5 @ by one less when adding - same for all
@
sub r8, r8, #128 @ Cb -= 128
sub r9, r9, #128 @ Cr -= 128
@
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
add r10, r10, r10, asl #4 @
add r10, r10, r8, asl #3 @
add r10, r10, r8, asl #4 @
@
add r11, r9, r9, asl #2 @ r9 = Cr*101
add r11, r11, r9, asl #5 @
add r9, r11, r9, asl #6 @
@
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
mov r8, r8, asr #2 @
add r9, r9, #256 @ r9 = rv = (r8 + 256) >> 9
mov r9, r9, asr #9 @
rsb r10, r10, #128 @ r10 = guv = (-r9 + 128) >> 8
mov r10, r10, asr #8 @
@ compute R, G, and B
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
@
orr r12, r3, r11 @ check if clamping is needed...
orr r12, r12, r7, asr #1 @ ...at all
cmp r12, #31 @
bls 15f @ no clamp @
cmp r3, #31 @ clamp b
mvnhi r3, r3, asr #31 @
andhi r3, r3, #31 @
cmp r11, #31 @ clamp r
mvnhi r11, r11, asr #31 @
andhi r11, r11, #31 @
cmp r7, #63 @ clamp g
mvnhi r7, r7, asr #31 @
andhi r7, r7, #63 @
15: @ no clamp @
@
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
@
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
@
orr r7, r14, r3, lsr #8 @ store pixel
orr r11, r14, r3 @
20: @
ldr r3, [r0] @
tst r3, #LCD2_BUSY_MASK @
bne 20b @
str r7, [r0] @
str r11, [r0] @
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
add r12, r7, r7, asl #2 @
add r7, r12, r7, asl #5 @
@ compute R, G, and B
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
@
orr r12, r3, r11 @ check if clamping is needed...
orr r12, r12, r7, asr #1 @ ...at all
cmp r12, #31 @
bls 15f @ no clamp @
cmp r3, #31 @ clamp b
mvnhi r3, r3, asr #31 @
andhi r3, r3, #31 @
cmp r11, #31 @ clamp r
mvnhi r11, r11, asr #31 @
andhi r11, r11, #31 @
cmp r7, #63 @ clamp g
mvnhi r7, r7, asr #31 @
andhi r7, r7, #63 @
15: @ no clamp @
@
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
@
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
@
orr r7, r14, r3, lsr #8 @ store pixel
orr r11, r14, r3 @
20: @
ldr r3, [r0] @
tst r3, #LCD2_BUSY_MASK @
bne 20b @
str r7, [r0] @
str r11, [r0] @
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
add r12, r7, r7, asl #2 @
add r7, r12, r7, asl #5 @
@ compute R, G, and B
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
@
orr r12, r3, r11 @ check if clamping is needed...
orr r12, r12, r7, asr #1 @ ...at all
cmp r12, #31 @
bls 15f @ no clamp @
cmp r3, #31 @ clamp b
mvnhi r3, r3, asr #31 @
andhi r3, r3, #31 @
cmp r11, #31 @ clamp r
mvnhi r11, r11, asr #31 @
andhi r11, r11, #31 @
cmp r7, #63 @ clamp g
mvnhi r7, r7, asr #31 @
andhi r7, r7, #63 @
15: @ no clamp @
@
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
@
orr r3, r3, r7, lsl #5 @ r3 = b | (g << 5)
orr r3, r3, r11, lsl #11 @ r3 |= (r << 11)
@
orr r7, r14, r3, lsr #8 @ store pixel
orr r11, r14, r3 @
20: @
ldr r3, [r0] @
tst r3, #LCD2_BUSY_MASK @
bne 20b @
str r7, [r0] @
str r11, [r0] @
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
add r12, r7, r7, asl #2 @
add r7, r12, r7, asl #5 @
@ compute R, G, and B
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
@
orr r12, r3, r11 @ check if clamping is needed...
orr r12, r12, r7, asr #1 @ ...at all
cmp r12, #31 @
bls 15f @ no clamp @
cmp r3, #31 @ clamp b
mvnhi r3, r3, asr #31 @
andhi r3, r3, #31 @
cmp r11, #31 @ clamp r
mvnhi r11, r11, asr #31 @
andhi r11, r11, #31 @
cmp r7, #63 @ clamp g
mvnhi r7, r7, asr #31 @
andhi r7, r7, #63 @
15: @ no clamp @
@
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
@
orr r7, r14, r3, lsr #8 @ store pixel
orr r11, r14, r3 @
20: @
ldr r3, [r0] @
tst r3, #LCD2_BUSY_MASK @
bne 20b @
str r7, [r0] @
str r11, [r0] @
@
subs r1, r1, #2 @ subtract block from width
bgt 10b @ loop line @
@
ldmfd sp!, { r4-r12, pc } @ restore registers and return
.ltorg @ dump constant pool
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
/****************************************************************************
* void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
* int width,
* int stride,
* int x_screen,
* int y_screen);
*
* |R| |1.000000 -0.000001 1.402000| |Y'|
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
* |B| |1.000000 1.772000 0.000000| |Pr|
* Red scaled at twice g & b but at same precision to place it in correct
* bit position after multiply and leave instruction count lower.
* |R| |258 0 408| |Y' - 16|
* |G| = |149 -49 -104| |Cb - 128|
* |B| |149 258 0| |Cr - 128|
*
* Write four RGB565 pixels in the following order on each loop:
* 1 3 + > down
* 2 4 \/ left
*
* Kernel pattern (raw|use order):
* 5 3 4 2 row0 row2 > down
* 1 7 0 6 | 5 1 3 7 4 0 2 6 col0 left
* 4 2 5 3 | 4 0 2 6 5 1 3 7 col2 \/
* 0 6 1 7
*/
.section .icode, "ax", %progbits
.align 2
.global lcd_write_yuv420_lines_odither
.type lcd_write_yuv420_lines_odither, %function
lcd_write_yuv420_lines_odither:
@ r0 = yuv_src
@ r1 = width
@ r2 = stride
@ r3 = x_screen
@ [sp] = y_screen
stmfd sp!, { r4-r12, lr } @ save non-scratch
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
@ r5 = yuv_src[1] = Cb_p
@ r6 = yuv_src[2] = Cr_p
@
ldr r0, [sp, #40] @ Line up pattern and kernel quadrant
eor r14, r3, r0 @
and r14, r14, #0x2 @
mov r14, r14, lsl #6 @ 0x00 or 0x80
@
mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c
add r0, r0, #0x8a00 @
@
sub r2, r2, #1 @ Adjust stride because of increment
10: @ loop line @
@
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
@
eor r14, r14, #0x80 @ flip pattern quadrant
@
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
add r12, r7, r7, asl #2 @
add r12, r12, r12, asl #4 @
add r7, r12, r7, asl #6 @
@
sub r8, r8, #128 @ Cb -= 128
sub r9, r9, #128 @ Cr -= 128
@
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
add r10, r10, r8, asl #5 @
add r10, r10, r9, asl #3 @
add r10, r10, r9, asl #5 @
add r10, r10, r9, asl #6 @
@
mov r8, r8, asl #1 @ r8 = bu = Cb*258
add r8, r8, r8, asl #7 @
@
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
add r9, r9, r9, asl #4 @
mov r9, r9, asl #3 @
@
@ compute R, G, and B
add r3, r8, r7 @ r3 = b' = Y + bu
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
rsb r7, r10, r7 @ r7 = g' = Y + guv
@
@ r8 = bu, r9 = rv, r10 = guv
@
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
add r3, r12, r3, lsr #8 @
@
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
add r11, r12, r11, lsr #8 @
@
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
add r7, r12, r7, lsr #8 @
@
add r12, r14, #0x200 @
@
add r3, r3, r12 @ b = r3 + delta
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
@
orr r12, r3, r11, asr #1 @ check if clamping is needed...
orr r12, r12, r7 @ ...at all
movs r12, r12, asr #15 @
beq 15f @ no clamp @
movs r12, r3, asr #15 @ clamp b
mvnne r3, r12, lsr #15 @
andne r3, r3, #0x7c00 @ mask b only if clamped
movs r12, r11, asr #16 @ clamp r
mvnne r11, r12, lsr #16 @
movs r12, r7, asr #15 @ clamp g
mvnne r7, r12, lsr #15 @
15: @ no clamp @
@
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
@
and r11, r11, #0xf800 @ pack pixel
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
orr r3, r11, r3, lsr #10 @ (b >> 10)
@
mov r11, #LCD2_DATA_MASK @ store pixel
orr r7, r11, r3, lsr #8 @
orr r11, r11, r3 @
20: @
ldr r3, [r0] @
tst r3, #LCD2_BUSY_MASK @
bne 20b @
str r7, [r0] @
str r11, [r0] @
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
add r12, r7, r7, asl #2 @
add r12, r12, r12, asl #4 @
add r7, r12, r7, asl #6 @
@ compute R, G, and B
add r3, r8, r7 @ r3 = b' = Y + bu
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
rsb r7, r10, r7 @ r7 = g' = Y + guv
@
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
add r3, r12, r3, lsr #8 @
@
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
add r11, r12, r11, lsr #8 @
@
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
add r7, r12, r7, lsr #8 @
@
@ This element is zero - use r14 @
@
add r3, r3, r14 @ b = r3 + delta
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
@
orr r12, r3, r11, asr #1 @ check if clamping is needed...
orr r12, r12, r7 @ ...at all
movs r12, r12, asr #15 @
beq 15f @ no clamp @
movs r12, r3, asr #15 @ clamp b
mvnne r3, r12, lsr #15 @
andne r3, r3, #0x7c00 @ mask b only if clamped
movs r12, r11, asr #16 @ clamp r
mvnne r11, r12, lsr #16 @
movs r12, r7, asr #15 @ clamp g
mvnne r7, r12, lsr #15 @
15: @ no clamp @
@
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
@
and r11, r11, #0xf800 @ pack pixel
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
orr r3, r11, r3, lsr #10 @ (b >> 10)
@
mov r11, #LCD2_DATA_MASK @ store pixel
orr r7, r11, r3, lsr #8 @
orr r11, r11, r3 @
20: @
ldr r3, [r0] @
tst r3, #LCD2_BUSY_MASK @
bne 20b @
str r7, [r0] @
str r11, [r0] @
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
add r12, r7, r7, asl #2 @
add r12, r12, r12, asl #4 @
add r7, r12, r7, asl #6 @
@ compute R, G, and B
add r3, r8, r7 @ r3 = b' = Y + bu
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
rsb r7, r10, r7 @ r7 = g' = Y + guv
@
@ r8 = bu, r9 = rv, r10 = guv
@
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
add r3, r12, r3, lsr #8 @
@
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
add r11, r12, r11, lsr #8 @
@
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
add r7, r12, r7, lsr #8 @
@
add r12, r14, #0x100 @
@
add r3, r3, r12 @ b = r3 + delta
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
@
orr r12, r3, r11, asr #1 @ check if clamping is needed...
orr r12, r12, r7 @ ...at all
movs r12, r12, asr #15 @
beq 15f @ no clamp @
movs r12, r3, asr #15 @ clamp b
mvnne r3, r12, lsr #15 @
andne r3, r3, #0x7c00 @ mask b only if clamped
movs r12, r11, asr #16 @ clamp r
mvnne r11, r12, lsr #16 @
movs r12, r7, asr #15 @ clamp g
mvnne r7, r12, lsr #15 @
15: @ no clamp @
@
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
@
and r11, r11, #0xf800 @ pack pixel
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
orr r3, r11, r3, lsr #10 @ (b >> 10)
@
mov r11, #LCD2_DATA_MASK @ store pixel
orr r7, r11, r3, lsr #8 @
orr r11, r11, r3 @
20: @
ldr r3, [r0] @
tst r3, #LCD2_BUSY_MASK @
bne 20b @
str r7, [r0] @
str r11, [r0] @
@
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
add r12, r7, r7, asl #2 @
add r12, r12, r12, asl #4 @
add r7, r12, r7, asl #6 @
@ compute R, G, and B
add r3, r8, r7 @ r3 = b' = Y + bu
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
rsb r7, r10, r7 @ r7 = g' = Y + guv
@
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
add r3, r12, r3, lsr #8 @
@
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
add r11, r12, r11, lsr #8 @
@
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
add r7, r12, r7, lsr #8 @
@
add r12, r14, #0x300 @
@
add r3, r3, r12 @ b = r3 + delta
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
@
orr r12, r3, r11, asr #1 @ check if clamping is needed...
orr r12, r12, r7 @ ...at all
movs r12, r12, asr #15 @
beq 15f @ no clamp @
movs r12, r3, asr #15 @ clamp b
mvnne r3, r12, lsr #15 @
andne r3, r3, #0x7c00 @ mask b only if clamped
movs r12, r11, asr #16 @ clamp r
mvnne r11, r12, lsr #16 @
movs r12, r7, asr #15 @ clamp g
mvnne r7, r12, lsr #15 @
15: @ no clamp @
@
and r11, r11, #0xf800 @ pack pixel
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
orr r3, r11, r3, lsr #10 @ (b >> 10)
@
mov r11, #LCD2_DATA_MASK @ store pixel
orr r7, r11, r3, lsr #8 @
orr r11, r11, r3 @
20: @
ldr r3, [r0] @
tst r3, #LCD2_BUSY_MASK @
bne 20b @
str r7, [r0] @
str r11, [r0] @
@
subs r1, r1, #2 @ subtract block from width
bgt 10b @ loop line @
@
ldmfd sp!, { r4-r12, pc } @ restore registers and return
.ltorg @ dump constant pool
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither

View file

@ -0,0 +1,638 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 by Barry Wardell
*
* 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 "cpu.h"
#include "lcd.h"
#include "kernel.h"
#include "system.h"
/** Initialized in lcd_init_device() **/
/* Is the power turned on? */
static bool power_on;
/* Is the display turned on? */
static bool display_on;
/* Amount of vertical offset. Used for flip offset correction/detection. */
static int y_offset;
/* Reverse flag. Must be remembered when display is turned off. */
static unsigned short disp_control_rev;
/* Contrast setting << 8 */
static int lcd_contrast;
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
/* Forward declarations */
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
static void lcd_display_off(void);
#endif
/* register defines for the Renesas HD66773R */
#define R_START_OSC 0x00
#define R_DEVICE_CODE_READ 0x00
#define R_DRV_OUTPUT_CONTROL 0x01
#define R_DRV_AC_CONTROL 0x02
#define R_POWER_CONTROL1 0x03
#define R_POWER_CONTROL2 0x04
#define R_ENTRY_MODE 0x05
#define R_COMPARE_REG 0x06
#define R_DISP_CONTROL 0x07
#define R_FRAME_CYCLE_CONTROL 0x0b
#define R_POWER_CONTROL3 0x0c
#define R_POWER_CONTROL4 0x0d
#define R_POWER_CONTROL5 0x0e
#define R_GATE_SCAN_START_POS 0x0f
#define R_VERT_SCROLL_CONTROL 0x11
#define R_1ST_SCR_DRV_POS 0x14
#define R_2ND_SCR_DRV_POS 0x15
#define R_HORIZ_RAM_ADDR_POS 0x16
#define R_VERT_RAM_ADDR_POS 0x17
#define R_RAM_WRITE_DATA_MASK 0x20
#define R_RAM_ADDR_SET 0x21
#define R_WRITE_DATA_2_GRAM 0x22
#define R_RAM_READ_DATA 0x22
#define R_GAMMA_FINE_ADJ_POS1 0x30
#define R_GAMMA_FINE_ADJ_POS2 0x31
#define R_GAMMA_FINE_ADJ_POS3 0x32
#define R_GAMMA_GRAD_ADJ_POS 0x33
#define R_GAMMA_FINE_ADJ_NEG1 0x34
#define R_GAMMA_FINE_ADJ_NEG2 0x35
#define R_GAMMA_FINE_ADJ_NEG3 0x36
#define R_GAMMA_GRAD_ADJ_NEG 0x37
#define R_GAMMA_AMP_ADJ_POS 0x3a
#define R_GAMMA_AMP_ADJ_NEG 0x3b
static inline void lcd_wait_write(void)
{
while (LCD2_PORT & LCD2_BUSY_MASK);
}
/* Send command */
static inline void lcd_send_cmd(unsigned cmd)
{
lcd_wait_write();
LCD2_PORT = LCD2_CMD_MASK; /* Send MSB first (should always be 0) */
lcd_wait_write();
LCD2_PORT = LCD2_CMD_MASK | cmd;
}
/* Send 16-bit data */
static inline void lcd_send_data(unsigned data)
{
lcd_wait_write();
LCD2_PORT = (data >> 8) | LCD2_DATA_MASK; /* Send MSB first */
lcd_wait_write();
LCD2_PORT = (data & 0xff) | LCD2_DATA_MASK;
}
/* Send 16-bit data byte-swapped. Only needed until we can use block transfer. */
static inline void lcd_send_data_swapped(unsigned v)
{
lcd_wait_write();
LCD2_PORT = LCD2_DATA_MASK | (v & 0xff); /* Send LSB first */
LCD2_PORT = LCD2_DATA_MASK | (v >> 8);
}
/* Write value to register */
static void lcd_write_reg(int reg, int val)
{
lcd_send_cmd(reg);
lcd_send_data(val);
}
/*** hardware configuration ***/
int lcd_default_contrast(void)
{
return DEFAULT_CONTRAST_SETTING;
}
void lcd_set_contrast(int val)
{
/* Clamp val in range 0-14, 16-30 */
if (val < 1)
val = 0;
else if (val <= 15)
--val;
else if (val > 30)
val = 30;
lcd_contrast = val << 8;
if (!power_on)
return;
/* VCOMG=1, VDV4-0=xxxxx, VCM4-0=11000 */
lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast);
}
void lcd_set_invert_display(bool yesno)
{
if (yesno == (disp_control_rev == 0x0000))
return;
disp_control_rev = yesno ? 0x0000 : 0x0004;
if (!display_on)
return;
/* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=11 */
lcd_write_reg(R_DISP_CONTROL, 0x0033 | disp_control_rev);
}
/* turn the display upside down (call lcd_update() afterwards) */
void lcd_set_flip(bool yesno)
{
/* NOT MODIFIED FOR THE YH-925 */
if (yesno == (y_offset != 0))
return;
/* The LCD controller is 132x160 while the LCD itself is 128x160, so we need
* to shift the origin by 4 when we flip the LCD */
y_offset = yesno ? 4 : 0;
if (!power_on)
return;
/* SCN4-0=000x0 (G1/G160) */
lcd_write_reg(R_GATE_SCAN_START_POS, yesno ? 0x0002 : 0x0000);
/* SM=0, GS=x, SS=x, NL4-0=10011 (G1-G160) */
lcd_write_reg(R_DRV_OUTPUT_CONTROL, yesno ? 0x0213 : 0x0113);
}
/* LCD init */
void lcd_init_device(void)
{
#if 0
/* This is the OF LCD init */
int i;
DEV_EN2 |= 0x2000;
DEV_INIT1 |= 0xfc000000;
CLCD_CLOCK_SRC &= ~0xf;
DEV_INIT2 &= ~0x400;
GPIOF_ENABLE |= 0x4;
GPIOF_OUTPUT_EN |= 0x4;
GPIOF_OUTPUT_VAL &= ~0x4;
udelay(300000);
GPIOF_OUTPUT_VAL |= 0x4;
outl(0x220, 0x70008a00);
outl(0x1f00, 0x70008a04);
LCD2_BLOCK_CTRL = 0x10008080;
LCD2_BLOCK_CONFIG = 0xf00000;
udelay(100000);
for (i = 0; i < 8; i++)
{
lcd_send_data(0);
udelay(1);
}
lcd_write_reg(R_START_OSC, 0x0001);
udelay(20000);
lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x0315);
lcd_write_reg(R_DRV_AC_CONTROL, 0x0700);
lcd_write_reg(R_ENTRY_MODE, 0x1028);
lcd_write_reg(R_COMPARE_REG, 0x0000);
lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x4008);
lcd_write_reg(R_RAM_ADDR_SET, 0x0000);
lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0700);
lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0000);
lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0000);
lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0100);
lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0707);
lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0007);
lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0700);
lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0001);
lcd_write_reg(R_GATE_SCAN_START_POS, 0x0000);
lcd_write_reg(R_VERT_SCROLL_CONTROL, 0x0000);
lcd_write_reg(R_1ST_SCR_DRV_POS, 0xaf10);
lcd_write_reg(R_2ND_SCR_DRV_POS, 0x0000);
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0x7f00); /* ((LCD_HEIGHT - 1) << 8 | 0 */
lcd_write_reg(R_VERT_RAM_ADDR_POS, 0xaf10); /* ((LCD_WIDTH + 16 - 1) << 8) | 16 */
lcd_write_reg(R_GAMMA_AMP_ADJ_POS, 0x1600);
lcd_write_reg(R_GAMMA_AMP_ADJ_NEG, 0x0006);
lcd_write_reg(R_DISP_CONTROL, 0x0104);
lcd_write_reg(R_POWER_CONTROL4, 0x0100);
lcd_write_reg(R_POWER_CONTROL5, 0x0d18);
lcd_write_reg(R_POWER_CONTROL3, 0x0000);
udelay(50000);
lcd_write_reg(R_POWER_CONTROL1, 0x0008);
lcd_write_reg(R_POWER_CONTROL3, 0x0000);
lcd_write_reg(R_POWER_CONTROL2, 0x0000);
udelay(50000);
lcd_write_reg(R_POWER_CONTROL5, 0x2d18);
lcd_write_reg(R_POWER_CONTROL3, 0x0000);
udelay(50000);
lcd_write_reg(R_POWER_CONTROL4, 0x0110);
//~ lcd_clear_display();
lcd_write_reg(R_DISP_CONTROL, 0x0105);
udelay(20000);
lcd_write_reg(R_DISP_CONTROL, 0x0125);
lcd_write_reg(R_DISP_CONTROL, 0x0127);
udelay(20000);
lcd_write_reg(R_DISP_CONTROL, 0x0137);
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
GPIOF_ENABLE |= 0x02;
GPIOF_OUTPUT_EN |= 0x02;
GPIOF_OUTPUT_VAL |= 0x02;
#endif
#ifndef BOOTLOADER
/* The OF won't boot if this is done in the bootloader - ideally we should
tweak the lcd controller speed settings but this will do for now */
CLCD_CLOCK_SRC |= 0xc0000000; /* Set LCD interface clock to PLL */
#endif
/* only these bits are needed from the OF init */
lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x0215);
lcd_write_reg(R_ENTRY_MODE, 0x1028);
power_on = true;
display_on = true;
y_offset = 0;
disp_control_rev = 0x0004;
lcd_contrast = DEFAULT_CONTRAST_SETTING << 8;
}
/* THE SLEEP AND POWER FUNCTIONS HAVE NOT BEEN MODIFIED FOR THE YH-925 */
#ifdef HAVE_LCD_SLEEP
static void lcd_power_on(void)
{
/* Be sure standby bit is clear. */
/* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=0 */
lcd_write_reg(R_POWER_CONTROL1, 0x0000);
/** Power ON Sequence **/
/* Per datasheet Rev.1.10, Jun.21.2003, p. 99 */
lcd_write_reg(R_START_OSC, 0x0001); /* Start Oscillation */
/* 10ms or more for oscillation circuit to stabilize */
sleep(HZ/50);
/* Instruction (1) for power setting; VC2-0, VRH3-0, CAD,
VRL3-0, VCM4-0, VDV4-0 */
/* VC2-0=001 */
lcd_write_reg(R_POWER_CONTROL3, 0x0001);
/* VRL3-0=0100, PON=0, VRH3-0=0001 */
lcd_write_reg(R_POWER_CONTROL4, 0x0401);
/* CAD=1 */
lcd_write_reg(R_POWER_CONTROL2, 0x8000);
/* VCOMG=0, VDV4-0=xxxxx (19), VCM4-0=11000 */
lcd_write_reg(R_POWER_CONTROL5, 0x0018 | lcd_contrast);
/* Instruction (2) for power setting; BT2-0, DC2-0, AP2-0 */
/* BT2-0=000, DC2-0=001, AP2-0=011, SLP=0, STB=0 */
lcd_write_reg(R_POWER_CONTROL1, 0x002c);
/* Instruction (3) for power setting; VCOMG = "1" */
/* VCOMG=1, VDV4-0=xxxxx (19), VCM4-0=11000 */
lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast);
/* 40ms or more; time for step-up circuits 1,2 to stabilize */
sleep(HZ/25);
/* Instruction (4) for power setting; PON = "1" */
/* VRL3-0=0100, PON=1, VRH3-0=0001 */
lcd_write_reg(R_POWER_CONTROL4, 0x0411);
/* 40ms or more; time for step-up circuit 4 to stabilize */
sleep(HZ/25);
/* Instructions for other mode settings (in register order). */
/* SM=0, GS=x, SS=0, NL4-0=10011 (G1-G160)*/
lcd_write_reg(R_DRV_OUTPUT_CONTROL, y_offset ? 0x0013 : 0x0113); /* different to X5 */
/* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */
lcd_write_reg(R_DRV_AC_CONTROL, 0x0700);
/* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */
lcd_write_reg(R_ENTRY_MODE, 0x1028); /* different to X5 */
/* CP15-0=0000000000000000 */
lcd_write_reg(R_COMPARE_REG, 0x0000);
/* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */
lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x4000);
/* SCN4-0=000x0 (G1/G160) */
/* lcd_write_reg(R_GATE_SCAN_START_POS, y_offset ? 0x0000 : 0x0002); */
/* VL7-0=0x00 */
lcd_write_reg(R_VERT_SCROLL_CONTROL, 0x0000);
/* SE17-10(End)=0x9f (159), SS17-10(Start)=0x00 */
lcd_write_reg(R_1ST_SCR_DRV_POS, 0x9f00);
/* SE27-20(End)=0x5c (92), SS27-20(Start)=0x00 */
lcd_write_reg(R_2ND_SCR_DRV_POS, 0x5c00);
/* HEA7-0=7f, HSA7-0=00 */
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0x7f00);
/* PKP12-10=0x0, PKP02-00=0x0 */
lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0003);
/* PKP32-30=0x4, PKP22-20=0x0 */
lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0400);
/* PKP52-50=0x4, PKP42-40=0x7 */
lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0407);
/* PRP12-10=0x3, PRP02-00=0x5 */
lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0305);
/* PKN12-10=0x0, PKN02-00=0x3 */
lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0003);
/* PKN32-30=0x7, PKN22-20=0x4 */
lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0704);
/* PKN52-50=0x4, PRN42-40=0x7 */
lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0407);
/* PRN12-10=0x5, PRN02-00=0x3 */
lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0503);
/* VRP14-10=0x14, VRP03-00=0x09 */
lcd_write_reg(R_GAMMA_AMP_ADJ_POS, 0x1409);
/* VRN14-00=0x06, VRN03-00=0x02 */
lcd_write_reg(R_GAMMA_AMP_ADJ_NEG, 0x0602);
/* 100ms or more; time for step-up circuits to stabilize */
sleep(HZ/10);
power_on = true;
}
static void lcd_power_off(void)
{
/* Display must be off first */
if (display_on)
lcd_display_off();
power_on = false;
/** Power OFF sequence **/
/* Per datasheet Rev.1.10, Jun.21.2003, p. 99 */
/* Step-up1 halt setting bit */
/* BT2-0=110, DC2-0=001, AP2-0=011, SLP=0, STB=0 */
lcd_write_reg(R_POWER_CONTROL1, 0x062c);
/* Step-up3,4 halt setting bit */
/* VRL3-0=0100, PON=0, VRH3-0=0001 */
lcd_write_reg(R_POWER_CONTROL4, 0x0401);
/* VCOMG=0, VDV4-0=10011, VCM4-0=11000 */
lcd_write_reg(R_POWER_CONTROL5, 0x0018 | lcd_contrast);
/* Wait 100ms or more */
sleep(HZ/10);
/* Step-up2,amp halt setting bit */
/* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=0 */
lcd_write_reg(R_POWER_CONTROL1, 0x0000);
}
void lcd_sleep(void)
{
if (power_on)
lcd_power_off();
/* Set standby mode */
/* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=1 */
lcd_write_reg(R_POWER_CONTROL1, 0x0001);
}
#endif
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
static void lcd_display_off(void)
{
display_on = false;
/** Display OFF sequence **/
/* Per datasheet Rev.1.10, Jun.21.2003, p. 97 */
/* EQ1-0=00 already */
/* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=10 */
lcd_write_reg(R_DISP_CONTROL, 0x0032 | disp_control_rev);
sleep(HZ/25); /* Wait 2 frames or more */
/* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=10 */
lcd_write_reg(R_DISP_CONTROL, 0x0022 | disp_control_rev);
sleep(HZ/25); /* Wait 2 frames or more */
/* PT1-0=00, VLE2-1=00, SPT=0, GON=0, DTE=0, REV=0, D1-0=00 */
lcd_write_reg(R_DISP_CONTROL, 0x0000);
}
#endif
#if defined(HAVE_LCD_ENABLE)
static void lcd_display_on(void)
{
/* Be sure power is on first */
if (!power_on)
lcd_power_on();
/** Display ON Sequence **/
/* Per datasheet Rev.1.10, Jun.21.2003, p. 97 */
/* PT1-0=00, VLE2-1=00, SPT=0, GON=0, DTE=0, REV=0, D1-0=01 */
lcd_write_reg(R_DISP_CONTROL, 0x0001);
sleep(HZ/25); /* Wait 2 frames or more */
/* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=01 */
lcd_write_reg(R_DISP_CONTROL, 0x0021 | disp_control_rev);
/* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=11 */
lcd_write_reg(R_DISP_CONTROL, 0x0023 | disp_control_rev);
sleep(HZ/25); /* Wait 2 frames or more */
/* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=11 */
lcd_write_reg(R_DISP_CONTROL, 0x0033 | disp_control_rev);
display_on = true;
}
void lcd_enable(bool on)
{
if (on == display_on)
return;
if (on)
{
lcd_display_on();
/* Probably out of sync and we don't wanna pepper the code with
lcd_update() calls for this. */
lcd_update();
lcd_activation_call_hook();
}
else
{
lcd_display_off();
}
}
#endif
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
bool lcd_active(void)
{
return display_on;
}
#endif
/*** update functions ***/
void lcd_yuv_set_options(unsigned options)
{
lcd_yuv_options = options;
}
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
int width,
int stride);
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
int width,
int stride,
int x_screen, /* To align dither pattern */
int y_screen);
/* Performance function to blit a YUV bitmap directly to the LCD */
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 *yuv_src[3];
const unsigned char *ysrc_max;
int y0;
int options;
/* NOT MODIFIED FOR THE YH-925 */
if (!display_on)
return;
width &= ~1;
height &= ~1;
/* calculate the drawing region */
/* The 20GB LCD is actually 128x160 but rotated 90 degrees so the origin
* is actually the bottom left and horizontal and vertical are swapped.
* Rockbox expects the origin to be the top left so we need to use
* 127 - y instead of just y */
/* max vert << 8 | start vert */
lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
y0 = LCD_HEIGHT - 1 - y + y_offset;
/* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=0, LG2-0=000 */
lcd_write_reg(R_ENTRY_MODE, 0x1020);
yuv_src[0] = src[0] + src_y * stride + src_x;
yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
ysrc_max = yuv_src[0] + height * stride;
options = lcd_yuv_options;
do
{
/* max horiz << 8 | start horiz */
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1));
/* position cursor (set AD0-AD15) */
/* start vert << 8 | start horiz */
lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y0);
/* start drawing */
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
if (options & LCD_YUV_DITHER)
{
lcd_write_yuv420_lines_odither(yuv_src, width, stride,
x, y);
y -= 2;
}
else
{
lcd_write_yuv420_lines(yuv_src, width, stride);
}
y0 -= 2;
yuv_src[0] += stride << 1;
yuv_src[1] += stride >> 1;
yuv_src[2] += stride >> 1;
}
while (yuv_src[0] < ysrc_max);
/* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */
lcd_write_reg(R_ENTRY_MODE, 0x1028);
}
/* Update a fraction of the display. */
void lcd_update_rect(int x0, int y0, int width, int height)
{
int x1, y1;
int lcd_x0, lcd_x1, lcd_y0, lcd_y1;
unsigned short *addr;
if (!display_on)
return;
/* calculate the drawing region */
y1 = (y0 + height) - 1; /* max vert */
x1 = (x0 + width) - 1; /* max horiz */
if(x1 >= LCD_WIDTH)
x1 = LCD_WIDTH - 1;
if (x1 <= 0)
return; /* nothing left to do, 0 is harmful to lcd_write_data() */
if(y1 >= LCD_HEIGHT)
y1 = LCD_HEIGHT-1;
/* The LCD is actually 128x160 rotated 90 degrees */
lcd_x0 = (LCD_HEIGHT - 1) - y1 + 4;
lcd_x1 = (LCD_HEIGHT - 1) - y0 + 4;
lcd_y0 = x0 + 16;
lcd_y1 = x1 + 16;
/* set the drawing window */
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (lcd_x1 << 8) | lcd_x0);
lcd_write_reg(R_VERT_RAM_ADDR_POS, (lcd_y1 << 8) | lcd_y0);
/* set the starting position */
lcd_write_reg(R_RAM_ADDR_SET, (lcd_y0 << 8) | lcd_x1);
/* start drawing */
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
addr = (unsigned short*)&lcd_framebuffer[y0][x0];
int c, r;
/* for each row */
for (r = 0; r < height; r++) {
/* for each column */
for (c = 0; c < width; c++) {
/* output 1 pixel */
lcd_send_data(*addr++);
}
addr += (LCD_WIDTH - width);
}
}
/* Update the display.
This must be called after all other LCD functions that change the display. */
void lcd_update(void)
{
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
}

View file

@ -0,0 +1,59 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
* Revisions copyright (C) 2005 by Gerald Van Baren
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "adc.h"
#include "powermgmt.h"
/* TODO: Not yet calibrated */
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
3733
};
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
{
3627
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
{ 3733, 3772, 3821, 3840, 3869, 3917, 3985, 4034, 4072, 4140, 4198 }
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
const unsigned short percent_to_volt_charge[11] =
{
3956, 3995, 4024, 4043, 4063, 4082, 4111, 4140, 4179, 4218, 4266
};
#define BATTERY_SCALE_FACTOR 4650
/* full-scale ADC readout (2^10) in millivolt */
/* Returns battery voltage from ADC [millivolts] */
unsigned int battery_adc_voltage(void)
{
/* return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; */
return 4100;
}

View file

@ -141,6 +141,12 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void)
usb_insert_int();
}
/* end PHILIPS_HDD1630 */
#elif defined(SAMSUNG_YH820) || defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
else if (CPU_HI_INT_STAT & GPIO0_MASK) {
if (GPIOD_INT_STAT & 0x10)
usb_insert_int();
}
/* end SAMSUNG_YHxxx */
#endif
#ifdef IPOD_ACCESSORY_PROTOCOL
else if (CPU_HI_INT_STAT & SER0_MASK) {

View file

@ -75,6 +75,13 @@
#define USB_GPIO GPIOE
#define USB_GPIO_MASK 0x04
#define USB_GPIO_VAL 0x04
#elif defined(SAMSUNG_YH820) || defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
/* GPIO D bit 4 is usb detect */
#define USB_GPIO GPIOD
#define USB_GPIO_MASK 0x10
#define USB_GPIO_VAL 0x10
#else
#error No USB GPIO config specified
#endif

112
tools/configure vendored
View file

@ -736,25 +736,27 @@ cat <<EOF
5) Ondio FM 15) H10 5/6Gb 25) Mini 1G
6) AV300 26) Mini 2G
==Toshiba== 27) 1G, 2G
40) Gigabeat F
==Cowon/iAudio== 41) Gigabeat S ==SanDisk==
30) X5/X5V/X5L 50) Sansa e200
31) M5/M5L ==Tatung== 51) Sansa e200R
32) 7 60) Elio TPJ-1022 52) Sansa c200
33) D2 53) Sansa m200
34) M3/M3L ==Olympus== 54) Sansa c100
70) M:Robe 500 55) Sansa Clip
==Creative== 71) M:Robe 100 56) Sansa e200v2
90) Zen Vision:M 30GB 57) Sansa m200v4
91) Zen Vision:M 60GB ==Philips== 58) Sansa Fuze
92) Zen Vision 100) GoGear SA9200 59) Sansa c200v2
101) GoGear HDD1630/
HDD1830 ==Logik==
==Onda== 80) DAX 1GB MP3/DAB
120) VX747 ==Meizu==
121) VX767 110) M6SL ==Lyre project==
122) VX747+ 111) M6SP 130) Lyre proto 1
112) M3
==Cowon/iAudio== 40) Gigabeat F
30) X5/X5V/X5L 41) Gigabeat S ==SanDisk==
31) M5/M5L 50) Sansa e200
32) 7 ==Tatung== 51) Sansa e200R
33) D2 60) Elio TPJ-1022 52) Sansa c200
34) M3/M3L 53) Sansa m200
==Olympus== 54) Sansa c100
==Creative== 70) M:Robe 500 55) Sansa Clip
90) Zen Vision:M 30GB 71) M:Robe 100 56) Sansa e200v2
91) Zen Vision:M 60GB 57) Sansa m200v4
92) Zen Vision ==Philips== 58) Sansa Fuze
100) GoGear SA9200 59) Sansa c200v2
==Onda== 101) GoGear HDD1630/
120) VX747 HDD1830 ==Logik==
121) VX767 80) DAX 1GB MP3/DAB
122) VX747+ ==Meizu==
110) M6SL ==Lyre project==
==Samsung== 111) M6SP 130) Lyre proto 1
140) YH-820 112) M3
141) YH-920
142) YH-925
EOF
buildfor=`input`;
@ -2048,6 +2050,78 @@ fi
t_model="lyre_proto1"
;;
140|yh_820)
target_id=57
modelname="yh_820"
target="-DSAMSUNG_YH820"
memory=32 # always
arm7tdmicc
tool="$rootdir/tools/scramble -mi4v2 -model=y820 -type=RBOS"
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
output="rockbox.mi4"
appextra="recorder:gui"
plugins=""
swcodec="yes"
boottool="$rootdir/tools/scramble -mi4v2 -model=y820 -type=RBBL"
bootoutput="FW_YH820.mi4"
# toolset is the tools within the tools directory that we build for
# this particular target.
toolset=$scramblebitmaptools
# architecture, manufacturer and model for the target-tree build
t_cpu="arm"
t_manufacturer="samsung"
t_model="yh820"
;;
141|yh_920)
target_id=58
modelname="yh_920"
target="-DSAMSUNG_YH920"
memory=32 # always
arm7tdmicc
tool="$rootdir/tools/scramble -mi4v2 -model=y920 -type=RBOS"
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 2"
output="rockbox.mi4"
appextra="recorder:gui"
plugins=""
swcodec="yes"
boottool="$rootdir/tools/scramble -mi4v2 -model=y920 -type=RBBL"
bootoutput="PP5020.mi4"
# toolset is the tools within the tools directory that we build for
# this particular target.
toolset=$scramblebitmaptools
# architecture, manufacturer and model for the target-tree build
t_cpu="arm"
t_manufacturer="samsung"
t_model="yh920"
;;
142|yh_925)
target_id=59
modelname="yh_925"
target="-DSAMSUNG_YH925"
memory=32 # always
arm7tdmicc
tool="$rootdir/tools/scramble -mi4v2 -model=y925 -type=RBOS"
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
output="rockbox.mi4"
appextra="recorder:gui"
plugins=""
swcodec="yes"
boottool="$rootdir/tools/scramble -mi4v2 -model=y925 -type=RBBL"
bootoutput="FW_YH925.mi4"
# toolset is the tools within the tools directory that we build for
# this particular target.
toolset=$scramblebitmaptools
# architecture, manufacturer and model for the target-tree build
t_cpu="arm"
t_manufacturer="samsung"
t_model="yh925"
;;
*)
echo "Please select a supported target platform!"
exit 7

View file

@ -122,7 +122,8 @@ void usage(void)
"\t (X values: h100, h120, h140, h300, ipco, nano, ipvd, mn2g\n"
"\t ip3g, ip4g, mini, iax5, iam5, iam3, h10, h10_5gb,\n"
"\t tpj2, c200, e200, giga, gigs, m100, m500, d2,\n");
printf("\t 9200, 1630, ldax, m200, clip, e2v2, m2v4, fuze)\n");
printf("\t 9200, 1630, ldax, m200, clip, e2v2, m2v4, fuze,\n"
"\t y820, y920, y925)\n");
printf("\nNo option results in Archos standard player/recorder format.\n");
exit(1);
@ -297,6 +298,12 @@ int main (int argc, char** argv)
modelnum = 44;
else if (!strcmp(&argv[1][5], "x747"))
modelnum = 45;
else if (!strcmp(&argv[1][5], "y820")) /* Samsung YH-820 */
modelnum = 57;
else if (!strcmp(&argv[1][5], "y920")) /* Samsung YH-920 */
modelnum = 58;
else if (!strcmp(&argv[1][5], "y925")) /* Samsung YH-925 */
modelnum = 59;
else {
fprintf(stderr, "unsupported model: %s\n", &argv[1][5]);
return 2;

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 KiB

View file

@ -1101,6 +1101,42 @@ void button_event(int key, bool pressed)
case SDLK_KP_ENTER:
new_btn = BUTTON_MENU;
break;
#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
case SDLK_KP4:
case SDLK_LEFT:
new_btn = BUTTON_LEFT;
break;
case SDLK_KP6:
case SDLK_RIGHT:
new_btn = BUTTON_RIGHT;
break;
case SDLK_KP8:
case SDLK_UP:
new_btn = BUTTON_UP;
break;
case SDLK_KP2:
case SDLK_DOWN:
new_btn = BUTTON_DOWN;
break;
case SDLK_KP5:
case SDLK_KP_ENTER:
new_btn = BUTTON_PLAY;
break;
case SDLK_KP9:
case SDLK_PAGEUP:
new_btn = BUTTON_FFWD;
break;
#ifdef SAMSUNG_YH820
case SDLK_KP7:
#else
case SDLK_KP3:
#endif
case SDLK_PAGEDOWN:
new_btn = BUTTON_REW;
break;
case SDLK_KP_PLUS:
new_btn = BUTTON_REC;
break;
#else
#error No keymap defined!
#endif /* CONFIG_KEYPAD */

View file

@ -302,6 +302,24 @@
#define UI_LCD_POSX 45 /* x position of lcd */
#define UI_LCD_POSY 90 /* y position of lcd */
#elif defined(SAMSUNG_YH820)
#define UI_TITLE "Samsung YH-820"
#define UI_WIDTH 368 /* width of GUI window */
#define UI_HEIGHT 428 /* height of GUI window */
#define UI_LCD_POSX 120 /* x position of lcd */
#define UI_LCD_POSY 75 /* y position of lcd */
#elif defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
#ifdef SAMSUNG_YH920
#define UI_TITLE "Samsung YH-920"
#else
#define UI_TITLE "Samsung YH-925"
#endif
#define UI_WIDTH 408 /* width of GUI window */
#define UI_HEIGHT 454 /* height of GUI window */
#define UI_LCD_POSX 124 /* x position of lcd */
#define UI_LCD_POSY 42 /* y position of lcd */
#else
#error no UI defines
#endif